Merge remote-tracking branch 'origin/master' into feat/web-session-log-export

This commit is contained in:
_Kerman
2026-08-11 13:46:46 +08:00
142 changed files with 3934 additions and 262 deletions

View File

@@ -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 docs/architecture.md
architecture.md: 8d1c5a1be391e2455aefc69db89d96027aaf3efa
architecture.zh.md: 53bf9f54a5503ae40aa62a348822f9d92162dda2
architecture.md: aeda7f9674e75a1e97549f25c13d571b3b37ee8c
architecture.zh.md: a25f20ba9babefeaab4636027e97d6f2d4ae8caf

View File

@@ -42,6 +42,7 @@ Harnesses are [Cordis](cordis-primer.md) contexts; packages contribute services,
| `ctx.tasks` | [`tasks/`](../packages/tasks/README.md) | background task registry, generic `task_*` controls |
| `ctx.workflows` | [`workflow/`](../packages/workflow/README.md) | script-driven multi-agent orchestration |
| `ctx.goals` | [`goal/`](../packages/goal/README.md) | persisted same-session goals |
| `ctx.messageFeedback` | [`feedback/`](../packages/feedback/README.md) | lifecycle-bound editable feedback for individual assistant messages and its Host Remote contract |
| `ctx.sessionPersistence` | [`session/`](../packages/session/README.md) | durable session-log storage |
| `ctx.sessionQuery` | [`session-query/`](../packages/session-query/README.md) | live-preferred exact/filter/trace queries over SQLite FTS, workspace-authorized model tools |
| `ctx.sessionTitle` | [`session/session-title`](../packages/session/README.md) | log-backed fallbacks, one optional asynchronous provider |

View File

@@ -42,6 +42,7 @@
| `ctx.tasks` | [`tasks/`](../packages/tasks/README.md) | 后台任务注册表和通用 `task_*` 控制 |
| `ctx.workflows` | [`workflow/`](../packages/workflow/README.md) | 脚本驱动的多 agent 编排 |
| `ctx.goals` | [`goal/`](../packages/goal/README.md) | 持久化的同会话目标 |
| `ctx.messageFeedback` | [`feedback/`](../packages/feedback/README.md) | 绑定生命周期的单条 assistant 消息可编辑反馈及其 Host Remote 契约 |
| `ctx.sessionPersistence` | [`session/`](../packages/session/README.md) | 会话日志的持久化存储 |
| `ctx.sessionQuery` | [`session-query/`](../packages/session-query/README.md) | 基于 SQLite 全文搜索的实时优先精确检索/过滤/追踪、经工作区授权的模型工具 |
| `ctx.sessionTitle` | [`session/session-title`](../packages/session/README.md) | 基于日志的回退标题和单个可选异步提供方 |

View File

@@ -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 docs/capability-seams.md
capability-seams.md: c102167aa76b9ba613b1b434cb0aa58765d26106
capability-seams.zh.md: 7c4eab8d5a2d890bdf4513bb9acdc81f55414642
capability-seams.md: 64d20b1bfb609aec3acb3673e4589516bb315bfa
capability-seams.zh.md: 10b5116d12991319df55c551d51840bb566ac898

View File

@@ -30,6 +30,7 @@ flowchart LR
pkg_session_query_sqlite["session-query-sqlite"]
pkg_subagent_inprocess["subagent-inprocess"]
pkg_invariants["invariants"]
pkg_message_feedback["message-feedback"]
svc_invariants["ctx.invariants<br/>Package-owned invariant registry"]
pkg_scope["scope"]
pkg_typert_registry["typert-registry"]
@@ -60,6 +61,7 @@ flowchart LR
pkg_storage_domain["storage-domain"]
svc_storageDomain["ctx.storageDomain<br/>Domain data facility"]
pkg_workspace["workspace"]
svc_messageFeedback["ctx.messageFeedback<br/>Lifecycle-bound message feedback"]
svc_workspace["ctx.workspace<br/>Workspace entity registry"]
svc_sessionQuery["ctx.sessionQuery<br/>Session reads, traces, filters, and search"]
pkg_session_reference["session-reference"]
@@ -218,6 +220,7 @@ flowchart LR
pkg_llm_deepseek --> svc_llm
pkg_llm_pi_ai --> svc_llm
pkg_llm_replay --> svc_llm
pkg_message_feedback --> svc_messageFeedback
pkg_modules --> svc_clientModuleHost
pkg_permission --> svc_permission
pkg_plan_mode --> svc_planMode
@@ -322,6 +325,7 @@ flowchart LR
svc_sessionPersistence --> pkg_agent_loop
svc_sessionPersistence --> pkg_hooks_claude
svc_sessionPersistence --> pkg_hooks_codex
svc_sessionPersistence --> pkg_message_feedback
svc_sessionPersistence --> pkg_session_query
svc_sessionPersistence --> pkg_session_query_sqlite
svc_sessionPersistence --> pkg_tool_bash
@@ -334,6 +338,7 @@ flowchart LR
svc_sessions --> pkg_agent
svc_sessions --> pkg_agent_loop
svc_sessions --> pkg_invariants
svc_sessions --> pkg_message_feedback
svc_sessions --> pkg_session_persistence
svc_sessions --> pkg_session_query
svc_sessions --> pkg_session_query_sqlite
@@ -344,6 +349,7 @@ flowchart LR
svc_skills --> pkg_tool_skill
svc_spillStore --> pkg_spill_policy
svc_storage --> pkg_storage_domain
svc_storageDomain --> pkg_message_feedback
svc_storageDomain --> pkg_workspace
svc_subagents --> pkg_tool_ralph
svc_subagents --> pkg_tool_subagent
@@ -392,16 +398,17 @@ flowchart LR
| `ctx.llm` | `seam` | [`llm`](../packages/llm/llm) | [`llm-deepseek`](../packages/llm/llm-deepseek), [`llm-pi-ai`](../packages/llm/llm-pi-ai), [`llm-replay`](../packages/support/llm-replay) | [`agent-loop`](../packages/core/agent-loop), [`compact-basic`](../packages/compact/compact-basic) | - | Adapters register provider implementations; the loop and compaction call the provider-neutral stream service. |
| `ctx.tokenMeter` | `core` | [`token-meter`](../packages/llm/token-meter) | - | [`compact-basic`](../packages/compact/compact-basic) | - | Owns isolated per-session replay folds; pressure consumers share immutable revisioned measurements. |
| `ctx.toolResultPrune` | `core` | [`compact-tool-result-prune`](../packages/compact/compact-tool-result-prune) | - | [`compact-basic`](../packages/compact/compact-basic) | - | Rewrites oversized current tool results through replayable single-node surface replacements before summary compaction. |
| `ctx.sessions` | `core` | [`session`](../packages/core/session) | - | [`agent-loop`](../packages/core/agent-loop), [`agent`](../packages/core/agent), [`session-persistence`](../packages/session/session-persistence), [`session-query`](../packages/session-query/session-query), [`session-query-sqlite`](../packages/session-query/session-query-sqlite), [`subagent-inprocess`](../packages/subagent/subagent-inprocess), [`invariants`](../packages/support/invariants) | - | Owns append-only Session instances and emits the durable session event feed. |
| `ctx.sessions` | `core` | [`session`](../packages/core/session) | - | [`agent-loop`](../packages/core/agent-loop), [`agent`](../packages/core/agent), [`session-persistence`](../packages/session/session-persistence), [`session-query`](../packages/session-query/session-query), [`session-query-sqlite`](../packages/session-query/session-query-sqlite), [`subagent-inprocess`](../packages/subagent/subagent-inprocess), [`invariants`](../packages/support/invariants), [`message-feedback`](../packages/feedback/message-feedback) | - | Owns append-only Session instances and emits the durable session event feed. |
| `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.typert` | `core` | [`typert-registry`](../packages/typert/registry) | - | [`typert-loader`](../packages/typert/loader), [`api-gateway`](../packages/api/gateway) | - | Plugins register live zod contributions directly or through dsh-typert-loader; the API gateway consumes invocation descriptors and providers, while other runtime consumers query schemas and reflection metadata at their own edges. |
| `ctx.typertGateway` | `core` | [`api-gateway`](../packages/api/gateway) | - | - | - | Associates generated Remote descriptors with live Cordis services, resolves registered identities, and exposes unary calls through the shared Connection RPC carrier. |
| `ctx.sessionPersistence` | `seam` | [`session-persistence`](../packages/session/session-persistence) | [`session-persistence-jsonl`](../packages/session/session-persistence-jsonl), [`session-persistence-sqlite`](../packages/session/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), [`session-query`](../packages/session-query/session-query), [`session-query-sqlite`](../packages/session-query/session-query-sqlite) | - | Backends persist the same SessionEvent vocabulary; apps choose a backend at composition time. |
| `ctx.sessionPersistence` | `seam` | [`session-persistence`](../packages/session/session-persistence) | [`session-persistence-jsonl`](../packages/session/session-persistence-jsonl), [`session-persistence-sqlite`](../packages/session/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), [`session-query`](../packages/session-query/session-query), [`session-query-sqlite`](../packages/session-query/session-query-sqlite), [`message-feedback`](../packages/feedback/message-feedback) | - | Backends persist the same SessionEvent vocabulary; apps choose a backend at composition time. |
| `ctx.settings` | `seam` | [`settings`](../packages/settings/settings) | [`settings-local`](../packages/settings/settings-local) | [`llm-deepseek`](../packages/llm/llm-deepseek), [`llm-pi-ai`](../packages/llm/llm-pi-ai), `apiproxy` | - | Plugins register namespace schemas and resolve layered values; providers store the raw document. The LLM adapters register their entry config as the composition base under the user section; the web gateway serves redacted layered descriptors and writes the user layer. |
| `ctx.credentials` | `seam` | [`credentials`](../packages/credentials/credentials) | [`credentials-local`](../packages/credentials/credentials-local) | [`llm-deepseek`](../packages/llm/llm-deepseek), [`llm-pi-ai`](../packages/llm/llm-pi-ai), `apiproxy` | - | Configuration carries references to secrets; providers own the values. Consumers resolve per operation, so a rotated credential reaches the very next request; the web gateway exposes value-free views and write-only storage. |
| `ctx.telemetry` | `seam` | [`session-telemetry`](../packages/session/session-telemetry) | [`session-telemetry-otel`](../packages/session/session-telemetry-otel) | - | - | The seam captures, redacts, and hands session records to one backend; nothing else consumes the service — its output leaves the process. |
| `ctx.storage` | `seam` | [`storage`](../packages/storage/storage) | [`storage-json`](../packages/storage/storage-json), [`storage-sqlite`](../packages/storage/storage-sqlite) | [`storage-domain`](../packages/storage/storage-domain) | - | Backends register side by side under names; data forms (domain first) mount on the hub and translate typed operations into opaque KV-unit primitives. |
| `ctx.storageDomain` | `core` | [`storage-domain`](../packages/storage/storage-domain) | - | [`workspace`](../packages/workspace/workspace) | - | Waits for every configured backend, then publishes the domain form as one lifecycle-bound service for typed durable state. |
| `ctx.storageDomain` | `core` | [`storage-domain`](../packages/storage/storage-domain) | - | [`workspace`](../packages/workspace/workspace), [`message-feedback`](../packages/feedback/message-feedback) | - | Waits for every configured backend, then publishes the domain form as one lifecycle-bound service for typed durable state. |
| `ctx.messageFeedback` | `core` | [`message-feedback`](../packages/feedback/message-feedback) | - | - | - | Owns local per-assistant-message feedback, lifecycle and target validation, per-item compare-and-set, and the Host unary Remote contract without entering Session history or telemetry. |
| `ctx.workspace` | `core` | [`workspace`](../packages/workspace/workspace) | - | `apiproxy` | - | Owns WorkspaceId-branded records over the domain facility; stable sessionIds accounts drive Host RPC and GUI projections. |
| `ctx.sessionQuery` | `seam` | [`session-query`](../packages/session-query/session-query) | [`session-query-sqlite`](../packages/session-query/session-query-sqlite) | [`session-reference`](../packages/context/session-reference), [`tool-session-query`](../packages/session-query/tool-session-query) | - | The interface supplies exact reads, filters, and traces; its concrete backend adds full-text reconciliation, ranking, snippets, and cursor generations, while the model consumer owns workspace authority and cursor-free rendering. |
| `ctx.sessionReferences` | `core` | [`session-reference`](../packages/context/session-reference) | - | - | - | Projects bounded current-surface conversation snapshots into durable untrusted message context; host adapters own mention syntax. |

View File

@@ -32,6 +32,7 @@ flowchart LR
pkg_session_query_sqlite["session-query-sqlite"]
pkg_subagent_inprocess["subagent-inprocess"]
pkg_invariants["invariants"]
pkg_message_feedback["message-feedback"]
svc_invariants["ctx.invariants<br/>Package-owned invariant registry"]
pkg_scope["scope"]
pkg_typert_registry["typert-registry"]
@@ -62,6 +63,7 @@ flowchart LR
pkg_storage_domain["storage-domain"]
svc_storageDomain["ctx.storageDomain<br/>Domain data facility"]
pkg_workspace["workspace"]
svc_messageFeedback["ctx.messageFeedback<br/>Lifecycle-bound message feedback"]
svc_workspace["ctx.workspace<br/>Workspace entity registry"]
svc_sessionQuery["ctx.sessionQuery<br/>Session reads, traces, filters, and search"]
pkg_session_reference["session-reference"]
@@ -220,6 +222,7 @@ flowchart LR
pkg_llm_deepseek --> svc_llm
pkg_llm_pi_ai --> svc_llm
pkg_llm_replay --> svc_llm
pkg_message_feedback --> svc_messageFeedback
pkg_modules --> svc_clientModuleHost
pkg_permission --> svc_permission
pkg_plan_mode --> svc_planMode
@@ -324,6 +327,7 @@ flowchart LR
svc_sessionPersistence --> pkg_agent_loop
svc_sessionPersistence --> pkg_hooks_claude
svc_sessionPersistence --> pkg_hooks_codex
svc_sessionPersistence --> pkg_message_feedback
svc_sessionPersistence --> pkg_session_query
svc_sessionPersistence --> pkg_session_query_sqlite
svc_sessionPersistence --> pkg_tool_bash
@@ -336,6 +340,7 @@ flowchart LR
svc_sessions --> pkg_agent
svc_sessions --> pkg_agent_loop
svc_sessions --> pkg_invariants
svc_sessions --> pkg_message_feedback
svc_sessions --> pkg_session_persistence
svc_sessions --> pkg_session_query
svc_sessions --> pkg_session_query_sqlite
@@ -346,6 +351,7 @@ flowchart LR
svc_skills --> pkg_tool_skill
svc_spillStore --> pkg_spill_policy
svc_storage --> pkg_storage_domain
svc_storageDomain --> pkg_message_feedback
svc_storageDomain --> pkg_workspace
svc_subagents --> pkg_tool_ralph
svc_subagents --> pkg_tool_subagent
@@ -394,16 +400,17 @@ flowchart LR
| `ctx.llm` | `seam` | [`llm`](../packages/llm/llm) | [`llm-deepseek`](../packages/llm/llm-deepseek)、[`llm-pi-ai`](../packages/llm/llm-pi-ai)、[`llm-replay`](../packages/support/llm-replay) | [`agent-loop`](../packages/core/agent-loop)、[`compact-basic`](../packages/compact/compact-basic) | - | 适配器注册提供方实现agent loop智能体循环与压缩功能调用提供方无关的流服务。 |
| `ctx.tokenMeter` | `core` | [`token-meter`](../packages/llm/token-meter) | - | [`compact-basic`](../packages/compact/compact-basic) | - | 拥有按会话隔离的回放折叠区;压力消费方共享不可变且带修订版本的测量结果。 |
| `ctx.toolResultPrune` | `core` | [`compact-tool-result-prune`](../packages/compact/compact-tool-result-prune) | - | [`compact-basic`](../packages/compact/compact-basic) | - | 在摘要压缩前,通过可回放的单节点表层替换来改写过大的当前工具结果。 |
| `ctx.sessions` | `core` | [`session`](../packages/core/session) | - | [`agent-loop`](../packages/core/agent-loop)、[`agent`](../packages/core/agent)、[`session-persistence`](../packages/session/session-persistence)、[`session-query`](../packages/session-query/session-query)、[`session-query-sqlite`](../packages/session-query/session-query-sqlite)、[`subagent-inprocess`](../packages/subagent/subagent-inprocess)、[`invariants`](../packages/support/invariants) | - | 拥有仅追加的 Session 实例,并发出持久的会话事件流。 |
| `ctx.sessions` | `core` | [`session`](../packages/core/session) | - | [`agent-loop`](../packages/core/agent-loop)、[`agent`](../packages/core/agent)、[`session-persistence`](../packages/session/session-persistence)、[`session-query`](../packages/session-query/session-query)、[`session-query-sqlite`](../packages/session-query/session-query-sqlite)、[`subagent-inprocess`](../packages/subagent/subagent-inprocess)、[`invariants`](../packages/support/invariants)、[`message-feedback`](../packages/feedback/message-feedback) | - | 拥有仅追加的 Session 实例,并发出持久的会话事件流。 |
| `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) | - | 配套子路径注册所属包本地的检查;该服务负责选择、唯一性、子 fiber以及标明所属包的失败。 |
| `ctx.typert` | `core` | [`typert-registry`](../packages/typert/registry) | - | [`typert-loader`](../packages/typert/loader)、[`api-gateway`](../packages/api/gateway) | - | 插件直接或通过 dsh-typert-loader 注册实时 zod 贡献API 网关消费调用描述符和提供方,其他运行时消费方则在各自边界查询 schema 与反射元数据。 |
| `ctx.typertGateway` | `core` | [`api-gateway`](../packages/api/gateway) | - | - | - | 将生成的 Remote 描述符与实时 Cordis 服务关联,解析已注册的身份,并通过共享的 Connection RPC 载体提供一元调用。 |
| `ctx.sessionPersistence` | `seam` | [`session-persistence`](../packages/session/session-persistence) | [`session-persistence-jsonl`](../packages/session/session-persistence-jsonl)、[`session-persistence-sqlite`](../packages/session/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)、[`session-query`](../packages/session-query/session-query)、[`session-query-sqlite`](../packages/session-query/session-query-sqlite) | - | 各后端持久化同一套 SessionEvent 词汇;应用在组合时选择后端。 |
| `ctx.sessionPersistence` | `seam` | [`session-persistence`](../packages/session/session-persistence) | [`session-persistence-jsonl`](../packages/session/session-persistence-jsonl)、[`session-persistence-sqlite`](../packages/session/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)、[`session-query`](../packages/session-query/session-query)、[`session-query-sqlite`](../packages/session-query/session-query-sqlite)、[`message-feedback`](../packages/feedback/message-feedback) | - | 各后端持久化同一套 SessionEvent 词汇;应用在组合时选择后端。 |
| `ctx.settings` | `seam` | [`settings`](../packages/settings/settings) | [`settings-local`](../packages/settings/settings-local) | [`llm-deepseek`](../packages/llm/llm-deepseek)、[`llm-pi-ai`](../packages/llm/llm-pi-ai)、`apiproxy` | - | 插件注册命名空间 schema 并解析分层值提供方存储原始文档。LLM大语言模型适配器在用户分区下将其入口配置注册为组合基础Web 网关提供经过脱敏的分层描述符,并写入用户层。 |
| `ctx.credentials` | `seam` | [`credentials`](../packages/credentials/credentials) | [`credentials-local`](../packages/credentials/credentials-local) | [`llm-deepseek`](../packages/llm/llm-deepseek)、[`llm-pi-ai`](../packages/llm/llm-pi-ai)、`apiproxy` | - | 配置携带对机密信息的引用提供方拥有实际值。消费方按操作解析因此轮换后的凭据会在紧接着的下一次请求中生效Web 网关提供不含实际值的视图和只写存储。 |
| `ctx.telemetry` | `seam` | [`session-telemetry`](../packages/session/session-telemetry) | [`session-telemetry-otel`](../packages/session/session-telemetry-otel) | - | - | 该 seam 捕获会话记录、进行脱敏并交给一个后端;没有其他组件消费该服务,其输出会离开当前进程。 |
| `ctx.storage` | `seam` | [`storage`](../packages/storage/storage) | [`storage-json`](../packages/storage/storage-json)、[`storage-sqlite`](../packages/storage/storage-sqlite) | [`storage-domain`](../packages/storage/storage-domain) | - | 各后端以不同名称并列注册;数据形态(领域优先)挂载到枢纽上,并将类型化操作转换为不透明的 KV 单元原语。 |
| `ctx.storageDomain` | `core` | [`storage-domain`](../packages/storage/storage-domain) | - | [`workspace`](../packages/workspace/workspace) | - | 等待所有已配置后端就绪,然后将领域形态发布为一个受生命周期约束的服务,用于类型化持久状态。 |
| `ctx.storageDomain` | `core` | [`storage-domain`](../packages/storage/storage-domain) | - | [`workspace`](../packages/workspace/workspace)、[`message-feedback`](../packages/feedback/message-feedback) | - | 等待所有已配置后端就绪,然后将领域形态发布为一个受生命周期约束的服务,用于类型化持久状态。 |
| `ctx.messageFeedback` | `core` | [`message-feedback`](../packages/feedback/message-feedback) | - | - | - | 拥有本地逐 assistant 消息反馈、生命周期与目标校验、逐条目 compare-and-set 及 Host 一元 Remote 契约,且不进入 Session 历史或遥测。 |
| `ctx.workspace` | `core` | [`workspace`](../packages/workspace/workspace) | - | `apiproxy` | - | 通过领域设施拥有带 WorkspaceId 品牌类型的记录;稳定的 sessionIds 账户驱动 Host RPC 与 GUI 投影。 |
| `ctx.sessionQuery` | `seam` | [`session-query`](../packages/session-query/session-query) | [`session-query-sqlite`](../packages/session-query/session-query-sqlite) | [`session-reference`](../packages/context/session-reference)、[`tool-session-query`](../packages/session-query/tool-session-query) | - | 该接口提供精确读取、过滤和追踪;具体后端还提供全文协调、排序、摘要片段和游标世代,而模型消费方负责工作区权限与不含游标的渲染。 |
| `ctx.sessionReferences` | `core` | [`session-reference`](../packages/context/session-reference) | - | - | - | 将当前表层中有界的对话快照投影为持久但不可信的消息上下文Host 适配器负责提及语法。 |

View File

@@ -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 docs/config-catalog.md
config-catalog.md: 47b14a7ad5bd92286767d0b7e1ab9a7abafce8be
config-catalog.zh.md: 8c74940b3aad350f720361e197a389055784b445
config-catalog.md: 5fd3182b305d16d8c235736c5f50aa1fb3661ce0
config-catalog.zh.md: 1aefcaff17d272d4767a22a5ba72a7ab6dc0b914

View File

@@ -1129,6 +1129,20 @@ export interface ReconnectConfig {
Source: [`packages/mcp/mcp-client/src/index.ts:98`](../packages/mcp/mcp-client/src/index.ts)
## `@deepseek-ai/dsh-message-feedback`
Requires: `storageDomain` · `sessionPersistence` · `sessions`
```ts config-catalog
/** Required deployment policy for optional notes. */
export interface Config {
/** Maximum UTF-8 byte length accepted for one note. */
readonly maxNoteBytes: number
}
```
Source: [`packages/feedback/message-feedback/src/index.ts:49`](../packages/feedback/message-feedback/src/index.ts)
## `@deepseek-ai/dsh-permission`
Requires: `bash` · `approval` · `sessions`

View File

@@ -1131,6 +1131,20 @@ export interface ReconnectConfig {
来源:[`packages/mcp/mcp-client/src/index.ts:94`](../packages/mcp/mcp-client/src/index.ts)
## `@deepseek-ai/dsh-message-feedback`
需要:`storageDomain` · `sessionPersistence` · `sessions`
```ts config-catalog
/** Required deployment policy for optional notes. */
export interface Config {
/** Maximum UTF-8 byte length accepted for one note. */
readonly maxNoteBytes: number
}
```
来源:[`packages/feedback/message-feedback/src/index.ts:49`](../packages/feedback/message-feedback/src/index.ts)
## `@deepseek-ai/dsh-permission`
需要:`bash` · `approval` · `sessions`

View File

@@ -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 docs/cordis-tutorial/01-first-plugin.md
01-first-plugin.md: 448034b54107d5620673052ad388feecc22fe1e1
01-first-plugin.zh.md: a1838be61f8099831d59afa266fe40ce6bd165bf
01-first-plugin.md: 79df2f42df1f34a7ef32cc81607e1b926a1854ae
01-first-plugin.zh.md: 87cd7a96843d69d68fb95662e59bbfb9ebfc2a37

View File

@@ -92,4 +92,4 @@ One caveat worth knowing early: a config entry whose module cannot be **resolved
Next: [Lifecycle and effects](02-lifecycle-and-effects.md) — what happens when a plugin unloads.
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness-sdk)
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness)

View File

@@ -92,4 +92,4 @@ export function apply(ctx: Context) {
下一章:[生命周期与 effect](02-lifecycle-and-effects.md):插件卸载时会发生什么。
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness-sdk)
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness)

View File

@@ -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 docs/cordis-tutorial/02-lifecycle-and-effects.md
02-lifecycle-and-effects.md: 3e88c6f1e1fb1bc825fb74434520993c855010c3
02-lifecycle-and-effects.zh.md: 3cceecfb8334f2ed2ec9942fa876a0e51e1b315f
02-lifecycle-and-effects.md: 8e75708eb0cba1aceb7fa3dae5ae334995eb113f
02-lifecycle-and-effects.zh.md: bc4489e702ab58b5d1efd8a72fc693ee48af2624

View File

@@ -95,4 +95,4 @@ One ordering caveat: disposers start in reverse registration order, but multiple
Next: [Services](03-services.md) — how plugins share capabilities.
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness-sdk)
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness)

View File

@@ -95,4 +95,4 @@ PENDING → LOADING → ACTIVE → UNLOADING → DISPOSED
下一章:[服务](03-services.md):插件如何共享功能。
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness-sdk)
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness)

View File

@@ -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 docs/cordis-tutorial/03-services.md
03-services.md: 3f2273ba4061912640e409d7b4deb4cd1b45684f
03-services.zh.md: 657271aba6c0b2e824c79fa822e29c8a6dcf4275
03-services.md: 32007284be99ef46b4621089c9b3a80317e77189
03-services.zh.md: d82be29aa69686b8dc10cc6a45a658683c017cbd

View File

@@ -95,4 +95,4 @@ Service names live in one flat namespace per application. Prefix or namespace yo
Next: [Events](04-events.md) — communication without a shared service.
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness-sdk)
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness)

View File

@@ -95,4 +95,4 @@ export function apply(ctx: Context) {
下一章:[事件](04-events.md):无需共享服务即可通信。
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness-sdk)
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness)

View File

@@ -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 docs/cordis-tutorial/04-events.md
04-events.md: 0302adf7c81b802b406f5f6737539ccf3eb970f9
04-events.zh.md: ae41e757c06a46ef70c250c94a124546769e0112
04-events.md: db911b9a06d7304d73030a2020de3d465fde2f9c
04-events.zh.md: e0357b2c04785d52a54f839d1b8ff3ecccb027ed

View File

@@ -141,4 +141,4 @@ The harness uses waterfalls for decisions that cooperating plugins may wrap or a
Next: [Configuration](05-config.md) — plugin options from `cordis.yml`.
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness-sdk)
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness)

View File

@@ -141,4 +141,4 @@ harness 使用 waterfall 处理协作插件可以包装或回答的决策:[`ag
下一章:[配置](05-config.md):来自 `cordis.yml` 的插件选项。
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness-sdk)
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness)

View File

@@ -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 docs/cordis-tutorial/05-config.md
05-config.md: ad73a732242e4015b2976e6fb193ff464e148dfa
05-config.zh.md: edb3c4113288dfa80e899fb2e5eb21a67d929ca6
05-config.md: 2357f663135d6fc78a65f9d0952e0bc3f5eefae4
05-config.zh.md: fbd94d179494ad0b6f73baff2ca525c786cc9e33

View File

@@ -81,4 +81,4 @@ The loader used in this repo supports a `!!js` tag for config values that must b
Next: [Composition and HMR](06-composition-and-hmr.md) — treating `cordis.yml` as the application.
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness-sdk)
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness)

View File

@@ -81,4 +81,4 @@ ValidationError: invalid config:
下一章:[组合与 HMR热模块替换](06-composition-and-hmr.md):将 `cordis.yml` 视为应用。
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness-sdk)
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness)

View File

@@ -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 docs/cordis-tutorial/06-composition-and-hmr.md
06-composition-and-hmr.md: 490e3de3a98dd823190deefd47e1b6f2f8ba71b5
06-composition-and-hmr.zh.md: 4aefb5ecd036929590ab373a2883d90779997b4b
06-composition-and-hmr.md: 87ea26014657ae8c8199e1ebb486556c827d96ca
06-composition-and-hmr.zh.md: 830f55de7c1be351fe701cb068197543602619a7

View File

@@ -110,4 +110,4 @@ needs-timer is PENDING — a required service is missing
Next: [Into the harness](07-into-the-harness.md) — the same patterns against real harness services.
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness-sdk)
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness)

View File

@@ -110,4 +110,4 @@ needs-timer is PENDING — a required service is missing
下一章:[进入 harness](07-into-the-harness.md):把相同模式用于真实的 harness 服务。
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness-sdk)
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness)

View File

@@ -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 docs/cordis-tutorial/07-into-the-harness.md
07-into-the-harness.md: 41a30f032ac02d8e9e3b17ac8d9cd13e9973e36a
07-into-the-harness.zh.md: 159cede00d453796f6a2cacae184229d71e17f87
07-into-the-harness.md: 2d3c23f9f7f7fc6bd6cabd4e7e68ebfc46e20665
07-into-the-harness.zh.md: 45dc0ee6f07ab3b0275499cd4ab0c436eebdddef

View File

@@ -104,4 +104,4 @@ Where to go next:
- The generated `cordis-surface` regions on the [subsystem pages](../subsystems/core.md) — everything you can inject and listen to, each on its owning page.
- [Architecture](../architecture.md) — the system map these plugins live in.
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness-sdk)
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness)

View File

@@ -104,4 +104,4 @@ logger 会先触发:`tools/result` 在结果物化过程中发出,发生在
- [子系统页面](../subsystems/core.md)上生成的 `cordis-surface` 区块:可以注入和监听的所有内容,各在其所属页面上。
- [架构](../architecture.md):这些插件所处的系统地图。
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness-sdk)
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness)

View File

@@ -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 docs/cordis-tutorial/index.md
index.md: cf61fec07acd2022591cd858ba4146b6a4ae1a3d
index.zh.md: 775bf2fce2138b9edd91f5ee46b93b8c4eb4559e
index.md: fb700344e6d07d3864655009d2edac15ee9eede8
index.zh.md: a68e931d81e745164d8f9a5dc7ec9aec4cd0e590

View File

@@ -13,7 +13,7 @@ If you want the condensed concept reference instead of a walkthrough, read the [
You need a clone of this repository with dependencies installed — the [quick start](../user/guide/quickstart.md) covers prerequisites. No API key is needed for this tutorial; every example runs keylessly.
```sh
git clone https://github.com/deepseek-ai/deepseek-harness-sdk.git
git clone https://github.com/deepseek-ai/deepseek-harness.git
cd deepseek-harness
pnpm install
```
@@ -55,4 +55,4 @@ The examples use three TypeScript features beyond ordinary modern JavaScript:
Chapter 5 also uses an `interface` to describe a configuration object's fields and a generic type such as `Schema<Config>` to say which object fields a schema validates. You can copy those declarations as shown; the surrounding text explains what each one connects.
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness-sdk)
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness)

View File

@@ -13,7 +13,7 @@ Cordis 是 DeepSeek Harness SDK 底层的插件框架:它是一个小型运行
你需要克隆本仓库并安装依赖,具体前置条件见[快速入门](../user/guide/quickstart.md)。本教程不需要 API 密钥;所有示例均可在无密钥环境中运行。
```sh
git clone https://github.com/deepseek-ai/deepseek-harness-sdk.git
git clone https://github.com/deepseek-ai/deepseek-harness.git
cd deepseek-harness
pnpm install
```
@@ -55,4 +55,4 @@ node --import tsx ../../vendor/cordis/bin.js
第 5 章还会使用 `interface` 描述配置对象的字段,并使用 `Schema<Config>` 这类泛型表示 schema 校验哪些对象字段。你可以直接照写这些声明;周围的正文会解释每项声明连接了什么。
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness-sdk)
[![](https://img.shields.io/badge/powered_by-dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white)](https://github.com/deepseek-ai/deepseek-harness)

View File

@@ -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 docs/module-graph.md
module-graph.md: 4724a6a5d50a086b16ef1d0d58dae5055dc0a105
module-graph.zh.md: 59822a3e4805f2d0bdad5bc940f1fdde54e28ee0
module-graph.md: 44eef9fdd7a812d4d4d6973ba8366dd3ef86a713
module-graph.zh.md: 5984c74cef191c1ae268f2cd8e408e896007404a

View File

@@ -201,6 +201,7 @@ flowchart TD
end
subgraph group_feedback["packages/feedback"]
pkg_command_feedback["command-feedback"]
pkg_message_feedback["message-feedback"]
end
subgraph group_guard["packages/guard"]
pkg_repeat_tool_guard["repeat-tool-guard"]
@@ -571,6 +572,13 @@ flowchart TD
pkg_time_context --> pkg_agent
pkg_time_context --> pkg_invariants
pkg_time_context --> pkg_session
pkg_message_feedback --> pkg_brand
pkg_message_feedback --> pkg_invariants
pkg_message_feedback --> pkg_llm
pkg_message_feedback --> pkg_session
pkg_message_feedback --> pkg_session_persistence
pkg_message_feedback --> pkg_storage_domain
pkg_message_feedback --> pkg_type_meta
pkg_host_apiproxy --> pkg_agent_presets
pkg_host_apiproxy --> pkg_invariants
pkg_host_directory_picker_auto --> pkg_host_directory_picker_browse
@@ -1350,6 +1358,7 @@ flowchart TD
| [`spill-local`](../packages/spill/spill-local) | `spill` | [`invariants`](../packages/support/invariants), [`spill`](../packages/spill/spill) |
| [`loader-smoke`](../packages/support/loader-smoke) | `support` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session) |
| [`time-context`](../packages/context/time-context) | `context` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`session`](../packages/core/session) |
| [`message-feedback`](../packages/feedback/message-feedback) | `feedback` | [`brand`](../packages/util/brand), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`storage-domain`](../packages/storage/storage-domain), [`type-meta`](../packages/typert/type-meta) |
| [`host-apiproxy`](../packages/host/apiproxy) | `host` | [`agent-presets`](../packages/preset/agent-presets), [`invariants`](../packages/support/invariants) |
| [`host-directory-picker-auto`](../packages/host/directory-picker-auto) | `host` | [`host-directory-picker-browse`](../packages/host/directory-picker-browse), [`host-directory-picker-native`](../packages/host/directory-picker-native), [`host-webserver`](../packages/host/webserver), [`invariants`](../packages/support/invariants) |
| [`commands`](../packages/interaction/commands) | `interaction` | [`agent`](../packages/core/agent), [`brand`](../packages/util/brand), [`invariants`](../packages/support/invariants), [`scope`](../packages/core/scope), [`session`](../packages/core/session) |

View File

@@ -203,6 +203,7 @@ flowchart TD
end
subgraph group_feedback["packages/feedback"]
pkg_command_feedback["command-feedback"]
pkg_message_feedback["message-feedback"]
end
subgraph group_guard["packages/guard"]
pkg_repeat_tool_guard["repeat-tool-guard"]
@@ -573,6 +574,13 @@ flowchart TD
pkg_time_context --> pkg_agent
pkg_time_context --> pkg_invariants
pkg_time_context --> pkg_session
pkg_message_feedback --> pkg_brand
pkg_message_feedback --> pkg_invariants
pkg_message_feedback --> pkg_llm
pkg_message_feedback --> pkg_session
pkg_message_feedback --> pkg_session_persistence
pkg_message_feedback --> pkg_storage_domain
pkg_message_feedback --> pkg_type_meta
pkg_host_apiproxy --> pkg_agent_presets
pkg_host_apiproxy --> pkg_invariants
pkg_host_directory_picker_auto --> pkg_host_directory_picker_browse
@@ -1352,6 +1360,7 @@ flowchart TD
| [`spill-local`](../packages/spill/spill-local) | `spill` | [`invariants`](../packages/support/invariants), [`spill`](../packages/spill/spill) |
| [`loader-smoke`](../packages/support/loader-smoke) | `support` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session) |
| [`time-context`](../packages/context/time-context) | `context` | [`agent`](../packages/core/agent), [`invariants`](../packages/support/invariants), [`session`](../packages/core/session) |
| [`message-feedback`](../packages/feedback/message-feedback) | `feedback` | [`brand`](../packages/util/brand), [`invariants`](../packages/support/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`storage-domain`](../packages/storage/storage-domain), [`type-meta`](../packages/typert/type-meta) |
| [`host-apiproxy`](../packages/host/apiproxy) | `host` | [`agent-presets`](../packages/preset/agent-presets), [`invariants`](../packages/support/invariants) |
| [`host-directory-picker-auto`](../packages/host/directory-picker-auto) | `host` | [`host-directory-picker-browse`](../packages/host/directory-picker-browse), [`host-directory-picker-native`](../packages/host/directory-picker-native), [`host-webserver`](../packages/host/webserver), [`invariants`](../packages/support/invariants) |
| [`commands`](../packages/interaction/commands) | `interaction` | [`agent`](../packages/core/agent), [`brand`](../packages/util/brand), [`invariants`](../packages/support/invariants), [`scope`](../packages/core/scope), [`session`](../packages/core/session) |

View File

@@ -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 docs/subsystems/README.md
README.md: fddbf460c8e9e7c6f9ed1d3375bdabe65947661f
README.zh.md: febc5a97426fef5ec4b2b80d9677957369994a3b
README.md: 560851eeda607b762456fe20c874b4497704709f
README.zh.md: 4acba4372e995b54a3bb326bec0cf9606f997773

View File

@@ -18,6 +18,7 @@ One page per subsystem of the DeepSeek Harness: what it is, the data structures
| [settings.md](settings.md) | the user-settings seam: `SettingsNamespace` registration, layered resolution (defaults → composition `base` → user document), owner scopes, hot commits |
| [credentials.md](credentials.md) | the credential seam: `CredentialRef` references (never values) in configuration, per-operation resolution, UI-safe `CredentialInfo`, provider source layers |
| [session-query.md](session-query.md) | logical records, bounded exact-event reads, relationship traces, semantic filters/documents, and full-text result pages |
| [feedback.md](feedback.md) | lifecycle-bound per-message feedback records, optimistic versions, sidecar persistence, and the Host Remote contract |
| [session-title.md](session-title.md) | durable title snapshots, cited source-message seqs, and the asynchronous provider contract |
| [session-reference.md](session-reference.md) | structured cross-session references: `SessionReferenceInput`/`Candidate`, prepared message contexts, the stable error taxonomy |
| [system-prompt.md](system-prompt.md) | per-assembly context, tool-provider results, prompt sections, and cooperative assembly |

View File

@@ -18,6 +18,7 @@
| [settings.md](settings.md) | 用户设置 seam`SettingsNamespace` 注册、分层解析(默认值 → 组合 `base` → 用户文档、owner scope、热提交 |
| [credentials.md](credentials.md) | 凭据 seam配置中的 `CredentialRef` 引用(绝不含值)、按操作解析、对 UI 安全的 `CredentialInfo`、provider 来源层 |
| [session-query.md](session-query.md) | 逻辑记录、有界精确事件读取、关系追踪、语义筛选器/文档与全文检索结果页 |
| [feedback.md](feedback.md) | 绑定生命周期的逐消息反馈记录、乐观版本、伴随记录持久化与 Host Remote 契约 |
| [session-title.md](session-title.md) | 持久标题快照、被引用的来源消息 seq 与异步提供方约定 |
| [session-reference.md](session-reference.md) | 结构化跨会话引用:`SessionReferenceInput`/`Candidate`、prepared 消息上下文、稳定错误分类 |
| [system-prompt.md](system-prompt.md) | 逐次组装的上下文、工具提供方结果、提示词段落与协作式组装 |

View 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 docs/subsystems/feedback.md
feedback.md: 76a29f7d6ba604fa07ed56429c9b066e22639671
feedback.zh.md: 5a409832de68b6d0bc9688a907c0f22edd3b0a43

256
docs/subsystems/feedback.md Normal file
View File

@@ -0,0 +1,256 @@
# Message Feedback
English | [中文](feedback.zh.md)
[`@deepseek-ai/dsh-message-feedback`](../../packages/feedback/message-feedback) owns editable feedback for individual assistant messages. It is deliberately separate from the immutable Session-level `feedback/record` event: message feedback is a local storage-domain sidecar, not Session-log content or a projection, and it performs no telemetry handoff.
Source: [`packages/feedback/message-feedback/src/types.ts`](../../packages/feedback/message-feedback/src/types.ts)
## Public types
```ts type-equiv
/** Opaque compare-and-set token for one exact feedback item revision. */
type MessageFeedbackVersion = Branded<'MessageFeedbackVersion'>
```
```ts type-equiv
/** The human's overall judgment of one assistant message. */
type MessageFeedbackRating = 'positive' | 'negative'
```
```ts type-equiv
/** One current feedback value and its opaque mutation token. */
interface MessageFeedbackItem {
/** Stable identity of the assistant message inside the owning Session. */
readonly messageId: MessageId
/** Overall positive or negative judgment. */
readonly rating: MessageFeedbackRating
/** Optional explanation, preserved verbatim after validation. */
readonly note?: string
/** Equality-only token replaced by every material create or update. */
readonly version: MessageFeedbackVersion
/** Host-assigned creation time in Unix epoch milliseconds. */
readonly createdAt: number
/** Host-assigned time of the most recent material update. */
readonly updatedAt: number
}
```
```ts type-equiv
/** Read all message feedback belonging to one persisted Session lifecycle. */
interface MessageFeedbackListRequest {
/** Persisted Session whose sidecar should be read. */
readonly sessionId: SessionId
}
```
```ts type-equiv
/** Current feedback values for one Session, in first-creation order. */
interface MessageFeedbackListValue {
/** Fresh immutable item snapshots. */
readonly items: readonly MessageFeedbackItem[]
}
```
```ts type-equiv
/** Create or replace feedback for one assistant message. */
interface MessageFeedbackPutRequest {
/** Persisted Session that owns the target message. */
readonly sessionId: SessionId
/** Target assistant-message identity. */
readonly messageId: MessageId
/** Desired overall judgment. */
readonly rating: MessageFeedbackRating
/** Optional non-blank explanation. */
readonly note?: string
/** Observed item version, or `null` to require that no item exists. */
readonly ifVersion: MessageFeedbackVersion | null
}
```
```ts type-equiv
/** Delete feedback for one message after observing its current version. */
interface MessageFeedbackDeleteRequest {
/** Persisted Session that owns the sidecar. */
readonly sessionId: SessionId
/** Message whose feedback should be absent after this operation. */
readonly messageId: MessageId
/** Observed item version; ignored when the item is already absent. */
readonly ifVersion: MessageFeedbackVersion
}
```
```ts type-equiv
/** Idempotent deletion acknowledgement. */
interface MessageFeedbackDeleteValue {
/** Stable postcondition shared by the first deletion and every retry. */
readonly absent: true
}
```
```ts type-equiv
/** No persisted Session header exists for the requested id. */
interface MessageFeedbackSessionNotFound {
readonly code: 'session-not-found'
readonly sessionId: SessionId
}
```
```ts type-equiv
/** The id does not name a derived, append-origin assistant message. */
interface MessageFeedbackTargetNotFound {
readonly code: 'target-not-found'
readonly sessionId: SessionId
readonly messageId: MessageId
}
```
```ts type-equiv
/** A material mutation did not match the addressed item's current version. */
interface MessageFeedbackVersionConflict {
readonly code: 'version-conflict'
/** Authoritative current item, or `null` when it does not exist. */
readonly current: MessageFeedbackItem | null
}
```
```ts type-equiv
/** A supplied note contains no non-whitespace character. */
interface MessageFeedbackNoteBlank {
readonly code: 'note-blank'
}
```
```ts type-equiv
/** A supplied note exceeds the configured UTF-8 byte limit. */
interface MessageFeedbackNoteTooLarge {
readonly code: 'note-too-large'
readonly maxBytes: number
readonly actualBytes: number
}
```
```ts type-equiv
/** Failures shared by the public message-feedback operations. */
type MessageFeedbackFailure =
| MessageFeedbackSessionNotFound
| MessageFeedbackTargetNotFound
| MessageFeedbackVersionConflict
| MessageFeedbackNoteBlank
| MessageFeedbackNoteTooLarge
```
```ts type-equiv
/** Successful public operation result. */
interface MessageFeedbackSuccess<T> {
readonly ok: true
readonly value: T
}
```
```ts type-equiv
/** Rejected public operation result with a stable business failure. */
interface MessageFeedbackRejected<E extends MessageFeedbackFailure> {
readonly ok: false
readonly error: E
}
```
```ts type-equiv
/** Result returned by the message-feedback `list` operation. */
type MessageFeedbackListResult =
| MessageFeedbackSuccess<MessageFeedbackListValue>
| MessageFeedbackRejected<MessageFeedbackSessionNotFound>
```
```ts type-equiv
/** Result returned by the message-feedback `put` operation. */
type MessageFeedbackPutResult =
| MessageFeedbackSuccess<MessageFeedbackItem>
| MessageFeedbackRejected<
| MessageFeedbackSessionNotFound
| MessageFeedbackTargetNotFound
| MessageFeedbackVersionConflict
| MessageFeedbackNoteBlank
| MessageFeedbackNoteTooLarge
>
```
```ts type-equiv
/** Result returned by the message-feedback `delete` operation. */
type MessageFeedbackDeleteResult =
| MessageFeedbackSuccess<MessageFeedbackDeleteValue>
| MessageFeedbackRejected<MessageFeedbackSessionNotFound | MessageFeedbackVersionConflict>
```
## Data and concurrency
One Session sidecar row contains its header identity `{createdAt, cwd}` and feedback items keyed by `MessageId`. Each item carries a positive or negative rating, an optional note, Host-assigned `createdAt`/`updatedAt` timestamps, and its own opaque version. Versions are compared only for equality and only against the addressed message; callers do not order or synthesize them.
`put` uses strict optimistic concurrency: every request for an existing item must match its current `ifVersion`, including a no-op. A conflict returns the authoritative current item (or `null`), so a caller can reconcile a lost response or a concurrent edit without another read. Deleting an already absent item succeeds. A per-Session queue encloses inspection, read, conflict evaluation, and whole-row write, so these guarantees cover concurrent calls in one Host process.
## Target and lifecycle authority
`SessionPersistence.inspect()` supplies the target Session observation without publishing or resuming an Agent and without committing cold repair. A cold `listSnapshots()` preflight classifies definite absence; inspection failure for a catalogued Session propagates as infrastructure failure. `put` accepts only a non-empty, append-origin `assistant/message` with the requested `MessageId`; replacement-origin, usage-only empty, and non-assistant records are not feedback targets.
The stored `{createdAt, cwd}` identity must match the inspected header. A mismatch is treated as absence: `list` returns no items, while `put` may replace the stale row with one bound to the current header identity. Forks use a new Session identity and receive no sidecar copy even when their seed contains the same messages.
## Persistence and Remote contract
The service stores whole Session rows in the `message_feedback` storage domain through `ctx.storageDomain`. Before `put` commits a row that references a target message, a matching live target passes through the canonical `ctx.sessions.flush` checkpoint; both live and cold paths are then physically read from sequence zero through `SessionPersistence.readFrom`. The resulting observation is revalidated before the sidecar write, so the durable target log always precedes its sidecar commit. `maxNoteBytes` is required and bounds note text by UTF-8 bytes; the Web Host composition sets `8192`. The package publishes the Host `messageFeedback.list`, `messageFeedback.put`, and `messageFeedback.delete` unary Remote contract through `GatewayService` and `@Remote`; the generated Cordis surface below is the method-level authority.
Plugin disposal closes mutation admission, drains accepted per-Session queue work, and then closes the storage domain.
## Boundaries and limitations
- The client Remote aggregate mount and UI consumer are separately owned and deferred.
- The mutation queue is process-local. Storage-domain has no cross-process conditional write, so multiple Host writers to one storage root have no compare-and-swap or lost-update guarantee.
- Session persistence has no durable deletion surface. The service does not treat `session/disposed` or `host/session-removed` as deletion and therefore performs no fake cascade; orphan sidecar rows may remain after out-of-band log removal.
- A request in the narrow interval after live detach but before the persistence catalog materializes the header can receive `session-not-found`; callers retry after retirement materialization.
- Cold requests scan the complete Session snapshot catalog because persistence has no lookup-by-id metadata operation. One Session row also has no item-count or aggregate-byte cap; `maxNoteBytes` bounds only each note until a concrete consumer owns a row policy.
- Header identity detects a reused id only when `{createdAt, cwd}` differs; a cloned log retaining the same header identity is indistinguishable by this contract.
- The Host contract records no authenticated actor or audit identity and therefore assumes a trusted caller boundary.
<!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
<a id="cordis-surface"></a>
## Cordis surface
Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — this section is byte-identical in both language sides of the page. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` surface lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
<a id="ctxmessagefeedback--messagefeedbackservice"></a>
### `ctx.messageFeedback` — `MessageFeedbackService`
Storage-domain sidecar service. It inspects persisted Session history and never creates or resumes an Agent or Session.
```ts cordis-catalog
/**
* Read feedback belonging to the current persisted Session lifecycle.
* A stale row from a reused Session id is invisible.
* @param request - Session identity to inspect and list.
* @returns current immutable items or `session-not-found`.
*/
@Remote('list') async list(request: MessageFeedbackListRequest): Promise<MessageFeedbackListResult>
/**
* Create or replace feedback for one derived append-origin assistant
* message. Every request must match the addressed item's current version;
* a matching no-op returns the stored item without changing its revision.
* @param request - target, desired value, and observed item version.
* @returns the committed item or an explicit business failure.
*/
@Remote('put') put(request: MessageFeedbackPutRequest): Promise<MessageFeedbackPutResult>
/**
* Delete one feedback item. Absence is successful regardless of the
* supplied version; an existing item requires an exact version match.
* @param request - Session, message, and observed item version.
* @returns the stable absent postcondition, or an explicit failure.
*/
@Remote('delete') delete(request: MessageFeedbackDeleteRequest): Promise<MessageFeedbackDeleteResult>
```
Source: [`packages/feedback/message-feedback/src/index.ts:150`](../../packages/feedback/message-feedback/src/index.ts)
<!-- END GENERATED cordis-surface -->

View File

@@ -0,0 +1,256 @@
# 消息反馈
[English](feedback.md) | 中文
[`@deepseek-ai/dsh-message-feedback`](../../packages/feedback/message-feedback)拥有针对单条 assistant 消息的可编辑反馈。它刻意与不可变的 Session 级 `feedback/record` 事件分离message feedback 是本地 storage-domain 伴随记录sidecar不是 Session 日志内容或投影,也不执行遥测交接。
来源:[`packages/feedback/message-feedback/src/types.ts`](../../packages/feedback/message-feedback/src/types.ts)
## 公开类型
```ts type-equiv
/** Opaque compare-and-set token for one exact feedback item revision. */
type MessageFeedbackVersion = Branded<'MessageFeedbackVersion'>
```
```ts type-equiv
/** The human's overall judgment of one assistant message. */
type MessageFeedbackRating = 'positive' | 'negative'
```
```ts type-equiv
/** One current feedback value and its opaque mutation token. */
interface MessageFeedbackItem {
/** Stable identity of the assistant message inside the owning Session. */
readonly messageId: MessageId
/** Overall positive or negative judgment. */
readonly rating: MessageFeedbackRating
/** Optional explanation, preserved verbatim after validation. */
readonly note?: string
/** Equality-only token replaced by every material create or update. */
readonly version: MessageFeedbackVersion
/** Host-assigned creation time in Unix epoch milliseconds. */
readonly createdAt: number
/** Host-assigned time of the most recent material update. */
readonly updatedAt: number
}
```
```ts type-equiv
/** Read all message feedback belonging to one persisted Session lifecycle. */
interface MessageFeedbackListRequest {
/** Persisted Session whose sidecar should be read. */
readonly sessionId: SessionId
}
```
```ts type-equiv
/** Current feedback values for one Session, in first-creation order. */
interface MessageFeedbackListValue {
/** Fresh immutable item snapshots. */
readonly items: readonly MessageFeedbackItem[]
}
```
```ts type-equiv
/** Create or replace feedback for one assistant message. */
interface MessageFeedbackPutRequest {
/** Persisted Session that owns the target message. */
readonly sessionId: SessionId
/** Target assistant-message identity. */
readonly messageId: MessageId
/** Desired overall judgment. */
readonly rating: MessageFeedbackRating
/** Optional non-blank explanation. */
readonly note?: string
/** Observed item version, or `null` to require that no item exists. */
readonly ifVersion: MessageFeedbackVersion | null
}
```
```ts type-equiv
/** Delete feedback for one message after observing its current version. */
interface MessageFeedbackDeleteRequest {
/** Persisted Session that owns the sidecar. */
readonly sessionId: SessionId
/** Message whose feedback should be absent after this operation. */
readonly messageId: MessageId
/** Observed item version; ignored when the item is already absent. */
readonly ifVersion: MessageFeedbackVersion
}
```
```ts type-equiv
/** Idempotent deletion acknowledgement. */
interface MessageFeedbackDeleteValue {
/** Stable postcondition shared by the first deletion and every retry. */
readonly absent: true
}
```
```ts type-equiv
/** No persisted Session header exists for the requested id. */
interface MessageFeedbackSessionNotFound {
readonly code: 'session-not-found'
readonly sessionId: SessionId
}
```
```ts type-equiv
/** The id does not name a derived, append-origin assistant message. */
interface MessageFeedbackTargetNotFound {
readonly code: 'target-not-found'
readonly sessionId: SessionId
readonly messageId: MessageId
}
```
```ts type-equiv
/** A material mutation did not match the addressed item's current version. */
interface MessageFeedbackVersionConflict {
readonly code: 'version-conflict'
/** Authoritative current item, or `null` when it does not exist. */
readonly current: MessageFeedbackItem | null
}
```
```ts type-equiv
/** A supplied note contains no non-whitespace character. */
interface MessageFeedbackNoteBlank {
readonly code: 'note-blank'
}
```
```ts type-equiv
/** A supplied note exceeds the configured UTF-8 byte limit. */
interface MessageFeedbackNoteTooLarge {
readonly code: 'note-too-large'
readonly maxBytes: number
readonly actualBytes: number
}
```
```ts type-equiv
/** Failures shared by the public message-feedback operations. */
type MessageFeedbackFailure =
| MessageFeedbackSessionNotFound
| MessageFeedbackTargetNotFound
| MessageFeedbackVersionConflict
| MessageFeedbackNoteBlank
| MessageFeedbackNoteTooLarge
```
```ts type-equiv
/** Successful public operation result. */
interface MessageFeedbackSuccess<T> {
readonly ok: true
readonly value: T
}
```
```ts type-equiv
/** Rejected public operation result with a stable business failure. */
interface MessageFeedbackRejected<E extends MessageFeedbackFailure> {
readonly ok: false
readonly error: E
}
```
```ts type-equiv
/** Result returned by the message-feedback `list` operation. */
type MessageFeedbackListResult =
| MessageFeedbackSuccess<MessageFeedbackListValue>
| MessageFeedbackRejected<MessageFeedbackSessionNotFound>
```
```ts type-equiv
/** Result returned by the message-feedback `put` operation. */
type MessageFeedbackPutResult =
| MessageFeedbackSuccess<MessageFeedbackItem>
| MessageFeedbackRejected<
| MessageFeedbackSessionNotFound
| MessageFeedbackTargetNotFound
| MessageFeedbackVersionConflict
| MessageFeedbackNoteBlank
| MessageFeedbackNoteTooLarge
>
```
```ts type-equiv
/** Result returned by the message-feedback `delete` operation. */
type MessageFeedbackDeleteResult =
| MessageFeedbackSuccess<MessageFeedbackDeleteValue>
| MessageFeedbackRejected<MessageFeedbackSessionNotFound | MessageFeedbackVersionConflict>
```
## 数据与并发
每个 Session 的一条伴随记录包含 header 身份 `{createdAt, cwd}` 和以 `MessageId` 为键的反馈条目。每个条目携带好评或差评、可选备注、Host 分配的 `createdAt`/`updatedAt` 时间戳及自己的 opaque version。version 只能用于相等比较,且只与目标消息比较;调用方不能排序或自行合成它。
`put` 采用严格乐观并发:已有条目的每次请求都必须匹配当前 `ifVersion`,即使请求不会改变目标值。冲突会返回权威当前条目(不存在时为 `null`),因此调用方无需额外读取,即可协调丢失响应或并发编辑。删除已经不存在的条目同样成功。按 Session 划分的队列覆盖检查、读取、冲突判断与整行写入,因此这些保证适用于单个 Host 进程中的并发调用。
## 目标与生命周期权威
`SessionPersistence.inspect()` 提供目标 Session 的观测,且不会发布或恢复 Agent也不会提交 cold repair。cold 路径先由 `listSnapshots()` 预检明确不存在;已进入目录的 Session 若检查失败,会按基础设施故障原样传播。`put` 只接受具有指定 `MessageId` 的非空、append-origin `assistant/message`replacement-origin、仅承载 usage 的空记录和非 assistant 记录都不是反馈目标。
存储的 `{createdAt, cwd}` 身份必须与检查所得 header 匹配。不匹配按不存在处理:`list` 返回空条目,`put` 则可用绑定当前 header 身份的新记录替换陈旧行。fork 使用新的 Session 身份,即使种子包含相同消息,也不获得伴随记录副本。
## 持久化与 Remote 契约
服务通过 `ctx.storageDomain` 在 `message_feedback` 存储域中保存完整 Session 行。`put` 提交引用目标消息的伴随记录前,身份匹配的 live 目标先经过权威 `ctx.sessions.flush` checkpoint随后 live 与 cold 路径都会通过 `SessionPersistence.readFrom` 从序列零做物理复读。写入伴随记录前会再次校验所得观测,因此目标日志的持久提交始终先于其伴随记录。`maxNoteBytes` 为必填项,按 UTF-8 字节限制备注文本Web Host 组合将其设为 `8192`。该包通过 `GatewayService` 与 `@Remote` 发布 Host `messageFeedback.list`、`messageFeedback.put` 和 `messageFeedback.delete` 一元 Remote 契约;下方生成的 Cordis surface 是方法级权威。
Plugin disposal 会先关闭变更接纳,排空已进入各 Session 队列的工作,然后才关闭 storage domain。
## 边界与限制
- 客户端 Remote 聚合挂载与 UI 消费方由各自边界负责并保持延后。
- 变更队列仅在进程内生效。storage-domain 没有跨进程条件写,因此多个 Host 写入同一存储根目录时,不提供 compare-and-swap 或防止丢失更新的保证。
- Session persistence 没有持久删除接口。服务不把 `session/disposed` 或 `host/session-removed` 当作删除,因此不伪造级联;在带外移除日志后,孤儿伴随记录可能继续存在。
- 请求若恰好落在 live detach 之后、persistence catalog 物化 header 之前的极短窗口,可能收到 `session-not-found`;调用方应在 retirement materialization 后重试。
- 由于 persistence 没有按 id 读取元数据的操作cold 请求会扫描完整的 Session snapshot 目录。单个 Session 行也没有条目数或聚合字节上限;在具体消费方拥有行策略之前,`maxNoteBytes` 只限制每条备注。
- 只有 `{createdAt, cwd}` 不同时header 身份才能识别复用的 id本契约无法区分保留相同 header 身份的克隆日志。
- Host 契约不记录已认证的 actor 或审计身份,因此假设调用方边界可信。
<!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
<a id="cordis-surface"></a>
## Cordis surface
Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — this section is byte-identical in both language sides of the page. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` surface lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
<a id="ctxmessagefeedback--messagefeedbackservice"></a>
### `ctx.messageFeedback` — `MessageFeedbackService`
Storage-domain sidecar service. It inspects persisted Session history and never creates or resumes an Agent or Session.
```ts cordis-catalog
/**
* Read feedback belonging to the current persisted Session lifecycle.
* A stale row from a reused Session id is invisible.
* @param request - Session identity to inspect and list.
* @returns current immutable items or `session-not-found`.
*/
@Remote('list') async list(request: MessageFeedbackListRequest): Promise<MessageFeedbackListResult>
/**
* Create or replace feedback for one derived append-origin assistant
* message. Every request must match the addressed item's current version;
* a matching no-op returns the stored item without changing its revision.
* @param request - target, desired value, and observed item version.
* @returns the committed item or an explicit business failure.
*/
@Remote('put') put(request: MessageFeedbackPutRequest): Promise<MessageFeedbackPutResult>
/**
* Delete one feedback item. Absence is successful regardless of the
* supplied version; an existing item requires an exact version match.
* @param request - Session, message, and observed item version.
* @returns the stable absent postcondition, or an explicit failure.
*/
@Remote('delete') delete(request: MessageFeedbackDeleteRequest): Promise<MessageFeedbackDeleteResult>
```
Source: [`packages/feedback/message-feedback/src/index.ts:150`](../../packages/feedback/message-feedback/src/index.ts)
<!-- END GENERATED cordis-surface -->

View File

@@ -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 docs/subsystems/llm-streaming.md
llm-streaming.md: 8ae4e8b376b4c4221e6179eb719fcf162f3031e4
llm-streaming.zh.md: 7d244ab882521a90217873fc3cdee12cd5232db8
llm-streaming.md: 17f984166906914c49b2c330bdf57b3cecdbd013
llm-streaming.zh.md: 6519710dad8a174418bcc97f1bc4b36296ab969e

View File

@@ -234,7 +234,7 @@ interface AppIdentity {
product: string
/** Product version; sourced from package metadata, never hand-copied. */
version: string
/** Public home URL of the app, used as the `User-Agent` comment. */
/** Repository home URL of the app, used as the `User-Agent` comment. */
url: string
}
```

View File

@@ -238,7 +238,7 @@ interface AppIdentity {
product: string
/** Product version; sourced from package metadata, never hand-copied. */
version: string
/** Public home URL of the app, used as the `User-Agent` comment. */
/** Repository home URL of the app, used as the `User-Agent` comment. */
url: string
}
```

View File

@@ -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 docs/subsystems/subagent.md
subagent.md: 42359215b2e21028e13734c2a4cd2488f86a07af
subagent.zh.md: 0d1d4c42fa774867679ff248bfc99b0024b04257
subagent.md: cf728d9f15fdaaf8199954e91b564167e8efe439
subagent.zh.md: 1a8e2e5837b8ac88f7d7b7ca767fb7aa21391a9f

View File

@@ -390,7 +390,10 @@ Each provider is a named child-agent transport, and multiple providers may coexi
/**
* One registered transport for running child agents. Providers are trusted
* same-process implementations; callers treat descriptors and returned values
* as borrowed immutable data.
* as borrowed immutable data. The service may call one provider concurrently
* for distinct children. Providers isolate operation-local mutable state; a
* shared capacity controller may delay an operation but must not couple its
* settlement or cleanup to a sibling.
*/
interface SubagentProvider {
/** Unique registry name (e.g. `spawn`, `fork`, `acp`). */
@@ -411,7 +414,8 @@ interface SubagentProvider {
* initial turn. Before fulfillment, the provider owns setup and cleans any
* unpublished partial resources before rejecting. Ownership transfers on
* fulfillment; subsequent turn or infrastructure failure settles through
* the returned run.
* the returned run. Distinct starts may overlap; cancellation, failure,
* result settlement, and disposal remain independent for each run.
*/
start(request: ResolvedSubagentStartRequest): Promise<SubagentRun>
/**
@@ -426,6 +430,8 @@ interface SubagentProvider {
* continuation manager owns identity reservation, composition, Agent
* creation, prompt delivery, cold resume, ownership, and disposal, so a
* provider never sees the child's Agent, handle, turns, or teardown.
* Distinct preparations may overlap; each follows its own signal and returns
* data belonging only to `request.sessionId`.
*/
prepareContinuable?(request: ContinuableCreateRequest): Promise<ContinuableCreateSpec>
}

View File

@@ -392,7 +392,10 @@ interface SubagentRun {
/**
* One registered transport for running child agents. Providers are trusted
* same-process implementations; callers treat descriptors and returned values
* as borrowed immutable data.
* as borrowed immutable data. The service may call one provider concurrently
* for distinct children. Providers isolate operation-local mutable state; a
* shared capacity controller may delay an operation but must not couple its
* settlement or cleanup to a sibling.
*/
interface SubagentProvider {
/** Unique registry name (e.g. `spawn`, `fork`, `acp`). */
@@ -413,7 +416,8 @@ interface SubagentProvider {
* initial turn. Before fulfillment, the provider owns setup and cleans any
* unpublished partial resources before rejecting. Ownership transfers on
* fulfillment; subsequent turn or infrastructure failure settles through
* the returned run.
* the returned run. Distinct starts may overlap; cancellation, failure,
* result settlement, and disposal remain independent for each run.
*/
start(request: ResolvedSubagentStartRequest): Promise<SubagentRun>
/**
@@ -428,6 +432,8 @@ interface SubagentProvider {
* continuation manager owns identity reservation, composition, Agent
* creation, prompt delivery, cold resume, ownership, and disposal, so a
* provider never sees the child's Agent, handle, turns, or teardown.
* Distinct preparations may overlap; each follows its own signal and returns
* data belonging only to `request.sessionId`.
*/
prepareContinuable?(request: ContinuableCreateRequest): Promise<ContinuableCreateSpec>
}

View File

@@ -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 docs/user/guide/python-sdk.md
python-sdk.md: c48bc95c9334cfd16a925d12726c20b2f968c753
python-sdk.zh.md: dc31c391a180a742c7dc10807f6ed2ef8d11927d
python-sdk.md: 0713de6f96c110624d5f5a8f2ccf56dd4ce01096
python-sdk.zh.md: f8fa877b407a43c643fda405e1059fb487182761

View File

@@ -30,7 +30,7 @@ python -m pip install deepseek-harness-sdk
A source build additionally requires Git, Node.js ^22.19 or >= 24, Corepack-enabled pnpm 11, and `uv`. The following commands build the runtime for the current supported host platform, build both wheels, and install them into the active virtual environment:
```sh
git clone https://github.com/deepseek-ai/deepseek-harness-sdk.git deepseek-harness
git clone https://github.com/deepseek-ai/deepseek-harness.git deepseek-harness
cd deepseek-harness
python -m pip install uv==0.11.23
corepack enable

View File

@@ -30,7 +30,7 @@ python -m pip install deepseek-harness-sdk
从源码构建还需要 Git、Node.js ^22.19 或 >= 24、通过 Corepack 启用的 pnpm 11以及 `uv`。以下命令为当前受支持的宿主平台构建运行时和两个 wheel 包,并将它们安装进当前虚拟环境:
```sh
git clone https://github.com/deepseek-ai/deepseek-harness-sdk.git deepseek-harness
git clone https://github.com/deepseek-ai/deepseek-harness.git deepseek-harness
cd deepseek-harness
python -m pip install uv==0.11.23
corepack enable

View File

@@ -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 docs/user/guide/quickstart.md
quickstart.md: 635c0dffd6119f95c1951a441691f87f04396b4a
quickstart.zh.md: d0921382bcb0844fa0260c51546622c582867e68
quickstart.md: e93e5a430f0cb345728581cd6fa3175ffd20b7d1
quickstart.zh.md: 69cde830bb802ef19cc1204685395b957a0e02e3

View File

@@ -19,7 +19,7 @@ pnpm -v
## Step 1: install and configure the API key
```sh
git clone https://github.com/deepseek-ai/deepseek-harness-sdk.git
git clone https://github.com/deepseek-ai/deepseek-harness.git
cd deepseek-harness
pnpm install
```

View File

@@ -19,7 +19,7 @@ pnpm -v
## 第一步:安装并配置 API 密钥
```sh
git clone https://github.com/deepseek-ai/deepseek-harness-sdk.git
git clone https://github.com/deepseek-ai/deepseek-harness.git
cd deepseek-harness
pnpm install
```