Commit Graph
21032 Commits
Author SHA1 Message Date
Tianyi Cui ffb88d331e feat(llm): resolve minimum reasoning during call preparation 2026-10-07 14:33:23 +08:00
Tianyi Cui aa514ef8f8 test(llm-pi-ai): cover the floor-effort branch the coverage gate rejected
A reasoning route always declares at least one level, so the adapter's
"no floor" path is defensive; the resolver rejects an empty list before any
consumer sees it. Mark that branch with the repo's v8-ignore convention and
state why.
2026-10-06 18:58:38 +08:00
Tianyi Cui 9e36f20675 refactor(llm): report a route's floor effort and let the caller select it
`purpose` is a label for replay and transport metadata, so no adapter should
branch on one caller's value. Exact-model metadata now reports
`reasoning.floorEffort`, the least effort a route accepts, and the title
service selects it for its request. `llm-pi-ai` and `llm-deepseek` dispatch
the effort they receive and no longer recognize `session-title`; the
`minimizeReasoning` field is gone. A route with no registered adapter, such
as the recorded replay lanes serve, reports no floor, so the title request
keeps the adapter default instead of failing before dispatch.

Replaces the `minimizeReasoning` field from the previous commit.
2026-10-06 18:34:32 +08:00
Tianyi Cui 32a561f3a6 refactor(llm): request minimal reasoning without naming a caller purpose
`purpose` is a provider-neutral label for replay and transport metadata, so
an adapter must not branch on one caller's value. `GenerateOptions` gains
`minimizeReasoning`, which any auxiliary caller sets when reasoning would
consume the output budget it reserved for a short visible result; both
shipped adapters dispatch such a request at the least reasoning the model
supports, and `session-title-llm` sets it instead of relying on the
adapter recognizing `'session-title'`. The pasted type in the subsystem
page and the generated Cordis API catalog follow.

Prompted by review: llm-pi-ai must not know about session-title.
2026-10-06 15:47:09 +08:00
Tianyi Cui 8a199f81eb test(session-title): refresh the settlement expectation on the rebased master
Master changed the same recorded scenario, so its title-request line is
regenerated against the current base.
2026-10-06 15:16:17 +08:00
Tianyi Cui 5ff4172224 test(session-title): identify title requests by their own messages
A request body also carries the session log, whose recorded title event
embeds the framed prompt, so a body-wide marker search matches the main
request too; both mocks now read the request's own messages. The headless
scenarios also assert the dispatched cap, which is the base-bundle ceiling
on the 256000-token route and the route override's 1024 in the pi-ai
compatibility scenario. The extraction cases cover asterisks that are not
emphasis.
2026-10-06 15:12:59 +08:00
Tianyi Cui 791d83bbac docs(session-title): state the title request's real rationale and cap source
The lowest-level dispatch keeps reasoning off the title's output ceiling,
not a small cap's visible text, and it deliberately skips the
requested-effort check. The README pair records that the dispatched cap
is the smaller of the configured ceiling and the latest folded
request/header, including the tighter-main-cap and override consequences,
and the accepted-title comment states the deliberate whole-line emphasis
rule.
2026-10-06 15:12:59 +08:00
Tianyi Cui cd37d51092 test(session-title): record the shipped title prompt in the SDK snapshot
The keyless session-title snapshot replays the first-prompt provider, so
its recorded v4 log carries the exact system prompt of the title
request.
2026-10-06 15:12:58 +08:00
Tianyi Cui 37f53cbd45 test(session-title): follow the shipped 4096-token title cap in CLI and Web expectations
Headless stream-json and session expected outputs record the title
request's maxTokens, and every one of them still recorded the previous
base-bundle cap.
2026-10-06 15:12:58 +08:00
Tianyi Cui a6341ae88b docs(session-title): describe the accepted title and the clamped output cap
The README pair states that an accepted result is the first non-empty
line of the model text, with one wrapping emphasis pair removed, and that
the dispatched cap is the smaller of maxOutputTokens and the cap the
routed adapter declares. The pair is re-recorded with both sides.
2026-10-06 15:12:55 +08:00
Tianyi Cui 34622b0985 test(session-title): follow the shipped 4096-token title cap in CLI and Web markers
The headless and Web mock providers recognize a title request by its
max_tokens, which still assumed the previous 256-token base-bundle cap.
The recorded expected outputs carry that cap too and follow with it.
2026-10-06 15:12:55 +08:00
Tianyi Cui 3562e14f28 fix(session-title): widen the shipped title output cap to a runaway ceiling
The prompt asks for a short title, so the cap only stops runaway output:
reasoning a model cannot switch off also counts as output, and 256 tokens
truncated titles on the HFAI gateway. The measured worst title response
was 153 output tokens, so 4096 is about 25 times the observed maximum.
2026-10-06 15:12:55 +08:00
Tianyi Cui 6ec995d49b fix(session-title): keep the first output line and bound the cap by the request
Claude wraps some titles in asterisk emphasis and writes the title, a
blank line, then an explanation when the messages say little. Joining the
text blocks made that explanation part of the saved title. Take the first
non-empty line, drop one emphasis pair around it, and ask the model for a
short best-effort title instead of an explanation.

The dispatched cap is now the smaller of the configured cap and the cap
the session's current main request recorded, so a route the deployment
capped below the shipped ceiling is never asked for more than that cap.
2026-10-06 15:12:55 +08:00
Tianyi Cui a0c7da0444 docs(llm-pi-ai): describe how a session-title off dispatches; order the level helpers
A session-title request dispatches off exactly as a selected off does,
which on protocols that omit the reasoning field leaves the gateway
default in effect. The README now says so instead of implying reasoning
is always switched off. requestReasoningLevel follows the
resolveReasoningLevel it calls and names when it returns no level, and
the Loader composition helper takes provider config and further entries
as separate parameters.
2026-10-06 15:12:55 +08:00
Tianyi Cui 99d22d5e31 test(session-title): follow the shipped 256-token title cap in CLI and Web expectations
Headless stream-json and session expected outputs record the title
request's maxTokens, and the headless and Web mock providers recognize a
title request by its max_tokens. Both still assumed the previous 64-token
base-bundle cap.
2026-10-06 15:12:55 +08:00
Tianyi Cui 067241ae6c test(session-title): assert the pi-ai title request without untyped matchers 2026-10-06 15:12:49 +08:00
Tianyi Cui fabd805bfe fix(session-title): leave reasoning headroom in the shipped title output cap
The base bundle capped title generation at 64 output tokens, sized for a
route that disables thinking. Models whose reasoning cannot be switched
off spend output on it even at their lowest level: on the HFAI gateway,
GPT-6 Sol and GPT-6 Astra used up to 87 and 121 output tokens for
five-word titles at reasoning low, so Sol still finished with max-tokens
on most first prompts. Raise the shipped cap to 256; routes that disable
thinking stop after the title and are unaffected.
2026-10-06 15:12:48 +08:00
Tianyi Cui 80fd1f0b19 fix(llm-pi-ai): dispatch session-title requests at the lowest reasoning level
Session-title calls carry a 64-token output cap and rely on the adapter to
keep reasoning out of it. llm-deepseek maps purpose 'session-title' to
thinking disabled, but llm-pi-ai ignored the purpose, so pi-ai routes sent
title calls at the route's default effort. On HFAI's adaptive-thinking
Claude models (profile reasoning: max) the thinking consumed the cap, the
call finished with max-tokens, and the session kept its fallback title.

The pi-ai adapter now dispatches a session-title request at the model's
lowest supported level: off when the model offers it, otherwise the
lowest declared level. GenerateOptions.purpose documents that obligation
for every adapter.
2026-10-06 15:12:48 +08:00
Dudu-0223 bf1c4e01ba Merge pull request #4394 from deepseek-harness/refactor/subagent
refactor(subagent): unify activations and reuse parent catalog
2026-10-06 15:08:30 +08:00
Tianyi Cui 1103b0277b fix(session): await natural migration verifier worker exit
A successful verifier message was treated as terminal even though the
Worker Thread was still alive. The parent immediately terminated the
worker and detached cancellation, so an error, nonzero exit, or caller
cancellation after that message could be ignored and verification could
resolve successfully.

Keep the first successful response pending until an observed natural exit
with code 0. A missing response or nonzero exit rejects after the worker
has already exited. Error and abort callbacks retain the existing
terminate-and-join path, including its first-error and AggregateError
behavior. The scheduler stays unchanged: its permit remains held until
the verification promise settles, now after successful worker quiescence.
The worker already closes its parent port in finally, so success needs
neither a forced stop nor another protocol message.

Replace success-termination expectations with deterministic message/exit
barriers and cover post-response errors, nonzero exit, cancellation, and
permit handoff. Remove the obsolete hand-written termination thenable and
its retired unknown-assertion baseline entry. Add real source workers for
plain and Zstandard input, and require the built plain-Node migration smoke
to complete with zero termination calls. Document the settlement condition.

Native Windows CI recorded process access violation 0xC0000005 while a
migration fixture was active. Removing unnecessary successful-worker
termination is consistent with that evidence, but this commit does not
claim that the native faulting module or mechanism has been established.
The deterministic regressions prove the lifecycle defect independently;
the next native CI run must assess whether the observed crash recurs.

Validation:
- Original source failed all new message-to-exit regression scenarios;
  the updated focused lifecycle file passes 19 tests with 100% coverage.
- Node 24 owning package: 19 files, 741 passed, 1 skipped; every included
  package source file reaches 100% statements/branches/functions/lines.
- Real source workers passed for none/zstd; built plain-Node smoke passed
  with zero terminate calls and no timeout or process signal.
- Exact Node 22.19 source-mode none/zstd workers naturally exited 0 with
  zero terminate calls, exercising the async Module.register fallback.
- Host TypeScript build, focused lint, no-new-unknown-assertion gate,
  README translation pairing, and all 42 doc-sync gates passed.

Related to #4387 and #4394.
2026-10-06 11:29:17 +08:00
Tianyi Cui a7798a379d Merge pull request #5717 from deepseek-harness/worktree/client-control/cli-help-reference
feat(cli): generate the CLI help reference and add dsh plugin help
2026-10-06 11:11:26 +08:00
Tianyi Cui a33a0d84c6 test: refresh remaining cwd snapshot expectations
The master cwd integration updated the shipped headless profile, but three
current snapshot scenarios merged without textual conflicts and retained
expectations from before the directory service was composed. Full CI
replay found the stale product-subagent-both persona and missing current
working-directory context in the no-message-tool and structured-parent
parent logs; those two scenarios also owned stale child/header sidecars.

Refresh only those three scenarios through the real built headless profile.
Record the required runtime cwd section in their four parent/child V4
logs, remove static cwd text from three prompt sidecars, and include the
new cwd start parameters and working_directory tool in three schema
sidecars. Preserve every model response and event count. No production
code, scenario input, workspace oracle, or historical V0-V3 fixture changes.

Validation: selective refresh passed 3/3. Full DSH_EXAMPLE_MODE=lib pnpm
run test:snapshot passed all 8 files: 197 passed and 2 PowerShell scenarios
skipped. The first full local run selected macOS CPython 3.9.6 and failed
the two Python PTC scenarios; the final full run prepended the existing
CPython 3.12.13 bin directory to PATH, with no runtime or fixture workaround.
SHA256 guards confirmed all 363 retained historical inputs unchanged;
JSON comparison confirmed the four changed logs differ only by cwd context.
2026-10-06 11:09:17 +08:00
Tianyi Cui e0ca375065 Merge pull request #5418 from deepseek-harness/fix/pwsh-prompt-in-repaint-frame-20260929
test(pwsh): verify prompt readiness after scrolling and restart
2026-10-06 11:04:53 +08:00
Tianyi Cui 8f3959a196 Merge branch 'master' into worktree/client-control/cli-help-reference 2026-10-06 10:59:23 +08:00
Tianyi Cui a3cb678875 Merge master current-directory support into subagent activations
Integrate the observed master checkpoint 7ab215e23e5d977aae7eb5d4fb91782d39969dbb without rewriting the earlier published checkpoints. Master adds current-directory events, directory-aware consumers, and retained Git worktrees; its old subagent startup paths overlapped the unified activation implementation.

Resolve directory selection within managed startup after acquiring parent ownership. Preserve the original Session origin while setting each new local child directory, retain persisted directory state on cold resume, and pass a required absolute cwd to external providers. Keep unified local/external ownership, full completion notices, parked-input host completion, SDK wait/error/shutdown behavior, and ACP cancellation semantics. Retain removal of the old in-process driver and continuation managers.

Combine SDK wait with the new directory requests, preserve the new master directory/worktree fixtures, regenerate derived catalogs from the combined sources, and refresh only the four stale prompt/schema sidecars. Preserve every protected historical schema, archived note, catalog-v2 acknowledgement, and recorded predecessor input.

Validation: full build; 59 CI static gates; 855 subagent tests with 100% coverage on changed core/external sources; affected consumer suites including 119 repaired-fixture tests; SDK 11 and headless 16 recorded scenarios; two local headless expected cases; six built nested SDK/ACP cases; lint, strict cast inventory, workspace constraints, and whitespace checks. Native Windows worker diagnostics remain additive and require the next CI run to classify the original crash.
2026-10-06 10:52:35 +08:00
Tianyi Cui 13b4f716e7 test(pwsh): verify prompt readiness after scrolling and restart 2026-10-06 10:41:16 +08:00
Tianyi Cui 9a93c1f0dd Merge pull request #5781 from deepseek-harness/worktree/fix-claude-mods-windows-hold
fix(claude-code-mods): make Blast Radius holds independent of POSIX sleep
2026-10-06 10:34:24 +08:00
Tianyi Cui c042d32d21 Merge pull request #5363 from deepseek-harness/fix/pty-bundled-openconsole
fix(subprocess): back Windows terminals with node-pty's bundled console host
2026-10-06 10:30:24 +08:00
Tianyi Cui cbcbbf8825 fix(claude-code-mods): make Blast Radius holds independent of sleep 2026-10-06 10:20:25 +08:00
Tianyi Cui 6f566013b9 Merge pull request #5742 from deepseek-harness/worktree/working-directory/worktree-checkout-safety
fix(worktree): isolate checkout from Git filters and inherited selectors
2026-10-06 10:18:05 +08:00
Tianyi CuiandChinesezjc 9bc34fa962 ci: reuse reviewed coverage fork exit diagnostics
Repeated native Windows coverage runs stopped a Vitest fork while a JSONL
migration suite was unfinished. Vitest's generic unexpected-exit error
discarded the process exit code and signal, preventing classification of
the failure despite identifying the missing test file from the inventory.

Reuse the public ForksPoolWorker diagnostic implementation and protocol
fixtures from independently reviewed PR #4388, pinned at
77e215ff76711ec75ed8aa08aa5b414780e539ae. The runtime helper is unchanged.
It reports PID, project, worker identity, outstanding file request, code,
and signal before stock Vitest reports the original failure. It clears
ownership only on the typed testfileFinished response, suppresses expected
stop, and leaves cancellation and failure handling with the original pool.

Wire that existing pool into generated coverage partition configs. Keep
the original worker counts, partition scheduling, test timeouts, coverage
thresholds, and failure verdicts. No environment, raw argv, or test object
is serialized. This commit adds diagnostic evidence; it does not claim to
repair the still-unidentified Windows crash. PR #4388 remains the separate
reviewable owner; no duplicate diagnostic framework or PR is introduced.

Adapt the copied fixtures to the current no-new-unknown-assertions rule:
declare the private preload exit function, validate consumed logger fields
with the public logger type, and assign matcher/rejection values to typed
unknown locals without assertions. Add a concise bilingual testing note.

Validation:
- Diagnostic suite: 10 passed, including a real configured Vitest fork
  exiting 23, stock-pool negative control, successful silent shutdown,
  unexpected exit 0, early exit, independent forks, and signal metadata.
- Coverage coordinator suite: 51 passed.
- Targeted lint and focused strict TypeScript check passed.
- pnpm exec tsc -b tsconfig.host.json passed.
- verify-no-unknown-casts passed; 1430 existing assertions unchanged.
- doc-sync passed 40 gates; the two initially failing gates were repaired
  and rerun successfully: doc-typecheck and verify-doc-budgets.
- Translation pairing and git diff --check passed.

Refs #4387, #4388, #4394.

Co-authored-by: Chinesezjc <[email protected]>
2026-10-06 10:17:44 +08:00
Tianyi Cui acf7949db0 test(sdk): replace the cast context with typed runtime services
The cwd regression used a fake Context cast through unknown. Updating its service lookup for descendant shutdown changed the exact legacy assertion fingerprint, which the no-new-unknown-casts CI gate correctly rejected.

Exercise initialize, prompt, and wait with the real Context, Agent registry, Session store, and a scripted LLM adapter. Spy on the real service methods to keep the cwd, reasoning effort, and token-limit assertions. Remove both obsolete unknown assertions and prune only their recorded allowances; do not add or broaden an exception.

Validation: the cwd regression passes; all 54 SDK server tests pass with 100% server coverage. The full check:ci:static aggregate passes 59/59, including the strict unknown-cast inventory. No production behavior changes.
2026-10-06 03:23:56 +08:00
Tianyi Cui c729eb3bc6 test(subagent): preserve the flush result in the failure fixture
The gated final-flush fixture awaited the real flush but dropped its boolean return value. The regression ran correctly under Vitest, but the full Host build rejected the mock against Sessions.flush Promise<boolean>.

Return the real flush result after the gate. This retains the observation order and matches the service signature without a cast or altered production behavior.

Validation: targeted terminal-capture-failure regression passes; the complete build is rerun after this typing correction.
2026-10-06 03:09:06 +08:00
Tianyi Cui d69442b408 fix(sdk): drain descendants before releasing session roots
SDK shutdown disposed its root Agent handles without stopping managed
Activations below those exact roots. The manager owns descendant handles
in a separate context, so an interrupted child with parked input remained
registered after shutdown resolved. Its settlement watcher could then
outlive the SDK root and race later projection teardown.

Close scoped descendant admission and await child-first drain before
releasing root handles or the server adapter. Keep draining limited to the
server's exact root Agents so unrelated parent trees remain live. Collect
drain failures without skipping the existing root/adapter teardown, and
preserve the final single-error or aggregate-error result.

Add real AgentLoop/SubagentRuntime regressions for parked children at
one and two levels, child-first disposal, preservation of an unrelated
parked tree, and descendant/root teardown failure aggregation. Correct an
existing Context.get test stub to return its LLM only for the LLM service.
Document the lifecycle order in the server JSDoc and bilingual README.

Validation: 52 SDK server tests with 100% server.ts statements, branches,
functions, and lines; four final shutdown regressions; host TypeScript
build; full lint; 21 quick documentation checks; staged pairing/diff checks.
Doc-sync passed 41/42 checks; the pre-existing config catalog source link
for subagent-acp/index.ts is stale at base and left to integration refresh.
2026-10-06 03:07:45 +08:00
Tianyi Cui b730d6c0c9 fix(subagent): let parked inboxes stop delaying host completion
Interrupting a local child can preserve unclaimed steering while leaving the Agent idle. Activation residency intentionally continues in that state, but completion barriers joined its result forever. The real SDK server reproduced the hang for both direct children and a nested parked leaf.

Join progressing work and cleanup while retaining parked inboxes and their activation results. Observe local activity and maintenance, external execution, unpublished ownership holds, and materialization; rescan after changes. Recheck resumed Agents after concurrent idle observations. Inbox insertion and ownership publication wake pending observations, so late non-waking injection cannot strand a result wait. Existing descendants remain responsible for their own work; no second state store or polling timer is introduced.

Document that persistent SDK/ACP hosts keep these children available for later wake-up, while headless shutdown discards unclaimed input. Simplify the final settlement recheck to retry changed readiness uniformly. Update generated API and event references from their sources.

Validation: real SDK negative controls fail at both depths on the prior manager with clean teardown; 545 tests pass across 27 files. Manager, local activation, and headless runner each reach 100% statements/branches/functions/lines. Six deterministic races cover revival, preparation publication/rollback, flush-time injection, and late children. doc-sync 42/42, targeted build, lint, and whitespace checks pass.
2026-10-06 03:07:24 +08:00
Tianyi Cui 9b1fc3be05 docs(subagent-acp): refresh the generated configuration source link
Removing the duplicate ACP directory helpers moved its Config declaration by one line. The generated English and Chinese catalogs still referenced the old line, so the exact-source freshness gate rejected the otherwise unchanged configuration.

Regenerate only the affected source links. No configuration fields, defaults, examples, or translated prose change.

Validation: pnpm run gen-config-catalog produced exactly these two link updates; the combined doc-sync run verifies freshness.
2026-10-06 03:06:34 +08:00
Tianyi Cui b023791481 fix(headless): retain live failures without a later terminal
A child completion can wake the parent after its first completed turn. If
that summary cannot append turn/start or turn/end, AgentLoop reports an
agent/error and contains the rejected driver. Whole-agent idleness then
resolves, but the headless runner previously reused the older completed
terminal and exited successfully, sometimes printing the older answer.

Retain failures from the exact owned Agent with the current Session log
offset. Only a later terminal committed by the same Session clears that
failure. After work and persistence drain, fail the run before emitting a
final answer when no such terminal exists. Dispose both observers with
the run. Ordinary durable error outcomes and later successful recovery
continue to use the log's final terminal.

Add real AgentLoop regressions for missing summary start/end commits in
plain and JSON output, ordinary hook failures with and without recovery,
recovery after persistence failures, and unrelated Agent errors. Update
the bilingual exit contract and generated event consumer matrix.

Validation: 106 headless package tests; 100% runner statements, branches,
functions, and lines; 9 focused terminal-failure tests after the typed
append wrapper correction; package TypeScript build; full lint including
host build; 21 quick documentation checks; 42 doc-sync checks; diff check.
2026-10-06 02:53:04 +08:00
Tianyi Cui 1dbbc59d3e fix(subagent): retain local failures without a durable ending
Local activation results were derived only from committed Session events.
When the first turn/end append failed, no ending existed and the result
defaulted to completed. When the first turn/start append failed, the initial
message remained unclaimed and kept the idle activation resident forever.
Both paths emitted agent/error but had no durable terminal to project.

Retain the log offset of the latest exact-Agent live failure on the local
activation. Clear it only when the same Session commits a turn/end at or
after that offset, so a later recovery can supply its own outcome and a
reentrant older terminal notification cannot erase a newer failure. The
child scope owns both observers and removes them with its Agent handle.

Capture error while that live failure remains. Let the failed local
activation settle despite its own unclaimed inbox, while preserving the
existing requirement to wait for owned descendants. Wake its settlement
observer when a live failure changes readiness. No public API, raw Agent
idle semantics, or descendant teardown policy changes.

Add regressions through real local activation creation for first start/end
append failures, recovery by later durable endings, exact-Agent isolation,
and an error emitted reentrantly during an older terminal notification.
Update the bilingual package contract and generated event consumer graph.

Validation:
- Both first-append regressions reproduced before the fix: turn/start
  remained pending; turn/end returned completed instead of error.
- Six focused behavior cases passed after the fix.
- 423 subagent package tests passed; activation.ts and manager.ts reached
  100% statements, branches, functions, and lines under scoped coverage.
- pnpm exec tsc -b packages/subagent/subagent/tsconfig.json passed.
- Focused source/test oxlint and git diff --check passed.
- doc-sync passed 41 gates; its sole stale event-graph failure was corrected
  with gen-doc-graphs, then verify-doc-graphs passed for all seven graphs.
- README translation pairing regenerated and passed the doc-sync check.
2026-10-06 02:46:21 +08:00
Tianyi Cui 5b9dd96963 docs(workflow): clarify local child continuation requirements
Caller delivery changes result ownership, but does not make local workflow children private or remove their continuable catalog entries. The workflow README stated durable discovery without making the message and cold-resume consequences explicit.

Document that resident workflow children accept continuation and that cold continuation requires persistence and Session query. An ephemeral child therefore returns NOT_RESUMABLE after disposal. This describes current supported behavior and does not add fallback storage or a new child mode.

Validation: checked against startActivation, sendMessage, and cold-resume admission; English and Chinese pairing updated. Full doc-sync follows the combined review fixes.
2026-10-06 02:44:37 +08:00
Tianyi Cui 4c8cb2fac6 refactor(subagent-acp): reuse shared working directory resolution
ACP retained a private copy of the external-provider directory helpers after the other providers adopted the shared implementation. The copies differed on absolute-path validation and imposed separate filesystem branches and maintenance.

Use resolveChildCwd and validateConfiguredCwd from the existing subagent package. Preserve configuration-time relative-path resolution, parent workspace inheritance, missing-directory failures, and ACP diagnostic normalization. This deletes the duplicate directory implementation without introducing an abstraction or dependency.

Validation: 85 passing tests across the ACP provider and shared out-of-process helper suites, including real child process cwd, configured overrides, and invalid-directory rejection.
2026-10-06 02:44:10 +08:00
Tianyi Cui 0963845443 test(headless): expect complete child settlement notices
Parent completion notices now always carry the child closing answer, even when the child can send progress messages. Two assembled headless expectations still asserted the removed omission and made the snapshots-and-artifacts CI lane fail.

Require CHILD_RESULT in the settlement assertion and refresh only the owning parent and stream output expectations. Preserve released replay inputs, event ordering, sandbox denial evidence, and the recorded model responses.

Validation: DSH_EXAMPLE_MODE=lib pnpm run test:expected apps/cli/tests/profiles/headless/tests/headless.expected.e2e.ts apps/cli/tests/profiles/headless/tests/subagent-inheritance.expected.e2e.ts (18 passed).
2026-10-06 02:43:31 +08:00
Tianyi Cui 1595e34656 docs(subagent): distinguish execution results from cleanup failure signals
The subsystem result paragraph still said that a parent log records the
final cleanup-failure status and that the result had already been returned.
The manager instead captures the execution result, performs cleanup, sends
that preserved result in the parent notice, and then resolves the public
result. Cleanup failure separately rejects dispose and marks the live
subagent/end event as error.

Correct the bilingual paragraph to name those actual recipients and timing.
Do not imply that the successful execution notice becomes a failed notice,
or change the runtime's independent execution/cleanup outcomes.

Validation: the updated bilingual pair passes. The statement is checked
against finishDisposal/notifySettlement and the existing cleanup-failure
regressions; final documentation gates run before publication.
2026-10-06 02:06:05 +08:00
Tianyi Cui 813c7d2ef8 test(acp): honor the asynchronous content fixture contract
The initial-cancellation regression supplied a synchronous content array to
defineContentToolFixture, whose executor contract requires a Promise of
content blocks. Vitest executes the fixture, but the strict repository
Host build correctly rejects its signature with TS2739.

Return the same blocks through Promise.resolve. Keep the deterministic
stream/output gates and assertions unchanged; do not widen the shared
fixture API merely to accept this one caller.

Validation: the focused initial-cancellation regression passes. The full
Host build is rerun before publication to validate the fixture signature.
2026-10-06 02:00:43 +08:00
Tianyi Cui cbf618845a fix(acp): bind cancellation to the interrupted root activity
Cancelling during the prompt's initial whenIdle() wait could retain its
slot indefinitely. If a child delivered a result while the aborted root
was unwinding, Agent.whenIdle() followed the replacement driver and waited
for the newly autonomous summary. The earlier child-wait recheck could
not help because settlement had not yet reached that child wait.

This is an inherited latent issue: the pre-PR ACP bridge also awaited the
same replacement-following whenIdle() after cancellation. Existing
continuable spawn children could expose it; the unified asynchronous fork
default makes the ordering possible for fork delegations as well.

Give the existing InflightPrompt one cancellation-completion promise,
replacing the local cancellation wake-up and its listener. The private
admission AbortSignal is the cancellation flag instead of duplicated
boolean state. The exact root's emitted status identifies the interrupted
activity's retirement and synchronously adopts that output queue. Later
root work and later output cannot replace the first captured completion.

Record whether cancellation began at public idle. Maintenance has that
public status too, so its next running transition establishes release of
work behind maintenance; the ordinary whenIdle promise provides a
fallback when no transition occurs or plugin disposal detaches observers.
Both observations settle the same promise. Settlement races that promise
against initial idle and child waits, then waits only for the interrupted
activity/output on the cancellation path. No future work is re-cancelled,
child admission remains open, and session close keeps its separate full
quiescence and descendant teardown.

Add two deterministic real-Agent regressions. One gates aborted model
cleanup, previously queued image delivery, and the later autonomous
summary independently. The other gates cancelled maintenance cleanup and
the later summary. Both failed before this fix; both now wait for old work
and output, return cancelled while later work remains gated, and permit a
subsequent ACP prompt to execute another real local delegation. Existing
plugin-disposal tests also verify the idle fallback after observer cutoff.
Update the bilingual ACP semantics and generated event-consumer matrix.

Validation:
- Both focused regressions reproduced pending cancellation before the fix.
- pnpm exec vitest run packages/acp/acp/tests --coverage --coverage.include=packages/acp/acp/src/session.ts --coverage.include=packages/acp/acp/src/index.ts --coverage.reportsDirectory=/tmp/pr4394-acp-owned-cancel-89ec33e5788-consumer-v2
  (150 passed; both changed source files have 100% statements, branches,
  functions, and lines)
- pnpm exec tsc -b packages/acp/acp/tsconfig.json
- pnpm exec tsdown --config-loader native --env.DSH_BUILD_FACE host --filter '@deepseek-ai/dsh-acp'
- DSH_EXAMPLE_MODE=lib pnpm run test:e2e packages/subagent/subagent-dsh-sdk/tests/nested-delegation.e2e.ts -t '^external tasks.*acp'
  (3 passed, 3 unselected)
- Focused lint, named translation pairing, generated graph verification,
  and git diff --check passed.

Independent ACP rereview found no remaining issue, passed seven focused
turn/disposal cases, and verified a prepended idle listener can start a
new hanging root before ACP handles the old idle event without retaining
the cancelled prompt.
2026-10-06 01:55:26 +08:00
Tianyi Cui cfad6ba882 fix(worktrees): isolate inherited attributes and clarify Git content 2026-10-06 01:39:48 +08:00
Tianyi Cui c7e4da483b test(worktrees): replay configured checkout filters 2026-10-06 01:39:48 +08:00
Tianyi Cui 2b6040c40c fix(worktrees): suppress configured checkout filters 2026-10-06 01:39:48 +08:00
Tianyi Cui a1e89dd84d test(gui): include worktrees in official plugin configuration 2026-10-06 01:39:47 +08:00
Tianyi Cui 2481ad8eb6 docs(worktree): keep the capability seam translation paired 2026-10-06 01:39:47 +08:00
Tianyi Cui a1363f7f47 fix(worktree): offer GUI opt-in through official plugins 2026-10-06 01:39:47 +08:00