docs(i18n): mirror the record refactor across the bilingual pairs
Chinese sides of the jobs, jobs-local, tool-bash, tool-pwsh, tool-workflow, session-controller, and ui-jobs pages follow their English edits; the generated en-only catalogs (config catalog, capability seams, event producer/consumer) get the same section surgery by hand; the activity subsystem page triplet is fully removed and the jobs page carries the record contract in both languages with fresh type-equiv manifest entries. The three prior activity notes point at the superseding note. Web e2e label assertions follow the ui-jobs copy, and the three test call sites that invoked run() bare pass the producer face.
This commit is contained in:
1 parent
0dca00b425
commit
3c79e71cdc
33 files changed
+214
-137
No files matched your search
+6
@@ -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 .agents/notes/implemented/architecture/2026-09-01-jobs-absorb-activity-record.md
|
||||
2026-09-01-jobs-absorb-activity-record.md: cc2cc8606a50e2d7c06e183a09df709b75b9bd35
|
||||
2026-09-01-jobs-absorb-activity-record.zh.md: 8b6739192b56899899773ba1e7af2bf1bd846b0b
|
||||
@@ -22,7 +22,7 @@ The one activity without a job was the foreground workflow mirror. Everything el
|
||||
- **`ui-activity` returns to its upstream name `ui-jobs`** and renders one roster: `jobsBySession` rows, expandable exactly when `outputTotal` is present. The two-roster join is deleted.
|
||||
- **Foreground workflow loses its live panel deliberately.** `tool-workflow`'s activity mirror is removed; a foreground run surfaces through its recorded run/member lifecycle events only, and the per-line `workflow/phase` / `workflow/log` narration has no observer until workflow gains `run_in_background` and registers a record job. Jobs stay a pure background registry — no `foreground` mode bit, no model-invisible rows, no run-less rows.
|
||||
|
||||
## Rejected
|
||||
## Alternatives considered
|
||||
|
||||
- **A `foreground: true` job mode** to keep the foreground workflow panel: it needs two coupled enforcement points (reported-at-birth and a `job_list` filter) whose divergence double-delivers or leaks rows to the model, for one edge feature replaceable by `run_in_background`.
|
||||
- **Serving model reads from the record** (deleting `readOutput`): model reads are producer-formatted (truncation and spill notices, sandbox markers) and consuming; the record is raw, channel-labeled, and non-consuming. Unifying them moves producer-specific formatting into the registry or noise into the observer stream.
|
||||
|
||||
@@ -22,7 +22,7 @@ Status: implemented
|
||||
- **`ui-activity` 改回上游名字 `ui-jobs`**,渲染单一名册:`jobsBySession` 行,恰在 `outputTotal` 存在时可展开。双名册 join 被删除。
|
||||
- **前台 workflow 有意失去实时面板。** `tool-workflow` 的 activity 镜像被移除;前台 run 只通过已记录的 run/member 生命周期事件呈现,逐行的 `workflow/phase` / `workflow/log` 叙述在 workflow 获得 `run_in_background` 并登记 record job 之前没有观察者。jobs 保持纯后台注册表——没有 `foreground` 模式位、没有模型不可见行、没有无 run 行。
|
||||
|
||||
## 已否决
|
||||
## 曾考虑的替代方案
|
||||
|
||||
- **`foreground: true` job 模式**以保留前台 workflow 面板:它需要两个耦合的执行点(出生即 reported 与 `job_list` 过滤),两者一旦分叉就会双投递或向模型泄漏行,而它换来的只是一个可被 `run_in_background` 替代的边缘特性。
|
||||
- **用 record 服务模型读取**(删除 `readOutput`):模型读取是生产者格式化的(截断与 spill 提示、sandbox 标记)且消耗型;record 是原始、带 channel 标签、非消耗的。统一二者要么把生产者特有格式化搬进注册表,要么把噪声混入观察者流。
|
||||
|
||||
@@ -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 .agents/notes/implemented/feature/2026-08-08-web-background-job-display.md
|
||||
2026-08-08-web-background-job-display.md: 23074b5d38cdab8c45925c75a7d0b851f7be2ece
|
||||
2026-08-08-web-background-job-display.zh.md: 06645267ee8afadf284b7654b0cd4a672fe7e4b4
|
||||
2026-08-08-web-background-job-display.md: 3dd003c0e972ec7a5857e84980520eee93b53955
|
||||
2026-08-08-web-background-job-display.zh.md: 5d1ee4bada9c1966e4329d35f5a4db64300ca3b4
|
||||
@@ -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 .agents/notes/implemented/feature/2026-08-24-activity-observation-seam.md
|
||||
2026-08-24-activity-observation-seam.md: 88109cb3404132885bde359af0907a29ea1bee2c
|
||||
2026-08-24-activity-observation-seam.zh.md: b8aa938edfd0019794211975c616aa50381ffe77
|
||||
2026-08-24-activity-observation-seam.md: 29ee08b1bb7f72a63d2f84278af62587060de3fe
|
||||
2026-08-24-activity-observation-seam.zh.md: 97ac4f195c83cdd4f16d2f0a108abd2b3338d95d
|
||||
@@ -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 .agents/notes/implemented/feature/2026-08-25-unified-task-list.md
|
||||
2026-08-25-unified-task-list.md: e67ca84d96424e723f6a5660cbb2b02733e42892
|
||||
2026-08-25-unified-task-list.zh.md: 2a71b04ec33b635478bd4897e8777abb3081a8df
|
||||
2026-08-25-unified-task-list.md: daf6582bf2c9e4b4a5ce26d6ae632fb78b30dbcb
|
||||
2026-08-25-unified-task-list.zh.md: 624747396e175a216047239333575322ec4b1808
|
||||
@@ -80,7 +80,7 @@ describe.skipIf(MODE === 'record')('web e2e: background job list', () => {
|
||||
it('shows a running background job in the session header without a refresh', async () => {
|
||||
onTestFailed(() => saveFailureShot(page, 'web-e2e-background-job-running'))
|
||||
// Polling for zero would pass at t=0 before delivery and prove nothing.
|
||||
const trigger = page.getByRole('button', { name: '1 task running' })
|
||||
const trigger = page.getByRole('button', { name: '1 background job running' })
|
||||
expect(await trigger.count()).toBe(0)
|
||||
|
||||
const started = await scaffold.ctx.tools.execute({
|
||||
@@ -97,7 +97,7 @@ describe.skipIf(MODE === 'record')('web e2e: background job list', () => {
|
||||
|
||||
await trigger.waitFor({ timeout: 15_000 })
|
||||
await trigger.click()
|
||||
const row = page.getByRole('list', { name: 'Tasks' }).getByRole('listitem').first()
|
||||
const row = page.getByRole('list', { name: 'Background jobs' }).getByRole('listitem').first()
|
||||
await row.waitFor({ timeout: 10_000 })
|
||||
await expect.poll(() => row.textContent()).toContain(COMMAND)
|
||||
|
||||
@@ -111,7 +111,7 @@ describe.skipIf(MODE === 'record')('web e2e: background job list', () => {
|
||||
onTestFailed(() => saveFailureShot(page, 'web-e2e-background-job-settled'))
|
||||
expect(scaffold.ctx.jobs.kill(jobId, agent, 'web e2e cancellation')).toBe('requested')
|
||||
|
||||
const idle = page.getByRole('button', { name: '1 task' })
|
||||
const idle = page.getByRole('button', { name: '1 background job' })
|
||||
await idle.waitFor({ timeout: 20_000 })
|
||||
|
||||
const snapshot = await captureStableAria(page, '[class*="menu"]', scaffold.workspaceCwd)
|
||||
|
||||
@@ -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: 8a2f9b772c6c50aed0389421fd26a713668b1907
|
||||
architecture.zh.md: cc291fb0184bcc62a283741ff453e62d7400eb0a
|
||||
architecture.md: f36c956d9a14f6b4490d2cd5ce03d807da4a94ad
|
||||
architecture.zh.md: 67e2ae905cdf0ddb210f320fd7b8cb34395d99d4
|
||||
@@ -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: 6c0867eeb8d47fefcbbf270e79123935cdae2aa3
|
||||
capability-seams.zh.md: aa741f96303e0dbf5f883c2fb4a2af927e165f63
|
||||
capability-seams.md: db2b8db95647204b4a49a63c6a7f1d97b942e635
|
||||
capability-seams.zh.md: f145241760737654c39662c76ddd027cf22bc409
|
||||
@@ -47,8 +47,6 @@ flowchart LR
|
||||
pkg_api_workspace_controller["api-workspace-controller"]
|
||||
svc_workspaceController["ctx.workspaceController<br/>Host Workspace Remote controller"]
|
||||
svc_directoryPickerController["ctx.directoryPickerController<br/>Host directory-picking Remote controller"]
|
||||
pkg_api_activity_controller["api-activity-controller"]
|
||||
svc_activityController["ctx.activityController<br/>Host Activity Remote controller"]
|
||||
svc_invariants["ctx.invariants<br/>Package-owned invariant registry"]
|
||||
pkg_scope["scope"]
|
||||
pkg_typert_registry["typert-registry"]
|
||||
@@ -188,11 +186,6 @@ flowchart LR
|
||||
svc_jobs["ctx.jobs<br/>Background job registry"]
|
||||
pkg_jobs_local["jobs-local"]
|
||||
pkg_tool_jobs["tool-jobs"]
|
||||
pkg_activity["activity"]
|
||||
svc_activities["ctx.activities<br/>Live activity observation registry"]
|
||||
pkg_activity_local["activity-local"]
|
||||
pkg_tool_workflow["tool-workflow"]
|
||||
pkg_activity_controller["activity-controller"]
|
||||
pkg_web["web"]
|
||||
svc_web["ctx.web<br/>Web access provider registry"]
|
||||
pkg_web_search_exa["web-search-exa"]
|
||||
@@ -216,6 +209,7 @@ flowchart LR
|
||||
pkg_workflow["workflow"]
|
||||
svc_workflowEngine["ctx.workflowEngine<br/>Workflow script engine"]
|
||||
pkg_workflow_worker_thread["workflow-worker-thread"]
|
||||
pkg_tool_workflow["tool-workflow"]
|
||||
pkg_webhook["webhook"]
|
||||
svc_webhookRuntime["ctx.webhookRuntime<br/>Webhook rule runtime"]
|
||||
pkg_webhook_github["webhook-github"]
|
||||
@@ -225,13 +219,10 @@ flowchart LR
|
||||
pkg_cordis_host_runner["cordis-host-runner"]
|
||||
svc_dynamicCordisRunner["ctx.dynamicCordisRunner<br/>Dynamic Cordis package host runner"]
|
||||
svc_cordisInspect["ctx.cordisInspect<br/>Dynamic Cordis inspect registry"]
|
||||
pkg_activity --> svc_activities
|
||||
pkg_activity_local --> svc_activities
|
||||
pkg_agent --> svc_agents
|
||||
pkg_agent_default_model --> svc_agentDefaultModel
|
||||
pkg_agent_loop --> svc_agentLoop
|
||||
pkg_agent_presets --> svc_agentPresets
|
||||
pkg_api_activity_controller --> svc_activityController
|
||||
pkg_api_gateway --> svc_typertGateway
|
||||
pkg_api_session_controller --> svc_sessionController
|
||||
pkg_api_session_controller --> svc_sessionFileReferences
|
||||
@@ -344,10 +335,6 @@ flowchart LR
|
||||
pkg_workflow --> svc_workflowEngine
|
||||
pkg_workflow_worker_thread --> svc_workflowEngine
|
||||
pkg_workspace --> svc_workspaceRegistry
|
||||
svc_activities --> pkg_activity_controller
|
||||
svc_activities --> pkg_tool_bash
|
||||
svc_activities --> pkg_tool_pwsh
|
||||
svc_activities --> pkg_tool_workflow
|
||||
svc_agentDefaultModel --> pkg_api_session_controller
|
||||
svc_agentDefaultModel --> pkg_headless
|
||||
svc_agentLoop --> pkg_agent_spine_demo
|
||||
@@ -384,6 +371,7 @@ flowchart LR
|
||||
svc_invariants --> pkg_session
|
||||
svc_jobs --> pkg_tool_bash
|
||||
svc_jobs --> pkg_tool_jobs
|
||||
svc_jobs --> pkg_tool_pwsh
|
||||
svc_jobs --> pkg_tool_subagent
|
||||
svc_jobs --> pkg_tool_terminal
|
||||
svc_llm --> pkg_agent_loop
|
||||
@@ -491,7 +479,6 @@ flowchart LR
|
||||
| `ctx.settingsController` | `core` | [`api-settings-controller`](../packages/api/settings-controller) | - | - | - | 把用户设置 seam 投影到生成的 Remote namespace:读取一律脱敏,所有拒绝在这里分类,而不在 seam Definition 上。 |
|
||||
| `ctx.workspaceController` | `core` | [`api-workspace-controller`](../packages/api/workspace-controller) | - | - | - | 通过生成的 Remote namespace 负责 Workspace 命令和可在重连后收敛的 Workspace 状态投递。 |
|
||||
| `ctx.directoryPickerController` | `core` | [`api-workspace-controller`](../packages/api/workspace-controller) | - | - | - | 把选目录 seam 送上线:能力门禁、取消传播,以及浏览器目录流程用于分支判断的 seam 错误码。 |
|
||||
| `ctx.activityController` | `core` | [`api-activity-controller`](../packages/api/activity-controller) | - | - | - | 通过生成的 Remote namespace 负责实时活动 roster 流与逐活动的非消费输出观察。 |
|
||||
| `ctx.invariants` | `core` | [`invariants`](../packages/runtime-diagnostics/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 载体提供一元调用。 |
|
||||
@@ -537,8 +524,7 @@ flowchart LR
|
||||
| `ctx.subagents` | `seam` | [`subagent`](../packages/subagent/subagent) | [`subagent-spawn-in-process`](../packages/subagent/subagent-spawn-in-process), [`subagent-fork-in-process`](../packages/subagent/subagent-fork-in-process), [`subagent-acp`](../packages/subagent/subagent-acp), [`subagent-codex`](../packages/subagent/subagent-codex), [`subagent-claude-code`](../packages/subagent/subagent-claude-code), [`subagent-dsh-sdk`](../packages/subagent/subagent-dsh-sdk) | [`tool-subagent`](../packages/subagent/tool-subagent), [`tool-subagent-control`](../packages/subagent/tool-subagent-control), [`tool-ralph`](../packages/workflow/tool-ralph) | - | 提供方实现传输;该服务还负责可选的、基于 Activation 的延续编排,tool-subagent 选择一次性或可延续委派,tool-subagent-control 传递后续消息,而 tool-ralph 要求一条全新的结构化输出路由。 |
|
||||
| `ctx.agentTeams` | `core` | [`experimental-agent-team`](../packages/experimental/agent-team) | - | [`experimental-tool-agent-team`](../packages/experimental/tool-agent-team), [`experimental-client-ui-agent-team`](../packages/experimental/client-ui-agent-team) | - | 负责隐式 Root roster、持久 peer mailbox、共享任务 DAG、continuable child 生命周期与生成式 Team Remote method;tool-agent-team 提供模型控制工具,client-ui-agent-team 挂载浏览器 contribution。 |
|
||||
| `ctx.inspector` | `core` | `inspector` | - | - | - | 负责 Worker 托管的 CDP target,以及独立于传输的 Host 和 Client observation 与 Cordis tree query API。 |
|
||||
| `ctx.jobs` | `seam` | [`jobs`](../packages/jobs/jobs) | [`jobs-local`](../packages/jobs/jobs-local) | [`tool-bash`](../packages/shell/tool-bash), [`tool-terminal`](../packages/terminal/tool-terminal), [`tool-subagent`](../packages/subagent/tool-subagent), [`tool-jobs`](../packages/jobs/tool-jobs) | - | 生产方(后台 bash、PTY 发送和 subagent 委派)登记正在运行的工作;tool-jobs 是面向模型的控制器,用于读取、列出和终止这些工作;jobs-local 是进程本地注册表。 |
|
||||
| `ctx.activities` | `seam` | [`activity`](../packages/activity/activity) | [`activity-local`](../packages/activity/activity-local) | [`tool-bash`](../packages/shell/tool-bash), [`tool-pwsh`](../packages/shell/tool-pwsh), [`tool-workflow`](../packages/workflow/tool-workflow), `activity-controller` | - | 生产者把实时输出与状态镜像进非消费的偏移寻址流;activity-controller 把它们提供给浏览器,模型可见路径(jobs 游标、工具结果)保持不动。 |
|
||||
| `ctx.jobs` | `seam` | [`jobs`](../packages/jobs/jobs) | [`jobs-local`](../packages/jobs/jobs-local) | [`tool-bash`](../packages/shell/tool-bash), [`tool-pwsh`](../packages/shell/tool-pwsh), [`tool-terminal`](../packages/terminal/tool-terminal), [`tool-subagent`](../packages/subagent/tool-subagent), [`tool-jobs`](../packages/jobs/tool-jobs) | - | 生产方(后台 bash/pwsh、PTY 发送和 subagent 委派)登记正在运行的工作;声明 record 的 job 还为非消费观察者流式提供原始输出;tool-jobs 是面向模型的控制器,用于读取、列出和终止这些工作;jobs-local 是进程本地注册表。 |
|
||||
| `ctx.web` | `seam` | [`web`](../packages/web/web) | [`web-search-exa`](../packages/web/web-search-exa), [`web-search-perplexity`](../packages/web/web-search-perplexity), [`web-search-deepseek`](../packages/web/web-search-deepseek), [`web-fetch-http`](../packages/web/web-fetch-http) | [`tool-web`](../packages/web/tool-web) | - | 搜索和抓取提供方注册到同一个 ctx.web seam;tool-web 负责稳定的面向模型名称。 |
|
||||
| `ctx.spillStore` | `seam` | [`spill`](../packages/spill/spill) | [`spill-local`](../packages/spill/spill-local) | [`spill-policy`](../packages/spill/spill-policy) | - | 后端保存过大的工具文本,并返回面向模型的定位信息和取回提示;spill-policy 是 tools/post-execute 消费方,负责决定何时 spill。 |
|
||||
| `ctx.directoryPicker` | `seam` | [`host-directory-picker`](../packages/host/directory-picker) | [`host-directory-picker-native`](../packages/host/directory-picker-native), [`host-directory-picker-browse`](../packages/host/directory-picker-browse) | [`api-workspace-controller`](../packages/api/workspace-controller) | - | 带判别标记的交互能力:原生后端在 Host 显示设备上打开一个操作系统选择器,浏览后端为应用内浏览器提供列表与创建原语;双端后端通过其浏览器侧填充 ui-workspace 目录流程的 slot(不通过协议发布)。 |
|
||||
|
||||
@@ -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: 424eff1c5e6e4ab96687e0688280cfc20cd31729
|
||||
config-catalog.zh.md: 9591737dbf8593edb594ccc3373ab8354a2201aa
|
||||
config-catalog.md: 64b72e0ff774bd7ecd6142a1ee1f0663e28194b7
|
||||
config-catalog.zh.md: ab2c0aac8f341e5855299236787421f4b60d357a
|
||||
+17
-44
@@ -35,22 +35,6 @@ export interface AcpConfig {
|
||||
|
||||
来源:[`packages/acp/acp/src/index.ts:75`](../packages/acp/acp/src/index.ts)
|
||||
|
||||
<a id="deepseek-aidsh-activity-local"></a>
|
||||
|
||||
## `@deepseek-ai/dsh-activity-local`
|
||||
|
||||
```ts config-catalog
|
||||
/** Configuration for the process-local observation registry. */
|
||||
export interface Config {
|
||||
/** Live output retention per activity in UTF-8 bytes; omission defaults to 262144. */
|
||||
retainBytes?: number
|
||||
/** Output retention kept after an activity settles, in UTF-8 bytes; omission defaults to 16384. */
|
||||
settledRetainBytes?: number
|
||||
}
|
||||
```
|
||||
|
||||
来源:[`packages/activity/activity-local/src/index.ts:31`](../packages/activity/activity-local/src/index.ts)
|
||||
|
||||
<a id="deepseek-aidsh-agent-default-model"></a>
|
||||
|
||||
## `@deepseek-ai/dsh-agent-default-model`
|
||||
@@ -294,24 +278,6 @@ export interface Config {
|
||||
|
||||
来源:[`packages/core/agent-tool-presentation/src/index.ts:38`](../packages/core/agent-tool-presentation/src/index.ts)
|
||||
|
||||
<a id="deepseek-aidsh-api-activity-controller"></a>
|
||||
|
||||
## `@deepseek-ai/dsh-api-activity-controller`
|
||||
|
||||
Requires: `typert`
|
||||
|
||||
```ts config-catalog
|
||||
/** Configuration for the Activity Remote owner. */
|
||||
export interface Config {
|
||||
/** Coalescing window after new output before an observation read, in milliseconds (default 100). */
|
||||
flushMs?: number
|
||||
/** Soft byte budget per observation output frame (default 65536); one larger chunk ships whole. */
|
||||
maxFrameBytes?: number
|
||||
}
|
||||
```
|
||||
|
||||
来源:[`packages/api/activity-controller/src/index.ts:26`](../packages/api/activity-controller/src/index.ts)
|
||||
|
||||
<a id="deepseek-aidsh-api-gateway"></a>
|
||||
|
||||
## `@deepseek-ai/dsh-api-gateway`
|
||||
@@ -341,10 +307,14 @@ export interface Config {
|
||||
readonly coldBlankProbeMaxBytes?: number
|
||||
/** Override platform desktop-opener detection. */
|
||||
readonly nativeOpen?: boolean
|
||||
/** Coalescing window after new record output before a job-observation read, in milliseconds (default 100). */
|
||||
readonly observeFlushMs?: number
|
||||
/** Soft byte budget per job-observation output frame (default 65536); one larger chunk ships whole. */
|
||||
readonly observeMaxFrameBytes?: number
|
||||
}
|
||||
```
|
||||
|
||||
来源:[`packages/api/session-controller/src/index.ts:67`](../packages/api/session-controller/src/index.ts)
|
||||
来源:[`packages/api/session-controller/src/index.ts:77`](../packages/api/session-controller/src/index.ts)
|
||||
|
||||
<a id="deepseek-aidsh-api-settings-controller"></a>
|
||||
|
||||
@@ -990,10 +960,14 @@ export interface Config {
|
||||
* omission defaults to 10.
|
||||
*/
|
||||
maxConcurrentJobsPerOwner?: number
|
||||
/** Live record retention per job in UTF-8 bytes; omission defaults to 262144. */
|
||||
retainBytes?: number
|
||||
/** Record retention kept after a job settles, in UTF-8 bytes; omission defaults to 16384. */
|
||||
settledRetainBytes?: number
|
||||
}
|
||||
```
|
||||
|
||||
来源:[`packages/jobs/jobs-local/src/index.ts:31`](../packages/jobs/jobs-local/src/index.ts)
|
||||
来源:[`packages/jobs/jobs-local/src/index.ts:38`](../packages/jobs/jobs-local/src/index.ts)
|
||||
|
||||
<a id="deepseek-aidsh-llm-deepseek"></a>
|
||||
|
||||
@@ -2714,12 +2688,12 @@ export type TokenMeterConfig = Record<string, never>
|
||||
export interface Config {
|
||||
/** Expose `run_in_background` (default true); disabled calls are also rejected. */
|
||||
enableRunInBackground?: boolean
|
||||
/** Poll cadence for mirroring background output into `ctx.activities`, in milliseconds (default 150). */
|
||||
activityPollMs?: number
|
||||
/** Poll cadence for copying background output into the job record, in milliseconds (default 150). */
|
||||
recordPollMs?: number
|
||||
}
|
||||
```
|
||||
|
||||
来源:[`packages/shell/tool-bash/src/index.ts:33`](../packages/shell/tool-bash/src/index.ts)
|
||||
来源:[`packages/shell/tool-bash/src/index.ts:34`](../packages/shell/tool-bash/src/index.ts)
|
||||
|
||||
<a id="deepseek-aidsh-tool-bash-persistent"></a>
|
||||
|
||||
@@ -2881,12 +2855,12 @@ export interface Config {
|
||||
export interface Config {
|
||||
/** Expose `run_in_background` (default true); disabled calls are also rejected. */
|
||||
enableRunInBackground?: boolean
|
||||
/** Poll cadence for mirroring background output into `ctx.activities`, in milliseconds (default 150). */
|
||||
activityPollMs?: number
|
||||
/** Poll cadence for copying background output into the job record, in milliseconds (default 150). */
|
||||
recordPollMs?: number
|
||||
}
|
||||
```
|
||||
|
||||
来源:[`packages/shell/tool-pwsh/src/index.ts:51`](../packages/shell/tool-pwsh/src/index.ts)
|
||||
来源:[`packages/shell/tool-pwsh/src/index.ts:53`](../packages/shell/tool-pwsh/src/index.ts)
|
||||
|
||||
<a id="deepseek-aidsh-tool-pwsh-persistent"></a>
|
||||
|
||||
@@ -3456,7 +3430,6 @@ export interface Config {
|
||||
- `@deepseek-ai/dsh-authorization` — 需要 `credentials`([`packages/credentials/authorization/src/index.ts`](../packages/credentials/authorization/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-locale`([`packages/client/locale/src/index.ts`](../packages/client/locale/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-modules` — 需要 `webServer` · `loader`([`packages/client/modules/src/index.ts`](../packages/client/modules/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-activity`([`packages/client/ui-activity/src/index.ts`](../packages/client/ui-activity/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-agent-preset`([`packages/client/ui-agent-preset/src/index.ts`](../packages/client/ui-agent-preset/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-approval`([`packages/client/ui-approval/src/index.ts`](../packages/client/ui-approval/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-attachment`([`packages/client/ui-attachment/src/index.ts`](../packages/client/ui-attachment/src/index.ts))
|
||||
@@ -3470,6 +3443,7 @@ export interface Config {
|
||||
- `@deepseek-ai/dsh-client-ui-directory-picker-native`([`packages/client/ui-directory-picker-native/src/index.ts`](../packages/client/ui-directory-picker-native/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-goal`([`packages/client/ui-goal/src/index.ts`](../packages/client/ui-goal/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-input-trigger`([`packages/client/ui-input-trigger/src/index.ts`](../packages/client/ui-input-trigger/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-jobs`([`packages/client/ui-jobs/src/index.ts`](../packages/client/ui-jobs/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-message-feedback`([`packages/client/ui-message-feedback/src/index.ts`](../packages/client/ui-message-feedback/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-model-selection`([`packages/client/ui-model-selection/src/index.ts`](../packages/client/ui-model-selection/src/index.ts))
|
||||
@@ -3530,7 +3504,6 @@ export interface Config {
|
||||
|
||||
抽象服务类——部署时应改为加载具体的实现包(参见[能力 seam](../.agents/notes/implemented/architecture/2026-06-13-capability-seams.zh.md))。
|
||||
|
||||
- `@deepseek-ai/dsh-activity` — 抽象 `ActivityRegistry`([`packages/activity/activity/src/index.ts`](../packages/activity/activity/src/index.ts))
|
||||
- `@deepseek-ai/dsh-attachment` — 抽象 `AttachmentStore`([`packages/attachment/attachment/src/index.ts`](../packages/attachment/attachment/src/index.ts))
|
||||
- `@deepseek-ai/dsh-code-runtime` — 抽象 `CodeRuntime`([`packages/code-runtime/code-runtime/src/index.ts`](../packages/code-runtime/code-runtime/src/index.ts))
|
||||
- `@deepseek-ai/dsh-compaction` — 抽象 `CompactionEngine`([`packages/compaction/compaction/src/index.ts`](../packages/compaction/compaction/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 docs/event-producer-consumer.md
|
||||
event-producer-consumer.md: 48aacf9dc6ece2431402ab72c171d236ed3b1359
|
||||
event-producer-consumer.zh.md: f644336b2cf540e28a88e2a6729508586021d46f
|
||||
event-producer-consumer.md: fc05e2ec6ba8d3d5cfc409a617ee069759c93c08
|
||||
event-producer-consumer.zh.md: 42e79d5469f2b56e119b34b7dac63b8b590ff145
|
||||
@@ -23,11 +23,11 @@
|
||||
| `agent/session-start` | `emit` | [`packages/core/agent/src/runtime-types.ts:224`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emitAgentEvent`) | `agent-team`, [`goal`](../packages/goal/goal), [`goal-round-driver`](../packages/goal/goal-round-driver), [`hooks-claude-code`](../packages/hooks/hooks-claude-code), [`hooks-codex`](../packages/hooks/hooks-codex) |
|
||||
| `agent/status` | `emit` | [`packages/core/agent/src/runtime-types.ts:185`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`agent`](../packages/core/agent), `agent-team`, [`compaction-basic`](../packages/compaction/compaction-basic), [`goal-round-driver`](../packages/goal/goal-round-driver), [`schedule`](../packages/schedule/schedule), `server`, `session-controller` |
|
||||
| `agent/turn-stopping` | `serial` | [`packages/core/agent/src/runtime-types.ts:285`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`serial`) | [`hooks-claude-code`](../packages/hooks/hooks-claude-code), [`hooks-codex`](../packages/hooks/hooks-codex) |
|
||||
| `api-session/activity` | `emit` | [`packages/api/session-controller/src/types.ts:523`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
|
||||
| `api-session/added` | `emit` | [`packages/api/session-controller/src/types.ts:503`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
|
||||
| `api-session/error` | `emit` | [`packages/api/session-controller/src/types.ts:530`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
|
||||
| `api-session/removed` | `emit` | [`packages/api/session-controller/src/types.ts:509`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
|
||||
| `api-session/status` | `emit` | [`packages/api/session-controller/src/types.ts:516`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
|
||||
| `api-session/activity` | `emit` | [`packages/api/session-controller/src/types.ts:586`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
|
||||
| `api-session/added` | `emit` | [`packages/api/session-controller/src/types.ts:566`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
|
||||
| `api-session/error` | `emit` | [`packages/api/session-controller/src/types.ts:593`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
|
||||
| `api-session/removed` | `emit` | [`packages/api/session-controller/src/types.ts:572`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
|
||||
| `api-session/status` | `emit` | [`packages/api/session-controller/src/types.ts:579`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
|
||||
| `approval/request` | `waterfall` | [`packages/interaction/user-approval/src/types.ts:85`](../packages/interaction/user-approval/src/types.ts) | [`user-approval`](../packages/interaction/user-approval) (`waterfall`) | [`acp`](../packages/acp/acp), `remotes` |
|
||||
| `authorization/settled` | `emit` | [`packages/credentials/authorization/src/index.ts:57`](../packages/credentials/authorization/src/index.ts) | [`authorization`](../packages/credentials/authorization) (`events.dispatch`) | [`authorization`](../packages/credentials/authorization) |
|
||||
| `commands/change` | `emit` | [`packages/interaction/commands/src/types.ts:80`](../packages/interaction/commands/src/types.ts) | [`commands`](../packages/interaction/commands) (`events.dispatch`) | `remotes` |
|
||||
@@ -71,8 +71,8 @@
|
||||
| `workflow/agent-end` | `emit` | [`packages/workflow/workflow/src/index.ts:79`](../packages/workflow/workflow/src/index.ts) | [`workflow`](../packages/workflow/workflow) (`events.dispatch`) | [`tool-workflow`](../packages/workflow/tool-workflow), [`workflow`](../packages/workflow/workflow) |
|
||||
| `workflow/agent-start` | `emit` | [`packages/workflow/workflow/src/index.ts:68`](../packages/workflow/workflow/src/index.ts) | [`workflow`](../packages/workflow/workflow) (`events.dispatch`) | [`tool-workflow`](../packages/workflow/tool-workflow), [`workflow`](../packages/workflow/workflow) |
|
||||
| `workflow/end` | `emit` | [`packages/workflow/workflow/src/index.ts:89`](../packages/workflow/workflow/src/index.ts) | [`workflow`](../packages/workflow/workflow) (`events.dispatch`) | [`workflow`](../packages/workflow/workflow) |
|
||||
| `workflow/log` | `emit` | [`packages/workflow/workflow/src/index.ts:58`](../packages/workflow/workflow/src/index.ts) | [`workflow`](../packages/workflow/workflow) (`events.dispatch`) | [`tool-workflow`](../packages/workflow/tool-workflow) |
|
||||
| `workflow/phase` | `emit` | [`packages/workflow/workflow/src/index.ts:51`](../packages/workflow/workflow/src/index.ts) | [`workflow`](../packages/workflow/workflow) (`events.dispatch`) | [`tool-workflow`](../packages/workflow/tool-workflow) |
|
||||
| `workflow/log` | `emit` | [`packages/workflow/workflow/src/index.ts:58`](../packages/workflow/workflow/src/index.ts) | [`workflow`](../packages/workflow/workflow) (`events.dispatch`) | - |
|
||||
| `workflow/phase` | `emit` | [`packages/workflow/workflow/src/index.ts:51`](../packages/workflow/workflow/src/index.ts) | [`workflow`](../packages/workflow/workflow) (`events.dispatch`) | - |
|
||||
| `workflow/start` | `emit` | [`packages/workflow/workflow/src/index.ts:43`](../packages/workflow/workflow/src/index.ts) | [`workflow`](../packages/workflow/workflow) (`events.dispatch`) | [`workflow`](../packages/workflow/workflow) |
|
||||
|
||||
## 包源码中出现的非 harness 或未声明事件字符串
|
||||
|
||||
@@ -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: d75bd368d5976813133bb8f62b1b5295bfb32b7c
|
||||
README.zh.md: 589a72d81fd4e7d277b31626f896b41dc0ea1eb2
|
||||
README.md: f3340ebeb426fe9cc5c4570b3c8a3440cc1682ec
|
||||
README.zh.md: 2e4523f03d1a942d9f93abf34ad2cc8687b413b8
|
||||
@@ -1,6 +0,0 @@
|
||||
# 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/activity.md
|
||||
activity.md: 000bdc30be05eb17d670367df3fd214e7d0af7f3
|
||||
activity.zh.md: 1fc79e9d596351a1f818ea83c15d1b5082689b79
|
||||
@@ -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/jobs.md
|
||||
jobs.md: 092da7b6f7e10c5713d3d6c9c5c46f925084f86a
|
||||
jobs.zh.md: 9dc390eb30901664edb47c6727a54ddd83839fa7
|
||||
jobs.md: 1b8e58f27be9e7198063960d436e61502c4f7e3b
|
||||
jobs.zh.md: 0a1d04fcaf0ea0ceadcb457c756f0962e47eca34
|
||||
+104
-10
@@ -23,7 +23,7 @@ interface JobKindMap {
|
||||
|
||||
## 生产方约定
|
||||
|
||||
`JobStart` 声明身份和启动器。运行时会在调用 `run()` 前完成预检,随后提交注册,不再执行可能失败的步骤。生产方拥有执行资源;运行时拥有身份、访问权限和生命周期状态。
|
||||
`JobStart` 声明身份和启动器。运行时会在完成预检后携带该 job 的生产者面调用 `run()`,随后提交注册,不再执行可能失败的步骤。生产方拥有执行资源;运行时拥有身份、访问权限和生命周期状态。
|
||||
|
||||
```ts type-equiv
|
||||
/**
|
||||
@@ -38,7 +38,9 @@ interface JobStart {
|
||||
label: string
|
||||
/**
|
||||
* Optional UTF-8 byte cap for each complete model-facing completion notice or
|
||||
* output read, including controller status metadata.
|
||||
* output read, including controller status metadata. Independent of record
|
||||
* retention: it bounds the consuming model surface, never
|
||||
* {@link JobRegistry.readRecord}.
|
||||
*/
|
||||
outputLimitBytes?: number
|
||||
/**
|
||||
@@ -49,11 +51,22 @@ interface JobStart {
|
||||
*/
|
||||
owner?: Agent
|
||||
/**
|
||||
* Start the work after preflight and synchronously return its hooks. Called
|
||||
* once; a throw leaves nothing registered, and the producer must clean up any
|
||||
* partially started resources.
|
||||
* Declares an observable output record beside the model-facing surfaces:
|
||||
* {@link RunningJob.append} retains chunks in a bounded ring that any number
|
||||
* of observers read at absolute byte offsets through
|
||||
* {@link JobRegistry.readRecord}, and snapshots carry
|
||||
* {@link JobSnapshot.outputTotal} and {@link JobSnapshot.outputEarliest}.
|
||||
* Without the declaration `append` logs and drops.
|
||||
*/
|
||||
run(): JobHooks
|
||||
record?: true
|
||||
/**
|
||||
* Start the work after preflight and synchronously return its hooks. Called
|
||||
* once with the job's producer face; a throw leaves nothing registered (the
|
||||
* spent ordinal is skipped), and the producer must clean up any partially
|
||||
* started resources.
|
||||
* @param job - the issued id plus the record append and live-detail writers.
|
||||
*/
|
||||
run(job: RunningJob): JobHooks
|
||||
}
|
||||
```
|
||||
|
||||
@@ -71,13 +84,16 @@ interface JobHooks {
|
||||
* Resolves after the producer releases its resources, not merely when work
|
||||
* finishes. Must not reject; the runtime converts a rejection to `failed`.
|
||||
* If teardown cancellation throws, the runtime may force-fail only the
|
||||
* registry record without claiming that the work stopped.
|
||||
* registry record without claiming that the work stopped. Settlement also
|
||||
* ends the record: fold any record-filling pump into this promise so the
|
||||
* final drain lands before the registry trims and closes the stream.
|
||||
*/
|
||||
done: Promise<JobOutcome>
|
||||
/**
|
||||
* Consume output produced since the previous call. The producer formats
|
||||
* truncation and spill notices. Absence marks a final-output-only job; each
|
||||
* job has one consuming cursor.
|
||||
* job has one consuming cursor. Independent of the record: this is the
|
||||
* model-facing projection, {@link JobRegistry.readRecord} the observer one.
|
||||
*/
|
||||
readOutput?(): string
|
||||
}
|
||||
@@ -95,6 +111,70 @@ interface JobOutcome {
|
||||
}
|
||||
```
|
||||
|
||||
## 观测 record
|
||||
|
||||
声明 `record: true` 的生产方通过 starter 收到的 `RunningJob` 面把原始输出流入按 job 划分的有界环形缓冲;任意数量的观察者通过 `readRecord` 按绝对字节偏移读取保留块,不触碰消耗型的模型游标与通知状态。job 结算即封流并把保留量裁剪到结算上限——record 没有独立生命周期。`pumpJobOutput` 以有界节奏把生产方的偏移读取器(subprocess 的 `readFrom` 家族)复制进 record。
|
||||
|
||||
```ts type-equiv
|
||||
/**
|
||||
* Producer face of one registered job, handed to {@link JobStart.run} and
|
||||
* valid for the job's whole life. All methods are synchronous. Writes staged
|
||||
* inside the starter call are retained and become visible with the
|
||||
* registration commit; after settlement — the producer's own outcome, a kill,
|
||||
* or a registry-forced teardown end — both methods log and drop instead of
|
||||
* throwing, so a producer's trailing flush cannot break its own teardown path.
|
||||
*/
|
||||
interface RunningJob {
|
||||
/** The registry-issued id (`<kind>-N`). */
|
||||
readonly id: JobId
|
||||
/**
|
||||
* Append one record chunk. Offsets advance by the chunk's UTF-8 byte
|
||||
* length; an empty chunk is dropped without waking observers. Without a
|
||||
* {@link JobStart.record} declaration the chunk is logged and dropped.
|
||||
* @param text - the chunk text, exactly as produced.
|
||||
* @param options - stream label and gap marker.
|
||||
*/
|
||||
append(text: string, options?: JobAppendOptions): void
|
||||
/**
|
||||
* Replace the snapshot's status detail with a live progress line (`3/10`).
|
||||
* Works for every job, with or without a record.
|
||||
* @param detail - the new detail line.
|
||||
*/
|
||||
updateDetail(detail: string): void
|
||||
}
|
||||
```
|
||||
|
||||
```ts type-equiv
|
||||
/** One retained record chunk returned by {@link JobRegistry.readRecord}. */
|
||||
interface JobRecordChunk {
|
||||
/** Absolute offset of the chunk's first byte. */
|
||||
at: number
|
||||
/** Chunk text exactly as appended (possibly tail-trimmed by retention). */
|
||||
text: string
|
||||
/** Stream label, when the producer supplied one. */
|
||||
channel?: JobChannel
|
||||
/** Producer-reported loss immediately before this chunk. */
|
||||
gapBefore?: true
|
||||
}
|
||||
```
|
||||
|
||||
```ts type-equiv
|
||||
/** Result of one non-consuming {@link JobRegistry.readRecord}. */
|
||||
interface JobRecordRead {
|
||||
/** Retained chunks overlapping `[from, total)`, in offset order. */
|
||||
chunks: readonly JobRecordChunk[]
|
||||
/**
|
||||
* Offset to resume from — the record's current `outputTotal`. Always a
|
||||
* chunk boundary: appends land whole and trimming only advances chunk
|
||||
* starts, and consumers concatenate `chunks` under that assumption, so a
|
||||
* provider serving partial chunks would silently duplicate text.
|
||||
*/
|
||||
next: number
|
||||
/** True when `from` fell below the oldest retained byte, so bytes are missing before `chunks`. */
|
||||
lossy: boolean
|
||||
}
|
||||
```
|
||||
|
||||
## 消费方视图
|
||||
|
||||
快照是每次新建的只读投影。`ownerSession` 携带用于授权的共享 `SessionId`;完成监听器则会另行收到用于生命周期清理的确切拥有者对象。另一个接口已经交付终止状态或承诺交付时,`reported` 会抑制完成通知;排空 owner 或服务的 teardown 取消同样计入。
|
||||
@@ -121,7 +201,10 @@ interface JobSnapshot {
|
||||
ownerSession?: SessionId
|
||||
/** Current lifecycle state. */
|
||||
status: JobStatus
|
||||
/** Kind-specific status detail, present once the producer supplied one (usually terminal). */
|
||||
/**
|
||||
* Kind-specific status detail: live progress while the producer updates it
|
||||
* through {@link RunningJob.updateDetail}, the terminal detail once settled.
|
||||
*/
|
||||
detail?: string
|
||||
/** Epoch ms when the job was registered. */
|
||||
startedAt: number
|
||||
@@ -135,6 +218,17 @@ interface JobSnapshot {
|
||||
* otherwise spend a model request per teardown layer.
|
||||
*/
|
||||
reported: boolean
|
||||
/**
|
||||
* Total UTF-8 bytes ever appended to the record — the offset the next chunk
|
||||
* starts at. Present exactly when the job declared {@link JobStart.record}.
|
||||
*/
|
||||
outputTotal?: number
|
||||
/**
|
||||
* Offset of the oldest retained record byte. Greater than zero exactly when
|
||||
* retention dropped the head; a reader starting below it gets a lossy read.
|
||||
* Present exactly when the job declared {@link JobStart.record}.
|
||||
*/
|
||||
outputEarliest?: number
|
||||
}
|
||||
```
|
||||
|
||||
@@ -154,7 +248,7 @@ interface JobRead {
|
||||
|
||||
## 服务行为
|
||||
|
||||
抽象的 [`JobRegistry`](../../packages/jobs/jobs/src/index.ts) Service Definition 规定原子 `start`、限定调用方作用域的 `get` 和 `list`、`read`、`kill`、有界 `wait`、故障隔离的 `onJobDone` 与 `onJobsChanged` 监听器,以及 `attachController`;[`LocalJobRegistry`](../../packages/jobs/jobs-local/src/index.ts) 是其进程局部 Service Provider。授权会比较拥有者会话;拥有者清理与准入会使用确切的已注册 `Agent` 实例。本地 Service Provider 的 `maxConcurrentJobsPerOwner` 配置必须是正的安全整数,默认值为 `10`;它按确切 owner 统计 `running` 与 `stopping` 记录,所有无 owner 任务共享一个服务级桶,并在生产方终止结算后释放容量。Service Definition 约定见 [`dsh-jobs`](../../packages/jobs/jobs/README.zh.md),注册表生命周期与准入策略见 [`dsh-jobs-local`](../../packages/jobs/jobs-local/README.zh.md),面向模型的 Consumer 见 [`dsh-tool-jobs`](../../packages/jobs/tool-jobs/README.zh.md)。
|
||||
抽象的 [`JobRegistry`](../../packages/jobs/jobs/src/index.ts) Service Definition 规定了原子化的 `start`、按调用方划定的 `get` 与 `list`、`read`、非消耗的 `readRecord`、`kill`、有界的 `wait`、故障隔离的 `onJobDone`、`onJobsChanged` 与 `onOutput` 监听器,以及 `attachController`;[`LocalJobRegistry`](../../packages/jobs/jobs-local/src/index.ts) 是进程本地的 Service Provider。授权比较 owner 会话;owner 清理与准入使用注册在案的确切 `Agent` 实例。本地 provider 的正安全整数配置 `maxConcurrentJobsPerOwner` 默认 `10`,按确切 owner 统计 `running` 加 `stopping` 记录,无主任务共享一个桶;生产方终态结算释放容量,`retainBytes`(默认 262144)与 `settledRetainBytes`(默认 16384)约束每个已声明 record 的运行期与结算后保留量。参见 [`dsh-jobs`](../../packages/jobs/jobs/README.zh.md)(Service Definition 契约)、[`dsh-jobs-local`](../../packages/jobs/jobs-local/README.zh.md)(注册表生命周期与准入策略)与 [`dsh-tool-jobs`](../../packages/jobs/tool-jobs/README.zh.md)(模型侧 Consumer)。
|
||||
|
||||
<!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
|
||||
|
||||
|
||||
@@ -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 packages/api/session-controller/README.md
|
||||
README.md: 2f2192cde2941019c9687738f8e3f5e50ddd6d8e
|
||||
README.zh.md: 273d304d3cd3bbcbadd3e40202d8d923f3a27498
|
||||
README.md: 2e5ca38bf51a1aca881e0a15b28f0b7856b51f73
|
||||
README.zh.md: e316aac4c07692720d1c6809d52bbe3ab06be033
|
||||
@@ -29,6 +29,8 @@ kind: "package-reference"
|
||||
|
||||
Client adapter 提供 `SessionEventStream`,即绑定到一个普通 Session 或 direct subagent address 的 Gateway `RemoteJournalStream`。它在读取首个 page 前打开 follow,只发布连续的 `replace`、`prepend` 和 `append` 变更,并通过 tail page 修复重连或 seq 缺口。普通 record 覆盖 `[event.seq, event.seq]`,packed row 覆盖 `[event.seq, event.seq + memberCount - 1]`。业务、persistence 或无法恢复的连续性错误会终止 stream,只有物理载体断开才触发自动恢复。`SessionControlStream` 是 Gateway `RemoteSnapshotStream`;每代都以完整的进程本地 baseline 开始,因此重连会替换 queue、jobs 和 projection 状态,而不会把瞬态值当作 durable event。
|
||||
|
||||
`SessionJob` 行恰在该 job 声明了观测 record 时携带 `outputTotal`,`session.observeJob` 从绝对字节偏移流式发送该 record——一个 `opened` 锚帧、聚合的 `output` 帧、最后一个终态 `status` 帧——围栏读取者由请求的 session 解析。record 读取是非消耗的:模型侧游标与完成通知状态永远观察不到它们。Client adapter 提供 `ctx.jobOutput`:按 job 引用计数的观测服务,任务列表 UI 渲染其累积视图;同一 job 的观察者共享一条流,重连时从模型游标续读。
|
||||
|
||||
Session 对象还承载本地提交回显:`session.beginSubmission` 在调用方序列化与 prompt 之前,同步把一条回显写入 `SessionSnapshot.pendingSubmissions`,会话 UI 因此能在点击提交的当帧显示消息。Session 根据当前运行状态与请求的投递模式推导每条回显的 `transcript`、`queued` 或 `steering` 位置,并在序列化期间保留该位置。prompt 的 `requestId` 是关联标识:Host 把它回显为 durable user source 的 `rpcId`,queue occurrence 也把它投影为 `SessionQueuedItem.rpcId`。回显在观察到其 durable event 或 queue occurrence 后延迟一个动画帧退休,该延迟保证替代内容就绪前回显仍可渲染;带标识的 prompt 失败或被放弃时立即退休,销毁时按 failed 退休;每次退休恰好触发一次注册的 `onRetire` 回调。回显只存在于 Client 内存;刷新与重连只从 durable event 重建会话。
|
||||
|
||||
-----
|
||||
@@ -40,6 +42,8 @@ Session 对象还承载本地提交回显:`session.beginSubmission` 在调用
|
||||
|---|---:|---|
|
||||
| `coldBlankProbeMaxBytes` | `1,024` | 可进行空白状态验证的冷 Session 工件最大物理大小;`0` 禁用探测 |
|
||||
| `nativeOpen` | 平台探测 | 是否能把 Session 工作区路径交给原生桌面打开器 |
|
||||
| `observeFlushMs` | `100` | 新 record 输出到一次 job 观测读取之间的聚合窗口,毫秒 |
|
||||
| `observeMaxFrameBytes` | `65,536` | 每个 job 观测输出帧的软字节预算;更大的单块整块发送 |
|
||||
|
||||
生成的[配置目录](../../../docs/config-catalog.zh.md#deepseek-aidsh-api-session-controller)是所有受支持字段及其 JSDoc 的完整来源。
|
||||
|
||||
|
||||
@@ -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 packages/client/README.md
|
||||
README.md: 3e45bac9b06e7006d955fc0cd8d600732e5f36ca
|
||||
README.zh.md: e624cd5f87c450655c04b348cc72345b9389b0bd
|
||||
README.md: 367a6d39ce1248b4246aa3e497093b5edb315fb0
|
||||
README.zh.md: 05a0143ce4eee253e1d94a1ff29e4c4f08da1274
|
||||
@@ -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 packages/jobs/jobs-local/README.md
|
||||
README.md: cfbda98ccf59bcd12e931350c708cc15b30ec54c
|
||||
README.zh.md: 07acfc3c75ef730328792ab1aa45197bfcd5c849
|
||||
README.md: 2da0a0b3399ce5a55b63cad491ab6ee48a2f8a90
|
||||
README.zh.md: cc362ad7935a91a564cca5a82228934bcc15077d
|
||||
@@ -9,7 +9,7 @@ kind: "package-reference"
|
||||
|
||||
## 概述
|
||||
|
||||
`dsh-jobs-local` 在 harness 进程内运行后台任务:工作会在 agent 继续推进的同时保持运行,拥有它的 agent 可以读取、等待、列出和取消它;同时挂载 `dsh-tool-jobs` 时,完成以会话内通知送达。它用内存记录实现 `dsh-jobs` 约定,并且只交出全新快照,从不交出实时状态。按所有者的并发上限(默认 10)约束一个 agent 同时处于运行或停止中的任务数量;任务会随 harness 进程终止而消失,无法跨重启持久。
|
||||
`dsh-jobs-local` 在 harness 进程内运行后台任务:工作会在 agent 继续推进的同时保持运行,拥有它的 agent 可以读取、等待、列出和取消它;同时挂载 `dsh-tool-jobs` 时,完成以会话内通知送达。它用内存记录实现 `dsh-jobs` 约定,并且只交出全新快照,从不交出实时状态。按所有者的并发上限(默认 10)约束一个 agent 同时处于运行或停止中的任务数量,声明了 record 的任务另持有一个有界的内存输出环(默认运行期 256 KiB、结算时裁剪到 16 KiB),供观察者按绝对偏移读取;任务会随 harness 进程终止而消失,无法跨重启持久。
|
||||
|
||||
## 目录
|
||||
|
||||
@@ -42,6 +42,8 @@ kind: "package-reference"
|
||||
| 字段 | 默认值 | 含义 |
|
||||
|---|---|---|
|
||||
| `maxConcurrentJobsPerOwner` | `10` | 每个精确所有者,或共享的无主桶中,`running` 加 `stopping` 任务的最大数量 |
|
||||
| `retainBytes` | `262144` | 每个任务 record 的运行期保留量,UTF-8 字节 |
|
||||
| `settledRetainBytes` | `16384` | 任务结算后保留的 record 量,UTF-8 字节 |
|
||||
|
||||
生成的[配置目录](../../../docs/config-catalog.zh.md#deepseek-aidsh-jobs-local)是每个受支持字段的穷尽式真源。
|
||||
|
||||
@@ -69,7 +71,8 @@ kind: "package-reference"
|
||||
|
||||
### 设计理念
|
||||
|
||||
- **内存记录,全新快照。** `LocalJobRegistry` 为每个任务保存一条 `TrackedTask`,每次调用都投影出新的只读快照;调用方永远不会拿到实时状态。
|
||||
- **内存记录、全新快照。** `LocalJobRegistry` 为每个任务保存一份 `TrackedTask`——生命周期状态加可选的 record 环——每次调用都投影新的只读快照或块副本;调用方永远拿不到实时状态。
|
||||
- **record 保留量有界。** 追加超出运行期上限时丢弃最老的保留块(单个超限块保留其 UTF-8 安全尾部);低于保留窗口的读取得到 lossy 结果而非错误,结算时裁剪到结算上限。
|
||||
- **按所有者分层,一个进程级注册表。** 控制器、完成监听器与变更观察者归档到注册方所在的 scope(`ScopedLayers`),读取把全局层与所有者的 scope 链求并集——因此某个 preset 的任务控制绝不会为自身组合未加载任何控制器的 agent 保持 `start()` 可用,一次结算也只会抵达其所有者所属组合注册的监听器。
|
||||
- **启动前先预检。** `start()` 在调用生产方之前检查控制器服务、spec 有效性、仍存活的所有权与容量,因此拒绝不会留下 job id 或执行资源;注册一旦提交,后续不再有可失败步骤。
|
||||
- **结算首次优先,完成最后。** 最早的终止结果只记录一次,释放等待方,并只通知监听器一次,各监听器故障单独隔离;完成在记录提交且可见集变更发布之后才宣布,因为报告方可能同步开启一个模型轮次。
|
||||
@@ -84,11 +87,11 @@ kind: "package-reference"
|
||||
|
||||
### scope 分层
|
||||
|
||||
`attachController`、`onJobDone` 与 `onJobsChanged` 注册到调用上下文所在的 scope 层。控制器问题(`servesOwner`)与监听器投递(`listenersFor`、`changedFor`)走同一条链:先是全局层,再沿所有者的链逐层。注册是无名 token,因此重复标签仍可独立释放。
|
||||
`attachController`、`onJobDone`、`onJobsChanged` 与 `onOutput` 注册到调用上下文所在的 scope 层。控制器问题(`servesOwner`)与监听器投递(`listenersFor`、`changedFor`、`outputFor`)走同一条链:先是全局层,再沿所有者的链逐层。注册是无名 token,因此重复标签仍可独立释放。
|
||||
|
||||
### 准入与结算
|
||||
|
||||
`activeTaskCount` 按精确所有者或共享无主桶统计权威记录。`settle` 在存在挂起等待方时把任务标为已报告,解析每个等待方,记录终止快照,宣布可见集变更,然后通知完成监听器。挂起的等待会在监听器运行前把任务标为已报告,因此完成报告方不会重复通知;销毁时的取消出于同样理由标记——面向正在被销毁的所有者的通知不会有人读到。
|
||||
`activeTaskCount` 按精确所有者或共享无主桶统计权威记录。`settle` 在存在挂起等待方时把任务标为已报告,把已声明的 record 裁剪到结算保留量,解析每个等待方,记录终止快照,宣布可见集变更与 record 的最终输出信号,然后通知完成监听器。挂起的等待会在监听器运行前把任务标为已报告,因此完成报告方不会重复通知;销毁时的取消出于同样理由标记——面向正在被销毁的所有者的通知不会有人读到。
|
||||
|
||||
### 销毁
|
||||
|
||||
|
||||
@@ -200,7 +200,7 @@ describe('LocalJobRegistry.start', () => {
|
||||
for (const job of live) ctx.jobs.start(job.spec)
|
||||
|
||||
const blocked = producer()
|
||||
const run = vi.fn(() => blocked.spec.run())
|
||||
const run = vi.fn((job: RunningJob) => blocked.spec.run(job))
|
||||
expect(() => ctx.jobs.start({ ...blocked.spec, run }))
|
||||
.toThrow('background job limit reached for this owner (limit: 10)')
|
||||
expect(run).not.toHaveBeenCalled()
|
||||
@@ -213,7 +213,7 @@ describe('LocalJobRegistry.start', () => {
|
||||
expect(ctx.jobs.start(first.spec)).toBe('bash-1')
|
||||
|
||||
const blocked = producer()
|
||||
const run = vi.fn(() => blocked.spec.run())
|
||||
const run = vi.fn((job: RunningJob) => blocked.spec.run(job))
|
||||
expect(() => ctx.jobs.start({ ...blocked.spec, run }))
|
||||
.toThrow('use job_kill to stop an unneeded job, wait for it to finish, then retry')
|
||||
expect(run).not.toHaveBeenCalled()
|
||||
@@ -658,7 +658,7 @@ describe('LocalJobRegistry owner isolation', () => {
|
||||
ctx.jobs.start(current.spec) // Attach the current owner's cleanup first.
|
||||
|
||||
const stale = producer({ owner: staleOwner })
|
||||
const staleRun = vi.fn(() => stale.spec.run())
|
||||
const staleRun = vi.fn((job: RunningJob) => stale.spec.run(job))
|
||||
expect(() => ctx.jobs.start({ ...stale.spec, run: staleRun }))
|
||||
.toThrow('is not the registered agent instance')
|
||||
expect(staleRun).not.toHaveBeenCalled()
|
||||
|
||||
@@ -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 packages/jobs/jobs/README.md
|
||||
README.md: 7625c3672d24edff908c7be01723e970bd44d1f7
|
||||
README.zh.md: d62953d325ad14479539ccb61fb51378d21e3b52
|
||||
README.md: 10c74af908f64c18616e3c1eb71f19a3cbbf4eb3
|
||||
README.zh.md: 1fc500311c58a538ebfc7fbd89886d9c12b96acd
|
||||
@@ -9,7 +9,7 @@ kind: "package-reference"
|
||||
|
||||
## 概述
|
||||
|
||||
`dsh-jobs` 让工具可以把长时间工作注册为后台任务:工作获得稳定的 `<kind>-N` id,在 agent 继续推进的同时保持运行,拥有它的 agent 可以随时读取输出、带超时等待或请求取消。任务属于启动它的 agent 会话,因此一个 agent 的工作永远不会被另一个 agent 看到;完成以会话内通知而非轮询的方式送达给拥有者。本包只提供约定:进程本地注册表位于 `dsh-jobs-local`,模型侧控制与完成通知位于 `dsh-tool-jobs`。加载一个实现才能获得后台任务;没有实现时 `ctx.jobs` 不存在,`start()` 无法运行。
|
||||
`dsh-jobs` 让工具可以把长时间工作注册为后台任务:工作获得稳定的 `<kind>-N` id,在 agent 继续推进的同时保持运行,拥有它的 agent 可以随时读取输出、带超时等待或请求取消。任务属于启动它的 agent 会话,因此一个 agent 的工作永远不会被另一个 agent 看到;完成以会话内通知而非轮询的方式送达给拥有者。生产方还可以声明按 job 划分的观测 record:一条追加式的有界输出流,任意数量的观察者(Web 客户端)按绝对字节偏移读取,不触碰模型侧的消耗型游标。本包只提供约定:进程本地注册表位于 `dsh-jobs-local`,模型侧控制与完成通知位于 `dsh-tool-jobs`。加载一个实现才能获得后台任务;没有实现时 `ctx.jobs` 不存在,`start()` 无法运行。
|
||||
|
||||
## 目录
|
||||
|
||||
@@ -31,6 +31,8 @@ kind: "package-reference"
|
||||
|
||||
生产方以 kind 和一行标签注册工作;注册表返回 `<kind>-N` id,例如 `bash-1`。拥有任务的任何一方都可以读取输出、列出任务、带超时等待结算或请求取消——每次调用都返回任务状态的全新快照,从 `running`、`stopping` 到终止态的 `completed`、`killed` 或 `failed`。任务结算时,拥有它的 agent 会通过 `dsh-tool-jobs` 转成会话内通知的完成监听器得到通知,因此无需轮询。生产方还可以附加可选的字节上限,让每次完整的模型侧输出读取或完成通知保持有界。
|
||||
|
||||
声明 `record: true` 的生产方还会通过 starter 收到的 `RunningJob` 面把原始输出流入该 job 的有界 record:观察者按绝对字节偏移读取保留块并在推进时收到信号,结束 job 的结算同时封流,`updateDetail` 把实时进度行发布进每个快照。record 对模型不可见:读取不消耗任何东西,也永不触碰通知状态。
|
||||
|
||||
### 归属边界
|
||||
|
||||
任务属于启动它的 agent 会话:其他 agent 无法读取或停止它。`bash-1` 这样的 id 可预测,因此这道隔离是授权,而非保密。没有所有者启动的任务对任何调用方开放,并持续到服务被释放为止。
|
||||
@@ -75,13 +77,14 @@ kind: "package-reference"
|
||||
| 文件 | 职责 |
|
||||
|---|---|
|
||||
| [`src/index.ts`](src/index.ts) | 插件入口:抽象 `JobRegistry` 服务及其约定 |
|
||||
| [`src/types.ts`](src/types.ts) | 共享词汇:`JobKindMap`、`JobStart`、`JobHooks`、`JobSnapshot`、监听器类型 |
|
||||
| [`src/types.ts`](src/types.ts) | 共享词汇:`JobKindMap`、`JobStart`、`JobHooks`、`RunningJob`、`JobSnapshot`、监听器类型 |
|
||||
| [`src/brand.ts`](src/brand.ts) | `JobId` 带类型标记的标识符,无需 agent 依赖即可导入 |
|
||||
| [`src/invariant.ts`](src/invariant.ts) | 不变式伴生插件:校验快照标识、状态、时间戳与所有者字段 |
|
||||
| [`src/pump.ts`](src/pump.ts) | `pumpJobOutput`:把生产方偏移读取器复制进 job record 的轮询泵 |
|
||||
| [`src/invariant.ts`](src/invariant.ts) | 不变式伴生插件:校验快照标识、状态、时间戳、所有者与 record 偏移字段 |
|
||||
|
||||
### 服务操作
|
||||
|
||||
每个操作都是已注册任务之上的薄投影:`get` 与 `list` 返回非消费式快照,`read` 推进唯一的流游标,`kill` 在改变状态前调用生产方取消,`wait` 阻塞至超时,`start()` 在调用生产方 `run()` 一次之前预检访问、校验与准入,同时拒绝任何没有已附加控制器服务的所有者;监听器按所有者粒度观察终止记录与可见集变化,`attachController` 把控制器可用性限定在其 effect 生命周期内。确切签名与行为见 [`src/index.ts`](src/index.ts) 的 JSDoc 与生成的 [`ctx.jobs` cordis 接口面](../../../docs/subsystems/jobs.zh.md)。
|
||||
每个操作都是已注册任务之上的薄投影:`get` 与 `list` 返回非消费式快照,`read` 推进唯一的流游标,`readRecord` 按绝对偏移读取保留的 record 块且不消耗任何东西,`kill` 在改变状态前调用生产方取消,`wait` 阻塞至超时,`start()` 在调用生产方 `run()` 一次之前预检访问、校验与准入,同时拒绝任何没有已附加控制器服务的所有者;监听器按所有者粒度观察终止记录、可见集变化与 record 推进,`attachController` 把控制器可用性限定在其 effect 生命周期内。确切签名与行为见 [`src/index.ts`](src/index.ts) 的 JSDoc 与生成的 [`ctx.jobs` cordis 接口面](../../../docs/subsystems/jobs.zh.md)。
|
||||
|
||||
</details>
|
||||
|
||||
@@ -118,7 +121,7 @@ kind: "package-reference"
|
||||
这些限制说明约定何时不合适。它们是当前包约束,不是任务积压。
|
||||
|
||||
- **约定是进程内的**——`JobStart.run()` 传入回调和确切的 `Agent` 对象;持久化或跨进程后端必须先重塑身份、重启、所有权与观察语义,才能实现此 seam。
|
||||
- **流输出只有一个消费游标**——它属于模型;独立观察者改用生产者镜像进去的非消费 [`dsh-activity`](../../activity/activity/README.zh.md) 观察面。
|
||||
- **流输出只有一个消费游标**——它属于模型;独立观察者改用非消耗的 `readRecord` 读取 job 声明的 record。
|
||||
- **前台工作无法转为后台**——生产方在启动前选择前台或后台。
|
||||
|
||||
<a id="dev-note"></a>
|
||||
|
||||
@@ -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 packages/shell/tool-bash/README.md
|
||||
README.md: 5e30ed598e894fc764e62366218f4e5ded0a7084
|
||||
README.zh.md: a62938a09f9a8ddd38094efca006932645d79d0d
|
||||
README.md: 39e894970a92f68e09edf7b8dd10e040ed602b43
|
||||
README.zh.md: 025fb536a5196f4103a3476ba7ae20d5a59bda39
|
||||
@@ -55,7 +55,7 @@ kind: "package-reference"
|
||||
|
||||
### 后台运行长时间命令
|
||||
|
||||
传入 `run_in_background: true` 会立即返回 job id,不应用超时;命令继续运行,agent 同时处理其他事情。agent 用 `job_output` 读取输出(除非 `wait: true`,否则非阻塞)、用 `job_list` 列出任务、用 `job_kill` 停止任务;完成的任务会在会话内通知拥有它的 agent。后台支持需要挂载通用任务运行时(`dsh-jobs-local`)及其控制工具(`dsh-tool-jobs`)。加载了可选的 `ctx.activities` 注册表时,已提交的后台运行还会被尽力镜像进去:一个与调用和 job 关联的 `bash` activity 以 `activityPollMs`(默认 150)的节奏泵送句柄的非消费 `observed` 读取器,使 Web 客户端在不触碰 job 游标的情况下流式看到实时输出;任何观察失败都被记录并吞掉。
|
||||
传入 `run_in_background: true` 会立即返回 job id,不应用超时;命令继续运行,agent 同时处理其他事情。agent 用 `job_output` 读取输出(除非 `wait: true`,否则非阻塞)、用 `job_list` 列出任务、用 `job_kill` 停止任务;完成的任务会在会话内通知拥有它的 agent。后台支持需要挂载通用任务运行时(`dsh-jobs-local`)及其控制工具(`dsh-tool-jobs`)。后台 job 声明观测 record:运行的非消费 `observed` 读取器以 `recordPollMs`(默认 150)的节奏泵入其中,使 Web 客户端在不触碰 job 消耗游标的情况下流式看到实时输出;泵失败会被记录并吞掉,job 继续运行。
|
||||
|
||||
### 沙箱执行与升权
|
||||
|
||||
|
||||
@@ -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 packages/shell/tool-pwsh/README.md
|
||||
README.md: 8ea7e6f1e20f9c61f34fdc730c5c0b18706a2865
|
||||
README.zh.md: 2d8d51209a2ea66650904f10df263dfa0614aae3
|
||||
README.md: cfd6af5fe08a5f996d49c4b12c80930c687834fd
|
||||
README.zh.md: 3b9a53047216d3ba80ca850f06bcf7a5c06bbfea
|
||||
@@ -9,7 +9,7 @@ kind: "package-reference"
|
||||
|
||||
## 概述
|
||||
|
||||
`dsh-tool-pwsh` 为 agent 提供 `pwsh` 工具,通过已挂载的 shell 执行器运行 PowerShell 命令——它是 `dsh-tool-bash` 的 Windows 对应物,逐调用镜像。每次调用都运行在全新 pwsh 进程中,因此状态不会保留;`run_in_background` 把长时间运行的命令变成后台任务。命令是 PowerShell 方言:原生 `C:\...` 路径与 `$env:NAME` 变量,不做方言翻译。每次调用都运行在受管 `DSH_*` 环境中;在沙箱执行器下,工具会教授并执行 Windows 特有的语言模式与命名管道约定。请与 `dsh-pwsh-local` 等 PowerShell 执行器以及 `dsh-shell-env` 插件一起挂载。加载了可选的 `ctx.activities` 注册表时,已提交的后台运行还会被尽力镜像为按 `activityPollMs`(默认 150)泵送的 `pwsh` activity,与 `dsh-tool-bash` 完全一致。
|
||||
`dsh-tool-pwsh` 为 agent 提供 `pwsh` 工具,通过已挂载的 shell 执行器运行 PowerShell 命令——它是 `dsh-tool-bash` 的 Windows 对应物,逐调用镜像。每次调用都运行在全新 pwsh 进程中,因此状态不会保留;`run_in_background` 把长时间运行的命令变成后台任务。命令是 PowerShell 方言:原生 `C:\...` 路径与 `$env:NAME` 变量,不做方言翻译。每次调用都运行在受管 `DSH_*` 环境中;在沙箱执行器下,工具会教授并执行 Windows 特有的语言模式与命名管道约定。请与 `dsh-pwsh-local` 等 PowerShell 执行器以及 `dsh-shell-env` 插件一起挂载。后台运行的 job 声明按 `recordPollMs`(默认 150)泵送的观测 record,与 `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 packages/workflow/tool-workflow/README.md
|
||||
README.md: a7096838da13f7f744bb1e6179a758d3dedc38a3
|
||||
README.zh.md: 254f498b4fe13397a035c97bfd7c708cde3415d7
|
||||
README.md: 2291b274a5cd52813266f4cb0e9276cd8019c4f8
|
||||
README.zh.md: d3009fa57d2ec2a16ed01c4926bb41066f1bbf2c
|
||||
@@ -68,7 +68,7 @@ kind: "package-reference"
|
||||
|
||||
对于根 transport 执行(`exec.parent` 缺省),工具会用四个 log-only 事件把运行投影到调用 Agent 的 Session:`start()` 返回后写 run-start,只记录 `run.id` 匹配的成员开始与结束,并且只在结果可用且 dispose 完全停稳后写 run-end。嵌套 transport 调用照常执行,但不写任何记录。任一次 Session append 首次失败后,本运行会停止后续记录并只告警一次,留下空记录或合法连续前缀,同时不改变工具结果和清理。包 invariant 会在冷加载与实时追加时拒绝重复 start、未配对成员、仍有开放成员的终点与 run-end 后更新,同时允许缺失终态后缀的连续前缀。
|
||||
|
||||
在持久记录之外,每个被记录的顶层运行还会被尽力镜像进可选的 `ctx.activities` 注册表,作为一个 `workflow` activity:原本无人消费的 `workflow/phase` 与 `workflow/log` 事件加上成员生命周期行流入其中,使 Web 客户端看到会话日志刻意不逐行携带的实时叙述。没有注册表、或镜像出现任何失败时,运行本身不受影响。
|
||||
引擎的 `workflow/phase` 与 `workflow/log` 事件在本工具没有逐行的持久或观察面:会话日志刻意只记录 run 与成员生命周期,Web transcript 由这些记录派生。
|
||||
|
||||
### 渲染意图
|
||||
|
||||
@@ -80,7 +80,6 @@ kind: "package-reference"
|
||||
|---|---|
|
||||
| [`src/index.ts`](src/index.ts) | 插件入口:工具注册、运行生命周期、记录器接线 |
|
||||
| [`src/types.ts`](src/types.ts) | 四个 log-only 记录事件 payload 及其 `SessionEventMap` 声明 |
|
||||
| [`src/activity.ts`](src/activity.ts) | 顶层运行的尽力 activity 镜像 |
|
||||
| [`src/invariant.ts`](src/invariant.ts) | 不变式伴生插件:持久工作流记录协议校验 |
|
||||
|
||||
</details>
|
||||
|
||||
@@ -1016,6 +1016,21 @@
|
||||
"symbol": "JobRead",
|
||||
"source": "packages/jobs/jobs/src/types.ts"
|
||||
},
|
||||
{
|
||||
"doc": "docs/subsystems/jobs.md",
|
||||
"symbol": "RunningJob",
|
||||
"source": "packages/jobs/jobs/src/types.ts"
|
||||
},
|
||||
{
|
||||
"doc": "docs/subsystems/jobs.md",
|
||||
"symbol": "JobRecordChunk",
|
||||
"source": "packages/jobs/jobs/src/types.ts"
|
||||
},
|
||||
{
|
||||
"doc": "docs/subsystems/jobs.md",
|
||||
"symbol": "JobRecordRead",
|
||||
"source": "packages/jobs/jobs/src/types.ts"
|
||||
},
|
||||
{
|
||||
"doc": "docs/subsystems/terminal.md",
|
||||
"symbol": "TerminalWaitReason",
|
||||
|
||||
Reference in new issue
Block a user