Commit Graph

1259 Commits

Author SHA1 Message Date
Chinesezjc
581d2ee621 docs(tools): correct the propagated branch-name example to the index-derived 1 2026-08-05 16:31:07 +08:00
Chinesezjc
cc6e4d59fc docs(tools): scope the Python SDK validity standard to the grammar
The list-nesting cap guards against a tokenizer SyntaxError, which makes the
text not Python. A long `A | B | …` union is valid at any length and only
defeats CPython's compile-time C recursion (measured: 1,000 branches compile,
5,000 raise RecursionError); nothing compiles this block, and capping would
retire the deep-chain tests pinning the walk's linear time. Records that
boundary at the `oneOf` arm and in the Agent Note (both languages).

Also documents that the context-free degrade marker reads the call's
className rather than the frame's — frames propagate a derived name, so a
per-frame read would declare classes the caller cannot receive — and pins
that path with oneOf-of-objects and array-of-oneOf assertions.
2026-08-05 15:59:15 +08:00
Chinesezjc
0d17baae01 fix(tools): restore the v8 ignore adjacency broken by an inserted comment
The directive must sit on the line before its target; the nesting-cap comment
displaced it onto a comment line, leaving the `?? ''` arm uncovered.
2026-08-05 15:55:42 +08:00
Chinesezjc
95da760696 fix(tools): cap Python SDK list nesting at CPython's bracket limit
A schema nesting arrays past ~200 levels rendered a `list[list[...]]` chain
CPython's tokenizer rejects outright (`too many nested parentheses`), so the
SDK block was not valid Python at all — the failure docstring escaping in the
same file already guards against. The chain now degrades to `Any` at 180
levels; nesting restarts per TypedDict field, since a field annotation is its
own logical line. Unions and nested objects are unaffected: neither
accumulates open brackets.

Also aligns the unreachable SDK_RENDERERS guard message with the two reachable
ones, and corrects a test comment that still said class docstring.
2026-08-05 14:59:52 +08:00
Chinesezjc
a1d7b9a3cd fix(tools): treat a whitespace-only description as absent in the Python SDK
It collapsed to '' rather than undefined, so the renderer emitted an empty
`""""""` docstring or a bare `#   ` line for a node that documents nothing.
2026-08-05 14:05:02 +08:00
Chinesezjc
3f7707e9aa test(tools): satisfy noUncheckedIndexedAccess in the docstring test 2026-08-05 14:03:43 +08:00
Chinesezjc
7a178951d6 fix(tools): attach Python SDK docstrings to their own methods
A description was emitted above the `async def`, where Python treats the
first string as the `Tools` class docstring and every later one as a dead
expression — leaving each method undocumented in the model's only source of
tool semantics. Emit it as the first statement of the method body instead.

Also names the known languages in the run_code flavor guard (the reachable
rejection, symmetric with the SDK_RENDERERS guard) and corrects three doc
claims: the code-runtime group README no longer calls the generated SDK
TypeScript, the base Code Mode note states its serial dispatch in past
tense, and the tools README points at the rationale the language-dispatch
note actually carries.
2026-08-05 14:02:47 +08:00
Chinesezjc
975350c7b8 Merge remote-tracking branch 'origin/master' into feat/py-types-code-mode 2026-08-05 13:18:05 +08:00
Chinesezjc
698fdaea9b fix(tools): emit Python SDK members in one lexicographic stream
The Python renderer partitioned identifier methods ahead of subscript
comments, so a tool set like {a-tool, z} emitted z first — contradicting
the documented lexicographic contract and the TypeScript flavor, which
quotes exotic keys in place. Interleave both kinds in one ordered stream
and track emitted statements for the pass fallback.

Also correct four stale serialization claims in the base Code Mode note
that the live-parallel scheduler superseded.
2026-08-05 12:59:20 +08:00
imccyu
5ae0a23f42 fix(session): remove unreachable header guard 2026-08-05 11:57:17 +08:00
imccyu
1832df038d docs(session): document creation ownership boundaries 2026-08-05 11:57:17 +08:00
imccyu
c02871b910 refactor(session): separate validation from snapshots 2026-08-05 11:56:14 +08:00
imccyu
69b1ea8d8c refactor(agent-loop): extract setup and publication 2026-08-05 11:56:14 +08:00
imccyu
8cbdd5b9d0 refactor(session): route construction through Session.create 2026-08-05 11:56:14 +08:00
Chinesezjc
c273b4c25b Merge remote-tracking branch 'origin/master' into feat/py-types-code-mode 2026-08-05 11:50:52 +08:00
Chinesezjc
a9a12ad720 Merge remote-tracking branch 'origin/master' into feat/py-types-code-mode 2026-08-05 11:46:45 +08:00
xjt
7bd111b2af Merge origin/master into xjt/proofreading-active-docs-2-apply 2026-08-05 10:57:53 +08:00
imccyu
ca27512529 fix(packages): omit source publication payloads 2026-08-05 01:15:19 +08:00
xjt
edb3e82c35 docs(i18n): address proofreading review findings 2026-08-04 18:42:13 +08:00
xjt
2db712eec7 docs(i18n): proofread active Chinese documentation 2026-08-04 17:36:14 +08:00
Huanqi Cao
ffeccc138b Merge branch 'feat/ripgrep-packaged-binary' into feat/pwsh-tool
# Conflicts:
#	docs/module-graph.md
2026-08-03 20:22:16 +08:00
Chinesezjc
823b83f97a Merge remote-tracking branch 'origin/master' into feat/py-types-code-mode
# Conflicts:
#	docs/config-catalog.md
#	docs/cordis-catalog/services.md
#	packages/core/tools/README.i18n.yaml
2026-08-03 11:08:42 +08:00
Tianyi Cui
1ea72962eb Merge master into fix/subagent-stack-end-result 2026-08-02 23:13:00 +08:00
Huanqi Cao
37bceb7dad Merge branch 'feat/ripgrep-packaged-binary' into feat/pwsh-tool 2026-08-02 22:29:44 +08:00
ZiyaZhang
820a5a97f1 review(tool-goal,llm-replay): address ds-review-bot round one
- fromRequest placeholder: the last two braces of a consecutive } run now
  terminate the placeholder, so patterns may end with a brace quantifier
  (bot warning; the truncated pattern could even silently mis-match since
  an unclosed { is literal in JS regexes)
- document that derived JSONL entries pass through the same resolution
- widen ToolRunContext/deferContext seam docs beyond composite-only usage
  (source JSDoc, README pair, core-data-structures type-equiv blocks)
- pin direct-human blocked as uninstructed, completing the
  goal-round/direct-human x complete/blocked test quadrant
2026-08-02 07:19:26 -07:00
Tianyi Cui
b54381f3e7 fix(agent): commit mutable setup at publication
Agent setup may await while a mutable contribution registry changes. The previous subagent path validated and committed its provisioning batch inside the setup callback. A revocation queued after that callback returned therefore treated the installation as resident and released it, even though AgentLoop had not published the child yet. AgentLoop could then admit and announce a child whose required capability had already disappeared.

Introduce AgentSetupCommit as the optional synchronous result of create and resume setup. AgentLoop now awaits setup, invokes that commit with no intervening asynchronous boundary, and only then enters the Session and Agent registries. A commit failure follows the existing private-transaction rollback, so neither identity is published and the caller can reuse the id.

Keep continuable-subagent installations provisional until this publication commit. Contribution removal still releases every installation immediately, but now marks an unpublished batch invalid so its commit rejects with ACTIVATION_SETUP_REVOKED. Once the commit succeeds, later removal remains ordinary live revocation.

Cover create and resume ordering, resume commit rejection and identity reuse, and an assembled microtask revocation that leaves only the parent Agent and Session. Update the public JSDoc, architecture flow, package contracts, current Agent Notes, Chinese counterparts, pairing records, and generated Cordis API to describe the new boundary.

Validated with the four focused Agent/subagent test files (91 tests), the isolated assembled regression, targeted TypeScript project builds, generated Cordis API freshness, export JSDoc verification, scoped translation pairing, Markdown wrapping, and Mermaid parsing.
2026-08-02 20:09:05 +08:00
Chinesezjc
cbd2bb939a Merge remote-tracking branch 'origin/master' into feat/py-types-code-mode 2026-08-02 18:58:16 +08:00
imccyu
7d08e43720 fix(web): address steering review feedback 2026-08-02 17:53:07 +08:00
kingwl
955a12cca4 feat(web): steer queued messages into active turns 2026-08-02 17:53:07 +08:00
Chinesezjc
0d6191d0db test(tools): make the deep oneOf-object test a real quadratic tripwire
The 60k oneOf-object test had only one object node (the innermost), so the
pre-fix code called allocateClassName once — linear, never tripping the
timeout, so it did not cover the class-name Θ(depth²) it named. Give every
level an object branch (both oneOf arms are objects) so each level propagates
a one-segment-longer class name; the pre-fix rope slice is then Θ(depth²)
(~9.5s, past the 5s default) while the capped path stays linear. Also extract
the shared cap expression into capClassNameBase (used by allocateClassName and
childClassName). py-types.ts stays at 100% per-file coverage.
2026-08-02 17:48:33 +08:00
Chinesezjc
345375747e perf(tools): cap propagated class names so deep oneOf-object chains stay linear
The oneOf perf fix left a second Θ(depth²): a deep oneOf chain whose branches
are named objects propagated an ever-growing ConsString as the class-name
base, which allocateClassName then re-materialized (.length/.slice) at every
level. A childClassName helper now caps the base AT PROPAGATION, so each level
is O(1) and the walk is linear; the collision counter still makes truncated
bases unique. Also reword the oneOf comment (it said `+` but the code uses a
template literal — both are ConsString) and strengthen the tests: the deep
oneOf test now runs 100k levels (a quadratic regression trips the 5s timeout),
plus a 60k oneOf-object chain and a >120-char tool-name cap case. py-types.ts
stays at 100% per-file coverage.
2026-08-02 17:36:04 +08:00
Chinesezjc
b0e405a679 perf(tools): keep py-types oneOf rendering linear in schema depth
A deep oneOf chain joined the accumulated union string at every level
(Array.join forces materialization), making it Theta(depth^2) — a
50,000-level chain took ~7.6s. Concatenate with `+` instead: V8 builds a
lazy ConsString that materializes once at the root, matching the array
arm's template-literal laziness and ts-types' composable-document approach.
The whole walk is now linear in depth. Adds a 20,000-level oneOf test
alongside the existing deep-array one; py-types.ts stays at 100% coverage.
2026-08-02 17:22:38 +08:00
Chinesezjc
282b0d7443 docs(tools): align SDK_RENDERERS comment with the note wording
The SDK_RENDERERS JSDoc kept the circular "a renderer here … plus the
renderer itself" phrasing the note already fixed, and its
{@link RUN_CODE_FLAVORS} pointed at a non-exported const in another module
(unresolvable). Reword to "an entry here and a RUN_CODE_FLAVORS entry in
code-mode.ts … plus the renderer function this table points at".
2026-08-02 17:11:36 +08:00
Chinesezjc
cabeaed1eb refactor(tools): type the py-types render frame and tighten the note
Follow-ups from the bot's review of the trusted-after-validation revert:
- renderType's Frame now carries JsonSchemaNode (the root schema is asserted
  before any frame is built), dropping the `as Record<string, unknown>` casts,
  the `node.oneOf as unknown[]` cast, and the runtime `required` filter — the
  same typed-frame shape as the sibling ts-types renderer, so the "symmetric
  with ts-types" claim holds structurally, not just behaviorally.
- The language-dispatch note broadens the trusted-input argument to cover all
  real sources (first-party defineTool/raw registration and wire-derived plain
  JSON), and the zh side uses full-width punctuation per translation-rules.md.
py-types.ts stays at 100% per-file coverage.
2026-08-02 16:42:32 +08:00
Chinesezjc
f61b138e08 refactor(tools): restore py-types to the ts-types trusted-after-validation stance
Rounds 6-9 of the bot review kept finding adjacent hostile-getter variants
(post-validation cycles, TOCTOU on const/enum/oneOf, self-referential
functions) because the renderer had grown per-shape runtime defenses the
sibling ts-types renderer does not have. Those inputs are unreachable: the
schema is a first-party defineTool object literal that already passed
assertSupportedJsonSchema, and per AGENTS.md "Trust TypeScript at typed
same-process seams" a typed same-process seam does not add hostile-input
handling for values the static interface forbids.

renderType now validates the whole tree once and trusts it, wrapping the walk
in one try/catch that degrades to Any — byte-for-byte the stance of the
ts-types sibling. This removes the cycle-tracking (activeSchemas/hasIdentity),
the const/enum/oneOf read snapshots, the isPyScalar re-check, the typing
rollback, and the pyScalar null->None re-read handling; the corresponding
hostile-getter tests are removed. Behavior fixes that hold for legitimate
input are kept: RESERVED soft-keyword exclusion, closed-empty-object TypedDict,
class-name cap + per-base collision counter, BigInt digits for beyond-safe
integers. py-types.ts stays at 100% per-file coverage.

The language-dispatch Agent Note documents the stance and its symmetry with
ts-types so the boundary is not re-litigated.
2026-08-02 16:25:01 +08:00
Huanqi Cao
1361e9718e Merge remote-tracking branch 'origin/feat/ripgrep-packaged-binary' into feat/pwsh-tool
# Conflicts:
#	apps/cli/package.json
#	packages/core/tools/tests/gen-tool-catalog.spec.ts
2026-08-02 16:22:24 +08:00
Chinesezjc
7518a5cb65 fix(tools): snapshot const/enum/oneOf reads to close stateful-getter TOCTOU
Address ds-review-bot v5/v6 review round 8. The prior guards re-read a
stateful getter's value between the check and the spelling, so a getter
returning different values across reads could still emit invalid Python:
- renderConstrainedScalar reads node.const ONCE into a local, then checks and
  spells that snapshot; a third-read switch can no longer produce
  Literal[[object Object]].
- The enum path snapshots via [...raw] (reading each element exactly once,
  covering accessor-property elements) and requires the snapshot be a non-empty
  all-scalar array; an emptied re-read no longer spells Literal[], and a
  non-array re-read degrades.
- The oneOf branch build guards a non-array or empty re-read to Any instead of
  joining to '' (a missing type).
- pyScalar spells null as None; its JSDoc no longer claims null cannot reach it.
Tests cover each re-read shape; py-types.ts stays at 100% coverage.
2026-08-02 15:51:23 +08:00
Chinesezjc
51189a650c fix(tools): track functions in cycle detection and guard scalar re-reads
Address ds-review-bot v5/v6 review round 7:
- The render-walk cycle guard tracked only plain objects; a function has
  typeof 'function' yet carries own properties and can reference itself, so a
  post-validation getter returning a self-referential function bypassed the
  guard and looped forever. A hasIdentity() helper now covers objects AND
  functions, applied symmetrically at the three sites (root add, finish remove,
  child check).
- renderConstrainedScalar re-reads const/enum at render time; a stateful getter
  that validated as a scalar could return an object, spelling the invalid
  Literal[[object Object]]. It now degrades to the broad type when the re-read
  value is not a scalar (or the enum not an all-scalar array).
- The activeSchemas comment notes the out-of-scope boundary: a getter
  fabricating a fresh node per read never repeats an ancestor and is
  indistinguishable from a legitimately unbounded-depth schema.
Tests cover the function cycle and non-scalar const/enum re-reads; py-types.ts
stays at 100% per-file coverage.
2026-08-02 15:35:19 +08:00
Chinesezjc
96a2e38fa3 fix(tools): detect render-phase cycles and fix class-name JSDoc placement
Address ds-review-bot v5/v6 review round 6:
- renderType tracks the active ancestor schemas by object identity (the frame
  stack is the DFS path). A stateful getter can mutate the graph after
  validation so a child returns an ancestor at render time; without this the
  walk pushed frames forever instead of degrading. A repeated ancestor now
  degrades to Any, honoring the never-throw contract; distinct nodes in a
  legitimately deep chain are different objects, so it stays O(1) per push and
  O(depth) memory.
- The multiline allocateClassName JSDoc was still attached to the
  MAX_CLASS_NAME_BASE constant (a self-referential @link, and the function had
  no doc). Move the doc onto the function and give the constant its own
  one-liner.
- Tests cover the post-validation cycle and a non-object render-time child;
  py-types.ts stays at 100% per-file coverage.
2026-08-02 15:24:10 +08:00
Chinesezjc
1614f19686 fix(tools): amortize class-name allocation and tighten py-types render contract
Address ds-review-bot v5/v6 review round 5:
- allocateClassName: keep a per-base collision counter (state.nextClassCounter)
  so a deep single-field chain sharing one capped base allocates in amortized
  O(1) instead of rescanning from 2 each time (Theta(depth^2) time); remove the
  stale one-line JSDoc left above the multiline one and attach the doc to the
  function, not the constant.
- renderType's catch rolls back the typing symbols the discarded subtree added
  (not just the classes) so the import line still lists exactly the symbols the
  surviving output uses; the comment now names that the same path also degrades
  this module's internal-invariant throws to Any, the trade for never throwing.
- README (both languages) no longer describes an installable
  dsh-code-runtime-python package: the Python renderer is built in and drives
  any runtime reporting language: 'python'; the first-party backend ships
  separately.
- Tests: assert the render-phase degrade on the first call, assert the import
  line after rollback, and cover the collision-skip loop; py-types.ts stays at
  100% per-file coverage.
2026-08-02 14:50:01 +08:00
Chinesezjc
d7b4b014eb fix(tools): make py-types render total and bound deep class names
Address ds-review-bot v5/v6 review round 4:
- renderType now holds the no-throw contract across the whole walk, not
  just root validation: a stateful getter that passes validation and then
  throws in the render phase degrades the node to Any, rolling back any
  classes the call had begun emitting, instead of escaping.
- allocateClassName caps the accumulated base name. Child class names
  derive from their parent's, so an unbounded single-field object chain
  grew the sum of names to Theta(depth^2) (a 5000-deep schema produced a
  ~25MB SDK); the cap keeps total emitted text linear, the collision
  counter still makes truncated bases unique.
- The language-dispatch note's Consequences first sentence and the zh
  guard paragraph are corrected: two table entries (not one), and
  full-width Chinese punctuation per translation-rules.md.
2026-08-02 14:32:35 +08:00
Chinesezjc
59affddfc5 docs(tools): align Code Mode docs with multi-language dispatch; py-types notes
Address ds-review-bot v5/v6 review round 3:
- Config.mode JSDoc and the regenerated config-catalog no longer claim Code
  Mode requires a TypeScript runtime; both now say a language with a
  registered SDK renderer.
- The active 2026-06-15-code-mode base note (both languages) follows shipped
  reality: the SDK renders the loaded runtime's language, dsh-tools accepts
  any language with a renderer and run_code flavor, and it cross-links the
  language-dispatch note.
- The language-dispatch note distinguishes the two Object.hasOwn guards'
  reachability and documents the peekRuntime no-runtime degrade vs the
  rejected silent fallback.
- SDK_RENDERERS comment: adding a language is two table entries, not one.
- py-types: document the deliberate PEP 586 deviation for float Literals;
  add oneOf-object-branch tests (named union classes and context-free
  degrade), keeping py-types.ts at 100% per-file coverage.
2026-08-02 13:55:28 +08:00
Chinesezjc
938ee4e2eb Merge remote-tracking branch 'origin/master' into feat/py-types-code-mode 2026-08-02 13:34:27 +08:00
Dudu-0223
431fb4b035 feat(subagent): add explicit child reports 2026-08-02 12:51:10 +08:00
Dudu-0223
f0ab04273d fix(web): deduplicate subagent navigation 2026-08-02 12:51:09 +08:00
Dudu-0223
2e5c439ecf fix(subagent): decouple child listing runtime 2026-08-02 12:51:09 +08:00
Dudu-0223
4240c7dd7b feat(subagent): durable child catalog and list_agents
Implements the durable-subagent-catalog RFC: SubagentControlService.listChildren()
enumerates a parent's direct continuable children from one sessionQuery trace,
validates each child's sole subagent/descriptor event (now carrying the durable
creation label), and returns one ordered SubagentListEntry[] with per-child
corrupt/unsupported/unavailable diagnostics. The list_agents tool ships as a
separately loadable plugin of dsh-tool-subagent-control requiring sessionQuery
at load; send_message stays usable without it.
2026-08-02 12:51:09 +08:00
imccyu
bb6e6d6f3b fix(subagent): preserve continuable behavior after rebase 2026-08-02 04:35:23 +08:00
Tianyi Cui
f14121a4c2 refactor(subagent): narrow continuation interface 2026-08-02 04:34:17 +08:00
Dudu-0223
efc47b6a76 fix(subagent): require durability participant 2026-08-02 04:34:16 +08:00