Files
deepseek-harness/packages/client/ui-tool
Yichen Jiang eab0aeb9db feat(web): list background tasks in the session header
The task registry has run every background bash, pwsh, pty-send, and
one-shot subagent since it landed, but only the model could read it: a
human at the Web client could not see that a build was running, tell a
finished task from a stuck one, or find its outcome anywhere but the
`run_in_background` tool card that printed an id and never updated.

Task state now reaches the browser as one whole-snapshot `session/tasks`
mux frame per session, pushed at every registry commit that changes what
that session can see. `TaskService` gains `onTasksChanged`, which is
owner-granular because owner-disposal removal is a change no per-task
record can express. The carrier reads the exact owner the listener hands
it, so a push stays correct while that scope tears down, and reads the
baseline through the non-resuming `ctx.agents.get` so listing never
revives a cold session. The client keeps a last-wins mirror on
`SessionListState`, and a new `dsh-client-ui-task` package renders it
beside the subagent catalog — rendering nothing at all until the session
has a task, so an ordinary conversation grows no new chrome.

Streamed per-task output and human-initiated cancellation are separate
phases; the note records why neither has to undo this channel, and why
no Web path may call the consuming `ctx.tasks.read()`.
2026-08-08 23:29:41 +08:00
..

@deepseek-ai/dsh-client-ui-tool

English | 中文

Client Tool presentation plugin. ui-conversation supplies one ordered root call through conversation.chat.tool; this package renders that root and its Code Dispatch children, then dispatches every atomic call through the keyed tool.call.toolview slot. Unregistered Tool names use the generic card.

Business UI packages register only their wire Tool names and atomic views. They do not pair Session events, rebuild the transcript, or own root/subcall topology. The Runtime remains authoritative for call/result pairing, lifecycle, and recursive subCalls projection; the conversation view remains authoritative for ChatFlow placement.

Rendering contract

ToolCallTree receives one root ToolCallBlock that already contains recursive subCalls, selection state, the session cwd, and Host callbacks for opening files and inspecting calls. It recursively walks the standard call blocks and sends the root and children at every depth through the same atomic dispatch path, without subscribing to a separate parent-to-children map.

Each root and child wrapper preserves the conversation.chat.tool call-anchor DOM contract used for paging and selection.

The package also fills conversation.details.tool with ToolDetails. The row and details renderers share the same pure card models for terminal, read, diff, search, and web render intents. Unknown intent tags and malformed wire card data fall back to flattened Tool result text.

Generic rows classify known Tool names into search, read, shell, write, edit, code, or generic variants. Running, successful, failed, and interrupted lifecycle states come only from the frozen call/result slice. File paths resolve against the session cwd only when the user invokes the Host open-file callback; presentation code does not read Session services.

Atomic Tool views

An owning business package registers its wire Tool name into tool.call.toolview:

ctx.slots.inject('tool.call.toolview', () =>
  ctx.slots.register({
    name: 'tool.call.toolview',
    key: '<wire tool name>',
  }, BusinessToolRow))

The owner payload is ToolCallOwnerProps: callId, toolName, the frozen block, optional cwd, and plain openFile/inspect callbacks. The registration receives the normal session slot runtime share. It does not receive React nodes, Runtime services, or root/subcall knowledge.

This package currently owns the generic fallback and the built-in bash/pwsh, read, write/edit, grep/glob, web, todo, question, and Code Dispatch presentations. ui-skill demonstrates a business-owned registration for skill.

Card-specific limits and fallback rules remain in the owning terminal, diff, read, search, and web notes.

Model Experience

None, as this package renders already logged Tool calls and results without altering model requests, Tool execution, or session events.

KV Cache effect

None. The package is client-only presentation.

Known Limitations and Deferred Work

  • The Host excludes run_code from Code Mode program bindings, so production events currently produce one dispatch level; the recursive Runtime/UI contract is ready for future nested producers.
  • Existing first-party Tool views are initially colocated here and can move to their owning business packages independently through the keyed slot.
  • Tool copy temporarily reuses the ui-conversation locale namespace.