@1agents/dreammate-network 0.1.0 → 0.2.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 CHANGED
@@ -28,7 +28,7 @@ dreammate-network/
28
28
  import type { NodeManifest, Execution, SessionURI } from "dreammate-network";
29
29
  ```
30
30
 
31
- Go / Swift 侧读同一份 `schemas/*.json`。详见 [`docs/protocol.md` §9](docs/protocol.md)。
31
+ Go / Swift 侧读同一份 `schemas/*.json`。详见 [`docs/protocol.md` §10](docs/protocol.md)。
32
32
 
33
33
  ## 三条不能破的规则
34
34
 
@@ -47,6 +47,30 @@ export interface AccessDescriptor {
47
47
  /** protocol=cli:命令,如 `tingqi transcript get` */
48
48
  command?: string;
49
49
  }
50
+ /**
51
+ * 约定端口。发现是 pull 的(Control Plane 探测节点的 `/manifest` 与
52
+ * `/health`),所以「哪个服务在哪个端口」必须是公共词汇,否则探测方无从下手。
53
+ *
54
+ * 这是**默认值,不是强制**:服务可以跑在别的端口,代价是探测发现不了它,
55
+ * 得由它自己 `POST /nodes/register` 告知。
56
+ *
57
+ * 与 docs/protocol.md §6 的表格一一对应,改动必须同步两边。
58
+ */
59
+ export declare const DEFAULT_PORTS: {
60
+ readonly "session-registry": 7777;
61
+ readonly "data-service": 7778;
62
+ readonly "control-plane": 7779;
63
+ readonly "tingqi-adapter": 7780;
64
+ };
65
+ export type WellKnownService = keyof typeof DEFAULT_PORTS;
66
+ /**
67
+ * 节点身份是从哪来的。
68
+ *
69
+ * `tailscale` 表示取自 tailnet(`Self.ID` / `DNSName` / `OS`),此时 `name`
70
+ * 跨设备唯一。`local` 是回退,`name` **不保证唯一**——iOS 的 hostname 全是
71
+ * `localhost`——只适合单机自用。放进 `metadata.identity_source` 如实告诉对端。
72
+ */
73
+ export type IdentitySource = "tailscale" | "local";
50
74
  /**
51
75
  * 非 generic 的几种在传输层保留原生协议,不强行塞进
52
76
  * `POST /capabilities/:name/invoke`。
@@ -9,3 +9,21 @@
9
9
  * @packageDocumentation
10
10
  */
11
11
  export const PROTOCOL_VERSION = "0.1.0";
12
+ /* ------------------------------------------------------------------ *
13
+ * 发现
14
+ * ------------------------------------------------------------------ */
15
+ /**
16
+ * 约定端口。发现是 pull 的(Control Plane 探测节点的 `/manifest` 与
17
+ * `/health`),所以「哪个服务在哪个端口」必须是公共词汇,否则探测方无从下手。
18
+ *
19
+ * 这是**默认值,不是强制**:服务可以跑在别的端口,代价是探测发现不了它,
20
+ * 得由它自己 `POST /nodes/register` 告知。
21
+ *
22
+ * 与 docs/protocol.md §6 的表格一一对应,改动必须同步两边。
23
+ */
24
+ export const DEFAULT_PORTS = {
25
+ "session-registry": 7777,
26
+ "data-service": 7778,
27
+ "control-plane": 7779,
28
+ "tingqi-adapter": 7780,
29
+ };
package/docs/protocol.md CHANGED
@@ -118,7 +118,70 @@ POST /capabilities/:name/invoke
118
118
 
119
119
  Capability Manifest 只负责告诉调用方:**我有什么,以及应该怎么访问。**
120
120
 
121
- ## 6. 传输只出现在 `access` 里
121
+ ## 6. 节点与服务的发现
122
+
123
+ 发现分两层,各有各的事实源:
124
+
125
+ ```
126
+ 有哪些节点 ← tailnet(tailscale status --json)
127
+ 节点是不是开着 ← tailnet 的 Online
128
+ 节点上有什么服务 ← 探测约定端口的 GET /manifest
129
+ 服务还活着吗 ← 定期探 GET /health
130
+ ```
131
+
132
+ **方向永远是 L3 → L2(pull),不是 L2 → L3(push)。** 服务不需要知道
133
+ Control Plane 存在,也不需要心跳定时器;Control Plane 挂了,服务毫无感觉。
134
+ 这与「上层通过 HTTP 调用下层」的单向依赖一致。
135
+
136
+ ⚠️ **Node 在线 ≠ Service 在线。** tailnet 的 `Online` 只说明机器开着;
137
+ 进程被 kill 了它照样报在线。Service 级的存活只能靠探 `/health`。
138
+
139
+ ### 约定端口
140
+
141
+ pull 要知道探哪儿,所以端口是公共词汇的一部分:
142
+
143
+ | 端口 | Service | 层 |
144
+ |------|---------|-----|
145
+ | 7777 | `session-registry`(session-reader) | L2 |
146
+ | 7778 | `data-service` | L2 |
147
+ | 7779 | `control-plane` | L3 |
148
+ | 7780 | `tingqi-adapter` 等 Resource Provider | L2 |
149
+ | 7781–7789 | 预留给后续 L2 服务 | — |
150
+
151
+ 这是**默认值,不是强制**。服务可以跑在别的端口,代价是探测发现不了它,
152
+ 得由它自己 `POST /nodes/register` 告知——register 因此是可选的加速/兜底,
153
+ 不是必需品。
154
+
155
+ ### 节点身份取自 tailnet
156
+
157
+ 节点的 `node_id` / `name` / `type` 应该直接用 tailnet 的事实,而不是自己生成:
158
+
159
+ | Manifest 字段 | tailscale status 的来源 |
160
+ |---|---|
161
+ | `node_id` | `Self.ID`(稳定,重启不变) |
162
+ | `name` | `Self.DNSName` 的第一段 |
163
+ | `type` | `Self.OS`(macOS→macos,iOS→ios,…) |
164
+ | `tailscale_name` | `Self.DNSName` |
165
+
166
+ > ⚠️ **不要用 `HostName`。** iOS 设备的 HostName 全是 `localhost`——实测一个
167
+ > 11 节点的 tailnet 里只有 9 个 HostName 唯一,而 DNSName 是 11/11 唯一且可读
168
+ > (`iphone-15-pro`)。用 HostName 做 `session://<node>/...` 的第一段,几台
169
+ > 手机接进来就会全部撞在 `session://localhost/...`。
170
+
171
+ 本机所有服务读同一份 tailnet 状态,所以不会各自生成 id 把一台机器裂成几个 Node。
172
+ 拿不到 tailscale 时可以回退到本地身份,但要在 `metadata.identity_source` 里
173
+ 如实标明,因为回退身份的 `name` 不保证跨设备唯一。
174
+
175
+ ### `/manifest` 永远是部分视图
176
+
177
+ 一个节点上跑着多个服务时,每个服务的 `/manifest` 只报**自己**那一个 service,
178
+ 但 `node_id` 是相同的。完整的节点视图(把同一 `node_id` 下的 services 合并)
179
+ 只存在于 Control Plane 的 `GET /nodes/:id/manifest`。
180
+
181
+ 消费方看到两份 `node_id` 相同、`services` 不同的 manifest 是**正常的**,
182
+ 不是冲突。
183
+
184
+ ## 7. 传输只出现在 `access` 里
122
185
 
123
186
  数据模型里**不存在** MCP Capability / CLI Capability / HTTP Capability。
124
187
  一个 Capability 可以有多种 access,调用方不关心底层是谁:
@@ -141,7 +204,7 @@ Capability Manifest 只负责告诉调用方:**我有什么,以及应该怎
141
204
  ACP 面向 Agent Runtime 的 Session 控制(`agent.session.new` / `prompt` / `cancel` /
142
205
  `status` / `resume`)。
143
206
 
144
- ## 7. 图的边由事件实时写入
207
+ ## 8. 图的边由事件实时写入
145
208
 
146
209
  不跑后台扫库猜 DAG。调用发生时就写边:
147
210
 
@@ -156,7 +219,7 @@ ACP 面向 Agent Runtime 的 Session 控制(`agent.session.new` / `prompt` / `
156
219
 
157
220
  整体 Work Graph **不是** DAG(Session 之间可以成环);DAG 只是它的投影视图。
158
221
 
159
- ## 8. Execution 的粒度边界
222
+ ## 9. Execution 的粒度边界
160
223
 
161
224
  | 层级 | 记录为 |
162
225
  |------|--------|
@@ -166,7 +229,7 @@ ACP 面向 Agent Runtime 的 Session 控制(`agent.session.new` / `prompt` / `
166
229
  否则一个 338 次 tool call 的 Codex Session 会生成 338 个 Execution,
167
230
  Work Graph 立刻失去意义。
168
231
 
169
- ## 9. 怎么消费本包
232
+ ## 10. 怎么消费本包
170
233
 
171
234
  **TypeScript**(工作区内直接引源码,不引入构建链,从而保持真正零依赖):
172
235
 
@@ -205,7 +268,7 @@ npx -p ajv-cli@5 -p ajv-formats@2 ajv validate --spec=draft2020 -c ajv-formats \
205
268
 
206
269
  每个 schema 自带 `examples`,可以直接抽出来当冒烟用例跑。
207
270
 
208
- ## 10. 第一版明确不做
271
+ ## 11. 第一版明确不做
209
272
 
210
273
  - ❌ 不写任何业务逻辑(本包只是公共语言)
211
274
  - ❌ Capability 不带 provider / permission / availability 元数据
@@ -215,7 +278,7 @@ npx -p ajv-cli@5 -p ajv-formats@2 ajv validate --spec=draft2020 -c ajv-formats \
215
278
  - ❌ 不要求所有能力统一成 MCP
216
279
  - ❌ 不存 `planned = true/false`(由时间事实推导)
217
280
 
218
- ## 11. 版本
281
+ ## 12. 版本
219
282
 
220
283
  `PROTOCOL_VERSION = "0.1.0"`。v0.x 期间 schema 可能破坏性变更,
221
284
  以设计册 06-实施路线图的 M1–M5 验收结果为准收敛。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@1agents/dreammate-network",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "DreamMate Network L0 协议包:schema + types,零运行时依赖,不含业务逻辑。",
5
5
  "keywords": [
6
6
  "dreammate",