Commit Graph
81 Commits
Author SHA1 Message Date
Dudu-0223 3dde36b5bb Merge master while preserving subagent lifecycle changes 2026-10-23 15:41:00 +08:00
Dudu-0223 cf072384b5 fix(headless): resume ordinary forks using subagent origin 2026-10-23 14:59:25 +08:00
Dudu-0223 9581e13e78 refactor(subagent): name root wait for tree work 2026-10-22 17:19:33 +08:00
_Kerman a9c006f9c3 refactor(agent): own model selection on each agent 2026-10-20 21:09:09 +08:00
_Kerman c18f5bd3c0 Merge remote-tracking branch 'origin/master' into xtr/session-model-selection
# Conflicts:
#	docs/capability-seams.i18n.yaml
#	docs/capability-seams.md
#	docs/capability-seams.zh.md
#	docs/config-catalog.md
#	docs/config-catalog.zh.md
#	docs/event-producer-consumer.md
#	docs/event-producer-consumer.zh.md
#	docs/module-graph.md
#	docs/module-graph.zh.md
#	docs/persistence-catalog.i18n.yaml
#	docs/persistence-catalog.md
#	docs/persistence-catalog.zh.md
#	docs/persistence-schema.json
#	packages/api/session-controller/src/types.ts
#	packages/bundle/base/package.json
#	packages/bundle/headless/README.i18n.yaml
#	packages/bundle/headless/README.md
#	packages/bundle/headless/README.zh.md
#	packages/bundle/headless/package.json
#	packages/bundle/headless/tsconfig.json
#	packages/subagent/tool-subagent/tests/model-selection-settings.spec.ts
#	scripts/type-equiv.manifest.json
2026-10-19 11:30:55 +08:00
Tianyi Cui 55fddb3424 refactor(auto-review): recognize existing user task sources 2026-10-18 11:44:14 +08:00
Tianyi Cui e0dffac6fa fix(headless): refine Auto policy reporting and fixtures 2026-10-18 11:44:14 +08:00
Tianyi Cui 7181effc69 feat(headless): support unattended experimental Auto review 2026-10-18 11:44:14 +08:00
Tianyi Cui 3ca9c5e623 fix(headless): preserve explicit policy flags in custom profiles 2026-10-18 11:13:48 +08:00
Tianyi Cui cec41e73e0 fix(headless): validate invocation policy across custom profiles 2026-10-18 11:13:48 +08:00
Tianyi Cui 29630d9fa6 feat(headless): support supervised worktree tasks 2026-10-18 11:13:48 +08:00
_Kerman 7b112942ab refactor(agent-model): move Session model selection into its own package
Add @deepseek-ai/dsh-agent-model. It provides ctx.agentModel
(resolveForNextStep, select, applyConfiguredRoute) and owns the
modelSelection projection, which the Agent registry no longer registers.
dsh-agent-loop now injects agentModel; the base and SDK-minimal bundles
and the Python SDK runtime include it.

The provider keeps the projection registered until consumers that are
still unloading finish their cleanup. The model-switch notice becomes an
opt-in per-Agent plugin at @deepseek-ai/dsh-agent-model/notice, and
agent/request now also rejects reasoning-effort changes after step
preparation.

Mount the provider in every composition that loads dsh-agent-loop, and
update consumers, the switch-notice snapshot driver, docs, and the
upgrade guide.
2026-10-16 15:28:59 +08:00
_Kerman 76acba476b fix(headless): retain explicit effort on same-route resume 2026-10-15 20:22:09 +08:00
_Kerman e39b5f58c2 refactor(agent): persist model selection in session state 2026-10-15 19:05:09 +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
Dudu-0223 307c75011b Merge master and reconcile declarative presets with activations 2026-09-21 16:41:53 +08:00
Turtle d1e22a7e24 feat(preset): declare Agent compositions in profile YAML (#4569)
* feat(preset): declare Agent compositions in profile YAML

* fix(preset): share scope binding cleanup and refresh module graph

* fix(preset): use host syntax colors in the YAML editor

* fix(preset): write new profile declarations as block YAML

* fix(preset): align eager activation with browser and worker surfaces

* fix(ui-agent-preset): retain the existing preset card layout

* fix(preset): keep rows waiting for a Host service mounted and re-audit after settlement

A preset row whose Host provider was still activating at declaration time
was reported as waiting for a missing service, and the registry recorded the
definition as broken for the rest of the process. Split the mount audit into
failed and pending rows: failures and root-realm leaks still reject the
mount, while pending rows stay mounted and every read and binding re-audits
them after the Host Loader tree settles.

Remove the accidental self-dependency of @deepseek-ai/dsh-web-app and its
lockfile self-link. Archive the copy-only preset authoring note, which the
declarative-preset note fully supersedes, and update the ralph note's
restore recipe to the profile-patch mechanism.

* chore(lint): re-key and prune the unknown-cast baseline after the master merge

* refactor(web-app): ship each Agent preset as its own bundle patch file

`dsh.bundle.patch` accepts an ordered file list, so the four shipped preset
declarations move out of the 1000-line web patch into
`presets/<id>.patch.yml`, one insert per file, applied after the host patch.
The host patch keeps the preset registry row. Gates and test scaffolds that
read the web layer resolve every patch file through `bundlePatchPaths`
instead of one hardcoded path.

* refactor(preset): drop the save notice injected into live Agents

The notice duplicated the save result the Web editor already shows, and
after the producer-owned message sources it would have needed its own
persisted source kind. Saving now only persists and reports the activation
diagnostic; the persistence catalog is unchanged from master.

* docs: regenerate the module graph after dropping the registry's llm dependency

* test(ui-agent-preset): cover the guide dialog's keyboard handling on the declarative section

* fix(preset): address the remaining review comments

Apply the lowercase id rule only when creating a declaration, so presets
declared with other ids stay editable. Export `isBuiltInPreset` from the
display fold and key the client card groups on it. Remove the dead `error`
and `retry` locale keys, the JSDoc orphaned by the `trust` removal, the
`trust` fields in the plugin-inventory test fixtures, and the stale
`dsh-agent-presets` package name in comments and READMEs.

* refactor(preset): make the Web preset page view-and-select only

Remove the child-plugin YAML editor, the `agent_preset` tool and the
registry's read/save Remote methods. Presets are declared and changed only by
bundle patches; the settings page keeps the roster, the new-task default and
the mode help, and its question icon explains that and offers to start a
Creator-mode task. The `editing-cordis-compositions` skill and the Creator
persona describe the bundle-based path, and the authored skill-load Session
and Web snapshots are refreshed for it.

* docs(skill): make the composition skill self-sufficient for preset authoring

State where the shipped declarations live, list every declaration field,
inline a complete minimal bundle and an override example, and name the
verification calls, so Creator mode no longer reads DSH package sources to
infer the format. Refresh the authored skill-load Session for the new text.

* test(tools): drop the removed agent_preset tool from the catalog expectation
2026-09-21 08:24:18 +00:00
Dudu-0223 a1da7bcfb9 fix(subagent): close settlement delivery gaps 2026-09-21 16:19:07 +08:00
Dudu-0223 6419c0eb21 chore(subagent): integrate latest master and typed test fixtures 2026-09-19 20:44:43 +08:00
Dudu-0223 7e8591de1c refactor(subagent): rebuild activations on master with shared catalog 2026-09-19 20:39:43 +08:00
Tianyi Cui 580bdc7258 refactor: remove redundant unknown casts 2026-09-19 20:13:58 +08:00
_KermanandTianyi Cui f4a32dbd0a refactor(llm): flatten tool results and validate native V4 sessions
Represent tool results as tool-role messages and migrate released wrappers
without losing outer own JSON fields, call identity, error state, or writer
field order. Refuse nested or wrapper-only information that has no lossless
current representation before successor publication.

Validate current event relationships directly instead of projecting V4 data
back into V3. Keep lifecycle, PTC, title/command, compaction, system-field and
retired-syntax checks on catalog restoration and ordinary JSONL opens. The
Worker JSON equality helper must inspect own keys so it cannot admit PTC
arguments that Node rejects.

Keep the source role change, required native admission and consumer fixture
updates in one complete review layer. Explain shared-type changes in the
persistence record and the native reader rationale in its existing note.
Use checked branded fixture identities and discriminant narrowing instead
of unknown double casts; fixture values and assertions remain intact.

This recomposes the original tool-role work by _Kerman with the independently
validated migration and admission repairs by Tianyi Cui. Frozen generations
and snapshot input version selection are retained.

Co-authored-by: Tianyi Cui <[email protected]>
2026-09-18 19:05:32 +08:00
Dudu-0223 3d852a1cea refactor(subagent): unify local and external activation lifecycles 2026-09-17 14:54:10 +08:00
Tianyi Cui caa69608fb refactor(sandbox): await cancellable preparation in process consumers 2026-09-12 15:03:02 +08:00
lsdsjy 71b2cc80aa fix(headless): waive the deferred Session history read
Master's `deprecate-synchronous-session-event-reads` marks `Session.eventAt`
deprecated and rejects new production calls. `liveEvents` predates that decision
and still needs the ordered log to reconstruct the preset a session runs under,
so carry the repository's standard line-scoped waiver for deferred migration.
2026-09-10 19:32:54 +08:00
lsdsjy 79bd986fa7 Merge remote-tracking branch 'origin/master' into HEAD 2026-09-10 19:16:53 +08:00
lsdsjy 3be1ea10b9 refactor(headless): move the runner process hooks out of the package entry
Address the Code Entropy follow-up on d9c4f53758: the runner entry still
expanded its process-substitution object with a `readStdin` hook used only by
tests. Move that seam to `src/runner-internals.ts`, mirroring
`src/startup-internals.ts`, so neither entry grows package API for tests.
2026-09-10 19:13:05 +08:00
lsdsjy 6d05765405 refactor(headless): keep the startup process seam out of the public entry
Address the Code Entropy finding on f67d722243: the `./startup` entry exported
`internals` only so tests could substitute process facts, which added avoidable
package API. Move the seam to `src/startup-internals.ts`, which no package
export names, and have the provider and its tests import it from there.
2026-09-10 17:29:15 +08:00
lsdsjy 9b330b653f docs(headless): correct the adopt-only wording and lockfile attribution
Address the ds-review-bot suggestions on 4099b84ee8:

- The post-resume comment scopes the write lease to other processes, so it no
  longer contradicts the post-idle re-check that defends against a same-process
  overlay writer.
- The Agent Note attributes `pnpm-lock.yaml` to the new
  `@deepseek-ai/dsh-session-query` workspace link instead of the shared chunk,
  which `scripts/check-workspace-constraints.ts` and the manifest publish.
- The package summary keeps "leaves nothing running behind", so it does not
  imply the runner leaves no persisted Session behind.
2026-09-10 16:52:43 +08:00
lsdsjy 31be030ccc fix(headless): keep --json stderr free of commander's error print
Address the ds-review-bot findings on 8724223621:

- The JSON error override throws commander's control-flow error instead of
  delegating to `program.error`, whose own printer wrote an unprefixed
  `error: …` line to stderr and broke the documented `--json` contract.
- Cover the post-idle adoptability re-check with a focused case: an overlay that
  appends a preset while the runner awaits idle is still rejected, and the stale
  "live Session" comment now names that residual writer.
- Scope the Agent Note change sentence to the product change so it no longer
  claims the whole patch is confined to one package.
2026-09-10 16:25:19 +08:00
lsdsjy 9bcb1e214c fix(headless): refuse a live Agent identity and finish the adopt-only docs
Address the ds-review-bot findings on 472554a29e:

- resolveAgent refuses an Agent already live under the requested id: its owner
  may still drive it, and `whenIdle` is not a single-message signal, so the
  one-shot runner cannot own an exclusive run interval over it. The adoptability
  rules still run first so the refusal stays specific.
- Refresh the README intro, identity section, and limitations, and the Agent
  Note live-identity rule and change scope, for adopt-only.
- Clarify the loader-smoke `cwd` JSDoc (the prefix/parent inputs are ignored)
  and pin the resumed wake's final text in the two-wake e2e.
2026-09-10 16:00:53 +08:00
lsdsjy 127d2c8eb5 fix(headless): align the adopt-only docs and prove resume end to end
Address the ds-review-bot findings on 9aea4b0804:

- Drop the stale "freshly created" wording from the resolveAgent `@returns`
  and rewrite its leading comment for the two remaining identity paths.
- Rewrite the README run-flow paragraph (EN and ZH), the intro sentence, and
  the cordis.patch.yml header comment for adopt-only.
- Add a real-composition two-wake e2e: capture the generated id from the first
  `--json` wake, resume it by `--session-id`, and assert one persisted log holds
  both tasks. `runLoaderSmoke` gains an optional caller-owned `cwd` so both
  wakes share one world; the harness leaves that directory in place.
2026-09-10 15:19:17 +08:00
lsdsjy ea84ad31b6 feat(headless): require --session-id to name an existing Session
`--session-id` now adopts only: an id with no stored Session fails before the
task runs instead of creating an empty history the caller believes it is
resuming. A first round omits the flag, and the runtime reports the minted
`session-<uuid>` identity in the opening `session` event, so a supervisor
persists it and names it on every later wake.

Updates the help text, the README pair, the Agent Note pair, the generated
config catalog, the unit suite, and the product-profile e2e.
2026-09-10 14:44:44 +08:00
lsdsjy a69933d3e5 fix(headless): omit step usage when any attempt lacks a sample
Address the ds-review-bot v12 critical on PR #3849: `addUsage` published the
sum of the attempts that reported usage while silently dropping the ones that
did not, so `step_end.usage` looked exact but under-counted billed tokens.
Track completeness per step and omit usage entirely when any attempt in the
step reports no sample, matching `deriveTurnTokenUsage`'s fail-closed rule.
2026-09-09 21:05:19 +08:00
lsdsjy 980b4b77af fix(headless): close the v11 review gaps in the json run surface
Address the ds-review-bot v11 review on PR #3849:

- Accumulate every attempt's usage into `step_end.usage`, including a retried
  attempt whose only sample sits in its discarded `assistant/attempt` stream.
- Re-check the adopted Session after the idle wait, so a preset selected in
  that window is still rejected.
- Reject a whitespace-only `sessionId` supplied through a Cordis overlay, which
  bypasses the CLI trim check.
- Narrow the documented error contract: a profile whose own plugins fail to
  load exits before the runner mounts and keeps only stderr diagnostics.
2026-09-09 20:46:16 +08:00
lsdsjy b3f6c5e991 fix(headless): count the line terminator inside the 32 KiB event cap
Address the ds-review-bot v10 review on PR #3849: `boundJsonLine` bounded the
serialized JSON but not the newline the writer appends, so an event that
serialized to exactly 32 KiB produced a 32 KiB + 1 byte record. Reserve the
terminator byte inside the cap, document the cap as newline-inclusive, and
assert the written record length in the boundary tests.
2026-09-09 20:16:58 +08:00
lsdsjy 755b44bbcd fix(headless): require the query service for every --session-id run
Address the ds-review-bot v9 review on PR #3849:

- Require `sessionQuery` before the live fast path too: a later process has no
  live Agent and must find the id through the query service, so a live identity
  no longer bypasses the check.
- Soften the live `stat` comment to what it proves: a stored record rules out an
  in-memory registration, while write-handle ownership is not queryable.
- Complete the `parseArguments` JSDoc and fix the broken English sentence in
  README.md and the Agent Note.
2026-09-09 19:53:03 +08:00
lsdsjy 7a4a55f30b fix(headless): fail closed on malformed preset records and unroundtrippable args
Address the ds-review-bot v6 review on PR #3849:

- A persisted `agent-preset/selected` record whose `data.agentPreset` is not a
  non-empty string used to read as "no preset", letting the run continue under
  this bundle's composition. It now fails closed.
- A live identity now has to be known to `sessionPersistence` (`stat`), since
  an Agent registered only in memory has no write handle and would flush
  nothing.
- Tool arguments that JSON cannot round-trip (an overflowing number such as
  `1e400`) keep their raw text instead of the `null` JSON.stringify reports.
2026-09-09 19:39:31 +08:00
lsdsjy a5c21a69b8 fix(headless): require persistence for every --session-id path
Address the ds-review-bot v6 review on PR #3849: the guard sat before the
create branch only, so adopting an already-live identity could still run a
session whose history dies at exit. Move it to the top of resolveAgent, where
it covers both the live and the create path, and add a rejection test for the
live path alongside the existing create-path one.
2026-09-09 19:17:01 +08:00
lsdsjy b3756a89d1 fix(headless): fail loud when --session-id would create a non-durable session
Address the ds-review-bot v6 review on PR #3849:

- Require the composed sessionPersistence service before creating an exact
  --session-id identity, so a profile that keeps sessionQuery but drops
  persistence exits 1 instead of printing an id whose history dies at exit.
- Stop exporting the now-internal boundJsonEvent and describe it in the
  present tense; its test now exercises boundJsonLine.
- Say "64 levels or deeper" in the README and Agent Note, matching the
  depth budget (an input keeps 63 nested containers, the 64th is cut).

Tests: 77 headless unit tests with per-file 100% coverage on src, 14 profile
e2e tests, constraints/typecheck/lint/doc/pairing gates.
2026-09-09 19:00:06 +08:00
lsdsjy 3488db77bf fix(headless): cap the bounding recursion depth and route error events through the line cap
Address the ds-review-bot v6 review on PR #3849:

- Cut a projected payload nested deeper than 64 levels instead of recursing
  until the stack overflows; the isolated session listener would otherwise
  drop the `tool_call` silently.
- Write both `error` events (startup usage errors and runner failures) through
  `boundJsonLine`, so the documented 32 KiB line cap covers JSON-escaping
  expansion as well as the 8 KiB message cap.

Tests: 76 headless unit tests with per-file 100% coverage on src, 14 profile
e2e tests, constraints/typecheck/lint/doc/pairing gates.
2026-09-09 18:06:29 +08:00
lsdsjy 0ca42f3b78 fix(headless): bound whole events, re-check adoption after resume, tighten --json scan
Address the ds-review-bot v5/v6 review on PR #3849:

- Register the shared `lib/json-stream-*.js` chunk in `packageFileExtras` and
  order `files` as the workspace-constraints gate requires, so
  `pnpm run constraints` passes.
- Re-validate the preset on the Session `agents.resume` actually attached,
  closing the TOCTOU window between `observeSession` and the write lease.
- Bound one serialized event line at 32 KiB: an over-long event keeps its
  scalar fields, drops structured ones, and at the extreme reduces to `type`.
- Normalize an empty tool-argument string to `{}`, matching the executor.
- Scan only real `--json` flags (stop at `--`, skip a `--session-id` value)
  before installing the JSON error override.

Tests: 74 headless unit tests with per-file 100% coverage on src, 14 profile
e2e tests, constraints/typecheck/lint/doc/pairing gates, tarball import smoke.
2026-09-09 17:40:47 +08:00
lsdsjy 3797127eb2 fix(headless): publish the shared chunk and read the session's current preset
Address the ds-review-bot v6 review on PR #3849:

- Publish the `lib/json-stream-*.js` chunk that both entry points import.
  Without it the installed tarball failed to load with ERR_MODULE_NOT_FOUND,
  because `files` listed only `lib/index.js` and `lib/startup.js`.
- Resolve a Session's preset from its log (`agent-preset/selected`) instead of
  only the immutable creation header, so a Session that switched preset while
  blank is rejected too. Both the persisted and the live path scan the events.
- Write the `--json` error event for Commander grammar rejections (an unknown
  option, a missing option value) as well as the action's own usage errors, and
  drop Commander's `error: ` prefix from the event message so one event type
  carries one message shape.
- Reject a whitespace-only positional instead of falling back to stdin, so an
  accidental blank argument cannot consume a pipe.
- Document the stdin task as verbatim and the widened usage-error contract.

Tests: 68 headless unit tests with per-file 100% coverage on src, 14 profile
e2e tests, plus a packed-tarball import smoke check.
2026-09-09 17:16:09 +08:00
lsdsjy 45032ea1bd fix(headless): address re-review findings on the machine-readable run surface
- Reject adopting a Session recorded under an agent preset, and one that
  recorded no cwd; align the subagent/forked diagnostic wording.
- Write the bounded JSON `error` event for a --json usage error before exit,
  since the runner never mounts to write it.
- Keep the caller's exact --session-id instead of the trimmed value.
- Bound object keys and copy a literal `__proto__` key as data rather than
  through the inherited setter.
- Reject a lone `-` mixed with other task words.
- Document the in-turn failure contract and step-commit text/thinking timing.
2026-09-09 16:58:24 +08:00
lsdsjy ba6e19809d fix(headless): project committed content and scope live adoption 2026-09-09 15:51:23 +08:00
lsdsjy 0e7361a489 test(headless): close per-file coverage on the run projection 2026-09-09 15:19:52 +08:00
lsdsjy d5fe1fb887 docs(headless): regenerate event producer graph and restore model-selection note 2026-09-09 15:17:01 +08:00
lsdsjy ba6a90d2f2 feat(headless): add stdin task, --session-id, and --json run events 2026-09-09 15:12:32 +08:00
_Kerman 37abcb74c5 chore(session): permit existing deprecated history reads 2026-09-09 12:33:53 +08:00
Tianyi Cui f99b06eaed feat(session)!: embed assistant streams in format v2 2026-09-02 04:00:01 +08:00