@deepseek-ai/dsh-cordis-host-runner 0.1.1-rc.2 → 0.1.2-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.i18n.yaml +2 -2
- package/README.md +109 -37
- package/README.zh.md +107 -39
- package/lib/index.js +1 -1
- package/lib/typert.host.js +215 -47
- package/lib/typert.remote-client.d.ts +2 -1
- package/lib/typert.remote-client.js +5 -5
- package/lib/types/index.d.ts +1 -1
- package/lib/types/inspect-registry.d.ts +1 -1
- package/lib/types/inspect-registry.js +1 -1
- package/lib/types/types.d.ts +2 -1
- package/package.json +22 -21
package/README.i18n.yaml
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
3
|
# after editing either side, bring the other along and re-record with:
|
|
4
4
|
# pnpm run verify-translation-pairing --write packages/extensions/cordis-host-runner/README.md
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: ec229d225955718977679b00db522ddcf4a3035e
|
|
6
|
+
README.zh.md: 862746798e355d9f5c53fad2b8c69be4d73db3eb
|
package/README.md
CHANGED
|
@@ -1,72 +1,144 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Host half of dynamic Cordis packages for agents and maintainers choosing, composing, or debugging the registry, sandbox, and run round trip."
|
|
3
|
+
kind: "package-reference"
|
|
4
|
+
---
|
|
5
|
+
|
|
1
6
|
# @deepseek-ai/dsh-cordis-host-runner
|
|
2
7
|
|
|
3
8
|
English | [中文](README.zh.md)
|
|
4
9
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
## What it does
|
|
8
|
-
|
|
9
|
-
Two phases: `define` only records, and everything with an effect hangs off a run.
|
|
10
|
-
|
|
11
|
-
- `define` / `undefine` own a definition's life. `define` trims and requires the metadata, prechecks each half's syntax by compiling it (running nothing), mints `dyn-<n>`, and records the definition against the session that asked — it has no effect to roll back, so unparseable code is refused before an id exists. `undefine` stops a running definition first, then forgets it. Neither crosses the wire: only the model's own tool call defines.
|
|
12
|
-
- `run` answers the model's request to run one definition, and its two shapes differ by whose business the package is. A host-only package is this process's own: the host half is evaluated in the vm under the `cordis-dynamic` group fiber and the call returns. A package with a browser half has to be carried out by a page, so `run` becomes an answerable round trip — it emits `cordis/request-run`, suspends, and is settled by a person allowing or declining it. There is no timer; the caller's `AbortSignal` (the asking turn was cancelled) is the only other way out, and it announces the cancellation so other pages stop offering an answer. Whether any page will answer is not knowable when the request is sent — a page that received it may still never answer, so a deployment with no page connected suspends like any other unanswered request and ends in `cancelled`. `run` has no wire face — `cordis_run` calls it in process.
|
|
13
|
-
- `runHostHalf` / `getClientCode` are the steps an allowed page walks, host half first, so a host-half failure short-circuits before the browser has moved. `runHostHalf` is idempotent by contract: a running package is bound rather than evaluated again, concurrent calls for one definition evaluate it once, and `startedHere` names the caller that did. `getClientCode` then hands that one page the browser-half source, refusing a definition that is gone, has no browser half, or is not running. Code never rides an announcement, so this is the only way it reaches a browser.
|
|
14
|
-
- `resolveRequestRun` closes the round trip with the answering page's verdict, and broadcasts `cordis/request-run-resolved` so every other page drops the pending affordance. The first answer wins; a later or unknown request id is accepted and ignored. A success naming a revision the registry has moved past is refused rather than applied (`accepted: false`, request still suspended), because the page that answered loaded a dispatch that is no longer live. A failing verdict unwinds the host half only when this same request evaluated it, so a page that cannot load its own half never stops a package the other pages are using.
|
|
15
|
-
- `stop` unwinds one live dispatch — handlers dropped, host-half fiber disposed to quiescence, `dynamicCordisRunner/retract` broadcast — and leaves the definition runnable.
|
|
16
|
-
- `inventory` answers the whole registry, unaddressed by session and with each row naming the session that owns it, because the run-control surface is global. Listing is not acting: every acting verb still checks that ownership. Each row also names whether the definition has a browser half, so a run-control surface offers loading it into the current page only when there is a half to load. `snapshot` is its session-scoped host-local counterpart, carrying each live host half's fiber so `cordis_inspect` can render provides/waiting/state itself (a fiber cannot cross the wire).
|
|
17
|
-
- `reportRenderFailure` records what a page saw a LOADED browser half do wrong at render time. Rendering happens strictly after a load succeeded, so a run has already answered `ok` by then: this report is fire-and-forget, carries no settle authority, and never touches `resolveRequestRun` or any part of the run outcome — **it is not the retired v2 `report`/ack**. The host keeps the last failure per definition across every page (a second page reporting overwrites), and a fresh run, a stop, or an undefine clears it, so the model is never shown a failure from a dispatch that no longer exists. The browser-half face keeps its own "what THIS page is showing now"; the two answer different questions rather than duplicating one. A report for a definition the reporting session does not own is dropped, because the reporting path must never fail a render.
|
|
18
|
-
- `invoke` routes one call from a package's browser half to a method its own host half registered with `harness.handle`. The infrastructure only routes — no host-to-browser direction exists.
|
|
10
|
+
## Summary
|
|
19
11
|
|
|
20
|
-
|
|
12
|
+
`dsh-cordis-host-runner` makes dynamic packages runnable in this process: definitions the model records with `cordis_define` stay here, host halves run in a `node:vm` sandbox, a package with a browser half waits for a person to approve or decline it on a page, and the model can inspect the live runtime and its definitions here. The model-facing tools live in `@deepseek-ai/dsh-tool-cordis`, and the browser half loads through `@deepseek-ai/dsh-cordis-client-runner`. Definitions live only in process memory, so a DSH restart clears them and nothing is written to disk. One config field, `vmTimeoutMs`, bounds synchronous sandbox evaluation.
|
|
21
13
|
|
|
22
|
-
|
|
14
|
+
## Table of Contents
|
|
23
15
|
|
|
24
|
-
|
|
16
|
+
- [Use this package](#use-this-package)
|
|
17
|
+
- [Understand the implementation](#understand-the-implementation)
|
|
18
|
+
- [Further Exploration](#further-exploration)
|
|
19
|
+
- [Model Experience](#model-experience)
|
|
20
|
+
- [Known Limitations and Deferred Work](#known-limitations-and-deferred-work)
|
|
21
|
+
- [Dev Note](#dev-note)
|
|
25
22
|
|
|
26
|
-
|
|
23
|
+
-----
|
|
27
24
|
|
|
28
|
-
|
|
25
|
+
<a id="use-this-package"></a>
|
|
26
|
+
## Use this package
|
|
29
27
|
|
|
30
|
-
|
|
28
|
+
Mount this plugin in any composition that should support dynamic packages — it powers the model's `cordis_*` tools, and packages with a browser half additionally need the client runner plus the UI package composed on the client side. The common path is explicit: load this package, optionally set `vmTimeoutMs`, and let the tools and the browser do the rest.
|
|
31
29
|
|
|
32
|
-
|
|
30
|
+
### Minimal configuration
|
|
33
31
|
|
|
34
|
-
|
|
32
|
+
```yaml
|
|
33
|
+
- name: '@deepseek-ai/dsh-cordis-host-runner'
|
|
34
|
+
config:
|
|
35
|
+
vmTimeoutMs: 5000
|
|
36
|
+
```
|
|
35
37
|
|
|
36
38
|
| Field | Default | Meaning |
|
|
37
39
|
|---|---|---|
|
|
38
40
|
| `vmTimeoutMs` | `5000` | Milliseconds the synchronous portion of a host half may run in the vm before evaluation is aborted |
|
|
39
41
|
|
|
40
|
-
|
|
42
|
+
The generated [configuration catalog](../../../docs/config-catalog.md#deepseek-aidsh-cordis-host-runner) is the exhaustive source for every accepted field.
|
|
43
|
+
|
|
44
|
+
### What a run does
|
|
45
|
+
|
|
46
|
+
A definition is recorded by `cordis_define` and activated by `cordis_run`. A package with only a host half activates directly in this process: its code runs in the sandbox. A package with a browser half becomes a request: it waits until a person allows or declines it on a page, or the asking turn is cancelled; the answering page then loads the host half first and the browser half second. `mode: "run"` starts the current package or restarts it, `mode: "update"` switches to a different package version. `cordis_stop` ends the live run — removing the package's handlers and any loaded browser UI — while keeping the definition runnable; `cordis_undefine` stops and forgets it.
|
|
47
|
+
|
|
48
|
+
### What happens to definitions
|
|
49
|
+
|
|
50
|
+
Definitions are session-scoped and process-local: a package is visible only to the session that defined it, other sessions read it as absent, and everything disappears on DSH restart. The session log keeps the define call's arguments — including the code it submitted — and the receipt; only the in-memory registry holds the parsed definition. A browser half reaches a page only through a run, so a reloaded page holds nothing until someone runs the package again.
|
|
51
|
+
|
|
52
|
+
### Trust stance
|
|
53
|
+
|
|
54
|
+
The sandbox isolates globals but is not a security boundary: Node globals are absent or redirect to Cordis services (`ctx.fs`, `ctx.web`, `ctx.bash`, the timer helpers), and a host half receives a façade without framework internals, yet the services it declares reach the live runtime. Treat a dynamic package like bash access — see the [self-referential toolset Agent Note](../../../.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md).
|
|
55
|
+
|
|
56
|
+
-----
|
|
57
|
+
|
|
58
|
+
<a id="understand-the-implementation"></a>
|
|
59
|
+
## Understand the implementation
|
|
60
|
+
|
|
61
|
+
<details>
|
|
62
|
+
<summary>Implementation internals — click to expand</summary>
|
|
63
|
+
|
|
64
|
+
This section explains the design behind the runner; the observable behavior is fully covered in [Use this package](#use-this-package).
|
|
65
|
+
|
|
66
|
+
### Design philosophy
|
|
41
67
|
|
|
42
|
-
|
|
68
|
+
The runner is built on two separations. **Registry and sandbox are one service.** The `DynamicCordisRunnerService` owns the definition registry, the vm sandbox, the host-half fiber lifecycle, and the invoke handler table, so a definition's whole life has one owner. **Versions are immutable packages.** A plugin holds packages that never change after `define`; `currentPackageId` and `nextPackageId` point at the running and target versions, and `mode: "run"` versus `"update"` encodes whether the target equals the current version. The browser round trip exists because a browser half can only be carried out by a page: the service emits a request, suspends, and is settled by the page's verdict, with the caller's `AbortSignal` as the only other exit.
|
|
43
69
|
|
|
44
|
-
|
|
70
|
+
### Source map
|
|
45
71
|
|
|
72
|
+
| File | Role |
|
|
73
|
+
|---|---|
|
|
74
|
+
| [`src/index.ts`](src/index.ts) | Service entry: `Config`, registry wiring, lifecycle verbs, steer messages |
|
|
75
|
+
| [`src/registry.ts`](src/registry.ts) | Definition store: plugin and package identities, run attempts, approval requests |
|
|
76
|
+
| [`src/sandbox.ts`](src/sandbox.ts) | `node:vm` evaluation: globals, Node-API traps, define-time syntax precheck |
|
|
77
|
+
| [`src/guard.ts`](src/guard.ts) | Registration boundary: schema normalization, the sandbox `ctx` façade, plugin-shape checks |
|
|
78
|
+
| [`src/lifecycle.ts`](src/lifecycle.ts) | Starting a host half under the `cordis-dynamic` fiber group |
|
|
79
|
+
| [`src/inspect-registry.ts`](src/inspect-registry.ts) | The `ctx.cordisInspect` registry: host providers plus the mirrored client manifest |
|
|
80
|
+
| [`src/types.ts`](src/types.ts) | Client-safe payload shapes for the `dynamicCordisRunner` remote namespace and forwarded events |
|
|
81
|
+
|
|
82
|
+
### How a run flows
|
|
83
|
+
|
|
84
|
+
`define` trims and requires the metadata, prechecks each half's syntax by compiling it (running nothing), mints the plugin and package ids, and records the definition against the session that asked. `run` resolves the target against `currentPackageId` and `nextPackageId`; a host-only package evaluates in the sandbox and commits immediately, while a browser-half package arms an approval request, emits `cordis/request-run`, and suspends. The answering page walks `runHostHalf`, `getClientCode`, then `resolveRequestRun`; a success naming the live revision commits the activation and sets `currentPackageId`, and `cordis/request-run-resolved` drops the pending affordance on every other page. `stop` retracts the live dispatch — handler disposers, fiber dispose, and the `cordis/dynamic-retract` broadcast — and leaves the definition runnable. Four forwarded events (`cordis/request-run`, `cordis/request-run-resolved`, `cordis/dynamic-package`, `cordis/dynamic-retract`) are declared on the client-safe `./types` subpath and allowlisted for delivery by `@deepseek-ai/dsh-api-remotes`, which is what lets a browser reach them through `ctx.remote.$on`.
|
|
85
|
+
|
|
86
|
+
</details>
|
|
87
|
+
|
|
88
|
+
-----
|
|
89
|
+
|
|
90
|
+
<a id="further-exploration"></a>
|
|
91
|
+
## Further Exploration
|
|
92
|
+
|
|
93
|
+
Read these pages when the package-level contract is not enough. They move from the runner to the tools that call it, the browser half that answers it, and the generated surface.
|
|
94
|
+
|
|
95
|
+
- [Tool package](../tool-cordis/README.md) — the model-facing tools that call this service.
|
|
96
|
+
- [Client runner](../cordis-client-runner/README.md) — the browser half that answers run requests and loads browser-half code.
|
|
97
|
+
- [UI package](../ui-cordis/README.md) — the panel users approve and operate runs with.
|
|
98
|
+
- [Generated configuration catalog](../../../docs/config-catalog.md#deepseek-aidsh-cordis-host-runner) — every accepted config field.
|
|
99
|
+
- [Extensions subsystem](../../../docs/subsystems/extensions.md) — the generated `ctx.cordisInspect` and `ctx.dynamicCordisRunner` API and `cordis/*` events.
|
|
100
|
+
- [Self-referential Cordis toolset Agent Note](../../../.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md) — sandbox semantics, lifecycle, and composition rationale.
|
|
101
|
+
|
|
102
|
+
-----
|
|
103
|
+
|
|
104
|
+
<a id="model-experience"></a>
|
|
46
105
|
## Model Experience
|
|
47
106
|
|
|
48
|
-
###
|
|
107
|
+
### Run outcomes, refusals, and diagnostics relayed to the owning session
|
|
49
108
|
|
|
50
109
|
#### What the model sees
|
|
51
110
|
|
|
52
|
-
Nothing directly: this package registers no tool and injects no prompt.
|
|
111
|
+
Nothing directly: this package registers no tool and injects no prompt. It steers the owning session when a run settles — a success names the current package and says to continue, a user rejection says not to request the same activation again, and a technical failure names the reason, the version pointers, and the inspect-then-correct-and-update path. It also steers post-settle render failures (slot, whether the entry was removed), host guard rejections, and host handler failures. Panel stop and remove gestures inject a user-role message naming what the user did. Refusals from `run` or `stop` also reach the model through the calling tool's result.
|
|
53
112
|
|
|
54
113
|
#### Token effect
|
|
55
114
|
|
|
56
|
-
|
|
115
|
+
Conditional and data-dependent: messages arrive only when an event occurs, and each carries a bounded description of what happened; there is no fixed per-request cost.
|
|
57
116
|
|
|
58
117
|
#### KV Cache effect
|
|
59
118
|
|
|
60
|
-
A host half that registers tools changes the next request's tool view, which invalidates prefix reuse from the first changed schema token; running or stopping a package with no tool registrations is prefix-neutral.
|
|
119
|
+
None of its own. A host half that registers tools changes the next request's tool view, which invalidates prefix reuse from the first changed schema token; running or stopping a package with no tool registrations is prefix-neutral.
|
|
61
120
|
|
|
62
121
|
## Known Limitations and Deferred Work
|
|
63
122
|
|
|
64
|
-
|
|
123
|
+
<a id="known-limitations-and-deferred-work"></a>
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
These limits define when the runner needs special care. They are current package constraints, not a task backlog.
|
|
127
|
+
|
|
128
|
+
- **A successful run does not mean the UI rendered** — `run` returns once the answering page has loaded the browser half; React renders afterwards, so a component that throws cannot appear in the run receipt. The failure surfaces through steering and `cordis_inspect_self` diagnostics.
|
|
129
|
+
- **A browser-half package suspends where no page is connected** — headless and ACP deployments hold the run until the asking turn is cancelled; host-only packages are unaffected.
|
|
130
|
+
- **A suspended run request has no timeout** — it waits for a person until the asking turn is cancelled, so unattended automation cannot use packages with a browser half.
|
|
131
|
+
- **`vmTimeoutMs` bounds only synchronous evaluation** — an async host-half body escapes it, matching the toolset's cooperative trust stance.
|
|
132
|
+
- **A stale-success refusal leaves the request suspended** — when the answering page names a revision the registry has moved past, the resolution is refused (`accepted: false`) and the request stays answerable until another page answers or the caller cancels; the browser half does not read the acknowledgement.
|
|
133
|
+
- **The run announcement carries no service declarations** — a browser half's declared `inject` is read from the plugin it returns in the page, so `cordis/request-run` carries metadata only, never code or service lists.
|
|
134
|
+
- **`zod` is a runtime dependency of the generated Typert faces, not of `src`** — `./typert` and `./remote` resolve to unbundled `lib` files with a bare `import { z } from 'zod'`, so the package declares it even though nothing in `src` imports zod.
|
|
135
|
+
|
|
136
|
+
<a id="dev-note"></a>
|
|
137
|
+
### Dev Note
|
|
138
|
+
|
|
139
|
+
<details>
|
|
140
|
+
<summary>Working context for maintainers — click to expand</summary>
|
|
141
|
+
|
|
142
|
+
None.
|
|
65
143
|
|
|
66
|
-
|
|
67
|
-
- A suspended run request has **no timeout**: it waits for a person until the asking turn is cancelled, so unattended automation cannot use packages with a browser half.
|
|
68
|
-
- `vmTimeoutMs` bounds only synchronous evaluation; an async host-half body escapes it, matching the toolset's cooperative trust stance.
|
|
69
|
-
- `runHostHalf` carries no request id, so "which request evaluated this host half" is attributed host-side to the most recently armed request for that definition; several concurrent run requests for one definition would need that rule revisited.
|
|
70
|
-
- A success answer naming a superseded revision is refused (`accepted: false`) and leaves the request suspended, so the model's call ends only through a valid answer or its own cancellation. Settling it would take a fresh orchestration against the live revision, and no page does that today — the [browser half](../cordis-client-runner/README.md) does not read the ack — so in practice such a request is closed by another page's answer or by the caller's cancellation.
|
|
71
|
-
- A browser half's declared `inject` is read from the plugin it returns in the page, so the announcement carries no service-declaration field at all.
|
|
72
|
-
- **`zod` is a runtime dependency of the generated TypeRT faces, not of `src`.** `./typert` and `./remote` resolve to `lib/typert.*.js`, which `tsc` emits unbundled with a bare `import { z } from 'zod'`, so the package must declare it (the `@deepseek-ai/dsh-goal` precedent) and `knip.json` must ignore it for this workspace — knip reads source, and these faces are build products. Nothing in `src` imports zod.
|
|
144
|
+
</details>
|
package/README.zh.md
CHANGED
|
@@ -1,76 +1,144 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "动态 Cordis 包的 host 半说明,供选择、组合或排查注册表、沙箱与运行往返的 agent 与维护者阅读。"
|
|
3
|
+
kind: "package-reference"
|
|
4
|
+
---
|
|
5
|
+
|
|
1
6
|
# @deepseek-ai/dsh-cordis-host-runner
|
|
2
7
|
|
|
3
8
|
[English](README.md) | 中文
|
|
4
9
|
|
|
5
|
-
|
|
10
|
+
## 概述
|
|
6
11
|
|
|
7
|
-
|
|
12
|
+
`dsh-cordis-host-runner` 让动态包在本进程中可运行:模型用 `cordis_define` 记录的定义留在这里,host 半在 `node:vm` 沙箱中运行,带浏览器半的包会等待人在页面上批准或拒绝,模型也可以在这里检查实时运行时及其定义。面向模型的工具在 `@deepseek-ai/dsh-tool-cordis` 中,浏览器半经 `@deepseek-ai/dsh-cordis-client-runner` 装载。定义只存在于进程内存中,因此 DSH 重启即清空,也不会向磁盘写任何东西。唯一的配置字段 `vmTimeoutMs` 限制同步沙箱求值的时长。
|
|
8
13
|
|
|
9
|
-
|
|
14
|
+
## 目录
|
|
10
15
|
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
- `reportRenderFailure` 记录某个页面看到一个**已装载**的浏览器半在渲染时做错了什么。渲染严格发生在装载成功之后,因此到那时 run 早已回答了 `ok`:这份上报是 fire-and-forget 的,不带任何结算权威,也绝不触碰 `resolveRequestRun` 或 run 结论的任何部分——**它不是那个已退役的 v2 `report`/ack**。host 按定义保留跨所有页面的最后一次失败(第二个页面上报即覆盖),而一次全新的 run、一次 stop 或一次 undefine 都会清掉它,因此模型绝不会看到一次已不存在的下发留下的失败。浏览器半的契约面自己保留一份「**这个页面**当前正在显示什么」;两者回答的是不同的问题,不是同一个问题的两份答案。上报的会话若并不拥有该定义,这次上报会被丢弃,因为上报路径绝不能让一次渲染失败。
|
|
18
|
-
- `invoke` 把一个包的浏览器半发起的一次调用,路由到它自己的 host 半用 `harness.handle` 注册的方法。这套基础设施只做路由:不存在 host 到浏览器的方向。
|
|
16
|
+
- [使用本包](#use-this-package)
|
|
17
|
+
- [理解实现](#understand-the-implementation)
|
|
18
|
+
- [进一步探索](#further-exploration)
|
|
19
|
+
- [模型体验](#model-experience)
|
|
20
|
+
- [已知限制与延期工作](#known-limitations-and-deferred-work)
|
|
21
|
+
- [开发备注](#dev-note)
|
|
19
22
|
|
|
20
|
-
|
|
23
|
+
-----
|
|
21
24
|
|
|
22
|
-
|
|
25
|
+
<a id="use-this-package"></a>
|
|
26
|
+
## 使用本包
|
|
23
27
|
|
|
24
|
-
|
|
28
|
+
在任何一个应当支持动态包的组合中挂载本插件——它支撑模型的 `cordis_*` 工具,而带浏览器半的包还需要在客户端组合中额外挂载 client runner 与 UI 包。常用路径是显式的:加载本包,按需设置 `vmTimeoutMs`,其余交给工具与浏览器。
|
|
25
29
|
|
|
26
|
-
|
|
30
|
+
### 最小配置
|
|
27
31
|
|
|
28
|
-
|
|
32
|
+
```yaml
|
|
33
|
+
- name: '@deepseek-ai/dsh-cordis-host-runner'
|
|
34
|
+
config:
|
|
35
|
+
vmTimeoutMs: 5000
|
|
36
|
+
```
|
|
29
37
|
|
|
30
|
-
|
|
38
|
+
| 字段 | 默认值 | 含义 |
|
|
39
|
+
|---|---|---|
|
|
40
|
+
| `vmTimeoutMs` | `5000` | host 半在 vm 中同步执行的那部分被中止求值前可运行的毫秒数 |
|
|
31
41
|
|
|
32
|
-
|
|
42
|
+
生成的[配置目录](../../../docs/config-catalog.zh.md#deepseek-aidsh-cordis-host-runner)是每个受支持字段的穷尽式真源。
|
|
33
43
|
|
|
34
|
-
|
|
44
|
+
### run 会做什么
|
|
35
45
|
|
|
36
|
-
|
|
46
|
+
定义由 `cordis_define` 记录、由 `cordis_run` 激活。只有 host 半的包直接在本进程中激活:它的代码在沙箱中运行。带浏览器半的包变成一次请求:它一直等到有人在一个页面上允许或拒绝,或提问的轮次被取消;作答页面随后先装载 host 半、再装载浏览器半。`mode: "run"` 启动当前包或重启它,`mode: "update"` 切换到另一个包版本。`cordis_stop` 结束一次存活运行——移除该包的 handler 与任何已装载的浏览器 UI——同时保留可再次运行的定义;`cordis_undefine` 停止并忘掉它。
|
|
37
47
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
48
|
+
### 定义的去向
|
|
49
|
+
|
|
50
|
+
定义以会话为界、以进程为本:包只对定义它的会话可见,其他会话读起来是不存在,DSH 重启后一切都消失。会话日志保留一次 define 调用的参数——包括它提交的代码——以及回执;解析出的定义只存于内存注册表。浏览器半只能经一次运行到达页面,因此刷新后的页面手上什么都没有,直到有人再次运行该包。
|
|
51
|
+
|
|
52
|
+
### 信任立场
|
|
53
|
+
|
|
54
|
+
沙箱隔离全局变量,但不是安全边界:Node 全局变量不存在,或重定向到 Cordis 服务(`ctx.fs`、`ctx.web`、`ctx.bash` 与定时器 helper),host 半收到的是不含框架内部机制的 façade,但它声明的服务仍会触达存活运行时。对待动态包要像对待 bash 访问一样,参见[自引用工具集 Agent Note](../../../.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.zh.md)。
|
|
55
|
+
|
|
56
|
+
-----
|
|
57
|
+
|
|
58
|
+
<a id="understand-the-implementation"></a>
|
|
59
|
+
## 理解实现
|
|
60
|
+
|
|
61
|
+
<details>
|
|
62
|
+
<summary>实现细节——点击展开</summary>
|
|
63
|
+
|
|
64
|
+
本节解释 runner 背后的设计;可观察行为已在[使用本包](#use-this-package)中完整说明。
|
|
41
65
|
|
|
42
|
-
|
|
66
|
+
### 设计理念
|
|
43
67
|
|
|
44
|
-
|
|
68
|
+
runner 建立在两个分离之上。**注册表与沙箱是同一个服务。** `DynamicCordisRunnerService` 拥有定义注册表、vm 沙箱、host 半 fiber 生命周期与 invoke handler 表,因此一个定义的整个生命周期只有一个 owner。**版本是不可变的包。** 插件持有 `define` 之后永不变化的包;`currentPackageId` 与 `nextPackageId` 指向运行中与目标版本,`mode: "run"` 与 `"update"` 编码目标是否等于当前版本。浏览器往返之所以存在,是因为浏览器半只能由页面执行:服务 emit 请求并挂起,由页面的结论结算,调用方的 `AbortSignal` 是唯一的另一条出路。
|
|
45
69
|
|
|
46
|
-
|
|
70
|
+
### 源码地图
|
|
47
71
|
|
|
72
|
+
| 文件 | 职责 |
|
|
73
|
+
|---|---|
|
|
74
|
+
| [`src/index.ts`](src/index.ts) | 服务入口:`Config`、注册表接线、生命周期动词、steer 消息 |
|
|
75
|
+
| [`src/registry.ts`](src/registry.ts) | 定义存储:插件与包标识、运行尝试、审批请求 |
|
|
76
|
+
| [`src/sandbox.ts`](src/sandbox.ts) | `node:vm` 求值:全局变量、Node API 陷阱、define 时语法预检 |
|
|
77
|
+
| [`src/guard.ts`](src/guard.ts) | 注册边界:schema 规范化、沙箱 `ctx` façade、插件形态检查 |
|
|
78
|
+
| [`src/lifecycle.ts`](src/lifecycle.ts) | 在 `cordis-dynamic` fiber 组下启动 host 半 |
|
|
79
|
+
| [`src/inspect-registry.ts`](src/inspect-registry.ts) | `ctx.cordisInspect` 注册表:host provider 加镜像的 client manifest |
|
|
80
|
+
| [`src/types.ts`](src/types.ts) | `dynamicCordisRunner` remote namespace 与转发事件共享的 client 安全载荷形态 |
|
|
81
|
+
|
|
82
|
+
### 一次 run 的流程
|
|
83
|
+
|
|
84
|
+
`define` 对元数据做首尾去空白与必填校验,用编译预检每一半的语法(不执行任何代码),铸出插件与包标识,并把定义登记在发起调用的会话名下。`run` 对照 `currentPackageId` 与 `nextPackageId` 解析目标:纯 host 包在沙箱中求值并立即提交,带浏览器半的包则挂起一次审批请求、emit `cordis/request-run` 并挂起。作答页面依次走 `runHostHalf`、`getClientCode` 与 `resolveRequestRun`;命名存活 revision 的成功会提交激活、设置 `currentPackageId`,`cordis/request-run-resolved` 让其他每个页面撤下待作答入口。`stop` 回退存活下发——handler disposer、fiber dispose 与 `cordis/dynamic-retract` 广播——并让定义保持可运行。四条转发事件(`cordis/request-run`、`cordis/request-run-resolved`、`cordis/dynamic-package`、`cordis/dynamic-retract`)声明在 client 安全的 `./types` 子路径上,并由 `@deepseek-ai/dsh-api-remotes` 的白名单准许投递——正是这一点让浏览器能经 `ctx.remote.$on` 收到它们。
|
|
85
|
+
|
|
86
|
+
</details>
|
|
87
|
+
|
|
88
|
+
-----
|
|
89
|
+
|
|
90
|
+
<a id="further-exploration"></a>
|
|
91
|
+
## 进一步探索
|
|
92
|
+
|
|
93
|
+
当包级约定不够用时阅读以下页面。它们从 runner 逐步进入调用它的工具、应答它的浏览器半与生成的表面。
|
|
94
|
+
|
|
95
|
+
- [工具包](../tool-cordis/README.zh.md)——调用本服务的模型侧工具。
|
|
96
|
+
- [Client runner](../cordis-client-runner/README.zh.md)——应答运行请求并装载浏览器半代码的浏览器半。
|
|
97
|
+
- [UI 包](../ui-cordis/README.zh.md)——用户批准并操作运行的面板。
|
|
98
|
+
- [生成的配置目录](../../../docs/config-catalog.zh.md#deepseek-aidsh-cordis-host-runner)——每个受支持配置字段。
|
|
99
|
+
- [extensions 子系统](../../../docs/subsystems/extensions.zh.md)——生成的 `ctx.cordisInspect` 与 `ctx.dynamicCordisRunner` API 及 `cordis/*` 事件。
|
|
100
|
+
- [自引用 Cordis 工具集 Agent Note](../../../.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.zh.md)——沙箱语义、生命周期与组合的理由。
|
|
101
|
+
|
|
102
|
+
-----
|
|
103
|
+
|
|
104
|
+
<a id="model-experience"></a>
|
|
48
105
|
## 模型体验
|
|
49
106
|
|
|
50
|
-
###
|
|
107
|
+
### 转达给所属会话的运行结果、拒绝与诊断
|
|
51
108
|
|
|
52
109
|
#### 模型看到的内容
|
|
53
110
|
|
|
54
|
-
|
|
111
|
+
没有直接可见的内容:本包不注册任何工具,也不注入提示词。当一次 run 结算时,它会 steer 所属会话——成功时点名当前包并指示继续,用户拒绝时指示不要再次请求同一激活,技术性失败则给出原因、版本指针与「检查—修正—更新」路径。它还会在结算后 steer 渲染失败(槽位、条目是否已被移除)、host guard 拒绝与 host handler 失败。面板上的停止与移除手势会注入一条 user 角色消息,说明用户做了什么。`run` 或 `stop` 的拒绝还会经调用它的工具结果到达模型。
|
|
55
112
|
|
|
56
113
|
#### Token 影响
|
|
57
114
|
|
|
58
|
-
|
|
115
|
+
有条件且随数据而定:消息只在事件发生时到达,每条都携带一段有界的说明;没有固定的每请求成本。
|
|
59
116
|
|
|
60
117
|
#### KV Cache 影响
|
|
61
118
|
|
|
62
|
-
|
|
119
|
+
本包自身没有。注册工具的 host 半会改变下一次请求的工具视图,从第一个变化的 schema token 起使前缀复用失效;运行或停止一个不注册任何工具的包对前缀不产生影响。
|
|
120
|
+
|
|
121
|
+
## 已知限制与延期工作
|
|
63
122
|
|
|
64
123
|
<a id="known-limitations-and-deferred-work"></a>
|
|
65
124
|
|
|
66
|
-
## 已知限制与暂缓事项
|
|
67
125
|
|
|
68
|
-
|
|
126
|
+
这些限制说明 runner 何时需要特别小心。它们是当前包约束,不是任务积压。
|
|
127
|
+
|
|
128
|
+
- **run 成功不等于 UI 渲染成功**——只要作答页面已装载浏览器半,`run` 就会返回;React 是随后才渲染的,因此抛异常的组件不可能出现在 run 回执里。该失败经 steer 与 `cordis_inspect_self` 诊断浮现。
|
|
129
|
+
- **带浏览器半的包在没有页面连接的地方挂起**——headless 与 ACP(Agent Client Protocol)部署会把 run 一直挂到提问的轮次被取消;纯 host 包不受影响。
|
|
130
|
+
- **挂起的 run 请求没有超时**——它一直等人,直到提问的轮次被取消,因此无人值守的自动化用不了带浏览器半的包。
|
|
131
|
+
- **`vmTimeoutMs` 只约束同步求值**——async 的 host 半函数体会逃出该上限,这与工具集基于协作的信任立场一致。
|
|
132
|
+
- **陈旧成功的拒绝会让请求继续挂起**——作答页面点名的 revision 已被注册表越过时,该结论会被拒绝(`accepted: false`),请求保持可作答,直到另一个页面作答或调用方取消;浏览器半不读这个 ack。
|
|
133
|
+
- **运行播报不携带服务声明**——浏览器半声明的 `inject` 是从它在页面里返回的插件上读出的,因此 `cordis/request-run` 只携带元数据,绝无代码或服务清单。
|
|
134
|
+
- **`zod` 是生成的 Typert 契约面的运行时依赖,不是 `src` 的依赖**——`./typert` 与 `./remote` 解析到未打包的 `lib` 文件,其中带有裸的 `import { z } from 'zod'`,所以即使 `src` 里没有任何代码 import zod,本包也要声明它。
|
|
135
|
+
|
|
136
|
+
<a id="dev-note"></a>
|
|
137
|
+
### 开发备注
|
|
138
|
+
|
|
139
|
+
<details>
|
|
140
|
+
<summary>维护者的工作上下文——点击展开</summary>
|
|
141
|
+
|
|
142
|
+
无。
|
|
69
143
|
|
|
70
|
-
|
|
71
|
-
- 挂起的 run 请求**没有超时**:它一直等人,直到提问的那一轮次被取消,因此无人值守的自动化用不了带浏览器半的包。
|
|
72
|
-
- `vmTimeoutMs` 只约束同步求值;async 的 host 半函数体会逃出该上限,这与该工具集基于协作的信任立场一致。
|
|
73
|
-
- `runHostHalf` 不携带 request id,因此「这个 host 半是哪次请求求值的」由 host 侧归因到该定义最近一次挂起的请求;若同一个定义出现多个并发 run 请求,这条规则需要重新审议。
|
|
74
|
-
- 命名了已被取代版本的成功结论会被拒绝(`accepted: false`)并让该请求继续挂起,因此模型这次调用只能靠一次有效作答或自身被取消才结束。要把它结算掉,需要对着存活版本重新走一遍编排,而当前没有任何页面会这么做——[浏览器半](../cordis-client-runner/README.zh.md)不读这个 ack——所以这类请求实际上由别的页面作答、或由调用方取消来收尾。
|
|
75
|
-
- 浏览器半声明的 `inject` 是从它在页面里返回的插件上读出的,因此播报完全不携带服务声明字段。
|
|
76
|
-
- **`zod` 是生成的 TypeRT 契约面的运行时依赖,不是 `src` 的依赖。** `./typert` 与 `./remote` 解析到 `lib/typert.*.js`,`tsc` 以不打包的形式产出它们,其中带有裸的 `import { z } from 'zod'`,所以本包必须声明它(沿用 `@deepseek-ai/dsh-goal` 的先例),而 `knip.json` 必须在这个 workspace 里忽略它:knip 读的是源码,而这些契约面是构建产物。`src` 里没有任何代码 import zod。
|
|
144
|
+
</details>
|
package/lib/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import { Remote, TypertRemoteService } from "@deepseek-ai/dsh-typert-protocol";
|
|
|
4
4
|
import { Context, Service } from "@deepseek-ai/cordis";
|
|
5
5
|
import { scopeOf } from "@deepseek-ai/dsh-scope";
|
|
6
6
|
import { assertSupportedJsonSchema, defineTool, validateJsonSchemaValue } from "@deepseek-ai/dsh-tools";
|
|
7
|
-
import { snapshotJsonValue } from "@deepseek-ai/dsh-
|
|
7
|
+
import { snapshotJsonValue } from "@deepseek-ai/dsh-util-values";
|
|
8
8
|
import { Script, createContext, runInContext } from "node:vm";
|
|
9
9
|
//#region lib/types/guard.js
|
|
10
10
|
/**
|
package/lib/typert.host.js
CHANGED
|
@@ -35,16 +35,16 @@ const _deepseek_ai_dsh_cordis_host_runner_dynamicCordisRunner_inventory_result$s
|
|
|
35
35
|
'pluginRunId': z.intersection(z.string(), z.unknown()),
|
|
36
36
|
'packageId': z.intersection(z.string(), z.unknown()),
|
|
37
37
|
'mode': z.union([z.literal("run"), z.literal("update")]),
|
|
38
|
-
'status': z.union([z.literal("
|
|
38
|
+
'status': z.union([z.literal("running"), z.literal("failed"), z.literal("rejected"), z.literal("awaiting-approval"), z.literal("cancelled"), z.literal("starting-host"), z.literal("client-pending"), z.literal("waiting"), z.literal("stopped")]),
|
|
39
39
|
'approvalRequestId': z.intersection(z.string(), z.unknown()).optional(),
|
|
40
40
|
'requiresApproval': z.boolean().optional(),
|
|
41
41
|
'host': z.object({
|
|
42
|
-
'status': z.union([z.literal("
|
|
42
|
+
'status': z.union([z.literal("pending"), z.literal("running"), z.literal("failed"), z.literal("waiting"), z.literal("stopped"), z.literal("absent")]),
|
|
43
43
|
'waitingFor': z.array(z.string()),
|
|
44
44
|
'error': z.string().optional(),
|
|
45
45
|
}),
|
|
46
46
|
'client': z.object({
|
|
47
|
-
'status': z.union([z.literal("
|
|
47
|
+
'status': z.union([z.literal("pending"), z.literal("running"), z.literal("failed"), z.literal("waiting"), z.literal("stopped"), z.literal("absent")]),
|
|
48
48
|
'waitingFor': z.array(z.string()),
|
|
49
49
|
'error': z.string().optional(),
|
|
50
50
|
}),
|
|
@@ -154,7 +154,7 @@ const _deepseek_ai_dsh_cordis_host_runner_dynamicCordisRunner_settleUserRun_para
|
|
|
154
154
|
})])
|
|
155
155
|
const _deepseek_ai_dsh_cordis_host_runner_dynamicCordisRunner_settleUserRun_result$schema = z.union([z.object({
|
|
156
156
|
'ok': z.literal(true),
|
|
157
|
-
'status': z.union([z.literal("
|
|
157
|
+
'status': z.union([z.literal("running"), z.literal("awaiting-approval"), z.literal("starting")]),
|
|
158
158
|
'pluginId': z.intersection(z.string(), z.unknown()),
|
|
159
159
|
'packageId': z.intersection(z.string(), z.unknown()),
|
|
160
160
|
'pluginRunId': z.intersection(z.string(), z.unknown()),
|
|
@@ -314,7 +314,7 @@ export const TYPERT = {
|
|
|
314
314
|
source: 'json',
|
|
315
315
|
codec: {
|
|
316
316
|
mode: 'strict',
|
|
317
|
-
typeSymbol: '@deepseek-ai/dsh-
|
|
317
|
+
typeSymbol: '@deepseek-ai/dsh-util-values#JsonValue',
|
|
318
318
|
schema: _deepseek_ai_dsh_cordis_host_runner_dynamicCordisRunner_invoke_parameter_3$schema,
|
|
319
319
|
},
|
|
320
320
|
},
|
|
@@ -824,7 +824,7 @@ export const TYPERT = {
|
|
|
824
824
|
},
|
|
825
825
|
{
|
|
826
826
|
"name": "AgentOptions",
|
|
827
|
-
"declaration": "export interface AgentOptions {\n provider?: string;\n model?: string;\n maxTokens?: number;\n}"
|
|
827
|
+
"declaration": "export interface AgentOptions {\n provider?: string;\n model?: string;\n reasoningEffort?: ReasoningEffortId;\n maxTokens?: number;\n subagentDepth?: number;\n}"
|
|
828
828
|
},
|
|
829
829
|
{
|
|
830
830
|
"name": "AgentStatus",
|
|
@@ -858,22 +858,10 @@ export const TYPERT = {
|
|
|
858
858
|
"name": "Branded",
|
|
859
859
|
"declaration": "export type Branded<B extends string> = string & { readonly [BRAND]: B; };"
|
|
860
860
|
},
|
|
861
|
-
{
|
|
862
|
-
"name": "CallId",
|
|
863
|
-
"declaration": "export type CallId = Branded<'CallId'>;"
|
|
864
|
-
},
|
|
865
861
|
{
|
|
866
862
|
"name": "CancelOptions",
|
|
867
863
|
"declaration": "export interface CancelOptions {\n keepInbox?: boolean | undefined;\n}"
|
|
868
864
|
},
|
|
869
|
-
{
|
|
870
|
-
"name": "CodeDispatchEventData",
|
|
871
|
-
"declaration": "export interface CodeDispatchEventData extends CodeDispatchStartEventData {\n isError: boolean;\n content: ContentBlock[];\n}"
|
|
872
|
-
},
|
|
873
|
-
{
|
|
874
|
-
"name": "CodeDispatchStartEventData",
|
|
875
|
-
"declaration": "export interface CodeDispatchStartEventData {\n rootCallId: CallId;\n parentCallId: CallId;\n subCallId: CallId;\n name: string;\n arguments: unknown;\n}"
|
|
876
|
-
},
|
|
877
865
|
{
|
|
878
866
|
"name": "CommandId",
|
|
879
867
|
"declaration": "export type CommandId = Branded<'CommandId'>;"
|
|
@@ -910,6 +898,14 @@ export const TYPERT = {
|
|
|
910
898
|
"name": "ContextSnapshotSection",
|
|
911
899
|
"declaration": "export interface ContextSnapshotSection {\n readonly name: string;\n readonly text: string;\n}"
|
|
912
900
|
},
|
|
901
|
+
{
|
|
902
|
+
"name": "ContinuableSubagentDescriptorData",
|
|
903
|
+
"declaration": "export interface ContinuableSubagentDescriptorData extends SubagentDescriptorBase {\n readonly mode: 'continuable';\n readonly label: string;\n readonly agentProvider?: string;\n readonly agentModel?: string;\n readonly agentReasoningEffort?: ReasoningEffortId;\n readonly persona?: string;\n readonly toolFilter?: ToolRestriction;\n}"
|
|
904
|
+
},
|
|
905
|
+
{
|
|
906
|
+
"name": "CoordinatorMessageSource",
|
|
907
|
+
"declaration": "export interface CoordinatorMessageSource {\n readonly kind: 'coordinator';\n readonly form: 'relay';\n readonly senderSessionId: SessionId;\n}"
|
|
908
|
+
},
|
|
913
909
|
{
|
|
914
910
|
"name": "CordisInspectMethodManifest",
|
|
915
911
|
"declaration": "export interface CordisInspectMethodManifest {\n name: string;\n description: string;\n inputSchema: JsonValue;\n outputSchema: JsonValue;\n}"
|
|
@@ -1048,16 +1044,32 @@ export const TYPERT = {
|
|
|
1048
1044
|
},
|
|
1049
1045
|
{
|
|
1050
1046
|
"name": "MessageSourceMap",
|
|
1051
|
-
"declaration": "export interface MessageSourceMap {\n user: { kind: 'user'; };\n plugin: { kind: 'plugin'; plugin: string; } & ContextFormed;\n model: ModelMessageSource;\n tool: ToolMessageSource;\n goal: GoalMessageSource;\n 'session-reference': SessionReferenceSource;\n}"
|
|
1047
|
+
"declaration": "export interface MessageSourceMap {\n user: { kind: 'user'; };\n plugin: { kind: 'plugin'; plugin: string; } & ContextFormed;\n model: ModelMessageSource;\n tool: ToolMessageSource;\n 'user-rpc': { kind: 'user'; rpcId: SessionRequestId; clientTimeZone?: string; };\n coordinator: CoordinatorMessageSource;\n 'subagent-report': SubagentReportMessageSource;\n 'subagent-settled': SubagentSettledMessageSource;\n 'skill-invocation': SkillInvocationSource;\n 'team-message': TeamMessageSource;\n goal: GoalMessageSource;\n 'session-reference': SessionReferenceSource;\n}"
|
|
1052
1048
|
},
|
|
1053
1049
|
{
|
|
1054
1050
|
"name": "ModelMessageSource",
|
|
1055
1051
|
"declaration": "export interface ModelMessageSource extends AssistantProvenance {\n kind: 'model';\n}"
|
|
1056
1052
|
},
|
|
1053
|
+
{
|
|
1054
|
+
"name": "ModelSelection",
|
|
1055
|
+
"declaration": "export interface ModelSelection {\n readonly provider: string;\n readonly model: string;\n readonly reasoningEffort?: string;\n}"
|
|
1056
|
+
},
|
|
1057
|
+
{
|
|
1058
|
+
"name": "OneShotSubagentDescriptorData",
|
|
1059
|
+
"declaration": "export interface OneShotSubagentDescriptorData extends SubagentDescriptorBase {\n readonly mode: 'one-shot';\n readonly label?: string;\n}"
|
|
1060
|
+
},
|
|
1057
1061
|
{
|
|
1058
1062
|
"name": "ProviderRequestId",
|
|
1059
1063
|
"declaration": "export type ProviderRequestId = Branded<'ProviderRequestId'>;"
|
|
1060
1064
|
},
|
|
1065
|
+
{
|
|
1066
|
+
"name": "PtcDispatchEventData",
|
|
1067
|
+
"declaration": "export interface PtcDispatchEventData extends PtcDispatchStartEventData {\n isError: boolean;\n content: ContentBlock[];\n}"
|
|
1068
|
+
},
|
|
1069
|
+
{
|
|
1070
|
+
"name": "PtcDispatchStartEventData",
|
|
1071
|
+
"declaration": "export interface PtcDispatchStartEventData {\n rootCallId: ToolCallId;\n parentCallId: ToolCallId;\n subCallId: ToolCallId;\n name: string;\n arguments: unknown;\n}"
|
|
1072
|
+
},
|
|
1061
1073
|
{
|
|
1062
1074
|
"name": "ReasoningBlock",
|
|
1063
1075
|
"declaration": "export interface ReasoningBlock {\n type: 'reasoning';\n text: string;\n}"
|
|
@@ -1076,7 +1088,11 @@ export const TYPERT = {
|
|
|
1076
1088
|
},
|
|
1077
1089
|
{
|
|
1078
1090
|
"name": "RequestHeaderReason",
|
|
1079
|
-
"declaration": "export type RequestHeaderReason = 'initial' | 'resume' | 'change';"
|
|
1091
|
+
"declaration": "export type RequestHeaderReason = 'initial' | 'resume' | 'change' | 'series';"
|
|
1092
|
+
},
|
|
1093
|
+
{
|
|
1094
|
+
"name": "SandboxMode",
|
|
1095
|
+
"declaration": "export type SandboxMode = 'read-only' | 'workspace-write' | 'danger-full-access';"
|
|
1080
1096
|
},
|
|
1081
1097
|
{
|
|
1082
1098
|
"name": "Session",
|
|
@@ -1088,7 +1104,7 @@ export const TYPERT = {
|
|
|
1088
1104
|
},
|
|
1089
1105
|
{
|
|
1090
1106
|
"name": "SessionEventMap",
|
|
1091
|
-
"declaration": "export interface SessionEventMap {\n 'turn/start': { turn: number; };\n 'turn/end': { turn: number; reason: TurnEndReason; };\n 'step/start': { turn: number; step: number; };\n 'step/end': { turn: number; step: number; };\n 'user/message': UserMessage;\n 'assistant/chunk': { turn: number; step: number; chunk: StreamChunk; };\n 'assistant/message': { turn: number; step: number; message: AssistantMessage; usage?: TokenUsage; interrupted?: true; };\n 'tool/call': { turn: number; step: number; callId:
|
|
1107
|
+
"declaration": "export interface SessionEventMap {\n 'turn/start': { turn: number; };\n 'turn/end': { turn: number; reason: TurnEndReason; };\n 'step/start': { turn: number; step: number; };\n 'step/end': { turn: number; step: number; };\n 'user/message': UserMessage;\n 'assistant/chunk': { turn: number; step: number; chunk: StreamChunk; };\n 'assistant/message': { turn: number; step: number; message: AssistantMessage; usage?: TokenUsage; interrupted?: true; };\n 'tool/call': { turn: number; step: number; callId: ToolCallId; name: string; arguments: string; };\n 'tool/result': { turn: number; step: number; message: ToolResultMessage; error?: { name: string; code: string; }; meta?: JsonValue; };\n 'request/header': { header: EpochHeader; reason: RequestHeaderReason; startsSeries?: true; };\n 'request/context': RequestContext;\n 'session/end-seed': Record<string, never>;\n 'agent/inbox/spliced': { target: InboxTarget; start: number; removedCount?: number; inserted: UserMessage[]; outcome?: 'canceled'; };\n 'approval/asked': { id: ApprovalRequestId; toolName: string; callId?: ToolCallId; reason?: string; };\n 'approval/decided': { id: ApprovalRequestId; outcome: ApprovalOutcome; };\n 'approval/policy': { policy: ApprovalPolicy; source?: 'delegation'; };\n 'tool/code-dispatch-start': PtcDispatchStartEventData;\n 'tool/code-dispatch': PtcDispatchEventData;\n 'agent-preset/selected': { agentPreset: string; };\n 'session/title': SessionTitleEventData;\n 'todo/write': { todos: TodoItem[]; };\n 'model/selection': ModelSelection;\n 'subagent/descriptor': SubagentDescriptorData;\n 'sandbox/mode': { mode: SandboxMode; source?: 'delegation'; };\n 'command/run': { commandId: CommandId; name: string; args?: string; source: CommandSource; };\n 'command/done': { commandId: CommandId; kind: 'success' | 'error'; text?: string; sourceEventSeq?: number; };\n 'team/member': { version: 1; teamId: TeamId; member: TeamMemberSnapshot; };\n 'team/task': { version: 1; teamId: TeamId; task: TeamTaskSnapshot; };\n 'team/message/queued': { version: 1; teamId: TeamId; message: TeamMessageSnapshot; };\n 'team/message/delivered': { version: 1; teamId: TeamId; messageId: TeamMessageId; targetId: SessionId; };\n 'goal/change': GoalChangeMeta;\n 'compaction/start': { compactionId: CompactionId; sourceCommandId?: CommandId; turn: number | null; };\n 'compaction/summary': { compactionId: CompactionId; sourceCommandId?: CommandId; summary: ContentBlock[]; shadowedRange: { start: number; end: number; }; shadowedSeqs: number[]; shadowedTokenCount: number; provider: string; model: string; maxTokens?: number; usage?: TokenUsage; } & ({ rawOutput: ContentBlock[]; llmStreamCall: true; } | { rawOutput?: ContentBlock[]; llmStreamCall?: never; });\n 'compaction/end': { compactionId: CompactionId; sourceCommandId?: CommandId; turn: number | null; error?: string; };\n 'compaction/prune': { shadowedRange: { start: number; end: number; }; shadowedSeqs: number[]; shadowedTokenCount: number; };\n}"
|
|
1092
1108
|
},
|
|
1093
1109
|
{
|
|
1094
1110
|
"name": "SessionEventType",
|
|
@@ -1106,6 +1122,10 @@ export const TYPERT = {
|
|
|
1106
1122
|
"name": "SessionReferenceSource",
|
|
1107
1123
|
"declaration": "export interface SessionReferenceSource {\n kind: 'session-reference';\n form: 'recall';\n version: 1;\n references: { sessionId: string; label: string; capturedThroughSeq: number | null; compacted: boolean; originalMessages: number; retainedMessages: number; omittedMessages: number; omittedBytes: number; truncated: boolean; inputIndex: number; }[];\n}"
|
|
1108
1124
|
},
|
|
1125
|
+
{
|
|
1126
|
+
"name": "SessionRequestId",
|
|
1127
|
+
"declaration": "export type SessionRequestId = Branded<'session-request-id'>;"
|
|
1128
|
+
},
|
|
1109
1129
|
{
|
|
1110
1130
|
"name": "SessionSurface",
|
|
1111
1131
|
"declaration": "export interface SessionSurface {\n readonly nodes: readonly number[];\n readonly replaceGeneration: number;\n}"
|
|
@@ -1126,9 +1146,29 @@ export const TYPERT = {
|
|
|
1126
1146
|
"name": "SessionTitleSource",
|
|
1127
1147
|
"declaration": "export type SessionTitleSource = { readonly kind: 'fallback'; } | { readonly kind: 'provider'; readonly provider: SessionTitleProviderId; readonly model?: SessionTitleModelProvenance; } | { readonly kind: 'user'; };"
|
|
1128
1148
|
},
|
|
1149
|
+
{
|
|
1150
|
+
"name": "SkillInvocationSource",
|
|
1151
|
+
"declaration": "export interface SkillInvocationSource {\n readonly kind: 'skill-invocation';\n readonly name: string;\n readonly form: 'instructions';\n}"
|
|
1152
|
+
},
|
|
1129
1153
|
{
|
|
1130
1154
|
"name": "StreamChunk",
|
|
1131
|
-
"declaration": "export type StreamChunk = { type: 'block-start'; index: number; blockType: ContentBlockType; } | { type: 'text-delta'; index: number; text: string; } | { type: 'reasoning-delta'; index: number; text: string; } | { type: 'tool-call-delta'; index: number; id:
|
|
1155
|
+
"declaration": "export type StreamChunk = { type: 'block-start'; index: number; blockType: ContentBlockType; } | { type: 'text-delta'; index: number; text: string; } | { type: 'reasoning-delta'; index: number; text: string; } | { type: 'tool-call-delta'; index: number; id: ToolCallId; name?: string; argumentsDelta: string; } | { type: 'block-end'; index: number; block: ContentBlock; } | { type: 'usage'; usage: TokenUsage; } | { type: 'finish'; reason: FinishReason; replayState?: ReplayEnvelope; };"
|
|
1156
|
+
},
|
|
1157
|
+
{
|
|
1158
|
+
"name": "SubagentDescriptorBase",
|
|
1159
|
+
"declaration": "export interface SubagentDescriptorBase {\n readonly version: number;\n readonly mode: 'one-shot' | 'continuable';\n readonly provider: string;\n}"
|
|
1160
|
+
},
|
|
1161
|
+
{
|
|
1162
|
+
"name": "SubagentDescriptorData",
|
|
1163
|
+
"declaration": "export type SubagentDescriptorData = OneShotSubagentDescriptorData | ContinuableSubagentDescriptorData;"
|
|
1164
|
+
},
|
|
1165
|
+
{
|
|
1166
|
+
"name": "SubagentReportMessageSource",
|
|
1167
|
+
"declaration": "export interface SubagentReportMessageSource {\n readonly kind: 'subagent-report';\n readonly form: 'relay';\n readonly senderSessionId: SessionId;\n}"
|
|
1168
|
+
},
|
|
1169
|
+
{
|
|
1170
|
+
"name": "SubagentSettledMessageSource",
|
|
1171
|
+
"declaration": "export interface SubagentSettledMessageSource {\n readonly kind: 'subagent-settled';\n readonly form: 'notice';\n readonly summary: string;\n readonly senderSessionId: SessionId;\n}"
|
|
1132
1172
|
},
|
|
1133
1173
|
{
|
|
1134
1174
|
"name": "SurfaceEventType",
|
|
@@ -1142,6 +1182,42 @@ export const TYPERT = {
|
|
|
1142
1182
|
"name": "SurfaceOp",
|
|
1143
1183
|
"declaration": "export type SurfaceOp = 'append' | { op: 'replace'; start: number; end: number; };"
|
|
1144
1184
|
},
|
|
1185
|
+
{
|
|
1186
|
+
"name": "TeamId",
|
|
1187
|
+
"declaration": "export type TeamId = Branded<'TeamId'>;"
|
|
1188
|
+
},
|
|
1189
|
+
{
|
|
1190
|
+
"name": "TeamMemberPhase",
|
|
1191
|
+
"declaration": "export type TeamMemberPhase = 'provisioning' | 'active' | 'failed';"
|
|
1192
|
+
},
|
|
1193
|
+
{
|
|
1194
|
+
"name": "TeamMemberSnapshot",
|
|
1195
|
+
"declaration": "export interface TeamMemberSnapshot {\n readonly id: SessionId;\n readonly name: string;\n readonly description: string;\n readonly provider: string;\n readonly context: 'fresh' | 'fork';\n readonly phase: TeamMemberPhase;\n readonly error?: string;\n}"
|
|
1196
|
+
},
|
|
1197
|
+
{
|
|
1198
|
+
"name": "TeamMessageId",
|
|
1199
|
+
"declaration": "export type TeamMessageId = Branded<'TeamMessageId'>;"
|
|
1200
|
+
},
|
|
1201
|
+
{
|
|
1202
|
+
"name": "TeamMessageSnapshot",
|
|
1203
|
+
"declaration": "export interface TeamMessageSnapshot {\n readonly id: TeamMessageId;\n readonly senderId: SessionId;\n readonly senderName: string;\n readonly targetId: SessionId;\n readonly delivery: 'quiet' | 'wakeup';\n readonly content: ContentBlock[];\n}"
|
|
1204
|
+
},
|
|
1205
|
+
{
|
|
1206
|
+
"name": "TeamMessageSource",
|
|
1207
|
+
"declaration": "export interface TeamMessageSource {\n readonly kind: 'team-message';\n readonly teamId: TeamId;\n readonly messageId: TeamMessageId;\n readonly senderId: SessionId;\n readonly senderName: string;\n}"
|
|
1208
|
+
},
|
|
1209
|
+
{
|
|
1210
|
+
"name": "TeamTaskId",
|
|
1211
|
+
"declaration": "export type TeamTaskId = Branded<'TeamTaskId'>;"
|
|
1212
|
+
},
|
|
1213
|
+
{
|
|
1214
|
+
"name": "TeamTaskSnapshot",
|
|
1215
|
+
"declaration": "export interface TeamTaskSnapshot {\n readonly id: TeamTaskId;\n readonly revision: number;\n readonly subject: string;\n readonly description: string;\n readonly status: TeamTaskStatus;\n readonly ownerId?: SessionId;\n readonly blockedBy: TeamTaskId[];\n readonly writeScopes: string[];\n}"
|
|
1216
|
+
},
|
|
1217
|
+
{
|
|
1218
|
+
"name": "TeamTaskStatus",
|
|
1219
|
+
"declaration": "export type TeamTaskStatus = 'pending' | 'in_progress' | 'completed' | 'deleted';"
|
|
1220
|
+
},
|
|
1145
1221
|
{
|
|
1146
1222
|
"name": "TextBlock",
|
|
1147
1223
|
"declaration": "export interface TextBlock {\n type: 'text';\n text: string;\n}"
|
|
@@ -1152,19 +1228,27 @@ export const TYPERT = {
|
|
|
1152
1228
|
},
|
|
1153
1229
|
{
|
|
1154
1230
|
"name": "TokenUsage",
|
|
1155
|
-
"declaration": "export interface TokenUsage {\n inputTokens: number;\n outputTokens: number;\n cacheReadTokens?: number;\n cacheWriteTokens?: number;\n reasoningTokens?: number;\n}"
|
|
1231
|
+
"declaration": "export interface TokenUsage {\n inputTokens: number;\n outputTokens: number;\n totalTokens?: number;\n cacheReadTokens?: number;\n cacheWriteTokens?: number;\n reasoningTokens?: number;\n}"
|
|
1156
1232
|
},
|
|
1157
1233
|
{
|
|
1158
1234
|
"name": "ToolCallBlock",
|
|
1159
|
-
"declaration": "export interface ToolCallBlock {\n type: 'tool-call';\n id:
|
|
1235
|
+
"declaration": "export interface ToolCallBlock {\n type: 'tool-call';\n id: ToolCallId;\n name: string;\n arguments: string;\n}"
|
|
1236
|
+
},
|
|
1237
|
+
{
|
|
1238
|
+
"name": "ToolCallId",
|
|
1239
|
+
"declaration": "export type ToolCallId = Branded<'ToolCallId'>;"
|
|
1160
1240
|
},
|
|
1161
1241
|
{
|
|
1162
1242
|
"name": "ToolMessageSource",
|
|
1163
|
-
"declaration": "export interface ToolMessageSource {\n kind: 'tool';\n callId:
|
|
1243
|
+
"declaration": "export interface ToolMessageSource {\n kind: 'tool';\n callId: ToolCallId;\n}"
|
|
1244
|
+
},
|
|
1245
|
+
{
|
|
1246
|
+
"name": "ToolRestriction",
|
|
1247
|
+
"declaration": "export interface ToolRestriction {\n readonly allow?: readonly string[];\n readonly deny?: readonly string[];\n}"
|
|
1164
1248
|
},
|
|
1165
1249
|
{
|
|
1166
1250
|
"name": "ToolResultBlock",
|
|
1167
|
-
"declaration": "export interface ToolResultBlock {\n type: 'tool-result';\n toolCallId:
|
|
1251
|
+
"declaration": "export interface ToolResultBlock {\n type: 'tool-result';\n toolCallId: ToolCallId;\n content: ContentBlock[];\n isError?: boolean;\n}"
|
|
1168
1252
|
},
|
|
1169
1253
|
{
|
|
1170
1254
|
"name": "ToolResultMessage",
|
|
@@ -1359,7 +1443,7 @@ export const TYPERT = {
|
|
|
1359
1443
|
},
|
|
1360
1444
|
{
|
|
1361
1445
|
"name": "AgentOptions",
|
|
1362
|
-
"declaration": "export interface AgentOptions {\n provider?: string;\n model?: string;\n maxTokens?: number;\n}"
|
|
1446
|
+
"declaration": "export interface AgentOptions {\n provider?: string;\n model?: string;\n reasoningEffort?: ReasoningEffortId;\n maxTokens?: number;\n subagentDepth?: number;\n}"
|
|
1363
1447
|
},
|
|
1364
1448
|
{
|
|
1365
1449
|
"name": "AgentStatus",
|
|
@@ -1397,22 +1481,10 @@ export const TYPERT = {
|
|
|
1397
1481
|
"name": "Branded",
|
|
1398
1482
|
"declaration": "export type Branded<B extends string> = string & { readonly [BRAND]: B; };"
|
|
1399
1483
|
},
|
|
1400
|
-
{
|
|
1401
|
-
"name": "CallId",
|
|
1402
|
-
"declaration": "export type CallId = Branded<'CallId'>;"
|
|
1403
|
-
},
|
|
1404
1484
|
{
|
|
1405
1485
|
"name": "CancelOptions",
|
|
1406
1486
|
"declaration": "export interface CancelOptions {\n keepInbox?: boolean | undefined;\n}"
|
|
1407
1487
|
},
|
|
1408
|
-
{
|
|
1409
|
-
"name": "CodeDispatchEventData",
|
|
1410
|
-
"declaration": "export interface CodeDispatchEventData extends CodeDispatchStartEventData {\n isError: boolean;\n content: ContentBlock[];\n}"
|
|
1411
|
-
},
|
|
1412
|
-
{
|
|
1413
|
-
"name": "CodeDispatchStartEventData",
|
|
1414
|
-
"declaration": "export interface CodeDispatchStartEventData {\n rootCallId: CallId;\n parentCallId: CallId;\n subCallId: CallId;\n name: string;\n arguments: unknown;\n}"
|
|
1415
|
-
},
|
|
1416
1488
|
{
|
|
1417
1489
|
"name": "CommandId",
|
|
1418
1490
|
"declaration": "export type CommandId = Branded<'CommandId'>;"
|
|
@@ -1449,6 +1521,14 @@ export const TYPERT = {
|
|
|
1449
1521
|
"name": "ContextSnapshotSection",
|
|
1450
1522
|
"declaration": "export interface ContextSnapshotSection {\n readonly name: string;\n readonly text: string;\n}"
|
|
1451
1523
|
},
|
|
1524
|
+
{
|
|
1525
|
+
"name": "ContinuableSubagentDescriptorData",
|
|
1526
|
+
"declaration": "export interface ContinuableSubagentDescriptorData extends SubagentDescriptorBase {\n readonly mode: 'continuable';\n readonly label: string;\n readonly agentProvider?: string;\n readonly agentModel?: string;\n readonly agentReasoningEffort?: ReasoningEffortId;\n readonly persona?: string;\n readonly toolFilter?: ToolRestriction;\n}"
|
|
1527
|
+
},
|
|
1528
|
+
{
|
|
1529
|
+
"name": "CoordinatorMessageSource",
|
|
1530
|
+
"declaration": "export interface CoordinatorMessageSource {\n readonly kind: 'coordinator';\n readonly form: 'relay';\n readonly senderSessionId: SessionId;\n}"
|
|
1531
|
+
},
|
|
1452
1532
|
{
|
|
1453
1533
|
"name": "CordisDynamicPackageId",
|
|
1454
1534
|
"declaration": "export type CordisDynamicPackageId = Branded<'CordisDynamicPackageId'>;"
|
|
@@ -1675,16 +1755,32 @@ export const TYPERT = {
|
|
|
1675
1755
|
},
|
|
1676
1756
|
{
|
|
1677
1757
|
"name": "MessageSourceMap",
|
|
1678
|
-
"declaration": "export interface MessageSourceMap {\n user: { kind: 'user'; };\n plugin: { kind: 'plugin'; plugin: string; } & ContextFormed;\n model: ModelMessageSource;\n tool: ToolMessageSource;\n goal: GoalMessageSource;\n 'session-reference': SessionReferenceSource;\n}"
|
|
1758
|
+
"declaration": "export interface MessageSourceMap {\n user: { kind: 'user'; };\n plugin: { kind: 'plugin'; plugin: string; } & ContextFormed;\n model: ModelMessageSource;\n tool: ToolMessageSource;\n 'user-rpc': { kind: 'user'; rpcId: SessionRequestId; clientTimeZone?: string; };\n coordinator: CoordinatorMessageSource;\n 'subagent-report': SubagentReportMessageSource;\n 'subagent-settled': SubagentSettledMessageSource;\n 'skill-invocation': SkillInvocationSource;\n 'team-message': TeamMessageSource;\n goal: GoalMessageSource;\n 'session-reference': SessionReferenceSource;\n}"
|
|
1679
1759
|
},
|
|
1680
1760
|
{
|
|
1681
1761
|
"name": "ModelMessageSource",
|
|
1682
1762
|
"declaration": "export interface ModelMessageSource extends AssistantProvenance {\n kind: 'model';\n}"
|
|
1683
1763
|
},
|
|
1764
|
+
{
|
|
1765
|
+
"name": "ModelSelection",
|
|
1766
|
+
"declaration": "export interface ModelSelection {\n readonly provider: string;\n readonly model: string;\n readonly reasoningEffort?: string;\n}"
|
|
1767
|
+
},
|
|
1768
|
+
{
|
|
1769
|
+
"name": "OneShotSubagentDescriptorData",
|
|
1770
|
+
"declaration": "export interface OneShotSubagentDescriptorData extends SubagentDescriptorBase {\n readonly mode: 'one-shot';\n readonly label?: string;\n}"
|
|
1771
|
+
},
|
|
1684
1772
|
{
|
|
1685
1773
|
"name": "ProviderRequestId",
|
|
1686
1774
|
"declaration": "export type ProviderRequestId = Branded<'ProviderRequestId'>;"
|
|
1687
1775
|
},
|
|
1776
|
+
{
|
|
1777
|
+
"name": "PtcDispatchEventData",
|
|
1778
|
+
"declaration": "export interface PtcDispatchEventData extends PtcDispatchStartEventData {\n isError: boolean;\n content: ContentBlock[];\n}"
|
|
1779
|
+
},
|
|
1780
|
+
{
|
|
1781
|
+
"name": "PtcDispatchStartEventData",
|
|
1782
|
+
"declaration": "export interface PtcDispatchStartEventData {\n rootCallId: ToolCallId;\n parentCallId: ToolCallId;\n subCallId: ToolCallId;\n name: string;\n arguments: unknown;\n}"
|
|
1783
|
+
},
|
|
1688
1784
|
{
|
|
1689
1785
|
"name": "ReasoningBlock",
|
|
1690
1786
|
"declaration": "export interface ReasoningBlock {\n type: 'reasoning';\n text: string;\n}"
|
|
@@ -1703,7 +1799,11 @@ export const TYPERT = {
|
|
|
1703
1799
|
},
|
|
1704
1800
|
{
|
|
1705
1801
|
"name": "RequestHeaderReason",
|
|
1706
|
-
"declaration": "export type RequestHeaderReason = 'initial' | 'resume' | 'change';"
|
|
1802
|
+
"declaration": "export type RequestHeaderReason = 'initial' | 'resume' | 'change' | 'series';"
|
|
1803
|
+
},
|
|
1804
|
+
{
|
|
1805
|
+
"name": "SandboxMode",
|
|
1806
|
+
"declaration": "export type SandboxMode = 'read-only' | 'workspace-write' | 'danger-full-access';"
|
|
1707
1807
|
},
|
|
1708
1808
|
{
|
|
1709
1809
|
"name": "Session",
|
|
@@ -1715,7 +1815,7 @@ export const TYPERT = {
|
|
|
1715
1815
|
},
|
|
1716
1816
|
{
|
|
1717
1817
|
"name": "SessionEventMap",
|
|
1718
|
-
"declaration": "export interface SessionEventMap {\n 'turn/start': { turn: number; };\n 'turn/end': { turn: number; reason: TurnEndReason; };\n 'step/start': { turn: number; step: number; };\n 'step/end': { turn: number; step: number; };\n 'user/message': UserMessage;\n 'assistant/chunk': { turn: number; step: number; chunk: StreamChunk; };\n 'assistant/message': { turn: number; step: number; message: AssistantMessage; usage?: TokenUsage; interrupted?: true; };\n 'tool/call': { turn: number; step: number; callId:
|
|
1818
|
+
"declaration": "export interface SessionEventMap {\n 'turn/start': { turn: number; };\n 'turn/end': { turn: number; reason: TurnEndReason; };\n 'step/start': { turn: number; step: number; };\n 'step/end': { turn: number; step: number; };\n 'user/message': UserMessage;\n 'assistant/chunk': { turn: number; step: number; chunk: StreamChunk; };\n 'assistant/message': { turn: number; step: number; message: AssistantMessage; usage?: TokenUsage; interrupted?: true; };\n 'tool/call': { turn: number; step: number; callId: ToolCallId; name: string; arguments: string; };\n 'tool/result': { turn: number; step: number; message: ToolResultMessage; error?: { name: string; code: string; }; meta?: JsonValue; };\n 'request/header': { header: EpochHeader; reason: RequestHeaderReason; startsSeries?: true; };\n 'request/context': RequestContext;\n 'session/end-seed': Record<string, never>;\n 'agent/inbox/spliced': { target: InboxTarget; start: number; removedCount?: number; inserted: UserMessage[]; outcome?: 'canceled'; };\n 'approval/asked': { id: ApprovalRequestId; toolName: string; callId?: ToolCallId; reason?: string; };\n 'approval/decided': { id: ApprovalRequestId; outcome: ApprovalOutcome; };\n 'approval/policy': { policy: ApprovalPolicy; source?: 'delegation'; };\n 'tool/code-dispatch-start': PtcDispatchStartEventData;\n 'tool/code-dispatch': PtcDispatchEventData;\n 'agent-preset/selected': { agentPreset: string; };\n 'session/title': SessionTitleEventData;\n 'todo/write': { todos: TodoItem[]; };\n 'model/selection': ModelSelection;\n 'subagent/descriptor': SubagentDescriptorData;\n 'sandbox/mode': { mode: SandboxMode; source?: 'delegation'; };\n 'command/run': { commandId: CommandId; name: string; args?: string; source: CommandSource; };\n 'command/done': { commandId: CommandId; kind: 'success' | 'error'; text?: string; sourceEventSeq?: number; };\n 'team/member': { version: 1; teamId: TeamId; member: TeamMemberSnapshot; };\n 'team/task': { version: 1; teamId: TeamId; task: TeamTaskSnapshot; };\n 'team/message/queued': { version: 1; teamId: TeamId; message: TeamMessageSnapshot; };\n 'team/message/delivered': { version: 1; teamId: TeamId; messageId: TeamMessageId; targetId: SessionId; };\n 'goal/change': GoalChangeMeta;\n 'compaction/start': { compactionId: CompactionId; sourceCommandId?: CommandId; turn: number | null; };\n 'compaction/summary': { compactionId: CompactionId; sourceCommandId?: CommandId; summary: ContentBlock[]; shadowedRange: { start: number; end: number; }; shadowedSeqs: number[]; shadowedTokenCount: number; provider: string; model: string; maxTokens?: number; usage?: TokenUsage; } & ({ rawOutput: ContentBlock[]; llmStreamCall: true; } | { rawOutput?: ContentBlock[]; llmStreamCall?: never; });\n 'compaction/end': { compactionId: CompactionId; sourceCommandId?: CommandId; turn: number | null; error?: string; };\n 'compaction/prune': { shadowedRange: { start: number; end: number; }; shadowedSeqs: number[]; shadowedTokenCount: number; };\n}"
|
|
1719
1819
|
},
|
|
1720
1820
|
{
|
|
1721
1821
|
"name": "SessionEventType",
|
|
@@ -1733,6 +1833,10 @@ export const TYPERT = {
|
|
|
1733
1833
|
"name": "SessionReferenceSource",
|
|
1734
1834
|
"declaration": "export interface SessionReferenceSource {\n kind: 'session-reference';\n form: 'recall';\n version: 1;\n references: { sessionId: string; label: string; capturedThroughSeq: number | null; compacted: boolean; originalMessages: number; retainedMessages: number; omittedMessages: number; omittedBytes: number; truncated: boolean; inputIndex: number; }[];\n}"
|
|
1735
1835
|
},
|
|
1836
|
+
{
|
|
1837
|
+
"name": "SessionRequestId",
|
|
1838
|
+
"declaration": "export type SessionRequestId = Branded<'session-request-id'>;"
|
|
1839
|
+
},
|
|
1736
1840
|
{
|
|
1737
1841
|
"name": "SessionSurface",
|
|
1738
1842
|
"declaration": "export interface SessionSurface {\n readonly nodes: readonly number[];\n readonly replaceGeneration: number;\n}"
|
|
@@ -1753,9 +1857,29 @@ export const TYPERT = {
|
|
|
1753
1857
|
"name": "SessionTitleSource",
|
|
1754
1858
|
"declaration": "export type SessionTitleSource = { readonly kind: 'fallback'; } | { readonly kind: 'provider'; readonly provider: SessionTitleProviderId; readonly model?: SessionTitleModelProvenance; } | { readonly kind: 'user'; };"
|
|
1755
1859
|
},
|
|
1860
|
+
{
|
|
1861
|
+
"name": "SkillInvocationSource",
|
|
1862
|
+
"declaration": "export interface SkillInvocationSource {\n readonly kind: 'skill-invocation';\n readonly name: string;\n readonly form: 'instructions';\n}"
|
|
1863
|
+
},
|
|
1756
1864
|
{
|
|
1757
1865
|
"name": "StreamChunk",
|
|
1758
|
-
"declaration": "export type StreamChunk = { type: 'block-start'; index: number; blockType: ContentBlockType; } | { type: 'text-delta'; index: number; text: string; } | { type: 'reasoning-delta'; index: number; text: string; } | { type: 'tool-call-delta'; index: number; id:
|
|
1866
|
+
"declaration": "export type StreamChunk = { type: 'block-start'; index: number; blockType: ContentBlockType; } | { type: 'text-delta'; index: number; text: string; } | { type: 'reasoning-delta'; index: number; text: string; } | { type: 'tool-call-delta'; index: number; id: ToolCallId; name?: string; argumentsDelta: string; } | { type: 'block-end'; index: number; block: ContentBlock; } | { type: 'usage'; usage: TokenUsage; } | { type: 'finish'; reason: FinishReason; replayState?: ReplayEnvelope; };"
|
|
1867
|
+
},
|
|
1868
|
+
{
|
|
1869
|
+
"name": "SubagentDescriptorBase",
|
|
1870
|
+
"declaration": "export interface SubagentDescriptorBase {\n readonly version: number;\n readonly mode: 'one-shot' | 'continuable';\n readonly provider: string;\n}"
|
|
1871
|
+
},
|
|
1872
|
+
{
|
|
1873
|
+
"name": "SubagentDescriptorData",
|
|
1874
|
+
"declaration": "export type SubagentDescriptorData = OneShotSubagentDescriptorData | ContinuableSubagentDescriptorData;"
|
|
1875
|
+
},
|
|
1876
|
+
{
|
|
1877
|
+
"name": "SubagentReportMessageSource",
|
|
1878
|
+
"declaration": "export interface SubagentReportMessageSource {\n readonly kind: 'subagent-report';\n readonly form: 'relay';\n readonly senderSessionId: SessionId;\n}"
|
|
1879
|
+
},
|
|
1880
|
+
{
|
|
1881
|
+
"name": "SubagentSettledMessageSource",
|
|
1882
|
+
"declaration": "export interface SubagentSettledMessageSource {\n readonly kind: 'subagent-settled';\n readonly form: 'notice';\n readonly summary: string;\n readonly senderSessionId: SessionId;\n}"
|
|
1759
1883
|
},
|
|
1760
1884
|
{
|
|
1761
1885
|
"name": "SurfaceEventType",
|
|
@@ -1769,6 +1893,42 @@ export const TYPERT = {
|
|
|
1769
1893
|
"name": "SurfaceOp",
|
|
1770
1894
|
"declaration": "export type SurfaceOp = 'append' | { op: 'replace'; start: number; end: number; };"
|
|
1771
1895
|
},
|
|
1896
|
+
{
|
|
1897
|
+
"name": "TeamId",
|
|
1898
|
+
"declaration": "export type TeamId = Branded<'TeamId'>;"
|
|
1899
|
+
},
|
|
1900
|
+
{
|
|
1901
|
+
"name": "TeamMemberPhase",
|
|
1902
|
+
"declaration": "export type TeamMemberPhase = 'provisioning' | 'active' | 'failed';"
|
|
1903
|
+
},
|
|
1904
|
+
{
|
|
1905
|
+
"name": "TeamMemberSnapshot",
|
|
1906
|
+
"declaration": "export interface TeamMemberSnapshot {\n readonly id: SessionId;\n readonly name: string;\n readonly description: string;\n readonly provider: string;\n readonly context: 'fresh' | 'fork';\n readonly phase: TeamMemberPhase;\n readonly error?: string;\n}"
|
|
1907
|
+
},
|
|
1908
|
+
{
|
|
1909
|
+
"name": "TeamMessageId",
|
|
1910
|
+
"declaration": "export type TeamMessageId = Branded<'TeamMessageId'>;"
|
|
1911
|
+
},
|
|
1912
|
+
{
|
|
1913
|
+
"name": "TeamMessageSnapshot",
|
|
1914
|
+
"declaration": "export interface TeamMessageSnapshot {\n readonly id: TeamMessageId;\n readonly senderId: SessionId;\n readonly senderName: string;\n readonly targetId: SessionId;\n readonly delivery: 'quiet' | 'wakeup';\n readonly content: ContentBlock[];\n}"
|
|
1915
|
+
},
|
|
1916
|
+
{
|
|
1917
|
+
"name": "TeamMessageSource",
|
|
1918
|
+
"declaration": "export interface TeamMessageSource {\n readonly kind: 'team-message';\n readonly teamId: TeamId;\n readonly messageId: TeamMessageId;\n readonly senderId: SessionId;\n readonly senderName: string;\n}"
|
|
1919
|
+
},
|
|
1920
|
+
{
|
|
1921
|
+
"name": "TeamTaskId",
|
|
1922
|
+
"declaration": "export type TeamTaskId = Branded<'TeamTaskId'>;"
|
|
1923
|
+
},
|
|
1924
|
+
{
|
|
1925
|
+
"name": "TeamTaskSnapshot",
|
|
1926
|
+
"declaration": "export interface TeamTaskSnapshot {\n readonly id: TeamTaskId;\n readonly revision: number;\n readonly subject: string;\n readonly description: string;\n readonly status: TeamTaskStatus;\n readonly ownerId?: SessionId;\n readonly blockedBy: TeamTaskId[];\n readonly writeScopes: string[];\n}"
|
|
1927
|
+
},
|
|
1928
|
+
{
|
|
1929
|
+
"name": "TeamTaskStatus",
|
|
1930
|
+
"declaration": "export type TeamTaskStatus = 'pending' | 'in_progress' | 'completed' | 'deleted';"
|
|
1931
|
+
},
|
|
1772
1932
|
{
|
|
1773
1933
|
"name": "TextBlock",
|
|
1774
1934
|
"declaration": "export interface TextBlock {\n type: 'text';\n text: string;\n}"
|
|
@@ -1779,19 +1939,27 @@ export const TYPERT = {
|
|
|
1779
1939
|
},
|
|
1780
1940
|
{
|
|
1781
1941
|
"name": "TokenUsage",
|
|
1782
|
-
"declaration": "export interface TokenUsage {\n inputTokens: number;\n outputTokens: number;\n cacheReadTokens?: number;\n cacheWriteTokens?: number;\n reasoningTokens?: number;\n}"
|
|
1942
|
+
"declaration": "export interface TokenUsage {\n inputTokens: number;\n outputTokens: number;\n totalTokens?: number;\n cacheReadTokens?: number;\n cacheWriteTokens?: number;\n reasoningTokens?: number;\n}"
|
|
1783
1943
|
},
|
|
1784
1944
|
{
|
|
1785
1945
|
"name": "ToolCallBlock",
|
|
1786
|
-
"declaration": "export interface ToolCallBlock {\n type: 'tool-call';\n id:
|
|
1946
|
+
"declaration": "export interface ToolCallBlock {\n type: 'tool-call';\n id: ToolCallId;\n name: string;\n arguments: string;\n}"
|
|
1947
|
+
},
|
|
1948
|
+
{
|
|
1949
|
+
"name": "ToolCallId",
|
|
1950
|
+
"declaration": "export type ToolCallId = Branded<'ToolCallId'>;"
|
|
1787
1951
|
},
|
|
1788
1952
|
{
|
|
1789
1953
|
"name": "ToolMessageSource",
|
|
1790
|
-
"declaration": "export interface ToolMessageSource {\n kind: 'tool';\n callId:
|
|
1954
|
+
"declaration": "export interface ToolMessageSource {\n kind: 'tool';\n callId: ToolCallId;\n}"
|
|
1955
|
+
},
|
|
1956
|
+
{
|
|
1957
|
+
"name": "ToolRestriction",
|
|
1958
|
+
"declaration": "export interface ToolRestriction {\n readonly allow?: readonly string[];\n readonly deny?: readonly string[];\n}"
|
|
1791
1959
|
},
|
|
1792
1960
|
{
|
|
1793
1961
|
"name": "ToolResultBlock",
|
|
1794
|
-
"declaration": "export interface ToolResultBlock {\n type: 'tool-result';\n toolCallId:
|
|
1962
|
+
"declaration": "export interface ToolResultBlock {\n type: 'tool-result';\n toolCallId: ToolCallId;\n content: ContentBlock[];\n isError?: boolean;\n}"
|
|
1795
1963
|
},
|
|
1796
1964
|
{
|
|
1797
1965
|
"name": "ToolResultMessage",
|
|
@@ -4,7 +4,8 @@ import type {
|
|
|
4
4
|
TypertRemoteContribution,
|
|
5
5
|
} from '@deepseek-ai/dsh-typert-protocol'
|
|
6
6
|
import type { ApprovalRequestId, CordisDynamicPackageId, CordisDynamicPluginId, CordisDynamicPluginRunId, CordisDynamicRunMode, CordisErrorDetails, CordisInspectProviderManifest, CordisInspectQueryResolution, CordisInspectRequestId, CordisInspectResolveAck, DynamicCordisClientSource, DynamicCordisHostHalfResult, DynamicCordisInventoryRow, DynamicCordisInvokeResult, DynamicCordisRenderFailure, DynamicCordisResolveAck, DynamicCordisRunResolution, DynamicCordisRunResponse, DynamicCordisStopResponse, DynamicCordisUndefineReceipt } from '@deepseek-ai/dsh-cordis-host-runner/types'
|
|
7
|
-
import type {
|
|
7
|
+
import type { SessionId } from '@deepseek-ai/dsh-session/types'
|
|
8
|
+
import type { JsonValue } from '@deepseek-ai/dsh-util-values'
|
|
8
9
|
|
|
9
10
|
declare module '@deepseek-ai/dsh-typert-protocol' {
|
|
10
11
|
interface TypertRemoteNamespace$64796e616d6963436f7264697352756e6e6572 {
|
|
@@ -35,16 +35,16 @@ const _deepseek_ai_dsh_cordis_host_runner_dynamicCordisRunner_inventory_result$s
|
|
|
35
35
|
'pluginRunId': z.intersection(z.string(), z.unknown()),
|
|
36
36
|
'packageId': z.intersection(z.string(), z.unknown()),
|
|
37
37
|
'mode': z.union([z.literal("run"), z.literal("update")]),
|
|
38
|
-
'status': z.union([z.literal("
|
|
38
|
+
'status': z.union([z.literal("running"), z.literal("failed"), z.literal("rejected"), z.literal("awaiting-approval"), z.literal("cancelled"), z.literal("starting-host"), z.literal("client-pending"), z.literal("waiting"), z.literal("stopped")]),
|
|
39
39
|
'approvalRequestId': z.intersection(z.string(), z.unknown()).optional(),
|
|
40
40
|
'requiresApproval': z.boolean().optional(),
|
|
41
41
|
'host': z.object({
|
|
42
|
-
'status': z.union([z.literal("
|
|
42
|
+
'status': z.union([z.literal("pending"), z.literal("running"), z.literal("failed"), z.literal("waiting"), z.literal("stopped"), z.literal("absent")]),
|
|
43
43
|
'waitingFor': z.array(z.string()),
|
|
44
44
|
'error': z.string().optional(),
|
|
45
45
|
}),
|
|
46
46
|
'client': z.object({
|
|
47
|
-
'status': z.union([z.literal("
|
|
47
|
+
'status': z.union([z.literal("pending"), z.literal("running"), z.literal("failed"), z.literal("waiting"), z.literal("stopped"), z.literal("absent")]),
|
|
48
48
|
'waitingFor': z.array(z.string()),
|
|
49
49
|
'error': z.string().optional(),
|
|
50
50
|
}),
|
|
@@ -154,7 +154,7 @@ const _deepseek_ai_dsh_cordis_host_runner_dynamicCordisRunner_settleUserRun_para
|
|
|
154
154
|
})])
|
|
155
155
|
const _deepseek_ai_dsh_cordis_host_runner_dynamicCordisRunner_settleUserRun_result$schema = z.union([z.object({
|
|
156
156
|
'ok': z.literal(true),
|
|
157
|
-
'status': z.union([z.literal("
|
|
157
|
+
'status': z.union([z.literal("running"), z.literal("awaiting-approval"), z.literal("starting")]),
|
|
158
158
|
'pluginId': z.intersection(z.string(), z.unknown()),
|
|
159
159
|
'packageId': z.intersection(z.string(), z.unknown()),
|
|
160
160
|
'pluginRunId': z.intersection(z.string(), z.unknown()),
|
|
@@ -311,7 +311,7 @@ export const TYPERT_REMOTE = {
|
|
|
311
311
|
source: 'json',
|
|
312
312
|
codec: {
|
|
313
313
|
mode: 'strict',
|
|
314
|
-
typeSymbol: '@deepseek-ai/dsh-
|
|
314
|
+
typeSymbol: '@deepseek-ai/dsh-util-values#JsonValue',
|
|
315
315
|
schema: _deepseek_ai_dsh_cordis_host_runner_dynamicCordisRunner_invoke_parameter_3$schema,
|
|
316
316
|
},
|
|
317
317
|
},
|
package/lib/types/index.d.ts
CHANGED
|
@@ -7,8 +7,8 @@ import { Context } from '@deepseek-ai/cordis';
|
|
|
7
7
|
import type { Fiber } from '@deepseek-ai/cordis';
|
|
8
8
|
import z from '@deepseek-ai/schemastery';
|
|
9
9
|
import type { Agent } from '@deepseek-ai/dsh-agent';
|
|
10
|
-
import type { JsonValue } from '@deepseek-ai/dsh-session/types';
|
|
11
10
|
import { TypertRemoteService } from '@deepseek-ai/dsh-typert-protocol';
|
|
11
|
+
import type { JsonValue } from '@deepseek-ai/dsh-util-values';
|
|
12
12
|
import type { DynamicCordisDefineReceipt, DynamicCordisDefineRequest, DynamicCordisPackageInspection, DynamicCordisPluginInspection, DynamicCordisReference } from './registry.ts';
|
|
13
13
|
import type { ApprovalRequestId, CordisDynamicPackageId, CordisDynamicPluginId, CordisDynamicPluginRunId, CordisErrorDetails, CordisDynamicRunMode, CordisInspectProviderManifest, CordisInspectQueryResolution, CordisInspectRequestId, CordisInspectResolveAck, DynamicCordisClientSource, DynamicCordisHostHalfResult, DynamicCordisInventoryRow, DynamicCordisInvokeResult, DynamicCordisRenderFailure, DynamicCordisResolveAck, DynamicCordisRunAttempt, DynamicCordisRunResolution, DynamicCordisRunResponse, DynamicCordisStopResponse, DynamicCordisUndefineReceipt } from './types.ts';
|
|
14
14
|
export type * from './types.ts';
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { Service } from '@deepseek-ai/cordis';
|
|
3
3
|
import type { Context } from '@deepseek-ai/cordis';
|
|
4
4
|
import type { Agent } from '@deepseek-ai/dsh-agent';
|
|
5
|
-
import type
|
|
5
|
+
import { type JsonValue } from '@deepseek-ai/dsh-util-values';
|
|
6
6
|
import type { CordisInspectPlatform, CordisInspectProviderManifest, CordisInspectProviderView, CordisInspectQueryResolution, CordisInspectRequestId, CordisInspectResolveAck } from './types.ts';
|
|
7
7
|
/** Context supplied to a Host inspect query. */
|
|
8
8
|
export interface HostCordisInspectQueryContext {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** Host registry for model-visible, read-only Cordis capability queries. */
|
|
2
2
|
import { Service } from '@deepseek-ai/cordis';
|
|
3
|
-
import { snapshotJsonValue } from '@deepseek-ai/dsh-
|
|
3
|
+
import { snapshotJsonValue } from '@deepseek-ai/dsh-util-values';
|
|
4
4
|
import { assertSupportedJsonSchema, validateJsonSchemaValue } from '@deepseek-ai/dsh-tools';
|
|
5
5
|
/** Registry and cross-page router behind the two model-facing inspect tools. */
|
|
6
6
|
export class CordisInspectRegistryService extends Service {
|
package/lib/types/types.d.ts
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
* @module @deepseek-ai/dsh-cordis-host-runner/types
|
|
4
4
|
*/
|
|
5
5
|
import type { Branded } from '@deepseek-ai/dsh-brand';
|
|
6
|
-
import type {
|
|
6
|
+
import type { SessionId } from '@deepseek-ai/dsh-session/types';
|
|
7
|
+
import type { JsonValue } from '@deepseek-ai/dsh-util-values';
|
|
7
8
|
/** Stable identity of one dynamic plugin instance. */
|
|
8
9
|
export type CordisDynamicPluginId = Branded<'CordisDynamicPluginId'>;
|
|
9
10
|
/** Identity of one immutable package version belonging to a dynamic plugin. */
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepseek-ai/dsh-cordis-host-runner",
|
|
3
3
|
"description": "Dynamic package definition registry, host-half sandbox lifecycle, and invoke handler table for model-mounted dual-half packages",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.2-alpha.2",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -50,29 +50,30 @@
|
|
|
50
50
|
"license": "MIT",
|
|
51
51
|
"dependencies": {
|
|
52
52
|
"zod": "^4.4.3",
|
|
53
|
-
"@deepseek-ai/
|
|
53
|
+
"@deepseek-ai/dsh-util-values": "^0.1.2-alpha.2",
|
|
54
|
+
"@deepseek-ai/schemastery": "^3.18.2"
|
|
54
55
|
},
|
|
55
56
|
"peerDependencies": {
|
|
56
|
-
"@deepseek-ai/
|
|
57
|
-
"@deepseek-ai/dsh-
|
|
58
|
-
"@deepseek-ai/dsh-
|
|
59
|
-
"@deepseek-ai/dsh-llm": "^0.1.
|
|
60
|
-
"@deepseek-ai/dsh-
|
|
61
|
-
"@deepseek-ai/dsh-
|
|
62
|
-
"@deepseek-ai/dsh-tools": "^0.1.
|
|
63
|
-
"@deepseek-ai/dsh-
|
|
64
|
-
"@deepseek-ai/
|
|
57
|
+
"@deepseek-ai/cordis": "^4.0.2",
|
|
58
|
+
"@deepseek-ai/dsh-agent": "^0.1.2-alpha.2",
|
|
59
|
+
"@deepseek-ai/dsh-brand": "^0.1.2-alpha.2",
|
|
60
|
+
"@deepseek-ai/dsh-llm": "^0.1.2-alpha.2",
|
|
61
|
+
"@deepseek-ai/dsh-scope": "^0.1.2-alpha.2",
|
|
62
|
+
"@deepseek-ai/dsh-session": "^0.1.2-alpha.2",
|
|
63
|
+
"@deepseek-ai/dsh-tools": "^0.1.2-alpha.2",
|
|
64
|
+
"@deepseek-ai/dsh-typert-protocol": "^0.1.2-alpha.2",
|
|
65
|
+
"@deepseek-ai/dsh-invariants": "^0.1.2-alpha.2"
|
|
65
66
|
},
|
|
66
67
|
"devDependencies": {
|
|
67
|
-
"@deepseek-ai/cordis": "^4.0.
|
|
68
|
-
"@deepseek-ai/
|
|
69
|
-
"@deepseek-ai/
|
|
70
|
-
"@deepseek-ai/dsh-brand": "^0.1.
|
|
71
|
-
"@deepseek-ai/dsh-invariants": "^0.1.
|
|
72
|
-
"@deepseek-ai/dsh-llm": "^0.1.
|
|
73
|
-
"@deepseek-ai/dsh-scope": "^0.1.
|
|
74
|
-
"@deepseek-ai/dsh-
|
|
75
|
-
"@deepseek-ai/dsh-
|
|
76
|
-
"@deepseek-ai/dsh-
|
|
68
|
+
"@deepseek-ai/cordis": "^4.0.2",
|
|
69
|
+
"@deepseek-ai/cordis-plugin-timer": "^1.1.4",
|
|
70
|
+
"@deepseek-ai/dsh-agent": "^0.1.2-alpha.2",
|
|
71
|
+
"@deepseek-ai/dsh-brand": "^0.1.2-alpha.2",
|
|
72
|
+
"@deepseek-ai/dsh-invariants": "^0.1.2-alpha.2",
|
|
73
|
+
"@deepseek-ai/dsh-llm": "^0.1.2-alpha.2",
|
|
74
|
+
"@deepseek-ai/dsh-scope": "^0.1.2-alpha.2",
|
|
75
|
+
"@deepseek-ai/dsh-tools": "^0.1.2-alpha.2",
|
|
76
|
+
"@deepseek-ai/dsh-session": "^0.1.2-alpha.2",
|
|
77
|
+
"@deepseek-ai/dsh-typert-protocol": "^0.1.2-alpha.2"
|
|
77
78
|
}
|
|
78
79
|
}
|