agent-embassy 2.0.1 → 3.0.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/CHANGELOG.md +56 -0
- package/CONTRIBUTING.md +19 -34
- package/README.md +110 -228
- package/SECURITY.md +55 -89
- package/dist/src/errors.d.ts +10 -1
- package/dist/src/errors.js +3 -1
- package/dist/src/errors.js.map +1 -1
- package/dist/src/gateway/claude-helper-protocol.d.ts +8 -11
- package/dist/src/gateway/claude-helper-protocol.js +12 -11
- package/dist/src/gateway/claude-helper-protocol.js.map +1 -1
- package/dist/src/gateway/claude-helper-supervisor.d.ts +1 -5
- package/dist/src/gateway/claude-helper-supervisor.js +10 -9
- package/dist/src/gateway/claude-helper-supervisor.js.map +1 -1
- package/dist/src/gateway/claude-helper.js +6 -6
- package/dist/src/gateway/claude-helper.js.map +1 -1
- package/dist/src/gateway/claude-peer.d.ts +0 -3
- package/dist/src/gateway/claude-peer.js +6 -18
- package/dist/src/gateway/claude-peer.js.map +1 -1
- package/dist/src/gateway/cli.d.ts +17 -6
- package/dist/src/gateway/cli.js +912 -261
- package/dist/src/gateway/cli.js.map +1 -1
- package/dist/src/gateway/codex-socket-holder.d.ts +26 -0
- package/dist/src/gateway/codex-socket-holder.js +76 -0
- package/dist/src/gateway/codex-socket-holder.js.map +1 -0
- package/dist/src/gateway/codex-stateless-transport.js +1 -1
- package/dist/src/gateway/codex-stateless-transport.js.map +1 -1
- package/dist/src/gateway/config.d.ts +1 -10
- package/dist/src/gateway/config.js +4 -10
- package/dist/src/gateway/config.js.map +1 -1
- package/dist/src/gateway/control.d.ts +45 -77
- package/dist/src/gateway/control.js +56 -141
- package/dist/src/gateway/control.js.map +1 -1
- package/dist/src/gateway/federation-nodes.d.ts +29 -2
- package/dist/src/gateway/federation-nodes.js +177 -7
- package/dist/src/gateway/federation-nodes.js.map +1 -1
- package/dist/src/gateway/peer-client.d.ts +4 -3
- package/dist/src/gateway/peer-client.js +22 -13
- package/dist/src/gateway/peer-client.js.map +1 -1
- package/dist/src/gateway/peer-protocol.d.ts +8 -11
- package/dist/src/gateway/peer-protocol.js +5 -12
- package/dist/src/gateway/peer-protocol.js.map +1 -1
- package/dist/src/gateway/provenance-envelope.d.ts +0 -1
- package/dist/src/gateway/provenance-envelope.js +4 -19
- package/dist/src/gateway/provenance-envelope.js.map +1 -1
- package/dist/src/gateway/providers.d.ts +7 -4
- package/dist/src/gateway/providers.js +16 -20
- package/dist/src/gateway/providers.js.map +1 -1
- package/dist/src/gateway/server.d.ts +3 -12
- package/dist/src/gateway/server.js +31 -50
- package/dist/src/gateway/server.js.map +1 -1
- package/dist/src/gateway/service-agent.d.ts +187 -0
- package/dist/src/gateway/service-agent.js +758 -0
- package/dist/src/gateway/service-agent.js.map +1 -0
- package/dist/src/gateway/service.d.ts +114 -31
- package/dist/src/gateway/service.js +461 -566
- package/dist/src/gateway/service.js.map +1 -1
- package/dist/src/gateway/status-view.d.ts +167 -0
- package/dist/src/gateway/status-view.js +488 -0
- package/dist/src/gateway/status-view.js.map +1 -0
- package/dist/src/gateway/store.d.ts +103 -21
- package/dist/src/gateway/store.js +454 -529
- package/dist/src/gateway/store.js.map +1 -1
- package/dist/src/gateway/types.d.ts +48 -99
- package/dist/src/gateway/types.js +15 -52
- package/dist/src/gateway/types.js.map +1 -1
- package/docs/CONFIGURATION.md +173 -44
- package/docs/DELIVERY.md +11 -11
- package/docs/GATEWAY-ARCHITECTURE.md +277 -375
- package/package.json +4 -12
- package/skills/embassy-peer/SKILL.md +65 -90
- package/skills/embassy-peer/agents/openai.yaml +1 -1
- package/README.zh-CN.md +0 -275
- package/assets/live-dashboard/app.css +0 -1619
- package/assets/vendor/react/LICENSE +0 -21
- package/assets/vendor/react/react-dom.production.min.js +0 -267
- package/assets/vendor/react/react.production.min.js +0 -31
- package/dist/src/gateway/acp-client.d.ts +0 -110
- package/dist/src/gateway/acp-client.js +0 -407
- package/dist/src/gateway/acp-client.js.map +0 -1
- package/dist/src/gateway/acp-provider.d.ts +0 -66
- package/dist/src/gateway/acp-provider.js +0 -275
- package/dist/src/gateway/acp-provider.js.map +0 -1
- package/dist/src/gateway/cli-copy.d.ts +0 -8
- package/dist/src/gateway/cli-copy.en.d.ts +0 -22
- package/dist/src/gateway/cli-copy.en.js +0 -62
- package/dist/src/gateway/cli-copy.en.js.map +0 -1
- package/dist/src/gateway/cli-copy.js +0 -27
- package/dist/src/gateway/cli-copy.js.map +0 -1
- package/dist/src/gateway/cli-copy.zh-CN.d.ts +0 -22
- package/dist/src/gateway/cli-copy.zh-CN.js +0 -62
- package/dist/src/gateway/cli-copy.zh-CN.js.map +0 -1
- package/dist/src/gateway/codex-doctor.d.ts +0 -36
- package/dist/src/gateway/codex-doctor.js +0 -127
- package/dist/src/gateway/codex-doctor.js.map +0 -1
- package/dist/src/gateway/dashboard-copy.d.ts +0 -7
- package/dist/src/gateway/dashboard-copy.en.d.ts +0 -504
- package/dist/src/gateway/dashboard-copy.en.js +0 -505
- package/dist/src/gateway/dashboard-copy.en.js.map +0 -1
- package/dist/src/gateway/dashboard-copy.js +0 -514
- package/dist/src/gateway/dashboard-copy.js.map +0 -1
- package/dist/src/gateway/dashboard-copy.zh-CN.d.ts +0 -504
- package/dist/src/gateway/dashboard-copy.zh-CN.js +0 -505
- package/dist/src/gateway/dashboard-copy.zh-CN.js.map +0 -1
- package/dist/src/gateway/dashboard-model.d.ts +0 -343
- package/dist/src/gateway/dashboard-model.js +0 -1061
- package/dist/src/gateway/dashboard-model.js.map +0 -1
- package/dist/src/gateway/dashboard.d.ts +0 -20
- package/dist/src/gateway/dashboard.js +0 -874
- package/dist/src/gateway/dashboard.js.map +0 -1
- package/dist/src/gateway/deepseek-detect.d.ts +0 -14
- package/dist/src/gateway/deepseek-detect.js +0 -41
- package/dist/src/gateway/deepseek-detect.js.map +0 -1
- package/dist/src/gateway/live-dashboard-app/app.js +0 -2385
- package/dist/src/gateway/live-dashboard-assets.d.ts +0 -10
- package/dist/src/gateway/live-dashboard-assets.js +0 -74
- package/dist/src/gateway/live-dashboard-assets.js.map +0 -1
- package/dist/src/gateway/live-dashboard-command.d.ts +0 -60
- package/dist/src/gateway/live-dashboard-command.js +0 -334
- package/dist/src/gateway/live-dashboard-command.js.map +0 -1
- package/dist/src/gateway/live-dashboard-http.d.ts +0 -39
- package/dist/src/gateway/live-dashboard-http.js +0 -383
- package/dist/src/gateway/live-dashboard-http.js.map +0 -1
- package/dist/src/gateway/live-dashboard-protocol.d.ts +0 -34
- package/dist/src/gateway/live-dashboard-protocol.js +0 -114
- package/dist/src/gateway/live-dashboard-protocol.js.map +0 -1
- package/dist/src/gateway/live-dashboard-server.d.ts +0 -33
- package/dist/src/gateway/live-dashboard-server.js +0 -144
- package/dist/src/gateway/live-dashboard-server.js.map +0 -1
- package/dist/src/gateway/live-dashboard-stream.d.ts +0 -46
- package/dist/src/gateway/live-dashboard-stream.js +0 -234
- package/dist/src/gateway/live-dashboard-stream.js.map +0 -1
- package/dist/src/gateway/live-dashboard.d.ts +0 -28
- package/dist/src/gateway/live-dashboard.js +0 -154
- package/dist/src/gateway/live-dashboard.js.map +0 -1
- package/dist/src/gateway/locale.d.ts +0 -4
- package/dist/src/gateway/locale.js +0 -10
- package/dist/src/gateway/locale.js.map +0 -1
- package/dist/src/gateway/progress-watch-machine.d.ts +0 -45
- package/dist/src/gateway/progress-watch-machine.js +0 -70
- package/dist/src/gateway/progress-watch-machine.js.map +0 -1
- package/docs/CONFIGURATION.zh-CN.md +0 -97
- package/docs/DASHBOARD.md +0 -98
- package/docs/DASHBOARD.zh-CN.md +0 -49
- package/docs/DELIVERY.zh-CN.md +0 -55
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
export declare const PROGRESS_WATCH_DEFAULT_IDLE_MS: number;
|
|
2
|
-
export declare const PROGRESS_WATCH_MIN_IDLE_MS = 60000;
|
|
3
|
-
export declare const PROGRESS_WATCH_MAX_IDLE_MS: number;
|
|
4
|
-
export declare const PROGRESS_WATCH_DEFAULT_CAPACITY = 32;
|
|
5
|
-
export declare const PROGRESS_WATCH_HARD_CAPACITY = 256;
|
|
6
|
-
/** One process-local active watch. Settlement is represented by its absence. */
|
|
7
|
-
export type ProgressWatch = Readonly<{
|
|
8
|
-
conversationId: string;
|
|
9
|
-
ownerAlias: string;
|
|
10
|
-
workerAlias: string;
|
|
11
|
-
lastActivityAt: string;
|
|
12
|
-
idleMs: number;
|
|
13
|
-
nudgeCount: 0 | 1 | 2;
|
|
14
|
-
nextActionAt: string;
|
|
15
|
-
}>;
|
|
16
|
-
type ProgressWatchDueInspection = Readonly<{
|
|
17
|
-
kind: "not_due";
|
|
18
|
-
}> | Readonly<{
|
|
19
|
-
kind: "rescheduled";
|
|
20
|
-
watch: ProgressWatch;
|
|
21
|
-
}> | Readonly<{
|
|
22
|
-
kind: "nudge";
|
|
23
|
-
nudgeNumber: 1 | 2;
|
|
24
|
-
}> | Readonly<{
|
|
25
|
-
kind: "settled";
|
|
26
|
-
reason: "idle_timeout";
|
|
27
|
-
}>;
|
|
28
|
-
export declare function createProgressWatch(input: Readonly<{
|
|
29
|
-
conversationId: string;
|
|
30
|
-
ownerAlias: string;
|
|
31
|
-
workerAlias: string;
|
|
32
|
-
idleMs: number;
|
|
33
|
-
at: number;
|
|
34
|
-
}>): ProgressWatch;
|
|
35
|
-
export declare function recordProgressWatchActivity(watch: ProgressWatch, at: number): ProgressWatch;
|
|
36
|
-
export declare function inspectProgressWatchDue(watch: ProgressWatch, input: Readonly<{
|
|
37
|
-
at: number;
|
|
38
|
-
bothIdle: boolean;
|
|
39
|
-
}>): ProgressWatchDueInspection;
|
|
40
|
-
export declare function commitProgressWatchNudge(watch: ProgressWatch, input: Readonly<{
|
|
41
|
-
at: number;
|
|
42
|
-
nudgeNumber: 1 | 2;
|
|
43
|
-
}>): ProgressWatch;
|
|
44
|
-
export declare function deferProgressWatchNudge(watch: ProgressWatch, at: number): ProgressWatch;
|
|
45
|
-
export {};
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
export const PROGRESS_WATCH_DEFAULT_IDLE_MS = 5 * 60_000;
|
|
2
|
-
export const PROGRESS_WATCH_MIN_IDLE_MS = 60_000;
|
|
3
|
-
export const PROGRESS_WATCH_MAX_IDLE_MS = 24 * 60 * 60_000;
|
|
4
|
-
const PROGRESS_WATCH_NUDGE_RETRY_MS = 1_000;
|
|
5
|
-
export const PROGRESS_WATCH_DEFAULT_CAPACITY = 32;
|
|
6
|
-
export const PROGRESS_WATCH_HARD_CAPACITY = 256;
|
|
7
|
-
function iso(at) {
|
|
8
|
-
if (!Number.isFinite(at))
|
|
9
|
-
throw new RangeError("INVALID_PROGRESS_WATCH_TIME");
|
|
10
|
-
return new Date(at).toISOString();
|
|
11
|
-
}
|
|
12
|
-
function plus(at, delayMs) {
|
|
13
|
-
return iso(at + delayMs);
|
|
14
|
-
}
|
|
15
|
-
export function createProgressWatch(input) {
|
|
16
|
-
if (!Number.isSafeInteger(input.idleMs) ||
|
|
17
|
-
input.idleMs < PROGRESS_WATCH_MIN_IDLE_MS ||
|
|
18
|
-
input.idleMs > PROGRESS_WATCH_MAX_IDLE_MS) {
|
|
19
|
-
throw new RangeError("INVALID_PROGRESS_WATCH_IDLE_MS");
|
|
20
|
-
}
|
|
21
|
-
const timestamp = iso(input.at);
|
|
22
|
-
return {
|
|
23
|
-
conversationId: input.conversationId, ownerAlias: input.ownerAlias,
|
|
24
|
-
workerAlias: input.workerAlias, lastActivityAt: timestamp,
|
|
25
|
-
idleMs: input.idleMs, nudgeCount: 0,
|
|
26
|
-
nextActionAt: plus(input.at, input.idleMs),
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
export function recordProgressWatchActivity(watch, at) {
|
|
30
|
-
const timestamp = iso(at);
|
|
31
|
-
return {
|
|
32
|
-
...watch,
|
|
33
|
-
lastActivityAt: timestamp, nudgeCount: 0,
|
|
34
|
-
nextActionAt: plus(at, watch.idleMs),
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
export function inspectProgressWatchDue(watch, input) {
|
|
38
|
-
iso(input.at);
|
|
39
|
-
if (input.at < Date.parse(watch.nextActionAt))
|
|
40
|
-
return { kind: "not_due" };
|
|
41
|
-
if (!input.bothIdle) {
|
|
42
|
-
return {
|
|
43
|
-
kind: "rescheduled",
|
|
44
|
-
watch: recordProgressWatchActivity(watch, input.at),
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
if (watch.nudgeCount < 2) {
|
|
48
|
-
return { kind: "nudge", nudgeNumber: (watch.nudgeCount + 1) };
|
|
49
|
-
}
|
|
50
|
-
return { kind: "settled", reason: "idle_timeout" };
|
|
51
|
-
}
|
|
52
|
-
export function commitProgressWatchNudge(watch, input) {
|
|
53
|
-
iso(input.at);
|
|
54
|
-
if (input.at < Date.parse(watch.nextActionAt) ||
|
|
55
|
-
input.nudgeNumber !== watch.nudgeCount + 1) {
|
|
56
|
-
throw new RangeError("INVALID_PROGRESS_WATCH_NUDGE");
|
|
57
|
-
}
|
|
58
|
-
return {
|
|
59
|
-
...watch,
|
|
60
|
-
nudgeCount: input.nudgeNumber,
|
|
61
|
-
nextActionAt: plus(input.at, watch.idleMs * (input.nudgeNumber === 1 ? 1 : 2)),
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
export function deferProgressWatchNudge(watch, at) {
|
|
65
|
-
return {
|
|
66
|
-
...watch,
|
|
67
|
-
nextActionAt: plus(at, PROGRESS_WATCH_NUDGE_RETRY_MS),
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
//# sourceMappingURL=progress-watch-machine.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"progress-watch-machine.js","sourceRoot":"","sources":["../../../src/gateway/progress-watch-machine.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
# 配置与提供方契约
|
|
2
|
-
|
|
3
|
-
Embassy 主要通过各命令启动时读取的环境变量进行配置。本文档汇集所有变量、提供方传输契约、提供方运行时规则与寻址模型。除下文所述的私有 `nodes.json` 联合清单外,所有值均为环境变量或 CLI 标志。
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## 常用配置
|
|
8
|
-
|
|
9
|
-
| 变量 | 默认值 | 用途 |
|
|
10
|
-
| --- | --- | --- |
|
|
11
|
-
| `EMBASSY_STATE_DIR` | `$XDG_STATE_HOME/agent-embassy`,当 `XDG_STATE_HOME` 未设置时为 `$HOME/.local/state/agent-embassy` | 私有状态、控制套接字和仪表盘;覆盖值必须为绝对路径,且不会迁移固定的主机级租约 |
|
|
12
|
-
| `DSH_HOME` | `$HOME/.dsh` | DeepSeek Harness checkout 根目录;当自有目录与 `package.json` 存在时,Embassy 会在首次投递时惰性运行 `pnpm --dir <home> run demo:acp` |
|
|
13
|
-
| `EMBASSY_STEERING_ENABLED` | `1` | 全局 Claude→Codex `STEER:` 停用开关;精确设为 `0` 后,所有 Claude→Codex 正文都按朝向 Codex 的普通排队消息处理;朝向 Claude 的邮箱写入时机不受影响 |
|
|
14
|
-
| `EMBASSY_DELIVERY_NOTICES` | `merged` | Claude 发送方通知策略:`merged` 保留停滞通知并把终局诊断合并到原生状态;`verbose` 同时发送两者;`quiet` 不发送任何网关用户帧通知 |
|
|
15
|
-
| `EMBASSY_TRACKING_ENABLED` | `1` | 全局进度监视停用开关;精确设为 `0` 后,`--track`、`--idle-minutes` 与 `TRACK:` 开启请求会被拒绝。活跃监视只存在于内存中,并随代理进程结束;重启后绝不恢复。没有活跃监视时,`DONE:` 不产生作用;`untrack` 不会因开关而被特别拒绝,而是返回 `NOT_FOUND`。取值只能是 `1` 或 `0`,其他值均为配置错误 |
|
|
16
|
-
| `EMBASSY_LOCALE` | `en` | CLI 输出语言,精确取值 `en` 或 `zh-CN`。`--lang` 标志会覆盖当次调用;未设置或为空表示 `en`,其他任何取值都是参数错误 |
|
|
17
|
-
|
|
18
|
-
任何与网关通信的 Embassy 客户端调用,都会先读取状态目录和 `nodes.json`,
|
|
19
|
-
再连接控制套接字;请将该目录授予沙箱化 Codex 任务作为可写根目录,或批准
|
|
20
|
-
等效的本地访问,并且不要为了绕过拒绝而迁移状态或启动第二个网关进程。
|
|
21
|
-
|
|
22
|
-
联合权限仅来自 `EMBASSY_STATE_DIR` 中的 `nodes.json`。它必须是当前用户所有的 mode-0600 普通文件,且对象形状必须精确为 `{"version":1,"host":"<lowercase-host>","nodes":["<lowercase-ssh-alias>",...]}`。`host` 指定当前代理;`nodes` 包含 0 到 31 个唯一的 OpenSSH 别名,不得包含 `host`,使联合总主机数不超过 32。该文件是必需的;缺失时 Embassy 会打印精确的 `nodes:[]` 仅本地修复方法并拒绝启动。
|
|
23
|
-
移除节点不会删除其持久镜像;在缺少该节点的配置下重启前,请重置私有状态。
|
|
24
|
-
|
|
25
|
-
### 私有状态重置
|
|
26
|
-
|
|
27
|
-
版本 2.0 只接受全新的架构-4 私有状态;它不会转换或重写旧状态。重置前,
|
|
28
|
-
请使用仍在运行的旧代理的 `status` 与投递查询,确认没有排队、已授权或已
|
|
29
|
-
接受的工作,并且每条投递都已结算。然后:
|
|
30
|
-
|
|
31
|
-
1. 停止代理。
|
|
32
|
-
2. 将 `gateway-state.json` 移到一旁,使旧账本仍可恢复。
|
|
33
|
-
3. 原样保留 `nodes.json`。
|
|
34
|
-
4. 启动版本-2 代理以创建全新状态。
|
|
35
|
-
5. 重新注册路由、选择 Claude 路由,并配对所需边。
|
|
36
|
-
|
|
37
|
-
旧版或未知架构会以 `GATEWAY_STATE_SCHEMA_UNSUPPORTED` 拒绝,且不会修改
|
|
38
|
-
状态文件。不存在转换命令或自动恢复路径。
|
|
39
|
-
|
|
40
|
-
当前台实时仪表盘组件运行时,可直接通过 `http://127.0.0.1:41961/` 访问。端口是单次命令的 CLI 选择,而不是环境设置;如需另一个稳定端口,请向 `embassy dashboard --live` 传入 `--port <n>`,其中整数范围为 1024 到 65535。当前台进程运行时,该 URL 最多支持四个并发实时视图(可分布在窗口、标签页或浏览器中);在其中一个关闭前,第五条流会被拒绝。端口冲突会以 `LIVE_DASHBOARD_PORT_IN_USE` 失败并提示使用 `--port`;Embassy 绝不会回退到临时或其他端口。
|
|
41
|
-
|
|
42
|
-
## 高级边界
|
|
43
|
-
|
|
44
|
-
以下变量保留保守的默认值:
|
|
45
|
-
|
|
46
|
-
| 变量 | 默认值 |
|
|
47
|
-
| --- | ---: |
|
|
48
|
-
| `EMBASSY_MAX_ROUTES` | `128` |
|
|
49
|
-
| `EMBASSY_MAX_PAIRS` | `128` |
|
|
50
|
-
| `EMBASSY_MAX_WATCHES` | `32` |
|
|
51
|
-
| `EMBASSY_EVENT_CAPACITY` / `EMBASSY_EVENT_TTL_MS` | `500` / `86400000` |
|
|
52
|
-
| `EMBASSY_DEDUPE_CAPACITY` / `EMBASSY_DEDUPE_TTL_MS` | `2000` / `300000` |
|
|
53
|
-
| `EMBASSY_MAX_QUEUE_MESSAGES` / `EMBASSY_MAX_QUEUE_PER_ROUTE` | `100` / `20` |
|
|
54
|
-
| `EMBASSY_MAX_IN_FLIGHT` | `16` |
|
|
55
|
-
| `EMBASSY_MAX_QUEUE_BYTES` / `EMBASSY_MAX_MESSAGE_BYTES` | `1048576` / `16384` |
|
|
56
|
-
| `EMBASSY_MESSAGE_DEADLINE_MS` | `14400000` |
|
|
57
|
-
| `EMBASSY_RATE_LIMIT` / `EMBASSY_RATE_WINDOW_MS` | `30` / `60000` |
|
|
58
|
-
|
|
59
|
-
`EMBASSY_MAX_PAIRS` 就是 README 中"默认上限 128 个配对"背后的那个变量,取值范围为 1 到 256。`EMBASSY_MAX_WATCHES` 限制并发进度监视数量,硬上限为 256。`EMBASSY_MAX_ROUTES` 接受 2 到 256。本表中的每个值都在启动时校验;超出范围或非整数的设置会以 `INVALID_GATEWAY_CONFIGURATION` 关闭失败,而不是被截断到边界。
|
|
60
|
-
|
|
61
|
-
停滞通知本身不可单独配置。它在 `min(floor(EMBASSY_MESSAGE_DEADLINE_MS / 2), 120000)` 毫秒时触发,因此在默认的四小时截止时间下,待投递消息会在两分钟时被报告,而不是两小时。
|
|
62
|
-
|
|
63
|
-
初始发送方从 CLI 结果获得完整 `conv_` 令牌,接收方则从入站消息的来源封装和回复提示中获得同一个令牌。令牌是内存中的参与方范围定位符,不是权限凭据:每次 `reply` 都会重新检查调用方身份、参与关系和实时路由。代理重启后令牌不再存在;路由失效或身份替换后,也不得重试或重构旧令牌。
|
|
64
|
-
|
|
65
|
-
公开发布的启动器仍绑定本地主机。在 SSH 许可清单联合模式下,每个代理服务 `nodes.json` 已验证的精确主机身份。`register-codex` 会推断该主机;别名及任何 `--succeeds` 别名都必须使用相同后缀。
|
|
66
|
-
|
|
67
|
-
## Claude Code 自身的设置:`crossSessionInbound`
|
|
68
|
-
|
|
69
|
-
`crossSessionInbound` 是 Claude Code 的原生跨会话消息设置:它决定一个 Claude 会话接受、挂起还是拒绝来自其他会话的消息。Embassy 需要在你选择作为 Codex→Claude 目的地的会话上启用此设置,且无法覆盖该决定。请在 Claude Code 中配置它,而不是在 Embassy 中。
|
|
70
|
-
|
|
71
|
-
这是你唯一必须主动开启的前置条件,也是最常见的首次运行故障——因为它**失败得很晚**。快速开始的第 3 步(`select-claude`)无论该设置是否启用都会打印 `"accepted":true`:选择不会创建权限边,也不查询 Claude 的原生入站策略。请使用 `pair` 显式创建权限边;拒绝要到消息抵达 Claude 端时才出现。如果注册、选择与配对都成功,但第一条 `send` 没有送达,请先检查目的地会话上的 `crossSessionInbound`,再去怀疑路由。
|
|
72
|
-
|
|
73
|
-
## 提供方与运行时契约
|
|
74
|
-
|
|
75
|
-
Embassy 路由五种提供方:Claude 使用对等协议 1,Codex 使用托管 App Server,DeepSeek 与 Grok Build 使用 ACP v1,通用 shell 对等方使用私有控制套接字。发布版自有的[支持矩阵](../support/provider-support-matrix.json)记录离线测试的精确构件、协议、能力、停止保真度、限制与测试日期;运行时从不导入它。构建或版本事实可以限定发布版“已测试”的说法,但绝不授予或撤销路由权限。
|
|
76
|
-
|
|
77
|
-
运行时采用尽力而为模式:显式同意边加上精确自有路由/会话身份会授权一次尝试。当前逐操作传输、被消费协议字段的严格结构与相关操作决定结果。接口变化或可选提供方缺失会显示为提供方局部的降级/离线健康度与精确安全代码;它不会产生兼容性等级,也不会阻止其他提供方。
|
|
78
|
-
|
|
79
|
-
只有 Embassy 自有或执行的构件及其回调、控制或状态路径出现不安全 OS 证据——例如不安全的租约或状态、被替换的二进制、所有权/路径/符号链接不匹配,或无效的代际——才会拒绝代理启动。Claude 自有的外部会话注册表根目录属于读取侧身份依据:UID 或模式不安全时,只会让 Claude 降级并醒目显示,代理与其他提供方继续运行。Claude 每条会话记录仍必须使用原生 `peerProtocol: 1`;声明其他值的记录会单独被拒绝并纳入有界拒绝证据,不会阻止代理启动或隐藏其他可用会话。
|
|
80
|
-
|
|
81
|
-
运行时仍会严格解析每个已知注册表字段、帧和响应;未知的 Claude 注册表顶层字段会被忽略,因为 Embassy 从不使用它们。公开状态中的 Claude 连接器行会携带可选的有界 `registry` 观测:`entriesScanned`、`parseableRecords`、单调的 `parseableRecordSeenSinceBoot`、按安全代码分组且有界的 `rejected`,以及 `rejectedCodesOmitted`。两种仪表盘会醒目呈现同一事实:如果 Claude 正在运行,但自代理启动以来从未观测到带可解析必需字段的记录,它的注册表布局可能已更改。
|
|
82
|
-
|
|
83
|
-
托管 Codex 安装通过精确已验证路径解析;`PATH` 上其他位置的 `codex` 不会被使用或修改。Claude 注册表与回调根目录从已验证的当前 OS 用户派生;不会读取 Claude 启动器或配置文件。DeepSeek 只使用上方已验证的 checkout 根目录。Grok Build 使用发布版固定的 ACP 启动。版本字符串如存在,也只是有界诊断元数据。
|
|
84
|
-
|
|
85
|
-
## 寻址
|
|
86
|
-
|
|
87
|
-
Claude 会话通过其当前的 `name@host` 或用户提供的原生会话 UUID 寻址。UUID 是稳定的逻辑标识;当前名称是实时查找别名。重命名后,旧名称立即停止解析,而已选择的 UUID 绑定路由在新名称下继续有效。重命名会在该会话的下一次状态切换(通常是下一个轮次边界)时才对外可见——因为 Claude Code 在状态切换时整体重写会话注册表记录,而非在重命名的瞬间;Embassy 反映的是注册表记录,而非重命名操作本身。
|
|
88
|
-
|
|
89
|
-
名称、旧名称、PID、注册表路径、进程生成号和套接字生成号绝不会成为替代身份键。当两个在线会话共享同一当前名称时,Embassy 拒绝猜测。
|
|
90
|
-
|
|
91
|
-
Codex 路由使用显式的 `codex-*` 别名和任务继承的线程标识。私有线程 ID 从不作为命令行参数接受,也从不打印。注册时不执行 App Server 操作。每次投递都会打开并验证新的托管传输,初始化后在不读取历史的前提下恢复精确任务,并仅授权一次正文写入。App Server、桌面应用或代理重启不会改变逻辑路由权限,也无需重新注册。当前任务不可用或不可观察时,尝试会报告操作级安全代码,而注册和同意边仍会保留。
|
|
92
|
-
|
|
93
|
-
Shell 路由使用 `peer-*` 别名与注册时铸造的 `peer_` 令牌。Broker 只持久化
|
|
94
|
-
其 UID/别名/令牌哈希路由句柄,绝不持久化原始令牌。认证调用使用
|
|
95
|
-
`--token-stdin` 在标准输入第一行提供令牌;携带正文的调用将其余字节作为
|
|
96
|
-
正文。`--emit-env` 仍可供稳定 shell harness 选择使用。这里没有 PID 绑定、
|
|
97
|
-
令牌文件、Keychain 条目、守护进程或其他持久化路径。
|
package/docs/DASHBOARD.md
DELETED
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
# Dashboards
|
|
2
|
-
|
|
3
|
-
Embassy ships two dashboard surfaces: a metadata-only static file pair and a
|
|
4
|
-
live streaming companion that may also show bounded retained message bodies.
|
|
5
|
-
This document covers both: the static snapshot model and the live companion's
|
|
6
|
-
tabs, request controls, bounded actions, and security caveat.
|
|
7
|
-
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
## Static dashboard
|
|
11
|
-
|
|
12
|
-
Open `gateway-dashboard.html` inside the configured state directory. It gives a metadata-only view of all five provider rows (Claude, Codex, DeepSeek, Grok Build, and shell peer), connector health, exact named routes and consent edges, recent delivery states, queue depth, latency, and last safe codes.
|
|
13
|
-
|
|
14
|
-
Interpret queue and delivery by direction. Codex-bound ordinary work can wait
|
|
15
|
-
for the task to become idle. Claude-bound work does not wait for Claude idle:
|
|
16
|
-
after routing and pre-write checks it enters Claude's native mailbox
|
|
17
|
-
immediately, and `transport_written` settles that direction as `delivered`.
|
|
18
|
-
The mailbox boundary does not mean Claude read or consumed the body.
|
|
19
|
-
|
|
20
|
-
Every publish writes the language pair — `gateway-dashboard.html` and `gateway-dashboard.zh-CN.html` — side by side in the state directory, and each page carries an in-page link to the other. That link is the only way to switch the static language; `--lang` is a flag of the live companion, not of `refresh-dashboard`.
|
|
21
|
-
|
|
22
|
-
A static page is a point-in-time snapshot and never refreshes itself. Run `embassy refresh-dashboard` and reload to see newer state, or run `embassy dashboard --live` for a streaming view.
|
|
23
|
-
|
|
24
|
-
The static dashboard is deliberately a file rather than a web application. Anything already running as your OS user can read it, so place `EMBASSY_STATE_DIR` outside agent workspaces if that distinction matters to you.
|
|
25
|
-
|
|
26
|
-
## Live dashboard
|
|
27
|
-
|
|
28
|
-
With `embassy serve` already running in another terminal, start the companion in a third:
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
embassy dashboard --live
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
`embassy dashboard --live` starts a separate foreground companion process that
|
|
35
|
-
uses a five-tab browser view (overview, deliveries, routes, activity,
|
|
36
|
-
diagnostics) to stream broker state, including bounded retained bodies in
|
|
37
|
-
delivery detail. It reaches the broker over the same private control socket
|
|
38
|
-
every other command uses, so it reports the gateway as unavailable when
|
|
39
|
-
nothing is serving. The companion is not part of `embassy serve`, which
|
|
40
|
-
remains socket-only with no TCP or HTTP listener.
|
|
41
|
-
|
|
42
|
-
The companion binds exact `127.0.0.1` on stable port `41961` by default and is
|
|
43
|
-
available directly at `http://127.0.0.1:41961/`. To choose another stable port
|
|
44
|
-
for one invocation, pass `--port <n>` with an integer from 1024 through 65535:
|
|
45
|
-
|
|
46
|
-
```bash
|
|
47
|
-
embassy dashboard --live --port 41962
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
The command auto-opens a browser and its ready result prints the same
|
|
51
|
-
bookmarkable dashboard URL. Up to four concurrent live views—across windows,
|
|
52
|
-
tabs, or browsers—can use that URL while the foreground process runs; a fifth
|
|
53
|
-
stream is refused until one closes. If the port is already occupied, startup fails with
|
|
54
|
-
`LIVE_DASHBOARD_PORT_IN_USE`, tells the operator to choose another with
|
|
55
|
-
`--port`, and does not select an ephemeral or alternate port.
|
|
56
|
-
|
|
57
|
-
There is no fragment capability, cookie, login, per-browser session, or
|
|
58
|
-
bootstrap file. The intended posture is one operator and software already
|
|
59
|
-
trusted under that operator's macOS UID. The HTTP listener deliberately does
|
|
60
|
-
not authenticate a process or OS user, so this remains a trusted
|
|
61
|
-
single-user-machine assumption rather than a same-UID enforcement mechanism.
|
|
62
|
-
Any local software that can reach or spoof loopback can read the live view,
|
|
63
|
-
including retained bodies, and submit its bounded actions.
|
|
64
|
-
|
|
65
|
-
The exact Host header is checked on every request. Navigation GETs may omit
|
|
66
|
-
Origin, but every POST requires the exact Origin plus
|
|
67
|
-
`X-Embassy-Request: 1`. `OPTIONS` is not accepted and no CORS headers are sent.
|
|
68
|
-
These checks constrain browser cross-origin requests; they do not authenticate
|
|
69
|
-
local software. There are no generic control or provider routes, telemetry, or
|
|
70
|
-
external assets. The only mutation route accepts exact pair, unpair,
|
|
71
|
-
refresh-discovery, and named Codex-registration-removal actions, requires an
|
|
72
|
-
explicit in-page consequence confirmation, rejects bodies over 1 KiB, and is
|
|
73
|
-
limited to six actions per minute. Removal names only a public `codex-*` alias;
|
|
74
|
-
the broker removes that registration's consent edges and settles active work by
|
|
75
|
-
its durable write phase. No task ID enters the browser contract. The
|
|
76
|
-
browser client keeps only a display-preference key
|
|
77
|
-
(active tab and language) in `localStorage`.
|
|
78
|
-
The browser cannot create tasks, send, reply, approve,
|
|
79
|
-
interrupt, change settings, or invoke arbitrary broker/provider methods. It receives a sanitized
|
|
80
|
-
snapshot via same-origin `fetch`; after each bounded action it reads
|
|
81
|
-
a fresh snapshot. A snapshot observation may settle already-due delivery
|
|
82
|
-
deadlines before projecting state.
|
|
83
|
-
|
|
84
|
-
App Server generations, re-anchors, and refreshes do not appear in Activity or grant route authority. The dashboard reports only best-effort runtime facts from the bounded public snapshot. That public snapshot remains schema version 2 even though the private native store is schema 4. Overview and Routes dynamically enumerate Claude, Codex, DeepSeek, Grok Build, and shell peer even when a route or connector is absent; Deliveries filters by all five source and target providers; Diagnostics shows observed protocol/version metadata, current connector health, and the last safe code. Raw peer tokens and private mailbox receipts never enter the public model. Version metadata never changes route authority.
|
|
85
|
-
|
|
86
|
-
The Diagnostics registry block mirrors optional bounded `registry` observations on the Claude connector row: `entriesScanned`, `parseableRecords`, monotonic `parseableRecordSeenSinceBoot`, bounded per-safe-code `rejected`, and `rejectedCodesOmitted`. It derives “Parseable required fields observed”, “Empty since broker start”, or “No parseable record since broker start”. The last warning says that no Claude registry record with parseable required fields has been observed since broker start and that, if Claude is running, its registry layout may have changed; that possible layout change therefore cannot look like a healthy empty peer list. The dashboard never exposes retained native IDs, operation-local endpoint evidence, raw registry records, or the release-owned offline support matrix, and a later attempt never replays an uncertain message body.
|
|
87
|
-
|
|
88
|
-
An optional `--lang en|zh-CN` flag selects the display language. It belongs to
|
|
89
|
-
the live companion only; the static pair is always written in both languages
|
|
90
|
-
and switched by the in-page link.
|
|
91
|
-
|
|
92
|
-
**Caveat.** The loopback listener does not identify the caller's process or
|
|
93
|
-
UID. Run it only on a trusted single-user machine: local processes, other local
|
|
94
|
-
users, root, and browser extensions able to reach or spoof loopback may read
|
|
95
|
-
and act on everything the live dashboard exposes.
|
|
96
|
-
|
|
97
|
-
The static `gateway-dashboard.html` and `gateway-dashboard.zh-CN.html` files
|
|
98
|
-
remain the inert offline floor: mode 0600, no script, no network.
|
package/docs/DASHBOARD.zh-CN.md
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
# 仪表盘
|
|
2
|
-
|
|
3
|
-
Embassy 提供两种仪表盘界面:一对仅包含元数据的静态文件,以及一个还可以显示有界保留消息正文的实时流式组件。本文档涵盖两者:静态快照模型,以及实时组件的选项卡、请求控制、有限操作和安全注意事项。
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## 静态仪表盘
|
|
8
|
-
|
|
9
|
-
在配置的状态目录下打开 `gateway-dashboard.html`。它提供一个纯元数据视图,包含五种提供方行(Claude、Codex、DeepSeek、Grok Build、Shell 对等方)、连接器健康度、精确具名路由与同意边、近期投递状态、队列深度、延迟和最近安全代码。
|
|
10
|
-
|
|
11
|
-
请按方向理解队列与投递。朝向 Codex 的普通工作可以等待任务空闲;朝向 Claude 的工作不等待 Claude 空闲:通过路由与写前检查后,它会立即进入 Claude 的原生邮箱,而 `transport_written` 会把该方向结算为 `delivered`。这个邮箱边界不表示 Claude 已读取或消费正文。
|
|
12
|
-
|
|
13
|
-
每次发布都会在状态目录下并排写入语言对——`gateway-dashboard.html` 和 `gateway-dashboard.zh-CN.html`,且每个页面都包含指向另一个页面的页内链接。该链接是静态版本切换语言的唯一方式;`--lang` 是实时组件的标志,而非 `refresh-dashboard` 的标志。
|
|
14
|
-
|
|
15
|
-
静态页面是时间点快照,不会自动刷新。运行 `embassy refresh-dashboard` 并重新加载页面以查看最新状态,或运行 `embassy dashboard --live` 获取流式视图。
|
|
16
|
-
|
|
17
|
-
静态仪表盘被有意设计为文件而非 Web 应用。以你的 OS 用户身份运行的任何程序都能读取它,因此如果这种区分对你有意义,请将 `EMBASSY_STATE_DIR` 放在代理工作区之外。
|
|
18
|
-
|
|
19
|
-
## 实时仪表盘
|
|
20
|
-
|
|
21
|
-
在另一个终端中 `embassy serve` 已经运行的情况下,在第三个终端中启动组件:
|
|
22
|
-
|
|
23
|
-
```bash
|
|
24
|
-
embassy dashboard --live
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
`embassy dashboard --live` 启动一个独立的前台组件进程,以五个选项卡(总览、投递、路由、活动、诊断)流式呈现代理状态,并在投递详情中显示有界保留的正文。它通过与其他命令相同的私有控制套接字连接代理,因此在没有服务运行时会报告网关不可用。该组件不是 `embassy serve` 的一部分;后者仍然是纯套接字的,没有 TCP 或 HTTP 监听器。
|
|
28
|
-
|
|
29
|
-
组件默认精确绑定 `127.0.0.1` 上的稳定端口 `41961`,可直接通过 `http://127.0.0.1:41961/` 访问。如需为单次启动选择另一个稳定端口,请传入 1024 到 65535 之间的整数:
|
|
30
|
-
|
|
31
|
-
```bash
|
|
32
|
-
embassy dashboard --live --port 41962
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
命令会自动打开浏览器,ready 结果也会打印同一个可收藏的仪表盘 URL。当前台进程运行时,该 URL 最多支持四个并发实时视图(可分布在窗口、标签页或浏览器中);在其中一个关闭前,第五条流会被拒绝。若端口已被占用,启动会以 `LIVE_DASHBOARD_PORT_IN_USE` 失败,并提示操作员用 `--port` 选择其他端口。Embassy 不会自动选择临时或其他端口。
|
|
36
|
-
|
|
37
|
-
这里没有 URL 片段令牌、Cookie、登录、逐浏览器会话或引导文件。预期姿态是一名操作员,以及已经受信任、以该操作员 macOS UID 运行的软件。HTTP 监听器有意不认证进程或 OS 用户,因此这是可信单用户机器的假设,而不是强制执行同 UID 的机制。任何能够访问或伪造 loopback 的本地软件都可以读取实时视图(包括保留的正文)并提交其有限操作。
|
|
38
|
-
|
|
39
|
-
每个请求都会检查精确的 Host 头。导航 GET 可以缺少 Origin,但每个 POST 都要求精确的 Origin 与 `X-Embassy-Request: 1`。服务器不接受 `OPTIONS`,也不发送 CORS 头。这些检查约束浏览器的跨来源请求,但不认证本地软件。没有通用控制或提供方路由、遥测或外部资源。唯一的变更路由只接受配对、取消配对、刷新发现结果和移除具名 Codex 注册四种精确操作;每次都要求页内明确说明后果并确认,正文上限为 1 KiB,并限制为每分钟六次。移除操作只携带公开的 `codex-*` 别名;代理会删除该注册的同意边,并按其持久化写入阶段结算活动工作。任务 ID 不会进入浏览器契约。浏览器客户端仅在 `localStorage` 中保存一个显示偏好键(当前选项卡与语言)。浏览器不能创建任务、发送、回复、审批、中断、更改设置,也不能调用任意代理或提供方方法。它通过同源 `fetch` 接收快照,并在每次有限操作后重新读取最新快照。一次快照观测可能会在投射状态之前结算已到期的投递截止时间。
|
|
40
|
-
|
|
41
|
-
App Server 代际、重新锚定与刷新不会出现在“活动”中,也不会授予路由权限。仪表盘只报告有界公开快照中的尽力而为运行时事实。即使私有原生存储使用架构 4,公开快照仍保持架构版本 2。“总览”与“路由”会动态枚举 Claude、Codex、DeepSeek、Grok Build 与 Shell 对等方,即使路由或连接器缺失也会显示;“投递”可按五种发送方与接收方提供方筛选;“诊断”显示已观察协议/版本元数据、当前连接器健康度与最近安全代码。原始 peer 令牌与私有邮箱回执绝不会进入公开模型。版本元数据绝不改变路由权限。
|
|
42
|
-
|
|
43
|
-
“诊断”中的注册表区块会镜像 Claude 连接器行上可选的有界 `registry` 观测:`entriesScanned`、`parseableRecords`、单调的 `parseableRecordSeenSinceBoot`、按安全代码分组且有界的 `rejected`,以及 `rejectedCodesOmitted`。它会派生“已观察到可解析必需字段”、“自代理启动以来为空”或“自代理启动以来没有可解析记录”。最后一种警告会说明:自代理启动以来从未观察到带可解析必需字段的 Claude 注册表记录;如果 Claude 正在运行,它的注册表布局可能已更改。因此,这种变化不会伪装成健康的空对等列表。仪表盘绝不暴露保留的原生 ID、逐操作端点证据、原始注册表记录或发布版自有的离线支持矩阵;之后的尝试也绝不重放结果不确定的消息正文。
|
|
44
|
-
|
|
45
|
-
可选的 `--lang en|zh-CN` 标志用于选择显示语言。它仅属于实时组件;静态版本始终以两种语言写入,通过页内链接切换。
|
|
46
|
-
|
|
47
|
-
**注意事项。** loopback 监听器不识别调用方的进程或 UID。请仅在可信的单用户机器上运行:能够访问或伪造 loopback 的本地进程、其他本地用户、root 和浏览器扩展都可能读取并操作实时仪表盘所暴露的一切内容。
|
|
48
|
-
|
|
49
|
-
静态的 `gateway-dashboard.html` 和 `gateway-dashboard.zh-CN.html` 文件仍然是惰性的离线底线:mode 0600,无脚本,无网络。
|
package/docs/DELIVERY.zh-CN.md
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
# 投递语义
|
|
2
|
-
|
|
3
|
-
Embassy 跟踪每条被接受的消息,从 CLI 接受到终态结算的全过程。本文档将投递模型汇集于一处:队列行为、证据状态、失败处理、重试策略,以及让发送方跟踪消息直至结算的投递令牌。这是 Embassy 中 `delivered` 含义与不含义的权威参考。
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
- **投递时机因方向而异。** 通过路由与写前检查后,朝向 Claude 的正文会立即写入 Claude 的原生邮箱,无论观测到 Claude 正繁忙还是空闲;Claude 繁忙绝不是在 Embassy 队列中暂扣这次写入的理由。朝向 Codex 的普通正文则会等待任务可用。仅 Claude→Codex 方向中正文以精确 `STEER:` 开头的消息,可以在当前轮次的下一个工具调用边界被接纳。Embassy 绝不会中断轮次或在生成过程中注入文本;若边界明确不可用,消息会回到普通队列。每条路由最多保留三条排队中的转向消息;第四条被接受时,最旧的一条会结算为 `cancelled/STEER_QUEUE_SUPERSEDED`。
|
|
8
|
-
|
|
9
|
-
- **接受不等于完成。** CLI 初始接受返回一个对话令牌和一个投递令牌。对于朝向 Claude 的投递,`transport_written` 表示原生邮箱写入完成,并且就是终局 `delivered` 边界;Embassy 不会等待 Claude 后续读取或消费正文的证据。朝向 Codex 时,`delivered` 表示 App Server 接受了该轮次。这两个边界都不表示模型已读取、理解或完成工作。
|
|
10
|
-
|
|
11
|
-
- **Shell 对等方确认 stdout。** `peer-*` 投递需要一个在线的 `embassy await` 等待者;没有等待者时,分派会以 `PEER_NOT_AWAITING` 干净推迟。Embassy 武装精确的预备帧,将其交给等待者,并且只在 CLI 把完整帧刷新到 stdout 且返回私有回执后结算为 `delivered`。回执丢失结算为 `unconfirmed`;武装后的不确定性结算为 `ambiguous`。每条注册路由允许一个等待者,全局最多 16 个;等待者、回执和重复确认墓碑状态都只存在于内存。
|
|
12
|
-
|
|
13
|
-
- **接收方获得来源和回复能力。** 每条实际路由到提供方的消息都带有 Embassy 在写入边界生成的单一 `<cross-session-message>` 文本封装:已经验证的发送方别名,以及含完整 `conv_` 令牌、精确接收方别名和对应 `embassy reply` 命令的首个 `<embassy-reply-hint>` 元素。接收方可以只使用该提示继续对话;每次回复仍会重新检查调用方身份、对话参与关系和当前路由。
|
|
14
|
-
|
|
15
|
-
- **证据有三种形态。** `delivered` 表示观测到了该方向的终端提供方边界;已经确认的 Claude 邮箱写入会立即到达这个边界。`unconfirmed` 表示虽有部分分派证据,Embassy 仍无法证明所需终端边界;它不是已确认 Claude 邮箱写入后的降级状态。`ambiguous` 表示写入结果本身未知。三者均为终态,`unconfirmed` 和 `ambiguous` 都不构成重试授权——请检查接收方,因为重发可能导致消息重复。
|
|
16
|
-
|
|
17
|
-
- **原生失败。** Claude 发起的路由或投递失败会结算为原生 `expired`;其原生确认始终在 reason 字段中保留规范化安全代码。默认的 `merged` 通知模式保留早期停滞帧,但抑制重复的终局 `<gateway-delivery-diagnostic>` 用户帧。`verbose` 会恢复该可读诊断帧;`quiet` 会抑制所有由网关生成的用户帧通知(包括停滞通知),但仍保留原生状态和仪表盘事实。任何通知都不包含路径、原生标识符、异常或消息体。`denied` 保留用于真实的用户或策略拒绝,Embassy v1 不会生成该状态。`held` 和已完成传输写入是进度状态,不是成功状态。
|
|
18
|
-
- **原生 held 采用“先尝试、后确认”。** 对 Claude→Codex 入站消息,Embassy 会先尝试精确的立即投递。在一秒提示边界前观察到终局结果时,只发送终局确认。仅当正文确实仍在排队(包括路由繁忙或提供方明确推迟)或到达该边界时投递仍未终结,才发送原生 `held`;终局确认随后发送。Claude 显示的“已批准并释放”通知只表示具备配对同意的网关已接受正文并将其释放到接收方队列;它不表示模型已读取,也不表示有人类批准。
|
|
19
|
-
|
|
20
|
-
- **保守重试。** 尚未分派、朝向 Codex 的消息会在任务忙碌或暂时不可用期间保持排队。每次尝试都打开新的 App Server 传输;注册和连接器观测都不证明可达性。写入前的干净延迟可将已保留工作退回队列。一旦正文写入已被授权,任何不确定性都是终态,绝不重放。朝向 Claude 的正文只有在写前路由失败或暂时不可用时才可能排队。
|
|
21
|
-
|
|
22
|
-
- **有界设计。** 消息体、队列、速率窗口、去重表、截止时间和临时对话都有固定的上限。
|
|
23
|
-
|
|
24
|
-
- **进度监视是独立证据。** 选择启用的监视可能比一条在投递前已过期的开启消息存续更久,因此即使线程活动让监视保持健康,工作方仍可能从未看到原始任务。所有者在假定任务文本已到达之前,应单独检查开启消息的 `delivery-status`。
|
|
25
|
-
|
|
26
|
-
- **重启仅保留干净工作。** 排队或已保留的消息体按有界策略持久化,并可在同一逻辑路由和同意边上恢复一次。崩溃时已授权或已接受的工作结算为 ambiguous 或 unconfirmed,绝不重放。每条仍保留的消息会在私有 v4 状态中保存其不透明投递令牌和状态,因此发送方可在重启后继续检查这一次精确尝试。待处理的等待者、shell 回执、回复或对话能力均不保留。
|
|
27
|
-
|
|
28
|
-
已接受的消息在代理和提供方连接保持健康的情况下被跟踪至终态投递。仪表盘区分接受、进行中、已投递、过期、失败、不明确和废弃等状态。
|
|
29
|
-
|
|
30
|
-
## 来源封装与对话回复
|
|
31
|
-
|
|
32
|
-
Embassy 的存储、队列、`STEER:` 分类、去重、速率限制和 16 KiB 接纳边界都作用于原始正文。只有在最后的提供方写入边界,Embassy 才会确定性地添加一次权威文本封装。因此,干净的写前重试会得到字节级一致、且不会重复嵌套的封装。
|
|
33
|
-
|
|
34
|
-
双向封装共享一个由代理拥有的外层 `<cross-session-message>` 标记和首个 `<embassy-reply-hint>` 元素,但遵循各接收方的固定协议:
|
|
35
|
-
|
|
36
|
-
- **朝向 Codex:** 外层的 `from-name` 包含已经验证的精确来源别名,`conversation` 包含完整对话令牌。
|
|
37
|
-
- **朝向 Claude:** 外层只使用 Claude Code 规范解析器接受的有界 `from-name`。来源别名超过 64 个字符时会得到确定性的 64 字符显示标签,首个回复提示则通过 `from-alias` 保留精确别名。Claude 的外层封装不带 `conversation`,因为该属性不属于其规范解析格式。
|
|
38
|
-
- **两个方向:** 首个 `embassy-reply-hint` 都带有 `conversation`、`reply-as` 和从标准输入读取正文的精确回复命令。`reply-as` 始终是接收方别名,不是发送方别名;提示会明确说明调用方、对话参与关系和路由仍会重新检查。
|
|
39
|
-
|
|
40
|
-
这个格式是与 Claude Code 兼容的文本框架和模型可见的来源边界,不是通用 XML、密码学签名,也不能证明正文安全。Embassy 先用已经验证的代理元数据组成真实外层和提示;随后仅在不可信原始正文内,对大小写不敏感且形似边界的 `cross-session-message` 与 `embassy-reply-hint` 起止标记进行中和:在其前导 `<` 后立即插入 `\`。其余正文保持原样。正文内已有的 Claude 原生封装因此只是 Embassy 单一权威外层之下的不可信嵌套文本。
|
|
41
|
-
|
|
42
|
-
对话令牌是临时的参与方范围定位符,单独持有它并不足以取得权限。接收方可以使用收到的完整令牌,但代理仍会验证继承的调用方身份、当前对话参与关系、路由状态和入站策略。切勿根据仅含元数据的视图所显示的后缀重构令牌。
|
|
43
|
-
|
|
44
|
-
完整对话令牌只会进入初始发送方的临时 CLI 接纳结果和接收方的临时提供方投递负载;合成后的来源封装只进入后者。已经验证的别名仍遵循现有的公开元数据规则。完整令牌从不被持久化、写入路由日志、记录到普通日志、快照化、放入回执,或呈现在任一仪表盘上。封装、元数据或大小检查失败会在提供方写入之前干净地终局失败;这绝不会被归类为不明确写入,也不会重放。代理重启、身份转交或对话失效后,旧令牌不可恢复,也不得猜测。
|
|
45
|
-
|
|
46
|
-
## 投递令牌
|
|
47
|
-
|
|
48
|
-
每次被接受的 `send` 和 `reply` 都会返回一个投递令牌:`dlv_` 后跟恰好 24 个 base64url 字符。它指向私有 v4 状态中一条有界的消息/状态记录,不是提供方回执句柄。令牌只持久化在 mode-0600 的代理状态中,绝不会进入公开快照、普通日志、提供方回执或任何仪表盘。
|
|
49
|
-
|
|
50
|
-
```bash
|
|
51
|
-
embassy delivery-status --token dlv_<token>
|
|
52
|
-
embassy wait-delivery --token dlv_<token>
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
`delivery-status` 读取保留状态一次。`wait-delivery` 轮询直至消息到达终态或投递截止时间到期。仅在 `delivered` 时以退出码 `0` 退出,任何其他终态(`unconfirmed`、`expired`、`failed`、`ambiguous` 或 `cancelled`)以退出码 `6` 退出,令牌未知时以 `3` 退出,本地等待超时以 `4` 退出——超时不是终态,不构成重发授权。重启前仍受保留的令牌在重启后会继续解析;`found: false` 表示该精确令牌不在有界状态中,例如其终态记录已按保留上限被淘汰。
|