Commit Graph

1471 Commits

Author SHA1 Message Date
Yichen Jiang
a7eab2867a Merge remote-tracking branch 'origin/master' into worktree/preset-plane-fallout-p1
`minimal` was rewritten upstream into a fixed-prompt PTY surface that now
carries its own compaction group, so this branch's token-meter move applies to
it too: the row leaves the group and `tokenMeter` leaves the realm, exactly as
in the other three presets. Master's header prose is kept whole — the note this
branch had added there described a composition that no longer exists.

`docs/event-producer-consumer.*` is generated; regenerated after the merge.
2026-08-10 23:50:28 +08:00
Turtle
09e2d2ddc1 refactor(cmdline): make command providers ordinary 2026-08-10 23:45:05 +08:00
Turtle
d4ccfbd80f refactor(cli)!: complete app-owned profile startup 2026-08-10 23:45:04 +08:00
Turtle
b692f38506 refactor(cli): discover app startup rows from injection 2026-08-10 23:45:04 +08:00
Turtle
37cbd155f5 refactor(cli)!: the launcher parses only its own flags
Launcher flags come first and end at the first token dsh does not
recognize; everything after reaches the booted app verbatim, so
dsh --profile tui --resume <id> works with no launcher change and
dsh --profile web --help prints the web app's help. A bare dsh -h, which
has no app to hand the flag to, still prints the launcher's own.

src/web.ts is deleted: the Web flag family, its LAN-trust sampling, and the
one-shot task positional now live in their bundles, and runProfile no
longer knows any row id. What the startup row decides comes back as a
launcher-owned patch layer above every layer a user can edit, so a live
config edit recomposes the tree without resetting a served port.

dsh web and dsh --profile web finally boot through one path, which also
gives --profile web the harness-source prompt section that only the alias
used to add.
2026-08-10 23:45:04 +08:00
Turtle
82728808d4 feat(bundle): the web and one-shot apps own their own flags
dsh-web-app owns --host/--port/--dev/--workspace-root/--trusted-host and
its --help in a web-startup row; the rows it configures wait for the
webStartup service, and the client-plugin HMR receiver now ships disabled
so --dev is a row toggle rather than a runtime insert (the Loader cannot
resolve a row inserted from inside a mounting plugin).

dsh-headless owns the task positional and rejects a missing task as its own
usage error. Its runner ships disabled, not merely waiting: the schema
requires the task, and a row's config is validated when its fiber is
created, before the startup row can supply one. A composition has exactly
one command-line owner, so the patch disables the web startup row and this
one provides webStartup too, leaving the web rows on their composed
one-shot values.

The keyless web scaffold provides the same three values with no arguments,
which is what an embedding host with no command line does.
2026-08-10 23:45:04 +08:00
Turtle
788368e314 feat(cmdline): hand the launcher's remaining arguments to the app it boots
A launcher provides three values before the tree mounts: ctx.cmdlineArgs
(get() is the whole interface) carrying everything after its own flags,
ctx.appExit for a bounded exit, and ctx.appPatches for decisions a later
recomposition must keep. An app's startup row injects cmdlineArgs and calls
runStartup() with its own commander program.

Rows the app configures inject its startup service, so they wait until the
startup row has resolved their values and provided it; --help prints,
disables those rows, and exits without the app ever starting.

A changed row is recycled — disabled, then re-enabled with its new values —
because a row's config is resolved when the Loader creates its fiber, while
the row is still waiting. Recycling never touches inject: an inject update
restarts the row from its unwrapped callback and loses the plugin's own
static injections. A mount still in flight is allowed to settle first, so
the disable has a fiber to dispose instead of racing one into existence.
2026-08-10 23:45:04 +08:00
Tianyi Cui
bdc9bbdf9d Merge origin/master into feat/mcp-auto-reconnect
Integrate master at 8b4ef532 before addressing review feedback so each bot issue remains isolated in its own descendant commit. Resolve the vendor package rescope by moving the PR's new MCP supervisor imports to @deepseek-ai/cordis and @deepseek-ai/schemastery, preserve the reconnect implementation and e2e coverage, and regenerate the merged config and module catalogs with fresh bilingual pairing records.
2026-08-10 23:44:58 +08:00
pku-xht
396925ad4c Merge pull request #2137 from deepseek-harness/codex/product-subagent-presets
feat(agent-presets): add Codex and Claude Code subagent tools
2026-08-10 23:43:23 +08:00
Yichen Jiang
0b42259b82 Merge origin/master into worktree/web-plugin-config
Resolves the vendored-package rescope (cordis -> @deepseek-ai/cordis,
schemastery -> @deepseek-ai/schemastery) against this branch's settings
namespaces: the bash capability namespace, its two executors' section
installs, and the new plugin-config client package all move to the scoped
specifiers.
2026-08-10 23:13:11 +08:00
Yichen Jiang
fe221be572 Merge remote-tracking branch 'origin/master' into worktree/preset-plane-fallout-p1
The vendored Cordis rescope (`cordis` -> `@deepseek-ai/cordis`,
`@cordisjs/plugin-*` -> `@deepseek-ai/cordis-plugin-*`) collided with this
branch's two added edges. Resolved by taking master's package names and
keeping this branch's additions: `@deepseek-ai/dsh-agent` and
`@deepseek-ai/dsh-system-prompt` peers, the `scopeChainOf` import, and the
`agent/created` type-only edge.

`docs/event-producer-consumer.*` is generated; regenerated after the merge
rather than hand-resolved.
2026-08-10 23:00:23 +08:00
Yichen Jiang
2e59ff5ef0 Merge remote-tracking branch 'origin/master' into worktree/fix-minimal-preset-prompt
# Conflicts:
#	docs/event-producer-consumer.i18n.yaml
#	docs/event-producer-consumer.md
#	docs/event-producer-consumer.zh.md
2026-08-10 22:49:25 +08:00
Yichen Jiang
a7e8805340 fix(packaging): materialize runtime dependencies 2026-08-10 22:47:18 +08:00
Yichen Jiang
1cfbafab6a fix(preset): keep the token meter host-plane and name unjoined agents
Moving the agent plane behind presets left two readers on the wrong side of
the host/agent line.

`dsh-token-meter` was disabled on the host and mounted inside each preset's
`compaction` realm, but its three projection units register into the
process-wide `sessionProjections` table. A unit registered from one preset
answers for every session, so whether a `minimal` session showed a context
meter depended on whether some other session had mounted `standard` since
boot, and a process that only ever ran `minimal` showed none. The meter takes
no configuration, keys every fold by Session, and registers no tool or prompt
section, so it returns to the host composition and leaves the presets'
`isolate` map; the realm and `compact-basic` stay, because what a preset
chooses is whether its agent compacts, not whether its tokens are counted.

Nothing named an agent that joined no preset. The join is a scope-parent link,
and without it the tools, prompt-section, and skill views resolve the empty
global layer: the agent publishes, the turn runs, and the model receives
nothing. `AgentPresets` now logs one warning per such agent while a roster is
configured, and the invariant companion fails outright — at
`system-prompt/assemble` rather than at publication, because an unjoined agent
is legal until it addresses a model and `recompose` binds exactly such an
agent. The warning stays advisory: a synchronous `agent/created` throw vetoes
publication, and the ACP bridge, SDK server, and headless bundle all create an
unjoined agent today.

Three limits are recorded rather than fixed: projection key presence is not a
per-session capability signal, a superseded standing generation is never
reclaimed, and a `cordis_mount` temporary plugin belongs to the composition
rather than the session that mounted it.

Fixes #2203
2026-08-10 22:36:06 +08:00
Yichen Jiang
75f4434787 fix(packaging): close rescoped runtime deploy 2026-08-10 22:27:34 +08:00
Hypatia May
29c00d59a5 Merge remote-tracking branch 'origin/master' into fix/continuable-subagent-policy-inheritance
# Conflicts:
#	packages/subagent/subagent-inprocess/package.json
#	packages/subagent/subagent/package.json
#	pnpm-lock.yaml
2026-08-10 22:24:56 +08:00
pku-xht
c3362d0e60 Merge master at f4c0ba1489 2026-08-10 22:20:59 +08:00
Yichen Jiang
b87a3b1baf Merge remote-tracking branch 'origin/master' into worktree/fix-minimal-preset-prompt 2026-08-10 22:18:22 +08:00
Yichen Jiang
a4e679853f Merge remote-tracking branch 'origin/master' into worktree/fix-minimal-preset-prompt 2026-08-10 22:15:30 +08:00
imccyu
ec601ca13d build(vendor): rescope the vendored Cordis packages into @deepseek-ai
Machine-produced by `pnpm run rescope-vendor --apply` plus the regeneration it
prints: `pnpm install` for the lockfile, `pnpm run gen-third-party-notices`,
`verify-translation-pairing --write` for the touched bilingual pairs,
`gen-doc-graphs`, and one typert snapshot whose ids embed character offsets.
`pnpm run rescope-vendor --check` verifies the result.

Renames nine vendored packages (cordis, cosmokit, schemastery and the six
@cordisjs plugins) and every reference that resolves them: manifest names and
dependency keys, module specifiers including declare-module merges, cordis.yml
plugin names, tsconfig paths, every Markdown fence, and `docs/` prose.
Directory names, upstream versions, and dependency ranges are unchanged, so
vendor/README.md still reads as an upstream snapshot; its manifest table gains
an upstream-name column so THIRD_PARTY_NOTICES keeps MIT attribution pointed
at each fork's origin.

The tutorial tier follows the rename end to end: its yaml fences named plugins
the Loader can no longer resolve, its `ts ignore-check` fences disagreed with
the compiled fences beside them, and its prose quoted both. The contracts that
told readers to keep upstream names — the root convention and the vendoring
cookbook's tree comment and manifest invariant — now say to rescope instead.

Two rules read `@deepseek-ai/` as "another workspace plugin": the client bundle
purity gate now names the vendored libraries a browser bundle inlines, and the
files where a bare `cordis` is an agent-preset id keep that product data.
2026-08-10 22:04:13 +08:00
Hypatia May
76061417d9 Merge remote-tracking branch 'origin/master' into fix/continuable-subagent-policy-inheritance
# Conflicts:
#	examples/acp-agent/tests/snapshots/advanced-toolchain/session.1.jsonl
#	examples/acp-agent/tests/snapshots/advanced-toolchain/session.2.jsonl
#	examples/acp-agent/tests/snapshots/advanced-toolchain/session.jsonl
#	examples/headless-agent/tests/snapshots/advanced-toolchain/session.1.jsonl
#	examples/headless-agent/tests/snapshots/advanced-toolchain/session.2.jsonl
#	examples/headless-agent/tests/snapshots/advanced-toolchain/session.jsonl
2026-08-10 22:02:36 +08:00
pku-xht
9a2799e941 Merge master at 261989e36e 2026-08-10 21:55:57 +08:00
Hypatia May
2b2899b4ce Merge remote-tracking branch 'origin/master' into fix/continuable-subagent-policy-inheritance
# Conflicts:
#	docs/module-graph.i18n.yaml
#	docs/module-graph.md
#	docs/module-graph.zh.md
#	packages/subagent/subagent-inprocess/src/index.ts
#	packages/subagent/subagent/package.json
#	packages/subagent/subagent/src/child-agent.ts
#	packages/subagent/subagent/src/continuation.ts
#	packages/subagent/subagent/tsconfig.json
2026-08-10 21:42:45 +08:00
Turtle
993550e6c8 refactor: remove repository plugin path 2026-08-10 21:32:13 +08:00
Yichen Jiang
dae6cad065 fix(web): show the plugin settings a user actually gets
Three things the page got wrong.

The web-search provider's defaults lived only at their use site, so the
served section carried no value for them and the card fell back to a zero it
invented — a number the schema itself rejects. Declaring them on the schema
makes the settings service the one authority: `maxUses` now reads 5 because
that is what the Host resolves, not because the page guessed. `baseURL` keeps
its code-side default, which exists so `$DEEPSEEK_SEARCH_BASE_URL` can win.

A field the Host serves no value for now renders empty rather than as zero.

The cards were rows in a settings page of cards: name and description ran
together on one line because the shared disclosure row lays them side by side.
Each card now draws its own header, stacking the two, and the section follows
the idiom the Agent Preset page established.
2026-08-10 21:29:45 +08:00
pku-xht
791d0b7233 Merge commit '0b307c4ea80ba603dee91b46731e4d14644d84d2' into codex/workflow-runs-chat-node-f6 2026-08-10 21:08:32 +08:00
pku-xht
8d88edb880 Merge commit '0b307c4ea80ba603dee91b46731e4d14644d84d2' into codex/product-subagent-presets 2026-08-10 21:07:22 +08:00
Yichen Jiang
7175ba3d5e Merge remote-tracking branch 'origin/master' into worktree/fix-minimal-preset-prompt 2026-08-10 21:06:25 +08:00
Yichen Jiang
4481637684 fix(python): package the minimal runtime closure 2026-08-10 20:55:02 +08:00
Yichen Jiang
6301320a63 Merge remote-tracking branch 'origin/master' into worktree/subagent-missing-tools-fb2359 2026-08-10 20:32:58 +08:00
lintianle
517449d85f Merge remote-tracking branch 'origin/master' into feat/mcp-auto-reconnect 2026-08-10 20:28:46 +08:00
pku-xht
e6b6f1a047 Merge master at 35eeb4a112 2026-08-10 20:25:58 +08:00
lintianle
00f68d7e93 feat(mcp-client): auto-reconnect with bounded backoff after transport close
A per-instance connection supervisor restarts the original server config
with exponential backoff when the transport closes, re-runs tool discovery
on success, and atomically replaces the previous generation. Default policy
retries for ~2.5 minutes (10 attempts, 500ms→30s doubling) before giving up
and unregistering the server's tools.

New config block reconnect { enabled, initialDelayMs, maxDelayMs, maxAttempts }
on both transports; misconfiguration fails plugin load. A connection that
survives past the stability window (maxDelayMs) resets the attempt budget,
so occasional crashes recover indefinitely while a crash loop still exhausts
the cap.

Integrates with the upstream failOnStartupError: the initial sync uses
registrationFailure:'throw' when that flag is set so a squatted namespace
still rejects activation.

Fixes #1746
2026-08-10 20:10:54 +08:00
_Kerman
9b96a1380b Merge remote-tracking branch 'origin/master' into feat/web-session-log-export 2026-08-10 20:02:24 +08:00
_Kerman
2a34ca51a3 test(web): assembled session-log download e2e and refreshed golden
The navigation-panes replay scenario clicks the trajectory toolbar export
button and asserts the real host-streamed download: filename, a single
session.jsonl entry, and byte-verbatim seed content. The toolbar golden
refreshes for the localized export button.
2026-08-10 19:50:32 +08:00
Hypatia May
9e40fc7f6b Merge remote-tracking branch 'origin/master' into fix/continuable-subagent-policy-inheritance 2026-08-10 19:40:14 +08:00
pku-xht
850b78144a Merge commit '598bfdb91462c0402a6a11a32176c9f48f0df9fa' into codex/workflow-runs-chat-node-f6 2026-08-10 19:27:57 +08:00
creatixchu
888538dd5b Merge remote-tracking branch 'origin/master' into feat/read-image-context 2026-08-10 19:24:28 +08:00
Yichen Jiang
8c5e0f7b6a Merge remote-tracking branch 'origin/master' into worktree/web-plugin-config
# Conflicts:
#	docs/event-producer-consumer.i18n.yaml
#	docs/event-producer-consumer.zh.md
#	docs/module-graph.i18n.yaml
#	packages/client/ui-conversation/README.i18n.yaml
#	packages/client/ui-conversation/README.zh.md
2026-08-10 19:18:11 +08:00
Yichen Jiang
f8555b5561 feat(client): configure host-plane plugins from a settings section
The section knows no namespace: it declares `settings.plugin.item` and
renders whatever cards were registered into it, so a plugin that ships a
browser half owns its card and its controls. The three cards here cover the
host-plane sections this deployment exposes.

A field shows its effective value and, when the raw user layer carries it, an
override badge and a reset that clears it back to the composition layer.
Controls commit on blur and Enter rather than per keystroke, which would burn
namespace revisions and race its own reads. The search key is the one value
that never rides a response: the card reports only whether one is configured
and writes it through the credentials domain, addressed by the reference the
section names.

A card renders nothing while its namespace is unavailable — a deployment that
does not compose the owning plugin should show no trace of it rather than a
disabled card the user cannot act on.
2026-08-10 19:14:59 +08:00
creatixchu
b07844dd4c Merge branch 'master' into feat/read-image-context
# Conflicts:
#	docs/module-graph.i18n.yaml
#	docs/module-graph.md
#	docs/module-graph.zh.md
2026-08-10 19:01:47 +08:00
pku-xht
8de6df19d9 feat(workflow): show durable run records in Chat 2026-08-10 18:37:30 +08:00
Yichen Jiang
f736e6f584 feat(web-search-deepseek): resolve provider options from the settings section
The provider now takes a thunk rather than a value: it projects the
authoritative section per search, so a stored endpoint, model, or key
reference reaches the next call without re-registering the provider — which
would make the seam's provider selection observable as a flicker.

apiKey already carries role('secret'), so the section is safe to describe:
the literal never rides a response in any layer and a configuration surface
learns only that a key is set.
2026-08-10 18:06:27 +08:00
Yichen Jiang
fdf9bddbf8 feat(agent-loop): make the parallel tool-call cap a user setting
The section is a strict subset of the plugin config: `agents` is consumed
once when the service starts, so a stored change there could only look like
it had an effect. The cap resolves through a getter over the settings source,
which the scheduler destructures at the start of each tool group, so a
committed change bounds the next group without disturbing the one in flight.
`resolveMaxParallelToolCalls` becomes the section validator, refusing a value
at the write instead of at that group.

The deferred-resume effect-shape assertion now allows the one plugin effect
the optional settings wiring adds at the fiber's own level; a resumed agent
joining it there is still the regression it pins.
2026-08-10 18:00:03 +08:00
Yichen Jiang
da5d9aaee9 Merge remote-tracking branch 'origin/master' into worktree/subagent-missing-tools-fb2359 2026-08-10 17:57:59 +08:00
_Kerman
ded90bffba feat(apiproxy): host session-log download surface
Streams one ZIP of the root session artifact plus each subagent descendant
verbatim (the persistence readRaw bytes) from GET /api/session.export as a
host-only download — no wire envelope, absent from IApiClient. The downloads
domain owns the query schema, the fetch handler answers the GET alongside the
SSE routes, and compression runs on the host with fflate's streaming Zip API.
2026-08-10 17:57:40 +08:00
Yichen Jiang
e53f448650 fix(subagent): compose children from their parent's preset
Tool and prompt-section visibility is inherited along dsh-scope's parent
chain, and an agent's scope key is minted with no parent. Per-session agent
presets moved every model-facing row onto the agent plane and made
AgentPresets.mount() the one thing that binds that link, from the api-proxy's
session create, resume, and fork paths. The two in-process subagent drivers
installed only the per-child persona and tool filter, so a child's scope chain
had length one and its registry view resolved the global layer alone — which
is empty wherever a preset roster is composed. One-shot children reached the
model with no tools, continuable ones with only the host-plane `report`, and
neither carried its parent's persona, workspace context, or skill catalog.

AgentPresets.composeFrom() joins one agent to the standing composition another
already runs on. It is a bind, not a mount: the child gets its parent's exact
generation, so a composition edited since the parent started cannot fork it
onto another one, and it is synchronous, which is what lets a child creation
window use it. applyChildComposition() now takes the parent and performs the
join first, making a child composed without it unrepresentable at the call
sites. childSessionMeta() records the joined id so a cold read rebuilds the
composition the child actually ran under.

The audit that followed found two api-proxy readers on the wrong authority:
presenterScopeFor() and the live-agent branch of assertPresetUnchanged() both
read header.agentPreset, which goes stale the moment a blank session switches
preset. A switched session's cold transcript resolved presenters in the older
composition's layer and silently degraded to generic cards, and the gateway
refused to adopt a live session under the preset it actually runs while
accepting the one it left. Both now resolve through resolveSessionPreset(),
matching the resume branch fifteen lines above. The owning architecture Agent
Note carried the stale claim that the header records what a session runs; it
is corrected to name the header/log pair and its three readers.

Fixes #2165
2026-08-10 17:46:34 +08:00
Yichen Jiang
94f4183afd Merge remote-tracking branch 'origin/master' into worktree/web-theme-settings-integration-fde706 2026-08-10 17:05:18 +08:00
Hypatia May
9bb3a203ce Merge remote-tracking branch 'origin/master' into fix/continuable-subagent-policy-inheritance 2026-08-10 16:50:09 +08:00
Yichen Jiang
be7bf24169 Merge remote-tracking branch 'origin/master' into fix/preset-host-plane-task-registry 2026-08-10 16:45:13 +08:00