Files
deepseek-harness/packages/api/activity-controller/README.md
T
Yichen Jiang 4a79310339 feat(activity): optional live-output observation seam with a web viewer
Add the activity capability seam: ctx.activities is a pure observation
plane where long-running work (background bash/pwsh, workflow runs) opens a
handle, appends transient output into a byte-offset ring buffer, and settles
exactly once. Nothing model-visible changes: reads are non-consuming and
lossy-by-design (absolute UTF-8 offsets survive eviction and report gaps),
correlation carries {callId, jobId}, and visibility is owner-fenced like jobs.

The seam is strictly optional. Producers tap it through ctx.get('activities')
and contain every observation failure, so an unregistered or broken registry
never affects the underlying job (proven by broken-registry tests).

Ship the full path in one change:
- @deepseek-ai/dsh-activity: Service Definition, pumpActivityOutput pull
  substrate, invariant companion; dsh-activity-local: ring-buffer provider
  with retention config and owner cleanup.
- shell: ShellProcess.observed exposes non-consuming stdout/stderr readers;
  tool-bash/tool-pwsh mirror background jobs into activities.
- tool-workflow: phase/log/agent lines mirrored as a workflow activity.
- api-activity-controller: Typert Remote control (roster baseline+buckets)
  and observe (opened/output/status frames, coalesced and byte-capped)
  streams plus the client feed service with reference-counted observation.
- ui-activity: session-header action rendering live output through
  TerminalBlock, which now shows output while a command is still running.

Docs: activity subsystem page, architecture row, regenerated catalogs, and
the Agent Note (2026-08-24-activity-observation-seam), all bilingual. A
keyless web e2e replays a real run_in_background stream to ARIA goldens.
2026-08-24 22:40:14 +08:00

2.3 KiB

@deepseek-ai/dsh-api-activity-controller

English | 中文

Activity Remote streams over the optional ctx.activities registry, plus their React-free client model. A pure read surface: it starts nothing, cancels nothing, and never touches the model-facing consuming cursors — the wire path reads only the registry's non-consuming offsets.

The Host ActivityController (namespace activity) exposes two @Remote({ mode: 'stream' }) methods:

  • control(signal) — one complete roster baseline, then whole-bucket replacement frames per owner session on every registry change (the self-healing shape the session control stream uses for jobs). A composition without the registry serves an empty baseline.
  • observe({ activityId, from? }, signal) — one opened anchor, coalesced output frames (flushMs window, maxFrameBytes soft budget; one larger chunk ships whole), then one terminal status after the settled activity is drained, after which the generation closes normally. Reconnecting callers resume by passing the last frame's next; a resume behind the retained window arrives flagged lossy. Status rides the same stream as output, so settlement can never race a still-open output channel.
Config Default Meaning
flushMs 100 Coalescing window after new output before an observation read.
maxFrameBytes 65536 Soft byte budget per observation output frame.

The client half (./client) installs ctx.activityFeed: ClientActivityModel mirrors the roster (last-wins buckets, generation replace) and accumulates each observed activity's bounded render tail, and ClientActivityFeed.observe(id) opens reference-counted observation streams that resume from the model's cursor across carrier generations.

Model Experience

None, as activity transport is browser and Host observation state and registers no prompt, tool, or session event.

KV Cache effect

None; the package never assembles or alters provider requests.

Known Limitations and Deferred Work

  • Registry presence is sampled at construction — a registry mounted after the controller stays unobserved until the controller reloads.
  • The roster names no watermark — an observation stream anchors itself; correlating roster rows against observation offsets is client policy.