Merge remote-tracking branch 'origin/master' into codex/session-scoped-sandbox-roots
# Conflicts: # .agents/notes/implemented/feature/2026-07-14-cross-family-fs-sandbox.i18n.yaml # .agents/notes/implemented/feature/2026-07-14-cross-family-fs-sandbox.md # .agents/notes/implemented/feature/2026-07-14-cross-family-fs-sandbox.zh.md # examples/acp-agent/README.md # packages/examples/agent-spine-demo/package.json # packages/fs/fs-sandbox/src/index.ts # packages/fs/tool-fs-search/tests/tools.spec.ts # packages/support/acp-snapshot/README.md # packages/support/acp-snapshot/src/suite.ts # pnpm-lock.yaml # scripts/type-equiv.manifest.json
This commit is contained in:
6
docs/architecture.i18n.yaml
Normal file
6
docs/architecture.i18n.yaml
Normal file
@@ -0,0 +1,6 @@
|
||||
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write
|
||||
architecture.md: d7555368b583203cee664da3615c4fb4fb680c30
|
||||
architecture.zh.md: bafe59dee0559d5969c7400bdae85be0d012b3b5
|
||||
@@ -1,18 +1,20 @@
|
||||
# DeepSeek Harness Architecture
|
||||
|
||||
The **DeepSeek Harness SDK** builds on Cordis: **everything is a plugin**, including the shipped loop.
|
||||
English | [中文](architecture.zh.md)
|
||||
|
||||
**DeepSeek Harness SDK** uses Cordis: **everything is a plugin**, including the loop.
|
||||
|
||||
## Overview
|
||||
|
||||
Harnesses are [Cordis](cordis-primer.md) contexts whose packages contribute disposable services, events, and registrations.
|
||||
Harnesses are [Cordis](cordis-primer.md) contexts whose packages contribute services, typed events, and disposable registrations.
|
||||
|
||||
`packages/core/` groups the default agent flow.
|
||||
`packages/core/` groups the default agent flow; capabilities remain plugins.
|
||||
|
||||
### Default Services
|
||||
|
||||
| ctx key | Package | Role |
|
||||
|---|---|---|
|
||||
| — | [`dsh-scope`](../packages/core/scope/README.md) | scoped-context registration primitive (library) |
|
||||
| — | [`dsh-scope`](../packages/core/scope/README.md) | scoped-context registration and shared layer storage (library) |
|
||||
| `ctx.sessions` | `dsh-session` | in-memory event-sourced sessions |
|
||||
| `ctx.systemPrompt` | `dsh-system-prompt` | ordered prompt sections, tool schemas, and prompt variables |
|
||||
| `ctx.tools` | `dsh-tools` | tool registry and [execution pipeline](tool-execution-pipeline.md) |
|
||||
@@ -35,11 +37,13 @@ Harnesses are [Cordis](cordis-primer.md) contexts whose packages contribute disp
|
||||
| `ctx.web` | [`web/`](../packages/web/README.md) | search/fetch provider registries |
|
||||
| `ctx.compact`, `ctx.toolResultPrune` | [`compact/`](../packages/compact/README.md)/[`compact-tool-result-prune`](../packages/compact/compact-tool-result-prune/README.md) | summary compaction; optional model-free result pruning |
|
||||
| `ctx.subagents` | [`subagent/`](../packages/subagent/README.md) | named delegation providers |
|
||||
| `ctx.planMode` | [`plan/`](../packages/plan/README.md) | logged plan collaboration state |
|
||||
| `ctx.tasks` | [`tasks/`](../packages/tasks/README.md) | background task registry + generic `task_*` control tools |
|
||||
| `ctx.workflows` | [`workflow/`](../packages/workflow/README.md) | script-driven multi-agent orchestration |
|
||||
| `ctx.goals` | [`goal/`](../packages/goal/README.md) | persisted same-session goals |
|
||||
| `ctx.sessionPersistence` | [`session-persistence/`](../packages/session-persistence/README.md) | durable storage for session logs |
|
||||
| `ctx.sessionQuery` | [`session-query/`](../packages/session-query/README.md) | live-preferred logical-corpus exact reads and relationship traces |
|
||||
| `ctx.sessionTitle` | [`session-title/`](../packages/session-title/README.md) | log-backed fallback titles and one optional asynchronous provider |
|
||||
| `ctx.invariants` | [`support/invariants`](../packages/support/invariants/README.md) | registry and package-name selection for package-owned runtime checks |
|
||||
|
||||
## Event
|
||||
@@ -48,9 +52,9 @@ Events form the service extension API; see the exhaustive [events catalog](cordi
|
||||
|
||||
### Event Domains
|
||||
|
||||
- **Session events** are durable, replayable facts: boundaries, messages, tool activity, steering, compaction, and tool-owned records append to the log and flow through `session/event`.
|
||||
- **Agent events** carry the live `Agent` handle for status, diagnostics, prompt admission, request shaping, result validation, and continuation policy.
|
||||
- **Capability events** belong to their owning seam; `tools/*`, `llm/*`, `system-prompt/*`, `fs/*`, and `subagent/*` attach policy and adapters without importing the loop.
|
||||
- **Session events** are durable facts appended to the log and emitted through `session/event`.
|
||||
- **Agent events** carry the live `Agent` for status, prompt admission, request shaping, validation, and continuation.
|
||||
- **Capability events** let owning seams attach policy and adapters without importing the loop.
|
||||
|
||||
### Interception Semantics
|
||||
|
||||
@@ -60,9 +64,9 @@ Waterfall events behave like around-middleware: a listener delegates by calling
|
||||
|
||||
The shipped loop drains prompt-to-checkpoint work through plugin-visible services and events.
|
||||
|
||||
A **session** is an append-only log. Each ordinary **turn** claims one queued `send()` item; injection claims none. A claimed `send()` successor awaits the preceding claimed ordinary turn's checkpoint but may share its `running` interval ([decision](../.agents/notes/implemented/simplification/2026-07-17-one-send-one-turn.md)). A turn ends when model and plugins stop it. A **step** is one model request plus tools. Below ([sequence companion](agent-lifecycle.md)), quotes mark durable events; other names are extension points.
|
||||
A **session** is append-only. Each ordinary **turn** claims one queued `send()` item; injection claims none. A successor awaits the preceding claimed turn's checkpoint but may share its `running` interval ([decision](../.agents/notes/implemented/simplification/2026-07-17-one-send-one-turn.md)). A turn ends when model and plugins stop it; a **step** is one model request plus tools. In the [sequence below](agent-lifecycle.md), quotes mark durable events.
|
||||
|
||||
No id mints `<config-id>-session-<uuid>`; `sessionId` resumes/creates; `resumeSessionId` needs history. Resume restores lineage, seeds, and delegation depth pre-publication. Failures emit `agent-loop/config-start-failed(sessionId, error)`; front doors reject; teardown stays silent.
|
||||
Without an id, creation mints `<config-id>-session-<uuid>`; `sessionId` resumes or creates, while `resumeSessionId` requires history. Resume restores lineage and delegation depth before publication. Setup failures emit `agent-loop/config-start-failed`; teardown is silent.
|
||||
|
||||
### Turn Flow
|
||||
|
||||
@@ -110,43 +114,45 @@ forever:
|
||||
checkpoint persistence and notify idle/running status
|
||||
```
|
||||
|
||||
Each step assembles ordered prompt sections, tool schemas, and `{{name}}` variables; unknown or valueless references fail the turn. `dsh-system-prompt` owns the harness identity and default persona, which an agent scope may shadow. The loop supplies `model` and `cwd` ([prompt ownership](../.agents/notes/implemented/architecture/2026-07-05-prompt-variables-and-tool-guidance-ownership.md)).
|
||||
Each step assembles ordered prompt sections, tool schemas, and variables; unknown references fail the turn. `dsh-system-prompt` owns identity and persona, while the loop supplies `model` and `cwd` ([prompt ownership](../.agents/notes/implemented/architecture/2026-07-05-prompt-variables-and-tool-guidance-ownership.md)).
|
||||
|
||||
Tool-time context—including async `agent.inject()` notices and post-tool `additionalContexts`—settles after results. Steering drains; before signal closure, `agent/post-step` observes durable output, results, context, and steering. Leftovers queue. Terminal `agent/turn-stop` runs after continuation and steering folding, remains authoritative through close/flush, and discards later steering while preserving queued prompts.
|
||||
Tool-time context—including async `inject()` and post-tool `additionalContexts`—settles after results. Steering drains before `agent/post-step`, which sees durable output, results, context, and steering. Leftovers queue. Terminal `agent/turn-stop` remains authoritative through close/flush; later steering is discarded while queued prompts remain.
|
||||
|
||||
Pruning precedes summaries; overflow retries require durable progress. Bounded transient retries compose on `agent/request-error`; cancellation wins ([compaction](../.agents/notes/implemented/architecture/2026-07-10-after-call-compaction-pressure-and-overflow-recovery.md), [retry](../.agents/notes/implemented/architecture/2026-06-21-bounded-llm-request-recovery.md)).
|
||||
|
||||
### Failure Boundaries
|
||||
|
||||
The turn is the containment boundary. Adapter failures close the step, entering `agent/request-error` with the exact `Error`, `LlmFailure`, and retry history. Retry opens a numbered step; success clears history; exhaustion stores the failure on `turn/end`. Failed chunks commit no message or tool.
|
||||
The turn contains failures. Adapter failures close the step before `agent/request-error`, which receives exact `Error`, `LlmFailure`, and history. Retry opens another step; success clears history; exhaustion stores failure on `turn/end`. Failed chunks commit no message/tool.
|
||||
|
||||
Other failures use `agent/error`. Cancellation beats recovery; undispatched calls get synthetic `ABORTED` results. Effective `cancel()` emits `agent/cancel-requested` before queue clearing or abort; observers cannot veto it, and idle calls emit nothing. Disposal awaits quiescence.
|
||||
Other failures use `agent/error`. Cancellation and disposal beat recovery; undispatched tool calls get synthetic `tool/call`/`ABORTED_BEFORE_DISPATCH` pairs. The turn signal retires before `turn/end`. Effective `cancel()` emits its typed cause before clearing queues and aborting; observers cannot veto, idle calls emit nothing, and durability records `aborted`. Disposal awaits quiescence ([decision](../.agents/notes/implemented/architecture/2026-07-16-explicit-turn-cancellation.md)).
|
||||
|
||||
Every session event is turn-enclosed. Reloading preserves an interrupted tail and closes it with a synthetic `interrupted` turn end. Failures after durable turn close report only through `agent/error` because no safe in-turn position remains. Each turn has one `TurnEndReason`; [TurnEndReasonMap](core-data-structures/session.md#why-a-turn-ended-turnendreasonmap) owns the variants.
|
||||
|
||||
### Agent Handles
|
||||
|
||||
`ctx.agents` owns live agents and returns `AgentHandle { agent, dispose() }`. Plugins drive `Agent` through `send()`, `steer()`, `inject()`, `cancel()`, and `whenIdle()`. The caller fiber and factory provider structurally co-own programmatic lifecycles; the consumer handle is the only other teardown capability. All owners await one disposer.
|
||||
`ctx.agents` owns live agents and returns `AgentHandle { agent, dispose() }`. Plugins use `send()`, `steer()`, `inject()`, `cancel()`, and `whenIdle()`. The caller fiber, factory provider, and consumer handle co-own teardown through one awaited disposer.
|
||||
|
||||
### Agent Scope
|
||||
|
||||
Every live agent owns a scoped `agent.ctx`. Its registrations shadow globals, receive only that agent's dispatches, and unwind with it; async effects such as background-task cleanup are awaited. `CreateAgentOptions.setup(agentCtx)` composes the scope before publication. Typed resolvers derive carrier checks from merged `Events` signatures and `scopeTarget` ([semantic gates](../.agents/notes/implemented/process/2026-07-14-typescript-program-backed-semantic-gates.md)). See [agent scope](../.agents/notes/implemented/architecture/2026-07-08-agent-scope-contexts.md) and [subagent composition controls](../.agents/notes/implemented/feature/2026-07-12-subagent-persona-tool-filter-and-depth.md). `AgentLoop` runs drivers inside `ctx.agents.withInitiator()`; private orchestration derives `agent.session`; other identities stay explicit ([decision](../.agents/notes/implemented/architecture/2026-07-15-agent-initiator-scope.md)).
|
||||
Each agent owns a scoped `agent.ctx`; shared storage overlays global tool, prompt, and command entries while preserving domain views ([decision](../.agents/notes/implemented/architecture/2026-07-12-scoped-layers-store.md)). Scoped listeners filter dispatch, and every scoped contribution unwinds with awaited cleanup. `CreateAgentOptions.setup(agentCtx)` composes before publication. Typed resolvers derive carrier checks from merged `Events` and `scopeTarget` ([semantic gates](../.agents/notes/implemented/process/2026-07-14-typescript-program-backed-semantic-gates.md)). See [agent scope](../.agents/notes/implemented/architecture/2026-07-08-agent-scope-contexts.md) and [subagent composition](../.agents/notes/implemented/feature/2026-07-12-subagent-persona-tool-filter-and-depth.md). `AgentLoop` runs inside `ctx.agents.withInitiator()`; private orchestration derives `agent.session`, while turn, step, signal, cwd, and authority remain explicit ([decision](../.agents/notes/implemented/architecture/2026-07-15-agent-initiator-scope.md)).
|
||||
|
||||
## State
|
||||
|
||||
### Session Log
|
||||
|
||||
The session log is the source of truth. `deriveMessages()` projects session events into the `Message[]` sent to the model; raw `assistant/chunk` events stay in the log for replay and UI fidelity. Replay, fork, resume, transcript rendering, telemetry, and persistence all derive from the same event stream.
|
||||
The session log is authoritative. `deriveMessages()` projects model history; raw `assistant/chunk` events remain for replay and UI fidelity. Fork, resume, transcript rendering, telemetry, and persistence derive from the same stream.
|
||||
|
||||
**Model-visible ⟺ logged**: the log reconstructs every request — messages at `step/start` fronted by the header's session prefix, and headers by folding `request/header` — and the package-owned `dsh-agent-loop/invariant` can assert it through `ctx.invariants` ([reconstructability](../.agents/notes/implemented/architecture/2026-07-05-reconstructable-requests.md)).
|
||||
|
||||
Durability is a plugin concern. Backends buffer synchronous `session/event` notifications; the loop awaits a turn-end checkpoint. `SessionPersistence` stores `SessionEvent` directly and metadata in `SessionHeader`; JSONL defaults to checksummed Zstandard, with SQLite under one contract.
|
||||
|
||||
`ctx.sessions.appendOutOfBand()` joins plugin-owned log-only events to an open turn or creates a balanced, flushed zero-step turn. `session/title` folds latest-wins with source seqs and provenance; its immediate fallback and sole optional async provider never delay the agent response. Forks inherit titles ([decision](../.agents/notes/implemented/feature/2026-07-21-log-backed-session-titles.md)).
|
||||
|
||||
### Model Content
|
||||
|
||||
Messages contain typed blocks (`text`, `reasoning`, `tool-call`, `tool-result`) derived from merge-extensible `ContentBlockMap`; the same pattern types `MessageSource`, `FinishReason`, `TurnTrigger`, and `TurnEndReason`. New block types coordinate adapters, UI bridges, compaction pricing, token metering, and persistence as one repo-wide contract; replay measurement types live in [token-meter.md](core-data-structures/token-meter.md).
|
||||
Messages use typed blocks from merge-extensible `ContentBlockMap`; the same pattern types `MessageSource`, `FinishReason`, `TurnTrigger`, and `TurnEndReason`. New blocks coordinate adapters, UI, compaction, token metering, and persistence; replay measurements live in [token-meter.md](core-data-structures/token-meter.md).
|
||||
|
||||
Streaming uses raw chunks and `BlockAssembler`. One `LlmAdapter.stream()` is one provider attempt; adapters report facts, while recovery policy lives on `agent/request-error`. The loop logs chunks and successful provenance/replay state. Remote adapters stop stalled transport with per-read idle watchdogs. Replay state reaches targets only when routes share an adapter instance ([contract](core-data-structures/llm-streaming.md)).
|
||||
Streaming uses raw chunks and `BlockAssembler`. Each `LlmAdapter.stream()` is one provider attempt; adapters report facts and `agent/request-error` owns recovery. The loop logs chunks and successful provenance/replay state. Remote adapters use per-read idle watchdogs. Replay state crosses routes only when they share an adapter instance ([contract](core-data-structures/llm-streaming.md)).
|
||||
|
||||
## Extension And Composition
|
||||
|
||||
@@ -160,7 +166,7 @@ Exceptions combine layers: LLM interface/consumer; filesystem policy; web regist
|
||||
|
||||
### Bundles And Apps
|
||||
|
||||
`dsh-agent-spine-demo` bundles the default spine and an opt-in persisted-goal stack ([README](../packages/examples/agent-spine-demo/README.md)). `dsh-tui-demo` owns the interactive full-screen terminal and enables goals plus `/goal` by default; `dsh-cli-demo` runs one persisted headless turn with format-pure stdout; `dsh-acp-demo` adds stdout-pure ACP over JSON-RPC and enables the same goal and command stack ([ui/](../packages/ui/README.md)). `dsh-jsonrpc-agent` boots external `cordis.yml`; the Python SDK supplies its default only without an explicit config channel and drives `dsh-jsonrpc` over line-delimited JSON-RPC ([Python SDK](../python/README.md)). Deployments remain thin leaves with swappable backends and optional product tools ([examples/](../examples/AGENTS.md), [runnable wirings](cookbook/extension-cookbook.md#runnable-wirings), [graph atlas](graph-atlas.md)).
|
||||
`dsh-agent-spine-demo` bundles a spine and optional goals. App packages own the TUI, one-shot CLI, and ACP/JSON-RPC front doors ([README](../packages/examples/agent-spine-demo/README.md), [ui/](../packages/ui/README.md)). `dsh-jsonrpc-agent` boots external `cordis.yml`; the Python SDK supplies a default only without explicit config ([Python SDK](../python/README.md)). Thin deployments use swappable backends and optional tools ([examples/](../examples/AGENTS.md), [runnable wirings](cookbook/extension-cookbook.md#runnable-wirings), [graph atlas](graph-atlas.md)).
|
||||
|
||||
### Where New Behavior Goes
|
||||
|
||||
@@ -179,6 +185,7 @@ New behavior attaches to a documented extension point; a loop change updates thi
|
||||
| Add a session-stable prefix outside history | compose `agent/session-prefix`; the request header logs it |
|
||||
| Add UI or editor integration | drive `ctx.agents` and render from `session/event` |
|
||||
| Add durable session state | add a `SessionEventMap` member and render/replay from the log |
|
||||
| Add asynchronous session-title generation | register the sole provider on `ctx.sessionTitle` |
|
||||
| Manage a same-session objective | use `ctx.goals`; continue through `Agent` and `agent/*` |
|
||||
| Fork a live session | use `ctx.sessions.fork(source, boundary?, childSessionId?)` |
|
||||
| Scope a registration to one agent | use that agent's `agent.ctx` (see Agent Scope) |
|
||||
@@ -188,7 +195,6 @@ The [extension cookbook](cookbook/extension-cookbook.md) carries plugin skeleton
|
||||
## Quick Reference
|
||||
- Domain terms in the [glossary](glossary.md)
|
||||
- Type definitions in [core-data-structures/](core-data-structures/core.md)
|
||||
- Exact event and service signatures in [events](cordis-catalog/events.md)
|
||||
- [services](cordis-catalog/services.md) catalogs
|
||||
- Exact signatures in the [event](cordis-catalog/events.md) and [service](cordis-catalog/services.md) catalogs
|
||||
- package contracts in the [package map](../packages/README.md)
|
||||
- [Agent Notes](../.agents/notes/README.md)
|
||||
|
||||
200
docs/architecture.zh.md
Normal file
200
docs/architecture.zh.md
Normal file
@@ -0,0 +1,200 @@
|
||||
# DeepSeek Harness 架构
|
||||
|
||||
[English](architecture.md) | 中文
|
||||
|
||||
**DeepSeek Harness SDK** 使用 Cordis:**一切皆插件**,循环也不例外。
|
||||
|
||||
## 概览
|
||||
|
||||
每个 harness 都是一个 [Cordis](cordis-primer.md) 上下文,由各包(package)贡献服务、类型化事件和可释放的注册项。
|
||||
|
||||
`packages/core/` 汇集默认的 agent(智能体)流程;各项功能仍以插件形式存在。
|
||||
|
||||
### 默认服务
|
||||
|
||||
| ctx 键 | 包 | 职责 |
|
||||
|---|---|---|
|
||||
| — | [`dsh-scope`](../packages/core/scope/README.md) | 作用域上下文注册与共享层存储(库) |
|
||||
| `ctx.sessions` | `dsh-session` | 内存中的事件溯源会话 |
|
||||
| `ctx.systemPrompt` | `dsh-system-prompt` | 有序提示词片段、工具 schema 和提示词变量 |
|
||||
| `ctx.tools` | `dsh-tools` | 工具注册表和[执行流水线](tool-execution-pipeline.md) |
|
||||
| `ctx.agents` | `dsh-agent` | 活跃 agent、委托创建、`agent/*` 事件和进程内发起方作用域 |
|
||||
| `ctx.agentLoop` | `dsh-agent-loop` | 实体 `Agent` 驱动器 |
|
||||
|
||||
### 功能服务
|
||||
|
||||
| ctx 键 | 包族 | 职责 |
|
||||
|---|---|---|
|
||||
| `ctx.llm` | [`llm/`](../packages/llm/README.md) | 适配器注册表和模型流式调用 |
|
||||
| `ctx.tokenMeter` | [`llm/token-meter`](../packages/llm/token-meter/README.md) | 感知回放的单实例请求压力和会话表面压力 |
|
||||
| `ctx.bash` | [`bash/`](../packages/bash/README.md) | 前台和后台命令执行 |
|
||||
| `ctx.sandbox` | [`sandbox/`](../packages/sandbox/README.md) | 同一执行环境内的进程限制(argv 包装、逐调用策略) |
|
||||
| `ctx.sandboxPolicy` | [`sandbox/`](../packages/sandbox/README.md) | 共享沙箱策略归属点 |
|
||||
| `ctx.codeRuntime` | [`code-runtime/`](../packages/code-runtime/README.md) | 执行模型编写的程序 |
|
||||
| `ctx.fs` | [`fs/`](../packages/fs/README.md) | 文件系统提供方原语和策略事件 |
|
||||
| `ctx.lsp` | [`lsp/`](../packages/lsp/README.md) | 语义导航注册表 |
|
||||
| `ctx.skills` | [`skill/`](../packages/skill/README.md) | skill(技能)提供方注册表和渐进式披露 |
|
||||
| `ctx.web` | [`web/`](../packages/web/README.md) | 搜索与抓取提供方注册表 |
|
||||
| `ctx.compact`,`ctx.toolResultPrune` | [`compact/`](../packages/compact/README.md)/[`compact-tool-result-prune`](../packages/compact/compact-tool-result-prune/README.md) | 摘要压缩(compaction);可选的无模型结果裁剪 |
|
||||
| `ctx.subagents` | [`subagent/`](../packages/subagent/README.md) | 具名委托提供方 |
|
||||
| `ctx.planMode` | [`plan/`](../packages/plan/README.md) | 落日志的 plan 协作状态 |
|
||||
| `ctx.tasks` | [`tasks/`](../packages/tasks/README.md) | 后台任务注册表和通用 `task_*` 控制工具 |
|
||||
| `ctx.workflows` | [`workflow/`](../packages/workflow/README.md) | 脚本驱动的多 agent 编排 |
|
||||
| `ctx.goals` | [`goal/`](../packages/goal/README.md) | 持久化的同会话目标 |
|
||||
| `ctx.sessionPersistence` | [`session-persistence/`](../packages/session-persistence/README.md) | 会话日志的持久存储 |
|
||||
| `ctx.sessionQuery` | [`session-query/`](../packages/session-query/README.md) | 实时优先的逻辑语料精确读取和关系追踪 |
|
||||
| `ctx.sessionTitle` | [`session-title/`](../packages/session-title/README.md) | 基于日志的回退标题和单个可选异步提供方 |
|
||||
| `ctx.invariants` | [`support/invariants`](../packages/support/invariants/README.md) | 按包名选择包自有运行时检查的注册表 |
|
||||
|
||||
## 事件
|
||||
|
||||
事件构成服务的扩展 API;完整清单见[事件目录](cordis-catalog/events.md)和[生产方与消费方映射](event-producer-consumer.md)。
|
||||
|
||||
### 事件域
|
||||
|
||||
- **会话事件**是追加到日志并通过 `session/event` 发出的持久事实。
|
||||
- **Agent 事件**携带活跃 `Agent`,用于状态、提示词准入、请求塑形、验证和续跑。
|
||||
- **功能事件**让所属服务边界无需导入循环即可附加策略和适配器。
|
||||
|
||||
### 拦截语义
|
||||
|
||||
waterfall(瀑布式事件)的行为类似环绕中间件:监听器调用 `next()` 即表示委托,直接返回而不调用它则会否决或接管。完整规则见 [Cordis waterfall 语义](cordis-primer.md#cordis-waterfall-semantics)。
|
||||
|
||||
## 默认循环生命周期
|
||||
|
||||
已交付的循环通过插件可见的服务和事件,持续处理从提示词到检查点的工作。
|
||||
|
||||
**会话**采用仅追加方式。每个普通**轮次**领取一项已排队的 `send()` 输入;注入不领取输入。后续轮次会等待前一个已领取轮次的检查点,但可以与其共用同一个 `running` 区间([决策](../.agents/notes/implemented/simplification/2026-07-17-one-send-one-turn.md))。模型和插件停止轮次时,该轮次结束;一个**步骤**包含一次模型请求及其工具。在[下文时序](agent-lifecycle.md)中,引号标记持久事件。
|
||||
|
||||
未提供 id 时,创建流程会生成 `<config-id>-session-<uuid>`;`sessionId` 用于恢复或创建会话,而 `resumeSessionId` 要求已有历史。恢复流程在发布前还原沿袭关系和委托深度。初始化失败会发出 `agent-loop/config-start-failed`;拆卸过程保持静默。
|
||||
|
||||
### 轮次流程
|
||||
|
||||
```text
|
||||
choose declarative identity and fresh/resume path
|
||||
-> prepare private session + agent.ctx -> await unpublished setup
|
||||
-> enter session + agent -> session/created -> agent/created
|
||||
-> enable driving -> agent/session-start(source) -> start driver
|
||||
forever:
|
||||
wait for a queued message
|
||||
emit agent/status(running)
|
||||
TURN:
|
||||
'turn/start'
|
||||
claimed message -> agent/prompt-submit
|
||||
allowed prompt -> 'user/message' plus injected context
|
||||
blocked prompt -> 'prompt/blocked' -> 'turn/end'(rejected)
|
||||
STEP loop:
|
||||
drain steering
|
||||
assemble system prompt and tool schemas
|
||||
agent/session-prefix (first step)
|
||||
agent/pre-step
|
||||
snapshot the derived messages (the reconstruction boundary)
|
||||
'step/start'
|
||||
agent/request (config only) -> log request/header -> llm/stream (frozen)
|
||||
on final adapter-path or terminal in-band failure:
|
||||
'step/end'
|
||||
agent/request-error(original error, failure facts, immutable prior failures, signal)
|
||||
retry in the next numbered step or preserve the original error
|
||||
otherwise:
|
||||
'assistant/chunk'
|
||||
agent/step-result
|
||||
'assistant/message' (transformed content or empty success anchor after step-result rejection)
|
||||
schedule tool calls by ctx.tools.executionMode:
|
||||
exclusive -> one-call barrier
|
||||
parallel -> rolling pool, <= maxParallelToolCalls in flight; reclassify before start
|
||||
each start -> 'tool/call' -> ordered tools/pre-execute -> concurrent tools/execute
|
||||
each model-order result -> ordered tools/post-execute -> 'tool/result'
|
||||
append accepted tool-batch context after all recorded results, then steering
|
||||
agent/post-step
|
||||
'step/end'
|
||||
agent/turn-continuation
|
||||
agent/turn-stop (terminal policy)
|
||||
stop unless tools or continuation policy ask for another step
|
||||
'turn/end'
|
||||
checkpoint persistence and notify idle/running status
|
||||
```
|
||||
|
||||
每个步骤都会组装有序提示词片段、工具 schema 和变量;未知引用会使该轮次失败。`dsh-system-prompt` 负责身份和角色设定,循环则提供 `model` 和 `cwd`([提示词归属](../.agents/notes/implemented/architecture/2026-07-05-prompt-variables-and-tool-guidance-ownership.md))。
|
||||
|
||||
工具执行阶段的上下文,包括异步 `inject()` 和工具执行后的 `additionalContexts`,会在结果产生后稳定。steering(中途引导)会在 `agent/post-step` 前排空;该事件会观察持久输出、结果、上下文和 steering。余留内容进入队列。终止型 `agent/turn-stop` 在关闭和刷写期间始终具有最终决定权;后续 steering 会被丢弃,排队提示词仍予保留。
|
||||
|
||||
裁剪先于摘要;溢出重试必须取得持久进展。有界的瞬态重试在 `agent/request-error` 上组合;取消优先([压缩](../.agents/notes/implemented/architecture/2026-07-10-after-call-compaction-pressure-and-overflow-recovery.md)、[重试](../.agents/notes/implemented/architecture/2026-06-21-bounded-llm-request-recovery.md))。
|
||||
|
||||
### 失败边界
|
||||
|
||||
轮次负责隔离故障。适配器故障会先关闭步骤,再进入 `agent/request-error`;该事件会收到准确的 `Error`、`LlmFailure` 和历史记录。重试会开启另一个步骤;成功会清除历史记录;重试耗尽后,故障存入 `turn/end`。失败分片不会提交消息或工具。
|
||||
|
||||
其他故障使用 `agent/error`。取消和资源释放均优先于恢复;尚未分派的工具调用会得到合成的 `tool/call`/`ABORTED_BEFORE_DISPATCH` 对。轮次信号会在 `turn/end` 前失效。实际生效的 `cancel()` 会在清空队列和中止前发出类型化原因;观察方不能否决该操作,空闲状态下的调用不发出任何事件,持久化会记录 `aborted`。dispose(资源释放)会等待系统停稳([决策](../.agents/notes/implemented/architecture/2026-07-16-explicit-turn-cancellation.md))。
|
||||
|
||||
每个会话事件都包围在轮次内。重新加载会保留中断的日志尾部,并用合成的 `interrupted` 轮次结束事件将其闭合。持久轮次关闭后的故障只通过 `agent/error` 报告,因为此时已没有安全的轮次内位置。每个轮次有一个 `TurnEndReason`;各变体由 [TurnEndReasonMap](core-data-structures/session.md#why-a-turn-ended-turnendreasonmap) 统一定义。
|
||||
|
||||
### Agent 句柄
|
||||
|
||||
`ctx.agents` 拥有活跃 agent,并返回 `AgentHandle { agent, dispose() }`。插件使用 `send()`、`steer()`、`inject()`、`cancel()` 和 `whenIdle()`。调用方 fiber、工厂提供方和消费方句柄通过同一个需等待完成的 disposer 共同拥有拆卸过程。
|
||||
|
||||
### Agent 作用域
|
||||
|
||||
每个 agent 都拥有一个作用域化的 `agent.ctx`;共享存储会在全局工具、提示词和命令条目之上叠加作用域条目,同时保留各领域视图([决策](../.agents/notes/implemented/architecture/2026-07-12-scoped-layers-store.md))。作用域监听器会过滤分派,每项作用域贡献都会在撤销时等待清理完成。`CreateAgentOptions.setup(agentCtx)` 在发布前完成组合。类型化解析器从合并后的 `Events` 和 `scopeTarget` 推导载体检查([语义门禁](../.agents/notes/implemented/process/2026-07-14-typescript-program-backed-semantic-gates.md))。参见 [agent 作用域](../.agents/notes/implemented/architecture/2026-07-08-agent-scope-contexts.md)和 [subagent 组合](../.agents/notes/implemented/feature/2026-07-12-subagent-persona-tool-filter-and-depth.md)。`AgentLoop` 在 `ctx.agents.withInitiator()` 内运行;私有编排会派生 `agent.session`,而轮次、步骤、信号、cwd 和权限仍保持显式([决策](../.agents/notes/implemented/architecture/2026-07-15-agent-initiator-scope.md))。
|
||||
|
||||
## 状态
|
||||
|
||||
### 会话日志
|
||||
|
||||
会话日志是权威依据。`deriveMessages()` 投影出模型历史;原始 `assistant/chunk` 事件留在日志中,以保证回放和 UI 保真。fork、恢复、transcript(文本记录)渲染、遥测和持久化均派生自同一个事件流。
|
||||
|
||||
**模型可见 ⟺ 已记录**:日志可以重建每个请求,包括由请求头会话前缀置于开头的 `step/start` 时消息,以及通过折叠 `request/header` 得到的请求头;开发期不变量会断言这一点([可重建性](../.agents/notes/implemented/architecture/2026-07-05-reconstructable-requests.md))。
|
||||
|
||||
持久性由插件负责。后端会缓冲同步的 `session/event` 通知;循环等待轮次结束检查点。`SessionPersistence` 直接存储 `SessionEvent`,并将元数据存入 `SessionHeader`;JSONL 默认采用带校验和的 Zstandard,SQLite 则遵循同一契约。
|
||||
|
||||
`ctx.sessions.appendOutOfBand()` 会把插件所属的纯日志事件加入开放轮次,或创建一个平衡且已刷写的零步骤轮次。`session/title` 按后写覆盖方式折叠,并携带源 seq 和来源信息;其即时回退标题和唯一可选异步提供方都不会延迟 agent 响应。fork 会继承标题([决策](../.agents/notes/implemented/feature/2026-07-21-log-backed-session-titles.md))。
|
||||
|
||||
### 模型内容
|
||||
|
||||
消息使用从可合并扩展的 `ContentBlockMap` 派生的类型化块;`MessageSource`、`FinishReason`、`TurnTrigger` 和 `TurnEndReason` 也采用同一模式定义类型。新增块会协调适配器、UI、压缩、token 计量和持久化;回放计量见 [token-meter.md](core-data-structures/token-meter.md)。
|
||||
|
||||
流式输出使用原始分片和 `BlockAssembler`。每次 `LlmAdapter.stream()` 调用代表一次提供方尝试;适配器报告事实,`agent/request-error` 负责恢复。循环会记录分片及成功结果的来源信息和回放状态。远程适配器使用逐次读取空闲看门狗。只有当路由共用同一个适配器实例时,回放状态才会跨路由传递([契约](core-data-structures/llm-streaming.md))。
|
||||
|
||||
## 扩展与组合
|
||||
|
||||
### 功能模式
|
||||
|
||||
可替换功能通常拆分为**接口/实现/消费方**:服务和事件、后端,以及面向模型的工具和提示词。Bash 是参考实现;[功能图](capability-seams.md)映射了每个包族。
|
||||
|
||||
例外情况会合并不同层次:LLM(大语言模型)合并接口和消费方,文件系统整合策略,web 使用注册表,skill 和 subagent 使用具名提供方。subagent 可以通过 spawn 创建全新实例、fork 一个已完成轮次的前缀,或使用 ACP(Agent Client Protocol)子 agent([subagent.md](core-data-structures/subagent.md))。
|
||||
|
||||
`dsh-workspace-context` 在 `agent/session-prefix` 上组合基线,并在通过 `ctx.fs` 发现嵌套变更后,于 `tools/post-execute` 追加这些变更;其[决策](../.agents/notes/implemented/feature/2026-06-24-workspace-context.md)记录了隔离方式。`dsh-paths` 负责共享路径。
|
||||
|
||||
### 组合包与应用
|
||||
|
||||
`dsh-agent-spine-demo` 组合一套主干和可选目标。应用包负责 TUI、单次运行的 CLI(命令行界面)以及 ACP/JSON-RPC 入口([README](../packages/examples/agent-spine-demo/README.md)、[ui/](../packages/ui/README.md))。`dsh-jsonrpc-agent` 启动外部 `cordis.yml`;Python SDK 仅在没有显式配置时提供默认项([Python SDK](../python/README.md))。轻量部署使用可替换后端和可选工具([examples/](../examples/AGENTS.md)、[可运行接线](cookbook/extension-cookbook.md#runnable-wirings)、[图谱](graph-atlas.md))。
|
||||
|
||||
### 新行为的归属位置
|
||||
|
||||
新行为附加到已有文档记录的扩展点;循环发生变更时,本架构图随之更新。
|
||||
|
||||
| 目标 | 机制 |
|
||||
|---|---|
|
||||
| 添加模型提供方 | 在 `ctx.llm` 上注册适配器 |
|
||||
| 添加面向模型的功能 | 在 `ctx.tools` 上注册;schema 进入提示词组装流程 |
|
||||
| 添加 shell 执行 | 实现并注册 `ctx.bash` 后端 |
|
||||
| 添加用户命令 | 在 `ctx.commands` 上注册;适配器无需模型轮次即可发现并分派该命令 |
|
||||
| 添加后台工作 | 在 `ctx.tasks` 上注册;通用 `task_*` 工具负责收集或停止 |
|
||||
| 添加文件系统访问或策略 | 实现 `ctx.fs` 提供方,或监听 `fs/*` 策略事件 |
|
||||
| 限制生成的进程 | 使用 `ctx.sandbox` 后端;消费方在生成进程前包装 argv |
|
||||
| 拦截请求、工具或轮次 | 使用相应的 `agent/*` 或 `tools/*` 事件;`agent/turn-stop` 是串行终止判定点 |
|
||||
| 添加历史记录之外的会话稳定前缀 | 组合 `agent/session-prefix`;请求头会记录该前缀 |
|
||||
| 添加 UI 或编辑器集成 | 驱动 `ctx.agents` 并从 `session/event` 渲染 |
|
||||
| 添加持久会话状态 | 添加一个 `SessionEventMap` 成员,并从日志渲染和回放 |
|
||||
| 添加异步会话标题生成 | 在 `ctx.sessionTitle` 上注册唯一提供方 |
|
||||
| 管理同会话目标 | 使用 `ctx.goals`;通过 `Agent` 和 `agent/*` 续跑 |
|
||||
| fork 活跃会话 | 使用 `ctx.sessions.fork(source, boundary?, childSessionId?)` |
|
||||
| 将注册项限定到单个 agent | 使用该 agent 的 `agent.ctx`(参见 Agent 作用域) |
|
||||
|
||||
[扩展实操手册(cookbook)](cookbook/extension-cookbook.md)提供插件骨架和功能到服务边界的映射;分步指南涵盖[包](cookbook/adding-a-package.md)、[工具](cookbook/adding-a-tool.md)、[LLM 适配器](cookbook/adding-an-llm-adapter.md)和 [vendored 包](cookbook/adding-a-vendored-package.md)。
|
||||
|
||||
## 快速参考
|
||||
- [术语表](glossary.md)中的领域术语
|
||||
- [core-data-structures/](core-data-structures/core.md) 中的类型定义
|
||||
- [事件](cordis-catalog/events.md)和[服务](cordis-catalog/services.md)目录中的准确签名
|
||||
- [包索引](../packages/README.md)中的包契约
|
||||
- [Agent Note(agent 决策记录)](../.agents/notes/README.md)
|
||||
@@ -36,6 +36,10 @@ flowchart LR
|
||||
pkg_hooks_codex["hooks-codex"]
|
||||
pkg_acp["acp"]
|
||||
svc_sessionQuery["ctx.sessionQuery<br/>Exact session-history reads and traces"]
|
||||
pkg_session_title["session-title"]
|
||||
svc_sessionTitle["ctx.sessionTitle<br/>Log-backed session titles"]
|
||||
pkg_session_title_first_message_llm["session-title-first-message-llm"]
|
||||
pkg_session_title_all_messages_llm["session-title-all-messages-llm"]
|
||||
pkg_system_prompt["system-prompt"]
|
||||
svc_systemPrompt["ctx.systemPrompt<br/>System prompt assembly registry"]
|
||||
pkg_tools["tools"]
|
||||
@@ -50,6 +54,8 @@ flowchart LR
|
||||
pkg_user_interaction["user-interaction"]
|
||||
svc_userInteraction["ctx.userInteraction<br/>Human question/answer seam"]
|
||||
pkg_tui["tui"]
|
||||
pkg_plan_mode["plan-mode"]
|
||||
svc_planMode["ctx.planMode<br/>Plan collaboration state"]
|
||||
pkg_commands["commands"]
|
||||
svc_commands["ctx.commands<br/>Human command registry"]
|
||||
pkg_skill["skill"]
|
||||
@@ -132,6 +138,7 @@ flowchart LR
|
||||
pkg_llm_pi_ai --> svc_llm
|
||||
pkg_llm_replay --> svc_llm
|
||||
pkg_permission --> svc_permission
|
||||
pkg_plan_mode --> svc_planMode
|
||||
pkg_sandbox --> svc_sandbox
|
||||
pkg_sandbox_local --> svc_sandbox
|
||||
pkg_sandbox_policy --> svc_sandboxPolicy
|
||||
@@ -140,6 +147,9 @@ flowchart LR
|
||||
pkg_session_persistence_jsonl --> svc_sessionPersistence
|
||||
pkg_session_persistence_sqlite --> svc_sessionPersistence
|
||||
pkg_session_query --> svc_sessionQuery
|
||||
pkg_session_title --> svc_sessionTitle
|
||||
pkg_session_title_all_messages_llm --> svc_sessionTitle
|
||||
pkg_session_title_first_message_llm --> svc_sessionTitle
|
||||
pkg_skill --> svc_skills
|
||||
pkg_skill_local --> svc_skills
|
||||
pkg_spill --> svc_spillStore
|
||||
@@ -185,6 +195,7 @@ flowchart LR
|
||||
svc_llm --> pkg_agent_loop
|
||||
svc_llm --> pkg_compact_basic
|
||||
svc_permission --> pkg_acp
|
||||
svc_planMode --> pkg_acp
|
||||
svc_sandbox --> pkg_bash_sandbox
|
||||
svc_sandboxPolicy --> pkg_bash_sandbox
|
||||
svc_sandboxPolicy --> pkg_fs_sandbox
|
||||
@@ -241,9 +252,11 @@ flowchart LR
|
||||
| `ctx.invariants` | `core` | [`invariants`](../packages/support/invariants) | - | [`session`](../packages/core/session), [`agent`](../packages/core/agent), [`scope`](../packages/core/scope), [`agent-loop`](../packages/core/agent-loop) | - | Companion subpaths register owner-local checks; the service owns selection, uniqueness, child fibers, and package-attributed failures. |
|
||||
| `ctx.sessionPersistence` | `seam` | [`session-persistence`](../packages/session-persistence/session-persistence) | [`session-persistence-jsonl`](../packages/session-persistence/session-persistence-jsonl), [`session-persistence-sqlite`](../packages/session-persistence/session-persistence-sqlite) | [`agent-loop`](../packages/core/agent-loop), [`tool-bash`](../packages/bash/tool-bash), [`hooks-claude`](../packages/hooks/hooks-claude), [`hooks-codex`](../packages/hooks/hooks-codex), [`acp`](../packages/ui/acp), [`session-query`](../packages/session-query/session-query) | - | Backends persist the same SessionEvent vocabulary; apps choose a backend at composition time. |
|
||||
| `ctx.sessionQuery` | `seam` | [`session-query`](../packages/session-query/session-query) | - | - | - | Resolves live and optional persisted logs into one logical corpus for exact reads and relationship traces. |
|
||||
| `ctx.sessionTitle` | `seam` | [`session-title`](../packages/session-title/session-title) | [`session-title-first-message-llm`](../packages/session-title/session-title-first-message-llm), [`session-title-all-messages-llm`](../packages/session-title/session-title-all-messages-llm) | - | - | Owns the deterministic fallback, latest-title fold, and sole optional asynchronous provider registration. |
|
||||
| `ctx.systemPrompt` | `core` | [`system-prompt`](../packages/core/system-prompt) | - | [`agent-loop`](../packages/core/agent-loop), [`tools`](../packages/core/tools), [`tool-fs`](../packages/fs/tool-fs), [`tool-web`](../packages/web/tool-web) | - | Collects prompt sections and model-facing tool schemas for each step. |
|
||||
| `ctx.tools` | `core` | [`tools`](../packages/core/tools) | - | [`agent-loop`](../packages/core/agent-loop), [`tool-ask-user`](../packages/ui/tool-ask-user), [`tool-bash`](../packages/bash/tool-bash), [`tool-cordis`](../packages/cordis/tool-cordis), [`tool-fs`](../packages/fs/tool-fs), [`tool-skill`](../packages/skill/tool-skill), [`tool-subagent`](../packages/subagent/tool-subagent), [`tool-todo`](../packages/todo/tool-todo), [`tool-web`](../packages/web/tool-web), [`acp`](../packages/ui/acp) | - | Registers capabilities, owns Code Mode transport, and routes calls through pre-policy, monotonic guards, around dispatch, post-policy, and final-result observation. |
|
||||
| `ctx.userInteraction` | `seam` | [`user-interaction`](../packages/ui/user-interaction) | [`tui`](../packages/ui/tui), [`acp`](../packages/ui/acp) | [`tool-ask-user`](../packages/ui/tool-ask-user), [`tui`](../packages/ui/tui), [`acp`](../packages/ui/acp) | - | UI front doors provide the active human-answer provider; tool-ask-user pauses a tool call on the provider-neutral ask() promise. |
|
||||
| `ctx.planMode` | `core` | [`plan-mode`](../packages/plan/plan-mode) | - | [`acp`](../packages/ui/acp) | - | Folds logged plan/mode state, flushes user selections at turn boundaries, renders deployment-owned guidance, registers /plan, and keeps the plan-exit schema stable across transitions. |
|
||||
| `ctx.commands` | `core` | [`commands`](../packages/ui/commands) | - | [`tui`](../packages/ui/tui), [`acp`](../packages/ui/acp) | - | Plugins register direct human commands; TUI and ACP consume the same effective per-agent catalog without sending invocations to the model. |
|
||||
| `ctx.skills` | `seam` | [`skill`](../packages/skill/skill) | [`skill-local`](../packages/skill/skill-local) | [`tool-skill`](../packages/skill/tool-skill) | - | Merges provider skill catalogs; tool-skill renders the session-prefix catalog and loads complete skill bodies. |
|
||||
| `ctx.agents` | `core` | [`agent`](../packages/core/agent) | - | [`agent-loop`](../packages/core/agent-loop), [`acp`](../packages/ui/acp), [`cli-demo`](../packages/examples/cli-demo), [`subagent-inprocess`](../packages/subagent/subagent-inprocess), [`tui-demo`](../packages/examples/tui-demo) | - | Owns live Agent handles, the create/resume factory seam, and process-local initiator propagation. |
|
||||
|
||||
@@ -27,7 +27,7 @@ export interface AcpConfig {
|
||||
|
||||
Depends on: `Stream` (`@agentclientprotocol/sdk`)
|
||||
|
||||
Source: [`packages/ui/acp/src/index.ts:252`](../packages/ui/acp/src/index.ts)
|
||||
Source: [`packages/ui/acp/src/index.ts:275`](../packages/ui/acp/src/index.ts)
|
||||
|
||||
## `@deepseek-ai/dsh-acp-demo`
|
||||
|
||||
@@ -56,6 +56,8 @@ export interface Config {
|
||||
tools?: ToolsConfig
|
||||
/** DeepSeek Harness home directory exposed to bash and used for local skill discovery. */
|
||||
dshHome?: string
|
||||
/** Fallback session-title limits forwarded through agent-spine-demo. */
|
||||
sessionTitle?: NonNullable<agentCore.Config['sessionTitle']>
|
||||
/** Directory the JSONL session backend writes under. Defaults to `./.sessions`. */
|
||||
persistenceRoot?: string
|
||||
/** JSONL artifact encoding; defaults to checksummed Zstandard frames. */
|
||||
@@ -118,7 +120,8 @@ Source: [`packages/core/agent-loop/src/index.ts:360`](../packages/core/agent-loo
|
||||
* bridge, simply omits it), `persona` and `toolOrder` to the system-prompt
|
||||
* plugin (the deployment's persona section and the explicit model-facing tool
|
||||
* order), the `tools` object to the tool registry (its presentation `mode`),
|
||||
* `dshHome` to bash environment and local skill discovery, `skills` to the
|
||||
* `dshHome` to bash environment and local skill discovery, `sessionTitle` to
|
||||
* the fallback title service, `skills` to the
|
||||
* skill registry/local provider/tool consumer, `workspaceContext` to the
|
||||
* workspace-context loader, `llmRetry` to the bounded request-recovery policy,
|
||||
* and `toolBash`/`toolTasks` to the model-facing tool plugins this bundle owns.
|
||||
@@ -143,6 +146,8 @@ export interface Config {
|
||||
tools?: ToolsConfig
|
||||
/** DeepSeek Harness home directory shared by shell context and local skill discovery. */
|
||||
dshHome?: string
|
||||
/** Deterministic fallback and accepted-title limits; omission uses the bundle's example policy. */
|
||||
sessionTitle?: SessionTitleConfig
|
||||
/** Workspace-context loader controls with an explicit byte budget; set `false` for hermetic prompts. */
|
||||
workspaceContext: workspaceContext.Config | false
|
||||
/** Skill registry, local provider, and model-facing consumer config. */
|
||||
@@ -180,9 +185,9 @@ export interface GoalConfig {
|
||||
}
|
||||
```
|
||||
|
||||
Depends on: [`AgentLoopConfig`](#deepseek-aidsh-agent-loop) · [`GoalDomainConfig`](#deepseek-aidsh-goal) · [`InvariantConfig`](#deepseek-aidsh-invariants) · [`llmRetry`](../packages/llm/llm-retry/src/index.ts) · [`SkillLocal`](../packages/skill/skill-local/src/index.ts) · [`SkillRegistryConfig`](#deepseek-aidsh-skill) · [`SystemPromptConfig`](#deepseek-aidsh-system-prompt) · [`toolBash`](../packages/bash/tool-bash/src/index.ts) · [`toolGoal`](../packages/goal/tool-goal/src/index.ts) · [`ToolsConfig`](#deepseek-aidsh-tools) · [`toolSkill`](../packages/skill/tool-skill/src/index.ts) · [`toolTasks`](../packages/tasks/tool-tasks/src/index.ts) · [`workspaceContext`](../packages/context/workspace-context/src/index.ts)
|
||||
Depends on: [`AgentLoopConfig`](#deepseek-aidsh-agent-loop) · [`GoalDomainConfig`](#deepseek-aidsh-goal) · [`InvariantConfig`](#deepseek-aidsh-invariants) · [`llmRetry`](../packages/llm/llm-retry/src/index.ts) · [`SessionTitleConfig`](#deepseek-aidsh-session-title) · [`SkillLocal`](../packages/skill/skill-local/src/index.ts) · [`SkillRegistryConfig`](#deepseek-aidsh-skill) · [`SystemPromptConfig`](#deepseek-aidsh-system-prompt) · [`toolBash`](../packages/bash/tool-bash/src/index.ts) · [`toolGoal`](../packages/goal/tool-goal/src/index.ts) · [`ToolsConfig`](#deepseek-aidsh-tools) · [`toolSkill`](../packages/skill/tool-skill/src/index.ts) · [`toolTasks`](../packages/tasks/tool-tasks/src/index.ts) · [`workspaceContext`](../packages/context/workspace-context/src/index.ts)
|
||||
|
||||
Source: [`packages/examples/agent-spine-demo/src/index.ts:78`](../packages/examples/agent-spine-demo/src/index.ts)
|
||||
Source: [`packages/examples/agent-spine-demo/src/index.ts:87`](../packages/examples/agent-spine-demo/src/index.ts)
|
||||
|
||||
## `@deepseek-ai/dsh-bash-local`
|
||||
|
||||
@@ -244,6 +249,8 @@ export interface Config {
|
||||
tools?: ToolsConfig
|
||||
/** DeepSeek Harness home directory exposed to bash and used for local skill discovery. */
|
||||
dshHome?: string
|
||||
/** Fallback session-title limits forwarded through agent-spine-demo. */
|
||||
sessionTitle?: NonNullable<agentCore.Config['sessionTitle']>
|
||||
/** Directory the JSONL session backend writes under. Defaults to `./.sessions`. */
|
||||
persistenceRoot?: string
|
||||
/** JSONL artifact encoding; defaults to checksummed Zstandard frames. */
|
||||
@@ -778,6 +785,20 @@ Depends on: [`ApprovalPolicy`](core-data-structures/approval.md) · [`SandboxMod
|
||||
|
||||
Source: [`packages/ui/permission/src/index.ts:83`](../packages/ui/permission/src/index.ts)
|
||||
|
||||
## `@deepseek-ai/dsh-plan-mode`
|
||||
|
||||
Requires: `tools` · `systemPrompt`
|
||||
|
||||
```ts config-catalog
|
||||
/** Deployment-owned plan guidance. */
|
||||
export interface PlanModeConfig {
|
||||
/** Guidance rendered as the `plan:policy` prompt section while plan mode is active. */
|
||||
section: string
|
||||
}
|
||||
```
|
||||
|
||||
Source: [`packages/plan/plan-mode/src/index.ts:57`](../packages/plan/plan-mode/src/index.ts)
|
||||
|
||||
## `@deepseek-ai/dsh-repeat-tool-guard`
|
||||
|
||||
```ts config-catalog
|
||||
@@ -884,7 +905,7 @@ export interface Config {
|
||||
export type JsonlCompression = 'zstd' | 'none'
|
||||
```
|
||||
|
||||
Source: [`packages/session-persistence/session-persistence-jsonl/src/index.ts:36`](../packages/session-persistence/session-persistence-jsonl/src/index.ts)
|
||||
Source: [`packages/session-persistence/session-persistence-jsonl/src/index.ts:37`](../packages/session-persistence/session-persistence-jsonl/src/index.ts)
|
||||
|
||||
## `@deepseek-ai/dsh-session-persistence-sqlite`
|
||||
|
||||
@@ -939,6 +960,50 @@ export interface Config {
|
||||
|
||||
Source: [`packages/session-query/session-query/src/config.ts:9`](../packages/session-query/session-query/src/config.ts)
|
||||
|
||||
## `@deepseek-ai/dsh-session-title`
|
||||
|
||||
Requires: `sessions`
|
||||
|
||||
```ts config-catalog
|
||||
/** Required deterministic fallback and accepted-title limits. */
|
||||
export interface Config {
|
||||
/** Maximum whitespace-delimited words in the built-in fallback. */
|
||||
readonly fallbackMaxWords: number
|
||||
/** Maximum UTF-8 bytes in the built-in fallback. */
|
||||
readonly fallbackMaxBytes: number
|
||||
/** Maximum UTF-8 bytes in any accepted title. */
|
||||
readonly maxTitleBytes: number
|
||||
}
|
||||
```
|
||||
|
||||
Source: [`packages/session-title/session-title/src/index.ts:69`](../packages/session-title/session-title/src/index.ts)
|
||||
|
||||
## `@deepseek-ai/dsh-session-title-all-messages-llm`
|
||||
|
||||
Requires: `sessionTitle` · `llm` · `sessions`
|
||||
|
||||
```ts config-catalog
|
||||
/** Required LLM policy; this plugin adds no defaults. */
|
||||
export type Config = SessionTitleLlmConfig
|
||||
```
|
||||
|
||||
Depends on: [`SessionTitleLlmConfig`](../packages/session-title/session-title-llm/src/index.ts)
|
||||
|
||||
Source: [`packages/session-title/session-title-all-messages-llm/src/index.ts:15`](../packages/session-title/session-title-all-messages-llm/src/index.ts)
|
||||
|
||||
## `@deepseek-ai/dsh-session-title-first-message-llm`
|
||||
|
||||
Requires: `sessionTitle` · `llm` · `sessions`
|
||||
|
||||
```ts config-catalog
|
||||
/** Required LLM policy; this plugin adds no defaults. */
|
||||
export type Config = SessionTitleLlmConfig
|
||||
```
|
||||
|
||||
Depends on: [`SessionTitleLlmConfig`](../packages/session-title/session-title-llm/src/index.ts)
|
||||
|
||||
Source: [`packages/session-title/session-title-first-message-llm/src/index.ts:15`](../packages/session-title/session-title-first-message-llm/src/index.ts)
|
||||
|
||||
## `@deepseek-ai/dsh-skill`
|
||||
|
||||
```ts config-catalog
|
||||
@@ -1043,7 +1108,7 @@ export interface Config {
|
||||
* before the parent escalates to a signal.
|
||||
*/
|
||||
disposeEofGraceMs?: number
|
||||
/** Grace period (ms) between `SIGTERM` and the `SIGKILL` escalation on dispose. */
|
||||
/** Termination confirmation window (ms), including forced exit on every platform. */
|
||||
disposeGraceMs?: number
|
||||
}
|
||||
|
||||
@@ -1100,7 +1165,7 @@ export interface Config {
|
||||
}
|
||||
```
|
||||
|
||||
Source: [`packages/core/system-prompt/src/index.ts:143`](../packages/core/system-prompt/src/index.ts)
|
||||
Source: [`packages/core/system-prompt/src/index.ts:147`](../packages/core/system-prompt/src/index.ts)
|
||||
|
||||
## `@deepseek-ai/dsh-time-context`
|
||||
|
||||
@@ -1399,7 +1464,7 @@ export interface Config {
|
||||
export type ToolPresentationMode = 'native' | 'code' | 'both'
|
||||
```
|
||||
|
||||
Source: [`packages/core/tools/src/index.ts:382`](../packages/core/tools/src/index.ts)
|
||||
Source: [`packages/core/tools/src/index.ts:419`](../packages/core/tools/src/index.ts)
|
||||
|
||||
## `@deepseek-ai/dsh-tui`
|
||||
|
||||
@@ -1408,10 +1473,18 @@ Requires: `agents` · `commands` · `userInteraction` · `tools` · `llm` · `sy
|
||||
```ts config-catalog
|
||||
/** Serializable plugin configuration. */
|
||||
export interface Config extends TuiConfig {
|
||||
/** Header subtitle. Defaults to `ready.`. */
|
||||
/** Banner subtitle line. When absent, the banner has no subtitle and sweeps in on start. */
|
||||
welcome?: string
|
||||
/** Exact shared agent/session identity driven by this terminal. Defaults to `main`. */
|
||||
sessionId?: string
|
||||
/**
|
||||
* Shell command template shown for resuming this session: printed on exit and
|
||||
* listed by `/resume`, with every `{session}` occurrence replaced by the live
|
||||
* session id. Absent disables both surfaces. Deployments set it only when a
|
||||
* persistence backend makes the session resumable (e.g.
|
||||
* `RESUME_SESSION_ID={session} dsh`).
|
||||
*/
|
||||
resumeCommand?: string
|
||||
}
|
||||
|
||||
/** Presentation settings for the pi-tui terminal mode. */
|
||||
@@ -1436,12 +1509,19 @@ export interface TuiConfig {
|
||||
showHardwareCursor?: boolean
|
||||
/** Apply the built-in ANSI color palette. */
|
||||
color?: boolean
|
||||
/** Terminal window title while the UI is mounted. */
|
||||
/**
|
||||
* Paint the startup banner's product name in the DeepSeek brand gradient
|
||||
* using 24-bit truecolor. Requires {@link TuiConfig.color}; falls back to the
|
||||
* flat accent color when either is off. Unset auto-detects `COLORTERM` at the
|
||||
* process boundary, so most deployments leave it unset.
|
||||
*/
|
||||
truecolor?: boolean
|
||||
/** Terminal window title while the UI is mounted; a logged session title prefixes it. */
|
||||
title?: string
|
||||
}
|
||||
```
|
||||
|
||||
Source: [`packages/ui/tui/src/index.ts:127`](../packages/ui/tui/src/index.ts)
|
||||
Source: [`packages/ui/tui/src/index.ts:145`](../packages/ui/tui/src/index.ts)
|
||||
|
||||
## `@deepseek-ai/dsh-tui-demo`
|
||||
|
||||
@@ -1462,12 +1542,21 @@ export interface Config {
|
||||
tools?: ToolsConfig
|
||||
/** DeepSeek Harness home directory exposed to bash and used for local skill discovery. */
|
||||
dshHome?: string
|
||||
/** Fallback session-title limits forwarded through agent-spine-demo. */
|
||||
sessionTitle?: NonNullable<agentCore.Config['sessionTitle']>
|
||||
/** Directory the JSONL session backend writes under. Defaults to `./.sessions`. */
|
||||
persistenceRoot?: string
|
||||
/** JSONL artifact encoding; defaults to checksummed Zstandard frames. */
|
||||
persistenceCompression?: JsonlCompression
|
||||
/** TUI subtitle rendered on start. Defaults to `ready.`. */
|
||||
/** TUI transcript's optional first line; absent renders nothing on start. */
|
||||
welcome?: string
|
||||
/**
|
||||
* Shell command template the TUI prints on exit and lists under `/resume`,
|
||||
* with `{session}` replaced by the live session id (forwarded to the front
|
||||
* door). Set it to a command that resumes via this app's env var, e.g.
|
||||
* `RESUME_SESSION_ID={session} dsh`.
|
||||
*/
|
||||
resumeCommand?: string
|
||||
/** Full-screen TUI presentation settings. */
|
||||
ui?: uiTui.TuiConfig
|
||||
/** Skill registry, local-provider, and model-facing consumer config. */
|
||||
@@ -1487,7 +1576,7 @@ export interface Config {
|
||||
|
||||
Depends on: [`agentCore`](../packages/examples/agent-spine-demo/src/index.ts) · [`JsonlCompression`](../packages/session-persistence/session-persistence-jsonl/src/index.ts) · [`ToolsConfig`](#deepseek-aidsh-tools) · [`uiTui`](../packages/ui/tui/src/index.ts)
|
||||
|
||||
Source: [`packages/examples/tui-demo/src/index.ts:33`](../packages/examples/tui-demo/src/index.ts)
|
||||
Source: [`packages/examples/tui-demo/src/index.ts:32`](../packages/examples/tui-demo/src/index.ts)
|
||||
|
||||
## `@deepseek-ai/dsh-user-approval`
|
||||
|
||||
@@ -1518,7 +1607,7 @@ export interface Config {
|
||||
export type ApprovalPolicy = 'ask' | 'never'
|
||||
```
|
||||
|
||||
Source: [`packages/ui/user-approval/src/index.ts:214`](../packages/ui/user-approval/src/index.ts)
|
||||
Source: [`packages/ui/user-approval/src/index.ts:198`](../packages/ui/user-approval/src/index.ts)
|
||||
|
||||
## `@deepseek-ai/dsh-web`
|
||||
|
||||
@@ -1672,18 +1761,34 @@ export interface Config {
|
||||
maxBytes: number
|
||||
/** Maximum UTF-8 bytes read from one instruction file; larger files are ignored. */
|
||||
maxSourceBytes?: number
|
||||
/** Ordered same-directory project candidates; the first existing regular file wins in each scope. */
|
||||
/**
|
||||
* Ordered same-directory project candidates; every existing file loads, with
|
||||
* per-directory trimmed-content duplicates collapsed to the earliest candidate.
|
||||
*/
|
||||
instructionFileCandidates?: string[]
|
||||
/**
|
||||
* Ordered same-directory local-overlay candidates loaded after the base files
|
||||
* under the same per-directory trimmed-content dedup; empty disables the overlay.
|
||||
*/
|
||||
localInstructionFileCandidates?: string[]
|
||||
}
|
||||
```
|
||||
|
||||
Source: [`packages/context/workspace-context/src/config.ts:16`](../packages/context/workspace-context/src/config.ts)
|
||||
Source: [`packages/context/workspace-context/src/config.ts:17`](../packages/context/workspace-context/src/config.ts)
|
||||
|
||||
## Loadable plugins with no config
|
||||
|
||||
These load from a `cordis.yml` entry with no `config:` block; they declare no config surface.
|
||||
|
||||
- `@deepseek-ai/dsh-agent` ([`packages/core/agent/src/index.ts`](../packages/core/agent/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-connection` ([`packages/client/connection/src/index.ts`](../packages/client/connection/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-i18n` ([`packages/client/i18n/src/index.ts`](../packages/client/i18n/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-runtime` ([`packages/client/runtime/src/index.ts`](../packages/client/runtime/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-conversation` ([`packages/client/ui-conversation/src/index.ts`](../packages/client/ui-conversation/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-layout` ([`packages/client/ui-layout/src/index.ts`](../packages/client/ui-layout/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-sidebar` ([`packages/client/ui-sidebar/src/index.ts`](../packages/client/ui-sidebar/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-theme` ([`packages/client/ui-theme/src/index.ts`](../packages/client/ui-theme/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-trajectory` ([`packages/client/ui-trajectory/src/index.ts`](../packages/client/ui-trajectory/src/index.ts))
|
||||
- `@deepseek-ai/dsh-command-goal` — requires `commands` · `goals` ([`packages/goal/command-goal/src/index.ts`](../packages/goal/command-goal/src/index.ts))
|
||||
- `@deepseek-ai/dsh-commands` ([`packages/ui/commands/src/index.ts`](../packages/ui/commands/src/index.ts))
|
||||
- `@deepseek-ai/dsh-fs-policy` ([`packages/fs/fs-policy/src/index.ts`](../packages/fs/fs-policy/src/index.ts))
|
||||
@@ -1720,15 +1825,22 @@ Imported as libraries by other packages; a `cordis.yml` cannot load them.
|
||||
- `@deepseek-ai/dsh-agent-loop-testkit` ([`packages/support/agent-loop-testkit/src/index.ts`](../packages/support/agent-loop-testkit/src/index.ts))
|
||||
- `@deepseek-ai/dsh-app-boot` ([`packages/ui/app-boot/src/index.ts`](../packages/ui/app-boot/src/index.ts))
|
||||
- `@deepseek-ai/dsh-brand` ([`packages/util/brand/src/index.ts`](../packages/util/brand/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-primitives` ([`packages/client/ui-primitives/src/index.ts`](../packages/client/ui-primitives/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-slots` ([`packages/client/ui-slots/src/index.ts`](../packages/client/ui-slots/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-web` ([`packages/client/web/src/index.ts`](../packages/client/web/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-web-react` ([`packages/client/web-react/src/index.ts`](../packages/client/web-react/src/index.ts))
|
||||
- `@deepseek-ai/dsh-helper` ([`packages/sdk/helper/src/index.ts`](../packages/sdk/helper/src/index.ts))
|
||||
- `@deepseek-ai/dsh-home` ([`packages/util/home/src/index.ts`](../packages/util/home/src/index.ts))
|
||||
- `@deepseek-ai/dsh-hook-protocol` ([`packages/hooks/hook-protocol/src/index.ts`](../packages/hooks/hook-protocol/src/index.ts))
|
||||
- `@deepseek-ai/dsh-host-apiproxy` ([`packages/host/apiproxy/src/index.ts`](../packages/host/apiproxy/src/index.ts))
|
||||
- `@deepseek-ai/dsh-host-runtime` ([`packages/host/runtime/src/index.ts`](../packages/host/runtime/src/index.ts))
|
||||
- `@deepseek-ai/dsh-host-webserver` ([`packages/host/webserver/src/index.ts`](../packages/host/webserver/src/index.ts))
|
||||
- `@deepseek-ai/dsh-jsonrpc-demo` ([`packages/examples/jsonrpc-demo/src/index.ts`](../packages/examples/jsonrpc-demo/src/index.ts))
|
||||
- `@deepseek-ai/dsh-loader-smoke` ([`packages/support/loader-smoke/src/index.ts`](../packages/support/loader-smoke/src/index.ts))
|
||||
- `@deepseek-ai/dsh-paths` ([`packages/util/paths/src/index.ts`](../packages/util/paths/src/index.ts))
|
||||
- `@deepseek-ai/dsh-retention` ([`packages/util/retention/src/index.ts`](../packages/util/retention/src/index.ts))
|
||||
- `@deepseek-ai/dsh-scope` ([`packages/core/scope/src/index.ts`](../packages/core/scope/src/index.ts))
|
||||
- `@deepseek-ai/dsh-scripts` ([`packages/sdk/scripts/src/index.ts`](../packages/sdk/scripts/src/index.ts))
|
||||
- `@deepseek-ai/dsh-session-title-llm` ([`packages/session-title/session-title-llm/src/index.ts`](../packages/session-title/session-title-llm/src/index.ts))
|
||||
- `@deepseek-ai/dsh-subagent-inprocess` ([`packages/subagent/subagent-inprocess/src/index.ts`](../packages/subagent/subagent-inprocess/src/index.ts))
|
||||
- `@deepseek-ai/dsh-subagent-subprocess` ([`packages/subagent/subagent-subprocess/src/index.ts`](../packages/subagent/subagent-subprocess/src/index.ts))
|
||||
- `@deepseek-ai/dsh-telemetry` ([`packages/sdk/telemetry/src/index.ts`](../packages/sdk/telemetry/src/index.ts))
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write
|
||||
adding-a-tool.md: a45315dc0ec92ab28963c2aca32dffcf5f778dcd
|
||||
adding-a-tool.zh.md: f574957ddd0e42cedc93ddc0f3270110a8f110c5
|
||||
adding-a-tool.md: 9e8fa1287c854f33f62a4c6a1ed93adfccc19471
|
||||
adding-a-tool.zh.md: be4e0800036ac9bde949a11d8a35e49cfb92efd7
|
||||
|
||||
@@ -25,7 +25,7 @@ export function apply(ctx: Context) {
|
||||
async execute(args, exec) {
|
||||
// args is TYPED from the schema: { path: string; limit?: number }
|
||||
// exec carries immutable identity + token; signal is the operational field
|
||||
return [{ type: 'text', text: await readFile(args.path, 'utf8') }]
|
||||
return [{ type: 'text', text: await readFile(args.path, { encoding: 'utf8', signal: exec.signal }) }]
|
||||
},
|
||||
}))
|
||||
}
|
||||
@@ -37,7 +37,7 @@ Registration is effect-based: disposing the plugin fiber unregisters the tool (w
|
||||
|
||||
- **Args are validated for you.** `defineTool` validates the model-generated `arguments` against the `SchemaSpec` before `execute` runs (type, required keys, enum membership, nested objects/arrays — [runtime arg validation](../../.agents/notes/implemented/architecture/2026-06-11-runtime-arg-validation.md)), so inside `execute` the args already match `InferArgs`. You still hand-check value constraints the DSL can't express (non-empty strings, positive numbers, cross-field rules); throw a descriptive Error for those. Raw JSON-Schema tools registered directly (MCP) are NOT validated by the harness — they validate their own input.
|
||||
- **Registration borrows your readonly definition.** A typed same-process contribution is not a serialization boundary; do not mutate its schema or replace callbacks after registration. `schemas()` materializes only the explicit model-facing projection. To hot-swap a tool, dispose its owning effect and register the replacement; mutable state inside the callback's closure remains ordinary plugin state.
|
||||
- **Execution identity is protected.** The registry materializes `arguments` as detached lossless JSON in one recursive pass, freezes that value before policy starts, and assigns an opaque `exec.token`; `callId`, `name`, `arguments`, `agent`, `token`, and an optional enclosing-transport `parent` token stay immutable through dispatch. `parent` is identity-only and exposes no live outer execution. Treat `args` as readonly input. An around-dispatch wrapper may add, replace, or remove only `exec.signal` to impose cancellation or a deadline.
|
||||
- **Execution identity is protected.** The registry materializes `arguments` as detached lossless JSON in one recursive pass, freezes that value before policy starts, and assigns an opaque `exec.token`; `callId`, `name`, `arguments`, `agent`, `token`, the required caller-owned `signal`, and an optional enclosing-transport `parent` token stay immutable through dispatch. `parent` is identity-only and exposes no live outer execution. Treat `args` as readonly input. Only an around-dispatch wrapper receives a mutable view, and it may replace and restore the required `exec.signal` to impose a deadline but cannot remove it.
|
||||
- **Throwing or returning non-JSON data means `isError`.** The registry catches throws and materializes the final result before observers run. A malformed or non-JSON result becomes `{ isError: true }`, preventing a live success that cannot be logged. Throw for infrastructure failures; report domain failures in result text when the model must interpret them.
|
||||
- **Honor `exec.signal`.** Cancel in-flight work when it fires.
|
||||
- **Attach durable card data with `meta` (optional).** `execute` may return `{ content, meta }` instead of a bare `ContentBlock[]` — `meta` is a JSON-serializable payload the core treats as opaque, persisted on the `tool/result` event and handed back to your `presentResult` (so a card that needs more than `args`, like `write`/`edit`'s applied-hunk diff, survives a session replay). Keep UI-only data here, never in the model-facing `content`.
|
||||
@@ -45,7 +45,7 @@ Registration is effect-based: disposing the plugin fiber unregisters the tool (w
|
||||
|
||||
## Long-running work
|
||||
|
||||
Gate `run_in_background` with producer config, reject a pre-aborted call, then register through `ctx.tasks.start({ kind, label, owner: exec.agent, run })`. The runtime validates ownership and control-surface availability before `run()` starts work, then supplies the id, session fence, generic control tools, notices, and owner cleanup.
|
||||
Gate `run_in_background` with producer config, then register through `ctx.tasks.start({ kind, label, owner: exec.agent, run })`. The registry skips a pre-aborted invocation before the producer body; the runtime validates ownership and control-surface availability before `run()` starts work, then supplies the id, session fence, generic control tools, notices, and owner cleanup.
|
||||
|
||||
The producer supplies synchronous `cancel`, non-rejecting `done` that settles after resource cleanup, and optional consuming `readOutput` with bounded-output formatting. Once the id is returned, use a task-owned cancellation signal rather than `exec.signal`. See the [background task runtime Agent Note](../../.agents/notes/implemented/architecture/2026-06-20-generic-long-running-tool-runtime.md) and `dsh-tool-bash` for a stream producer.
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ export function apply(ctx: Context) {
|
||||
async execute(args, exec) {
|
||||
// args is TYPED from the schema: { path: string; limit?: number }
|
||||
// exec carries immutable identity + token; signal is the operational field
|
||||
return [{ type: 'text', text: await readFile(args.path, 'utf8') }]
|
||||
return [{ type: 'text', text: await readFile(args.path, { encoding: 'utf8', signal: exec.signal }) }]
|
||||
},
|
||||
}))
|
||||
}
|
||||
@@ -37,7 +37,7 @@ export function apply(ctx: Context) {
|
||||
|
||||
- **参数已为你校验。** `defineTool` 在 `execute` 运行前,会根据 `SchemaSpec` 校验模型生成的 `arguments`(类型、必填键、枚举成员、嵌套对象/数组——见[运行时参数校验](../../.agents/notes/implemented/architecture/2026-06-11-runtime-arg-validation.md)),因此 `execute` 内部的 args 已匹配 `InferArgs`。你仍需手动检查 DSL 无法表达的值约束(非空字符串、正数、跨字段规则),对这些情况抛出描述性 Error。直接注册的原始 JSON-Schema 工具(MCP)不由 harness 校验,它们自行校验输入。
|
||||
- **注册借用你的只读定义。** 类型化的同进程贡献不是序列化边界;注册后不要修改其 schema 或替换回调。`schemas()` 只物化显式的模型可见投影。如需热替换工具,请 dispose 其所属副作用并注册替代品;回调闭包内的可变状态仍是普通的插件状态。
|
||||
- **执行身份受保护。** 注册表在一次递归遍历中将 `arguments` 物化为分离的无损 JSON,在策略开始前冻结该值,并分配一个不透明的 `exec.token`;`callId`、`name`、`arguments`、`agent`、`token` 以及可选的外层传输 `parent` token 在整个分发过程中保持不可变。`parent` 仅用于身份标识,不暴露活跃的外层执行。请将 `args` 视为只读输入。around-dispatch 包装器只能添加、替换或移除 `exec.signal`,以施加取消或截止时间。
|
||||
- **执行身份受保护。** 注册表在一次递归遍历中将 `arguments` 物化为分离的无损 JSON,在策略开始前冻结该值,并分配一个不透明的 `exec.token`;`callId`、`name`、`arguments`、`agent`、`token`、必填且由调用方持有的 `signal`,以及可选的外层传输 `parent` token 在整个分发过程中保持不可变。`parent` 仅用于身份标识,不暴露活跃的外层执行。请将 `args` 视为只读输入。只有 around-dispatch 包装器会收到可变视图;它可以替换并恢复必填的 `exec.signal` 以施加截止时间,但不能移除该信号。
|
||||
- **抛出异常或返回非 JSON 数据意味着 `isError`。** 注册表捕获异常,并在观察者运行前物化最终结果。格式错误或非 JSON 的结果变为 `{ isError: true }`,防止出现无法记录的活跃成功。基础设施故障请抛异常;当模型需要解读领域失败时,请在结果文本中报告。
|
||||
- **遵守 `exec.signal`。** 信号触发时取消进行中的工作。
|
||||
- **使用 `meta` 附加持久化的卡片数据(可选)。** `execute` 可以返回 `{ content, meta }` 而非裸的 `ContentBlock[]`。`meta` 是 JSON 可序列化的载荷,核心将其视为不透明数据,持久化在 `tool/result` 事件上并回传给你的 `presentResult`(这样需要 `args` 之外信息的卡片——如 `write`/`edit` 的已应用 hunk diff——在会话回放中依然存活)。仅在此处放 UI 数据,绝不放入模型可见的 `content`。
|
||||
@@ -45,7 +45,7 @@ export function apply(ctx: Context) {
|
||||
|
||||
## 长时间运行的工作
|
||||
|
||||
通过 producer 配置控制 `run_in_background`,拒绝已预先中止的调用,然后使用 `ctx.tasks.start({ kind, label, owner: exec.agent, run })` 注册任务。运行时会在 `run()` 启动工作前校验 owner 和控制面是否可用,随后提供 id、会话围栏、通用控制工具、通知和 owner cleanup。
|
||||
通过 producer 配置控制 `run_in_background`,然后使用 `ctx.tasks.start({ kind, label, owner: exec.agent, run })` 注册任务。注册表会在进入 producer 主体前跳过已预先中止的调用;运行时会在 `run()` 启动工作前校验 owner 和控制面是否可用,随后提供 id、会话围栏、通用控制工具、通知和 owner cleanup。
|
||||
|
||||
producer 提供同步的 `cancel`、在资源清理后 settle 且不 reject 的 `done`,以及可选的消费式 `readOutput`(负责有界输出的格式化)。返回 id 后,应使用 task 自有的取消信号,而不是 `exec.signal`。流式 producer 的示例和完整契约见[后台 task 运行时 Agent Note](../../.agents/notes/implemented/architecture/2026-06-20-generic-long-running-tool-runtime.md)与 `dsh-tool-bash`。
|
||||
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write
|
||||
extension-cookbook.md: a1f6d2f0d27b2258ae06236721bbd80cbd3af80e
|
||||
extension-cookbook.zh.md: f7729492b68bfef50d5e289581028d0c0c4164cf
|
||||
extension-cookbook.md: 8873cac21960e2e2efe0e8c6c5868c3a8e7ee75c
|
||||
extension-cookbook.zh.md: f34e9f2fa707be69b13ac408cc1ede1a86310fae
|
||||
|
||||
@@ -87,7 +87,7 @@ export function apply(ctx: Context) {
|
||||
|
||||
## Runnable wirings
|
||||
|
||||
Four runnable leaves load their plugin trees from `cordis.yml`: [`examples/tui-agent`](../../examples/tui-agent) (DeepSeek coding tools through the full-screen TUI, `pnpm run demo:tui`), [`examples/headless-agent`](../../examples/headless-agent) (the coding capabilities behind a one-shot task and DSH-native output, `pnpm run demo:headless "task"`), [`examples/cordis-agent`](../../examples/cordis-agent) (self-inspection and dynamic plugin mounting through the TUI, `pnpm run demo:cordis`), and [`examples/acp-agent`](../../examples/acp-agent) (an ACP server over JSON-RPC stdio, `pnpm run demo:acp`). Interactive leaves load [`@deepseek-ai/dsh-tui-demo`](../../packages/examples/tui-demo), non-interactive leaves load [`@deepseek-ai/dsh-cli-demo`](../../packages/examples/cli-demo), the ACP leaf loads [`@deepseek-ai/dsh-acp-demo`](../../packages/examples/acp-demo), and all three app packages share [`@deepseek-ai/dsh-agent-spine-demo`](../../packages/examples/agent-spine-demo).
|
||||
Runnable leaves load their plugin trees from `examples/*/cordis.yml`; the root `demo:*` scripts and those leaf directories are the authoritative inventory. Interactive leaves use [`@deepseek-ai/dsh-tui-demo`](../../packages/examples/tui-demo), non-interactive leaves use [`@deepseek-ai/dsh-cli-demo`](../../packages/examples/cli-demo), ACP leaves use [`@deepseek-ai/dsh-acp-demo`](../../packages/examples/acp-demo), and the app packages share [`@deepseek-ai/dsh-agent-spine-demo`](../../packages/examples/agent-spine-demo).
|
||||
|
||||
## The feature → mechanism map
|
||||
|
||||
@@ -113,7 +113,7 @@ Every product feature maps to a listener on a documented extension seam — the
|
||||
| Monotonic terminal turn policy | return `{ action: 'stop' }` from serial `agent/turn-stop`, after continuation and steering have already been folded |
|
||||
| Subprocess sandbox (landlock / sandbox-exec) | use a `ctx.sandbox` backend through `dsh-bash-sandbox`; use `tools/pre-execute` for capability-level denial |
|
||||
| Permission system / AskUserQuestion | return `ask` from `tools/pre-execute` and answer through `ctx.approval`; register a separate model-facing ask tool for ordinary user questions |
|
||||
| Plan mode | `tools/pre-execute` (deny writes) + a mode prompt section via `ctx.systemPrompt.section()` or `agent.inject()` (model-visible ⟺ logged: `agent/request` shapes call config only) |
|
||||
| Plan mode | Shipped: [`@deepseek-ai/dsh-plan-mode`](../../packages/plan/plan-mode/README.md) — logged `plan/mode` state, the `plan:policy` guidance section, `/plan [message]`, and the user-reviewed `exit_plan_mode` exit; enforcement stays on the independent sandbox/approval axes |
|
||||
| Sub-agent delegation | the `ctx.subagents` provider registry (`dsh-subagent-spawn`/`-fork`/`-acp`) + `dsh-tool-subagent` exposing one configured provider to the model |
|
||||
| MCP | one plugin per server: discover tools → `ctx.tools.register()` |
|
||||
| Skills | section + tool registration; `inject()` skill content on invocation |
|
||||
|
||||
@@ -87,7 +87,7 @@ export function apply(ctx: Context) {
|
||||
|
||||
## 可运行的组装示例
|
||||
|
||||
四个可运行叶子从 `cordis.yml` 加载各自的插件树:[`examples/tui-agent`](../../examples/tui-agent)(通过全屏 TUI 运行的 DeepSeek coding 工具,`pnpm run demo:tui`)、[`examples/headless-agent`](../../examples/headless-agent)(通过单次任务和 DSH 原生输出运行的 coding 能力,`pnpm run demo:headless "task"`)、[`examples/cordis-agent`](../../examples/cordis-agent)(通过 TUI 进行自我检查和动态插件挂载,`pnpm run demo:cordis`)与 [`examples/acp-agent`](../../examples/acp-agent)(通过 JSON-RPC stdio 暴露的 ACP 服务器,`pnpm run demo:acp`)。交互式叶子加载 [`@deepseek-ai/dsh-tui-demo`](../../packages/examples/tui-demo),非交互式叶子加载 [`@deepseek-ai/dsh-cli-demo`](../../packages/examples/cli-demo),ACP 叶子加载 [`@deepseek-ai/dsh-acp-demo`](../../packages/examples/acp-demo),三个 app 包都通过 [`@deepseek-ai/dsh-agent-spine-demo`](../../packages/examples/agent-spine-demo) 共享主干。
|
||||
可运行叶子从 `examples/*/cordis.yml` 加载各自的插件树;根目录的 `demo:*` 脚本和这些叶子目录是权威清单。交互式叶子使用 [`@deepseek-ai/dsh-tui-demo`](../../packages/examples/tui-demo),非交互式叶子使用 [`@deepseek-ai/dsh-cli-demo`](../../packages/examples/cli-demo),ACP 叶子使用 [`@deepseek-ai/dsh-acp-demo`](../../packages/examples/acp-demo),应用包共享 [`@deepseek-ai/dsh-agent-spine-demo`](../../packages/examples/agent-spine-demo)。
|
||||
|
||||
## 功能→机制映射
|
||||
|
||||
@@ -113,7 +113,7 @@ export function apply(ctx: Context) {
|
||||
| 单调终端轮次策略 | 从串行 `agent/turn-stop` 返回 `{ action: 'stop' }`,此时 continuation 和 steering 已折叠完毕 |
|
||||
| 子进程沙箱(landlock / sandbox-exec) | 通过 `dsh-bash-sandbox` 使用 `ctx.sandbox` 后端;能力级别的拒绝使用 `tools/pre-execute` |
|
||||
| 权限系统 / AskUserQuestion | 从 `tools/pre-execute` 返回 `ask` 并通过 `ctx.approval` 应答;为普通用户提问注册一个独立的面向模型的 ask 工具 |
|
||||
| Plan mode | `tools/pre-execute`(拒绝写操作)+ 通过 `ctx.systemPrompt.section()` 或 `agent.inject()` 注入模式提示词段(model-visible ⟺ logged:`agent/request` 仅塑形调用配置) |
|
||||
| Plan mode | 已交付:[`@deepseek-ai/dsh-plan-mode`](../../packages/plan/plan-mode/README.md) — 落日志的 `plan/mode` 状态、`plan:policy` 引导段、`/plan [message]`,以及经用户评审的 `exit_plan_mode` 出口;强制约束留在独立的沙箱/审批轴上 |
|
||||
| 子 agent 委派 | `ctx.subagents` 提供方注册表(`dsh-subagent-spawn`/`-fork`/`-acp`)+ `dsh-tool-subagent` 向模型暴露一个已配置的提供方 |
|
||||
| MCP | 每个服务器一个插件:发现工具 → `ctx.tools.register()` |
|
||||
| Skill(技能) | section + 工具注册;调用时通过 `inject()` 注入 skill 内容 |
|
||||
|
||||
@@ -15,24 +15,24 @@ Dispatch modes: **emit** (fire-and-forget), **waterfall** (each listener gets `n
|
||||
|
||||
### `agent/cancel-requested` — emit
|
||||
|
||||
Effective broad cancellation was requested, before queued/steering work is cleared or the active step is aborted. This observe-only notification cannot veto cancellation; listener failures are contained.
|
||||
Effective broad cancellation was requested, before queued/steering work is cleared or the active turn is aborted. This observe-only notification cannot veto cancellation; listener failures are contained.
|
||||
|
||||
```ts cordis-catalog
|
||||
/**
|
||||
* Effective broad cancellation was requested, before queued/steering work
|
||||
* is cleared or the active step is aborted. This observe-only notification
|
||||
* is cleared or the active turn is aborted. This observe-only notification
|
||||
* cannot veto cancellation; listener failures are contained.
|
||||
* @param agent - the agent whose current work is being cancelled.
|
||||
* @param reason - resolved cancellation reason, including the default.
|
||||
* @param cause - resolved typed cancellation cause, including the default.
|
||||
* Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent.
|
||||
* @mode emit
|
||||
*/
|
||||
'agent/cancel-requested'(this: Scoped<Agent>, agent: Agent, reason: string): void
|
||||
'agent/cancel-requested'(this: Scoped<Agent>, agent: Agent, cause: AgentCancelCause): void
|
||||
```
|
||||
|
||||
Types: [Agent](../core-data-structures/core.md) · [Scoped](../core-data-structures/scope.md)
|
||||
Types: [Agent](../core-data-structures/core.md) · [AgentCancelCause](../core-data-structures/core.md) · [Scoped](../core-data-structures/scope.md)
|
||||
|
||||
Source: [`packages/core/agent/src/types.ts:191`](../../packages/core/agent/src/types.ts)
|
||||
Source: [`packages/core/agent/src/types.ts:201`](../../packages/core/agent/src/types.ts)
|
||||
|
||||
### `agent/created` — emit
|
||||
|
||||
@@ -54,7 +54,7 @@ A fully configured agent and live session were published. Setup is composition-o
|
||||
|
||||
Types: [Agent](../core-data-structures/core.md) · [Scoped](../core-data-structures/scope.md)
|
||||
|
||||
Source: [`packages/core/agent/src/types.ts:153`](../../packages/core/agent/src/types.ts)
|
||||
Source: [`packages/core/agent/src/types.ts:163`](../../packages/core/agent/src/types.ts)
|
||||
|
||||
### `agent/disposed` — emit
|
||||
|
||||
@@ -74,7 +74,7 @@ An agent left the registry; AgentLoop emits this after driver quiescence but bef
|
||||
|
||||
Types: [Agent](../core-data-structures/core.md) · [Scoped](../core-data-structures/scope.md)
|
||||
|
||||
Source: [`packages/core/agent/src/types.ts:162`](../../packages/core/agent/src/types.ts)
|
||||
Source: [`packages/core/agent/src/types.ts:172`](../../packages/core/agent/src/types.ts)
|
||||
|
||||
### `agent/error` — emit
|
||||
|
||||
@@ -96,7 +96,7 @@ A step or turn errored. The loop reports a failure here (plus the logger) even w
|
||||
|
||||
Types: [Agent](../core-data-structures/core.md) · [Scoped](../core-data-structures/scope.md)
|
||||
|
||||
Source: [`packages/core/agent/src/types.ts:328`](../../packages/core/agent/src/types.ts)
|
||||
Source: [`packages/core/agent/src/types.ts:346`](../../packages/core/agent/src/types.ts)
|
||||
|
||||
### `agent/post-step` — serial
|
||||
|
||||
@@ -119,7 +119,7 @@ Awaited serial checkpoint after the response, real or synthetic tool results, in
|
||||
|
||||
Types: [Agent](../core-data-structures/core.md) · [Scoped](../core-data-structures/scope.md)
|
||||
|
||||
Source: [`packages/core/agent/src/types.ts:280`](../../packages/core/agent/src/types.ts)
|
||||
Source: [`packages/core/agent/src/types.ts:296`](../../packages/core/agent/src/types.ts)
|
||||
|
||||
### `agent/pre-step` — serial
|
||||
|
||||
@@ -142,28 +142,31 @@ Awaited serial checkpoint before `step/start`; appends land outside the pending
|
||||
|
||||
Types: [Agent](../core-data-structures/core.md) · [Scoped](../core-data-structures/scope.md)
|
||||
|
||||
Source: [`packages/core/agent/src/types.ts:220`](../../packages/core/agent/src/types.ts)
|
||||
Source: [`packages/core/agent/src/types.ts:230`](../../packages/core/agent/src/types.ts)
|
||||
|
||||
### `agent/prompt-submit` — waterfall
|
||||
|
||||
Allow, rewrite, or block one claimed prompt before it becomes a user message. Call `next()` for the unchanged default.
|
||||
Allow, rewrite, or block one claimed prompt before it becomes a user message. Call `next()` for the unchanged default. The signal controls only this turn; listeners may cooperate with it but must not retain it to control another turn.
|
||||
|
||||
```ts cordis-catalog
|
||||
/**
|
||||
* Allow, rewrite, or block one claimed prompt before it becomes a user
|
||||
* message. Call `next()` for the unchanged default.
|
||||
* message. Call `next()` for the unchanged default. The signal controls only
|
||||
* this turn; listeners may cooperate with it but must not retain it to
|
||||
* control another turn.
|
||||
* @param agent - the agent whose turn claimed the message.
|
||||
* @param content - the claimed message's blocks, as queued.
|
||||
* @param source - the message's resolved source.
|
||||
* @param signal - the current turn's explicit abort signal.
|
||||
* Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent.
|
||||
* @mode waterfall
|
||||
*/
|
||||
'agent/prompt-submit'(this: Scoped<Agent>, agent: Agent, content: ContentBlock[], source: MessageSource, next: () => Promise<PromptDecision>): Promise<PromptDecision>
|
||||
'agent/prompt-submit'(this: Scoped<Agent>, agent: Agent, content: ContentBlock[], source: MessageSource, signal: AbortSignal, next: () => Promise<PromptDecision>): Promise<PromptDecision>
|
||||
```
|
||||
|
||||
Types: [Agent](../core-data-structures/core.md) · [ContentBlock](../core-data-structures/core.md) · [MessageSource](../core-data-structures/core.md) · [PromptDecision](../core-data-structures/core.md) · [Scoped](../core-data-structures/scope.md)
|
||||
|
||||
Source: [`packages/core/agent/src/types.ts:230`](../../packages/core/agent/src/types.ts)
|
||||
Source: [`packages/core/agent/src/types.ts:243`](../../packages/core/agent/src/types.ts)
|
||||
|
||||
### `agent/queued` — emit
|
||||
|
||||
@@ -184,7 +187,7 @@ Detached, frozen content entered the agent's inbox. Source defaults have already
|
||||
|
||||
Types: [Agent](../core-data-structures/core.md) · [ContentBlock](../core-data-structures/core.md) · [MessageSource](../core-data-structures/core.md) · [Scoped](../core-data-structures/scope.md)
|
||||
|
||||
Source: [`packages/core/agent/src/types.ts:181`](../../packages/core/agent/src/types.ts)
|
||||
Source: [`packages/core/agent/src/types.ts:191`](../../packages/core/agent/src/types.ts)
|
||||
|
||||
### `agent/request` — waterfall
|
||||
|
||||
@@ -199,15 +202,17 @@ Replace the frozen call configuration. Model-visible content must use logged cha
|
||||
* @param turn - the open turn number.
|
||||
* @param step - the step whose request this is.
|
||||
* @param config - the config the loop would use (frozen); return a replacement to switch.
|
||||
* @param signal - the current turn's explicit abort signal; ambient
|
||||
* initiator identity does not imply liveness or cancellation authority.
|
||||
* Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent.
|
||||
* @mode waterfall
|
||||
*/
|
||||
'agent/request'(this: Scoped<Agent>, agent: Agent, turn: number, step: number, config: LlmCallConfig, next: () => Promise<LlmCallConfig>): Promise<LlmCallConfig>
|
||||
'agent/request'(this: Scoped<Agent>, agent: Agent, turn: number, step: number, config: LlmCallConfig, signal: AbortSignal, next: () => Promise<LlmCallConfig>): Promise<LlmCallConfig>
|
||||
```
|
||||
|
||||
Types: [Agent](../core-data-structures/core.md) · [LlmCallConfig](../core-data-structures/core.md) · [Scoped](../core-data-structures/scope.md)
|
||||
|
||||
Source: [`packages/core/agent/src/types.ts:242`](../../packages/core/agent/src/types.ts)
|
||||
Source: [`packages/core/agent/src/types.ts:257`](../../packages/core/agent/src/types.ts)
|
||||
|
||||
### `agent/request-error` — waterfall
|
||||
|
||||
@@ -233,7 +238,7 @@ Recover a model-request failure after its failed step has closed. `retry` opens
|
||||
|
||||
Types: [Agent](../core-data-structures/core.md) · [LlmFailure](../core-data-structures/llm-streaming.md) · [RequestError](../core-data-structures/core.md) · [RequestErrorDecision](../core-data-structures/core.md) · [Scoped](../core-data-structures/scope.md)
|
||||
|
||||
Source: [`packages/core/agent/src/types.ts:295`](../../packages/core/agent/src/types.ts)
|
||||
Source: [`packages/core/agent/src/types.ts:311`](../../packages/core/agent/src/types.ts)
|
||||
|
||||
### `agent/session-prefix` — waterfall
|
||||
|
||||
@@ -251,7 +256,7 @@ Compose request-only messages placed before derived history. The frozen result i
|
||||
* Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent.
|
||||
* @param agent - the agent whose session prefix is being composed.
|
||||
* @param prefix - the frozen seed; return an extended replacement.
|
||||
* @param signal - aborts composition when the step is torn down.
|
||||
* @param signal - the current turn's explicit abort signal.
|
||||
* @mode waterfall
|
||||
*/
|
||||
'agent/session-prefix'(this: Scoped<Agent>, agent: Agent, prefix: Message[], signal: AbortSignal, next: () => Promise<Message[]>): Promise<Message[]>
|
||||
@@ -259,7 +264,7 @@ Compose request-only messages placed before derived history. The frozen result i
|
||||
|
||||
Types: [Agent](../core-data-structures/core.md) · [Message](../core-data-structures/core.md) · [Scoped](../core-data-structures/scope.md)
|
||||
|
||||
Source: [`packages/core/agent/src/types.ts:257`](../../packages/core/agent/src/types.ts)
|
||||
Source: [`packages/core/agent/src/types.ts:272`](../../packages/core/agent/src/types.ts)
|
||||
|
||||
### `agent/session-start` — emit
|
||||
|
||||
@@ -281,7 +286,7 @@ The session lifecycle began, once before the first turn. Use `agent.inject()` to
|
||||
|
||||
Types: [Agent](../core-data-structures/core.md) · [Scoped](../core-data-structures/scope.md) · [SessionStartSource](../core-data-structures/core.md)
|
||||
|
||||
Source: [`packages/core/agent/src/types.ts:204`](../../packages/core/agent/src/types.ts)
|
||||
Source: [`packages/core/agent/src/types.ts:214`](../../packages/core/agent/src/types.ts)
|
||||
|
||||
### `agent/status` — emit
|
||||
|
||||
@@ -301,7 +306,7 @@ Agent status changed (`idle` ⇄ `running`, or → `disposed`). `send()` does no
|
||||
|
||||
Types: [Agent](../core-data-structures/core.md) · [AgentStatus](../core-data-structures/core.md) · [Scoped](../core-data-structures/scope.md)
|
||||
|
||||
Source: [`packages/core/agent/src/types.ts:171`](../../packages/core/agent/src/types.ts)
|
||||
Source: [`packages/core/agent/src/types.ts:181`](../../packages/core/agent/src/types.ts)
|
||||
|
||||
### `agent/step-result` — waterfall
|
||||
|
||||
@@ -315,15 +320,16 @@ Waterfall: post-process the assembled assistant Message before tool dispatch (va
|
||||
* @param turn - the open turn number.
|
||||
* @param step - the step that produced the message.
|
||||
* @param message - the assistant message as assembled from the stream.
|
||||
* @param signal - the current turn's explicit abort signal.
|
||||
* Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent.
|
||||
* @mode waterfall
|
||||
*/
|
||||
'agent/step-result'(this: Scoped<Agent>, agent: Agent, turn: number, step: number, message: Message, next: () => Promise<Message>): Promise<Message>
|
||||
'agent/step-result'(this: Scoped<Agent>, agent: Agent, turn: number, step: number, message: Message, signal: AbortSignal, next: () => Promise<Message>): Promise<Message>
|
||||
```
|
||||
|
||||
Types: [Agent](../core-data-structures/core.md) · [Message](../core-data-structures/core.md) · [Scoped](../core-data-structures/scope.md)
|
||||
|
||||
Source: [`packages/core/agent/src/types.ts:268`](../../packages/core/agent/src/types.ts)
|
||||
Source: [`packages/core/agent/src/types.ts:284`](../../packages/core/agent/src/types.ts)
|
||||
|
||||
### `agent/turn-continuation` — waterfall
|
||||
|
||||
@@ -336,15 +342,16 @@ Override whether the turn continues. The default continues after tool calls or s
|
||||
* @param agent - the agent deciding whether to run another step.
|
||||
* @param turn - the turn being continued or stopped.
|
||||
* @param defaultDecision - what the loop would do absent an override.
|
||||
* @param signal - the current turn's explicit abort signal.
|
||||
* Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent.
|
||||
* @mode waterfall
|
||||
*/
|
||||
'agent/turn-continuation'(this: Scoped<Agent>, agent: Agent, turn: number, defaultDecision: ContinuationDecision, next: () => Promise<ContinuationDecision>): Promise<ContinuationDecision>
|
||||
'agent/turn-continuation'(this: Scoped<Agent>, agent: Agent, turn: number, defaultDecision: ContinuationDecision, signal: AbortSignal, next: () => Promise<ContinuationDecision>): Promise<ContinuationDecision>
|
||||
```
|
||||
|
||||
Types: [Agent](../core-data-structures/core.md) · [ContinuationDecision](../core-data-structures/core.md) · [Scoped](../core-data-structures/scope.md)
|
||||
|
||||
Source: [`packages/core/agent/src/types.ts:305`](../../packages/core/agent/src/types.ts)
|
||||
Source: [`packages/core/agent/src/types.ts:322`](../../packages/core/agent/src/types.ts)
|
||||
|
||||
### `agent/turn-stop` — serial
|
||||
|
||||
@@ -357,15 +364,16 @@ Monotonic terminal-stop checkpoint after continuation and steering are folded; a
|
||||
* steering queued in that window is discarded, while ordinary sends survive.
|
||||
* @param agent - the agent whose composed continuation outcome may be stopped.
|
||||
* @param turn - the turn at its terminal-stop checkpoint.
|
||||
* @param signal - the current turn's explicit abort signal.
|
||||
* Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent.
|
||||
* @mode serial
|
||||
*/
|
||||
'agent/turn-stop'(this: Scoped<Agent>, agent: Agent, turn: number): ContinuationStop | undefined
|
||||
'agent/turn-stop'(this: Scoped<Agent>, agent: Agent, turn: number, signal: AbortSignal): Promise<ContinuationStop | undefined> | ContinuationStop | undefined
|
||||
```
|
||||
|
||||
Types: [Agent](../core-data-structures/core.md) · [ContinuationStop](../core-data-structures/core.md) · [Scoped](../core-data-structures/scope.md)
|
||||
|
||||
Source: [`packages/core/agent/src/types.ts:315`](../../packages/core/agent/src/types.ts)
|
||||
Source: [`packages/core/agent/src/types.ts:333`](../../packages/core/agent/src/types.ts)
|
||||
|
||||
## `agent-loop/*`
|
||||
|
||||
@@ -409,7 +417,7 @@ Ask composed answerers for one decision. Return an outcome to claim the request
|
||||
|
||||
Types: [ApprovalOutcome](../core-data-structures/approval.md) · [ApprovalRequest](../core-data-structures/approval.md) · [ApprovalService](../core-data-structures/approval.md) · [Scoped](../core-data-structures/scope.md)
|
||||
|
||||
Source: [`packages/ui/user-approval/src/index.ts:31`](../../packages/ui/user-approval/src/index.ts)
|
||||
Source: [`packages/ui/user-approval/src/index.ts:30`](../../packages/ui/user-approval/src/index.ts)
|
||||
|
||||
## `commands/*`
|
||||
|
||||
@@ -427,7 +435,7 @@ A command was registered or unregistered. This is an unfiltered registry notific
|
||||
'commands/change'(): void
|
||||
```
|
||||
|
||||
Source: [`packages/ui/commands/src/index.ts:83`](../../packages/ui/commands/src/index.ts)
|
||||
Source: [`packages/ui/commands/src/index.ts:103`](../../packages/ui/commands/src/index.ts)
|
||||
|
||||
## `fs/*`
|
||||
|
||||
@@ -524,11 +532,11 @@ Waterfall around every streaming model call (retry, replay, routing). Bound to t
|
||||
* Waterfall around every streaming model call (retry, replay, routing).
|
||||
* Bound to the {@link LlmService}; call `next()` to reach the resolved
|
||||
* adapter's stream, or yield your own chunks to short-circuit.
|
||||
* @param options - the full request. A LOOP-built request arrives
|
||||
* deep-frozen (mutation throws): its content is a pure function of the
|
||||
* session log (the reconstructability Agent Note), so listeners read it, never
|
||||
* rewrite it. A hand-built one-shot (compaction summarize) is the
|
||||
* caller's own object and stays mutable here.
|
||||
* @param options - the full request. A LOOP-built request carries the
|
||||
* process-local {@link markAgentLoopRequest} identity and arrives deep-frozen
|
||||
* (mutation throws): its content is a pure function of the session log (the
|
||||
* reconstructability Agent Note), so listeners read it, never rewrite it.
|
||||
* Hand-built calls own their mutability policy and do not carry that marker.
|
||||
* @mode waterfall
|
||||
*/
|
||||
'llm/stream'(this: LlmService, options: GenerateOptions, next: () => AsyncIterable<StreamChunk>): AsyncIterable<StreamChunk>
|
||||
@@ -561,7 +569,7 @@ Creation announcement during session publication. A synchronous throw vetoes and
|
||||
|
||||
Types: [Scoped](../core-data-structures/scope.md) · [Session](../core-data-structures/session.md)
|
||||
|
||||
Source: [`packages/core/session/src/index.ts:47`](../../packages/core/session/src/index.ts)
|
||||
Source: [`packages/core/session/src/index.ts:68`](../../packages/core/session/src/index.ts)
|
||||
|
||||
### `session/disposed` — emit
|
||||
|
||||
@@ -582,7 +590,7 @@ Emitted once when an announced session leaves the store, including publication r
|
||||
|
||||
Types: [Scoped](../core-data-structures/scope.md) · [Session](../core-data-structures/session.md)
|
||||
|
||||
Source: [`packages/core/session/src/index.ts:57`](../../packages/core/session/src/index.ts)
|
||||
Source: [`packages/core/session/src/index.ts:78`](../../packages/core/session/src/index.ts)
|
||||
|
||||
### `session/event` — emit
|
||||
|
||||
@@ -605,7 +613,7 @@ Post-commit, fire-and-forget append feed. The listener snapshot resolves before
|
||||
|
||||
Types: [Scoped](../core-data-structures/scope.md) · [Session](../core-data-structures/session.md) · [SessionEvent](../core-data-structures/core.md)
|
||||
|
||||
Source: [`packages/core/session/src/index.ts:69`](../../packages/core/session/src/index.ts)
|
||||
Source: [`packages/core/session/src/index.ts:90`](../../packages/core/session/src/index.ts)
|
||||
|
||||
### `session/flush` — parallel
|
||||
|
||||
@@ -626,7 +634,7 @@ Awaited parallel durability checkpoint: every listener runs and the caller await
|
||||
|
||||
Types: [Scoped](../core-data-structures/scope.md) · [Session](../core-data-structures/session.md)
|
||||
|
||||
Source: [`packages/core/session/src/index.ts:79`](../../packages/core/session/src/index.ts)
|
||||
Source: [`packages/core/session/src/index.ts:100`](../../packages/core/session/src/index.ts)
|
||||
|
||||
## `subagent/*`
|
||||
|
||||
@@ -708,13 +716,15 @@ Source: [`packages/subagent/subagent/src/index.ts:130`](../../packages/subagent/
|
||||
|
||||
### `system-prompt/assemble` — waterfall
|
||||
|
||||
Expert waterfall over the assembled sections, tools, and variables. Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): scoped listeners receive only that scope's assemblies. The returned value is authoritative.
|
||||
Expert waterfall over the assembled sections, tools, and variables. Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): scoped listeners receive only that scope's assemblies. The returned value is authoritative. A supplied signal controls only this explicit assembly request and must not be retained to control later turns.
|
||||
|
||||
```ts cordis-catalog
|
||||
/**
|
||||
* Expert waterfall over the assembled sections, tools, and variables.
|
||||
* Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): scoped listeners
|
||||
* receive only that scope's assemblies. The returned value is authoritative.
|
||||
* A supplied signal controls only this explicit assembly request and must not
|
||||
* be retained to control later turns.
|
||||
* @param assembly - the mutable assembly built from registered providers.
|
||||
* @param context - the caller's per-assembly context.
|
||||
* @mode waterfall
|
||||
@@ -724,7 +734,7 @@ Expert waterfall over the assembled sections, tools, and variables. Scope-filter
|
||||
|
||||
Types: [AssembleContext](../core-data-structures/system-prompt.md) · [Scoped](../core-data-structures/scope.md) · [SystemPrompt](../core-data-structures/system-prompt.md)
|
||||
|
||||
Source: [`packages/core/system-prompt/src/index.ts:27`](../../packages/core/system-prompt/src/index.ts)
|
||||
Source: [`packages/core/system-prompt/src/index.ts:29`](../../packages/core/system-prompt/src/index.ts)
|
||||
|
||||
### `system-prompt/change` — emit
|
||||
|
||||
@@ -739,7 +749,7 @@ Emitted when any prompt provider changes. This registry notification is unfilter
|
||||
'system-prompt/change'(): void
|
||||
```
|
||||
|
||||
Source: [`packages/core/system-prompt/src/index.ts:33`](../../packages/core/system-prompt/src/index.ts)
|
||||
Source: [`packages/core/system-prompt/src/index.ts:35`](../../packages/core/system-prompt/src/index.ts)
|
||||
|
||||
## `tools/*`
|
||||
|
||||
@@ -760,36 +770,41 @@ A tool was registered or unregistered, or a scoped restriction changed (the avai
|
||||
'tools/change'(): void
|
||||
```
|
||||
|
||||
Source: [`packages/core/tools/src/index.ts:116`](../../packages/core/tools/src/index.ts)
|
||||
Source: [`packages/core/tools/src/index.ts:123`](../../packages/core/tools/src/index.ts)
|
||||
|
||||
### `tools/execute` — waterfall
|
||||
|
||||
Around-dispatch waterfall for timeout, retry, or metrics. `next()` returns a normalized result; wrappers may change only `exec.signal`, while call identity remains immutable. Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent's calls.
|
||||
Around-dispatch waterfall for timeout, retry, or metrics. `next()` returns a normalized result; wrappers may change only `exec.signal`, while call identity remains immutable. The registry re-fuses the original caller signal before the body, so replacement cannot detach caller cancellation; wrappers must still restore their signal and reach quiescence. Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent's calls.
|
||||
|
||||
```ts cordis-catalog
|
||||
/**
|
||||
* Around-dispatch waterfall for timeout, retry, or metrics. `next()` returns
|
||||
* a normalized result; wrappers may change only `exec.signal`, while call
|
||||
* identity remains immutable.
|
||||
* identity remains immutable. The registry re-fuses the original caller
|
||||
* signal before the body, so replacement cannot detach caller cancellation;
|
||||
* wrappers must still restore their signal and reach quiescence.
|
||||
* Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent's calls.
|
||||
* @param exec - the allowed call about to dispatch (name, parsed arguments, caller agent, signal).
|
||||
* @mode waterfall
|
||||
*/
|
||||
'tools/execute'(this: Scoped<ToolRegistry>, exec: ToolExecution, next: () => Promise<ToolExecutionResult>): Promise<ToolExecutionResult>
|
||||
'tools/execute'(this: Scoped<ToolRegistry>, exec: ToolDispatchExecution, next: () => Promise<ToolExecutionResult>): Promise<ToolExecutionResult>
|
||||
```
|
||||
|
||||
Types: [Scoped](../core-data-structures/scope.md) · [ToolExecution](../core-data-structures/tools.md) · [ToolExecutionResult](../core-data-structures/tools.md) · [ToolRegistry](../core-data-structures/tools.md)
|
||||
Types: [Scoped](../core-data-structures/scope.md) · [ToolDispatchExecution](../core-data-structures/tools.md) · [ToolExecutionResult](../core-data-structures/tools.md) · [ToolRegistry](../core-data-structures/tools.md)
|
||||
|
||||
Source: [`packages/core/tools/src/index.ts:89`](../../packages/core/tools/src/index.ts)
|
||||
Source: [`packages/core/tools/src/index.ts:93`](../../packages/core/tools/src/index.ts)
|
||||
|
||||
### `tools/post-execute` — waterfall
|
||||
|
||||
Accept, replace, enrich, or block a normalized dispatch result. `next()` accepts it unchanged; thrown tools still reach this seam as errors. Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent's calls.
|
||||
Accept, replace, enrich, or block a normalized dispatch result. `next()` accepts it unchanged; thrown tools still reach this seam as errors. Async listeners must observe `exec.signal`; after they settle, caller cancellation replaces only a successful accepted outcome with the code selected by whether the tool body was invoked. Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent's calls.
|
||||
|
||||
```ts cordis-catalog
|
||||
/**
|
||||
* Accept, replace, enrich, or block a normalized dispatch result. `next()`
|
||||
* accepts it unchanged; thrown tools still reach this seam as errors.
|
||||
* accepts it unchanged; thrown tools still reach this seam as errors. Async
|
||||
* listeners must observe `exec.signal`; after they settle, caller
|
||||
* cancellation replaces only a successful accepted outcome with the code
|
||||
* selected by whether the tool body was invoked.
|
||||
* Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent's calls.
|
||||
* @param exec - the call that just ran (name, parsed arguments, caller agent).
|
||||
* @param result - the dispatch outcome a listener may accept, replace, or block.
|
||||
@@ -800,16 +815,18 @@ Accept, replace, enrich, or block a normalized dispatch result. `next()` accepts
|
||||
|
||||
Types: [PostToolDecision](../core-data-structures/tools.md) · [Scoped](../core-data-structures/scope.md) · [ToolExecution](../core-data-structures/tools.md) · [ToolExecutionResult](../core-data-structures/tools.md) · [ToolRegistry](../core-data-structures/tools.md)
|
||||
|
||||
Source: [`packages/core/tools/src/index.ts:98`](../../packages/core/tools/src/index.ts)
|
||||
Source: [`packages/core/tools/src/index.ts:105`](../../packages/core/tools/src/index.ts)
|
||||
|
||||
### `tools/pre-execute` — waterfall
|
||||
|
||||
Allow, deny, or ask before dispatch. `next()` delegates to allow; missing approval support turns `ask` into denial. Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent's calls.
|
||||
Allow, deny, or ask before dispatch. `next()` delegates to allow; missing approval support turns `ask` into denial. Async gates must observe `exec.signal`; the registry rechecks cancellation after they settle but never abandons their promise. Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent's calls.
|
||||
|
||||
```ts cordis-catalog
|
||||
/**
|
||||
* Allow, deny, or ask before dispatch. `next()` delegates to allow; missing
|
||||
* approval support turns `ask` into denial.
|
||||
* approval support turns `ask` into denial. Async gates must observe
|
||||
* `exec.signal`; the registry rechecks cancellation after they settle but
|
||||
* never abandons their promise.
|
||||
* Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent's calls.
|
||||
* @param exec - the pending call (name, parsed arguments, caller agent).
|
||||
* @mode waterfall
|
||||
@@ -819,7 +836,7 @@ Allow, deny, or ask before dispatch. `next()` delegates to allow; missing approv
|
||||
|
||||
Types: [PreToolDecision](../core-data-structures/tools.md) · [Scoped](../core-data-structures/scope.md) · [ToolExecution](../core-data-structures/tools.md) · [ToolRegistry](../core-data-structures/tools.md)
|
||||
|
||||
Source: [`packages/core/tools/src/index.ts:80`](../../packages/core/tools/src/index.ts)
|
||||
Source: [`packages/core/tools/src/index.ts:82`](../../packages/core/tools/src/index.ts)
|
||||
|
||||
### `tools/result` — emit
|
||||
|
||||
@@ -838,7 +855,7 @@ Observe the frozen, lossless-JSON final outcome. Listener failures are contained
|
||||
|
||||
Types: [Scoped](../core-data-structures/scope.md) · [ToolExecution](../core-data-structures/tools.md) · [ToolExecutionResult](../core-data-structures/tools.md) · [ToolRegistry](../core-data-structures/tools.md)
|
||||
|
||||
Source: [`packages/core/tools/src/index.ts:106`](../../packages/core/tools/src/index.ts)
|
||||
Source: [`packages/core/tools/src/index.ts:113`](../../packages/core/tools/src/index.ts)
|
||||
|
||||
## `workflow/*`
|
||||
|
||||
|
||||
@@ -216,7 +216,7 @@ roots(): Agent[]
|
||||
|
||||
Types: [Agent](../core-data-structures/core.md) · [SessionId](../core-data-structures/core.md)
|
||||
|
||||
Source: [`packages/core/agent/src/index.ts:224`](../../packages/core/agent/src/index.ts)
|
||||
Source: [`packages/core/agent/src/index.ts:225`](../../packages/core/agent/src/index.ts)
|
||||
|
||||
## `ctx.approval` — `ApprovalService`
|
||||
|
||||
@@ -246,7 +246,7 @@ async request(req: ApprovalRequest): Promise<ApprovalOutcome>
|
||||
|
||||
Types: [ApprovalOutcome](../core-data-structures/approval.md) · [ApprovalRequest](../core-data-structures/approval.md)
|
||||
|
||||
Source: [`packages/ui/user-approval/src/index.ts:229`](../../packages/ui/user-approval/src/index.ts)
|
||||
Source: [`packages/ui/user-approval/src/index.ts:213`](../../packages/ui/user-approval/src/index.ts)
|
||||
|
||||
## `ctx.bash` — `BashExecutor` (abstract seam)
|
||||
|
||||
@@ -379,7 +379,7 @@ async execute( agent: Agent, line: string, signal: AbortSignal, ): Promise<Comma
|
||||
|
||||
Types: [Agent](../core-data-structures/core.md) · [CommandDefinition](../core-data-structures/commands.md) · [CommandDescriptor](../core-data-structures/commands.md) · [CommandResult](../core-data-structures/commands.md)
|
||||
|
||||
Source: [`packages/ui/commands/src/index.ts:207`](../../packages/ui/commands/src/index.ts)
|
||||
Source: [`packages/ui/commands/src/index.ts:227`](../../packages/ui/commands/src/index.ts)
|
||||
|
||||
## `ctx.compact` — `CompactService` (abstract seam)
|
||||
|
||||
@@ -733,6 +733,33 @@ Types: [Session](../core-data-structures/session.md) · [SessionEvent](../core-d
|
||||
|
||||
Source: [`packages/ui/permission/src/index.ts:97`](../../packages/ui/permission/src/index.ts)
|
||||
|
||||
## `ctx.planMode` — `PlanModeService`
|
||||
|
||||
`ctx.planMode`: owns logged plan state, boundary application and narration, the `plan:policy` section, the `/plan` command, and the stable exit tool. UIs observe committed flips through `session/event`; there is no live mirror.
|
||||
|
||||
```ts cordis-catalog
|
||||
/**
|
||||
* Read the logged plan state and any selected state awaiting a boundary.
|
||||
*
|
||||
* @param agent The agent to read.
|
||||
* @returns Current logged state plus a pending selection, when present.
|
||||
*/
|
||||
get(agent: Agent): { active: boolean; pending?: boolean }
|
||||
|
||||
/**
|
||||
* Select whether plan mode should be active from the next turn boundary.
|
||||
* Repeated selection of the current or already-pending state is a no-op.
|
||||
*
|
||||
* @param agent The agent to switch.
|
||||
* @param active Whether plan mode should be active.
|
||||
*/
|
||||
set(agent: Agent, active: boolean): void
|
||||
```
|
||||
|
||||
Types: [Agent](../core-data-structures/core.md)
|
||||
|
||||
Source: [`packages/plan/plan-mode/src/index.ts:141`](../../packages/plan/plan-mode/src/index.ts)
|
||||
|
||||
## `ctx.sandbox` — `SandboxProvider` (abstract seam)
|
||||
|
||||
Abstract process-sandbox service. confine must return enforcing argv or fail closed at wrap or runner-execution time; silent unconfined passthrough is forbidden. Functional probes arbitrate multi-runner chains and may be skipped for a sole candidate, whose own refusal remains the fail-closed end.
|
||||
@@ -843,6 +870,13 @@ Live-preferred logical-corpus exact-read and relationship-tracing service.
|
||||
*/
|
||||
listSessions(): Promise<SessionRecord[]>
|
||||
|
||||
/**
|
||||
* Fold the latest log-backed title from one live-preferred logical session.
|
||||
* @param sessionId - live or persisted session id to read.
|
||||
* @returns latest title snapshot, or `undefined` when the log has no title event.
|
||||
*/
|
||||
async readTitle(sessionId: SessionId): Promise<SessionTitleSnapshot | undefined>
|
||||
|
||||
/**
|
||||
* List lightweight raw-log event records for one logical session.
|
||||
* @param sessionId - live-preferred session id to read.
|
||||
@@ -874,9 +908,9 @@ async traceEvent(request: SessionEventTraceRequest): Promise<SessionEventTrace>
|
||||
async readEvent(request: SessionEventReadRequest): Promise<SessionEventWindow>
|
||||
```
|
||||
|
||||
Types: [SessionEventReadRequest](../core-data-structures/session-query.md) · [SessionEventRecord](../core-data-structures/session-query.md) · [SessionEventTrace](../core-data-structures/session-query.md) · [SessionEventTraceRequest](../core-data-structures/session-query.md) · [SessionEventWindow](../core-data-structures/session-query.md) · [SessionId](../core-data-structures/core.md) · [SessionLineageTrace](../core-data-structures/session-query.md) · [SessionRecord](../core-data-structures/session-query.md)
|
||||
Types: [SessionEventReadRequest](../core-data-structures/session-query.md) · [SessionEventRecord](../core-data-structures/session-query.md) · [SessionEventTrace](../core-data-structures/session-query.md) · [SessionEventTraceRequest](../core-data-structures/session-query.md) · [SessionEventWindow](../core-data-structures/session-query.md) · [SessionId](../core-data-structures/core.md) · [SessionLineageTrace](../core-data-structures/session-query.md) · [SessionRecord](../core-data-structures/session-query.md) · [SessionTitleSnapshot](../core-data-structures/session-title.md)
|
||||
|
||||
Source: [`packages/session-query/session-query/src/index.ts:38`](../../packages/session-query/session-query/src/index.ts)
|
||||
Source: [`packages/session-query/session-query/src/index.ts:40`](../../packages/session-query/session-query/src/index.ts)
|
||||
|
||||
## `ctx.sessions` — `SessionStore`
|
||||
|
||||
@@ -972,6 +1006,28 @@ announce(session: Session): void
|
||||
*/
|
||||
async flush(session: Session): Promise<void>
|
||||
|
||||
/**
|
||||
* Append one plugin-declared log-only event without borrowing the agent
|
||||
* loop's lifecycle. An open turn receives the event directly and remains
|
||||
* responsible for its ordinary checkpoint. A closed log receives one
|
||||
* zero-step turn around the event, followed by an awaited flush.
|
||||
*
|
||||
* Once the synthetic `turn/start` commits, this method always attempts its
|
||||
* matching `turn/end` and flush, including when the target append fails.
|
||||
* Detachment requested by an event or flush listener is deferred until that
|
||||
* sequence settles, so publication cannot switch from a live scoped session
|
||||
* to an unobserved bare `Session` halfway through the update.
|
||||
*
|
||||
* @param session - exact live session that owns the target log.
|
||||
* @param type - event type opted into {@link OutOfBandSessionEventMap} by its owner.
|
||||
* @param data - typed JSON payload for the target event.
|
||||
* @param trigger - plugin-owned turn trigger used only when the log is closed.
|
||||
* @returns the accepted target event with its assigned sequence and timestamp.
|
||||
* @throws when the session is detached, another out-of-band append is active,
|
||||
* event acceptance fails, the synthetic turn cannot close, or flushing fails.
|
||||
*/
|
||||
async appendOutOfBand<T extends OutOfBandSessionEventType>( session: Session, type: T, data: SessionEventMap[T], trigger: TurnTrigger, ): Promise<SessionEvent<T>>
|
||||
|
||||
/**
|
||||
* Look up a live session.
|
||||
* @param id - the session id to look up.
|
||||
@@ -1001,9 +1057,43 @@ list(): Session[]
|
||||
fork(source: SessionForkSource, boundary?: number, childSessionId?: SessionId): Session
|
||||
```
|
||||
|
||||
Types: [CreateSessionOptions](../core-data-structures/persistence.md) · [Session](../core-data-structures/session.md) · [SessionId](../core-data-structures/core.md)
|
||||
Types: [CreateSessionOptions](../core-data-structures/persistence.md) · [OutOfBandSessionEventType](../core-data-structures/session.md) · [Session](../core-data-structures/session.md) · [SessionEvent](../core-data-structures/core.md) · [SessionEventMap](../core-data-structures/session.md) · [SessionId](../core-data-structures/core.md) · [TurnTrigger](../core-data-structures/session.md)
|
||||
|
||||
Source: [`packages/core/session/src/index.ts:553`](../../packages/core/session/src/index.ts)
|
||||
Source: [`packages/core/session/src/index.ts:592`](../../packages/core/session/src/index.ts)
|
||||
|
||||
## `ctx.sessionTitle` — `SessionTitleService`
|
||||
|
||||
Log-backed title fold plus asynchronous fallback generation.
|
||||
|
||||
```ts cordis-catalog
|
||||
/**
|
||||
* Read the latest folded title from one live or replayed session.
|
||||
* @param session - session whose log is the title source of truth.
|
||||
* @returns latest title snapshot, or `undefined` before eligible input.
|
||||
*/
|
||||
get(session: Session): SessionTitleSnapshot | undefined
|
||||
|
||||
/**
|
||||
* Explicitly retry the registered provider, or materialize the built-in
|
||||
* fallback when no provider is registered.
|
||||
* @param session - exact live session to refresh.
|
||||
* @param signal - optional caller cancellation; an in-progress fallback append may finish durably before rejection.
|
||||
* @returns latest accepted title, or `undefined` when no eligible text exists.
|
||||
*/
|
||||
async refresh(session: Session, signal?: AbortSignal): Promise<SessionTitleSnapshot | undefined>
|
||||
|
||||
/**
|
||||
* Register the sole optional title provider. Disposal aborts its pending and
|
||||
* active work before another provider may register.
|
||||
* @param provider - provider identity, cadence, and generation function.
|
||||
* @returns exact Cordis effect disposer, which settles after active calls quiesce.
|
||||
*/
|
||||
register(provider: SessionTitleProvider): () => Promise<void>
|
||||
```
|
||||
|
||||
Types: [Session](../core-data-structures/session.md) · [SessionTitleProvider](../core-data-structures/session-title.md) · [SessionTitleSnapshot](../core-data-structures/session-title.md)
|
||||
|
||||
Source: [`packages/session-title/session-title/src/index.ts:282`](../../packages/session-title/session-title/src/index.ts)
|
||||
|
||||
## `ctx.skills` — `SkillService`
|
||||
|
||||
@@ -1165,7 +1255,7 @@ async assemble(context: AssembleContext = {}): Promise<PromptAssembly>
|
||||
|
||||
Types: [AssembleContext](../core-data-structures/system-prompt.md) · [PromptSection](../core-data-structures/system-prompt.md) · [ToolProviderResult](../core-data-structures/system-prompt.md)
|
||||
|
||||
Source: [`packages/core/system-prompt/src/index.ts:209`](../../packages/core/system-prompt/src/index.ts)
|
||||
Source: [`packages/core/system-prompt/src/index.ts:246`](../../packages/core/system-prompt/src/index.ts)
|
||||
|
||||
## `ctx.tasks` — `TaskService`
|
||||
|
||||
@@ -1394,7 +1484,11 @@ executionMode(exec: ToolExecutionInput): ToolExecutionMode
|
||||
* Execute through pre-policy, guards, around-dispatch, post-policy, and final
|
||||
* notification. Tool and listener failures resolve as materialized error
|
||||
* results; an invisible tool reports `UNKNOWN_TOOL`. The returned outcome is
|
||||
* the same lossless, frozen snapshot final observers receive.
|
||||
* the same lossless, frozen snapshot final observers receive. Cancellation
|
||||
* arriving after entry and before final result materialization skips a
|
||||
* not-yet-started body with `ABORTED_BEFORE_DISPATCH` or replaces a
|
||||
* successful started outcome with `ABORTED`; already-started work is still
|
||||
* drained and may retain a tool-owned structured error.
|
||||
* @param exec - the typed same-process call input. The registry assigns its
|
||||
* correlation token before policy begins.
|
||||
* @returns the materialized final result.
|
||||
@@ -1404,7 +1498,7 @@ async execute(exec: ToolExecutionInput): Promise<ToolExecutionResult>
|
||||
|
||||
Types: [ScopeKey](../core-data-structures/scope.md) · [ToolDefinition](../core-data-structures/tools.md) · [ToolExecutionInput](../core-data-structures/tools.md) · [ToolExecutionMode](../core-data-structures/tools.md) · [ToolExecutionResult](../core-data-structures/tools.md) · [ToolGuard](../core-data-structures/tools.md) · [ToolRestriction](../core-data-structures/tools.md) · [ToolSchema](../core-data-structures/tools.md)
|
||||
|
||||
Source: [`packages/core/tools/src/index.ts:438`](../../packages/core/tools/src/index.ts)
|
||||
Source: [`packages/core/tools/src/index.ts:524`](../../packages/core/tools/src/index.ts)
|
||||
|
||||
## `ctx.userInteraction` — `UserInteractionService`
|
||||
|
||||
@@ -1430,7 +1524,7 @@ async ask(request: AskUserQuestionRequest): Promise<AskUserQuestionAnswer>
|
||||
|
||||
Types: [AskUserQuestionAnswer](../core-data-structures/user-interaction.md) · [AskUserQuestionRequest](../core-data-structures/user-interaction.md) · [UserInteractionProvider](../core-data-structures/user-interaction.md)
|
||||
|
||||
Source: [`packages/ui/user-interaction/src/index.ts:82`](../../packages/ui/user-interaction/src/index.ts)
|
||||
Source: [`packages/ui/user-interaction/src/index.ts:50`](../../packages/ui/user-interaction/src/index.ts)
|
||||
|
||||
## `ctx.web` — `WebService`
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ Everything else is documented on a **sub-page**, not here. The rule that draws t
|
||||
| [session.md](session.md) | the full `SessionEventMap` variant catalog, `TurnTrigger`/`TurnEndReason`, `deriveMessages()`, the turn-enclosure invariant |
|
||||
| [persistence.md](persistence.md) | the durability seam: `SessionPersistence`, JSONL + SQLite backends, `session/flush`, crash recovery, `SessionHeader` |
|
||||
| [session-query.md](session-query.md) | logical records, bounded exact-event reads, and relationship traces |
|
||||
| [session-title.md](session-title.md) | durable title snapshots, source provenance, and the asynchronous provider contract |
|
||||
| [system-prompt.md](system-prompt.md) | per-assembly context, tool-provider results, prompt sections, and cooperative assembly |
|
||||
| [tools.md](tools.md) | `ToolDefinition` full fields, the schema DSL, `ToolExecution`/`ToolResult`, tool-presentation UI types, and the guarded execution pipeline |
|
||||
| [user-interaction.md](user-interaction.md) | the UI-backed human question/answer seam: `AskUserQuestionRequest`, answer/options vocabulary, provider API, error taxonomy |
|
||||
@@ -234,6 +235,12 @@ interface GenerateOptions {
|
||||
* it; replay uses it to keep concurrent parent and child cursors independent.
|
||||
*/
|
||||
sessionId?: Branded<'SessionId'>
|
||||
/**
|
||||
* Provider-neutral classification for an auxiliary model call. Adapters may
|
||||
* map the purpose to model-hidden transport metadata. Ordinary conversation
|
||||
* requests leave it unset.
|
||||
*/
|
||||
purpose?: 'compaction'
|
||||
}
|
||||
```
|
||||
|
||||
@@ -279,7 +286,7 @@ The model-facing `ToolSchema` is the wire shape; the registered `ToolDefinition`
|
||||
|
||||
The loop builds each request from logged state. `EpochHeader` records call config, rendered prompt, authoritative returned tool order (configured by `toolOrder`, or lexicographic when unset), and session prefix through full `request/header` snapshots. Together with derived history, this makes the request reconstructable from the session log. See [session.md](session.md#the-request-header-event-requestheader) and the [reconstructability Agent Note](../../.agents/notes/implemented/architecture/2026-07-05-reconstructable-requests.md).
|
||||
|
||||
`agent/request` receives a frozen call-config seed and may return a replacement to switch provider, model, or sampling. `agent/session-prefix` composes request-only prefix messages once per loop instance, and the header records the exact result used. Requests reaching `llm/stream` are deep-frozen, so mutation throws.
|
||||
`agent/request` receives a frozen call-config seed and may return a replacement to switch provider, model, or sampling. `agent/session-prefix` composes request-only prefix messages once per loop instance, and the header records the exact result used. Requests reaching `llm/stream` are deep-frozen, so mutation throws, and carry a process-local loop identity so observers do not confuse separately logged frozen auxiliary calls with conversation requests.
|
||||
|
||||
On the wire, a loop-built request reads in this order: the `system` slot (the rendered prompt assembly) → `messagePrefix` (the frozen session prefix) → the derived history — the boundary snapshot, whose tail is the newest `user/message` on a turn's first step and the previous step's tool results on later steps. The prefix never enters the derived history; its durable record is the header events, and the dev invariant recomputes exactly this equation against every loop-built request.
|
||||
|
||||
@@ -361,6 +368,13 @@ interface InjectOptions extends SendOptions {
|
||||
}
|
||||
```
|
||||
|
||||
```ts type-equiv
|
||||
/** Stable runtime cause accepted by {@link Agent.cancel}. */
|
||||
type AgentCancelCause =
|
||||
| { readonly kind: 'user' }
|
||||
| { readonly kind: 'parent' }
|
||||
```
|
||||
|
||||
```ts type-equiv
|
||||
/** Public agent handle; its concrete implementation is internal to `@deepseek-ai/dsh-agent-loop`. */
|
||||
interface Agent {
|
||||
@@ -401,12 +415,14 @@ interface Agent {
|
||||
|
||||
/**
|
||||
* Clear all queued and steering work, including items waiting to start, and
|
||||
* abort the active step. An effective call first emits `agent/cancel-requested`
|
||||
* with the resolved reason. That reason is preserved across pre-step and active
|
||||
* cancellation windows, and `whenIdle()` resolves after cancellation reaches
|
||||
* quiescence. Idle cancellation is a no-op and does not arm a later cancel.
|
||||
* abort the active turn. An effective call first emits
|
||||
* `agent/cancel-requested` with the resolved typed cause. The first cause wins
|
||||
* for the active turn, and `whenIdle()` resolves after cancellation reaches
|
||||
* quiescence. Omission means `{ kind: 'user' }`. Idle cancellation is a no-op
|
||||
* and does not arm later work. The active turn snapshots and freezes the cause.
|
||||
* @param cause - the stable caller intent carried by the current turn signal.
|
||||
*/
|
||||
cancel(reason?: string): void
|
||||
cancel(cause?: AgentCancelCause): void
|
||||
|
||||
/** Resolve at idle quiescence; disposal waits for driver exit rather than only the status transition. */
|
||||
whenIdle(): Promise<void>
|
||||
@@ -414,7 +430,9 @@ interface Agent {
|
||||
}
|
||||
```
|
||||
|
||||
`AgentStatus` is `'idle' | 'running' | 'disposed'`, and `SessionId` is branded. `running` describes the driver-wide drain interval, which can span turn close, its durability checkpoint, and consecutive queued turns; it does not prove a turn is still open. `AgentOptions` is merge-extensible and currently includes `provider?` and `model?`; dispatch requires both after `agent/request`. Persona belongs to `dsh-system-prompt`: an agent-scoped `deployment:persona` may shadow the global default.
|
||||
`AgentStatus` is `'idle' | 'running' | 'disposed'`, and `SessionId` is branded. `running` describes the driver-wide drain interval, which can span turn close, its durability checkpoint, and consecutive queued turns; it does not prove a turn is still open. `AgentOptions` is merge-extensible: core declares `provider?` and `model?` (dispatch requires both after `agent/request`). Persona belongs to `dsh-system-prompt`: an agent-scoped `deployment:persona` may shadow the global default.
|
||||
|
||||
The cause is a TypeScript-enforced same-process input. An active holder copies its discriminant into the runtime-only `AbortSignal.reason`; it is retired before `turn/end` publication. `agentInterruptReasonOf(signal)` recognizes `user`, `parent`, and lifecycle-only `disposed` without consulting ambient initiator state. Durable `turn/end` retains the coarse `{ kind: 'aborted' }` outcome; request provenance would require a separate durable event rather than overloading the terminal result.
|
||||
|
||||
The [event taxonomy](../architecture.md#event) owns the `agent/*` lifecycle, checkpoint, and waterfall contracts. Turn and step boundaries are durable session events rather than agent emits.
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Scoped Registration
|
||||
|
||||
The [scope package](../../packages/core/scope) supplies the identity and carrier vocabulary that makes one registration context mean both per-agent visibility and shared lifetime ownership. It is a library primitive rather than a Cordis service; the [agent-scope runtime-design Agent Note](../../.agents/notes/implemented/architecture/2026-07-12-agent-scope-runtime-design.md#scope-routing-one-opaque-key-selects-one-layer) owns the implementation rationale, while the package [README](../../packages/core/scope/README.md) owns the callable API and filtering semantics.
|
||||
The [scope package](../../packages/core/scope) supplies the identity, carrier, and scoped-layer vocabulary that makes one registration context mean both per-agent visibility and shared lifetime ownership. It is a library primitive rather than a Cordis service; the [agent-scope runtime-design Agent Note](../../.agents/notes/implemented/architecture/2026-07-12-agent-scope-runtime-design.md#scope-routing-one-opaque-key-selects-one-layer) owns the lifecycle rationale, the [shared-storage Agent Note](../../.agents/notes/implemented/architecture/2026-07-12-scoped-layers-store.md) owns the registry-layer decision, and the package [README](../../packages/core/scope/README.md) owns the callable API and filtering semantics.
|
||||
|
||||
Source: [`packages/core/scope/src/index.ts`](../../packages/core/scope/src/index.ts).
|
||||
Sources: [`packages/core/scope/src/index.ts`](../../packages/core/scope/src/index.ts) and [`packages/core/scope/src/store.ts`](../../packages/core/scope/src/store.ts).
|
||||
|
||||
## Identity and dispatch carrier
|
||||
|
||||
@@ -39,3 +39,19 @@ interface Scope {
|
||||
dispose(): Promise<void>
|
||||
}
|
||||
```
|
||||
|
||||
## Scoped registry layer
|
||||
|
||||
`ScopeLayer` represents one registry's complete contribution at the global or exact-scope level. A concrete layer may aggregate multiple named and anonymous tables; whole-layer emptiness lets `ScopedLayers` reclaim scoped state without discarding a sibling table.
|
||||
|
||||
```ts type-equiv
|
||||
/** One scope's aggregate contribution to a registry. */
|
||||
interface ScopeLayer {
|
||||
/** Whether every table in this layer is empty. */
|
||||
isEmpty(): boolean
|
||||
}
|
||||
```
|
||||
|
||||
`ScopedLayers<L>` owns the eager global layer and lazily created exact-scope layers. Reads do not create layers: `peek(undefined)` means no overlay, while `merge()` materializes insertion-ordered global named entries followed by scoped shadows. Registrations use one context for both visibility and Cordis effect ownership, collect one synchronous undo before optional notification, return Cordis's exact disposer, and reclaim a scoped layer only when its complete `ScopeLayer` is empty.
|
||||
|
||||
`NamedEntries<V>` supplies insertion-ordered lookup and live iteration with caller-owned duplicate errors. `AnonymousEntries<V>` gives every append a unique identity so equal values remain independent. Iteration stays live within one nonempty table generation; draining the table detaches existing iterators from later insertions. Both return idempotent exact-entry undos; the shared `EntryValues` implementation interface is not public.
|
||||
|
||||
140
docs/core-data-structures/session-title.md
Normal file
140
docs/core-data-structures/session-title.md
Normal file
@@ -0,0 +1,140 @@
|
||||
# Session Titles
|
||||
|
||||
Durable latest-wins title state and the optional asynchronous provider vocabulary owned by [`@deepseek-ai/dsh-session-title`](../../packages/session-title/session-title). The shared LLM helper owns the exact auxiliary request record. Package READMEs own timing, fallback, failure, and fork behavior; the generated [persistence catalog](../persistence-catalog.md) owns the complete event declarations.
|
||||
|
||||
Sources: [`packages/session-title/session-title/src/index.ts`](../../packages/session-title/session-title/src/index.ts), [`packages/session-title/session-title-llm/src/index.ts`](../../packages/session-title/session-title-llm/src/index.ts)
|
||||
|
||||
## Durable title state
|
||||
|
||||
`SessionTitleProviderId` is recorded for provider-produced revisions. `SessionTitleEventData` carries exact human-message provenance, while `SessionTitleSnapshot` adds the durable event envelope facts selected by `foldSessionTitle()`.
|
||||
|
||||
```ts type-equiv
|
||||
/** Identifies one session-title provider registration. */
|
||||
type SessionTitleProviderId = Branded<'SessionTitleProviderId'>
|
||||
```
|
||||
|
||||
```ts type-equiv
|
||||
/** Exact auxiliary model route that produced a title. */
|
||||
interface SessionTitleModelProvenance {
|
||||
/** Registered LLM provider route. */
|
||||
readonly provider: string
|
||||
/** Provider model id. */
|
||||
readonly model: string
|
||||
}
|
||||
```
|
||||
|
||||
```ts type-equiv
|
||||
/** Durable ownership record for an accepted session title. */
|
||||
type SessionTitleSource =
|
||||
| { readonly kind: 'fallback' }
|
||||
| {
|
||||
readonly kind: 'provider'
|
||||
readonly provider: SessionTitleProviderId
|
||||
readonly model?: SessionTitleModelProvenance
|
||||
}
|
||||
```
|
||||
|
||||
```ts type-equiv
|
||||
/** Payload of the log-only `session/title` event. */
|
||||
interface SessionTitleEventData {
|
||||
/** Normalized non-empty title text. */
|
||||
readonly title: string
|
||||
/** Exact human `user/message` seqs used to derive this title. */
|
||||
readonly messageSeqs: number[]
|
||||
/** Built-in fallback or registered-provider provenance. */
|
||||
readonly source: SessionTitleSource
|
||||
}
|
||||
```
|
||||
|
||||
```ts type-equiv
|
||||
/** Latest folded title plus the title event's durable envelope facts. */
|
||||
interface SessionTitleSnapshot extends SessionTitleEventData {
|
||||
/** Seq of the latest `session/title` event. */
|
||||
readonly eventSeq: number
|
||||
/** Timestamp of the latest `session/title` event. */
|
||||
readonly updatedAt: number
|
||||
}
|
||||
```
|
||||
|
||||
## Auxiliary request record
|
||||
|
||||
The shared LLM helper records each validated, dispatchable title request before calling the model. The payload reproduces the model-visible system and message input, routing, output limit, provider ownership, and source-message attribution even when generation later fails.
|
||||
|
||||
```ts type-equiv
|
||||
/** Exact model-visible request recorded before one auxiliary title dispatch. */
|
||||
interface SessionTitleLlmRequestEventData {
|
||||
/** Registered title-provider identity responsible for the request. */
|
||||
readonly titleProvider: SessionTitleProviderId
|
||||
/** Exact human `user/message` seqs represented in `messages`. */
|
||||
readonly messageSeqs: number[]
|
||||
/** Exact auxiliary LLM route. */
|
||||
readonly route: SessionTitleModelProvenance
|
||||
/** Exact auxiliary system prompt. */
|
||||
readonly system: string
|
||||
/** Exact auxiliary message list. */
|
||||
readonly messages: Message[]
|
||||
/** Exact auxiliary output-token cap. */
|
||||
readonly maxTokens: number
|
||||
}
|
||||
```
|
||||
|
||||
## Provider input and output
|
||||
|
||||
The service snapshots eligible messages through one revision. A provider returns only seqs from that request; service-owned acceptance verifies ordering, normalizes the title, enforces the byte limit, and appends provenance.
|
||||
|
||||
```ts type-equiv
|
||||
/** One eligible human text message exposed to title providers. */
|
||||
interface SessionTitleUserMessage {
|
||||
/** Source `user/message` event seq. */
|
||||
readonly seq: number
|
||||
/** Exact concatenated text-block content. */
|
||||
readonly text: string
|
||||
}
|
||||
```
|
||||
|
||||
```ts type-equiv
|
||||
/** Automatic generation cadence owned by a registered provider. */
|
||||
type SessionTitleAutomaticMode = 'first-message' | 'all-user-messages'
|
||||
```
|
||||
|
||||
```ts type-equiv
|
||||
/** Immutable input supplied to one title-provider call. */
|
||||
interface SessionTitleProviderRequest {
|
||||
/** Live session being titled. */
|
||||
readonly session: Session
|
||||
/** All eligible human messages through this generation revision. */
|
||||
readonly messages: readonly SessionTitleUserMessage[]
|
||||
/** Exact current logged main-request route, when one has been recorded. */
|
||||
readonly route?: SessionTitleModelProvenance
|
||||
/** Cancellation for supersession, disposal, timeout composition, or the explicit caller. */
|
||||
readonly signal: AbortSignal
|
||||
}
|
||||
```
|
||||
|
||||
```ts type-equiv
|
||||
/** Provider output before service-owned normalization and durable acceptance. */
|
||||
interface SessionTitleProviderResult {
|
||||
/** Proposed title text. */
|
||||
readonly title: string
|
||||
/** Exact seqs from `request.messages` used by this result. */
|
||||
readonly messageSeqs: readonly number[]
|
||||
/** Auxiliary LLM route, when generation used a model. */
|
||||
readonly model?: SessionTitleModelProvenance
|
||||
}
|
||||
```
|
||||
|
||||
```ts type-equiv
|
||||
/** One optional asynchronous title implementation registered with the service. */
|
||||
interface SessionTitleProvider {
|
||||
/** Stable provider identity recorded in title provenance. */
|
||||
readonly id: SessionTitleProviderId
|
||||
/** When new human prompts start automatic generation. */
|
||||
readonly automatic: SessionTitleAutomaticMode
|
||||
/**
|
||||
* Produce one title revision.
|
||||
* @param request - message snapshot, current route, session, and cancellation.
|
||||
* @returns proposed title plus exact input seqs and optional model provenance.
|
||||
*/
|
||||
generate(request: SessionTitleProviderRequest): Promise<SessionTitleProviderResult>
|
||||
}
|
||||
```
|
||||
@@ -94,6 +94,20 @@ interface SessionEventMap {
|
||||
}
|
||||
```
|
||||
|
||||
### `OutOfBandSessionEventMap` — narrow late-append opt-in
|
||||
|
||||
`SessionEventMap` membership alone does not authorize an event outside the agent loop's ordinary lifecycle. An event owner declaration-merges the same key into this empty marker map before `ctx.sessions.appendOutOfBand()` accepts it; the derived type additionally excludes every surface event. An accepted update joins an open turn or receives a balanced, flushed zero-step turn.
|
||||
|
||||
```ts type-equiv
|
||||
/**
|
||||
* Marker map for plugin-owned log-only events accepted by
|
||||
* `SessionStore.appendOutOfBand()`. A plugin extends this map with the same key
|
||||
* it adds to {@link SessionEventMap}; surface and lifecycle events stay
|
||||
* ineligible unless their owner explicitly opts them into this narrow seam.
|
||||
*/
|
||||
interface OutOfBandSessionEventMap {}
|
||||
```
|
||||
|
||||
### `TodoItem` — one todo-list entry
|
||||
|
||||
The unit of the `todo/write` event's whole-list snapshot. Deliberately minimal — a `content` line and a three-state `status` (no id, priority, or `activeForm`): the list is replaced wholesale on every write, so entries need no stable identity, and the status triple is exactly the ACP `PlanEntryStatus`, so a UI bridge can map a todo list onto an ACP `plan` 1:1 (synthesizing the priority ACP additionally requires). See the [todo_write Agent Note](../../.agents/notes/implemented/feature/2026-06-29-todo-write-tool.md).
|
||||
@@ -463,13 +477,16 @@ interface TurnTriggerMap {
|
||||
|
||||
## Why a turn ended: `TurnEndReasonMap`
|
||||
|
||||
`aborted` is intentionally a coarse durable outcome: it records that cancellation interrupted the live turn, not which runtime caller requested it. The runtime-only caller vocabulary belongs to [`AgentCancelCause`](core.md#the-agent-handle); a future audit requirement would use a separate control-request event rather than overloading the terminal result.
|
||||
|
||||
```ts type-equiv
|
||||
/**
|
||||
* Why a turn ended. Merge-extensible sum type.
|
||||
*/
|
||||
interface TurnEndReasonMap {
|
||||
completed: { kind: 'completed' }
|
||||
aborted: { kind: 'aborted'; reason?: string }
|
||||
/** A cancellation request interrupted the live turn. */
|
||||
aborted: { kind: 'aborted' }
|
||||
/**
|
||||
* The turn failed: a step threw or the model reported a failure. `step` is the
|
||||
* step number the failure occurred on (the operational error's location — the
|
||||
@@ -501,7 +518,7 @@ interface TurnEndReasonMap {
|
||||
|
||||
## The turn-enclosure invariant
|
||||
|
||||
Every session event lives **inside** a turn (between a `turn/start` and its `turn/end`). The loop appends queued `user/message` events *after* `turn/start`, and an idle `agent.inject()` wraps its `context/message` in a one-shot `injection` turn. This makes the turn the single durability/replay boundary: a backend can treat anything after the last `turn/end` as an interrupted-crash tail without risking the loss of legitimately-recorded between-turn context. The optional `dsh-session/invariant` companion enforces it in dev through `ctx.invariants` (a message event outside an open turn throws). See [the turn-enclosure invariant Agent Note](../../.agents/notes/implemented/architecture/2026-06-15-turn-enclosure-invariant.md).
|
||||
Every session event lives **inside** a turn (between a `turn/start` and its `turn/end`). The loop appends queued `user/message` events *after* `turn/start`, an idle `agent.inject()` wraps its `context/message` in a one-shot `injection` turn, and `appendOutOfBand()` similarly wraps an eligible log-only event when no turn is open. This makes the turn the single durability/replay boundary: a backend can treat anything after the last `turn/end` as an interrupted-crash tail without risking the loss of legitimately-recorded between-turn context. The optional `dsh-session/invariant` companion enforces it in dev through `ctx.invariants` (a message event outside an open turn throws). See [the turn-enclosure invariant Agent Note](../../.agents/notes/implemented/architecture/2026-06-15-turn-enclosure-invariant.md).
|
||||
|
||||
## Plugin-contributed log-only events
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ Source: [`packages/core/system-prompt/src/index.ts`](../../packages/core/system-
|
||||
|
||||
## Assembly context
|
||||
|
||||
`AssembleContext` identifies the scope layer one assembly resolves. It is merge-extensible: `dsh-agent` adds the optional live `agent` field, and `assembleContextFor(agent)` sets that field and `scope` together.
|
||||
`AssembleContext` identifies the scope layer one assembly resolves and may carry the explicit control signal for that request. It is merge-extensible: `dsh-agent` adds the optional live `agent` field, and `assembleContextFor(agent, signal)` sets the explicit fields together. A bare assembly has neither scope nor signal.
|
||||
|
||||
```ts type-equiv
|
||||
/** Merge-extensible context for one prompt assembly. */
|
||||
@@ -16,6 +16,8 @@ interface AssembleContext {
|
||||
* only global providers and subject-less listeners participate.
|
||||
*/
|
||||
scope?: ScopeKey
|
||||
/** Explicit control signal for the turn that requested this assembly, when any. */
|
||||
signal?: AbortSignal
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -11,6 +11,15 @@ A `ToolSchema` (the model-facing fields) plus the `execute` function, host-only
|
||||
```ts type-equiv
|
||||
/** A registered tool: its schema plus the execution function. */
|
||||
interface ToolDefinition extends ToolSchema {
|
||||
/**
|
||||
* Run one accepted call. Async work must observe or forward `exec.signal` and
|
||||
* settle only after its owned work reaches quiescence. The registry preserves
|
||||
* caller cancellation through around-dispatch signal replacement and does
|
||||
* not abandon this promise, but it cannot hard-kill same-process code.
|
||||
* @param args - losslessly snapshotted, frozen model arguments.
|
||||
* @param exec - execution identity, cancellation signal, and context deferral.
|
||||
* @returns model-facing content plus optional private presentation metadata.
|
||||
*/
|
||||
execute(args: unknown, exec: ToolRunContext): Promise<ToolExecuteReturn>
|
||||
/**
|
||||
* Cooperative tool-call timeout budget in milliseconds. Omit for no deadline.
|
||||
@@ -138,7 +147,7 @@ interface ToolRestriction {
|
||||
|
||||
## Execution: extensible waterfalls plus monotonic policy
|
||||
|
||||
`ctx.tools.execute()` accepts a caller-owned `ToolExecutionInput`, materializes its parsed JSON arguments once into a pipeline-owned `ToolExecution`, and runs that call through `tools/pre-execute` (the reorderable allow/deny/ask waterfall) → registered monotonic guards → `tools/execute` (around-dispatch wrappers) → `tools/post-execute` (inspect/replace the result) → `tools/result` (the immutable authoritative outcome). The outcome is a `ToolExecutionResult`.
|
||||
`ctx.tools.execute()` accepts a caller-owned `ToolExecutionInput` with a required readonly `signal`, materializes its parsed JSON arguments once into a pipeline-owned `ToolExecution`, and runs that call through `tools/pre-execute` (the reorderable allow/deny/ask waterfall) → registered monotonic guards → `tools/execute` (around-dispatch wrappers) → `tools/post-execute` (inspect/replace the result) → `tools/result` (the immutable authoritative outcome). Only the `tools/execute` view may replace the required signal. The outcome is a `ToolExecutionResult`.
|
||||
|
||||
```ts type-equiv
|
||||
/** Opaque call identity that permits correlation without exposing mutable execution state. */
|
||||
@@ -161,10 +170,11 @@ interface ToolExecutionInput {
|
||||
/**
|
||||
* Opaque token of the enclosing transport execution, when one exists. Code
|
||||
* Mode sets this on SDK sub-dispatches so commit-style observers can wait for
|
||||
* the outer `run_code` outcome without receiving its live mutable execution.
|
||||
*/
|
||||
* the outer `run_code` outcome without receiving its live mutable execution.
|
||||
*/
|
||||
readonly parent?: ToolExecutionToken
|
||||
signal?: AbortSignal
|
||||
/** Required caller-owned cancellation for this invocation. */
|
||||
readonly signal: AbortSignal
|
||||
}
|
||||
```
|
||||
|
||||
@@ -203,9 +213,9 @@ type ToolExecutionMode =
|
||||
/**
|
||||
* One pending tool call inside the registry pipeline. Parsed arguments cross
|
||||
* one lossless-JSON materialization boundary before policy and are deep-frozen;
|
||||
* call identity and the registry-assigned {@link token} are readonly. An
|
||||
* around-dispatch wrapper may set, replace, or remove `signal`. The registry
|
||||
* freezes the complete object before `tools/result` observers run.
|
||||
* call identity, the caller signal, and the registry-assigned {@link token} are
|
||||
* readonly. The registry freezes the complete object before `tools/result`
|
||||
* observers run.
|
||||
*/
|
||||
interface ToolExecution extends ToolExecutionInput {
|
||||
/** Registry-assigned identity shared with nested calls only as their opaque `parent` token. */
|
||||
@@ -213,7 +223,19 @@ interface ToolExecution extends ToolExecutionInput {
|
||||
}
|
||||
```
|
||||
|
||||
`ToolExecutionToken` is an opaque runtime `Symbol` used only for identity comparison. Before policy, `execute()` materializes and freezes arguments, rejects non-JSON input, and assigns the token. Identity fields and the optional parent token remain readonly; only `signal` may change around dispatch. Final observers receive the frozen execution identity.
|
||||
```ts type-equiv
|
||||
/**
|
||||
* Around-dispatch view of a {@link ToolExecution}. A `tools/execute` wrapper
|
||||
* may replace the signal for its delegated lifetime, but it cannot remove it.
|
||||
* The registry fuses every replacement with the captured caller signal.
|
||||
*/
|
||||
interface ToolDispatchExecution extends Omit<ToolExecution, 'signal'> {
|
||||
/** Cancellation signal visible to the next wrapper or tool body. */
|
||||
signal: AbortSignal
|
||||
}
|
||||
```
|
||||
|
||||
`ToolExecutionToken` is an opaque runtime `Symbol` used only for identity comparison. Before policy, `execute()` materializes and freezes arguments, rejects non-JSON input, and assigns the token. Identity fields, the required caller signal, and the optional parent token remain readonly. A `ToolDispatchExecution` wrapper may replace but not remove the signal; the registry re-fuses the caller signal before invoking the body. Final observers receive the frozen execution identity.
|
||||
|
||||
A `ToolGuard` is scope-aware final pre-dispatch policy. Its shape deliberately has no allow result: `undefined` preserves the waterfall decision, while a returned reason can only reduce permission, so a later listener cannot undo it.
|
||||
|
||||
|
||||
@@ -20,15 +20,17 @@ interface AskUserQuestionOption {
|
||||
|
||||
## Question item
|
||||
|
||||
`AskUserQuestionItem` is one question in a request. The model supplies a stable `id`, which is echoed back with the answer so batched questions remain routable.
|
||||
`AskUserQuestionItem` is one question in a request. The caller supplies a stable `id`, which is echoed back with the answer so batched questions remain routable. Optional `detail` carries supporting text that providers render with the question but keep out of selectable option labels.
|
||||
|
||||
```ts type-equiv
|
||||
/** One question in an ask_user_question request. */
|
||||
/** One question in a user-interaction request. */
|
||||
interface AskUserQuestionItem {
|
||||
/** Stable model-provided question id, echoed in the answer. */
|
||||
/** Stable caller-provided question id, echoed in the answer. */
|
||||
id: string
|
||||
/** The question to display. */
|
||||
question: string
|
||||
/** Optional supporting detail rendered with the question but kept out of option labels. */
|
||||
detail?: string
|
||||
/** Optional short heading/group label. */
|
||||
header?: string
|
||||
/** Optional choices the UI can render as a menu. */
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write
|
||||
development.md: f0db7fbcb4a9df98e83d6c1edd5610e5cc4dd517
|
||||
development.zh.md: 62e16479a49d5548e1fbd773dabca5bd741a24fe
|
||||
development.md: 10406cebae1bf83fff663903b1478c9acb8476a1
|
||||
development.zh.md: 50051ffd631518b37c3ad96f5fd3830cf6893ec9
|
||||
|
||||
@@ -35,13 +35,13 @@ pnpm run typecheck
|
||||
|
||||
That first typecheck runs the package/vendor build graph and the root no-emit `tsconfig.json` graph for examples, tests, and scripts. The root graph uses the same source `paths` map but relies on project references so vendored code is checked under its own tsconfig settings.
|
||||
|
||||
If you are preparing to push from a fresh clone or worktree, also build once:
|
||||
If a relevant local check consumes built package output, build once first:
|
||||
|
||||
```sh
|
||||
pnpm run build
|
||||
```
|
||||
|
||||
`pnpm run hygiene` includes `publint`, which validates package entrypoints against the built `lib/*.js` files, and `verify-node-next-types`, which validates built declarations against a temporary NodeNext consumer. A fresh worktree has no bundled JS or declarations until `pnpm run build` runs.
|
||||
`pnpm run hygiene` includes `publint`, which validates package entrypoints against the built `lib/*.js` files, and `verify-node-next-types`, which validates built declarations against a temporary NodeNext consumer. A fresh worktree has no bundled JS or declarations until `pnpm run build` runs; ordinary commits and pushes do not require that build unless their selected checks consume it.
|
||||
|
||||
## Environment variables
|
||||
|
||||
@@ -56,14 +56,14 @@ DEEPSEEK_BASE_URL=https://... # optional
|
||||
|
||||
## Git hooks
|
||||
|
||||
lefthook is configured in `lefthook.yml` as an early local checkpoint before review:
|
||||
lefthook is configured in `lefthook.yml` as a fast local checkpoint:
|
||||
|
||||
- `pre-commit` runs staged-file ESLint fixes, `pnpm run typecheck`, and the vendor manifest guard.
|
||||
- `pre-push` runs `pnpm run check:pre-push`, whose scheduler runs runtime-closure verification, unit tests, duplication detection, snapshot tests, build, module-graph freshness, and the member gates of `pnpm run hygiene` and `pnpm run doc-sync` concurrently.
|
||||
- `pre-commit` runs staged-file ESLint fixes, checks the staged diff for whitespace errors, and runs the vendor manifest guard.
|
||||
- `pre-push` runs only the incremental repository typecheck.
|
||||
|
||||
The vendor manifest guard checks that changes under `vendor/*/src` are staged with the matching `vendor/README.md` manifest update. See `vendor/README.md` before editing vendored code.
|
||||
|
||||
These hooks do not exactly mirror CI. Notably, `pre-push` runs unit tests without coverage, while CI runs `pnpm run test:coverage`; CI also runs built-bin smoke tests and exercises the compatibility matrix on Node 22.19, 24, and 26.
|
||||
The hooks intentionally do not run tests, snapshots, documentation checks, builds, or hygiene. Contributors run the [checks relevant to the changed behavior](../AGENTS.md#run-relevant-checks-locally) once; CI owns exhaustive coverage, built-artifact smokes, and the Node 22.19, 24, and 26 compatibility matrix.
|
||||
|
||||
## CI gates
|
||||
|
||||
|
||||
@@ -35,13 +35,13 @@ pnpm run typecheck
|
||||
|
||||
首次类型检查会执行 package/vendor 的构建图,以及根目录下用于示例、测试和脚本的 no-emit `tsconfig.json` 项目图。根图使用同一份源码 `paths` 映射,但依赖 project references,因此 vendor 代码在它自己的 tsconfig 设置下被检查。
|
||||
|
||||
如果准备从新克隆或新 worktree 推送,还需要构建一次:
|
||||
如果相关的本地检查需要使用构建后的包产物,请先构建一次:
|
||||
|
||||
```sh
|
||||
pnpm run build
|
||||
```
|
||||
|
||||
`pnpm run hygiene` 包含 `publint`(用构建出的 `lib/*.js` 文件校验 package 入口点)和 `verify-node-next-types`(用一个临时的 NodeNext 消费方校验构建出的声明文件)。新 worktree 在 `pnpm run build` 运行之前没有打包的 JS 和声明文件。
|
||||
`pnpm run hygiene` 包含 `publint`(用构建出的 `lib/*.js` 文件校验 package 入口点)和 `verify-node-next-types`(用一个临时的 NodeNext 消费方校验构建出的声明文件)。新 worktree 在 `pnpm run build` 运行之前没有打包的 JS 和声明文件;普通提交和推送无需构建,除非所选检查会使用这些产物。
|
||||
|
||||
## 环境变量
|
||||
|
||||
@@ -56,14 +56,14 @@ DEEPSEEK_BASE_URL=https://... # optional
|
||||
|
||||
## Git 钩子
|
||||
|
||||
lefthook 在 `lefthook.yml` 中配置,作为评审前的本地早期检查点:
|
||||
lefthook 在 `lefthook.yml` 中配置,作为快速的本地检查点:
|
||||
|
||||
- `pre-commit` 运行对暂存文件的 ESLint 修复、`pnpm run typecheck` 和 vendor manifest(元数据清单)守卫;
|
||||
- `pre-push` 运行 `pnpm run check:pre-push`,其调度器并发运行 runtime-closure 校验、单元测试、重复代码检查、快照测试、构建、module-graph 新鲜度,以及 `pnpm run hygiene` 与 `pnpm run doc-sync` 的各成员门禁。
|
||||
- `pre-commit` 运行对暂存文件的 ESLint 修复,检查暂存 diff 中的空白错误,并运行 vendor manifest(元数据清单)守卫;
|
||||
- `pre-push` 只运行仓库增量类型检查。
|
||||
|
||||
vendor manifest 守卫检查 `vendor/*/src` 下的改动是否连同对应的 `vendor/README.md` manifest 更新一起暂存。请在编辑 vendor 代码前先阅读 `vendor/README.md`。
|
||||
|
||||
这些钩子并不与 CI 完全一致。特别是:`pre-push` 运行不带覆盖率的单元测试,而 CI 运行 `pnpm run test:coverage`;CI 还会运行 built-bin 冒烟测试,并在 Node 22.19、24 和 26 上执行兼容性矩阵。
|
||||
这些钩子有意不运行测试、快照、文档检查、构建或 `hygiene`。贡献者只运行一次[与改动行为相关的检查](../AGENTS.md#run-relevant-checks-locally);CI 负责全量覆盖率门禁、构建产物冒烟测试,以及 Node 22.19、24 和 26 兼容性矩阵。
|
||||
|
||||
## CI 门禁
|
||||
|
||||
|
||||
@@ -8,44 +8,44 @@ This matrix shows which packages dispatch each harness-owned event and which pac
|
||||
| Event | Mode | Declared in | Dispatchers | Listeners |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `agent-loop/config-start-failed` | `emit` | [`packages/core/agent-loop/src/index.ts:353`](../packages/core/agent-loop/src/index.ts) | [`agent-loop`](../packages/core/agent-loop) (`events.dispatch`) | [`tui`](../packages/ui/tui) |
|
||||
| `agent/cancel-requested` | `emit` | [`packages/core/agent/src/types.ts:191`](../packages/core/agent/src/types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`goal-session`](../packages/goal/goal-session) |
|
||||
| `agent/created` | `emit` | [`packages/core/agent/src/types.ts:153`](../packages/core/agent/src/types.ts) | [`agent`](../packages/core/agent) (`events.dispatch`) | [`goal-session`](../packages/goal/goal-session), [`tui`](../packages/ui/tui) |
|
||||
| `agent/disposed` | `emit` | [`packages/core/agent/src/types.ts:162`](../packages/core/agent/src/types.ts) | [`agent`](../packages/core/agent) (`events.dispatch`) | [`agent-loop`](../packages/core/agent-loop), [`goal-session`](../packages/goal/goal-session), [`tui`](../packages/ui/tui) |
|
||||
| `agent/error` | `emit` | [`packages/core/agent/src/types.ts:328`](../packages/core/agent/src/types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`goal-session`](../packages/goal/goal-session), [`tui`](../packages/ui/tui) |
|
||||
| `agent/post-step` | `serial` | [`packages/core/agent/src/types.ts:280`](../packages/core/agent/src/types.ts) | [`agent-loop`](../packages/core/agent-loop) (`serial`) | [`compact-basic`](../packages/compact/compact-basic) |
|
||||
| `agent/pre-step` | `serial` | [`packages/core/agent/src/types.ts:220`](../packages/core/agent/src/types.ts) | [`agent-loop`](../packages/core/agent-loop) (`serial`) | [`time-context`](../packages/context/time-context), [`user-approval`](../packages/ui/user-approval) |
|
||||
| `agent/prompt-submit` | `waterfall` | [`packages/core/agent/src/types.ts:230`](../packages/core/agent/src/types.ts) | [`agent-loop`](../packages/core/agent-loop) (`waterfall`) | [`acp`](../packages/ui/acp), [`goal-session`](../packages/goal/goal-session), [`hooks-claude`](../packages/hooks/hooks-claude), [`hooks-codex`](../packages/hooks/hooks-codex), [`repeat-tool-guard`](../packages/guard/repeat-tool-guard) |
|
||||
| `agent/queued` | `emit` | [`packages/core/agent/src/types.ts:181`](../packages/core/agent/src/types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`goal-session`](../packages/goal/goal-session) |
|
||||
| `agent/request` | `waterfall` | [`packages/core/agent/src/types.ts:242`](../packages/core/agent/src/types.ts) | [`agent-loop`](../packages/core/agent-loop) (`waterfall`) | [`agent`](../packages/core/agent) |
|
||||
| `agent/request-error` | `waterfall` | [`packages/core/agent/src/types.ts:295`](../packages/core/agent/src/types.ts) | [`agent-loop`](../packages/core/agent-loop) (`waterfall`) | [`compact-basic`](../packages/compact/compact-basic), [`llm-retry`](../packages/llm/llm-retry) |
|
||||
| `agent/session-prefix` | `waterfall` | [`packages/core/agent/src/types.ts:257`](../packages/core/agent/src/types.ts) | [`agent-loop`](../packages/core/agent-loop) (`waterfall`) | [`tool-skill`](../packages/skill/tool-skill), [`workspace-context`](../packages/context/workspace-context) |
|
||||
| `agent/session-start` | `emit` | [`packages/core/agent/src/types.ts:204`](../packages/core/agent/src/types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`goal`](../packages/goal/goal), [`goal-session`](../packages/goal/goal-session), [`hooks-claude`](../packages/hooks/hooks-claude), [`hooks-codex`](../packages/hooks/hooks-codex) |
|
||||
| `agent/status` | `emit` | [`packages/core/agent/src/types.ts:171`](../packages/core/agent/src/types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`agent`](../packages/core/agent), [`goal-session`](../packages/goal/goal-session), [`tui`](../packages/ui/tui) |
|
||||
| `agent/step-result` | `waterfall` | [`packages/core/agent/src/types.ts:268`](../packages/core/agent/src/types.ts) | [`agent-loop`](../packages/core/agent-loop) (`waterfall`) | - |
|
||||
| `agent/turn-continuation` | `waterfall` | [`packages/core/agent/src/types.ts:305`](../packages/core/agent/src/types.ts) | [`agent-loop`](../packages/core/agent-loop) (`waterfall`) | [`hooks-claude`](../packages/hooks/hooks-claude), [`hooks-codex`](../packages/hooks/hooks-codex) |
|
||||
| `agent/turn-stop` | `serial` | [`packages/core/agent/src/types.ts:315`](../packages/core/agent/src/types.ts) | [`agent-loop`](../packages/core/agent-loop) (`serial`) | [`subagent-inprocess`](../packages/subagent/subagent-inprocess), [`tool-goal`](../packages/goal/tool-goal) |
|
||||
| `approval/request` | `waterfall` | [`packages/ui/user-approval/src/index.ts:31`](../packages/ui/user-approval/src/index.ts) | [`user-approval`](../packages/ui/user-approval) (`waterfall`) | [`acp`](../packages/ui/acp) |
|
||||
| `commands/change` | `emit` | [`packages/ui/commands/src/index.ts:83`](../packages/ui/commands/src/index.ts) | [`commands`](../packages/ui/commands) (`events.dispatch`) | [`acp`](../packages/ui/acp), [`tui`](../packages/ui/tui) |
|
||||
| `agent/cancel-requested` | `emit` | [`packages/core/agent/src/types.ts:201`](../packages/core/agent/src/types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`goal-session`](../packages/goal/goal-session) |
|
||||
| `agent/created` | `emit` | [`packages/core/agent/src/types.ts:163`](../packages/core/agent/src/types.ts) | [`agent`](../packages/core/agent) (`events.dispatch`) | [`goal-session`](../packages/goal/goal-session), [`tui`](../packages/ui/tui) |
|
||||
| `agent/disposed` | `emit` | [`packages/core/agent/src/types.ts:172`](../packages/core/agent/src/types.ts) | [`agent`](../packages/core/agent) (`events.dispatch`) | [`agent-loop`](../packages/core/agent-loop), [`goal-session`](../packages/goal/goal-session), [`tui`](../packages/ui/tui) |
|
||||
| `agent/error` | `emit` | [`packages/core/agent/src/types.ts:346`](../packages/core/agent/src/types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`goal-session`](../packages/goal/goal-session), `runtime`, [`tui`](../packages/ui/tui) |
|
||||
| `agent/post-step` | `serial` | [`packages/core/agent/src/types.ts:296`](../packages/core/agent/src/types.ts) | [`agent-loop`](../packages/core/agent-loop) (`serial`) | [`compact-basic`](../packages/compact/compact-basic) |
|
||||
| `agent/pre-step` | `serial` | [`packages/core/agent/src/types.ts:230`](../packages/core/agent/src/types.ts) | [`agent-loop`](../packages/core/agent-loop) (`serial`) | [`time-context`](../packages/context/time-context), [`user-approval`](../packages/ui/user-approval) |
|
||||
| `agent/prompt-submit` | `waterfall` | [`packages/core/agent/src/types.ts:243`](../packages/core/agent/src/types.ts) | [`agent-loop`](../packages/core/agent-loop) (`waterfall`) | [`acp`](../packages/ui/acp), [`goal-session`](../packages/goal/goal-session), [`hooks-claude`](../packages/hooks/hooks-claude), [`hooks-codex`](../packages/hooks/hooks-codex), [`plan-mode`](../packages/plan/plan-mode), [`repeat-tool-guard`](../packages/guard/repeat-tool-guard) |
|
||||
| `agent/queued` | `emit` | [`packages/core/agent/src/types.ts:191`](../packages/core/agent/src/types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`goal-session`](../packages/goal/goal-session), [`tui`](../packages/ui/tui) |
|
||||
| `agent/request` | `waterfall` | [`packages/core/agent/src/types.ts:257`](../packages/core/agent/src/types.ts) | [`agent-loop`](../packages/core/agent-loop) (`waterfall`) | [`agent`](../packages/core/agent) |
|
||||
| `agent/request-error` | `waterfall` | [`packages/core/agent/src/types.ts:311`](../packages/core/agent/src/types.ts) | [`agent-loop`](../packages/core/agent-loop) (`waterfall`) | [`compact-basic`](../packages/compact/compact-basic), [`llm-retry`](../packages/llm/llm-retry), [`plan-mode`](../packages/plan/plan-mode) |
|
||||
| `agent/session-prefix` | `waterfall` | [`packages/core/agent/src/types.ts:272`](../packages/core/agent/src/types.ts) | [`agent-loop`](../packages/core/agent-loop) (`waterfall`) | [`tool-skill`](../packages/skill/tool-skill), [`workspace-context`](../packages/context/workspace-context) |
|
||||
| `agent/session-start` | `emit` | [`packages/core/agent/src/types.ts:214`](../packages/core/agent/src/types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`goal`](../packages/goal/goal), [`goal-session`](../packages/goal/goal-session), [`hooks-claude`](../packages/hooks/hooks-claude), [`hooks-codex`](../packages/hooks/hooks-codex) |
|
||||
| `agent/status` | `emit` | [`packages/core/agent/src/types.ts:181`](../packages/core/agent/src/types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`agent`](../packages/core/agent), [`goal-session`](../packages/goal/goal-session), `runtime`, [`tui`](../packages/ui/tui) |
|
||||
| `agent/step-result` | `waterfall` | [`packages/core/agent/src/types.ts:284`](../packages/core/agent/src/types.ts) | [`agent-loop`](../packages/core/agent-loop) (`waterfall`) | - |
|
||||
| `agent/turn-continuation` | `waterfall` | [`packages/core/agent/src/types.ts:322`](../packages/core/agent/src/types.ts) | [`agent-loop`](../packages/core/agent-loop) (`waterfall`) | [`hooks-claude`](../packages/hooks/hooks-claude), [`hooks-codex`](../packages/hooks/hooks-codex), [`plan-mode`](../packages/plan/plan-mode) |
|
||||
| `agent/turn-stop` | `serial` | [`packages/core/agent/src/types.ts:333`](../packages/core/agent/src/types.ts) | [`agent-loop`](../packages/core/agent-loop) (`serial`) | [`subagent-inprocess`](../packages/subagent/subagent-inprocess), [`tool-goal`](../packages/goal/tool-goal) |
|
||||
| `approval/request` | `waterfall` | [`packages/ui/user-approval/src/index.ts:30`](../packages/ui/user-approval/src/index.ts) | [`user-approval`](../packages/ui/user-approval) (`waterfall`) | [`acp`](../packages/ui/acp) |
|
||||
| `commands/change` | `emit` | [`packages/ui/commands/src/index.ts:103`](../packages/ui/commands/src/index.ts) | [`commands`](../packages/ui/commands) (`events.dispatch`) | [`acp`](../packages/ui/acp), [`tui`](../packages/ui/tui) |
|
||||
| `fs/edit-intent` | `waterfall` | [`packages/fs/fs/src/index.ts:62`](../packages/fs/fs/src/index.ts) | [`tool-fs`](../packages/fs/tool-fs) (`waterfall`) | [`fs-policy`](../packages/fs/fs-policy) |
|
||||
| `fs/observed` | `emit` | [`packages/fs/fs/src/index.ts:71`](../packages/fs/fs/src/index.ts) | [`tool-fs`](../packages/fs/tool-fs) (`emit`) | [`fs-policy`](../packages/fs/fs-policy) |
|
||||
| `fs/write-intent` | `waterfall` | [`packages/fs/fs/src/index.ts:54`](../packages/fs/fs/src/index.ts) | [`tool-fs`](../packages/fs/tool-fs) (`waterfall`) | [`fs-policy`](../packages/fs/fs-policy) |
|
||||
| `goal/changed` | `emit` | [`packages/goal/goal/src/types.ts:167`](../packages/goal/goal/src/types.ts) | [`goal`](../packages/goal/goal) (`emit`) | [`goal-session`](../packages/goal/goal-session) |
|
||||
| `llm/stream` | `waterfall` | [`packages/llm/llm/src/index.ts:52`](../packages/llm/llm/src/index.ts) | [`llm`](../packages/llm/llm) (`waterfall`) | [`agent-loop`](../packages/core/agent-loop), [`llm`](../packages/llm/llm), [`llm-replay`](../packages/support/llm-replay) |
|
||||
| `session/created` | `emit` | [`packages/core/session/src/index.ts:47`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`compact`](../packages/compact/compact), [`goal`](../packages/goal/goal), [`hook-protocol`](../packages/hooks/hook-protocol), [`jsonrpc`](../packages/ui/jsonrpc), [`llm-retry`](../packages/llm/llm-retry), [`session`](../packages/core/session), [`session-persistence`](../packages/session-persistence/session-persistence), [`user-approval`](../packages/ui/user-approval) |
|
||||
| `session/disposed` | `emit` | [`packages/core/session/src/index.ts:57`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`agent-loop`](../packages/core/agent-loop), [`session-persistence`](../packages/session-persistence/session-persistence) |
|
||||
| `session/event` | `emit` | [`packages/core/session/src/index.ts:69`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`acp`](../packages/ui/acp), [`cli-demo`](../packages/examples/cli-demo), [`compact`](../packages/compact/compact), [`goal`](../packages/goal/goal), [`goal-session`](../packages/goal/goal-session), [`hook-protocol`](../packages/hooks/hook-protocol), [`jsonrpc`](../packages/ui/jsonrpc), [`session`](../packages/core/session), [`session-persistence`](../packages/session-persistence/session-persistence), [`token-meter`](../packages/llm/token-meter), [`tui`](../packages/ui/tui), [`user-approval`](../packages/ui/user-approval), [`workspace-context`](../packages/context/workspace-context) |
|
||||
| `session/flush` | `parallel` | [`packages/core/session/src/index.ts:79`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`session-persistence`](../packages/session-persistence/session-persistence) |
|
||||
| `llm/stream` | `waterfall` | [`packages/llm/llm/src/index.ts:52`](../packages/llm/llm/src/index.ts) | [`llm`](../packages/llm/llm) (`waterfall`) | [`agent-loop`](../packages/core/agent-loop), [`llm`](../packages/llm/llm), [`llm-replay`](../packages/support/llm-replay), [`session-title`](../packages/session-title/session-title) |
|
||||
| `session/created` | `emit` | [`packages/core/session/src/index.ts:68`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`compact`](../packages/compact/compact), [`goal`](../packages/goal/goal), [`hook-protocol`](../packages/hooks/hook-protocol), [`jsonrpc`](../packages/ui/jsonrpc), [`llm-retry`](../packages/llm/llm-retry), `runtime`, [`session`](../packages/core/session), [`session-persistence`](../packages/session-persistence/session-persistence), [`user-approval`](../packages/ui/user-approval) |
|
||||
| `session/disposed` | `emit` | [`packages/core/session/src/index.ts:78`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`agent-loop`](../packages/core/agent-loop), `runtime`, [`session-persistence`](../packages/session-persistence/session-persistence), [`session-title`](../packages/session-title/session-title) |
|
||||
| `session/event` | `emit` | [`packages/core/session/src/index.ts:90`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`acp`](../packages/ui/acp), [`cli-demo`](../packages/examples/cli-demo), [`compact`](../packages/compact/compact), [`goal`](../packages/goal/goal), [`goal-session`](../packages/goal/goal-session), [`hook-protocol`](../packages/hooks/hook-protocol), [`jsonrpc`](../packages/ui/jsonrpc), `runtime`, [`session`](../packages/core/session), [`session-persistence`](../packages/session-persistence/session-persistence), [`session-title`](../packages/session-title/session-title), [`token-meter`](../packages/llm/token-meter), [`tui`](../packages/ui/tui), [`user-approval`](../packages/ui/user-approval), [`workspace-context`](../packages/context/workspace-context) |
|
||||
| `session/flush` | `parallel` | [`packages/core/session/src/index.ts:100`](../packages/core/session/src/index.ts) | [`session`](../packages/core/session) (`events.dispatch`) | [`session-persistence`](../packages/session-persistence/session-persistence) |
|
||||
| `subagent/end` | `emit` | [`packages/subagent/subagent/src/index.ts:139`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`events.dispatch`) | [`hooks-claude`](../packages/hooks/hooks-claude), [`jsonrpc`](../packages/ui/jsonrpc), [`subagent`](../packages/subagent/subagent) |
|
||||
| `subagent/provider-added` | `emit` | [`packages/subagent/subagent/src/index.ts:113`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`emit`) | [`subagent`](../packages/subagent/subagent), [`tool-subagent`](../packages/subagent/tool-subagent) |
|
||||
| `subagent/provider-removed` | `emit` | [`packages/subagent/subagent/src/index.ts:119`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`events.dispatch`) | [`subagent`](../packages/subagent/subagent), [`tool-subagent`](../packages/subagent/tool-subagent) |
|
||||
| `subagent/start` | `emit` | [`packages/subagent/subagent/src/index.ts:130`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`events.dispatch`) | [`hooks-claude`](../packages/hooks/hooks-claude), [`subagent`](../packages/subagent/subagent) |
|
||||
| `system-prompt/assemble` | `waterfall` | [`packages/core/system-prompt/src/index.ts:27`](../packages/core/system-prompt/src/index.ts) | [`system-prompt`](../packages/core/system-prompt) (`waterfall`) | [`agent`](../packages/core/agent), [`system-prompt`](../packages/core/system-prompt) |
|
||||
| `system-prompt/change` | `emit` | [`packages/core/system-prompt/src/index.ts:33`](../packages/core/system-prompt/src/index.ts) | [`system-prompt`](../packages/core/system-prompt) (`emit`) | - |
|
||||
| `tools/change` | `emit` | [`packages/core/tools/src/index.ts:116`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`emit`) | - |
|
||||
| `tools/execute` | `waterfall` | [`packages/core/tools/src/index.ts:89`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`waterfall`) | [`timeout-policy`](../packages/timeout/timeout-policy) |
|
||||
| `tools/post-execute` | `waterfall` | [`packages/core/tools/src/index.ts:98`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`waterfall`) | [`hooks-claude`](../packages/hooks/hooks-claude), [`hooks-codex`](../packages/hooks/hooks-codex), [`repeat-tool-guard`](../packages/guard/repeat-tool-guard), [`spill-policy`](../packages/spill/spill-policy), [`workspace-context`](../packages/context/workspace-context) |
|
||||
| `tools/pre-execute` | `waterfall` | [`packages/core/tools/src/index.ts:80`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`waterfall`) | [`hooks-claude`](../packages/hooks/hooks-claude), [`hooks-codex`](../packages/hooks/hooks-codex) |
|
||||
| `tools/result` | `emit` | [`packages/core/tools/src/index.ts:106`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`events.dispatch`) | [`subagent-inprocess`](../packages/subagent/subagent-inprocess), [`workspace-context`](../packages/context/workspace-context) |
|
||||
| `system-prompt/assemble` | `waterfall` | [`packages/core/system-prompt/src/index.ts:29`](../packages/core/system-prompt/src/index.ts) | [`system-prompt`](../packages/core/system-prompt) (`waterfall`) | [`agent`](../packages/core/agent), [`system-prompt`](../packages/core/system-prompt) |
|
||||
| `system-prompt/change` | `emit` | [`packages/core/system-prompt/src/index.ts:35`](../packages/core/system-prompt/src/index.ts) | [`system-prompt`](../packages/core/system-prompt) (`emit`) | - |
|
||||
| `tools/change` | `emit` | [`packages/core/tools/src/index.ts:123`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`emit`) | - |
|
||||
| `tools/execute` | `waterfall` | [`packages/core/tools/src/index.ts:93`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`waterfall`) | [`timeout-policy`](../packages/timeout/timeout-policy) |
|
||||
| `tools/post-execute` | `waterfall` | [`packages/core/tools/src/index.ts:105`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`waterfall`) | [`hooks-claude`](../packages/hooks/hooks-claude), [`hooks-codex`](../packages/hooks/hooks-codex), [`repeat-tool-guard`](../packages/guard/repeat-tool-guard), [`spill-policy`](../packages/spill/spill-policy), [`workspace-context`](../packages/context/workspace-context) |
|
||||
| `tools/pre-execute` | `waterfall` | [`packages/core/tools/src/index.ts:82`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`waterfall`) | [`hooks-claude`](../packages/hooks/hooks-claude), [`hooks-codex`](../packages/hooks/hooks-codex) |
|
||||
| `tools/result` | `emit` | [`packages/core/tools/src/index.ts:113`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`events.dispatch`) | [`subagent-inprocess`](../packages/subagent/subagent-inprocess), [`workspace-context`](../packages/context/workspace-context) |
|
||||
| `workflow/agent-end` | `emit` | [`packages/workflow/workflow/src/index.ts:81`](../packages/workflow/workflow/src/index.ts) | [`workflow`](../packages/workflow/workflow) (`events.dispatch`) | [`workflow`](../packages/workflow/workflow) |
|
||||
| `workflow/agent-start` | `emit` | [`packages/workflow/workflow/src/index.ts:70`](../packages/workflow/workflow/src/index.ts) | [`workflow`](../packages/workflow/workflow) (`events.dispatch`) | [`workflow`](../packages/workflow/workflow) |
|
||||
| `workflow/end` | `emit` | [`packages/workflow/workflow/src/index.ts:91`](../packages/workflow/workflow/src/index.ts) | [`workflow`](../packages/workflow/workflow) (`events.dispatch`) | [`workflow`](../packages/workflow/workflow) |
|
||||
@@ -57,7 +57,9 @@ This matrix shows which packages dispatch each harness-owned event and which pac
|
||||
|
||||
| Event string | Dispatchers | Listeners |
|
||||
| --- | --- | --- |
|
||||
| `internal/dispatch` | - | [`compact`](../packages/compact/compact), [`fs`](../packages/fs/fs), [`goal`](../packages/goal/goal), [`goal-session`](../packages/goal/goal-session), [`hook-protocol`](../packages/hooks/hook-protocol), [`llm-retry`](../packages/llm/llm-retry), [`permission`](../packages/ui/permission), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent), [`time-context`](../packages/context/time-context), [`tool-todo`](../packages/todo/tool-todo), [`tools`](../packages/core/tools), [`user-approval`](../packages/ui/user-approval), [`workflow`](../packages/workflow/workflow) |
|
||||
| `internal/dispatch` | - | [`compact`](../packages/compact/compact), [`fs`](../packages/fs/fs), [`goal`](../packages/goal/goal), [`goal-session`](../packages/goal/goal-session), [`hook-protocol`](../packages/hooks/hook-protocol), [`llm-retry`](../packages/llm/llm-retry), [`permission`](../packages/ui/permission), [`plan-mode`](../packages/plan/plan-mode), `runtime`, [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent), [`time-context`](../packages/context/time-context), [`tool-todo`](../packages/todo/tool-todo), [`tools`](../packages/core/tools), [`user-approval`](../packages/ui/user-approval), [`workflow`](../packages/workflow/workflow) |
|
||||
| `internal/plugin` | - | `webserver` |
|
||||
| `internal/status` | - | [`agent`](../packages/core/agent) |
|
||||
| `slots/changed` | `runtime` (`emit`) | - |
|
||||
|
||||
Maintenance mode: generated: Cordis event declarations and producer/listener edges are resolved from the repository TypeScript Program.
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write
|
||||
README.md: bd5d8c08a4c474a13342b6b60800cfe0d31e110b
|
||||
README.zh.md: a53ab8d9d6053b39def34505038504fefc80a3f9
|
||||
README.md: c4ddf44ad2497b4ff371918356ab1ec0698c7049
|
||||
README.zh.md: 4a31af4fdee4db2d0362cf9117a6eef4fea32393
|
||||
|
||||
@@ -21,7 +21,7 @@ This repo's documentation is read by people and agents both inside and outside t
|
||||
|
||||
## The gate: verify-translation-pairing
|
||||
|
||||
`pnpm run verify-translation-pairing` (part of `doc-sync`, so CI and the pre-push hook run it) enforces the contract mechanically:
|
||||
`pnpm run verify-translation-pairing` (part of `doc-sync`, which contributors run locally for documentation changes and CI runs exhaustively) enforces the contract mechanically:
|
||||
|
||||
1. Every file listed as `required` in [scripts/translation-pairing.manifest.json](../../scripts/translation-pairing.manifest.json) has a complete pair.
|
||||
2. Every pair that exists at all — required or not — is complete and consistent: all three files present, each side's current blob hash equals the recorded one (editing either side without re-confirming the pair goes red), both sides carry the language switcher, and the structural signatures match in order — heading depths, verbatim code blocks (info string and content), table row and column counts, list kinds, ordered-list starts, item counts, and every link target apart from the switcher.
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
## 门禁:verify-translation-pairing
|
||||
|
||||
`pnpm run verify-translation-pairing`(`doc-sync`(文档同步门禁)的一环,因此 CI 和 pre-push 钩子都会运行)机械地强制执行这份契约:
|
||||
`pnpm run verify-translation-pairing`(`doc-sync`(文档同步门禁)的一环,贡献者会针对文档变更在本地运行,CI 则会完整运行)机械地强制执行这份契约:
|
||||
|
||||
1. [scripts/translation-pairing.manifest.json](../../scripts/translation-pairing.manifest.json) 中 `required` 列出的每个文件都有完整配对。
|
||||
2. 任何已存在的配对——无论是否 required——都完整且一致:三个文件齐全、每一侧的当前 blob hash 等于记录值(改了任一侧而没重新确认配对就变红)、双方都带语言切换行、结构签名按序一致——标题深度、逐字节一致的代码块(信息字符串与内容)、表格行列数、列表类型、有序列表起始编号、列表项数量,以及除切换行之外的每个链接目标。
|
||||
|
||||
@@ -9,7 +9,6 @@ Inter-package dependencies among the `@deepseek-ai/dsh-*` harness packages, deri
|
||||
flowchart TD
|
||||
subgraph group_util["packages/util"]
|
||||
pkg_brand["brand"]
|
||||
pkg_home["home"]
|
||||
pkg_paths["paths"]
|
||||
pkg_retention["retention"]
|
||||
pkg_timeout["timeout"]
|
||||
@@ -87,6 +86,9 @@ flowchart TD
|
||||
subgraph group_todo["packages/todo"]
|
||||
pkg_tool_todo["tool-todo"]
|
||||
end
|
||||
subgraph group_plan["packages/plan"]
|
||||
pkg_plan_mode["plan-mode"]
|
||||
end
|
||||
subgraph group_cordis["packages/cordis"]
|
||||
pkg_tool_cordis["tool-cordis"]
|
||||
end
|
||||
@@ -103,6 +105,12 @@ flowchart TD
|
||||
subgraph group_session_query["packages/session-query"]
|
||||
pkg_session_query["session-query"]
|
||||
end
|
||||
subgraph group_session_title["packages/session-title"]
|
||||
pkg_session_title["session-title"]
|
||||
pkg_session_title_all_messages_llm["session-title-all-messages-llm"]
|
||||
pkg_session_title_first_message_llm["session-title-first-message-llm"]
|
||||
pkg_session_title_llm["session-title-llm"]
|
||||
end
|
||||
subgraph group_support["packages/support"]
|
||||
pkg_acp_snapshot["acp-snapshot"]
|
||||
pkg_agent_loop_testkit["agent-loop-testkit"]
|
||||
@@ -121,6 +129,20 @@ flowchart TD
|
||||
pkg_user_approval["user-approval"]
|
||||
pkg_user_interaction["user-interaction"]
|
||||
end
|
||||
subgraph group_client["packages/client"]
|
||||
pkg_client_connection["client-connection"]
|
||||
pkg_client_i18n["client-i18n"]
|
||||
pkg_client_runtime["client-runtime"]
|
||||
pkg_client_ui_conversation["client-ui-conversation"]
|
||||
pkg_client_ui_layout["client-ui-layout"]
|
||||
pkg_client_ui_primitives["client-ui-primitives"]
|
||||
pkg_client_ui_sidebar["client-ui-sidebar"]
|
||||
pkg_client_ui_slots["client-ui-slots"]
|
||||
pkg_client_ui_theme["client-ui-theme"]
|
||||
pkg_client_ui_trajectory["client-ui-trajectory"]
|
||||
pkg_client_web["client-web"]
|
||||
pkg_client_web_react["client-web-react"]
|
||||
end
|
||||
subgraph group_code_runtime["packages/code-runtime"]
|
||||
pkg_code_runtime["code-runtime"]
|
||||
pkg_code_runtime_worker["code-runtime-worker"]
|
||||
@@ -139,6 +161,11 @@ flowchart TD
|
||||
subgraph group_guard["packages/guard"]
|
||||
pkg_repeat_tool_guard["repeat-tool-guard"]
|
||||
end
|
||||
subgraph group_host["packages/host"]
|
||||
pkg_host_apiproxy["host-apiproxy"]
|
||||
pkg_host_runtime["host-runtime"]
|
||||
pkg_host_webserver["host-webserver"]
|
||||
end
|
||||
subgraph group_lsp["packages/lsp"]
|
||||
pkg_lsp["lsp"]
|
||||
pkg_lsp_local["lsp-local"]
|
||||
@@ -168,7 +195,6 @@ flowchart TD
|
||||
pkg_workflow_workerthread["workflow-workerthread"]
|
||||
end
|
||||
pkg_brand --> pkg_invariants
|
||||
pkg_home --> pkg_invariants
|
||||
pkg_paths --> pkg_invariants
|
||||
pkg_retention --> pkg_invariants
|
||||
pkg_timeout --> pkg_invariants
|
||||
@@ -177,19 +203,32 @@ flowchart TD
|
||||
pkg_subagent_subprocess --> pkg_invariants
|
||||
pkg_acp_snapshot --> pkg_invariants
|
||||
pkg_loader_smoke --> pkg_invariants
|
||||
pkg_app_boot --> pkg_invariants
|
||||
pkg_client_connection --> pkg_invariants
|
||||
pkg_client_i18n --> pkg_invariants
|
||||
pkg_client_runtime --> pkg_invariants
|
||||
pkg_client_ui_conversation --> pkg_invariants
|
||||
pkg_client_ui_layout --> pkg_invariants
|
||||
pkg_client_ui_primitives --> pkg_invariants
|
||||
pkg_client_ui_sidebar --> pkg_invariants
|
||||
pkg_client_ui_slots --> pkg_invariants
|
||||
pkg_client_ui_theme --> pkg_invariants
|
||||
pkg_client_ui_trajectory --> pkg_invariants
|
||||
pkg_client_web --> pkg_invariants
|
||||
pkg_client_web_react --> pkg_invariants
|
||||
pkg_code_runtime --> pkg_invariants
|
||||
pkg_jsonrpc_demo --> pkg_invariants
|
||||
pkg_host_apiproxy --> pkg_invariants
|
||||
pkg_host_runtime --> pkg_invariants
|
||||
pkg_host_webserver --> pkg_invariants
|
||||
pkg_llm --> pkg_brand
|
||||
pkg_llm --> pkg_invariants
|
||||
pkg_code_runtime_worker --> pkg_code_runtime
|
||||
pkg_code_runtime_worker --> pkg_invariants
|
||||
pkg_helper --> pkg_brand
|
||||
pkg_helper --> pkg_invariants
|
||||
pkg_scripts --> pkg_app_boot
|
||||
pkg_scripts --> pkg_invariants
|
||||
pkg_telemetry --> pkg_brand
|
||||
pkg_telemetry --> pkg_invariants
|
||||
pkg_telemetry --> pkg_paths
|
||||
pkg_llm_deepseek --> pkg_invariants
|
||||
pkg_llm_deepseek --> pkg_llm
|
||||
pkg_llm_deepseek --> pkg_timeout
|
||||
@@ -246,9 +285,16 @@ flowchart TD
|
||||
pkg_spill --> pkg_session
|
||||
pkg_session_persistence --> pkg_invariants
|
||||
pkg_session_persistence --> pkg_session
|
||||
pkg_session_title --> pkg_brand
|
||||
pkg_session_title --> pkg_invariants
|
||||
pkg_session_title --> pkg_llm
|
||||
pkg_session_title --> pkg_session
|
||||
pkg_llm_replay --> pkg_invariants
|
||||
pkg_llm_replay --> pkg_llm
|
||||
pkg_llm_replay --> pkg_session
|
||||
pkg_app_boot --> pkg_invariants
|
||||
pkg_app_boot --> pkg_paths
|
||||
pkg_app_boot --> pkg_system_prompt
|
||||
pkg_lsp_local --> pkg_brand
|
||||
pkg_lsp_local --> pkg_invariants
|
||||
pkg_lsp_local --> pkg_llm
|
||||
@@ -279,8 +325,8 @@ flowchart TD
|
||||
pkg_fs_policy --> pkg_fs
|
||||
pkg_fs_policy --> pkg_invariants
|
||||
pkg_skill_local --> pkg_fs
|
||||
pkg_skill_local --> pkg_home
|
||||
pkg_skill_local --> pkg_invariants
|
||||
pkg_skill_local --> pkg_paths
|
||||
pkg_skill_local --> pkg_skill
|
||||
pkg_compact_basic --> pkg_agent
|
||||
pkg_compact_basic --> pkg_compact
|
||||
@@ -304,6 +350,12 @@ flowchart TD
|
||||
pkg_session_query --> pkg_llm
|
||||
pkg_session_query --> pkg_session
|
||||
pkg_session_query --> pkg_session_persistence
|
||||
pkg_session_query --> pkg_session_title
|
||||
pkg_session_title_llm --> pkg_invariants
|
||||
pkg_session_title_llm --> pkg_llm
|
||||
pkg_session_title_llm --> pkg_session
|
||||
pkg_session_title_llm --> pkg_session_title
|
||||
pkg_session_title_llm --> pkg_timeout
|
||||
pkg_commands --> pkg_agent
|
||||
pkg_commands --> pkg_invariants
|
||||
pkg_commands --> pkg_scope
|
||||
@@ -320,6 +372,8 @@ flowchart TD
|
||||
pkg_time_context --> pkg_agent
|
||||
pkg_time_context --> pkg_invariants
|
||||
pkg_time_context --> pkg_session
|
||||
pkg_scripts --> pkg_app_boot
|
||||
pkg_scripts --> pkg_invariants
|
||||
pkg_tasks --> pkg_agent
|
||||
pkg_tasks --> pkg_brand
|
||||
pkg_tasks --> pkg_invariants
|
||||
@@ -356,6 +410,16 @@ flowchart TD
|
||||
pkg_fs_sandbox --> pkg_invariants
|
||||
pkg_fs_sandbox --> pkg_sandbox
|
||||
pkg_fs_sandbox --> pkg_sandbox_policy
|
||||
pkg_session_title_all_messages_llm --> pkg_invariants
|
||||
pkg_session_title_all_messages_llm --> pkg_llm
|
||||
pkg_session_title_all_messages_llm --> pkg_session
|
||||
pkg_session_title_all_messages_llm --> pkg_session_title
|
||||
pkg_session_title_all_messages_llm --> pkg_session_title_llm
|
||||
pkg_session_title_first_message_llm --> pkg_invariants
|
||||
pkg_session_title_first_message_llm --> pkg_llm
|
||||
pkg_session_title_first_message_llm --> pkg_session
|
||||
pkg_session_title_first_message_llm --> pkg_session_title
|
||||
pkg_session_title_first_message_llm --> pkg_session_title_llm
|
||||
pkg_permission --> pkg_bash
|
||||
pkg_permission --> pkg_invariants
|
||||
pkg_permission --> pkg_sandbox
|
||||
@@ -379,9 +443,9 @@ flowchart TD
|
||||
pkg_tool_goal --> pkg_tools
|
||||
pkg_tool_bash --> pkg_agent
|
||||
pkg_tool_bash --> pkg_bash
|
||||
pkg_tool_bash --> pkg_home
|
||||
pkg_tool_bash --> pkg_invariants
|
||||
pkg_tool_bash --> pkg_llm
|
||||
pkg_tool_bash --> pkg_paths
|
||||
pkg_tool_bash --> pkg_sandbox
|
||||
pkg_tool_bash --> pkg_sandbox_policy
|
||||
pkg_tool_bash --> pkg_session_persistence
|
||||
@@ -437,6 +501,13 @@ flowchart TD
|
||||
pkg_tool_todo --> pkg_invariants
|
||||
pkg_tool_todo --> pkg_session
|
||||
pkg_tool_todo --> pkg_tools
|
||||
pkg_plan_mode --> pkg_agent
|
||||
pkg_plan_mode --> pkg_commands
|
||||
pkg_plan_mode --> pkg_invariants
|
||||
pkg_plan_mode --> pkg_session
|
||||
pkg_plan_mode --> pkg_system_prompt
|
||||
pkg_plan_mode --> pkg_tools
|
||||
pkg_plan_mode --> pkg_user_interaction
|
||||
pkg_tool_cordis --> pkg_invariants
|
||||
pkg_tool_cordis --> pkg_scope
|
||||
pkg_tool_cordis --> pkg_tools
|
||||
@@ -453,20 +524,6 @@ flowchart TD
|
||||
pkg_agent_loop_testkit --> pkg_session
|
||||
pkg_agent_loop_testkit --> pkg_system_prompt
|
||||
pkg_agent_loop_testkit --> pkg_tools
|
||||
pkg_acp --> pkg_agent
|
||||
pkg_acp --> pkg_bash
|
||||
pkg_acp --> pkg_commands
|
||||
pkg_acp --> pkg_invariants
|
||||
pkg_acp --> pkg_llm
|
||||
pkg_acp --> pkg_llm_retry
|
||||
pkg_acp --> pkg_permission
|
||||
pkg_acp --> pkg_sandbox
|
||||
pkg_acp --> pkg_session
|
||||
pkg_acp --> pkg_session_persistence
|
||||
pkg_acp --> pkg_system_prompt
|
||||
pkg_acp --> pkg_tools
|
||||
pkg_acp --> pkg_user_approval
|
||||
pkg_acp --> pkg_user_interaction
|
||||
pkg_tool_ask_user --> pkg_agent
|
||||
pkg_tool_ask_user --> pkg_invariants
|
||||
pkg_tool_ask_user --> pkg_tools
|
||||
@@ -528,6 +585,22 @@ flowchart TD
|
||||
pkg_hooks_claude --> pkg_session_persistence
|
||||
pkg_hooks_claude --> pkg_subagent
|
||||
pkg_hooks_claude --> pkg_tools
|
||||
pkg_acp --> pkg_agent
|
||||
pkg_acp --> pkg_bash
|
||||
pkg_acp --> pkg_commands
|
||||
pkg_acp --> pkg_invariants
|
||||
pkg_acp --> pkg_llm
|
||||
pkg_acp --> pkg_llm_retry
|
||||
pkg_acp --> pkg_permission
|
||||
pkg_acp --> pkg_plan_mode
|
||||
pkg_acp --> pkg_sandbox
|
||||
pkg_acp --> pkg_session
|
||||
pkg_acp --> pkg_session_persistence
|
||||
pkg_acp --> pkg_session_title
|
||||
pkg_acp --> pkg_system_prompt
|
||||
pkg_acp --> pkg_tools
|
||||
pkg_acp --> pkg_user_approval
|
||||
pkg_acp --> pkg_user_interaction
|
||||
pkg_jsonrpc --> pkg_agent
|
||||
pkg_jsonrpc --> pkg_invariants
|
||||
pkg_jsonrpc --> pkg_llm
|
||||
@@ -542,6 +615,9 @@ flowchart TD
|
||||
pkg_tui --> pkg_llm
|
||||
pkg_tui --> pkg_llm_retry
|
||||
pkg_tui --> pkg_session
|
||||
pkg_tui --> pkg_session_persistence
|
||||
pkg_tui --> pkg_session_title
|
||||
pkg_tui --> pkg_skill
|
||||
pkg_tui --> pkg_system_prompt
|
||||
pkg_tui --> pkg_token_meter
|
||||
pkg_tui --> pkg_tools
|
||||
@@ -550,12 +626,13 @@ flowchart TD
|
||||
pkg_agent_spine_demo --> pkg_agent_loop
|
||||
pkg_agent_spine_demo --> pkg_goal
|
||||
pkg_agent_spine_demo --> pkg_goal_session
|
||||
pkg_agent_spine_demo --> pkg_home
|
||||
pkg_agent_spine_demo --> pkg_invariants
|
||||
pkg_agent_spine_demo --> pkg_llm
|
||||
pkg_agent_spine_demo --> pkg_llm_retry
|
||||
pkg_agent_spine_demo --> pkg_paths
|
||||
pkg_agent_spine_demo --> pkg_scope
|
||||
pkg_agent_spine_demo --> pkg_session
|
||||
pkg_agent_spine_demo --> pkg_session_title
|
||||
pkg_agent_spine_demo --> pkg_skill
|
||||
pkg_agent_spine_demo --> pkg_skill_local
|
||||
pkg_agent_spine_demo --> pkg_system_prompt
|
||||
@@ -629,7 +706,6 @@ flowchart TD
|
||||
| --- | --- | --- |
|
||||
| [`invariants`](../packages/support/invariants) | `support` | — |
|
||||
| [`brand`](../packages/util/brand) | `util` | [`invariants`](../packages/support/invariants) |
|
||||
| [`home`](../packages/util/home) | `util` | [`invariants`](../packages/support/invariants) |
|
||||
| [`paths`](../packages/util/paths) | `util` | [`invariants`](../packages/support/invariants) |
|
||||
| [`retention`](../packages/util/retention) | `util` | [`invariants`](../packages/support/invariants) |
|
||||
| [`timeout`](../packages/util/timeout) | `util` | [`invariants`](../packages/support/invariants) |
|
||||
@@ -638,14 +714,27 @@ flowchart TD
|
||||
| [`subagent-subprocess`](../packages/subagent/subagent-subprocess) | `subagent` | [`invariants`](../packages/support/invariants) |
|
||||
| [`acp-snapshot`](../packages/support/acp-snapshot) | `support` | [`invariants`](../packages/support/invariants) |
|
||||
| [`loader-smoke`](../packages/support/loader-smoke) | `support` | [`invariants`](../packages/support/invariants) |
|
||||
| [`app-boot`](../packages/ui/app-boot) | `ui` | [`invariants`](../packages/support/invariants) |
|
||||
| [`client-connection`](../packages/client/connection) | `client` | [`invariants`](../packages/support/invariants) |
|
||||
| [`client-i18n`](../packages/client/i18n) | `client` | [`invariants`](../packages/support/invariants) |
|
||||
| [`client-runtime`](../packages/client/runtime) | `client` | [`invariants`](../packages/support/invariants) |
|
||||
| [`client-ui-conversation`](../packages/client/ui-conversation) | `client` | [`invariants`](../packages/support/invariants) |
|
||||
| [`client-ui-layout`](../packages/client/ui-layout) | `client` | [`invariants`](../packages/support/invariants) |
|
||||
| [`client-ui-primitives`](../packages/client/ui-primitives) | `client` | [`invariants`](../packages/support/invariants) |
|
||||
| [`client-ui-sidebar`](../packages/client/ui-sidebar) | `client` | [`invariants`](../packages/support/invariants) |
|
||||
| [`client-ui-slots`](../packages/client/ui-slots) | `client` | [`invariants`](../packages/support/invariants) |
|
||||
| [`client-ui-theme`](../packages/client/ui-theme) | `client` | [`invariants`](../packages/support/invariants) |
|
||||
| [`client-ui-trajectory`](../packages/client/ui-trajectory) | `client` | [`invariants`](../packages/support/invariants) |
|
||||
| [`client-web`](../packages/client/web) | `client` | [`invariants`](../packages/support/invariants) |
|
||||
| [`client-web-react`](../packages/client/web-react) | `client` | [`invariants`](../packages/support/invariants) |
|
||||
| [`code-runtime`](../packages/code-runtime/code-runtime) | `code-runtime` | [`invariants`](../packages/support/invariants) |
|
||||
| [`jsonrpc-demo`](../packages/examples/jsonrpc-demo) | `examples` | [`invariants`](../packages/support/invariants) |
|
||||
| [`host-apiproxy`](../packages/host/apiproxy) | `host` | [`invariants`](../packages/support/invariants) |
|
||||
| [`host-runtime`](../packages/host/runtime) | `host` | [`invariants`](../packages/support/invariants) |
|
||||
| [`host-webserver`](../packages/host/webserver) | `host` | [`invariants`](../packages/support/invariants) |
|
||||
| [`llm`](../packages/llm/llm) | `llm` | [`brand`](../packages/util/brand), [`invariants`](../packages/support/invariants) |
|
||||
| [`code-runtime-worker`](../packages/code-runtime/code-runtime-worker) | `code-runtime` | [`code-runtime`](../packages/code-runtime/code-runtime), [`invariants`](../packages/support/invariants) |
|
||||
| [`helper`](../packages/sdk/helper) | `sdk` | [`brand`](../packages/util/brand), [`invariants`](../packages/support/invariants) |
|
||||
| [`scripts`](../packages/sdk/scripts) | `sdk` | [`app-boot`](../packages/ui/app-boot), [`invariants`](../packages/support/invariants) |
|
||||
| [`telemetry`](../packages/sdk/telemetry) | `sdk` | [`brand`](../packages/util/brand), [`invariants`](../packages/support/invariants) |
|
||||
| [`telemetry`](../packages/sdk/telemetry) | `sdk` | [`brand`](../packages/util/brand), [`invariants`](../packages/support/invariants), [`paths`](../packages/util/paths) |
|
||||
| [`llm-deepseek`](../packages/llm/llm-deepseek) | `llm` | [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`timeout`](../packages/util/timeout) |
|
||||
| [`llm-pi-ai`](../packages/llm/llm-pi-ai) | `llm` | [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`timeout`](../packages/util/timeout) |
|
||||
| [`session`](../packages/core/session) | `core` | [`brand`](../packages/util/brand), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`scope`](../packages/core/scope) |
|
||||
@@ -665,7 +754,9 @@ flowchart TD
|
||||
| [`web-search-perplexity`](../packages/web/web-search-perplexity) | `web` | [`invariants`](../packages/support/invariants), [`web`](../packages/web/web) |
|
||||
| [`spill`](../packages/spill/spill) | `spill` | [`brand`](../packages/util/brand), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session) |
|
||||
| [`session-persistence`](../packages/session-persistence/session-persistence) | `session-persistence` | [`invariants`](../packages/support/invariants), [`session`](../packages/core/session) |
|
||||
| [`session-title`](../packages/session-title/session-title) | `session-title` | [`brand`](../packages/util/brand), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session) |
|
||||
| [`llm-replay`](../packages/support/llm-replay) | `support` | [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session) |
|
||||
| [`app-boot`](../packages/ui/app-boot) | `ui` | [`invariants`](../packages/support/invariants), [`paths`](../packages/util/paths), [`system-prompt`](../packages/core/system-prompt) |
|
||||
| [`lsp-local`](../packages/lsp/lsp-local) | `lsp` | [`brand`](../packages/util/brand), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`lsp`](../packages/lsp/lsp), [`timeout`](../packages/util/timeout) |
|
||||
| [`sandbox-local`](../packages/sandbox/sandbox-local) | `sandbox` | [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`sandbox`](../packages/sandbox/sandbox) |
|
||||
| [`sandbox-policy`](../packages/sandbox/sandbox-policy) | `sandbox` | [`invariants`](../packages/support/invariants), [`sandbox`](../packages/sandbox/sandbox), [`session`](../packages/core/session) |
|
||||
@@ -674,17 +765,19 @@ flowchart TD
|
||||
| [`bash-local`](../packages/bash/bash-local) | `bash` | [`bash`](../packages/bash/bash), [`invariants`](../packages/support/invariants), [`timeout`](../packages/util/timeout) |
|
||||
| [`fs-local`](../packages/fs/fs-local) | `fs` | [`fs`](../packages/fs/fs), [`invariants`](../packages/support/invariants) |
|
||||
| [`fs-policy`](../packages/fs/fs-policy) | `fs` | [`fs`](../packages/fs/fs), [`invariants`](../packages/support/invariants) |
|
||||
| [`skill-local`](../packages/skill/skill-local) | `skill` | [`fs`](../packages/fs/fs), [`home`](../packages/util/home), [`invariants`](../packages/support/invariants), [`skill`](../packages/skill/skill) |
|
||||
| [`skill-local`](../packages/skill/skill-local) | `skill` | [`fs`](../packages/fs/fs), [`invariants`](../packages/support/invariants), [`paths`](../packages/util/paths), [`skill`](../packages/skill/skill) |
|
||||
| [`compact-basic`](../packages/compact/compact-basic) | `compact` | [`agent`](../packages/core/agent), [`compact`](../packages/compact/compact), [`compact-tool-result-prune`](../packages/compact/compact-tool-result-prune), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`token-meter`](../packages/llm/token-meter) |
|
||||
| [`spill-local`](../packages/spill/spill-local) | `spill` | [`invariants`](../packages/support/invariants), [`spill`](../packages/spill/spill) |
|
||||
| [`hook-protocol`](../packages/hooks/hook-protocol) | `hooks` | [`bash`](../packages/bash/bash), [`invariants`](../packages/support/invariants), [`session`](../packages/core/session) |
|
||||
| [`session-persistence-jsonl`](../packages/session-persistence/session-persistence-jsonl) | `session-persistence` | [`invariants`](../packages/support/invariants), [`session`](../packages/core/session), [`session-persistence`](../packages/session-persistence/session-persistence) |
|
||||
| [`session-persistence-sqlite`](../packages/session-persistence/session-persistence-sqlite) | `session-persistence` | [`invariants`](../packages/support/invariants), [`session`](../packages/core/session), [`session-persistence`](../packages/session-persistence/session-persistence) |
|
||||
| [`session-query`](../packages/session-query/session-query) | `session-query` | [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`session-persistence`](../packages/session-persistence/session-persistence) |
|
||||
| [`session-query`](../packages/session-query/session-query) | `session-query` | [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`session-persistence`](../packages/session-persistence/session-persistence), [`session-title`](../packages/session-title/session-title) |
|
||||
| [`session-title-llm`](../packages/session-title/session-title-llm) | `session-title` | [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`session-title`](../packages/session-title/session-title), [`timeout`](../packages/util/timeout) |
|
||||
| [`commands`](../packages/ui/commands) | `ui` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`scope`](../packages/core/scope) |
|
||||
| [`user-approval`](../packages/ui/user-approval) | `ui` | [`agent`](../packages/core/agent), [`brand`](../packages/util/brand), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`system-prompt`](../packages/core/system-prompt) |
|
||||
| [`user-interaction`](../packages/ui/user-interaction) | `ui` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm) |
|
||||
| [`time-context`](../packages/context/time-context) | `context` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`session`](../packages/core/session) |
|
||||
| [`scripts`](../packages/sdk/scripts) | `sdk` | [`app-boot`](../packages/ui/app-boot), [`invariants`](../packages/support/invariants) |
|
||||
| [`tasks`](../packages/tasks/tasks) | `tasks` | [`agent`](../packages/core/agent), [`brand`](../packages/util/brand), [`invariants`](../packages/support/invariants), [`session`](../packages/core/session), [`timeout`](../packages/util/timeout) |
|
||||
| [`workflow`](../packages/workflow/workflow) | `workflow` | [`agent`](../packages/core/agent), [`brand`](../packages/util/brand), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session) |
|
||||
| [`tools`](../packages/core/tools) | `core` | [`agent`](../packages/core/agent), [`code-runtime`](../packages/code-runtime/code-runtime), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`system-prompt`](../packages/core/system-prompt), [`user-approval`](../packages/ui/user-approval) |
|
||||
@@ -692,10 +785,12 @@ flowchart TD
|
||||
| [`goal-session`](../packages/goal/goal-session) | `goal` | [`agent`](../packages/core/agent), [`goal`](../packages/goal/goal), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session) |
|
||||
| [`bash-sandbox`](../packages/bash/bash-sandbox) | `bash` | [`bash`](../packages/bash/bash), [`bash-local`](../packages/bash/bash-local), [`invariants`](../packages/support/invariants), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy) |
|
||||
| [`fs-sandbox`](../packages/fs/fs-sandbox) | `fs` | [`fs`](../packages/fs/fs), [`fs-local`](../packages/fs/fs-local), [`invariants`](../packages/support/invariants), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy) |
|
||||
| [`session-title-all-messages-llm`](../packages/session-title/session-title-all-messages-llm) | `session-title` | [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`session-title`](../packages/session-title/session-title), [`session-title-llm`](../packages/session-title/session-title-llm) |
|
||||
| [`session-title-first-message-llm`](../packages/session-title/session-title-first-message-llm) | `session-title` | [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`session-title`](../packages/session-title/session-title), [`session-title-llm`](../packages/session-title/session-title-llm) |
|
||||
| [`permission`](../packages/ui/permission) | `ui` | [`bash`](../packages/bash/bash), [`invariants`](../packages/support/invariants), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`session`](../packages/core/session), [`user-approval`](../packages/ui/user-approval) |
|
||||
| [`agent-loop`](../packages/core/agent-loop) | `core` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`session-persistence`](../packages/session-persistence/session-persistence), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools) |
|
||||
| [`tool-goal`](../packages/goal/tool-goal) | `goal` | [`agent`](../packages/core/agent), [`goal`](../packages/goal/goal), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools) |
|
||||
| [`tool-bash`](../packages/bash/tool-bash) | `bash` | [`agent`](../packages/core/agent), [`bash`](../packages/bash/bash), [`home`](../packages/util/home), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`session-persistence`](../packages/session-persistence/session-persistence), [`system-prompt`](../packages/core/system-prompt), [`tasks`](../packages/tasks/tasks), [`tools`](../packages/core/tools), [`user-approval`](../packages/ui/user-approval) |
|
||||
| [`tool-bash`](../packages/bash/tool-bash) | `bash` | [`agent`](../packages/core/agent), [`bash`](../packages/bash/bash), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`paths`](../packages/util/paths), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`session-persistence`](../packages/session-persistence/session-persistence), [`system-prompt`](../packages/core/system-prompt), [`tasks`](../packages/tasks/tasks), [`tools`](../packages/core/tools), [`user-approval`](../packages/ui/user-approval) |
|
||||
| [`tool-fs`](../packages/fs/tool-fs) | `fs` | [`fs`](../packages/fs/fs), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`session`](../packages/core/session), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools), [`user-approval`](../packages/ui/user-approval) |
|
||||
| [`tool-fs-search`](../packages/fs/tool-fs-search) | `fs` | [`bash`](../packages/bash/bash), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`retention`](../packages/util/retention), [`session`](../packages/core/session), [`spill`](../packages/spill/spill), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools) |
|
||||
| [`tool-skill`](../packages/skill/tool-skill) | `skill` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`skill`](../packages/skill/skill), [`tools`](../packages/core/tools) |
|
||||
@@ -704,10 +799,10 @@ flowchart TD
|
||||
| [`spill-policy`](../packages/spill/spill-policy) | `spill` | [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`retention`](../packages/util/retention), [`session`](../packages/core/session), [`spill`](../packages/spill/spill), [`tools`](../packages/core/tools) |
|
||||
| [`timeout-policy`](../packages/timeout/timeout-policy) | `timeout` | [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`timeout`](../packages/util/timeout), [`tools`](../packages/core/tools) |
|
||||
| [`tool-todo`](../packages/todo/tool-todo) | `todo` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`session`](../packages/core/session), [`tools`](../packages/core/tools) |
|
||||
| [`plan-mode`](../packages/plan/plan-mode) | `plan` | [`agent`](../packages/core/agent), [`commands`](../packages/ui/commands), [`invariants`](../packages/support/invariants), [`session`](../packages/core/session), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools), [`user-interaction`](../packages/ui/user-interaction) |
|
||||
| [`tool-cordis`](../packages/cordis/tool-cordis) | `cordis` | [`invariants`](../packages/support/invariants), [`scope`](../packages/core/scope), [`tools`](../packages/core/tools) |
|
||||
| [`hooks-codex`](../packages/hooks/hooks-codex) | `hooks` | [`agent`](../packages/core/agent), [`hook-protocol`](../packages/hooks/hook-protocol), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`session-persistence`](../packages/session-persistence/session-persistence), [`tools`](../packages/core/tools) |
|
||||
| [`agent-loop-testkit`](../packages/support/agent-loop-testkit) | `support` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools) |
|
||||
| [`acp`](../packages/ui/acp) | `ui` | [`agent`](../packages/core/agent), [`bash`](../packages/bash/bash), [`commands`](../packages/ui/commands), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`llm-retry`](../packages/llm/llm-retry), [`permission`](../packages/ui/permission), [`sandbox`](../packages/sandbox/sandbox), [`session`](../packages/core/session), [`session-persistence`](../packages/session-persistence/session-persistence), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools), [`user-approval`](../packages/ui/user-approval), [`user-interaction`](../packages/ui/user-interaction) |
|
||||
| [`tool-ask-user`](../packages/ui/tool-ask-user) | `ui` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`tools`](../packages/core/tools), [`user-interaction`](../packages/ui/user-interaction) |
|
||||
| [`workspace-context`](../packages/context/workspace-context) | `context` | [`agent`](../packages/core/agent), [`fs`](../packages/fs/fs), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`paths`](../packages/util/paths), [`session`](../packages/core/session), [`tools`](../packages/core/tools) |
|
||||
| [`repeat-tool-guard`](../packages/guard/repeat-tool-guard) | `guard` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`tools`](../packages/core/tools) |
|
||||
@@ -719,9 +814,10 @@ flowchart TD
|
||||
| [`subagent-inprocess`](../packages/subagent/subagent-inprocess) | `subagent` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools) |
|
||||
| [`tool-subagent`](../packages/subagent/tool-subagent) | `subagent` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`subagent`](../packages/subagent/subagent), [`tasks`](../packages/tasks/tasks), [`tools`](../packages/core/tools) |
|
||||
| [`hooks-claude`](../packages/hooks/hooks-claude) | `hooks` | [`agent`](../packages/core/agent), [`hook-protocol`](../packages/hooks/hook-protocol), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`session-persistence`](../packages/session-persistence/session-persistence), [`subagent`](../packages/subagent/subagent), [`tools`](../packages/core/tools) |
|
||||
| [`acp`](../packages/ui/acp) | `ui` | [`agent`](../packages/core/agent), [`bash`](../packages/bash/bash), [`commands`](../packages/ui/commands), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`llm-retry`](../packages/llm/llm-retry), [`permission`](../packages/ui/permission), [`plan-mode`](../packages/plan/plan-mode), [`sandbox`](../packages/sandbox/sandbox), [`session`](../packages/core/session), [`session-persistence`](../packages/session-persistence/session-persistence), [`session-title`](../packages/session-title/session-title), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools), [`user-approval`](../packages/ui/user-approval), [`user-interaction`](../packages/ui/user-interaction) |
|
||||
| [`jsonrpc`](../packages/ui/jsonrpc) | `ui` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`llm-deepseek`](../packages/llm/llm-deepseek), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent) |
|
||||
| [`tui`](../packages/ui/tui) | `ui` | [`agent`](../packages/core/agent), [`agent-loop`](../packages/core/agent-loop), [`commands`](../packages/ui/commands), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`llm-retry`](../packages/llm/llm-retry), [`session`](../packages/core/session), [`system-prompt`](../packages/core/system-prompt), [`token-meter`](../packages/llm/token-meter), [`tools`](../packages/core/tools), [`user-interaction`](../packages/ui/user-interaction) |
|
||||
| [`agent-spine-demo`](../packages/examples/agent-spine-demo) | `examples` | [`agent`](../packages/core/agent), [`agent-loop`](../packages/core/agent-loop), [`goal`](../packages/goal/goal), [`goal-session`](../packages/goal/goal-session), [`home`](../packages/util/home), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`llm-retry`](../packages/llm/llm-retry), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`skill`](../packages/skill/skill), [`skill-local`](../packages/skill/skill-local), [`system-prompt`](../packages/core/system-prompt), [`tasks`](../packages/tasks/tasks), [`tool-bash`](../packages/bash/tool-bash), [`tool-goal`](../packages/goal/tool-goal), [`tool-skill`](../packages/skill/tool-skill), [`tool-tasks`](../packages/tasks/tool-tasks), [`tools`](../packages/core/tools), [`workspace-context`](../packages/context/workspace-context) |
|
||||
| [`tui`](../packages/ui/tui) | `ui` | [`agent`](../packages/core/agent), [`agent-loop`](../packages/core/agent-loop), [`commands`](../packages/ui/commands), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`llm-retry`](../packages/llm/llm-retry), [`session`](../packages/core/session), [`session-persistence`](../packages/session-persistence/session-persistence), [`session-title`](../packages/session-title/session-title), [`skill`](../packages/skill/skill), [`system-prompt`](../packages/core/system-prompt), [`token-meter`](../packages/llm/token-meter), [`tools`](../packages/core/tools), [`user-interaction`](../packages/ui/user-interaction) |
|
||||
| [`agent-spine-demo`](../packages/examples/agent-spine-demo) | `examples` | [`agent`](../packages/core/agent), [`agent-loop`](../packages/core/agent-loop), [`goal`](../packages/goal/goal), [`goal-session`](../packages/goal/goal-session), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`llm-retry`](../packages/llm/llm-retry), [`paths`](../packages/util/paths), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`session-title`](../packages/session-title/session-title), [`skill`](../packages/skill/skill), [`skill-local`](../packages/skill/skill-local), [`system-prompt`](../packages/core/system-prompt), [`tasks`](../packages/tasks/tasks), [`tool-bash`](../packages/bash/tool-bash), [`tool-goal`](../packages/goal/tool-goal), [`tool-skill`](../packages/skill/tool-skill), [`tool-tasks`](../packages/tasks/tool-tasks), [`tools`](../packages/core/tools), [`workspace-context`](../packages/context/workspace-context) |
|
||||
| [`tool-ralph`](../packages/workflow/tool-ralph) | `workflow` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`subagent`](../packages/subagent/subagent), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools), [`workflow`](../packages/workflow/workflow) |
|
||||
| [`workflow-workerthread`](../packages/workflow/workflow-workerthread) | `workflow` | [`agent`](../packages/core/agent), [`brand`](../packages/util/brand), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent), [`tools`](../packages/core/tools), [`workflow`](../packages/workflow/workflow) |
|
||||
| [`subagent-fork`](../packages/subagent/subagent-fork) | `subagent` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent), [`subagent-inprocess`](../packages/subagent/subagent-inprocess) |
|
||||
|
||||
@@ -79,7 +79,7 @@ export type SessionEvent<T extends SessionEventType = SessionEventType> = {
|
||||
}[T]
|
||||
```
|
||||
|
||||
Sources: [`packages/core/session/src/types.ts:267`](../packages/core/session/src/types.ts) · [`packages/core/session/src/types.ts:274`](../packages/core/session/src/types.ts) · [`packages/core/session/src/types.ts:304`](../packages/core/session/src/types.ts) · [`packages/core/session/src/types.ts:336`](../packages/core/session/src/types.ts)
|
||||
Sources: [`packages/core/session/src/types.ts:276`](../packages/core/session/src/types.ts) · [`packages/core/session/src/types.ts:289`](../packages/core/session/src/types.ts) · [`packages/core/session/src/types.ts:319`](../packages/core/session/src/types.ts) · [`packages/core/session/src/types.ts:351`](../packages/core/session/src/types.ts)
|
||||
|
||||
## Events
|
||||
|
||||
@@ -106,7 +106,7 @@ Sources: [`packages/core/session/src/types.ts:267`](../packages/core/session/src
|
||||
|
||||
Types: [CallId](core-data-structures/core.md)
|
||||
|
||||
Source: [`packages/ui/user-approval/src/index.ts:45`](../packages/ui/user-approval/src/index.ts)
|
||||
Source: [`packages/ui/user-approval/src/index.ts:44`](../packages/ui/user-approval/src/index.ts)
|
||||
|
||||
#### `approval/decided` — log-only
|
||||
|
||||
@@ -122,7 +122,7 @@ Source: [`packages/ui/user-approval/src/index.ts:45`](../packages/ui/user-approv
|
||||
}
|
||||
```
|
||||
|
||||
Source: [`packages/ui/user-approval/src/index.ts:56`](../packages/ui/user-approval/src/index.ts)
|
||||
Source: [`packages/ui/user-approval/src/index.ts:55`](../packages/ui/user-approval/src/index.ts)
|
||||
|
||||
#### `approval/policy` — log-only
|
||||
|
||||
@@ -138,7 +138,7 @@ Source: [`packages/ui/user-approval/src/index.ts:56`](../packages/ui/user-approv
|
||||
'approval/policy': { policy: ApprovalPolicy }
|
||||
```
|
||||
|
||||
Source: [`packages/ui/user-approval/src/index.ts:68`](../packages/ui/user-approval/src/index.ts)
|
||||
Source: [`packages/ui/user-approval/src/index.ts:67`](../packages/ui/user-approval/src/index.ts)
|
||||
|
||||
### `assistant/*`
|
||||
|
||||
@@ -151,7 +151,7 @@ Source: [`packages/ui/user-approval/src/index.ts:68`](../packages/ui/user-approv
|
||||
|
||||
Types: [StreamChunk](core-data-structures/llm-streaming.md)
|
||||
|
||||
Source: [`packages/core/session/src/types.ts:231`](../packages/core/session/src/types.ts)
|
||||
Source: [`packages/core/session/src/types.ts:232`](../packages/core/session/src/types.ts)
|
||||
|
||||
#### `assistant/message` — surface
|
||||
|
||||
@@ -167,7 +167,7 @@ Source: [`packages/core/session/src/types.ts:231`](../packages/core/session/src/
|
||||
|
||||
Types: [ContentBlock](core-data-structures/core.md) · [TokenUsage](core-data-structures/llm-streaming.md)
|
||||
|
||||
Source: [`packages/core/session/src/types.ts:238`](../packages/core/session/src/types.ts)
|
||||
Source: [`packages/core/session/src/types.ts:239`](../packages/core/session/src/types.ts)
|
||||
|
||||
### `compact/*`
|
||||
|
||||
@@ -246,7 +246,7 @@ Source: [`packages/compact/compact/src/types.ts:22`](../packages/compact/compact
|
||||
|
||||
Types: [ContentBlock](core-data-structures/core.md) · [MessageSource](core-data-structures/core.md)
|
||||
|
||||
Source: [`packages/core/session/src/types.ts:225`](../packages/core/session/src/types.ts)
|
||||
Source: [`packages/core/session/src/types.ts:226`](../packages/core/session/src/types.ts)
|
||||
|
||||
### `hook/*`
|
||||
|
||||
@@ -328,6 +328,21 @@ Source: [`packages/llm/llm-retry/src/index.ts:18`](../packages/llm/llm-retry/src
|
||||
|
||||
Source: [`packages/ui/permission/src/index.ts:36`](../packages/ui/permission/src/index.ts)
|
||||
|
||||
### `plan/*`
|
||||
|
||||
#### `plan/mode` — log-only
|
||||
|
||||
```ts persistence-catalog
|
||||
/**
|
||||
* Whether plan mode is in force from this point on: log-only, non-surface,
|
||||
* whole-value replace. The last `plan/mode` wins; a log with none folds to
|
||||
* inactive through {@link foldPlanMode}.
|
||||
*/
|
||||
'plan/mode': { active: boolean }
|
||||
```
|
||||
|
||||
Source: [`packages/plan/plan-mode/src/index.ts:40`](../packages/plan/plan-mode/src/index.ts)
|
||||
|
||||
### `prompt/*`
|
||||
|
||||
#### `prompt/blocked` — log-only
|
||||
@@ -342,7 +357,7 @@ Source: [`packages/ui/permission/src/index.ts:36`](../packages/ui/permission/src
|
||||
|
||||
Types: [ContentBlock](core-data-structures/core.md) · [MessageSource](core-data-structures/core.md)
|
||||
|
||||
Source: [`packages/core/session/src/types.ts:213`](../packages/core/session/src/types.ts)
|
||||
Source: [`packages/core/session/src/types.ts:214`](../packages/core/session/src/types.ts)
|
||||
|
||||
### `request/*`
|
||||
|
||||
@@ -356,7 +371,7 @@ Source: [`packages/core/session/src/types.ts:213`](../packages/core/session/src/
|
||||
'request/header': { header: EpochHeader; reason: RequestHeaderReason }
|
||||
```
|
||||
|
||||
Source: [`packages/core/session/src/types.ts:263`](../packages/core/session/src/types.ts)
|
||||
Source: [`packages/core/session/src/types.ts:264`](../packages/core/session/src/types.ts)
|
||||
|
||||
### `sandbox/*`
|
||||
|
||||
@@ -376,6 +391,33 @@ Source: [`packages/core/session/src/types.ts:263`](../packages/core/session/src/
|
||||
|
||||
Source: [`packages/sandbox/sandbox-policy/src/session-mode.ts:34`](../packages/sandbox/sandbox-policy/src/session-mode.ts)
|
||||
|
||||
### `session/*`
|
||||
|
||||
#### `session/title` — log-only
|
||||
|
||||
```ts persistence-catalog
|
||||
/**
|
||||
* Latest-wins session title snapshot. Log-only: it never enters the model
|
||||
* surface or derived history.
|
||||
*/
|
||||
'session/title': SessionTitleEventData
|
||||
```
|
||||
|
||||
Types: [SessionTitleEventData](core-data-structures/session-title.md)
|
||||
|
||||
Source: [`packages/session-title/session-title/src/index.ts:95`](../packages/session-title/session-title/src/index.ts)
|
||||
|
||||
#### `session/title-llm-request` — log-only
|
||||
|
||||
```ts persistence-catalog
|
||||
/** Log-only pre-dispatch record of one session-title model request. */
|
||||
'session/title-llm-request': SessionTitleLlmRequestEventData
|
||||
```
|
||||
|
||||
Types: [SessionTitleLlmRequestEventData](core-data-structures/session-title.md)
|
||||
|
||||
Source: [`packages/session-title/session-title-llm/src/index.ts:44`](../packages/session-title/session-title-llm/src/index.ts)
|
||||
|
||||
### `steering/*`
|
||||
|
||||
#### `steering/message` — surface
|
||||
@@ -387,7 +429,7 @@ Source: [`packages/sandbox/sandbox-policy/src/session-mode.ts:34`](../packages/s
|
||||
|
||||
Types: [ContentBlock](core-data-structures/core.md) · [MessageSource](core-data-structures/core.md)
|
||||
|
||||
Source: [`packages/core/session/src/types.ts:256`](../packages/core/session/src/types.ts)
|
||||
Source: [`packages/core/session/src/types.ts:257`](../packages/core/session/src/types.ts)
|
||||
|
||||
### `step/*`
|
||||
|
||||
@@ -398,7 +440,7 @@ Source: [`packages/core/session/src/types.ts:256`](../packages/core/session/src/
|
||||
'step/end': { turn: number; step: number }
|
||||
```
|
||||
|
||||
Source: [`packages/core/session/src/types.ts:206`](../packages/core/session/src/types.ts)
|
||||
Source: [`packages/core/session/src/types.ts:207`](../packages/core/session/src/types.ts)
|
||||
|
||||
#### `step/start` — log-only
|
||||
|
||||
@@ -407,7 +449,7 @@ Source: [`packages/core/session/src/types.ts:206`](../packages/core/session/src/
|
||||
'step/start': { turn: number; step: number }
|
||||
```
|
||||
|
||||
Source: [`packages/core/session/src/types.ts:204`](../packages/core/session/src/types.ts)
|
||||
Source: [`packages/core/session/src/types.ts:205`](../packages/core/session/src/types.ts)
|
||||
|
||||
### `todo/*`
|
||||
|
||||
@@ -420,7 +462,7 @@ Source: [`packages/core/session/src/types.ts:204`](../packages/core/session/src/
|
||||
|
||||
Types: [TodoItem](core-data-structures/session.md)
|
||||
|
||||
Source: [`packages/core/session/src/types.ts:258`](../packages/core/session/src/types.ts)
|
||||
Source: [`packages/core/session/src/types.ts:259`](../packages/core/session/src/types.ts)
|
||||
|
||||
### `tool/*`
|
||||
|
||||
@@ -437,7 +479,7 @@ Source: [`packages/core/session/src/types.ts:258`](../packages/core/session/src/
|
||||
|
||||
Types: [CallId](core-data-structures/core.md)
|
||||
|
||||
Source: [`packages/core/session/src/types.ts:244`](../packages/core/session/src/types.ts)
|
||||
Source: [`packages/core/session/src/types.ts:245`](../packages/core/session/src/types.ts)
|
||||
|
||||
#### `tool/code-dispatch` — log-only
|
||||
|
||||
@@ -481,7 +523,7 @@ Source: [`packages/core/tools/src/code-mode.ts:34`](../packages/core/tools/src/c
|
||||
|
||||
Types: [CallId](core-data-structures/core.md) · [ContentBlock](core-data-structures/core.md)
|
||||
|
||||
Source: [`packages/core/session/src/types.ts:254`](../packages/core/session/src/types.ts)
|
||||
Source: [`packages/core/session/src/types.ts:255`](../packages/core/session/src/types.ts)
|
||||
|
||||
### `turn/*`
|
||||
|
||||
@@ -499,7 +541,7 @@ Source: [`packages/core/session/src/types.ts:254`](../packages/core/session/src/
|
||||
|
||||
Types: [TurnEndReason](core-data-structures/session.md)
|
||||
|
||||
Source: [`packages/core/session/src/types.ts:202`](../packages/core/session/src/types.ts)
|
||||
Source: [`packages/core/session/src/types.ts:203`](../packages/core/session/src/types.ts)
|
||||
|
||||
#### `turn/start` — log-only
|
||||
|
||||
@@ -515,7 +557,7 @@ Source: [`packages/core/session/src/types.ts:202`](../packages/core/session/src/
|
||||
|
||||
Types: [TurnTrigger](core-data-structures/session.md)
|
||||
|
||||
Source: [`packages/core/session/src/types.ts:195`](../packages/core/session/src/types.ts)
|
||||
Source: [`packages/core/session/src/types.ts:196`](../packages/core/session/src/types.ts)
|
||||
|
||||
### `user/*`
|
||||
|
||||
@@ -528,4 +570,4 @@ Source: [`packages/core/session/src/types.ts:195`](../packages/core/session/src/
|
||||
|
||||
Types: [ContentBlock](core-data-structures/core.md) · [MessageSource](core-data-structures/core.md)
|
||||
|
||||
Source: [`packages/core/session/src/types.ts:208`](../packages/core/session/src/types.ts)
|
||||
Source: [`packages/core/session/src/types.ts:209`](../packages/core/session/src/types.ts)
|
||||
|
||||
@@ -17,6 +17,7 @@ This table connects model-visible tool names to the plugin package and service s
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| `@deepseek-ai/dsh-tool-ask-user` | `ask_user_question` | `ctx.tools`, `ctx.userInteraction` | `tool/call`, `tool/result after a UI/provider answers the question` | - | ask_user_question pauses the tool call until the active UI provider returns a human answer. |
|
||||
| `@deepseek-ai/dsh-tools` | `run_code` | `ctx.tools`, `ctx.codeRuntime (execution time)`, `ctx.systemPrompt` | `tool/call`, `one tool/code-dispatch per bridged sub-call`, `tool/result` | - | Owned by the tool registry as a reserved transport outside filterable capability layers under `mode: code` / `mode: both` (see the Code Mode Agent Note). Under `code` it is the registry's only wire contribution; the other visible capabilities are declared in a generated TypeScript SDK section, and a program calls them through serialized bindings that re-enter the complete guarded tool pipeline and link each nested execution to this outer result. |
|
||||
| `@deepseek-ai/dsh-plan-mode` | `exit_plan_mode` | `ctx.tools`, `ctx.systemPrompt`, `ctx.userInteraction (execution time, opportunistic)` | `tool/call`, `plan/mode inactive on an approved review`, `tool/result` | - | exit_plan_mode stays in the model-facing schema while planning is inactive so transitions add no tool-catalog churn on top of the plan-policy change. Its execute path rejects calls outside plan mode; in plan mode it presents the plan over the user-interaction seam (approve / keep planning with feedback), and approval logs plan mode inactive at the step boundary. |
|
||||
| `@deepseek-ai/dsh-tool-bash` | `bash` | `ctx.tools`, `ctx.bash`, `ctx.tasks at call time for run_in_background` | `tool/call`, `tool/result` | - | The bash tool is the model-facing consumer of the bash executor seam. A `run_in_background` run registers with the generic `ctx.tasks` runtime and is collected/stopped through the `task_*` tools from `@deepseek-ai/dsh-tool-tasks`; the `enableRunInBackground` config (default true) removes the parameter entirely when disabled. |
|
||||
| `@deepseek-ai/dsh-tool-cordis` | `cordis_inspect`, `cordis_mount`, `cordis_unmount` | `ctx.tools` | `tool/call`, `tool/result`, `live plugin-tree mutations (mount/unmount)` | - | Ships in examples/cordis-agent only (a deliberate opt-in — mounted code gets the real ctx, see .agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md). Plugins the model mounts may register ADDITIONAL model-visible tools at runtime; a full changed request header logs those tool-set changes. |
|
||||
| `@deepseek-ai/dsh-tool-fs` | `edit`, `read`, `write` | `ctx.tools`, `ctx.fs`, `ctx.systemPrompt` | `tool/call`, `fs/write-intent or fs/edit-intent for mutations`, `fs/observed after successful file operations`, `tool/result` | - | The read-before-write/edit policy is added by `@deepseek-ai/dsh-fs-policy` (an `fs/*` event-gate plugin, no schema change); a deployment that loads these tools is expected to also load it. The tool schemas above are identical with or without the policy plugin. |
|
||||
@@ -126,6 +127,31 @@ Source: [`packages/core/tools/src/code-mode.ts`](../packages/core/tools/src/code
|
||||
|
||||
Owned by the tool registry as a reserved transport outside filterable capability layers under `mode: code` / `mode: both` (see the Code Mode Agent Note). Under `code` it is the registry's only wire contribution; the other visible capabilities are declared in a generated TypeScript SDK section, and a program calls them through serialized bindings that re-enter the complete guarded tool pipeline and link each nested execution to this outer result.
|
||||
|
||||
## `@deepseek-ai/dsh-plan-mode`
|
||||
|
||||
### `exit_plan_mode`
|
||||
|
||||
Use only in plan mode. Present your plan for the user's review and, on approval, leave plan mode. Send the COMPLETE plan as markdown, starting with a # heading that names it. The user may approve (carry out the plan from your next step) or keep planning — their feedback comes back in the tool result; revise and present again.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"plan": {
|
||||
"type": "string",
|
||||
"description": "The complete plan, as markdown, starting with a # heading that names it."
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"plan"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Source: [`packages/plan/plan-mode/src/index.ts`](../packages/plan/plan-mode/src/index.ts)
|
||||
|
||||
exit_plan_mode stays in the model-facing schema while planning is inactive so transitions add no tool-catalog churn on top of the plan-policy change. Its execute path rejects calls outside plan mode; in plan mode it presents the plan over the user-interaction seam (approve / keep planning with feedback), and approval logs plan mode inactive at the step boundary.
|
||||
|
||||
## `@deepseek-ai/dsh-tool-bash`
|
||||
|
||||
### `bash`
|
||||
|
||||
107
docs/web-styling.md
Normal file
107
docs/web-styling.md
Normal file
@@ -0,0 +1,107 @@
|
||||
# Web GUI 样式规范
|
||||
|
||||
> **【token 体系已换代——§1 表格仅历史参考】** 本文的 `--bg-*`/`--text-*`/`--accent` token 族与其宿主包 `packages/client/web-ui` 已随插件化重构退役。现行 token 唯一来源=`packages/client/ui-theme/src/styles/` 的 `--dsw-*` 体系(static 色阶+alias 语义层,暗色=`body[data-ds-dark-theme]` 覆写);组件对账基准=`missions/tasks/20260721-1520-web-plugin-rfc/style-spec.md`。**仍然有效**:工程约束(CSS Modules + clsx、无组件库、无 tailwind、组件禁 hardcode 色值)、字号成对写行高、间距 4 倍数、代码字体栈末位不放 monospace——这些已收编进 architecture.md §15。
|
||||
|
||||
> 状态:原「活文档」(随 `packages/client/web-ui` 演进)。视觉基线源自对 deepseekchat 前端仓的实测调研。框架决策与工程约束由 [web-styling-system RFC](../.agents/notes/implemented/process/2026-07-19-web-styling-system.md) 拍板,本文不重复论证。
|
||||
|
||||
## 1. 设计 token 表(权威定义)
|
||||
|
||||
所有 token 住 `packages/client/web-ui/src/style/global.css`:`:root` 亮色实值,`[data-theme='dark']` 块覆盖同名变量(未补全前列为占位)。组件 CSS 只引 token,不出现字面量色值。
|
||||
|
||||
### 1.1 颜色(两层:注释里是 base 色板出处,变量名即语义别名)
|
||||
|
||||
| token | 亮色实值 | 暗色(占位) | 用途 |
|
||||
| --- | --- | --- | --- |
|
||||
| `--bg-base` | `#ffffff` | `#151517` | 页面底 |
|
||||
| `--bg-layer` | `#ffffff` | `#232324` | 浮层/面板 |
|
||||
| `--bg-sidebar` | `#f9fafb` | `#1b1b1c` | 侧边栏底 |
|
||||
| `--text-primary` | `#0f1115` | `#f9fafb` | 正文 |
|
||||
| `--text-secondary` | `#61666b` | `#cfd3d6` | 次要文字 |
|
||||
| `--text-tertiary` | `#81858c` | `#adb2b8` | 辅助/说明 |
|
||||
| `--border-l1` | `rgba(0,0,0,.04)` | `rgba(255,255,255,.06)` | 弱分隔(侧边栏右缘) |
|
||||
| `--border-l2` | `rgba(0,0,0,.1)` | `rgba(255,255,255,.12)` | 常规边框 |
|
||||
| `--hover-bg` | `rgba(38,49,72,.06)` | `rgba(255,255,255,.08)` | hover 态底 |
|
||||
| `--active-bg` | `rgba(38,49,72,.1)` | `rgba(255,255,255,.14)` | 按压/激活态底 |
|
||||
| `--accent` | `#3964fe` | `#5686fe` | 品牌蓝(deepseek-500;暗提亮一档) |
|
||||
| `--accent-soft` | `#edf3fe` | `#28313f` | 淡品牌底(强调块) |
|
||||
| `--accent-item` | `#e4edfd` | `#35363a` | 侧边栏选中条目底 |
|
||||
| `--bubble-bg` | `#edf3fe` | `#2c2c2e` | 用户消息气泡底 |
|
||||
| `--ok` / `--error` / `--warn` | `#22c55e` / `#ec1313` / `#f59e0b` | 同值 | 语义状态色 |
|
||||
| `--text-on-solid` | `#ffffff` | 同值 | 实色底(accent/error 徽标等)上的文字 |
|
||||
| `--ok-soft` / `--error-soft` | `#e6faed` / `#fee2e2` | `#233c2c` / `#570c0c` | 语义状态软底(徽章);green-100/red-100,暗为 900 档 |
|
||||
| `--color-frame-mux` / `--color-frame-host` | `#8250df` / `#0969da` | 同值 | RPC 调试面板方向色(自有,非基线) |
|
||||
| `--frame-mux-soft` / `--frame-host-soft` | `rgba(130,80,223,.1)` / `rgba(9,105,218,.1)` | 同色 `.24` | 方向色软底(徽章) |
|
||||
| `--scroll-color` / `--scroll-color-hover` | `rgba(0,0,0,.08)` / `.15` | `rgba(255,255,255,.15)` / `.24` | 滚动条(`.scrollable` 专用) |
|
||||
|
||||
### 1.2 非颜色
|
||||
|
||||
| token | 值 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `--font-ui` | `Inter, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif` | 正文栈 |
|
||||
| `--font-mono` | `Menlo, Monaco, Consolas, 'JetBrains Mono', 'Courier New', sans-serif` | 代码栈;**末位不放 monospace**(防 Windows 中文回退宋体) |
|
||||
| `--fw-strong` | `600` | 粗体统一权重 |
|
||||
| `--ease` | `cubic-bezier(.4,0,.2,1)` | 唯一缓动曲线 |
|
||||
| `--dur` / `--dur-fast` / `--dur-slow` | `.2s` / `.1s` / `.3s` | 过渡三档 |
|
||||
| `--radius-s` / `--radius-m` / `--radius-l` / `--radius-bubble` / `--radius-xl` | `8px` / `12px` / `16px` / `22px` / `24px` | 圆角语义档:小控件 / 列表条目与面板内块 / 浮层 / 气泡 / 输入卡片(基线 inputWrapper 同值);胶囊直接写 `999px` |
|
||||
| `--shadow-panel` | `0 0 1px rgba(0,0,0,.2), 0 0 4px rgba(0,0,0,.02), 0 12px 32px rgba(0,0,0,.08)` | 浮层阴影(基线 lv3) |
|
||||
| `--shadow-float` | `0 0 1px rgba(0,0,0,.24), 0 4px 12px rgba(0,0,0,.06), 0 16px 48px rgba(0,0,0,.16)` | 强浮动面板(lv3 加强档,如 RPC 调试浮层) |
|
||||
| `--shadow-card` | `0 4px 10px rgba(0,0,0,.02), 0 2px 4px rgba(0,0,0,.04)`;暗色 `none` | 输入卡片微阴影(基线:亮色同底靠边框+微影区分,暗色靠提亮底、阴影关闭) |
|
||||
|
||||
字号与间距**不 token 化**(基线仓同款决策):字号在组件里写 px 且**成对写行高**,常用对 16/24(气泡)、14/22(UI 默认)、12/18(辅助);间距用 4 的倍数。
|
||||
|
||||
## 2. 视觉基线(源自 deepseekchat)
|
||||
|
||||
- 侧边栏:宽 `260px + 1px` 右边框(`--border-l1`);底色 `--bg-sidebar`。
|
||||
- 侧边栏条目:高 `40px`、圆角 `--radius-m`、字号 14px;hover 底 `--hover-bg` 或 sidebar 专属灰、**选中底 `--accent-item` 且不改文字色**。
|
||||
- 侧边栏分组标题:12px / weight 500 / `--text-tertiary` / sticky 顶部(底色同侧边栏遮滚动内容)。
|
||||
- 会话列:`max-width: 840px` 居中,<1024px 降 712px。
|
||||
- 消息流:**仅用户侧有气泡**——`--bubble-bg` 底、圆角 `--radius-bubble`、padding `10px 16px`、字号 16px/24px、`max-width: calc(100% - 88px)`;**助手侧纯文档流无底色**。
|
||||
- 消息操作条:默认 `opacity: 0`,父块 hover/focus-within 淡入(`--dur` + `--ease`)。
|
||||
- 输入卡片:与会话列同宽(840px,<1024px 降 712px)居中悬浮(距底留白带);圆角 `--radius-xl`、边框 `--border-l2`、底 `--bg-base`、阴影 `--shadow-card`;内部上下两段=textarea(16px/24px,min 2 行 max 14 行=336px,镜像 div 自增高)+ 操作行(右下嵌 34px 主圆钮);focus 无边框/阴影变化(基线同款)。
|
||||
- 输入主按钮(拍板 2026-07-20 三连,视觉参照 Codex App):32px 实心正圆图标钮(内联 SVG)——空闲=`--accent` 底白↑箭头「发送」,运行中原地变 `--accent-soft` 底 accent ■「停止」(同色系不告警、不用红)。**运行中锁输入**(拍板 3,取代早先 hover 菜单方案):textarea disabled(灰、草稿内容保留可见)、无任何排队/插话菜单,停止是唯一动作;turn 结束解禁并 refocus。键盘 Enter=发送、Ctrl/Meta+Enter=换行(运行中键盘路径随锁失效)。
|
||||
- 滚动条:近隐形、hover 加深、`scrollbar-gutter: stable` 不占布局(统一走 `.scrollable`,见 §3-9)。
|
||||
- RPC 四象限方向符(官方视觉词汇,空间隐喻:上=去 server、下=来自 server;单线=unary、双线=SSE):
|
||||
|
||||
| 符号 | 象限 | 徽章配色 |
|
||||
| --- | --- | --- |
|
||||
| `↑` | client-request(unary 出站) | `--accent` / `--accent-soft` |
|
||||
| `↓` | server-response(unary 回包) | ok `--ok`/`--ok-soft`,error `--error`/`--error-soft` |
|
||||
| `⇟` | server-request(SSE 帧推送) | mux `--color-frame-mux`/`--frame-mux-soft`,host `--color-frame-host`/`--frame-host-soft` |
|
||||
| `⇞` | client-response(SSE 侧回应) | `--accent`/`--accent-soft` 降透明度 |
|
||||
|
||||
## 3. 样式编码规范(review 对照打勾)
|
||||
|
||||
1. 颜色/圆角/动效/字体栈只引 §1 token;组件 CSS 出现字面量色值即打回(渐变遮罩等特效除外,须注释说明)。
|
||||
2. 组件 CSS 禁止出现 `[data-theme]` 选择器;暗色差异只在 global.css token 表做。确需按主题换非 token 值(渐变端点等),组件定义局部 CSS 变量、主题块只覆写变量(变量桥)。
|
||||
3. 类名 camelCase;状态类用单形容词(`.active` `.show`),由 clsx 挂载:`clsx(styles.x, cond && styles.active, className)`。
|
||||
4. 对外组件必须透传 `className` 并合入根元素。
|
||||
5. 禁用 `composes`;复用靠 token 与组件抽取。
|
||||
6. `:global` 仅用于穿透第三方/跨包类名;禁止用它定义新全局类。
|
||||
7. 交互过渡一律 `var(--dur*) var(--ease)`,只过渡 opacity / transform / 背景色 / 阴影;纯 hover 展示型元素包 `@media (hover: hover)`。
|
||||
8. hover/active 底色优先用透明度制 token(叠任意海拔底色都成立),不新造实色灰。
|
||||
9. 滚动容器统一挂 global.css 的 `.scrollable` 工具类;组件内禁写 `::-webkit-scrollbar`。
|
||||
10. 媒体查询写在组件 css 尾部、贴着被覆盖规则;断点当前仅 1024px 一档(会话列降档),加第二档需先记入本文档。
|
||||
11. 动态样式 JS 侧只写 CSS 变量(`style={{'--x': v}}`),规则留在 CSS;禁止在 TSX 里拼接样式对象做主题/状态分支。
|
||||
12. 文字灰阶只用 `--text-primary/secondary/tertiary` 三级,不新造灰色。
|
||||
|
||||
## 4. 文件组织
|
||||
|
||||
- `src/style/global.css` 固定分区顺序:① token 表(`:root` + `[data-theme='dark']`)② 全局基础(box-sizing、body、button reset)③ 全局工具类(`.scrollable` 等,总数保持个位数)。
|
||||
- `*.module.css` 与组件同目录同名;一个组件一个 module 文件。
|
||||
- 类型声明用现有 `css-modules.d.ts` 通配;组件数超 20 再评估引入 tcm 生成精确 `.css.d.ts`。
|
||||
- PostCSS 特性白名单:当前**零插件**(平铺 CSS + 原生嵌套按需);引入 nested/custom-media 需先记入本文档。
|
||||
|
||||
## 5. 演进规则与偏离记录
|
||||
|
||||
- **加新 token**:先进 §1 表(含暗色占位列)再在组件使用;review 见到未入表的 `--` 新变量即打回(组件局部变量桥除外)。
|
||||
- **偏离基线**:与 §2 任一常数不一致的实现,须在下方偏离表记一行(日期/项/理由)。
|
||||
- **暗色表补全验收**:`[data-theme='dark']` 覆盖 §1 全部占位列后,用 RPC 面板 + 侧边栏 + 会话流三个界面人工/截图核对一遍,无组件级主题选择器即达标。
|
||||
|
||||
| 日期 | 偏离项 | 理由 |
|
||||
| --- | --- | --- |
|
||||
| (空) | | |
|
||||
|
||||
## 6. 相关文档
|
||||
|
||||
- [web-styling-system RFC](../.agents/notes/implemented/process/2026-07-19-web-styling-system.md)(框架五条与工程约束的裁决记录)
|
||||
- 客户端消费架构与分层协议:[Web 客户端架构 RFC](../.agents/notes/implemented/architecture/2026-07-19-gui-web-client-architecture.md)、[GUI 分层与 RPC 协议 RFC](../.agents/notes/implemented/architecture/2026-07-19-gui-layering-and-rpc-protocol.md)
|
||||
Reference in New Issue
Block a user