dsh-interconnect 0.11.8 → 0.11.10
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 +3 -1
- package/dsh.plugin.json +1 -1
- package/lib/index.js +16 -12
- package/lib/interconnect/index.js +17 -12
- package/lib/interconnect/index.js.map +2 -2
- package/lib/tool-interconnect/index.js +1749 -10
- package/lib/tool-interconnect/index.js.map +4 -4
- package/lib/types/interconnect/index.d.ts +18 -3
- package/lib/types/interconnect/index.d.ts.map +1 -1
- package/lib/types/interconnect/types.d.ts +2 -1
- package/lib/types/interconnect/types.d.ts.map +1 -1
- package/lib/types/tool-interconnect/index.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -58,6 +58,8 @@ session-b07326da-… [running]
|
|
|
58
58
|
答案有双重上限:行数(`MAX_LISTED_SESSIONS`,100 行)与字节预算(`MAX_LIST_ROWS_BYTES`,等于链路
|
|
59
59
|
帧上限减去 4 KiB 的 `query-result` 信封)。整帧必须待在链路的帧上限内,ws 对超限帧会直接关闭
|
|
60
60
|
链路,所以 live session 极多、或标题很长时,对端只回答能装下的前若干行,而不是把传输打断。
|
|
61
|
+
对端不上报截断标志,所以 `interconnect_list` 只在收到的行数正好等于该上限时追加一行提示
|
|
62
|
+
(`100 of possibly more live sessions`)——满页**可能**被截断,缺失的目标仍可能 live。
|
|
61
63
|
ping 与 list 的答复还会按调用方问的 kind 校验形状,形状不符按「无答复」处理(对应 `unreachable`)。
|
|
62
64
|
|
|
63
65
|
### 回复(`reply`)
|
|
@@ -266,7 +268,7 @@ pnpm run build # esbuild → lib/
|
|
|
266
268
|
|
|
267
269
|
## 验证
|
|
268
270
|
|
|
269
|
-
-
|
|
271
|
+
- 164/164 单测通过(服务 + 工具 + skill,含 wire 校验、畸形帧、心跳/池清理、结果帧按 kind 绑定与投影、list 的行数与字节双上限及满页提示等回归用例);
|
|
270
272
|
类型检查、构建均干净。
|
|
271
273
|
- 已在两台机器之间实测双向互通:消息投递、WebSocket 事件推流、以及 agent 经
|
|
272
274
|
`interconnect_send` 工具反向回发,均验证通过。
|
package/dsh.plugin.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-interconnect",
|
|
3
3
|
"description": "Cross-instance message/event handoff for DeepSeek Harness (DSH): WebSocket link, model-facing tools, and companion skill.",
|
|
4
|
-
"version": "0.11.
|
|
4
|
+
"version": "0.11.10",
|
|
5
5
|
"entry": {
|
|
6
6
|
"name": "dsh-interconnect/interconnect",
|
|
7
7
|
"inject": ["agents", "credentials"]
|
package/lib/index.js
CHANGED
|
@@ -1284,10 +1284,22 @@ var InterconnectService = class extends Service {
|
|
|
1284
1284
|
}
|
|
1285
1285
|
this.sendFrame(socket, { type: "query-result", reqId, result });
|
|
1286
1286
|
}
|
|
1287
|
-
/**
|
|
1287
|
+
/**
|
|
1288
|
+
* Surface one remote notification to local listeners and the log.
|
|
1289
|
+
*
|
|
1290
|
+
* `ctx.parallel` is used instead of `ctx.emit`: `emit` maps listeners without
|
|
1291
|
+
* awaiting them, so a listener that returns a rejected promise would surface
|
|
1292
|
+
* as an unhandled rejection, while `parallel` settles every listener and
|
|
1293
|
+
* aggregates their failures.
|
|
1294
|
+
*/
|
|
1288
1295
|
receiveEvent(eventPayload) {
|
|
1289
|
-
|
|
1290
|
-
this.ctx.
|
|
1296
|
+
const { notification, sender } = eventPayload;
|
|
1297
|
+
this.ctx.logger.info(`interconnect: remote event ${notification.kind} from ${sender}`);
|
|
1298
|
+
void this.ctx.parallel("interconnect/event", notification, sender).catch((error) => {
|
|
1299
|
+
const reasons = error instanceof AggregateError ? error.errors : [error];
|
|
1300
|
+
const detail = reasons.map((reason) => reason instanceof Error ? reason.message : String(reason)).join("; ");
|
|
1301
|
+
this.ctx.logger.warn(`interconnect: listener for a ${notification.kind} event from ${sender} threw: ${detail}`);
|
|
1302
|
+
});
|
|
1291
1303
|
}
|
|
1292
1304
|
/**
|
|
1293
1305
|
* Summarize the live local sessions so a sender can discover valid targets
|
|
@@ -1525,15 +1537,7 @@ var InterconnectService = class extends Service {
|
|
|
1525
1537
|
return;
|
|
1526
1538
|
}
|
|
1527
1539
|
if (frame.type === "event") {
|
|
1528
|
-
|
|
1529
|
-
const kind = frame.notification.kind;
|
|
1530
|
-
try {
|
|
1531
|
-
this.receiveEvent({ sender, notification: frame.notification });
|
|
1532
|
-
} catch (error) {
|
|
1533
|
-
this.ctx.logger.warn(
|
|
1534
|
-
`interconnect: listener for a ${kind} event from ${sender} threw: ` + (error instanceof Error ? error.message : String(error))
|
|
1535
|
-
);
|
|
1536
|
-
}
|
|
1540
|
+
this.receiveEvent({ sender: this.peerOf.get(socket) ?? "unknown-peer", notification: frame.notification });
|
|
1537
1541
|
return;
|
|
1538
1542
|
}
|
|
1539
1543
|
if (frame.type === "msg-result") {
|
|
@@ -1284,10 +1284,22 @@ var InterconnectService = class extends Service {
|
|
|
1284
1284
|
}
|
|
1285
1285
|
this.sendFrame(socket, { type: "query-result", reqId, result });
|
|
1286
1286
|
}
|
|
1287
|
-
/**
|
|
1287
|
+
/**
|
|
1288
|
+
* Surface one remote notification to local listeners and the log.
|
|
1289
|
+
*
|
|
1290
|
+
* `ctx.parallel` is used instead of `ctx.emit`: `emit` maps listeners without
|
|
1291
|
+
* awaiting them, so a listener that returns a rejected promise would surface
|
|
1292
|
+
* as an unhandled rejection, while `parallel` settles every listener and
|
|
1293
|
+
* aggregates their failures.
|
|
1294
|
+
*/
|
|
1288
1295
|
receiveEvent(eventPayload) {
|
|
1289
|
-
|
|
1290
|
-
this.ctx.
|
|
1296
|
+
const { notification, sender } = eventPayload;
|
|
1297
|
+
this.ctx.logger.info(`interconnect: remote event ${notification.kind} from ${sender}`);
|
|
1298
|
+
void this.ctx.parallel("interconnect/event", notification, sender).catch((error) => {
|
|
1299
|
+
const reasons = error instanceof AggregateError ? error.errors : [error];
|
|
1300
|
+
const detail = reasons.map((reason) => reason instanceof Error ? reason.message : String(reason)).join("; ");
|
|
1301
|
+
this.ctx.logger.warn(`interconnect: listener for a ${notification.kind} event from ${sender} threw: ${detail}`);
|
|
1302
|
+
});
|
|
1291
1303
|
}
|
|
1292
1304
|
/**
|
|
1293
1305
|
* Summarize the live local sessions so a sender can discover valid targets
|
|
@@ -1525,15 +1537,7 @@ var InterconnectService = class extends Service {
|
|
|
1525
1537
|
return;
|
|
1526
1538
|
}
|
|
1527
1539
|
if (frame.type === "event") {
|
|
1528
|
-
|
|
1529
|
-
const kind = frame.notification.kind;
|
|
1530
|
-
try {
|
|
1531
|
-
this.receiveEvent({ sender, notification: frame.notification });
|
|
1532
|
-
} catch (error) {
|
|
1533
|
-
this.ctx.logger.warn(
|
|
1534
|
-
`interconnect: listener for a ${kind} event from ${sender} threw: ` + (error instanceof Error ? error.message : String(error))
|
|
1535
|
-
);
|
|
1536
|
-
}
|
|
1540
|
+
this.receiveEvent({ sender: this.peerOf.get(socket) ?? "unknown-peer", notification: frame.notification });
|
|
1537
1541
|
return;
|
|
1538
1542
|
}
|
|
1539
1543
|
if (frame.type === "msg-result") {
|
|
@@ -1731,6 +1735,7 @@ var index_default = InterconnectService;
|
|
|
1731
1735
|
export {
|
|
1732
1736
|
INTERCONNECT_TOKEN_REF,
|
|
1733
1737
|
InterconnectService,
|
|
1738
|
+
MAX_LISTED_SESSIONS,
|
|
1734
1739
|
index_default as default,
|
|
1735
1740
|
linkUrl
|
|
1736
1741
|
};
|