Commit Graph
8144 Commits
Author SHA1 Message Date
imccyu 98d2baf2e5 docs(session): document streaming format migration 2026-09-06 02:06:22 +08:00
imccyu a548150f86 test(perf): isolate benchmark dependencies 2026-09-06 01:01:04 +08:00
imccyu 356a332195 test(perf): run benchmarks against built artifacts 2026-09-06 01:01:04 +08:00
imccyu 47a6fa0f28 test(perf): centralize lifecycle benchmarks 2026-09-06 01:01:03 +08:00
Tianyi Cui 2395f112d8 test(perf): gate opening large Sessions with synthetic CI benchmarks
Add a benchmark lane (`vitest.bench.config.ts`, `pnpm run test:bench`,
gate mode `ci-bench`) and a required `node 24 / benchmarks` CI job that
runs it alone. Benchmarks synthesize their input in-process from fixed
parameters and fail on documented budgets:

- `open-generation.bench.ts`: a 200-turn released-v0 log with 500 text
  and 125 reasoning deltas per reply (127,400 events, ~2.8 MB) encoded
  through the frozen v0 codec; the migrating first `open()` must finish
  within 2,000 ms in a child process capped at 128 MB of old space, and a
  fresh process must open the published current generation within 500 ms.
- `conversation-fold.bench.client.ts`: 200 replies whose compact streams
  hold 2,000 text + 500 reasoning deltas each, folded through every Chat
  Definition by the real assembler; the fold must finish within 150 ms
  and stay within 3x the fold of the same window with 100 deltas per
  reply.

On this commit both gates fail: the migration exhausts the 128 MB heap
(4.8 s and 696 MB peak RSS without the cap; the pre-stack decode of the
same bytes took 34 ms and 168 MB) and the fold scales 11x with the delta
count. The stacked fixes bring both paths to O(records).
2026-09-06 01:01:03 +08:00
fz 40539e9002 Merge origin/master into feat/remove-str-replace-editor-from-minimal 2026-09-06 00:58:49 +08:00
Tianyi Cui b25d4faaaa fix(spill): share persisted notice formatting with client recognition 2026-09-05 23:52:59 +08:00
Tianyi Cui 9ffe85a512 OTel uploads explicit feedback for all users by default 2026-09-05 23:21:23 +08:00
ChinesezjcandTianyi Cui 02a029e679 Feedback is recorded in the session log and delivered through DeepSeek
Co-authored-by: Tianyi Cui <[email protected]>
2026-09-05 23:21:22 +08:00
Tianyi Cui 7bab91d247 fix(llm): retain Anthropic resolved model during replay 2026-09-05 22:40:40 +08:00
Tianyi Cui 69a0441c34 chore(llm): upgrade pi-ai to 0.85.1 2026-09-05 22:36:58 +08:00
Yichen Jiang 4d56cbc3d3 refactor(manifest): centralize package manifest types 2026-09-05 20:44:31 +08:00
mektpoy 06cee18430 Merge remote-tracking branch 'upstream/master' into issue-1424-goal-resume-activation
# Conflicts:
#	.agents/notes/implemented/bug-fix/2026-09-01-host-goal-pause-aborts-turn.i18n.yaml
#	.agents/notes/implemented/feature/2026-07-19-human-goal-command.i18n.yaml
#	.agents/notes/implemented/feature/2026-07-19-same-session-goal-round-driver.i18n.yaml
2026-09-05 15:34:05 +08:00
Yichen Jiang d46f840e99 Merge origin/master into worktree/ui-primitives-consolidation-429264
Archiving low-future-value Agent Notes (#3548) stripped the inbound
citations to three now-archived notes from the ui-primitives README, and
this branch rewrote the same "Controls and icons" opener so the new
component catalog owns the export enumeration. The resolution keeps this
branch's opener and drops the archived-note citation master removed, in
both languages; the pairing record is re-recorded from the merged pair.
2026-09-05 15:17:44 +08:00
Tianyi Cui a7a5be1703 docs(notes): archive low-future-value Agent Notes
Run the dsh-archive-agent-notes audit over every active Agent Note on
current master, judging each record by whether its rationale still guides
work rather than by size or age.

- Archive 453 implemented bilingual triplets (417,882 English words):
  completed UI chrome, narrow adapters, closed bug fixes, implementation
  walkthroughs whose package READMEs, docs pages, generators, or successor
  notes now carry the useful behavior, and 51 records fully superseded by
  a later active note. Keep 201 implemented notes whose ownership rules,
  negative guarantees, durable or wire semantics, security rules,
  reintroduction conditions, or still-tempting rejected alternatives
  remain useful.
- Reject 7 proposals whose premise is gone or whose work shipped in
  amended form under other records; delete 2 rejected notes that no
  longer prevent a plausible mistake.
- Retarget every remaining inbound link to the archived path, and repair
  active prose that named an archived record as the owner of a live fact:
  parenthetical citations drop, ownership sentences redirect to the
  README, docs page, or active note that states the fact, and history
  citations say so. Chinese files link the English archived path because
  the pairing gate treats the frozen tree as outside the bilingual corpus.
- Seal 1,359 new frozen artifacts; existing seals are unchanged and
  outbound links from archived notes are neither inspected nor repaired.
- Regenerate docs/config-catalog.md after the hook-bridge comment edits
  shifted two source line numbers.
2026-09-05 14:37:32 +08:00
Yichen Jiang 57d51b3802 Merge branch 'worktree/process-plugin-streaming-72f9b3' into worktree/job-kill-delivery 2026-09-05 14:34:41 +08:00
Yichen Jiang 452b2a816a refactor(client): share the capsule tag, switch, and idle state dot
Client feature plugins never import one another's components, so
ui-primitives is their only channel for sharing one. Nothing told an
author to look there first, and the package offered nothing to look
at: its README named six source files against forty-plus exports.

Add Tag (read-only capsule badge, eight tones) and Switch (36x20
toggle with a required accessible name), extend StateDotState with
idle for a tracked subject with no activity, and move ui-agent-preset,
ui-settings-plugins, and ui-settings-plugin-inventory onto them.

The plugin inventory's conditional tag referenced
--dsw-alias-state-warning-primary, which does not exist, so both
themes had been painting its hardcoded #b45309 fallback.

State the reuse rule as the first step of the new-component checklist,
and give the README a component catalog so the rule has something to
check. The rule is guidance, not a gate: a package may still write its
own control, and the Agent Note records the five that stay local.
2026-09-05 14:32:59 +08:00
Yichen Jiang f3b538cf8f Merge remote-tracking branch 'origin/master' into worktree/process-plugin-streaming-72f9b3 2026-09-05 14:32:14 +08:00
Yichen Jiang 3be4761178 Merge branch 'worktree/process-plugin-streaming-72f9b3' into worktree/job-kill-delivery
# Conflicts:
#	packages/api/job-controller/README.i18n.yaml
#	packages/api/job-controller/README.md
#	packages/api/job-controller/README.zh.md
2026-09-05 14:31:23 +08:00
Yichen Jiang 4baea3bb83 fix(jobs): spill paths as source metadata, live wait claims, narrower entries
Three review follow-ups on the consolidated jobs seam.

The spill file a pull source keeps is job metadata now: the pump reports it
to the registry on every read (present or withdrawn), the projection lists
it under output.spillPaths, and the model's dropped-output notice names it
from there. Attached to a gap chunk it was lost whenever the ring itself
evicted (a pump that kept up never produced a gap) or whenever the gap chunk
was evicted later, and it could not follow a source that withdrew its file.

A job_output wait's claim on the settlement now carries a live flag that
the caller's abort clears synchronously from the abort event. The registry
rejects an aborted wait on a later microtask, so a settlement announced in
between used to find the claim counted and skip the notice the tool result
was not going to carry either.

The job-controller client entry and the tool-jobs entry stop exporting
implementation classes and render helpers nothing outside the packages
consumes; the client entry keeps IJobs, which also carries the ctx.jobs
Context augmentation to consumers.
2026-09-05 14:28:28 +08:00
mektpoy b9a4b682c4 Merge remote-tracking branch 'upstream/master' into issue-1424-goal-resume-activation 2026-09-05 14:16:58 +08:00
Yichen Jiang 206e5c6545 Merge branch 'worktree/process-plugin-streaming-72f9b3' into worktree/job-kill-delivery
# Conflicts:
#	apps/web/tests/background-job-list.e2e.ts
#	docs/config-catalog.i18n.yaml
#	docs/config-catalog.zh.md
#	packages/api/job-controller/README.i18n.yaml
#	packages/api/job-controller/README.md
#	packages/api/job-controller/README.zh.md
#	packages/api/session-controller/README.i18n.yaml
#	packages/api/session-controller/README.md
#	packages/api/session-controller/README.zh.md
2026-09-05 14:06:00 +08:00
Yichen Jiang 8bcd6f7519 refactor(jobs): rename visibleTo/VisibleJobs to forCaller/CallerJobs
The caller-bound operation set now says what it is: the jobs one caller
may operate on. The caller argument is required (SessionId | undefined),
so an anonymous view has to be requested explicitly instead of falling
out of a forgotten argument.
2026-09-05 14:00:47 +08:00
Yichen Jiang 1e04fcff35 fix(connection): validate retry factors and clarify timeout recovery 2026-09-05 12:21:59 +08:00
Yichen Jiang 1bd26370cc fix(connection): recover stalled handshakes and keep retrying 2026-09-05 11:50:27 +08:00
Yichen Jiang d3b1f2d1bc Merge remote-tracking branch 'origin/master' into worktree/process-plugin-streaming-72f9b3
# Conflicts:
#	docs/event-producer-consumer.i18n.yaml
#	docs/event-producer-consumer.md
#	docs/event-producer-consumer.zh.md
#	docs/module-graph.i18n.yaml
#	docs/module-graph.md
#	docs/module-graph.zh.md
#	packages/api/remotes/package.json
#	packages/api/remotes/src/client/index.ts
#	packages/api/session-controller/README.i18n.yaml
#	packages/api/session-controller/README.md
#	packages/api/session-controller/README.zh.md
#	packages/api/session-controller/tsconfig.host.json
#	packages/client/ui-approval/src/client/contract/slots.ts
#	packages/client/ui-chat/src/client/chat/MessageItem.tsx
#	packages/client/ui-chat/src/client/conversation-nodes/assistant.ts
#	packages/client/ui-chat/src/client/conversation-nodes/partial.ts
#	packages/client/ui-chat/src/client/conversation-nodes/tool.ts
#	packages/client/ui-chat/src/client/model/tool-call-tree.ts
2026-09-04 17:28:12 +08:00
07akioni 737a965e92 Merge remote-tracking branch 'origin/master' into feat/electron 2026-09-04 16:41:04 +08:00
mektpoy b55a8e4777 Merge remote-tracking branch 'upstream/master' into issue-1424-goal-resume-activation 2026-09-04 16:34:50 +08:00
07akioni 75c7bbb88d Merge remote-tracking branch 'origin/master' into feat/electron
# Conflicts:
#	packages/client/connection/README.i18n.yaml
#	packages/client/connection/README.md
#	packages/client/connection/README.zh.md
2026-09-04 16:23:37 +08:00
ihsiang 0180c5cdea Merge pull request #3547 from deepseek-harness/ihsiangzhang/tool-call-clickable-styles
feat(client): 统一回答中可点击链接样式——链接别名、hover 点状虚线、分类图标
2026-09-04 16:23:14 +08:00
07akioni fe0b7f2814 fix(desktop): move host out of CLI package 2026-09-04 16:21:45 +08:00
yx.zhang 8ffdee4fe5 feat(client): unify clickable-link language with link alias and category glyphs
Clickable artifact links across the transcript (markdown anchors, prose
file mentions, web source/fetch links, produced-file chips, workflow
member links) now share one language: a dedicated --dsw-alias-link color
(light deepseek-500, dark deepseek-400) decoupled from
state-business-primary, font-weight 500, no underline at rest, and a
dotted 3px-offset underline on hover/focus. A new ui-primitives LinkIcon
leads each link with a currentColor category glyph (url / folder / code /
image / document / other) derived from the path extension by
classifyLinkPath. Produced-file chips drop the grey pill and 96px cap and
render at natural width, shrinking with ellipsis only on row overflow.
ToolRow's grey dotted file links and the grey show-in-folder action stay
as they were. The inline-code chip tint moves to neutral-50 (dark
neutral-800) with its 0.5px border kept.

Coverage: LinkIcon unit spec, refreshed markdown-dom fixtures, and the
clickable-links-gallery web e2e registered in the host compiler face.

Closes #3546
2026-09-04 15:55:49 +08:00
creatixchu 58ec1f0867 refactor(file-upload): keep storage helpers and the HTTP route package-private
Stop re-exporting the verbatim file-store helpers from attachment-local, move
the raw-byte upload route handler into a non-entry module of file-upload, and
drop the redundant hook type re-exports from the Client entry. The route test
moves next to the module it exercises.
2026-09-04 15:41:25 +08:00
mektpoy 0928bb2c16 Merge remote-tracking branch 'upstream/master' into issue-1424-goal-resume-activation 2026-09-04 15:37:06 +08:00
mektpoy 56d6c25c9d fix(client): keep goal activation coverage in client face 2026-09-04 15:21:37 +08:00
07akioni ff146b84a3 Merge remote-tracking branch 'origin/master' into feat/electron
# Conflicts:
#	pnpm-lock.yaml
2026-09-04 15:11:38 +08:00
mektpoy 14baecfa86 Merge remote-tracking branch 'upstream/master' into issue-1424-goal-resume-activation 2026-09-04 14:49:37 +08:00
mektpoy 206e79ee3d fix(client): order goal activation through inject hooks 2026-09-04 14:49:32 +08:00
creatixchu b4517feed5 Merge remote-tracking branch 'origin/master' into worktree/2984-generic-file-upload 2026-09-04 14:46:36 +08:00
07akioni 1553862ac1 Merge remote-tracking branch 'origin/master' into feat/electron 2026-09-04 14:26:23 +08:00
Turtle c58097a826 feat(session-persistence-jsonl): cross-process write-ownership lease
Write handles now hold a durable lease (session.lock.json beside the
log): a random owner token, diagnostic pid, and an expiry. Acquisition
wins by exclusive create; a second process's create or write open rejects
while the record is unrenewed for less than leaseTtlMs (default 5 min),
and takes over after that — a crashed holder is waited out, never
reclaimed by pid. The holder renews every leaseRenewIntervalMs (default
4 min); a renewal that finds a foreign, vanished, or expired record — or
fails outright — marks the lease lost permanently, so every later
append/flush rejects with SessionOwnershipLostError while reads continue.
Close releases the record; read handles never touch it. Takeover of an
expired record is eventually exclusive: a replaced holder stops within
one renewal interval.

Refs #3245
2026-09-04 14:12:14 +08:00
Yichen Jiang a444460ad4 fix(shell): never offer cancelled work from the offer arm
The offer arm relayed the caller signal only through an abort listener, which a signal that was already aborted never fires, so a command cancelled before execute() spawned anyway, ran to its deadline, and was offered for promotion. The deadline callback also offered regardless of an earlier caller abort, so a process still in its termination grace could be promoted after the tool call was aborted. Both providers now relay an already-aborted signal immediately and settle the promotion undefined at the deadline once the caller aborted; the seam JSDoc states that an already-aborted signal counts as fired. Real-process and hanging-backend cases cover both providers.
2026-09-04 14:03:24 +08:00
Yichen Jiang 3d5431a862 Merge remote-tracking branch 'origin/worktree/process-plugin-streaming-72f9b3' into worktree/job-kill-delivery 2026-09-04 13:30:34 +08:00
Yichen Jiang 063ef188a6 chore(jobs): regenerate the catalogs after the review fixes
The settled-retention JSDoc, the required observed streams, and the session-controller type shifts changed what the config, persistence, Cordis, and event catalogs embed; CI's static and coverage lanes compared the stale copies. Regenerated, with the zh mirrors updated in step.
2026-09-04 13:29:54 +08:00
Yichen Jiang 42858723a6 Merge remote-tracking branch 'origin/worktree/process-plugin-streaming-72f9b3' into worktree/job-kill-delivery
# Conflicts:
#	packages/api/job-controller/README.i18n.yaml
#	packages/api/job-controller/README.md
#	packages/api/job-controller/README.zh.md
#	packages/api/session-controller/README.i18n.yaml
#	packages/api/session-controller/README.md
#	packages/api/session-controller/README.zh.md
#	packages/shell/bash-local/src/index.ts
#	packages/shell/pwsh-local/src/index.ts
#	packages/shell/tool-bash/src/background.ts
#	packages/shell/tool-bash/tests/tools.spec.ts
#	packages/shell/tool-pwsh/src/background.ts
#	packages/shell/tool-pwsh/tests/background.spec.ts
#	snapshots/web/approval-composer/session.v2.jsonl
#	snapshots/web/feedback-command/session.v2.jsonl
#	snapshots/web/fresh-round-trip/session.v2.jsonl
#	snapshots/web/goal-multi-turn-actions/session.jsonl
#	snapshots/web/lifecycle-chrome/session.v2.jsonl
#	snapshots/web/live-interactions/session.v2.jsonl
#	snapshots/web/minimal-preset/session.v2.jsonl
#	snapshots/web/permission-policy-context/session.v2.jsonl
#	snapshots/web/plan-review/session.jsonl
#	snapshots/web/ptc-round/session.v2.jsonl
#	snapshots/web/question-composer/session.v2.jsonl
#	snapshots/web/steering/session.v2.jsonl
#	snapshots/web/turn-tail-actions/session.v2.jsonl
#	snapshots/web/web-search-round/session.v2.jsonl
2026-09-04 13:27:34 +08:00
creatixchu 268cf0101e Merge remote-tracking branch 'origin/master' into worktree/2984-generic-file-upload 2026-09-04 13:08:41 +08:00
creatixchu f0e52c2731 refactor(file-upload): tighten service boundaries 2026-09-04 13:08:25 +08:00
Yichen Jiang 3a03d68891 fix(shell): serve a background spawn failure on the observed stderr stream
A rejected background spawn produces no process output, so the observed stderr reader the job registry pumps was empty and the model's job_output after such a failure showed only killed before exit, where master's consuming read rendered [stderr] followed by spawn failed: … with the cause. The local providers now serve the note as the whole observed stderr stream once the spawn rejected, and the consuming read still folds it in exactly once, so the model's first read after the failure is byte-identical to master's. ShellProcess.observed and both of its readers are required: every background process exposes offset readers, and the shell tools' pull sources no longer carry a no-readers branch.
2026-09-04 12:59:41 +08:00
Yichen Jiang 80bbdba617 fix(jobs): restore the dropped-output notice with its spill files for the model
The consuming shell read on master told the model where a truncated stream's complete text lived: [some output was dropped from memory; full output: <paths>]. The ring-backed read rendered a notice only for the ring's own eviction and ignored the gapBefore mark the pump puts on a chunk whose source lost bytes between two polls, so a fast producer's tail read as continuous output and no path survived. A lossy source read now carries the source's spillPath onto its gap chunk (JobSourceRead, JobAppendOptions, JobChunk), the pump forwards it, the ring retains it, and the model renderer emits master's notice for a producer-side gap or a ring eviction, listing the distinct spill files in offset order. The bash and pwsh sources already returned the subprocess reader's spillPath; the type now admits it.
2026-09-04 12:47:21 +08:00
Yichen Jiang 0712a4cc68 fix(jobs-local): keep unconsumed settled output for the model and announce registration first
Settlement trimmed the ring to settledRetainBytes before releasing waiters, so a job that finished before its first job_output handed the model only the last 16 KiB plus a dropped-output notice where master's consuming read kept the executor's whole tail. The ring now keeps every byte the model cursor has not consumed on top of the settled cap, and the first terminal model read trims to the cap.

The registered event was emitted after startPump, whose first drain runs synchronously and may announce output, so a source readable at once produced an output event for an id no subscriber had seen registered. The announcement now precedes the pump; the events JSDoc states that a job's first event is registered.
2026-09-04 12:25:14 +08:00