Commit Graph
275 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 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 8cbdd5b9d0 refactor(session): route construction through Session.create 2026-08-05 11:56:14 +08:00
Chinesezjc a9a12ad720 Merge remote-tracking branch 'origin/master' into feat/py-types-code-mode 2026-08-05 11:46:45 +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 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 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
Dudu-0223 99a778d63f feat(subagent): continuable background subagents
Implement the continuable background subagents RFC: a durable child
session with a series of Task-backed activations, each disposing its
run before the Task settles.

- dsh-subagent: rename SubagentRun.sendMessage to strict steer, drop
  run-level resume, add SubagentProvider.resume dispatch via
  SubagentService.resume, the continuation start field, and the
  versioned model-hidden subagent/descriptor session event.
- dsh-subagent-inprocess/-spawn/-fork: publish the control-allocated
  child id, append the descriptor inside the initial turn, implement
  cold resume from the child's own transcript under the live parent
  scope, and strict running-only steer.
- dsh-subagent-control (new): SubagentControlService owning stable
  child ids, descriptor snapshot/fold/authorization, Task-backed
  activation with settle-then-dispose ordering, the process-local
  active-run association, and steer-or-resume sendMessage routing.
- dsh-tool-subagent: background route branches on the provider's
  resume capability (continuable via the control service; one-shot
  task for ACP), returning both child and task ids.
- dsh-tool-subagent-control (new): the globally named send_message
  tool rendering steered/started routes.

Keyless coverage spans Task ownership and disposal ordering, running
delivery, cold follow-up, descriptor rejection and rollback, known-id
reconstruction, kill during lookup, admission races, and a new
subagent-continuable ACP snapshot scenario.
2026-08-02 04:34:15 +08:00
Huanqi Cao 30c421ed75 fix(pwsh): pin CI expectations for the mirror design
- jscpd: the executor/tool mirror dsh-bash-local/dsh-tool-bash by design
  (Agent Note), so the mirrored regions carry explicit ignore markers with
  reasons instead of being flagged as duplication.
- pwsh-local: a self-terminated process reports SIGTERM or SIGKILL on
  POSIX (PowerShell's Stop-Process choice), not only SIGTERM.
- gen-tool-catalog.spec: the shipped-tool completeness list gains 'pwsh'.
2026-08-01 19:34:12 +08:00
Chinesezjc 683c92cb2e fix(tools): correct Python SDK fidelity and language-dispatch contract
Address ds-review-bot v5/v6 review on the Python SDK renderer:
- resolveFlavor now takes a peekRuntime() reader: undefined (no runtime,
  the doc-catalog harvest) degrades to the TS flavor, but a mounted
  runtime whose language is absent from RUN_CODE_FLAVORS fails loud. This
  removes the try/catch that silently swallowed the invalid-language path
  and drops the /* v8 ignore */ that hid the flavor guard from coverage;
  wireSchemas validates the runtime before projecting schemas so the
  renderer-table rejection stays the canonical assembly error.
- py-types RESERVED drops the soft keywords match/case: they are legal as
  TypedDict fields and methods, so keeping them needlessly degraded
  common search/regex arg objects to dict[str, Any].
- py-types treats an object with omitted properties as {} like the unified
  validator and TS renderer do, so a closed empty object declares an empty
  TypedDict instead of a permissive dict[str, Any].
- README: symmetric jsonSchemaToPy->Any note; a stale zh SDK bullet and
  limitation corrected; link the service-wide-language limitation to its
  Agent Note.
2026-07-31 18:55:07 +08:00
Chinesezjc 4fdfa89d51 feat(tools): render a Python SDK and dispatch Code Mode by runtime language
Code Mode generated only a TypeScript SDK and rejected any runtime whose
language was not "typescript". Add py-types.ts (jsonSchemaToPy /
renderToolsSdkPy) and select the SDK-section renderer and the run_code
schema flavor by ctx.codeRuntime.language through two parallel tables
(SDK_RENDERERS, RUN_CODE_FLAVORS), read with Object.hasOwn and failing
loud on a language with no renderer. The tool layer depends only on the
code-runtime seam's language field, so it lands independently of the
Python protocol and backend.
2026-07-31 18:16:15 +08:00
Yichen Jiang dbdfb8d3b7 test(tools): include persistent tool schemas 2026-07-29 14:29:16 +08:00
_Kerman 019b0abb68 Merge remote-tracking branch 'origin/master' into xtr/identified-immutable-messages
# Conflicts:
#	.agents/notes/implemented/architecture/2026-07-24-separate-context-injection-from-turn-execution.i18n.yaml
#	docs/cordis-catalog/services.md
#	docs/core-data-structures/core.i18n.yaml
#	docs/core-data-structures/session.i18n.yaml
#	docs/event-producer-consumer.md
#	docs/persistence-catalog.md
#	packages/core/session/README.i18n.yaml
#	packages/session-title/session-title/tests/persistence.spec.ts
2026-07-28 15:45:53 +08:00
_Kerman a39ffb095a fix(session): preserve plugin turn invariants 2026-07-28 15:18:48 +08:00
_Kerman 350c296cff fix: complete immutable message migration 2026-07-28 14:15:23 +08:00
_Kerman fbf87e660c refactor: identify and freeze messages at creation 2026-07-28 13:55:59 +08:00
_Kerman 92ff4b0eea Merge remote-tracking branch 'origin/master' into xtr/agent-loop-message-machine
# Conflicts:
#	docs/config-catalog.md
#	docs/cordis-catalog/services.md
#	docs/core-data-structures/tools.i18n.yaml
#	packages/core/tools/README.i18n.yaml
2026-07-27 01:44:13 +08:00
_Kerman 344943e097 Merge remote-tracking branch 'origin/master' into xtr/agent-loop-message-machine
# Conflicts:
#	docs/cordis-catalog/services.md
#	examples/acp-agent/tests/snapshots/code-mode-workspace-context/session.jsonl
#	packages/core/tools/README.i18n.yaml
#	packages/core/tools/src/code-mode.ts
2026-07-26 22:17:47 +08:00
_Kerman 04f0435cc9 refactor(tools): let the terminal marker ride the nested result
The staged-promotion machinery (concludingParents keyed by parent token
plus a pendingParentConclusions staging map) spread one fact — this call
concluded the turn — across three registry-side collections with manual
cleanup. Align it with how additionalContexts already crosses the same
boundary: concludeTurn() marks only its own execution, the marker rides
that execution's successful result (ToolExecutionFailure types
concludesTurn as never, so a policy-converted failure sheds it with the
type), and the composite that owns the nested dispatch forwards it —
Code Mode's binding does so beside its existing context forwarding.

The registry loses both parent-keyed collections and the promotion
block; the propagation decision moves to the owning boundary; the
structured-output consumer's own two-phase commit is untouched.
2026-07-26 21:24:16 +08:00
_Kerman 39c09c9a49 Merge remote-tracking branch 'origin/master' into xtr/agent-loop-message-machine
# Conflicts:
#	docs/core-data-structures/tools.i18n.yaml
#	examples/acp-agent/tests/snapshots/code-mode-workspace-context/session.jsonl
#	packages/core/tools/README.i18n.yaml
2026-07-26 21:08:54 +08:00
_Kerman 2a51ef85fb fix: close three seams the message-machine refactor left open
agent-loop lifecycle: dispose drains machine.done to true quiescence.
cancel()'s own running-to-idle transition can legitimately re-enter
through an automation listener (goal-session's idle drive runs
synchronously to its first await) and replace done with a fresh
admission after the single capture; teardown now re-cancels and
re-awaits until the slot stabilizes, so the scope never unwinds under a
live run.

tools: a nested concludeTurn() stages on its own execution and promotes
to the enclosing composite only on the call's authoritative successful
verdict. A post-execute policy that converts the nested success into an
error no longer lets a recovering composite stop the turn on a failed
terminal operation (the Code Mode structured-output shape).

goal-session: the driver owns its round durability barrier again. The
loop's persistence is eager write-behind with no turn-end flush, so the
old post-turn agent/error signal for flush failures never fires; a
settled round now sets needsCheckpoint and re-enters drive, flushing
before the next reservation and disarming on failure instead of queueing
an autonomous round on state that was never persisted.
2026-07-26 20:51:32 +08:00
Tianyi Cui 442a3dd884 Merge branch 'code-mode-ui/live-parallel' into code-mode-ui/dispatch-spill
Conflict resolution: drainDispatches composes both sides — the reworked
single-lane driver's drive() (ordered stages, mid-flight commit drain)
followed by this branch's logWork drain, so every shaped settle append
still lands inside the open run_code turn.
2026-07-26 15:31:09 +08:00
Tianyi Cui f9cc62266c fix(tools): single ordered driver lane for the sub-dispatch scheduler; validate the cap
Responding to ds-review-bot round 2 on #658 (three critical findings, one
warning — all rooted in the pump/commit split racing ordered stages):

- ONE driver lane now owns every ordered stage: the start append, prepare
  (pre-execute/guards), and the head-of-line commit (post-execute, context
  deferral, settle append). start() is awaited before the next entry can
  start, so concurrent submissions can no longer run pre-execute pipelines
  concurrently; only the around-dispatch/body stage overlaps, matching the
  native loop's fillPool sequencing.
- An exclusive call's barrier now holds through its COMMIT: later starts
  wait for the exclusive pipeline (post-execute included) to finish, the
  native exclusive-group semantics.
- drainDispatches() awaits the driver run itself, so a commit already
  mid-flight when the program returns is drained before run_code closes
  the turn — the settle event and deferred contexts land inside it.
- maxParallelSubCalls is resolved and validated at construction (positive
  integer), so direct construction can no longer wedge the pool with 0.

New tests: overlapping-submission ordered-prepare, barrier-through-commit,
drain-mid-commit, cap rejection. 96 keyless snapshots replay unchanged;
Agent Note updated (both languages).
2026-07-26 15:26:52 +08:00
Tianyi Cui 3b63bcbeec test: cover the dispatch-log seam's contained-failure and decline arms
CI's full-tree coverage flagged three untaken paths this PR introduced:
- shapeDispatchLog's catch (a throwing tools/code-dispatch-log listener
  must be contained — the settle event logs the unshaped content);
- the spill listener's flatten-decline arm (non-text sub-result content
  passes through unchanged);
- the generated scope-key extractor row for tools/code-dispatch-log
  (registered in the scope invariant matrix like the other tools events).
2026-07-26 14:32:22 +08:00
_Kerman 57d90c343d Merge remote-tracking branch 'origin/master' into xtr/agent-loop-message-machine
# Conflicts:
#	.agents/notes/implemented/feature/2026-06-14-acp-agent-client-protocol.md
#	.agents/notes/implemented/feature/2026-06-14-acp-agent-client-protocol.zh.md
#	.agents/notes/implemented/feature/2026-06-30-hook-bridges.i18n.yaml
#	.agents/notes/implemented/feature/2026-06-30-interception-seams.i18n.yaml
#	.agents/notes/implemented/feature/2026-07-06-sandbox.i18n.yaml
#	.agents/notes/implemented/feature/2026-07-06-sandbox.md
#	.agents/notes/implemented/feature/2026-07-06-sandbox.zh.md
#	.agents/notes/implemented/feature/2026-07-19-model-facing-goal-tools.i18n.yaml
#	.agents/notes/implemented/feature/2026-07-19-same-session-goal-round-driver.i18n.yaml
#	.agents/notes/implemented/feature/2026-07-25-workspace-ui-product-flow.i18n.yaml
#	.agents/notes/implemented/simplification/2026-07-02-remove-stream-chunk-mirror.i18n.yaml
#	docs/architecture.i18n.yaml
#	docs/cookbook/adding-a-tool.i18n.yaml
#	docs/cookbook/extension-cookbook.i18n.yaml
#	docs/core-data-structures/llm-streaming.i18n.yaml
#	docs/core-data-structures/session.i18n.yaml
#	docs/core-data-structures/tools.i18n.yaml
#	docs/event-producer-consumer.md
#	docs/persistence-catalog.md
#	examples/acp-agent/tests/snapshots/cordis-inspect-jsdoc/stdout.expected.jsonl
#	examples/acp-agent/tests/snapshots/escalation-approved/session.jsonl
#	examples/acp-agent/tests/snapshots/escalation-rejected/session.jsonl
#	examples/acp-agent/tests/snapshots/fs-escalation-approved/session.jsonl
#	examples/acp-agent/tests/snapshots/hook-cc-pretool-ask/session.jsonl
#	examples/acp-agent/tests/snapshots/permission-switching/session.jsonl
#	examples/acp-agent/tests/snapshots/plan-mode-reject/session.jsonl
#	examples/acp-agent/tests/snapshots/plan-mode/session.jsonl
#	examples/acp-agent/tests/snapshots/session-sandbox-root/session.jsonl
#	packages/context/session-reference/README.md
#	packages/core/agent-loop/tests/agent.spec.ts
#	packages/hooks/hooks-claude/tests/coverage-cases.ts
#	packages/host/runtime/tests/host-runtime.spec.ts
#	packages/llm/llm-retry/tests/retry.spec.ts
#	packages/session-persistence/session-persistence/src/coordinator.ts
#	packages/support/acp-snapshot/README.md
#	packages/support/acp-snapshot/src/normalize.ts
#	packages/ui/acp/acp-feature-support.md
#	packages/ui/acp/src/codec.ts
#	packages/ui/acp/src/index.ts
#	packages/ui/acp/tests/bridge.spec.ts
#	packages/ui/acp/tests/codec.spec.ts
#	packages/ui/acp/tests/config-options.spec.ts
#	packages/ui/acp/tests/dispose.spec.ts
#	packages/ui/acp/tests/edges.spec.ts
#	packages/ui/acp/tests/stream-update.spec.ts
#	packages/ui/acp/tests/turns.spec.ts
2026-07-26 14:05:33 +08:00
Tianyi Cui 06556237f4 fix(tools): close scheduler coverage gaps; regen persistence catalog
The coverage gate flagged three untaken paths in the bridge scheduler:
- the exclusive-head inFlight re-check was dead (the shared guard above
  already returns for an exclusive head with any in-flight sibling) — removed;
- the commit-cursor undefined-dispatched break was structurally unreachable
  once entries join commitQueue only after start() ran synchronously —
  reordered the pump so the invariant holds by construction, annotated;
- the finish (final-result) commit arm and the pump re-entry guard gain a
  covering test (throwing tools/pre-execute listener) and a defensive
  annotation respectively; mid-run unregistration test renamed to match its
  actual post-result settlement path.

Also covers the direct-construction maxParallelSubCalls default (index.ts)
and commits the regenerated persistence catalog for the new dispatch pair.
2026-07-26 13:24:34 +08:00
Tianyi Cui 5bf4d573f7 fix: address review — staged scheduler, start-time reclassification, catalogs
ds-review-bot findings on the parallel bridge: sub-dispatches now run
through the registry's staged scheduler view (the loop's own seam) —
ordered prepare (pre-execute/guards) at submission-ordered start time,
only the dispatch/body stage overlapping, and a head-of-line commit
cursor running post-execute, context deferral, and the settle event in
submission order (new spec pins post order + context order under
out-of-order completion). Queued dispatches reclassify via
executionMode() immediately before starting, so a registry mutation
while queued flips them exclusive (native lazy-reclassification
semantics). Config and tool catalogs regenerated; the tool-catalog
metadata now names the start/settle pair and the scheduling contract.
2026-07-26 10:33:48 +08:00
Tianyi Cui 8a79679489 feat(tools): live dispatch lifecycle + native-contract parallel sub-calls in Code Mode
The bridge replaces its serialization queue with a pool that reuses the
native concurrency contract: submissions classify through
registry.executionMode (fail-closed isConcurrencySafe), start strictly in
submission order, overlap up to the validated maxParallelSubCalls config
(default 10; 1 restores serial), and exclusive calls drain the pool, run
alone, and bar later calls. Each started sub-call logs a
tool/code-dispatch-start event at pool entry; the existing
tool/code-dispatch settles the pair (started ⇔ settles exactly once;
abandoned queued calls log neither). SDK prompt guidance now states the
true Promise.all contract — re-recorded across every code/both-mode
snapshot (plus the stale cordis-dynamic-toolchain fixture gaining the
required description arg).

Client: CodeSubCall widens to RunningToolCall | ToolResultNode — starts
land the running shape (rows wear the native running ring), settles
replace in place preserving start order, callTime pairs to the start
time. Fixture emits start/settle pairs; jsdom pins the running sub-row;
runtime specs pin in-place settlement and out-of-order completion.
2026-07-26 06:02:36 +08:00
Tianyi Cui d60dea9f55 feat(tools): run_code description param + native-parity dispatch logging + web code-mode seam
run_code gains a required bash-style description parameter: presentCall
titles the card with it and moves the program to rawInput, so every
surface gets a readable label. tool/code-dispatch now logs each
sub-call's complete content/isError (the tool/result vocabulary),
replacing the bounded resultSummary and deleting the summarize/cwd
machinery — a UI renders sub-calls through the identical path as native
results. The dsh config tree mounts the worker code runtime and reads
DSH_TOOLS_MODE (temporary seam until per-session mode selection lands).

Session format stays v0 (pre-release churn). Code-mode ACP/TUI fixtures
re-recorded; TUI presenter pin refreshed; catalogs regenerated. Keyless
web smoke pins the code-mode wire contract (tools=[run_code] + SDK
prompt section).
2026-07-26 02:43:34 +08:00
Hypatia May 7cf5b08d07 Merge remote-tracking branch 'origin/master' into session-query-tool
# Conflicts:
#	docs/core-data-structures/persistence.i18n.yaml
#	packages/session-persistence/session-persistence-jsonl/src/index.ts
2026-07-25 15:43:45 +08:00
Hypatia May ddac36e46e Merge remote-tracking branch 'origin/master' into session-query-tool
# Conflicts:
#	docs/architecture.i18n.yaml
#	docs/capability-seams.md
#	examples/acp-agent/composition.md
#	examples/acp-agent/cordis.yml
#	examples/acp-agent/tests/snapshots/model-switching/system-prompt.expected.md
#	examples/acp-agent/tests/snapshots/model-switching/tool-schemas.expected.json
#	examples/acp-agent/tests/snapshots/permission-switching/system-prompt.expected.md
#	examples/acp-agent/tests/snapshots/permission-switching/tool-schemas.expected.json
#	examples/acp-agent/tests/snapshots/plan-mode/system-prompt.expected.md
#	examples/acp-agent/tests/snapshots/plan-mode/tool-schemas.expected.json
#	packages/examples/acp-demo/README.md
#	packages/host/runtime/README.md
#	packages/support/acp-snapshot/src/normalize.ts
#	packages/support/acp-snapshot/tests/normalize.spec.ts
#	packages/ui/acp/tests/harness.ts
#	scripts/type-equiv.manifest.json
#	tsconfig.host.json
2026-07-25 14:17:24 +08:00
Turtle 2e84a1a194 Merge remote-tracking branch 'origin/master' into codex/trim-redundant-comments
# Conflicts:
#	docs/config-catalog.md
#	examples/acp-agent/tests/acp.e2e.ts
#	packages/ui/acp/src/index.ts
#	packages/ui/acp/tests/bridge.spec.ts
#	packages/ui/acp/tests/config-options.spec.ts
#	packages/ui/acp/tests/dispose.spec.ts
#	packages/ui/acp/tests/properties.spec.ts
2026-07-25 13:36:21 +08:00