@dsh-enhanced/assistant-delivery 0.1.3
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/LICENSE +21 -0
- package/README.md +225 -0
- package/cordis.patch.yml +29 -0
- package/lib/agent-runtime.d.ts +112 -0
- package/lib/agent-runtime.d.ts.map +1 -0
- package/lib/agent-runtime.js +1866 -0
- package/lib/agent-runtime.js.map +1 -0
- package/lib/canonical.d.ts +18 -0
- package/lib/canonical.d.ts.map +1 -0
- package/lib/canonical.js +83 -0
- package/lib/canonical.js.map +1 -0
- package/lib/coordinator.d.ts +124 -0
- package/lib/coordinator.d.ts.map +1 -0
- package/lib/coordinator.js +676 -0
- package/lib/coordinator.js.map +1 -0
- package/lib/inbound-images.d.ts +38 -0
- package/lib/inbound-images.d.ts.map +1 -0
- package/lib/inbound-images.js +267 -0
- package/lib/inbound-images.js.map +1 -0
- package/lib/index.d.ts +12 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +12 -0
- package/lib/index.js.map +1 -0
- package/lib/operator.d.ts +23 -0
- package/lib/operator.d.ts.map +1 -0
- package/lib/operator.js +38 -0
- package/lib/operator.js.map +1 -0
- package/lib/service.d.ts +269 -0
- package/lib/service.d.ts.map +1 -0
- package/lib/service.js +1698 -0
- package/lib/service.js.map +1 -0
- package/lib/session-commands.d.ts +17 -0
- package/lib/session-commands.d.ts.map +1 -0
- package/lib/session-commands.js +39 -0
- package/lib/session-commands.js.map +1 -0
- package/lib/sqlite.d.ts +8 -0
- package/lib/sqlite.d.ts.map +1 -0
- package/lib/sqlite.js +411 -0
- package/lib/sqlite.js.map +1 -0
- package/lib/store.d.ts +353 -0
- package/lib/store.d.ts.map +1 -0
- package/lib/store.js +2614 -0
- package/lib/store.js.map +1 -0
- package/lib/tools.d.ts +4 -0
- package/lib/tools.d.ts.map +1 -0
- package/lib/tools.js +54 -0
- package/lib/tools.js.map +1 -0
- package/lib/types.d.ts +329 -0
- package/lib/types.d.ts.map +1 -0
- package/lib/types.js +2 -0
- package/lib/types.js.map +1 -0
- package/lib/version.d.ts +2 -0
- package/lib/version.d.ts.map +1 -0
- package/lib/version.js +2 -0
- package/lib/version.js.map +1 -0
- package/package.json +122 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 dsh-enhanced contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
# @dsh-enhanced/assistant-delivery
|
|
2
|
+
|
|
3
|
+
`assistant-delivery` 是个人助理唯一的、与厂商无关的消息核心。它把外部身份、一次性配对、conversation→DSH session 绑定、持久 Inbox/Outbox、adapter 生命周期、receipt、重试、对账和 dead letter 放在一个可审计边界内;飞书、Telegram 等包只实现协议适配。
|
|
4
|
+
|
|
5
|
+
本包不声明 exactly-once。它保证发送前先持久化 intent;若平台可能已经接收但响应丢失,则保留 `unknown_after_send`,只走 adapter 对账或显式 operator 决策,不盲目重发。
|
|
6
|
+
|
|
7
|
+
## 兼容性与安装顺序
|
|
8
|
+
|
|
9
|
+
- DSH / Agent / Agent Presets / LLM / Session:`>=0.1.0-rc.8 <0.2.0`
|
|
10
|
+
- `@deepseek-ai/dsh-attachment`:`>=0.1.0-rc.8 <0.2.0`,仅图片入站路径需要的可选 Host service
|
|
11
|
+
- `@deepseek-ai/dsh-commands`:`>=0.1.0-rc.8 <0.2.0`,可选 Host command service;按 `0.1.0-rc.8` 命令语法/执行契约只委托安全的原生 `/compact`。`/help`、`/status`、`/session`、`/new`、`/clear`、`/stop` 及模型/权限控制命令都由 Delivery 自有;其他原生命令即使被宿主发布也不委托、不进入 LLM
|
|
12
|
+
- `@deepseek-ai/dsh-permission-presets` / `@deepseek-ai/dsh-sandbox-policy` / `@deepseek-ai/dsh-user-approval`:`>=0.1.0-rc.8 <0.2.0`,权限档位命令使用 preset service,并通过 sandbox/approval 包的 canonical setter 固化执行事实;所需 Host service 缺失时命令 fail closed
|
|
13
|
+
- Cordis:`^4.0.1`
|
|
14
|
+
- `@dsh-enhanced/assistant-policy`:`>=0.1.0 <0.2.0`,硬依赖
|
|
15
|
+
- 真实多轮恢复还要求 profile 已配置官方 `ctx.sessionPersistence` provider;缺失时新建空 session 可以成功,但冷 resume 会进入有界失败/死信路径。
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
dsh plugin --profile headless add @dsh-enhanced/assistant-policy
|
|
19
|
+
dsh plugin --profile headless add @dsh-enhanced/assistant-delivery
|
|
20
|
+
dsh --profile headless --dump-config
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
标准 DSH `base` patch 已挂载 `@deepseek-ai/dsh-attachment-local`,因此由标准 profile 组合出来的 `web` / `headless` 部署无需重复安装 AttachmentStore;图片对象会以 content-addressed 形式保存在 `$DSH_HOME/attachments/v1`。如果自定义 profile 绕过了标准 `base`,必须自行挂载一个提供 `ctx.attachments` 的 `@deepseek-ai/dsh-attachment` 实现。服务缺失时只有图片路径会以 `attachment-store-unavailable` fail closed:不会调用渠道下载、不会把 provider reference 或伪占位文字交给 Agent,也不会退化为内存附件;普通文本仍按原路径工作。
|
|
24
|
+
|
|
25
|
+
当前 AttachmentStore 没有 reference-aware GC,也没有按 principal、时间窗口或全局容量实施磁盘配额。下载保存成功后若进程在 session 引用持久化前崩溃或授权被撤销,可能留下不可达的 content-addressed 对象;生产部署必须为该目录设置文件系统配额和容量监控,并由运维在能够证明无会话引用后清理孤儿对象。
|
|
26
|
+
|
|
27
|
+
Patch 通过 `inject: [assistantPolicy]` 固定加载策略依赖;入站 Agent runtime 另外等待 `agents`、`sessions` 与 `llm` 就绪。Web profile 提供 `agentPresets` 时会解析并挂载 session preset;不带 roster 的 headless profile 保留宿主全局工具组合。`schedulerEnabled` 默认开启,因此生产环境必须由 launchd、systemd 或 Docker restart policy 监管 DSH 进程。
|
|
28
|
+
|
|
29
|
+
## 配置
|
|
30
|
+
|
|
31
|
+
| 字段 | 默认值 | 含义 |
|
|
32
|
+
| --- | --- | --- |
|
|
33
|
+
| `databasePath` | `$DSH_HOME/assistant-delivery/state.sqlite` | 私有 SQLite 权威账本,必须为绝对路径 |
|
|
34
|
+
| `spoolPath` | `$DSH_HOME/assistant-delivery/spool` | 预留的私有附件隔离目录,必须为绝对路径 |
|
|
35
|
+
| `schedulerEnabled` | `true` | 启用 Inbox/Outbox 后台 pump |
|
|
36
|
+
| `tickIntervalMs` | `1000` | pump 周期 |
|
|
37
|
+
| `leaseMs` | `30000` | 单次 Inbox/Outbox/模型确认 claim 租约,也是模型确认实时解析的 deadline;运行中的 Inbox turn 与 Outbox send 都会周期续租 |
|
|
38
|
+
| `maxAttempts` | `5` | 发送与 unknown 对账各自的自动尝试上限;owner 显式 retry 会在不重置审计计数的前提下再授予一次尝试;无对账能力的 unknown 保持待人工处理 |
|
|
39
|
+
| `maxConcurrency` | `4` | 跨 binding 并发数;同一 binding 始终串行 |
|
|
40
|
+
| `maxTextBytes` | `65536` | 单条入站/出站正文 UTF-8 上限 |
|
|
41
|
+
| `retryBaseMs` / `retryMaxMs` | `1000` / `300000` | 指数退避边界;adapter 的 Retry-After 是下限 |
|
|
42
|
+
| `pairingTtlMs` / `pairingMaxAttempts` | `600000` / `5` | 一次性本地配对时效与尝试上限 |
|
|
43
|
+
| `defaultWorkspace` | `$DSH_HOME/assistant-workspace` | 新 session 的绝对工作区;fresh create 前自动创建缺失目录 |
|
|
44
|
+
| `defaultAgentPreset` | `standard` | 新 session 解析并挂载的 preset;该内置 preset 提供 Bash、文件、检索、Skills 等完整编码能力 |
|
|
45
|
+
| `policyRef` | `owner-dm` | 固化在 binding 上的策略引用标签 |
|
|
46
|
+
| `agentProvider` / `agentModel` | `deepseek-official` / `deepseek-v4-flash` | 渠道 Agent 的部署默认模型;会话可用 `/model` 覆盖 |
|
|
47
|
+
| `toolCapableProviders` | `[deepseek-official]` | 尚未发布 registry metadata 的上游原生工具 provider 审计列表;在 `unknownRouteToolCalls: deny` 下作为白名单生效 |
|
|
48
|
+
| `unknownRouteToolCalls` | `allow` | 未发布任何工具能力声明的 route 如何准入;`deny` 切换为严格白名单。provider 显式声明 `none` 时两种取值都 fail closed |
|
|
49
|
+
| `agentMaxOutputTokens` | `8192` | 单轮模型输出上限 |
|
|
50
|
+
| `modelPickerTtlMs` | `900000` | `/model` 选择卡片的签名提交有效期;范围 1 分钟至 24 小时 |
|
|
51
|
+
| `permissionPickerTtlMs` | `900000` | `/permissions` 三档权限卡片的签名提交有效期;范围 1 分钟至 24 小时 |
|
|
52
|
+
| `toolApprovalTtlMs` | `300000` | 当前 open turn 的即时工具审批有效期;范围 1 秒至 5 分钟 |
|
|
53
|
+
|
|
54
|
+
所有可变部署值都经过 Schemastery 校验。每个 binding 会持久固定 workspace 与已解析的 preset id;有 roster 时,fresh create 和 cold resume 都在 Agent 发布前挂载该 preset,不能把 session header 中的 `agentPreset` 当成已经完成组合。fresh create 的新 workspace 使用 `0700` 请求模式,已有目录的权限不会被改写;cold resume 只验证持久 workspace 仍是目录,不会在仓库被删除或网络盘掉线时悄悄创建一个空目录。SQLite 使用 `WAL`、`synchronous=FULL`、foreign keys、busy timeout 和 forward-only schema;私有目录/数据库权限分别收窄为 `0700` / `0600`,未来 schema 会拒绝打开。
|
|
55
|
+
|
|
56
|
+
## Policy 最小示例
|
|
57
|
+
|
|
58
|
+
默认无规则即全部拒绝。下面只是字段示意,请把 account、tenant、user、workspace 和 automation id 收窄到自己的真实值:
|
|
59
|
+
|
|
60
|
+
```yaml
|
|
61
|
+
rules:
|
|
62
|
+
- id: local-pairing
|
|
63
|
+
effect: allow
|
|
64
|
+
subject: { kind: external, id: "local:owner-cli" }
|
|
65
|
+
actions: [pair.issue, pair.link, delivery.resolve]
|
|
66
|
+
resource: { kind: message, id: "*" }
|
|
67
|
+
context: { initiators: [foreground] }
|
|
68
|
+
- id: owner-lark-ingress
|
|
69
|
+
effect: allow
|
|
70
|
+
subject: { kind: external, id: "lark/my-bot/my-tenant/my-user" }
|
|
71
|
+
actions: [pair.confirm, ingest, approval.decide]
|
|
72
|
+
resource: { kind: message, id: "*" }
|
|
73
|
+
context: { initiators: [external] }
|
|
74
|
+
- id: owner-channel-reply
|
|
75
|
+
effect: allow
|
|
76
|
+
subject: { kind: agent, id: standard, workspace: "/absolute/workspace" }
|
|
77
|
+
actions: [reply]
|
|
78
|
+
resource: { kind: message, id: "*" }
|
|
79
|
+
context: { initiators: [external] }
|
|
80
|
+
- id: owner-channel-bash
|
|
81
|
+
effect: allow
|
|
82
|
+
subject: { kind: agent, id: standard, workspace: "/absolute/workspace" }
|
|
83
|
+
actions: [execute]
|
|
84
|
+
resource: { kind: tool, id: bash }
|
|
85
|
+
context: { initiators: [external] }
|
|
86
|
+
- id: one-automation-send
|
|
87
|
+
effect: allow
|
|
88
|
+
subject: { kind: background, id: daily-review, workspace: "/absolute/workspace" }
|
|
89
|
+
actions: [approval.send, send]
|
|
90
|
+
resource: { kind: message, id: "binding_*" }
|
|
91
|
+
context: { initiators: [background] }
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
能力挂载、Policy 可达性和执行审查是分层的门:preset mount 决定 `bash`、`read`、`glob`、`grep` 等工具是否进入 Agent 目录,Policy 再按主体与 initiator 授权。安装器默认为本地 Web/direct `foreground` Agent 写入跨 preset/workspace 的通用 capability 规则,并为 Delivery 写入精确 preset + 绝对 workspace + canonical external principal + `external` 规则;Delivery 在每次 create/resume 时从 binding/envelope 绑定同一 principal。通配 action/resource 同时覆盖动态工具和 `memory.search`、`wiki.read`、`automation.propose` 等插件内部二次 Policy 动作,而 `background` 不会因此放宽。自定义部署可使用更窄的 allowlist 或显式 deny,deny 始终优先。message ingress/reply 使用 `resource.id: "*"` 是预期行为。`policyRef` 目前只是 binding 上的审计标签,不会把规则自动收窄为 DM;同一 owner principal 在群内 @ 机器人时仍会使用其精确 external Agent 规则。
|
|
95
|
+
|
|
96
|
+
`issuePairing()`、`linkPrincipal()`、`resolveDeadLetter()` 是可信本地控制面 API,不注册为模型工具。配对 code 只返回一次,数据库只保存随机 salt 的 scrypt hash;空 allowlist 不会把第一位来信者设成 owner。跨平台 principal 必须分别配对后再由 owner 显式 link。
|
|
97
|
+
|
|
98
|
+
`pairPrincipalLocally()` 是给安装向导使用的更窄离线入口:调用方必须已经拥有私有 Delivery SQLite 的本机文件权限,并提供完整 typed principal;函数内部仍走一次 challenge/confirm 事务,只返回 principal 记录,不返回 code。`lark-channel` 向导先用一次性 DM 短语确认具体 `open_id`,再调用该入口;普通 Agent、外部消息和后台任务都无法访问它。
|
|
99
|
+
|
|
100
|
+
## Adapter contract
|
|
101
|
+
|
|
102
|
+
渠道包通过 `ctx.assistantDelivery.registerAdapter()` 注册精确的 `(channel, account)`:
|
|
103
|
+
|
|
104
|
+
- `start({ accept, receipt })` 必须等 `accept()` 成功返回后才 ack/cursor;此时 event 已经持久化。
|
|
105
|
+
- `send(intent, signal)` 只能返回 `accepted`、可证明 `not-sent` 或 `unknown`。HTTP 200/平台 request accepted 只叫 `accepted`,不能伪装成 delivered/read。
|
|
106
|
+
- 429/明确 5xx 未发送应给出 `retryable` 与可选 `retryAfterMs`;永久 4xx 进入 dead。
|
|
107
|
+
- 请求可能已到平台但 response 丢失时返回 `unknown`。若声明 `reconcileUnknownSend` capability,必须实现对账,并使用独立的有界对账 attempt;连续无法判定达到上限后进入 dead,释放同 lane 后续消息。未声明该能力时记录保持 `unknown_after_send`,不会被领取为空对账 attempt,直到 owner 显式 retry/cancel。
|
|
108
|
+
- receipt 必须带同一个 channel、account、provider message id;状态只允许单调 `accepted→delivered→read`。
|
|
109
|
+
- adapter 的 socket、timer、SDK client 和 listener 必须由 `start()` disposer 释放。
|
|
110
|
+
|
|
111
|
+
内部身份始终是结构化的 `ExternalPrincipalKey`、`ConversationRef` 与 `ConversationBinding`,不会从 `platform:chat:thread` 字符串反解析路由。DM 不允许 thread;group 入口要求渠道提供显式且稳定的 thread,可以是真实 provider root,也可以是渠道命名空间内按 principal 派生的顶层合成 lane。binding 仍固定精确 principal,任何同 conversation 的另一 principal 都会在进入 session 前 dead-letter,不能共享既有 owner 上下文。Lark 顶层群消息使用按发送者派生的合成 lane,真实回复串继续按 `root_id` 隔离。
|
|
112
|
+
|
|
113
|
+
## Agent 与工具
|
|
114
|
+
|
|
115
|
+
获批入站正文以 user-role message 写入 DSH,source 固定包含:
|
|
116
|
+
|
|
117
|
+
```json
|
|
118
|
+
{ "kind": "delivery", "channel": "lark", "account": "my-bot", "eventId": "...", "trust": "untrusted" }
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
受支持的图片入站不会把渠道资源 key 当作正文。Delivery 在确认 binding、Policy、当前模型明确声明 `image` input modality 且 AttachmentStore 可用后,才调用原 adapter 的窄图片下载接口;通过 store 的批量限额、格式解码和持久写入后,只把返回的 `ImageAttachmentRef` 作为 `ImageBlock` 追加到 session。下载后的字节由 AttachmentStore 管理,session 重启和 fork 复用同一个不可变引用,不会再次访问渠道。命令、文件、音频、视频和 sticker 不进入这条下载路径。
|
|
122
|
+
|
|
123
|
+
真实 principal、tenant、token 不注入 prompt。每个 Delivery SQLite 在首次创建时持久生成随机实例命名空间;新 binding 的 session id 由该命名空间 + conversation + generation 确定生成。数据库重开会复用同一命名空间和既有 binding,数据库删除重建或另一个 profile 的独立数据库则得到不同命名空间,避免共享 DSH session 日志根时串用旧上下文;已持久 binding 始终按自身 `sessionId` 冷恢复,不受后续算法变化影响。`/new` 新建下一 generation 并保留旧 session。有 roster 时,binding 中的 preset 会在每次 create/resume 时重新解析并挂载到 Agent scope,因此 Web profile 可以继续关闭全局 Bash/FS,而渠道 Agent 仍获得自己的 preset 工具;无 roster 的 headless profile则沿用宿主全局组合。lookup/create 进程内 single-flight,SQLite unique constraint 是最终冲突边界。
|
|
124
|
+
|
|
125
|
+
## 会话命令与持久上下文
|
|
126
|
+
|
|
127
|
+
- `/help`:列出当前实际可用的命令。
|
|
128
|
+
- `/status`(别名 `/session`):显示 session 代次与指纹、上下文消息数、已记录轮次和当前模型。
|
|
129
|
+
- `/new`(别名 `/clear`):停止当前任务并切换到空白的下一 generation;旧 session 及历史不删除。
|
|
130
|
+
- `/stop`:停止当前任务,保留当前 session 与已持久的上下文。
|
|
131
|
+
- `/compact`:仅在当前 DSH command service/preset 实际发布时出现;通过原生命令面执行,不交给模型。
|
|
132
|
+
|
|
133
|
+
渠道 command envelope 只接受从正文第一字节开始的小写 ASCII slash 语法。未知命令、当前 preset 未发布的命令,以及大写、空命令等非法 slash 形态都只返回确定性帮助/错误,绝不作为自然语言进入 LLM。普通 Agent turn 只有在 session persistence `flush()` 明确返回 `true` 后才入队最终回复;返回 `false` 或抛错时不宣称任务成功。
|
|
134
|
+
|
|
135
|
+
需要 resume 的命令遇到已知的持久化格式不兼容、事件类型缺失或日志损坏时,只返回有界诊断码与恢复建议,不回显 prompt/历史,也不删除原 session;可在修复对应 DSH 插件后重试,或用 `/new` 开始空白会话。
|
|
136
|
+
|
|
137
|
+
`/stop` 与 `/new` 的 cancel-and-drain 强保证目前只覆盖同一 Host 进程;在该边界内,`/new` 的 generation rotation 与命令 Inbox 已原子提交,后到消息不会夹入旧 generation。共享 SQLite 的多 Host 部署可持久 fence 尚未 dispatch 的较早 Inbox,但还没有跨 Host cancel channel,已在另一 Host dispatch 的 turn 不保证立即停止;本包不宣称跨 Host 全局 exactly-once 停止/换代。
|
|
138
|
+
|
|
139
|
+
渠道控制命令在进入 Agent 前处理,因此默认模型未安装或临时不可用时,仍可自助恢复:
|
|
140
|
+
|
|
141
|
+
```text
|
|
142
|
+
/model
|
|
143
|
+
/model use codex-subscription/default
|
|
144
|
+
/model reset
|
|
145
|
+
/permissions
|
|
146
|
+
/permission ask
|
|
147
|
+
/permission auto
|
|
148
|
+
/permission full confirm
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
`/model` 从宿主 `ctx.llm` 的实时 provider/model 目录生成受限的 typed `model-picker` intent,不发起模型生成;每个模型会显式关联它自己的 `effortIds`,而不是共享全局 effort 并集。支持它的渠道可以据此显示“分组、模型、effort”三级联动选择和确认按钮,不支持它的渠道会把该 intent 明确拒绝而不会降级为任意卡片 JSON。持久 selection 会先投影为不含 `updatedAt/version` 的纯路由再进入严格 intent 边界;如果目录中的异常数据仍使卡片校验失败,系统会立即退回完整纯文本目录,确定性校验错误不会重试。某个 provider 或模型能力解析失败不影响其他项,最多载入 20 个 provider、50 个模型、每模型 20 档 effort,并且全目录最多 20 个不同 effort id。
|
|
152
|
+
|
|
153
|
+
卡片提交后,Delivery 会再次核对 active binding、精确 principal/chat 和 Policy,并用实时 `resolveModelInfo()` 验证 provider/model 及该模型支持的 effort;通过后把三项选择按 canonical conversation 持久化到 Delivery SQLite。选择从下一条普通消息生效,保留当前 session 上下文,跨 `/new` 和 Host 重启仍有效。卡片可选择“默认(由模型决定)”;`/model use` 保留为无卡片渠道和排错时的文字后备,`/model reset` 删除会话覆盖并恢复 `agentProvider` / `agentModel`。模型目录按宿主约定是建议性的,最终调用是否成功仍由对应 adapter 和账号认证决定。
|
|
154
|
+
|
|
155
|
+
`/permissions`(别名 `/permission`)只允许当前 active binding 的精确 owner 使用,命令本身不会进入 Agent 或触发 LLM。支持 typed `permission-picker` 的私聊渠道会显示“请求批准(ask)/帮我批准(auto)/完全访问权限(full)”三档卡片并标出当前档位;不支持卡片或渲染失败时自动退回含同等信息的文字命令。前两档都使用 `workspace-write + ask`,区别是持久 reviewer 为 `user` 或 `auto-review`。`full` 使用 `danger-full-access + never + none`,可访问网络及任意文件;卡片按钮带原生风险确认,文字入口则由 `/permission full` 显示橙色警告,必须再次发送 `/permission full confirm` 才切换。
|
|
156
|
+
|
|
157
|
+
权限卡片作为受限 Outbox intent 持久化,并用独立 HMAC 域绑定原始 route、精确 owner、binding version、session、权限状态指纹、Policy 紧急停止版本、目标档位和有效期。点击时还必须匹配原卡的 provider message id,并重新核对 active owner/binding、DM、Policy 与 session;转发、错人、跨 chat、篡改、过期、`/new` 后的旧卡,以及权限状态或紧急停止版本变化后的旧卡都会明确提示失效。最终提交在权限 mutation 前、reviewer 等待后和 session flush 后重复核对紧急停止版本,因此紧急停止开→关的 ABA 也只会触发 ask 补偿,不会完成旧卡提权。同一张卡的第一次选择进入原 binding 的 durable Inbox 串行队列;点击 Toast 只表示“已受理”,真正切换成功会另发持久回复。平台重投同一选择幂等,相反选择冲突而不会晚到覆盖;需要再次切档时应重新发送 `/permissions`。
|
|
158
|
+
|
|
159
|
+
原生 DSH 设置与 Web 权限面板会写 preset、sandbox 和 approval。生产表的 `workspace-write` / `auto` / `danger-full-access` 已由 AssistantPolicy 直接解释为 `user` / `auto-review` / `none`,所以 Web 与 Delivery 可互相切档且后写者获胜,不再为 canonical 三档补 custom reviewer。只有单 workspace preset、动态 id 和旧 session 继续使用兼容 reviewer event;非 canonical legacy full 仍经过严格迁移与 flush barrier。
|
|
160
|
+
|
|
161
|
+
旧版本中,这个缺口会产生一个很迷惑的症状:session 看似已经是 native full,但 reviewer 缺失会保守折叠成 `user`,AssistantPolicy 因而把未知/敏感工具送去 `ask-review`;同一 session 的 `approval=never` 又会在渠道审批展示前直接拒绝,上游最终误写成 `"the user rejected tool"`,所以用户既没看到弹窗也没有机会批准。迁移后精确 full 会持久补齐 `reviewer=none`;同时进度适配器会把嵌套 `tool-result.isError=true` 显示为工具失败,而不是继续显示“已完成”。
|
|
162
|
+
|
|
163
|
+
档位从 `ctx.permissionPresets.resolve()` 动态匹配:一个 `workspace-write + ask` 候选兼容旧版共享 ask/auto,两个候选按声明顺序映射 ask/auto,更多候选或多个 full 候选会失败关闭;full 候选必须唯一。目标表指纹也进入权限卡状态哈希,防止卡片发出后配置漂移。命令会显式固化 sandbox/approval;canonical 三档写官方 preset,动态/共享目标只在必要时写兼容 reviewer。mutation、flush、controller 或回复失败后会收敛并持久化到 ask;只有确认 ask 已 durable 且终态回复已经进入同一 Outbox,Inbox 才能结束,不会用“持久化结果不确定”冒充终态。
|
|
164
|
+
|
|
165
|
+
权限命令在第一次 reviewer/policy/sandbox mutation 前还必须先取得 Inbox 的 durable dispatch/recovery marker;每个异步边界后都复核 abort 与租约。若进程退出、续租失败、flush 未确认、依赖尚未就绪或回复入队失败,该 marker 会绕过普通 `maxAttempts`,在原 binding 串行 lane 中继续恢复,直到确认已持久化目标并补发成功终态,或安全收敛到 ask 后补发失败/取消终态。`/stop` 和 `/new` 会在 abort 前把正在执行的权限命令原子改标为 cancelled recovery;旧命令不会以 `processor-ambiguous` 终止,也不会从原始文本重新制造一次可能已取消的 full 提权。
|
|
166
|
+
|
|
167
|
+
普通消息真正 resume Agent 时,Delivery 会在 preset 挂载完成后检查最终 scoped tool schemas。非空工具时,provider 通过 `@dsh-enhanced/llm-route-capabilities` 声明 `native`/`bridge` 即放行。DSH 的 `generate` 契约对所有 adapter 都接受 `tools`,因此工具调用是 adapter 基线能力:未发布任何声明的 route(pi-ai 等内置/网关 provider 从不发布 registry metadata)默认按 `unknownRouteToolCalls: allow` 准入,避免整类可用 route 被误拒。需要严格白名单的部署设为 `deny`,此时只放行 `toolCapableProviders`。provider 显式声明 `none` 时始终 fail closed,不受上述任何一项影响。Claude、Cursor、Grok 和 Codex CLI 等 text-only route 因此会在 `followup()`、认证和子进程之前返回可操作的 `/model` 提示;显式 opt-in 的 Codex direct route 声明 `native`,可把 function call 交回同一个 DSH Agent Loop 执行。fresh session 创建本身不执行模型,仍可先持久建立 binding。最终工具为空时不要求能力声明。
|
|
168
|
+
|
|
169
|
+
只注册两个模型工具:
|
|
170
|
+
|
|
171
|
+
- `delivery_reply`:只能回复当前 Agent session 已验证的 binding,不能传 channel/account/chat/user。
|
|
172
|
+
- `delivery_status`:只返回有界 id/status/time/failureCode,不返回正文、route 或 secret。
|
|
173
|
+
|
|
174
|
+
普通 Agent 回复、Automation 结果和未来 Heartbeat 都必须 enqueue 到同一 Outbox。相同 `idempotencyKey` + 相同不可变 intent 返回同一行;同 key 改正文或 route 会冲突。
|
|
175
|
+
|
|
176
|
+
延迟审批由 domain 先通过 `prepareAgentApproval()` 从当前 Agent 的 active owner binding 派生不可伪造的 source/binding/workspace/principal route,再把该 route 随 Policy proposal 持久化;background Agent 可由可信 runner 使用 `bindAgentApprovalRoute()` 临时绑定 automation definition 中的 immutable `deliveryBindingId`,该绑定不会注册为模型工具。Delivery tick 会在发送前领取 Policy dispatch,以 `approval-card:<proposalId>` / `approval:<proposalId>` 写入同一 Outbox,再用 CAS 标记已入队;若进程在两步之间退出,重放仍命中同一 intent。schema v6 另以带版本 fence 的持久 `(createdAt, proposalId)` 高水位分页扫描 pending dispatch:无效 route 不会被伪标为已入队,但也不能用一个 poison page 永久饿死后续审批;扫描到尾后回绕重试这些条目,Host 重启与并发 scanner 都不会倒退覆盖新游标。
|
|
177
|
+
|
|
178
|
+
`enqueueApproval()` 只接受固定的 operation/proposal/version/expiry/title/diffHash 字段,并重新核对 active owner、精确 workspace/principal、Policy pending snapshot、展示标题和正文 SHA-256,调用方不能替换审批卡片展示内容。渠道签名后的点击仍必须回到 `settleApproval()`;它从 Outbox 取回持久 operation tuple,并再次核对 active owner binding、principal/chat、proposal version/expiry/diffHash 与 Policy pending snapshot,重复点击只会得到同一持久化结果。若 Policy 已提交而 Delivery 在写回结果前退出,只有此前已经落盘的同一 settlement 且当前 Policy 为精确同一终态时才能通过 `recoverApprovalSettlement()` 补全;该恢复路径不会新建 settlement,也不会决定 pending/expired proposal。
|
|
179
|
+
|
|
180
|
+
即时工具审批是另一条刻意不持久化的 open-turn 路径:effective reviewer 为 `user` 时由 Delivery 交给 owner;`auto-review` 则先由 Policy reviewer 处理,低风险 grant 不出卡,只有本地明确敏感、原生 sandbox escalation,或模型未 grant/失败后由 Policy 按 exact request identity 标记升级的请求,才允许 Delivery 接管。Policy listener 使用 prepend 注册,因此即使 Delivery 先于 LLM/reviewer 就绪也仍先完成自动审查;未标记或未知来源的 auto-review 请求只继续 waterfall,不会被 Delivery 抢跑。`never`/`none` 不创建渠道提示。以上人工路径还必须具有精确 direct binding 或显式 `bindAgentApprovalRoute()` delegated binding、当前 active owner,且会话为 DM;群聊一律 `unavailable`,因为 raw arguments 可能含 secret,不能向旁观者展示。Delivery 同时识别当前未结束 turn 内唯一且未结算的顶层 `tool/call`,以及带 exact root/parent/sub-call identity 的 Code Mode `tool/code-dispatch-start`;已经出现 `tool/result` 或 `tool/code-dispatch` 的调用一律拒绝。raw arguments 必须完整且不超过 16 KiB,reason 必须完整且不超过 2 KiB,均不截断。reason 只是未经信任的展示说明、绝不是可执行指令,但仍作为用户看到的 exact 内容纳入授权 hash。
|
|
181
|
+
|
|
182
|
+
展示前,`ctx.sessions.flush(session)` 必须返回 `true`,即至少一个持久化 listener 已成功把包含 `approval/asked` 与 exact tool/call 的事实落盘;返回 `false` 或抛错都会 `unavailable`。每次请求使用不可猜的随机 operation nonce,并以 SHA-256 `actionHash` 绑定 exact binding revision/route、owner、session incarnation、当前 turn、顶层或 Code Mode 调用身份与 raw arguments、exact reason、当前 provider/model/effort、人工 review route/escalation 与 permission/reviewer/policy 事件。flush 后、adapter 返回后都会重新核对 binding/principal/agent/delegated token/adapter 与 actionHash;撤权、解绑、route、escalation 或权限漂移都不能返回 grant。owner 返回允许后还会以不重复消耗预算的只读方式复核 Policy emergency stop;卡片等待期间打开紧急停止会把 grant 收紧为拒绝。
|
|
183
|
+
|
|
184
|
+
这类工具卡只在 `toolApprovalTtlMs` 内和当前进程的 open turn 中有效;调用方 abort 才是 `cancelled`,超时、过期、adapter 异常/断线/注销、Host 重启或 Delivery dispose 都 fail closed 为 `unavailable`。旧卡不恢复、不自动重放,也不进入 Outbox。它不同于上面的 durable Policy proposal:proposal 有持久 operation、CAS settlement 和受控 recovery,适合延迟审批;即时工具授权只允许同一 live call 的一次结果。
|
|
185
|
+
|
|
186
|
+
模型选择同样不开放任意渠道 payload。`model-picker` intent 只允许有界的 provider/model/effort 目录和有效的 model→effort 引用;目录与 operation 一起保存在 Outbox,渠道可在 Host 重启后按 operation 恢复同一份选择目录。schema v5 另外保存每个 operation 的选择 revision 和确认结算:渠道联动回调通过 CAS 前进,旧 revision 只能读取当前状态;确认先持久领取 operation,带租约和 fencing token 的 worker 在启动与 tick 时恢复未完成任务,并在实时模型解析后重新校验 active principal、binding 与 Policy。最终模型选择、结算结果与确认 Outbox 在同一事务中提交,因此重启、慢解析与重复回调不会重复应用选择。
|
|
187
|
+
|
|
188
|
+
## 故障语义
|
|
189
|
+
|
|
190
|
+
- Inbox:`received→authorized→queued→claimed→processed|retry_wait|dead_letter`。
|
|
191
|
+
- Outbox:`pending→attempting→accepted→delivered→read`,另有 `retry_wait`、`dead`、`unknown_after_send`。
|
|
192
|
+
- attempt 与 receipt 都是独立追加账本;不同 binding 可并行,同一 binding 保序。
|
|
193
|
+
- claim/complete 带 owner + fencing token;过期 worker 不能提交新 owner 的结果。
|
|
194
|
+
- 运行中的 Inbox/Outbox claim 每隔约三分之一租期按精确 owner + fencing token 续租;续租失败会 abort Agent/adapter signal,过期 worker 即使随后返回成功也不能提交结果。
|
|
195
|
+
- `maxAttempts` 只限制自动 claim;owner 对 dead letter/unknown 的显式 retry 把状态 CAS 回 `queued`/`pending` 并获得一次新 claim,`attempt_count` 与 attempt ledger 不回绕。
|
|
196
|
+
- Agent dispatch 前写 `dispatch-started` marker。此后进程崩溃会进入 `dispatch-ambiguous` dead letter,避免自动产生第二个 turn;这会牺牲一次自动重放,需要 owner 审阅后显式 retry。
|
|
197
|
+
- `/permission` 是受限例外:它使用专用 commit/cancel/failure recovery marker,并以精确 Inbox id(兼容旧 event id)与 `replyToEventId` 共同证明终态 Outbox;崩溃恢复不会把普通 background Outbox 或同名伪造 key 当成完成见证。
|
|
198
|
+
- 当前 rc.8 `followup()` 没有跨进程 `sourceEventId` 唯一接纳/完成 handle,因此本包诚实承诺“持久 event 去重 + at-most-once 自动 Agent dispatch”,不声称端到端 exactly-once。若宿主未来提供该 seam,可升级为安全的 at-least-once wake。
|
|
199
|
+
- Outbox adapter 抛异常一律视为可能已发送;不会按照普通 5xx 重试。
|
|
200
|
+
|
|
201
|
+
## 权限与数据边界
|
|
202
|
+
|
|
203
|
+
- **文件系统:**读写配置的 SQLite 与私有 spool 目录,并在 fresh Agent create 前创建缺失的 workspace;cold resume 只验证原目录仍存在。图片字节通过宿主 AttachmentStore 持久化;标准 `attachment-local` 将其写入 `$DSH_HOME/attachments/v1`,Delivery 自己不把字节写进 SQLite、spool 或 session 日志。Delivery 本身不读取任意 workspace 文件。挂载 preset 后,获 Policy 允许的文件工具可在 DSH 文件权限边界内读取 workspace。
|
|
204
|
+
- **网络:**本包自身无网络访问;网络权限属于注册的渠道 adapter。
|
|
205
|
+
- **进程/浏览器:**Delivery 本身不启动 subprocess、shell 或 browser;它挂载的 preset 可以暴露 Bash/Pwsh,真正执行由宿主 sandbox、approval 与 Policy 三层共同约束。
|
|
206
|
+
- **凭据:**不接收、存储或输出 provider token;adapter 必须通过 SecretRef/后续 credentials service 获取。
|
|
207
|
+
- **数据:**Inbox/Outbox 会保存消息正文、外部 identity 和 route,属于 PII。入站只登记最多 10 个受限 provider descriptor;授权图片会额外保存经过校验的 AttachmentStore 引用和内容摘要,provider reference 始终留在隔离账本而不进入 prompt、模型请求或工具输出。图片二进制遵循所选 AttachmentStore 的保留策略;标准 `attachment-local` 当前没有引用垃圾回收。文件、音频、视频和 sticker 仍保持 metadata quarantine。当前版本也不自动清理 Delivery 历史,请依部署的数据保留策略备份/轮换私有数据库和附件对象。
|
|
208
|
+
|
|
209
|
+
## 当前非目标
|
|
210
|
+
|
|
211
|
+
- 多主机分布式 worker、跨平台自动合并、群聊共享主 session、广播、presence/read SLA。
|
|
212
|
+
- 普通文件、音频、视频、sticker 的 payload 下载,OCR、病毒扫描与 multipart 附件发送;当前二进制入站能力严格限于受支持的光栅图片。
|
|
213
|
+
- 任意收件人模型工具、把 provider accepted 当 delivered、对未知发送自动重试。
|
|
214
|
+
- OS 级恶意插件隔离。它约束遵守 Cordis service contract 的代码;同进程恶意 Host 插件仍需容器或独立 runtime。
|
|
215
|
+
|
|
216
|
+
## 验证
|
|
217
|
+
|
|
218
|
+
```sh
|
|
219
|
+
pnpm --filter @dsh-enhanced/assistant-delivery test
|
|
220
|
+
pnpm --filter @dsh-enhanced/assistant-delivery typecheck
|
|
221
|
+
pnpm --filter @dsh-enhanced/assistant-delivery build
|
|
222
|
+
pnpm --dir plugins/assistant-delivery pack --dry-run
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
兼容性基线见 [docs/compatibility.md](../../docs/compatibility.md)。
|
package/cordis.patch.yml
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
- insert:
|
|
2
|
+
- id: dsh-enhanced-assistant-delivery
|
|
3
|
+
name: '@dsh-enhanced/assistant-delivery'
|
|
4
|
+
inject:
|
|
5
|
+
- assistantPolicy
|
|
6
|
+
config:
|
|
7
|
+
databasePath: !!js dshHomePath('assistant-delivery/state.sqlite')
|
|
8
|
+
spoolPath: !!js dshHomePath('assistant-delivery/spool')
|
|
9
|
+
schedulerEnabled: true
|
|
10
|
+
tickIntervalMs: 1000
|
|
11
|
+
leaseMs: 30000
|
|
12
|
+
maxAttempts: 5
|
|
13
|
+
maxConcurrency: 4
|
|
14
|
+
maxTextBytes: 65536
|
|
15
|
+
retryBaseMs: 1000
|
|
16
|
+
retryMaxMs: 300000
|
|
17
|
+
pairingTtlMs: 600000
|
|
18
|
+
pairingMaxAttempts: 5
|
|
19
|
+
defaultWorkspace: !!js dshHomePath('assistant-workspace')
|
|
20
|
+
defaultAgentPreset: standard
|
|
21
|
+
policyRef: owner-dm
|
|
22
|
+
agentProvider: deepseek-official
|
|
23
|
+
agentModel: deepseek-v4-flash
|
|
24
|
+
toolCapableProviders:
|
|
25
|
+
- deepseek-official
|
|
26
|
+
agentMaxOutputTokens: 8192
|
|
27
|
+
modelPickerTtlMs: 900000
|
|
28
|
+
permissionPickerTtlMs: 900000
|
|
29
|
+
toolApprovalTtlMs: 300000
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
2
|
+
import { type Agent } from '@deepseek-ai/dsh-agent';
|
|
3
|
+
import type { AgentPresets } from '@deepseek-ai/dsh-agent-presets';
|
|
4
|
+
import { type SessionEvent } from '@deepseek-ai/dsh-session';
|
|
5
|
+
import { type AssistantPolicyService } from '@dsh-enhanced/assistant-policy';
|
|
6
|
+
import type { InboundPrepareContext, InboundPrepareResult, InboundProcessResult, MarkInboundDispatching, PreparedInboundMessage } from './coordinator.js';
|
|
7
|
+
import type { InboundImageMaterializer } from './inbound-images.js';
|
|
8
|
+
import type { DeliveryInboundRuntime } from './service.js';
|
|
9
|
+
import type { ConversationBinding, ConversationModelSelection, ConversationRef, DeliveryProgressUpdate, InboundEnvelope, ModelPickerIntent, ModelRouteRef, PermissionPickerIntent } from './types.js';
|
|
10
|
+
declare module '@deepseek-ai/dsh-llm' {
|
|
11
|
+
interface MessageSourceMap {
|
|
12
|
+
delivery: {
|
|
13
|
+
kind: 'delivery';
|
|
14
|
+
channel: string;
|
|
15
|
+
account: string;
|
|
16
|
+
eventId: string;
|
|
17
|
+
trust: 'untrusted';
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
interface DshDeliveryRuntimeOptions {
|
|
22
|
+
sessionNamespace: string;
|
|
23
|
+
workspace: string;
|
|
24
|
+
agentPreset: string;
|
|
25
|
+
getAgentPresets(): Pick<AgentPresets, 'mount' | 'resolve'> | undefined;
|
|
26
|
+
policyRef: string;
|
|
27
|
+
provider: string;
|
|
28
|
+
model: string;
|
|
29
|
+
toolCapableProviders: ReadonlySet<string>;
|
|
30
|
+
unknownRouteToolCalls: 'allow' | 'deny';
|
|
31
|
+
maxOutputTokens: number;
|
|
32
|
+
permissionPickerTtlMs: number;
|
|
33
|
+
getModelSelection(conversation: ConversationRef): ConversationModelSelection | undefined;
|
|
34
|
+
imageMaterializer: Pick<InboundImageMaterializer, 'materialize'>;
|
|
35
|
+
isInboundAuthorized(binding: Readonly<ConversationBinding>, envelope: Readonly<InboundEnvelope>): boolean;
|
|
36
|
+
isPermissionController(binding: Readonly<ConversationBinding>, envelope: Readonly<InboundEnvelope>): boolean;
|
|
37
|
+
/** Durably reserve the exact terminal reply authorization before permission state can change. */
|
|
38
|
+
authorizePermissionReply(binding: Readonly<ConversationBinding>, envelope: Readonly<InboundEnvelope>): boolean;
|
|
39
|
+
beginModelCommand(conversation: ConversationRef): number;
|
|
40
|
+
commitModelCommand(input: {
|
|
41
|
+
conversation: ConversationRef;
|
|
42
|
+
expectedEpoch: number;
|
|
43
|
+
route?: ModelRouteRef;
|
|
44
|
+
}): {
|
|
45
|
+
applied: false;
|
|
46
|
+
} | {
|
|
47
|
+
applied: true;
|
|
48
|
+
selection?: ConversationModelSelection;
|
|
49
|
+
};
|
|
50
|
+
modelPickerTtlMs: number;
|
|
51
|
+
progress(binding: Readonly<ConversationBinding>, eventId: string, update: DeliveryProgressUpdate): Promise<void>;
|
|
52
|
+
replyCommand(binding: Readonly<ConversationBinding>, eventId: string, input: ModelCommandReply, idempotencyKey?: string): void;
|
|
53
|
+
reply(agent: Agent, eventId: string, input: ModelCommandReply): void;
|
|
54
|
+
}
|
|
55
|
+
interface ModelCommandReply {
|
|
56
|
+
text: string;
|
|
57
|
+
format?: 'markdown' | 'model-picker' | 'permission-picker' | 'plain';
|
|
58
|
+
modelPicker?: ModelPickerIntent;
|
|
59
|
+
permissionPicker?: PermissionPickerIntent;
|
|
60
|
+
fallbackText?: string;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Convert one durable session fact into a deliberately narrow, user-visible progress update.
|
|
64
|
+
* Raw reasoning chunks, tool arguments, result content, and error details never cross this boundary.
|
|
65
|
+
*
|
|
66
|
+
* The `reasoning` block of a durable `assistant/message` is the assistant's own settled summary of
|
|
67
|
+
* the step, not a streaming fragment, so it is the one reasoning form safe to surface. Only some
|
|
68
|
+
* providers emit it at all: subscription CLIs declare an effort capability but still return text
|
|
69
|
+
* only, and the ACP thought channel is not mapped to DSH reasoning yet. `step/start` therefore also
|
|
70
|
+
* yields a neutral phase label, so a turn reports progress even on providers that never reason
|
|
71
|
+
* out loud.
|
|
72
|
+
*/
|
|
73
|
+
export declare function deliveryProgressFromSessionEvent(event: SessionEvent): DeliveryProgressUpdate | undefined;
|
|
74
|
+
export declare function permissionStateHash(events: readonly SessionEvent[], tableFingerprint?: string): string;
|
|
75
|
+
export declare function permissionPickerOperationId(conversation: Readonly<ConversationRef>, eventId: string): string;
|
|
76
|
+
export declare function modelPickerOperationId(conversation: Readonly<ConversationRef>, eventId: string): string;
|
|
77
|
+
export declare class DshDeliveryRuntime implements DeliveryInboundRuntime {
|
|
78
|
+
private readonly ctx;
|
|
79
|
+
private readonly policy;
|
|
80
|
+
private readonly options;
|
|
81
|
+
readonly dispatchControl: "explicit";
|
|
82
|
+
private readonly activeSessionControls;
|
|
83
|
+
constructor(ctx: Context, policy: AssistantPolicyService, options: DshDeliveryRuntimeOptions);
|
|
84
|
+
cancelActive(binding: Readonly<ConversationBinding>, command: 'new' | 'stop'): Promise<boolean>;
|
|
85
|
+
private beginSessionControl;
|
|
86
|
+
private endSessionControl;
|
|
87
|
+
private disposeAfterReplyBoundary;
|
|
88
|
+
/** Wait for only the turn that claims Delivery's exact message identity. */
|
|
89
|
+
private followupTurn;
|
|
90
|
+
private setupAgent;
|
|
91
|
+
private reconcileNativeFullPermissionReviewer;
|
|
92
|
+
private runPermissionCommand;
|
|
93
|
+
createSession(input: {
|
|
94
|
+
envelope: Readonly<InboundEnvelope>;
|
|
95
|
+
generation: number;
|
|
96
|
+
previous?: Readonly<ConversationBinding>;
|
|
97
|
+
signal: AbortSignal;
|
|
98
|
+
}): Promise<{
|
|
99
|
+
sessionId: string;
|
|
100
|
+
workspace: string;
|
|
101
|
+
agentPreset: string;
|
|
102
|
+
policyRef: string;
|
|
103
|
+
}>;
|
|
104
|
+
prepare(binding: Readonly<ConversationBinding>, envelope: Readonly<InboundEnvelope>, signal: AbortSignal, context: Readonly<InboundPrepareContext>): Promise<InboundPrepareResult>;
|
|
105
|
+
private replySessionCommand;
|
|
106
|
+
private sessionHelp;
|
|
107
|
+
private runSessionCommand;
|
|
108
|
+
process(binding: Readonly<ConversationBinding>, envelope: Readonly<InboundEnvelope>, outerSignal: AbortSignal, prepared?: Readonly<PreparedInboundMessage>, markDispatching?: MarkInboundDispatching): Promise<InboundProcessResult>;
|
|
109
|
+
private processControlled;
|
|
110
|
+
}
|
|
111
|
+
export {};
|
|
112
|
+
//# sourceMappingURL=agent-runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-runtime.d.ts","sourceRoot":"","sources":["../src/agent-runtime.ts"],"names":[],"mappings":"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"}
|