Commit Graph
287 Commits
Author SHA1 Message Date
Turtle aa8bdfc79e Revert "feat(agent): admit Web prompts through the agent controller" 2026-10-20 19:09:02 +08:00
imccyu 14e5add505 Merge master into DSH 0.2.1 entry customization synchronization branch
Bring master 45d1196d3fe into the release/dsh-0.2.1 squash commit of #6247
so the release commit stays an ancestor of master.

Conflict resolutions:
- apps/web/tsconfig.json, tsconfig.host.json: keep the entry-customization
  e2e and master's Computer Use e2e entries.
- docs/subsystems/slots.{md,zh.md}: keep both added paragraphs; re-record the
  slots, ui-primitives, and ui-workspace README translation pairs.
- ui-sidebar SidebarRoot.tsx and locales.ts: keep the More menu imports and
  copy next to master's version-copy toast.
- apps/web/tests/agent-preset-selection.e2e.ts: keep the New Session
  blank-reuse assertions, read presets through master's
  sessionProjections.checkpoint() instead of the deprecated stateOf().

Follow-ups on master's side:
- ui-sidebar sidebar-root spec: give master's version-copy render the entry
  pin props that SidebarRootInjected now requires.
- snapshots/web/steering/trajectory.expected.md: add the More conversation
  views trigger to master's new Trajectory golden.
2026-10-20 15:47:29 +08:00
5ff29190ed feat(ui): add navigation entry customization (#6247)
* fix(ui): avoid tooltip trigger overlap when a side fits

* feat(ui): add navigation entry customization

* fix(test): keep tooltip geometry independent of JSX types

* fix(ui): align customization catalogs and integration fixtures

* test(ui): complete customization lifecycle and release integration coverage

* fix(ui): return entry discovery to the installed plugin list

* docs: refresh module graph for entry customization

* build: refresh workspace links for the moved entry customization package

* docs: regenerate catalogs and pairing hashes for the moved entry customization package

* test(web): cover default-loaded entry customization in the Web e2e

* test(ui): describe entry customization as a browser plugin in the host entry spec

* build: order entry customization publication files as workspace constraints require

* test(release): drop the moved entry customization package from the experimental family list

* style(ui): use the shared focus ring color on entry customization triggers

* test(web): re-record goldens for the default-loaded More navigation menus

* test(web): add the More conversation views trigger to the remaining CI-reported goldens

* docs: record region-owned pins for plugin entry customization

* refactor(ui): rebuild entry customization on region-owned pins and More menus

- Each navigation region (left sidebar, Conversation header, right sidebar
  guide) persists its own unpinned list under
  dsh.slot.manual-order.<list slot key>.v1, filters its own launchers, and
  draws its own More button and Menu around its actions slot.
- ui-entry-customization only registers the shared menu rows (entries with
  pin buttons, Browse other plugins, Create your plugin) into the three
  actions slots and keeps no state.
- Remove ctx.layout.entryVisibility, the plugin store, left-sidebar drag
  reordering, and agentPresetNavigation; ui-layout and ui-agent-preset match
  release/dsh-0.2.1 again.
- Keep the release <nav> and Conversation tab-bar visibility conditions.
- Move the More glyph into ui-primitives as IconAppsAddOutline{Regular,Medium}.

* docs: compile the entry customization owner props example

* docs(ui): describe the wrapping Conversation tab row in the header comment

* fix(ui): return New Session to the Workspace blank and its unsent draft

- New Session (startSession without options) takes the blank-reuse path
  again instead of creating a fresh Session on every call, which hid the
  previous blank and its unsent draft since a5c9c2aaeef (#5775).
- A request that names an Agent preset skips blanks listing a different
  preset, so Creator entries no longer take over an ordinary draft.
- Record the change in a v0.2.1-rc.2 upgrade guide; the Host refresh of a
  stale loaded blank stays deferred (see the Agent Note).

* docs: regenerate the Cordis inspect catalog for New Session blank reuse

* fix(ui): keep the selected entry visible while unpinned

- Left-sidebar rows and View tabs keep the selected entry, with aria-current or aria-selected, until another entry is selected.
- Entry menu Creator action takes no region argument; the registration's region selects the prompt.
- Document the 2px panel-row and 32px View-tab gaps; drop commit hashes from the New Session Agent Note.

* fix(ui): leave a blank of another preset unstaged when starting Creator

startCreatorDraft stages cordis only when the main blank lists no preset or already lists cordis; navigation opens a separate Creator blank otherwise, so a Standard draft blank keeps its preset.

* feat(ui): choose whether a draft prompt replaces, appends to, or keeps an existing draft

- DraftInitializationOptions gains whenDraftExists ('replace' | 'append' | 'keep', default 'keep'); clearPreviousDraft stays and maps to 'replace' only when whenDraftExists is omitted.
- Append adds the prompt as new paragraphs after the existing text and references; attachments stay in every mode.
- The three Create your plugin entries append their regional prompt.

* test(web): align e2e with New Session blank reuse and the visible selected entry

* refactor(ui): share the draft paragraph writer between setDraft and appendDraft

---------

Co-authored-by: Yif <[email protected]>
Co-authored-by: imccyu <[email protected]>
2026-10-20 15:17:13 +08:00
Yichen Jiang 43d6585375 refactor(agent-controller): recognize admission refusals by code
AgentAdmissionRejected now extends HarnessError with the fixed code
AGENT_ADMISSION_REJECTED. The Session Remote recognizes a refusal by that
code and imports only agent-controller types, so its mapping also holds for
an error from another copy of the module; its literals are typed by the
agent-controller constants, so a changed value fails the build.
2026-10-20 10:40:31 +08:00
Yichen Jiang 1d51715aca Merge remote-tracking branch 'origin/master' into worktree/session-agent-controller-refactor-ff892d
# Conflicts:
#	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/README.i18n.yaml
#	packages/api/session-controller/tests/commands-upload-file.host.spec.ts
#	scripts/gen-cordis-catalog.ts
2026-10-19 22:25:55 +08:00
Yichen Jiang a472820428 fix(agent): wait for deliveries on disposal and keep image prompts in order
The Agent controller now finishes disposal only after every delivery it
stopped has settled, and a sender that cancels stops waiting at once, also
while its message waits behind a held one; the message keeps its place and
is dropped at its turn.

An image prompt takes the Session's image admission turn when its
preparation starts, in the Agent's delivery order, and keeps it until the
prompt settles. Image and text prompts therefore enter the inbox in arrival
order, and a model selection waits only for the image prompt being
admitted, not for one still queued.

The core page documents the delivery types, and the architecture overview
lists the controller and its admission event.
2026-10-19 16:58:59 +08:00
Yichen Jiang 47d947d8b1 Merge remote-tracking branch 'origin/master' into worktree/session-agent-controller-refactor-ff892d
# Conflicts:
#	docs/capability-seams.i18n.yaml
#	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
2026-10-19 15:07:35 +08:00
_Kerman 955e600031 Merge master into session projection registration handles 2026-10-19 11:21:16 +08:00
imccyu 99eacb881f fix(session-controller): drop a redundant projection cast and refresh doc graphs 2026-10-19 10:43:21 +08:00
imccyu 6292808bf9 fix(session-controller): keep the list summary contract honest 2026-10-19 10:20:10 +08:00
imccyu f230fc2fc2 refactor(session-projection): review fixes for the summary key set
- Export `ProjectionKeySelection` (the read faces' key selection) and reuse it
  from the projection cache instead of restating the union twice. The Cordis
  catalog can now resolve the type its generated signatures reference.
- Make `wire.summary` a plain boolean: omitted means `true`, and a key whose
  map entry carries the summary mark declares `false` so the runtime key set
  and the client view type agree. The type no longer forbids a declaration.
- Describe the mark accurately: it has no runtime representation; `wire.view`
  and `viewSchema` are typed with `SessionProjectionViewValue`, which strips it,
  so the registration erase only widens the state type.
- Say plainly in the package README, the subsystem page, the client field
  comments, and the Agent Note that a list row carries the summary projection
  and never the full projection: a connected Session's store may hold more
  values, but those are outside the list contract.
- Document the summary vocabulary on the subsystem page with `ts type-equiv`
  blocks for the mark, its stripping, the excluded-key test, the summary value
  type, and the key selection; split the prose paragraph.
- Revert the behavior-neutral cache-double refactors in three specs, and record
  in the Agent Note why no upgrade guide accompanies the wire change and how a
  consumer migrates.
2026-10-19 01:13:24 +08:00
imccyu 8e2dd67de8 perf(session-controller): exclude the shared image limits from session summaries
`imageLimits` is a boot constant every Session shares: the unit stores no
per-Session state (`stateSchema: z.null()`, `apply: state => state`) and its
view returns `ctx.attachments.imageLimits`. A list row therefore repeated one
host-wide capability fact on every row. It now carries the summary mark like
the three log-derived units, so a summary read skips it while an opened Session
still receives it through `session/follow`, the control baseline, and
`session.projections`.

No other logic changes: the registration, its schema, its constant view, and
the host-side prompt validation keep reading `ctx.attachments` directly.
2026-10-18 23:04:29 +08:00
imccyu 92f9e79fac perf(session-projection): serve session-list rows from a summary key set
A Session-list row no longer carries every registered client view: the three
units whose values a list row never renders (`turnOutline`, `sessionStats`,
and `todos`) are excluded, which removes the whole-log turn outline and the
figure and todo payloads from every row. An opened Session is unchanged —
`session/follow`, the `session/control` baseline, and `session.projections`
still serve every projected key.

The exclusion is one type-level mark plus one registration interlock:
`SessionProjectionSummaryExcluded<T>` marks a map entry, and
`ProjectionDefinition.wire` requires `summary: false` exactly on a marked key
and rejects it everywhere else, so the mark and the declaration cannot drift.
A nullable entry keeps `null` outside the wrapper, so `todos` stays
`TodoItem[] | null`. `summaryKeys()` returns the derived set, stable until a
registration or its disposal changes the key table, and the existing
key-taking read faces (`cachedSnapshot`, `viewCheckpoint`) accept that set
directly, so summaries need no separate read face and no per-read key copy.
`packages/api/session-controller/src/list.ts` passes the set to the live and
cold cached faces; `cachedPredecessorTitle` is untouched.

Client types only: `SessionSummary.projectionValues` narrows to
`SessionProjectionSummaryValues`, `SessionProjectionSnapshot.values` keeps
every view value with the mark stripped, and no wire field or client name
changed. The cache, subsystem page, and package README document the summary
rule and the two read faces.
2026-10-18 22:13:18 +08:00
Yichen Jiang f34eaf7601 feat(agent): admit Web prompts through the agent controller
Add @deepseek-ai/dsh-agent-controller, composed in the base bundle, as the
entry through which a sender delivers a message from outside an Agent into
its inbox. deliver() runs the sender's content preparation in the Agent's
delivery order, asks the agent-controller/admission waterfall for a
decision, rechecks cancellation and registration, and appends the message
with followup() or steer(). dsh-agent and agent-loop are unchanged.

The Web session/prompt Remote delivers through it: the image model check,
upload receipt resolution, and attachment storage run as prepare, the
receipt binding runs as beforeInsert, and refusals map to
session/prompt-rejected. The Web client keeps its existing echo.

This replaces the Host half of deepseek-harness/deepseek-harness#6178,
whose admission stage lived in dsh-agent.
2026-10-17 17:09:29 +08:00
_Kerman ff731c72de refactor(session-projection): remove the host state map 2026-10-15 21:01:00 +08:00
_Kerman 491fa4a394 refactor(session-projection): clarify retained handle names 2026-10-15 20:12:09 +08:00
_Kerman c3efd4bff8 refactor(session-projection): keep state reads inside owning services 2026-10-15 18:18:58 +08:00
_Kerman 307d63792e Merge remote-tracking branch 'origin/master' into xtr/session-projection-registration-handles
# Conflicts:
#	benchmarks/session-corpus/projection-list.worker.ts
#	benchmarks/session-corpus/session-corpus.worker.ts
#	docs/config-catalog.md
#	docs/config-catalog.zh.md
#	packages/api/session-controller/README.i18n.yaml
#	packages/api/session-controller/src/index.ts
#	packages/api/session-controller/tests/list-scheduling.host.spec.ts
#	packages/client/ui-chat/README.i18n.yaml
#	packages/client/ui-chat/README.md
#	packages/client/ui-chat/README.zh.md
#	packages/client/ui-chat/src/client/chat/use-chat-viewport.ts
#	packages/experimental/client-ui-cot-translation/tests/activation.host.spec.ts
2026-10-14 11:12:24 +08:00
imccyu a4426261ab fix(ui-chat): fold next-message work details on one frame clock
Folding on the next message reserved the whole closing height as bottom
room and kept scrollTop whenever the input had no transcript echo on this
page: a message from another tab, a queued message delivered after the
previous Turn, or a send from a subagent child in the right Sidebar. A
reader below the fold was left on an empty viewport.

Every batch of closing rows now runs on the viewport's frame-clock driver.
It lands at the tail for this client's own input or a following reader and
otherwise keeps the reader's content still, installing only the room the
landing lacks. Subagent child sends register a local echo and pass its
request id to subagents.prompt, so the child's recorded message retires it.
2026-10-14 00:31:59 +08:00
imccyu 529706d163 fix(remote-access): drop buffered events on revoke, filter search, declare workspace file resources 2026-10-13 23:55:05 +08:00
imccyu 2640d3df82 feat(api): resolve endpoint resources and filter lists by access 2026-10-13 23:01:38 +08:00
imccyu d6e408d957 feat(session-controller): record non-owner principals on user message sources 2026-10-13 23:01:37 +08:00
_Kerman 2bdbdb4ae9 merge: integrate latest master with projection registration handles 2026-10-12 12:51:32 +08:00
_Kerman 08e48f34b5 refactor(plugins): migrate projection consumers to retained handles 2026-10-12 12:03:36 +08:00
Yichen Jiang d6a699591b Merge remote-tracking branch 'origin/master' into worktree/sleepy-grothendieck-64df7b
# Conflicts:
#	docs/event-producer-consumer.md
#	docs/event-producer-consumer.zh.md
#	packages/api/session-controller/README.i18n.yaml
#	packages/extensions/cordis-client-runner/tests/api-catalog.client.spec.ts
2026-10-09 11:38:51 +08:00
Yichen Jiang 1b8a55116e fix(session): claim named Sessions in arrival order before resolving presets
session.create resolved the requested preset before queueing on the named
identity, so a later request whose preset resolved first could run first, and
an undeclared preset masked the directory conflict the README promises.
Queue first, check the named Session's directory and ownership, then resolve
the preset inside the queue, and report the preset each request left the
Session running instead of reading it after the queue moved on. The no-roster
conflict message now names its actual cause.
2026-10-09 11:29:04 +08:00
imccyu dc22e172f4 feat(session): show header migration status before expansion 2026-10-08 16:47:45 +08:00
imccyu c1df683f8c feat(client): guide migration-required forks and subagent discovery 2026-10-08 16:45:26 +08:00
imccyu a2dd724c60 feat(session): expose format status and defer frontend-triggered migration 2026-10-08 16:45:25 +08:00
Yichen Jiang d0eb70425e Merge remote-tracking branch 'origin/master' into worktree/sleepy-grothendieck-64df7b
# Conflicts:
#	.agents/notes/implemented/architecture/2026-09-17-process-local-blank-sessions.i18n.yaml
#	.agents/notes/implemented/architecture/2026-09-18-declarative-agent-presets.i18n.yaml
#	.agents/notes/implemented/architecture/2026-09-18-declarative-agent-presets.md
#	.agents/notes/implemented/architecture/2026-09-18-declarative-agent-presets.zh.md
#	docs/event-producer-consumer.md
#	docs/event-producer-consumer.zh.md
#	docs/persistence-catalog.i18n.yaml
#	docs/persistence-catalog.md
#	docs/persistence-catalog.zh.md
#	packages/api/session-controller/README.i18n.yaml
#	packages/client/ui-agent-preset/src/client/index.ts
#	packages/client/ui-agent-preset/tests/apply.client.spec.ts
#	packages/client/ui-workspace/README.i18n.yaml
#	packages/client/ui-workspace/README.md
#	packages/client/ui-workspace/README.zh.md
#	packages/client/ui-workspace/src/client/index.ts
#	packages/client/ui-workspace/src/client/navigation.ts
#	packages/extensions/cordis-client-runner/src/client/api-catalog.ts
2026-10-08 14:55:44 +08:00
Tianyi Cui 55dfd3bab1 fix(plugins): narrow optional bundles and create fresh session agents 2026-10-06 23:48:59 +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 79bd3d8da7 feat(session): centralize working directories and directory context 2026-10-06 01:27:54 +08:00
Tianyi Cui 9dcc8fa985 Merge master into unified subagent activations
Integrate master 78ae4fc2d4d8ecaebb4b674028f781a358b92cc9 after the four
independent review fixes. Keep this base update separate from those fixes
and from subsequent review changes so the integration is independently
reviewable and the observed-master checkpoint remains preserved.

Retain activation-owned execution, caller-independent local discovery,
and unconditional parent final-answer delivery. Preserve master's preset
scoped scheduling tools and all delegated-child schedule deny rules. Move
the new scheduling regression from the removed driver package into the
surviving subagent package and run it through a real Spawn activation.

Preserve master's removal of runtime invariant plugins, dependencies,
exports, and test mounts. Keep context disposal before fixture directory
cleanup. Combine Python workflow ordering with activation/catalog events
without inventing unsupported source-plane import paths.

Keep all frozen Agent Note archives byte-for-byte identical to master;
do not accept Git's automatic edits to renamed archived notes. Retain
current lifecycle and delivery facts in active documentation, repair its
links, and regenerate catalogs/persistence schemas from merged source.
All 62 master persistence roots remain; only subagent/catalog gains the
PR's external membership extension. Keep master's third-party lock graph
and update only workspace dependency changes.

Validation before this checkpoint: 683 focused tests passed, seven
Windows-only cases skipped; 2,772 archived artifacts verified. Generated
catalog and active-pair checks passed. Fresh artifact build and remaining
build-dependent documentation checks continue before publication.
2026-10-05 23:49:47 +08:00
turtle1999 4402fa47e4 perf(api): time-slice Session list work 2026-09-30 18:02:50 +08:00
turtle1999 ecc01b54a4 perf(api): yield between Session list summaries 2026-09-30 15:50:40 +08:00
Yichen Jiang f17741c756 fix(session): reuse blank Sessions under the requested preset
session.create treats a named sessionId as a blank Session to reuse while
the Host can verify it is still reusable: no turn has started, it belongs to
the requested directory, it is an unarchived member of the requested
Workspace, and no other owner writes it. The reused Session runs the
requested agentPreset or the configured default; its recorded preset is not
resolved, so a blank recorded under a preset that is no longer declared no
longer breaks New Session or startup restoration. A change is logged as
agent-preset/selected before the Agent is published. A candidate that is no
longer reusable stays unchanged and the Host creates a new Session, which
replaces the client's writer-held fallback.

The Web client restores a saved draft with its recorded preset and falls back
to the default when that preset is missing or fails to activate, passes the
creator entry's preset through creation instead of issuing a concurrent
select, and reloads the projections of a declined candidate so a stale blank
hint no longer hides a started conversation.

Related to #2566
2026-09-29 14:52:11 +08:00
Dudu-0223 3254ed611d Merge master and preserve catalog-recursive subagent discovery 2026-09-27 15:23:31 +08:00
zhc 0b275fc3f6 merge: sync master release and align analytics policy checks 2026-09-24 23:08:59 +08:00
Yichen Jiang 86331673d9 fix(session): save default model settings in the background 2026-09-24 19:48:49 +08:00
zhc b1cf871b25 feat(desktop): collect product analytics through OTel 2026-09-24 17:08:31 +08:00
lsdsjy 4e0283c89b Merge remote-tracking branch 'origin/master' into feat/account-provider-signout 2026-09-23 20:45:29 +08:00
imccyu 1b55f5bea3 fix(chat): retain preparing tools and ordering until step completion 2026-09-23 19:48:45 +08:00
lsdsjy 9e19ca3e45 fix(account): limit automatic model selection to account login 2026-09-23 15:06:00 +08:00
lsdsjy 40da69ff75 refactor(account): isolate provider authentication and preserve model selections 2026-09-23 14:43:47 +08:00
lsdsjy 2fc9262f3e chore: merge master into account provider branch 2026-09-23 11:19:22 +08:00
imccyu 08c0e8e71b fix(chat): deduplicate admitted local steering 2026-09-22 22:47:12 +08:00
imccyu f6966f8fab test(client): align resize fixtures and restore branch coverage 2026-09-22 22:08:50 +08:00
imccyu 820824edd7 fix(chat): stabilize input echo admission and ordering 2026-09-22 21:07:55 +08:00
imccyu 50ba2c8bb2 fix(session): align history pagination with turn boundaries 2026-09-22 21:07:55 +08:00