@roll-agent/relay-protocol 0.1.1 → 0.3.0
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.md +134 -39
- package/dist/conformance.d.ts +571 -4
- package/dist/conformance.js +677 -8
- package/dist/control.d.ts +188 -0
- package/dist/control.js +180 -0
- package/dist/index.d.ts +3991 -287
- package/dist/index.js +676 -77
- package/dist/reference-adapter.d.ts +56 -0
- package/dist/reference-adapter.js +122 -0
- package/dist/schema/roll-relay-browser-session-v1.schema.json +23 -0
- package/dist/schema/roll-relay-control-v1.schema.json +127 -0
- package/dist/schema/roll-relay-protocol-v1.1.schema.json +3791 -0
- package/dist/schema/roll-relay-protocol-v1.schema.json +1 -1
- package/fixtures/control/v1.0/invalid-browser-session-trailing-whitespace.json +4 -0
- package/fixtures/control/v1.0/invalid-browser-session-uppercase-scheme.json +4 -0
- package/fixtures/control/v1.0/invalid-browser-session-url.json +4 -0
- package/fixtures/control/v1.0/invalid-browser-session-ws.json +4 -0
- package/fixtures/control/v1.0/invalid-control-extra-field.json +6 -0
- package/fixtures/control/v1.0/invalid-session-ready-wire-version.json +8 -0
- package/fixtures/control/v1.0/manifest.json +52 -0
- package/fixtures/control/v1.0/valid-browser-session.json +4 -0
- package/fixtures/control/v1.0/valid-session-error.json +5 -0
- package/fixtures/control/v1.0/valid-session-ready.json +8 -0
- package/fixtures/control/v1.0/valid-workspace-status.json +5 -0
- package/fixtures/v1.1/invalid-approval-projection-raw-input-leak.json +19 -0
- package/fixtures/v1.1/invalid-authentication-local-only.json +12 -0
- package/fixtures/v1.1/invalid-file-picker-local-only.json +12 -0
- package/fixtures/v1.1/invalid-interaction-cancelled-reason-leak.json +10 -0
- package/fixtures/v1.1/invalid-interaction-resolved-result-leak.json +18 -0
- package/fixtures/v1.1/invalid-legacy-approval-candidate.json +7 -0
- package/fixtures/v1.1/invalid-legacy-approval-respond.json +7 -0
- package/fixtures/v1.1/invalid-n-minus-one-device-connect.json +6 -0
- package/fixtures/v1.1/invalid-non-normal-sensitivity.json +21 -0
- package/fixtures/v1.1/invalid-runtime-event-tool-input-leak.json +22 -0
- package/fixtures/v1.1/invalid-runtime-event-tool-output-leak.json +21 -0
- package/fixtures/v1.1/invalid-user-input-projection-secret-leak.json +22 -0
- package/fixtures/v1.1/manifest.json +673 -0
- package/fixtures/v1.1/valid-device-connect.json +6 -0
- package/fixtures/v1.1/valid-interaction-cancelled.json +9 -0
- package/fixtures/v1.1/valid-interaction-candidate-user-input.json +25 -0
- package/fixtures/v1.1/valid-interaction-request-approval.json +17 -0
- package/fixtures/v1.1/valid-interaction-request-user-input.json +40 -0
- package/fixtures/v1.1/valid-interaction-resolved.json +9 -0
- package/fixtures/v1.1/valid-runtime-ack.json +5 -0
- package/fixtures/v1.1/valid-runtime-encrypted-interaction.json +10 -0
- package/fixtures/v1.1/valid-runtime-event-runtime-n-minus-one.json +16 -0
- package/fixtures/v1.1/valid-runtime-event.json +16 -0
- package/fixtures/v1.1/valid-runtime-gap.json +7 -0
- package/fixtures/v1.1/valid-runtime-request.json +10 -0
- package/fixtures/v1.1/valid-runtime-response.json +8 -0
- package/package.json +16 -3
package/README.md
CHANGED
|
@@ -9,7 +9,8 @@ Browser-safe 的 Roll Companion Relay Wire 契约。
|
|
|
9
9
|
|
|
10
10
|
| 使用方 | 是否直接安装 | 用途 |
|
|
11
11
|
|---|---:|---|
|
|
12
|
-
| Browser Web App |
|
|
12
|
+
| 普通 Browser Web App | 否 | 安装 `@roll-agent/relay-client`,不直接处理 frame |
|
|
13
|
+
| 自定义 Browser Transport | 是 | 实现 Relay frame、ACK/gap 与恢复 |
|
|
13
14
|
| Cloud Relay Server | 是 | 校验、路由和持久化 Relay frame |
|
|
14
15
|
| Local Companion Host | 是 | 与 Cloud 使用同一 Wire 契约 |
|
|
15
16
|
| Local-only Desktop GUI | 否 | 直接使用 Runtime Protocol,不经过 Relay |
|
|
@@ -19,54 +20,148 @@ Browser-safe 的 Roll Companion Relay Wire 契约。
|
|
|
19
20
|
pnpm add @roll-agent/relay-protocol
|
|
20
21
|
```
|
|
21
22
|
|
|
22
|
-
|
|
23
|
+
普通第三方 Web App 应安装 `@roll-agent/relay-client`;本包面向 Cloud Relay、Companion 和确实
|
|
24
|
+
需要自定义 Transport 的高级实现者。
|
|
23
25
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
- 以 `(workspaceId, requestId)` 为幂等键的 `new/replay/conflict` 分类;
|
|
29
|
-
- 稳定 Relay error code 与 retryability 映射;
|
|
30
|
-
- JSON Schema、跨语言 fixtures 和可复用 conformance cases。
|
|
26
|
+
## Control 1.0 与方向合同
|
|
27
|
+
|
|
28
|
+
Browser Session 的 HTTP 返回和 WebSocket 控制面从独立 subpath 导入,不属于
|
|
29
|
+
`relayMessageSchemaV11` 数据面 union:
|
|
31
30
|
|
|
32
31
|
```ts
|
|
33
32
|
import {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
RELAY_BROWSER_WSS_MESSAGE_TYPES_BY_DIRECTION,
|
|
34
|
+
RELAY_COMPANION_WSS_MESSAGE_TYPES_BY_DIRECTION,
|
|
35
|
+
parseRelayBrowserFirstControlFrame,
|
|
36
|
+
relayBrowserControlMessageSchema,
|
|
37
|
+
relaySessionDescriptorSchema,
|
|
38
|
+
} from "@roll-agent/relay-protocol/control";
|
|
39
|
+
|
|
40
|
+
const session = relaySessionDescriptorSchema.parse(await response.json());
|
|
41
|
+
const ready = parseRelayBrowserFirstControlFrame(firstWebSocketFrame);
|
|
42
|
+
relayBrowserControlMessageSchema.parse(laterControlFrame);
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
`session.ready` 必须是 Browser WebSocket 收到的第一帧,并固定声明 Control 1.0、Wire 1.1、
|
|
46
|
+
Relay 绑定的 Workspace 和在线状态。Browser 不能在请求中自行指定 `workspaceId`。
|
|
47
|
+
Ticket 无效、过期、重复消费或 Origin 不匹配时,Relay 必须在 HTTP upgrade 阶段拒绝连接;
|
|
48
|
+
这些错误属于 `RELAY_BROWSER_HANDSHAKE_ERROR_CODES`,不能伪装成已认证连接中的
|
|
49
|
+
`session.error`。后者只承载 `session.ready` 之后的会话错误。
|
|
50
|
+
|
|
51
|
+
方向 allowlist 固定为:Browser→Relay 只允许 Wire 1.1 `runtime.request` 与 `runtime.ack`;
|
|
52
|
+
Relay→Companion 同样只允许这两类。Relay→Browser 允许 Control 帧以及 response/event/gap/
|
|
53
|
+
Interaction 帧;Companion→Relay 还包含首帧 `device.connect`。`runtime.ack` 是 Wire 数据面,
|
|
54
|
+
不是 Control ACK。P0 不提供 E2EE,因此这些 P0 WSS allowlist 明确不含 `runtime.encrypted`。
|
|
55
|
+
|
|
56
|
+
## 版本
|
|
57
|
+
|
|
58
|
+
支持矩阵是 `["1.1", "1.0"]`。Wire 1.1 新增 typed Interaction;Wire 1.0 的 registry、
|
|
59
|
+
Schema、fixtures 和 Approval fallback 保持冻结。
|
|
60
|
+
|
|
61
|
+
为了让现有 Companion 和 Browser 不被 minor upgrade 静默升级,历史上没有版本后缀的
|
|
62
|
+
`RELAY_PROTOCOL_VERSION`、`relayMessageSchema`、`relayRequestMethodSchemas`、parser 和 type
|
|
63
|
+
仍固定指向 Wire 1.0。新代码应使用 `LATEST_RELAY_PROTOCOL_VERSION` 和显式的 `*V10` /
|
|
64
|
+
`*V11` / `*ForVersion` API。
|
|
65
|
+
|
|
66
|
+
```ts
|
|
38
67
|
import {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
68
|
+
LATEST_RELAY_PROTOCOL_VERSION,
|
|
69
|
+
parseRelayMessageForVersion,
|
|
70
|
+
relayMessageSchemaV11,
|
|
71
|
+
} from "@roll-agent/relay-protocol";
|
|
72
|
+
|
|
73
|
+
LATEST_RELAY_PROTOCOL_VERSION; // "1.1"
|
|
74
|
+
const frame = parseRelayMessageForVersion("1.1", input);
|
|
75
|
+
relayMessageSchemaV11.parse(frame);
|
|
42
76
|
```
|
|
43
77
|
|
|
44
|
-
|
|
45
|
-
|
|
78
|
+
`CompanionRelayBridge.connect(transport)` 这一历史一参入口仍只表示 Wire 1.0。支持 Wire 1.1
|
|
79
|
+
的 Host 必须使用显式协商版本的新入口;不得让旧调用自动选择 latest。
|
|
46
80
|
|
|
47
|
-
|
|
48
|
-
`query` / `mutation` / `local-only` disposition、duplicate/conflict 与错误码形状、基于调用方
|
|
49
|
-
已证明连续投递前缀的 ACK 边界、gap recovery、加密 metadata 和 Relay error retryability。
|
|
50
|
-
Transport 必须自行保证发送失败后不会越过序号缺口;Companion Bridge 会终止失败的
|
|
51
|
-
transport generation 并在重连后重放。当前只有 `"1.0"`,因此只能验证同版本与未知版本
|
|
52
|
-
fail-closed;真实 `N/N-1` 矩阵必须等下一版 Relay Wire 存在后补齐,不能伪造历史版本。
|
|
81
|
+
## Wire 1.1 Interaction
|
|
53
82
|
|
|
54
|
-
|
|
83
|
+
Wire 1.1 增加 `interaction.request`、`interaction.resolved`、
|
|
84
|
+
`interaction.cancelled` 三种 Companion→Browser frame。Browser 通过 mutation
|
|
85
|
+
`interaction.candidate` 提交候选;`approval.candidate` 只存在于冻结的 Wire 1.0。
|
|
86
|
+
|
|
87
|
+
远端候选不是独立授权事实源。Runtime policy 先决定 auto/confirm/deny;只有 confirm 才产生
|
|
88
|
+
可响应 Interaction,deny 不会被远端越过。官方 Companion 只再验证 request policy、Workspace、
|
|
89
|
+
responder 与绝对 deadline,不增加电脑端二次审批。低层自定义 Host 可以进一步收紧,但不能
|
|
90
|
+
放宽 Runtime 决议。
|
|
91
|
+
|
|
92
|
+
安全投影只允许:
|
|
55
93
|
|
|
56
|
-
|
|
57
|
-
|
|
94
|
+
- Approval:`approvalId`、`agentName`、`toolName`、可选 `explanation`;
|
|
95
|
+
- User Input:五类安全表单 control 及其 bounded 字段;
|
|
96
|
+
- resolved/cancelled:Interaction identity,不回显 Runtime Result 或原始取消原因;
|
|
97
|
+
- Timeline:安全消息、状态和 Tool 完成摘要;Tool input/output delta 与 Approval preview 会被剥离。
|
|
58
98
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
99
|
+
Runtime JSON-RPC `id`、原始 Tool input/output、secret、完整 User Input Result、本地授权信息
|
|
100
|
+
以及 Authentication/File Picker projector 都不能进入 Companion→Browser 投影。Browser→Companion 的
|
|
101
|
+
`interaction.candidate` 是 User Input Result 唯一允许的入站位置,并且必须关联原始表单重新校验。
|
|
102
|
+
|
|
103
|
+
Wire 1.1 Snapshot 不能重建一个仍可响应的 `interactionId`。Browser Session 重连时,Cloud
|
|
104
|
+
Relay 必须保留并重新投递尚未 resolved/cancelled 的 `interaction.request`;客户端不得从
|
|
105
|
+
`approvalId` 或 Snapshot 自行合成 Interaction identity。
|
|
106
|
+
|
|
107
|
+
Wire 1.1 的 pull 查询遵守同一边界:`thread.open` / `thread.snapshot` 必须把 Approval preview
|
|
108
|
+
投影为可选 explanation、移除本地 reason,并把 Operation display 与 outcome reason 脱敏;
|
|
109
|
+
Host 对前两种结果调用 `projectRelayThreadSnapshotV11(value)`,对 `operation.get` 调用
|
|
110
|
+
`projectRelayOperationGetResultV11(value)`。两个 projector 遇到畸形 Runtime 结果都会抛错并
|
|
111
|
+
fail closed。第一方 `CompanionRelayBridgeV11` 已自动应用它们;自定义 Host 仍必须在构造
|
|
112
|
+
`runtime.response` 前显式调用,不能把 Runtime 原始结果直接发送。
|
|
113
|
+
|
|
114
|
+
有意保留的内容包括完整 transcript 消息、Thread 标题/模型/时间元数据、安全 timeline 摘要,
|
|
115
|
+
以及 `thread.capabilities.manifest` 中可能出现的 cwd、平台、Agent、Skill、Tool Schema、规则
|
|
116
|
+
标识与 VCS 元数据。它们不是公开信息,Relay 与 Browser 宿主仍需按敏感数据保护。
|
|
117
|
+
|
|
118
|
+
冻结的 Wire 1.0 没有这些安全投影,只适用于处在等价本地信任边界内的 legacy peer。它不是
|
|
119
|
+
面向不受信 Cloud/Browser 的降级协议;需要远程投影的 Host 必须协商 1.1,失败时拒绝连接。
|
|
120
|
+
|
|
121
|
+
## Browser reference adapter
|
|
122
|
+
|
|
123
|
+
`@roll-agent/relay-protocol/reference-adapter` 提供最小、纯内存的 typed reference adapter:
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
import { createRelayBrowserReferenceAdapter } from
|
|
127
|
+
"@roll-agent/relay-protocol/reference-adapter";
|
|
128
|
+
|
|
129
|
+
const adapter = createRelayBrowserReferenceAdapter({ protocolVersion: "1.1" });
|
|
130
|
+
const update = adapter.receive(frame);
|
|
131
|
+
const candidateRequest = adapter.createCandidate({
|
|
132
|
+
workspaceId,
|
|
133
|
+
interactionId,
|
|
134
|
+
method: "approval.request",
|
|
135
|
+
candidate: { decision: "reject", reason: "用户取消" },
|
|
136
|
+
});
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Adapter 只做 Schema 校验、pending correlation 和 candidate frame 构造。它不提供账号身份、
|
|
140
|
+
controller 选举、可靠投递、WebSocket、持久 outbox 或 Interaction WAL;这些 responder
|
|
141
|
+
context 必须由宿主注入。
|
|
142
|
+
|
|
143
|
+
## Schema、fixtures 与 conformance
|
|
144
|
+
|
|
145
|
+
- `@roll-agent/relay-protocol/schema` 与 `/schema/v1.0`:冻结的 Wire 1.0 JSON Schema;
|
|
146
|
+
- `@roll-agent/relay-protocol/schema/v1.1`:Wire 1.1 JSON Schema;
|
|
147
|
+
- `@roll-agent/relay-protocol/control`:Control 1.0、Browser Session 和 WSS 方向 Schema;
|
|
148
|
+
- `@roll-agent/relay-protocol/control/schema`:Control 1.0 JSON Schema;
|
|
149
|
+
- `@roll-agent/relay-protocol/control/session-schema`:Browser Session JSON Schema;
|
|
150
|
+
- `@roll-agent/relay-protocol/control/fixtures/*`:Control/Session golden fixtures;
|
|
151
|
+
- `@roll-agent/relay-protocol/fixtures/v1/*`:字节冻结的 Wire 1.0 golden fixtures;
|
|
152
|
+
- `@roll-agent/relay-protocol/fixtures/v1.1/*`:Wire 1.1 Interaction 与安全负例;
|
|
153
|
+
- `@roll-agent/relay-protocol/conformance`:可复用的 N/N-1 suite。
|
|
154
|
+
|
|
155
|
+
历史 `runRelayProtocolConformance(adapter)` 一参调用固定执行 Wire 1.0 suite;新实现使用
|
|
156
|
+
`runRelayProtocolConformanceForVersion(version, adapter)` 显式选择 1.1 或 1.0。Suite 覆盖
|
|
157
|
+
版本协商、完整 method registry、duplicate/conflict、ACK/gap、Interaction 生命周期、加密
|
|
158
|
+
metadata 和安全 sentinel。
|
|
159
|
+
|
|
160
|
+
## 边界
|
|
62
161
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
162
|
+
本包不包含 Transport、WebSocket、账号/设备数据库、本地 Policy、加密实现或 Cloud 部署
|
|
163
|
+
代码。运行时代码只依赖 Browser-safe 的 `@roll-agent/protocol` 与 `zod`。Browser 与 Cloud
|
|
164
|
+
Relay 不能为了获得 Wire Schema 而安装 `@roll-agent/companion`。
|
|
66
165
|
|
|
67
|
-
Relay
|
|
68
|
-
`
|
|
69
|
-
`query` / `mutation` 才是远程请求分类。既有 Runtime method 的 Params/Result 继续属于按
|
|
70
|
-
Workspace 协商的 Runtime Protocol 契约;`relayRequestMethodSchemas` 是当前
|
|
71
|
-
`@roll-agent/protocol` 依赖版本的 typed 视图,不应被解释为 Relay `"1.0"` 单独复制的一套
|
|
72
|
-
Runtime Schema。
|
|
166
|
+
Relay `requestId`、逻辑 `interactionId`、Runtime JSON-RPC `id`、Runtime mutation
|
|
167
|
+
`requestId` 与 Relay `relaySequence` 是不同的类型和生命周期,不能互相复用。
|