dsh-interconnect 0.10.0 → 0.11.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 +20 -15
- package/assets/dsh-interconnect.md +5 -5
- package/dsh.plugin.json +2 -2
- package/lib/index.js +278 -154
- package/lib/interconnect/index.js +280 -155
- package/lib/interconnect/index.js.map +3 -3
- package/lib/skill-interconnect/index.js +1 -1
- package/lib/skill-interconnect/index.js.map +2 -2
- package/lib/tool-interconnect/index.js +70 -58
- package/lib/tool-interconnect/index.js.map +2 -2
- package/lib/types/interconnect/index.d.ts +64 -26
- package/lib/types/interconnect/index.d.ts.map +1 -1
- package/lib/types/interconnect/types.d.ts +7 -46
- package/lib/types/interconnect/types.d.ts.map +1 -1
- package/lib/types/skill-interconnect/index.d.ts.map +1 -1
- package/lib/types/tool-interconnect/index.d.ts +7 -3
- package/lib/types/tool-interconnect/index.d.ts.map +1 -1
- package/package.json +2 -5
|
@@ -11,7 +11,7 @@ var RESOURCE_BASE = {
|
|
|
11
11
|
path: fileURLToPath(new URL("../../assets/", import.meta.url))
|
|
12
12
|
};
|
|
13
13
|
var INVOCATION = { modelInvocable: true, userInvocable: true };
|
|
14
|
-
var DESCRIPTION = "Use the dsh-interconnect tools to exchange messages between DSH sessions, instances, and machines: list live
|
|
14
|
+
var DESCRIPTION = "Use the dsh-interconnect tools to exchange messages between DSH sessions, instances, and machines: list live sessions on a known peer instance, send messages, reply to the last sender, and probe liveness. Use whenever you need to message another DSH agent, coordinate across sessions, or respond to an incoming interconnect handoff.";
|
|
15
15
|
var CANDIDATE = {
|
|
16
16
|
name: "dsh-interconnect",
|
|
17
17
|
description: DESCRIPTION,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/skill-interconnect/index.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Companion skill for the dsh-interconnect tools: tells the model how to use\n * `interconnect_list`, `interconnect_ping`, `interconnect_send`, and\n * `interconnect_reply`, including the automatic sender-identity injection.\n *\n * This is a thin skill provider, intentionally separate from\n * `tool-interconnect`: the service and tools remain usable without the skill,\n * while a preset that wants model guidance can mount this row alongside them.\n * It injects the `interconnect` service so the skill only appears when the\n * transport it describes is actually present.\n * @module @deepseek-ai/dsh-skill-interconnect\n */\n\nimport { readFile } from 'node:fs/promises'\nimport { fileURLToPath } from 'node:url'\nimport { Context } from '@deepseek-ai/cordis'\nimport {\n BUNDLED_SKILL_RANK,\n type SkillCandidate,\n type SkillDefinition,\n type SkillProvider,\n} from '@deepseek-ai/dsh-skill'\n// Activates the `Context.interconnect` merge declared by the interconnect service plugin.\nimport type {} from '../interconnect/index.ts'\n\nconst PROVIDER_NAME = 'dsh-interconnect'\nconst SKILL_BODY_URL = new URL('../../assets/dsh-interconnect.md', import.meta.url)\nconst RESOURCE_BASE = {\n kind: 'directory',\n path: fileURLToPath(new URL('../../assets/', import.meta.url)),\n} as const\nconst INVOCATION = { modelInvocable: true, userInvocable: true } as const\nconst DESCRIPTION = 'Use the dsh-interconnect tools to exchange messages between DSH sessions, instances, and machines: list live
|
|
5
|
-
"mappings": ";AAaA,SAAS,gBAAgB;AACzB,SAAS,qBAAqB;AAE9B;AAAA,EACE;AAAA,OAIK;AAIP,IAAM,gBAAgB;AACtB,IAAM,iBAAiB,IAAI,IAAI,oCAAoC,YAAY,GAAG;AAClF,IAAM,gBAAgB;AAAA,EACpB,MAAM;AAAA,EACN,MAAM,cAAc,IAAI,IAAI,iBAAiB,YAAY,GAAG,CAAC;AAC/D;AACA,IAAM,aAAa,EAAE,gBAAgB,MAAM,eAAe,KAAK;AAC/D,IAAM,cAAc;
|
|
4
|
+
"sourcesContent": ["/**\n * Companion skill for the dsh-interconnect tools: tells the model how to use\n * `interconnect_list`, `interconnect_ping`, `interconnect_send`, and\n * `interconnect_reply`, including the automatic sender-identity injection.\n *\n * This is a thin skill provider, intentionally separate from\n * `tool-interconnect`: the service and tools remain usable without the skill,\n * while a preset that wants model guidance can mount this row alongside them.\n * It injects the `interconnect` service so the skill only appears when the\n * transport it describes is actually present.\n * @module @deepseek-ai/dsh-skill-interconnect\n */\n\nimport { readFile } from 'node:fs/promises'\nimport { fileURLToPath } from 'node:url'\nimport { Context } from '@deepseek-ai/cordis'\nimport {\n BUNDLED_SKILL_RANK,\n type SkillCandidate,\n type SkillDefinition,\n type SkillProvider,\n} from '@deepseek-ai/dsh-skill'\n// Activates the `Context.interconnect` merge declared by the interconnect service plugin.\nimport type {} from '../interconnect/index.ts'\n\nconst PROVIDER_NAME = 'dsh-interconnect'\nconst SKILL_BODY_URL = new URL('../../assets/dsh-interconnect.md', import.meta.url)\nconst RESOURCE_BASE = {\n kind: 'directory',\n path: fileURLToPath(new URL('../../assets/', import.meta.url)),\n} as const\nconst INVOCATION = { modelInvocable: true, userInvocable: true } as const\nconst DESCRIPTION = 'Use the dsh-interconnect tools to exchange messages between DSH sessions, instances, and machines: list live sessions on a known peer instance, send messages, reply to the last sender, and probe liveness. Use whenever you need to message another DSH agent, coordinate across sessions, or respond to an incoming interconnect handoff.'\n/* jscpd:ignore-start -- the bundled-skill provider shape is the same required boilerplate as skill-badge. */\nconst CANDIDATE: SkillCandidate = {\n name: 'dsh-interconnect',\n description: DESCRIPTION,\n invocation: INVOCATION,\n provider: PROVIDER_NAME,\n source: 'bundled',\n resourceBase: RESOURCE_BASE,\n rank: BUNDLED_SKILL_RANK,\n locator: SKILL_BODY_URL,\n}\n\nconst provider: SkillProvider = {\n name: PROVIDER_NAME,\n list: () => Promise.resolve([CANDIDATE]),\n async get(_candidate): Promise<SkillDefinition> {\n return {\n name: CANDIDATE.name,\n description: CANDIDATE.description,\n invocation: CANDIDATE.invocation,\n provider: CANDIDATE.provider,\n source: CANDIDATE.source,\n resourceBase: RESOURCE_BASE,\n content: await readFile(SKILL_BODY_URL, 'utf8'),\n }\n },\n}\n/* jscpd:ignore-end */\n\n/** Cordis plugin name. */\nexport const name = 'skill-interconnect'\n/** Services required by the companion provider. */\nexport const inject = ['skills', 'interconnect']\n\n/** Register the bundled `dsh-interconnect` skill on `ctx.skills`. */\nexport function apply(ctx: Context): void {\n ctx.skills.registerProvider(() => provider)\n}\n"],
|
|
5
|
+
"mappings": ";AAaA,SAAS,gBAAgB;AACzB,SAAS,qBAAqB;AAE9B;AAAA,EACE;AAAA,OAIK;AAIP,IAAM,gBAAgB;AACtB,IAAM,iBAAiB,IAAI,IAAI,oCAAoC,YAAY,GAAG;AAClF,IAAM,gBAAgB;AAAA,EACpB,MAAM;AAAA,EACN,MAAM,cAAc,IAAI,IAAI,iBAAiB,YAAY,GAAG,CAAC;AAC/D;AACA,IAAM,aAAa,EAAE,gBAAgB,MAAM,eAAe,KAAK;AAC/D,IAAM,cAAc;AAEpB,IAAM,YAA4B;AAAA,EAChC,MAAM;AAAA,EACN,aAAa;AAAA,EACb,YAAY;AAAA,EACZ,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,MAAM;AAAA,EACN,SAAS;AACX;AAEA,IAAM,WAA0B;AAAA,EAC9B,MAAM;AAAA,EACN,MAAM,MAAM,QAAQ,QAAQ,CAAC,SAAS,CAAC;AAAA,EACvC,MAAM,IAAI,YAAsC;AAC9C,WAAO;AAAA,MACL,MAAM,UAAU;AAAA,MAChB,aAAa,UAAU;AAAA,MACvB,YAAY,UAAU;AAAA,MACtB,UAAU,UAAU;AAAA,MACpB,QAAQ,UAAU;AAAA,MAClB,cAAc;AAAA,MACd,SAAS,MAAM,SAAS,gBAAgB,MAAM;AAAA,IAChD;AAAA,EACF;AACF;AAIO,IAAM,OAAO;AAEb,IAAM,SAAS,CAAC,UAAU,cAAc;AAGxC,SAAS,MAAM,KAAoB;AACxC,MAAI,OAAO,iBAAiB,MAAM,QAAQ;AAC5C;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,11 +1,49 @@
|
|
|
1
1
|
// src/tool-interconnect/index.ts
|
|
2
2
|
import { defineTool } from "@deepseek-ai/dsh-tools";
|
|
3
|
+
var name = "tool-interconnect";
|
|
3
4
|
var inject = ["interconnect", "tools"];
|
|
5
|
+
var deliveryOutcomeSchema = {
|
|
6
|
+
type: "object",
|
|
7
|
+
additionalProperties: false,
|
|
8
|
+
properties: {
|
|
9
|
+
delivered: { type: "boolean", required: true },
|
|
10
|
+
instance: { type: "string", required: true },
|
|
11
|
+
delivery: { type: "string" },
|
|
12
|
+
reason: { type: "string" }
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
var raceSignal = (signal, promise) => new Promise((resolve, reject) => {
|
|
16
|
+
const abort = () => {
|
|
17
|
+
const reason = signal.reason;
|
|
18
|
+
reject(reason instanceof Error ? reason : new Error(typeof reason === "string" ? reason : "aborted"));
|
|
19
|
+
};
|
|
20
|
+
if (signal.aborted) {
|
|
21
|
+
abort();
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
25
|
+
promise.then(
|
|
26
|
+
(value) => {
|
|
27
|
+
signal.removeEventListener("abort", abort);
|
|
28
|
+
resolve(value);
|
|
29
|
+
},
|
|
30
|
+
(error) => {
|
|
31
|
+
signal.removeEventListener("abort", abort);
|
|
32
|
+
reject(error instanceof Error ? error : new Error(String(error)));
|
|
33
|
+
}
|
|
34
|
+
);
|
|
35
|
+
});
|
|
36
|
+
var deliveryOutcome = (result) => ({
|
|
37
|
+
delivered: result.delivered,
|
|
38
|
+
instance: result.instance,
|
|
39
|
+
...result.delivery === void 0 ? {} : { delivery: result.delivery },
|
|
40
|
+
...result.reason === void 0 ? {} : { reason: result.reason }
|
|
41
|
+
});
|
|
4
42
|
function apply(ctx) {
|
|
5
43
|
const interconnect = ctx.interconnect;
|
|
6
44
|
ctx.tools.register(defineTool({
|
|
7
45
|
name: "interconnect_send",
|
|
8
|
-
description: 'Deliver one text message to a live session on another DSH instance (same machine, another machine, or another session), over a shared-secret-authenticated channel. Returns whether the peer instance received it and which instance answered. Only a session with a running agent
|
|
46
|
+
description: 'Deliver one text message to a live session on another DSH instance (same machine, another machine, or another session), over a shared-secret-authenticated channel. Returns whether the peer instance received it and which instance answered. Only a session with a running agent receives directly; a persisted one can be woken by setting resume, and when delivery fails the result reports the reason (for example "session-not-live") and interconnect_list shows which sessions are live there. The sending instance and session ids are attached automatically, so the receiver can reply with interconnect_reply; do not pass a sender parameter.',
|
|
9
47
|
parameters: {
|
|
10
48
|
instanceId: {
|
|
11
49
|
type: "string",
|
|
@@ -33,16 +71,7 @@ function apply(ctx) {
|
|
|
33
71
|
}
|
|
34
72
|
},
|
|
35
73
|
output: {
|
|
36
|
-
schema:
|
|
37
|
-
type: "object",
|
|
38
|
-
additionalProperties: false,
|
|
39
|
-
properties: {
|
|
40
|
-
delivered: { type: "boolean", required: true },
|
|
41
|
-
instance: { type: "string", required: true },
|
|
42
|
-
delivery: { type: "string" },
|
|
43
|
-
reason: { type: "string" }
|
|
44
|
-
}
|
|
45
|
-
},
|
|
74
|
+
schema: deliveryOutcomeSchema,
|
|
46
75
|
render: (_args, value) => {
|
|
47
76
|
if (value.delivered) {
|
|
48
77
|
return [{
|
|
@@ -61,7 +90,7 @@ function apply(ctx) {
|
|
|
61
90
|
case "session-owned-by-subagent":
|
|
62
91
|
return `not delivered: "${_args.sessionId}" is a subagent's session on ${value.instance} \u2014 its parent agent owns delivery, so reach it through that parent`;
|
|
63
92
|
default:
|
|
64
|
-
return `not delivered: no live session "${_args.sessionId}" on ${value.instance} \u2014 use interconnect_list to see which sessions are live there, or set resume to wake this one
|
|
93
|
+
return `not delivered: no live session "${_args.sessionId}" on ${value.instance}` + (_args.resume === true ? " \u2014 use interconnect_list to see which sessions are live there" : " \u2014 use interconnect_list to see which sessions are live there, or set resume to wake this one");
|
|
65
94
|
}
|
|
66
95
|
})();
|
|
67
96
|
return [{ type: "text", text }];
|
|
@@ -70,7 +99,7 @@ function apply(ctx) {
|
|
|
70
99
|
async execute(args, exec) {
|
|
71
100
|
const sessionId = exec.agent?.session.id;
|
|
72
101
|
const self = interconnect.selfSender(sessionId === void 0 ? "" : String(sessionId));
|
|
73
|
-
const result = await interconnect.send({
|
|
102
|
+
const result = await raceSignal(exec.signal, interconnect.send({
|
|
74
103
|
instanceId: args.instanceId,
|
|
75
104
|
sessionId: args.sessionId,
|
|
76
105
|
text: args.text,
|
|
@@ -79,18 +108,13 @@ function apply(ctx) {
|
|
|
79
108
|
sender: self,
|
|
80
109
|
...args.delivery === void 0 ? {} : { delivery: args.delivery },
|
|
81
110
|
...args.resume === void 0 ? {} : { resume: args.resume }
|
|
82
|
-
});
|
|
83
|
-
return
|
|
84
|
-
delivered: result.delivered,
|
|
85
|
-
instance: result.instance,
|
|
86
|
-
...result.delivery === void 0 ? {} : { delivery: result.delivery },
|
|
87
|
-
...result.reason === void 0 ? {} : { reason: result.reason }
|
|
88
|
-
};
|
|
111
|
+
}));
|
|
112
|
+
return deliveryOutcome(result);
|
|
89
113
|
}
|
|
90
114
|
}));
|
|
91
115
|
ctx.tools.register(defineTool({
|
|
92
116
|
name: "interconnect_ping",
|
|
93
|
-
description: "Probe a peer DSH instance for liveness and identity over the shared-secret channel.
|
|
117
|
+
description: "Probe a peer DSH instance for liveness and identity over the shared-secret channel. Reports reachable with the peer instance id, or unreachable when the link is down or unauthorized.",
|
|
94
118
|
parameters: {
|
|
95
119
|
instanceId: {
|
|
96
120
|
type: "string",
|
|
@@ -112,8 +136,8 @@ function apply(ctx) {
|
|
|
112
136
|
text: value.reachable ? `reachable: ${value.instance ?? "(unknown instance)"}` : "unreachable or unauthorized"
|
|
113
137
|
}]
|
|
114
138
|
},
|
|
115
|
-
async execute(args) {
|
|
116
|
-
const result = await interconnect.ping(args.instanceId);
|
|
139
|
+
async execute(args, exec) {
|
|
140
|
+
const result = await raceSignal(exec.signal, interconnect.ping(args.instanceId));
|
|
117
141
|
if (result === void 0) return { reachable: false };
|
|
118
142
|
return { reachable: true, instance: result.instance };
|
|
119
143
|
}
|
|
@@ -163,8 +187,8 @@ function apply(ctx) {
|
|
|
163
187
|
return [{ type: "text", text: lines.join("\n") }];
|
|
164
188
|
}
|
|
165
189
|
},
|
|
166
|
-
async execute(args) {
|
|
167
|
-
const result = await interconnect.list(args.instanceId);
|
|
190
|
+
async execute(args, exec) {
|
|
191
|
+
const result = await raceSignal(exec.signal, interconnect.list(args.instanceId));
|
|
168
192
|
if (result === void 0) return { reachable: false };
|
|
169
193
|
return {
|
|
170
194
|
reachable: true,
|
|
@@ -181,13 +205,8 @@ function apply(ctx) {
|
|
|
181
205
|
}));
|
|
182
206
|
ctx.tools.register(defineTool({
|
|
183
207
|
name: "interconnect_reply",
|
|
184
|
-
description:
|
|
208
|
+
description: `Deliver one text message back to the peer that this session last received an interconnect message from. Only the reply text is needed: the replying session is this agent's own, and the outbound target (the peer origin and its session id) is recalled from the message this session received, so you do not ask for an address twice. A session that never received a message through interconnect \u2014 or received one without a sender identity \u2014 reports reason "no-sender-known".`,
|
|
185
209
|
parameters: {
|
|
186
|
-
sessionId: {
|
|
187
|
-
type: "string",
|
|
188
|
-
required: true,
|
|
189
|
-
description: "The LOCAL session id that received the message being replied to."
|
|
190
|
-
},
|
|
191
210
|
text: {
|
|
192
211
|
type: "string",
|
|
193
212
|
required: true,
|
|
@@ -204,16 +223,7 @@ function apply(ctx) {
|
|
|
204
223
|
}
|
|
205
224
|
},
|
|
206
225
|
output: {
|
|
207
|
-
schema:
|
|
208
|
-
type: "object",
|
|
209
|
-
additionalProperties: false,
|
|
210
|
-
properties: {
|
|
211
|
-
delivered: { type: "boolean", required: true },
|
|
212
|
-
instance: { type: "string", required: true },
|
|
213
|
-
delivery: { type: "string" },
|
|
214
|
-
reason: { type: "string" }
|
|
215
|
-
}
|
|
216
|
-
},
|
|
226
|
+
schema: deliveryOutcomeSchema,
|
|
217
227
|
render: (_args, value) => {
|
|
218
228
|
if (value.delivered) {
|
|
219
229
|
return [{
|
|
@@ -223,43 +233,45 @@ function apply(ctx) {
|
|
|
223
233
|
}
|
|
224
234
|
const text = (() => {
|
|
225
235
|
if (value.reason === "no-sender-known") {
|
|
226
|
-
return
|
|
236
|
+
return "not delivered: this session never received an interconnect message with a sender identity";
|
|
227
237
|
}
|
|
228
238
|
if (value.reason === "session-owned-by-subagent") {
|
|
229
|
-
return
|
|
239
|
+
return "not delivered: the recorded sender's session belongs to a subagent and its parent agent owns delivery";
|
|
230
240
|
}
|
|
231
241
|
if (value.reason === "unreachable") {
|
|
232
|
-
return
|
|
242
|
+
return "not delivered: the recorded sender did not answer (unreachable or unauthorized)";
|
|
233
243
|
}
|
|
234
244
|
if (value.reason === "resume-refused") {
|
|
235
|
-
return
|
|
245
|
+
return "not delivered: the recorded sender does not allow waking persisted sessions";
|
|
236
246
|
}
|
|
237
247
|
if (value.reason === "resume-failed") {
|
|
238
|
-
return
|
|
248
|
+
return "not delivered: could not wake the recorded sender's session";
|
|
239
249
|
}
|
|
240
|
-
return
|
|
250
|
+
return "not delivered: the recorded sender's session is not live";
|
|
241
251
|
})();
|
|
242
252
|
return [{ type: "text", text }];
|
|
243
253
|
}
|
|
244
254
|
},
|
|
245
|
-
async execute(args) {
|
|
246
|
-
|
|
247
|
-
|
|
255
|
+
async execute(args, exec) {
|
|
256
|
+
if (exec.agent === void 0) {
|
|
257
|
+
return { delivered: false, instance: "unknown", reason: "session-not-live" };
|
|
258
|
+
}
|
|
259
|
+
const result = await raceSignal(exec.signal, interconnect.reply({
|
|
260
|
+
// The replying session is this executing agent's own session, never a
|
|
261
|
+
// model-supplied id: the local sender map is keyed by session, so a
|
|
262
|
+
// forged id could reply as another session.
|
|
263
|
+
sessionId: String(exec.agent.session.id),
|
|
248
264
|
text: args.text,
|
|
249
265
|
...args.delivery === void 0 ? {} : { delivery: args.delivery },
|
|
250
266
|
...args.resume === void 0 ? {} : { resume: args.resume }
|
|
251
|
-
});
|
|
252
|
-
return
|
|
253
|
-
delivered: result.delivered,
|
|
254
|
-
instance: result.instance,
|
|
255
|
-
...result.delivery === void 0 ? {} : { delivery: result.delivery },
|
|
256
|
-
...result.reason === void 0 ? {} : { reason: result.reason }
|
|
257
|
-
};
|
|
267
|
+
}));
|
|
268
|
+
return deliveryOutcome(result);
|
|
258
269
|
}
|
|
259
270
|
}));
|
|
260
271
|
}
|
|
261
272
|
export {
|
|
262
273
|
apply,
|
|
263
|
-
inject
|
|
274
|
+
inject,
|
|
275
|
+
name
|
|
264
276
|
};
|
|
265
277
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/tool-interconnect/index.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Model-facing tools for cross-instance message handoff: `interconnect_send`\n * delivers one text message to a live session on a peer DSH instance, and\n * `interconnect_ping` probes a peer's liveness and identity.\n *\n * The tools consume the host-plane `interconnect` service and publish nothing\n * themselves, so this row sits as an ordinary tool plugin in a preset while\n * the service it reaches stays host-side (the same split `tool-goal` uses\n * against `goals`).\n * @module @deepseek-ai/dsh-tool-interconnect\n */\n\nimport { Context } from '@deepseek-ai/cordis'\nimport { defineTool } from '@deepseek-ai/dsh-tools'\n// Activates the `Context.interconnect` merge declared by the interconnect service plugin.\nimport type {} from '../interconnect/index.ts'\n\n/** Services required before the tools can register. */\nexport const inject = ['interconnect', 'tools']\n\n/**\n * Register the two tool surfaces. Registration is idempotent per fiber; the\n * tools unregister with the owning fiber.\n * @param ctx - connection context carrying the interconnect service and the tool registry.\n */\nexport function apply(ctx: Context): void {\n const interconnect = ctx.interconnect\n\n ctx.tools.register(defineTool({\n name: 'interconnect_send',\n description: 'Deliver one text message to a live session on another DSH instance (same machine, '\n + 'another machine, or another session), over a shared-secret-authenticated channel. '\n + 'Returns whether the peer instance received it and which instance answered. '\n + 'Only a session with a running agent can receive a message; when none is running the result '\n + 'reports reason \"session-not-live\", and interconnect_list shows which sessions are live there. '\n + 'The sending instance and session ids are attached automatically, so the receiver can reply '\n + 'with interconnect_reply; do not pass a sender parameter.',\n parameters: {\n instanceId: {\n type: 'string',\n required: true,\n description: 'The peer instance id to deliver to, as configured under this instance\\'s '\n + 'interconnect peers map. Deliveries go over the persistent link to that instance.',\n },\n sessionId: {\n type: 'string',\n required: true,\n description: 'Target session id on the receiving instance to deliver the message to.',\n },\n text: {\n type: 'string',\n required: true,\n description: 'Message text delivered to the peer session.',\n },\n delivery: {\n type: 'string',\n enum: ['followup', 'steer', 'inject'],\n description: 'How the message reaches the target agent. `followup` queues it as its own turn '\n + 'behind whatever that agent is doing now. `steer` cuts into the nearest step boundary of a '\n + 'running turn, so an urgent message does not wait for that turn to end. `inject` seeds '\n + 'context without waking an idle agent, so it may sit unread. Omit to use the receiver\\'s '\n + 'configured default.',\n },\n resume: {\n type: 'boolean',\n description: 'Wake the target session if it is persisted but has no running agent. Off by '\n + 'default because delivery to a woken session starts a real agent turn \u2014 a billed model call '\n + 'with that session\\'s full toolset \u2014 in a conversation nobody is watching. Prefer '\n + 'interconnect_list and an already-live target; set this only when that specific session must '\n + 'be reached. The receiver may refuse, answering reason \"resume-refused\".',\n },\n },\n output: {\n schema: {\n type: 'object',\n additionalProperties: false,\n properties: {\n delivered: { type: 'boolean', required: true },\n instance: { type: 'string', required: true },\n delivery: { type: 'string' },\n reason: { type: 'string' },\n },\n },\n render: (_args, value) => {\n if (value.delivered) {\n return [{\n type: 'text',\n text: `delivered to ${value.instance}${value.delivery === undefined ? '' : ` via ${value.delivery}`}`,\n }]\n }\n // Each failure gets the response it actually needs: a not-live target is\n // the caller's to re-choose, while an unreachable peer may just be worth\n // retrying. The old single line claimed \"no live session\" even when the\n // peer never answered, which pointed at the wrong thing entirely.\n const text = ((): string => {\n switch (value.reason) {\n case 'unreachable':\n return `not delivered: ${value.instance} did not answer (unreachable or unauthorized)`\n case 'resume-refused':\n return `not delivered: ${value.instance} does not allow waking persisted sessions`\n case 'resume-failed':\n return `not delivered: could not wake \"${_args.sessionId}\" on ${value.instance}`\n + ' (no such persisted session, or another owner holds it)'\n case 'session-owned-by-subagent':\n return `not delivered: \"${_args.sessionId}\" is a subagent's session on ${value.instance}`\n + ' \u2014 its parent agent owns delivery, so reach it through that parent'\n default:\n return `not delivered: no live session \"${_args.sessionId}\" on ${value.instance}`\n + ' \u2014 use interconnect_list to see which sessions are live there,'\n + ' or set resume to wake this one'\n }\n })()\n return [{ type: 'text', text }]\n },\n },\n async execute(args, exec) {\n const sessionId = exec.agent?.session.id\n const self = interconnect.selfSender(sessionId === undefined ? '' : String(sessionId))\n const result = await interconnect.send({\n instanceId: args.instanceId,\n sessionId: args.sessionId,\n text: args.text,\n // Attribute this instance as the sender so the peer can reply back. The\n // calling session id comes from the executing agent (the session sending).\n sender: self,\n ...(args.delivery === undefined ? {} : { delivery: args.delivery }),\n ...(args.resume === undefined ? {} : { resume: args.resume }),\n })\n return {\n delivered: result.delivered,\n instance: result.instance,\n ...(result.delivery === undefined ? {} : { delivery: result.delivery }),\n ...(result.reason === undefined ? {} : { reason: result.reason }),\n }\n },\n }))\n\n ctx.tools.register(defineTool({\n name: 'interconnect_ping',\n description: 'Probe a peer DSH instance for liveness and identity over the shared-secret channel. '\n + 'Returns the peer instance id when reachable, or null on transport/auth failure.',\n parameters: {\n instanceId: {\n type: 'string',\n required: true,\n description: 'The peer instance id to probe, as configured under this instance\\'s '\n + 'interconnect peers map.',\n },\n },\n output: {\n schema: {\n type: 'object',\n additionalProperties: false,\n properties: {\n reachable: { type: 'boolean', required: true },\n instance: { type: 'string' },\n },\n },\n render: (_args, value) => [{\n type: 'text',\n text: value.reachable\n ? `reachable: ${value.instance ?? '(unknown instance)'}`\n : 'unreachable or unauthorized',\n }],\n },\n async execute(args) {\n const result = await interconnect.ping(args.instanceId)\n if (result === undefined) return { reachable: false }\n return { reachable: true, instance: result.instance }\n },\n }))\n\n ctx.tools.register(defineTool({\n name: 'interconnect_list',\n description: 'List the live sessions on a peer DSH instance, so a message can be addressed without '\n + 'knowing a session id in advance. Every returned sessionId is a valid interconnect_send target at '\n + 'the time of the call. Only live sessions appear: a session that exists on the peer but has no '\n + 'running agent is not listed and cannot receive a message.',\n parameters: {\n instanceId: {\n type: 'string',\n required: true,\n description: 'The peer instance id to list, as configured under this instance\\'s '\n + 'interconnect peers map.',\n },\n },\n output: {\n schema: {\n type: 'object',\n additionalProperties: false,\n properties: {\n reachable: { type: 'boolean', required: true },\n instance: { type: 'string' },\n sessions: {\n type: 'array',\n items: {\n type: 'object',\n additionalProperties: false,\n properties: {\n sessionId: { type: 'string', required: true },\n title: { type: 'string' },\n status: { type: 'string' },\n },\n },\n },\n },\n },\n render: (_args, value) => {\n if (!value.reachable) return [{ type: 'text', text: 'unreachable or unauthorized' }]\n const sessions = value.sessions ?? []\n if (sessions.length === 0) {\n return [{ type: 'text', text: `no live sessions on ${value.instance ?? '(unknown instance)'}` }]\n }\n const lines = sessions.map((session) => {\n const title = session.title === undefined ? '' : ` ${session.title}`\n const status = session.status === undefined ? '' : ` [${session.status}]`\n return `${session.sessionId}${title}${status}`\n })\n return [{ type: 'text', text: lines.join('\\n') }]\n },\n },\n async execute(args) {\n const result = await interconnect.list(args.instanceId)\n if (result === undefined) return { reachable: false }\n return {\n reachable: true,\n instance: result.instance,\n // Rebuild each row so an optional key stays absent rather than\n // becoming an explicit undefined the wire schema would reject.\n sessions: result.sessions.map(session => ({\n sessionId: session.sessionId,\n ...(session.title === undefined ? {} : { title: session.title }),\n ...(session.status === undefined ? {} : { status: session.status }),\n })),\n }\n },\n }))\n\n ctx.tools.register(defineTool({\n name: 'interconnect_reply',\n description: 'Deliver one text message back to the peer that this session last received an '\n + 'interconnect message from. Only the LOCAL session id and the reply text are needed: the '\n + 'outbound target (the peer origin and its session id) is recalled from the message this '\n + 'session received, so you do not ask for an address twice. A session that never received a '\n + 'message through interconnect \u2014 or received one without a sender identity \u2014 reports reason '\n + '\"no-sender-known\".',\n parameters: {\n sessionId: {\n type: 'string',\n required: true,\n description: 'The LOCAL session id that received the message being replied to.',\n },\n text: {\n type: 'string',\n required: true,\n description: 'Message text delivered back to the recorded sender session.',\n },\n delivery: {\n type: 'string',\n enum: ['followup', 'steer', 'inject'],\n description: 'How the reply reaches the target agent, as in interconnect_send. Omit to use '\n + \"the receiver's configured default.\",\n },\n resume: {\n type: 'boolean',\n description: 'Wake the target session if it is persisted but has no running agent, as in '\n + 'interconnect_send. Off by default; the receiver may refuse.',\n },\n },\n output: {\n schema: {\n type: 'object',\n additionalProperties: false,\n properties: {\n delivered: { type: 'boolean', required: true },\n instance: { type: 'string', required: true },\n delivery: { type: 'string' },\n reason: { type: 'string' },\n },\n },\n render: (_args, value) => {\n if (value.delivered) {\n return [{\n type: 'text',\n text: `replied to ${value.instance}${value.delivery === undefined ? '' : ` via ${value.delivery}`}`,\n }]\n }\n const text = ((): string => {\n if (value.reason === 'no-sender-known') {\n return `not delivered: no sender recorded for \"${_args.sessionId}\"`\n + ' \u2014 this session never received an interconnect message with a sender identity'\n }\n if (value.reason === 'session-owned-by-subagent') {\n return `not delivered: \"${_args.sessionId}\" is a subagent's session \u2014 its parent agent owns delivery`\n }\n if (value.reason === 'unreachable') {\n return `not delivered: the recorded sender did not answer (unreachable or unauthorized)`\n }\n if (value.reason === 'resume-refused') {\n return `not delivered: the recorded sender does not allow waking persisted sessions`\n }\n if (value.reason === 'resume-failed') {\n return `not delivered: could not wake the recorded sender's session`\n }\n return `not delivered: the recorded sender's session is not live`\n })()\n return [{ type: 'text', text }]\n },\n },\n async execute(args) {\n const result = await interconnect.reply({\n sessionId: args.sessionId,\n text: args.text,\n ...(args.delivery === undefined ? {} : { delivery: args.delivery }),\n ...(args.resume === undefined ? {} : { resume: args.resume }),\n })\n return {\n delivered: result.delivered,\n instance: result.instance,\n ...(result.delivery === undefined ? {} : { delivery: result.delivery }),\n ...(result.reason === undefined ? {} : { reason: result.reason }),\n }\n },\n }))\n}\n"],
|
|
5
|
-
"mappings": ";
|
|
4
|
+
"sourcesContent": ["/**\n * Model-facing tools for cross-instance message handoff: `interconnect_send`\n * delivers one text message to a live session on a peer DSH instance,\n * `interconnect_ping` probes a peer's liveness and identity, `interconnect_list`\n * discovers a peer's live sessions, and `interconnect_reply` answers the sender\n * a local session last heard from.\n *\n * The tools consume the host-plane `interconnect` service and publish nothing\n * themselves, so this row sits as an ordinary tool plugin in a preset while\n * the service it reaches stays host-side (the same split `tool-goal` uses\n * against `goals`).\n * @module @deepseek-ai/dsh-tool-interconnect\n */\n\nimport { Context } from '@deepseek-ai/cordis'\nimport { defineTool } from '@deepseek-ai/dsh-tools'\n// Activates the `Context.interconnect` merge declared by the interconnect service plugin.\nimport type {} from '../interconnect/index.ts'\n\n/** Cordis plugin name. */\nexport const name = 'tool-interconnect'\n\n/** Services required before the tools can register. */\nexport const inject = ['interconnect', 'tools']\n\n/** Shared `delivered`/`instance`/`delivery`/`reason` outcome shape of send and reply. */\nconst deliveryOutcomeSchema = {\n type: 'object',\n additionalProperties: false,\n properties: {\n delivered: { type: 'boolean', required: true },\n instance: { type: 'string', required: true },\n delivery: { type: 'string' },\n reason: { type: 'string' },\n },\n} as const\n\n/** Settle a service promise against the executing agent's cancellation signal. */\nconst raceSignal = <T>(signal: AbortSignal, promise: Promise<T>): Promise<T> =>\n new Promise<T>((resolve, reject) => {\n const abort = (): void => {\n const reason: unknown = signal.reason\n reject(reason instanceof Error ? reason : new Error(typeof reason === 'string' ? reason : 'aborted'))\n }\n if (signal.aborted) { abort(); return }\n signal.addEventListener('abort', abort, { once: true })\n promise.then(\n (value) => { signal.removeEventListener('abort', abort); resolve(value) },\n (error: unknown) => {\n signal.removeEventListener('abort', abort)\n reject(error instanceof Error ? error : new Error(String(error)))\n },\n )\n })\n\n/** Project one send/reply service result into the tool's canonical outcome. */\nconst deliveryOutcome = (result: {\n delivered: boolean\n instance: string\n delivery?: string\n reason?: string\n}): { delivered: boolean; instance: string; delivery?: string; reason?: string } => ({\n delivered: result.delivered,\n instance: result.instance,\n ...(result.delivery === undefined ? {} : { delivery: result.delivery }),\n ...(result.reason === undefined ? {} : { reason: result.reason }),\n})\n\n/**\n * Register the four tool surfaces. Registration is idempotent per fiber; the\n * tools unregister with the owning fiber.\n * @param ctx - connection context carrying the interconnect service and the tool registry.\n */\nexport function apply(ctx: Context): void {\n const interconnect = ctx.interconnect\n\n ctx.tools.register(defineTool({\n name: 'interconnect_send',\n description: 'Deliver one text message to a live session on another DSH instance (same machine, '\n + 'another machine, or another session), over a shared-secret-authenticated channel. '\n + 'Returns whether the peer instance received it and which instance answered. '\n + 'Only a session with a running agent receives directly; a persisted one can be woken by '\n + 'setting resume, and when delivery fails the result reports the reason (for example '\n + '\"session-not-live\") and interconnect_list shows which sessions are live there. '\n + 'The sending instance and session ids are attached automatically, so the receiver can reply '\n + 'with interconnect_reply; do not pass a sender parameter.',\n parameters: {\n instanceId: {\n type: 'string',\n required: true,\n description: 'The peer instance id to deliver to, as configured under this instance\\'s '\n + 'interconnect peers map. Deliveries go over the persistent link to that instance.',\n },\n sessionId: {\n type: 'string',\n required: true,\n description: 'Target session id on the receiving instance to deliver the message to.',\n },\n text: {\n type: 'string',\n required: true,\n description: 'Message text delivered to the peer session.',\n },\n delivery: {\n type: 'string',\n enum: ['followup', 'steer', 'inject'],\n description: 'How the message reaches the target agent. `followup` queues it as its own turn '\n + 'behind whatever that agent is doing now. `steer` cuts into the nearest step boundary of a '\n + 'running turn, so an urgent message does not wait for that turn to end. `inject` seeds '\n + 'context without waking an idle agent, so it may sit unread. Omit to use the receiver\\'s '\n + 'configured default.',\n },\n resume: {\n type: 'boolean',\n description: 'Wake the target session if it is persisted but has no running agent. Off by '\n + 'default because delivery to a woken session starts a real agent turn \u2014 a billed model call '\n + 'with that session\\'s full toolset \u2014 in a conversation nobody is watching. Prefer '\n + 'interconnect_list and an already-live target; set this only when that specific session must '\n + 'be reached. The receiver may refuse, answering reason \"resume-refused\".',\n },\n },\n output: {\n schema: deliveryOutcomeSchema,\n render: (_args, value) => {\n if (value.delivered) {\n return [{\n type: 'text',\n text: `delivered to ${value.instance}${value.delivery === undefined ? '' : ` via ${value.delivery}`}`,\n }]\n }\n // Each failure gets the response it actually needs: a not-live target is\n // the caller's to re-choose, while an unreachable peer may just be worth\n // The peer's lack of an answer is a delivery outcome, not a liveness claim.\n const text = ((): string => {\n switch (value.reason) {\n case 'unreachable':\n return `not delivered: ${value.instance} did not answer (unreachable or unauthorized)`\n case 'resume-refused':\n return `not delivered: ${value.instance} does not allow waking persisted sessions`\n case 'resume-failed':\n return `not delivered: could not wake \"${_args.sessionId}\" on ${value.instance}`\n + ' (no such persisted session, or another owner holds it)'\n case 'session-owned-by-subagent':\n return `not delivered: \"${_args.sessionId}\" is a subagent's session on ${value.instance}`\n + ' \u2014 its parent agent owns delivery, so reach it through that parent'\n default:\n // When the caller already asked to wake this session, the only\n // honest next step is choosing a live target, not re-requesting\n // resume.\n return `not delivered: no live session \"${_args.sessionId}\" on ${value.instance}`\n + (_args.resume === true\n ? ' \u2014 use interconnect_list to see which sessions are live there'\n : ' \u2014 use interconnect_list to see which sessions are live there, or set resume to wake this one')\n }\n })()\n return [{ type: 'text', text }]\n },\n },\n async execute(args, exec) {\n const sessionId = exec.agent?.session.id\n const self = interconnect.selfSender(sessionId === undefined ? '' : String(sessionId))\n const result = await raceSignal(exec.signal, interconnect.send({\n instanceId: args.instanceId,\n sessionId: args.sessionId,\n text: args.text,\n // Attribute this instance as the sender so the peer can reply back. The\n // calling session id comes from the executing agent (the session sending).\n sender: self,\n ...(args.delivery === undefined ? {} : { delivery: args.delivery }),\n ...(args.resume === undefined ? {} : { resume: args.resume }),\n }))\n return deliveryOutcome(result)\n },\n }))\n\n ctx.tools.register(defineTool({\n name: 'interconnect_ping',\n description: 'Probe a peer DSH instance for liveness and identity over the shared-secret channel. '\n + 'Reports reachable with the peer instance id, or unreachable when the link is down or unauthorized.',\n parameters: {\n instanceId: {\n type: 'string',\n required: true,\n description: 'The peer instance id to probe, as configured under this instance\\'s '\n + 'interconnect peers map.',\n },\n },\n output: {\n schema: {\n type: 'object',\n additionalProperties: false,\n properties: {\n reachable: { type: 'boolean', required: true },\n instance: { type: 'string' },\n },\n },\n render: (_args, value) => [{\n type: 'text',\n text: value.reachable\n ? `reachable: ${value.instance ?? '(unknown instance)'}`\n : 'unreachable or unauthorized',\n }],\n },\n async execute(args, exec) {\n const result = await raceSignal(exec.signal, interconnect.ping(args.instanceId))\n if (result === undefined) return { reachable: false }\n return { reachable: true, instance: result.instance }\n },\n }))\n\n ctx.tools.register(defineTool({\n name: 'interconnect_list',\n description: 'List the live sessions on a peer DSH instance, so a message can be addressed without '\n + 'knowing a session id in advance. Every returned sessionId is a valid interconnect_send target at '\n + 'the time of the call. Only live sessions appear: a session that exists on the peer but has no '\n + 'running agent is not listed and cannot receive a message.',\n parameters: {\n instanceId: {\n type: 'string',\n required: true,\n description: 'The peer instance id to list, as configured under this instance\\'s '\n + 'interconnect peers map.',\n },\n },\n output: {\n schema: {\n type: 'object',\n additionalProperties: false,\n properties: {\n reachable: { type: 'boolean', required: true },\n instance: { type: 'string' },\n sessions: {\n type: 'array',\n items: {\n type: 'object',\n additionalProperties: false,\n properties: {\n sessionId: { type: 'string', required: true },\n title: { type: 'string' },\n status: { type: 'string' },\n },\n },\n },\n },\n },\n render: (_args, value) => {\n if (!value.reachable) return [{ type: 'text', text: 'unreachable or unauthorized' }]\n const sessions = value.sessions ?? []\n if (sessions.length === 0) {\n return [{ type: 'text', text: `no live sessions on ${value.instance ?? '(unknown instance)'}` }]\n }\n const lines = sessions.map((session) => {\n const title = session.title === undefined ? '' : ` ${session.title}`\n const status = session.status === undefined ? '' : ` [${session.status}]`\n return `${session.sessionId}${title}${status}`\n })\n return [{ type: 'text', text: lines.join('\\n') }]\n },\n },\n async execute(args, exec) {\n const result = await raceSignal(exec.signal, interconnect.list(args.instanceId))\n if (result === undefined) return { reachable: false }\n return {\n reachable: true,\n instance: result.instance,\n // Rebuild each row so an optional key stays absent rather than\n // becoming an explicit undefined the wire schema would reject.\n sessions: result.sessions.map(session => ({\n sessionId: session.sessionId,\n ...(session.title === undefined ? {} : { title: session.title }),\n ...(session.status === undefined ? {} : { status: session.status }),\n })),\n }\n },\n }))\n\n ctx.tools.register(defineTool({\n name: 'interconnect_reply',\n description: 'Deliver one text message back to the peer that this session last received an '\n + 'interconnect message from. Only the reply text is needed: the replying session is this '\n + 'agent\\'s own, and the outbound target (the peer origin and its session id) is recalled '\n + 'from the message this session received, so you do not ask for an address twice. A session '\n + 'that never received a message through interconnect \u2014 or received one without a sender '\n + 'identity \u2014 reports reason \"no-sender-known\".',\n parameters: {\n text: {\n type: 'string',\n required: true,\n description: 'Message text delivered back to the recorded sender session.',\n },\n delivery: {\n type: 'string',\n enum: ['followup', 'steer', 'inject'],\n description: 'How the reply reaches the target agent, as in interconnect_send. Omit to use '\n + \"the receiver's configured default.\",\n },\n resume: {\n type: 'boolean',\n description: 'Wake the target session if it is persisted but has no running agent, as in '\n + 'interconnect_send. Off by default; the receiver may refuse.',\n },\n },\n output: {\n schema: deliveryOutcomeSchema,\n render: (_args, value) => {\n if (value.delivered) {\n return [{\n type: 'text',\n text: `replied to ${value.instance}${value.delivery === undefined ? '' : ` via ${value.delivery}`}`,\n }]\n }\n const text = ((): string => {\n if (value.reason === 'no-sender-known') {\n return 'not delivered: this session never received an interconnect message with a sender identity'\n }\n if (value.reason === 'session-owned-by-subagent') {\n return 'not delivered: the recorded sender\\'s session belongs to a subagent and its parent agent owns delivery'\n }\n if (value.reason === 'unreachable') {\n return 'not delivered: the recorded sender did not answer (unreachable or unauthorized)'\n }\n if (value.reason === 'resume-refused') {\n return 'not delivered: the recorded sender does not allow waking persisted sessions'\n }\n if (value.reason === 'resume-failed') {\n return 'not delivered: could not wake the recorded sender\\'s session'\n }\n return 'not delivered: the recorded sender\\'s session is not live'\n })()\n return [{ type: 'text', text }]\n },\n },\n async execute(args, exec) {\n if (exec.agent === undefined) {\n return { delivered: false, instance: 'unknown', reason: 'session-not-live' }\n }\n const result = await raceSignal(exec.signal, interconnect.reply({\n // The replying session is this executing agent's own session, never a\n // model-supplied id: the local sender map is keyed by session, so a\n // forged id could reply as another session.\n sessionId: String(exec.agent.session.id),\n text: args.text,\n ...(args.delivery === undefined ? {} : { delivery: args.delivery }),\n ...(args.resume === undefined ? {} : { resume: args.resume }),\n }))\n return deliveryOutcome(result)\n },\n }))\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,22 +1,32 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Cross-instance message handoff service: inbound half owns one
|
|
3
|
-
* the host webserver and delivers authenticated messages into
|
|
4
|
-
* outbound half
|
|
2
|
+
* Cross-instance message handoff service: the inbound half owns one WebSocket
|
|
3
|
+
* upgrade route on the host webserver and delivers authenticated messages into
|
|
4
|
+
* live sessions; the outbound half dials the same route on peer instances.
|
|
5
5
|
*
|
|
6
6
|
* Transport is deliberately NOT the Connection RPC channel: that registry's
|
|
7
7
|
* handler sees only `(endpoint, payload, signal)` and the trust fence is the
|
|
8
8
|
* DNS-rebinding `trustedHosts` check, neither of which carries the shared-key
|
|
9
|
-
* `Authorization` header this service authenticates on. Owning a plain
|
|
10
|
-
* route keeps bearer-token auth at the boundary where the header is
|
|
11
|
-
* and fails closed when the token is unconfigured.
|
|
9
|
+
* `Authorization` header this service authenticates on. Owning a plain
|
|
10
|
+
* upgrade route keeps bearer-token auth at the boundary where the header is
|
|
11
|
+
* readable and fails closed when the token is unconfigured.
|
|
12
12
|
* @module @deepseek-ai/dsh-interconnect
|
|
13
13
|
*/
|
|
14
14
|
import { Context, Service } from '@deepseek-ai/cordis';
|
|
15
15
|
import z from '@deepseek-ai/schemastery';
|
|
16
|
-
import WebSocket from 'ws';
|
|
17
16
|
import { type Config, type EventNotification, type ListResult, type PingResult, type ReplyRequest, type SendResult, type SendRequest, type SenderIdentity, type WebSocketLinkHandle } from './types.ts';
|
|
18
17
|
export type * from './types.ts';
|
|
19
|
-
|
|
18
|
+
/**
|
|
19
|
+
* Pathname prefix under which this service's WebSocket upgrade route lives.
|
|
20
|
+
* The persistent peer link is established at `<baseURL>/interconnect/link`.
|
|
21
|
+
*/
|
|
22
|
+
export declare const INTERCONNECT_CHANNEL = "/interconnect";
|
|
23
|
+
/**
|
|
24
|
+
* Credential reference holding the shared auth token. Both halves of a link
|
|
25
|
+
* must resolve the same value: inbound requests are rejected unless their
|
|
26
|
+
* `Authorization: Bearer <token>` matches this secret, and outbound requests
|
|
27
|
+
* send it. An unconfigured token fails closed on the inbound side.
|
|
28
|
+
*/
|
|
29
|
+
export declare const INTERCONNECT_TOKEN_REF = "DSH_INTERCONNECT_TOKEN";
|
|
20
30
|
declare module '@deepseek-ai/cordis' {
|
|
21
31
|
interface Context {
|
|
22
32
|
interconnect: InterconnectService;
|
|
@@ -25,15 +35,21 @@ declare module '@deepseek-ai/cordis' {
|
|
|
25
35
|
/**
|
|
26
36
|
* A remote peer instance pushed one authenticated lifecycle notification
|
|
27
37
|
* into this instance. Payload is the exact {@link EventNotification} that
|
|
28
|
-
* crossed the wire; listeners
|
|
38
|
+
* crossed the wire; listeners react synchronously on the frame handler.
|
|
39
|
+
* @mode emit
|
|
40
|
+
* @param notification - the serialized lifecycle fact that crossed the wire.
|
|
41
|
+
* @param peer - the sender's self-reported instance id.
|
|
29
42
|
*/
|
|
30
43
|
'interconnect/event'(notification: EventNotification, peer: string): void;
|
|
31
44
|
}
|
|
32
45
|
}
|
|
33
46
|
/**
|
|
34
47
|
* Live cross-instance handoff service, registered as `ctx.interconnect`.
|
|
35
|
-
* Requires the
|
|
36
|
-
*
|
|
48
|
+
* Requires the live agent registry and the credential store; the webserver is
|
|
49
|
+
* optional — with one, the service accepts inbound links on
|
|
50
|
+
* `/interconnect/link`; without one it still dials configured peers and
|
|
51
|
+
* delivers over those outbound links. Activation is availability-driven like
|
|
52
|
+
* every other host service.
|
|
37
53
|
*/
|
|
38
54
|
export declare class InterconnectService extends Service {
|
|
39
55
|
static inject: string[];
|
|
@@ -55,34 +71,46 @@ export declare class InterconnectService extends Service {
|
|
|
55
71
|
/** In-flight frames sent over a peer link, keyed by `reqId`, awaiting a correlated result. */
|
|
56
72
|
private readonly pendingMessages;
|
|
57
73
|
private reqIdCounter;
|
|
74
|
+
/** Set when the service fiber unwinds; guards late inbound deliveries against driving disposed agents. */
|
|
75
|
+
private disposed;
|
|
58
76
|
constructor(ctx: Context, config: Config);
|
|
59
77
|
/**
|
|
60
78
|
* This instance's identity to attach to outbound messages. Always present:
|
|
61
79
|
* it needs no address, only this instance's id and the calling session.
|
|
62
80
|
* @param sessionId - the local session that is sending, used as the reply target.
|
|
81
|
+
* @returns this instance's address-free identity for the calling session.
|
|
63
82
|
*/
|
|
64
83
|
selfSender(sessionId: string): SenderIdentity;
|
|
84
|
+
/**
|
|
85
|
+
* Deliver one text message to a live session on a peer instance.
|
|
86
|
+
* @param request - the peer instance id, target session, text, and optional delivery/resume overrides.
|
|
87
|
+
* @returns the peer's answer, or an unreachable result when no link answers.
|
|
88
|
+
*/
|
|
65
89
|
send(request: SendRequest): Promise<SendResult>;
|
|
66
90
|
/**
|
|
67
91
|
* Deliver one text message back to the peer that a local session last
|
|
68
92
|
* received a send from. `sessionId` names the LOCAL replying session; the
|
|
69
93
|
* outbound target is the `sender` that session recorded, addressed through
|
|
70
94
|
* this instance's own link to the sender's instance.
|
|
95
|
+
* @param request - the LOCAL replying session id, the reply text, and optional delivery/resume overrides.
|
|
96
|
+
* @returns the recalled sender's answer, or an unreachable result when no link answers.
|
|
71
97
|
*/
|
|
72
98
|
reply(request: ReplyRequest): Promise<SendResult>;
|
|
73
99
|
/**
|
|
74
100
|
* Probe a peer instance for liveness and identity over its persistent link.
|
|
75
101
|
* Returns the peer identity when reachable, or undefined when the link is
|
|
76
102
|
* not up or no answer arrives.
|
|
103
|
+
* @param instanceId - the peer's `instanceId` as configured under {@link Config.peers}.
|
|
104
|
+
* @returns the peer's identity, or undefined when the link is not up or no answer arrives.
|
|
77
105
|
*/
|
|
78
106
|
ping(instanceId: string): Promise<PingResult | undefined>;
|
|
79
107
|
/**
|
|
80
108
|
* List a peer instance's live sessions over its persistent link. Undefined on
|
|
81
109
|
* transport failure, matching `ping`.
|
|
110
|
+
* @param instanceId - the peer's `instanceId` as configured under {@link Config.peers}.
|
|
111
|
+
* @returns the peer's live session rows, or undefined on transport failure.
|
|
82
112
|
*/
|
|
83
113
|
list(instanceId: string): Promise<ListResult | undefined>;
|
|
84
|
-
/** The origin this instance dials to reach a configured peer, or undefined. */
|
|
85
|
-
private originOf;
|
|
86
114
|
/**
|
|
87
115
|
* Send a `msg` frame over the live link to a peer and resolve with its
|
|
88
116
|
* correlated `msg-result`. Undefined when the peer has no live link here
|
|
@@ -102,7 +130,10 @@ export declare class InterconnectService extends Service {
|
|
|
102
130
|
* @returns disposer removing the peer route.
|
|
103
131
|
*/
|
|
104
132
|
subscribe(instanceId: string, origin: string): () => void;
|
|
105
|
-
/**
|
|
133
|
+
/**
|
|
134
|
+
* Remove a peer route, closing its outbound link.
|
|
135
|
+
* @param instanceId - the peer route to remove.
|
|
136
|
+
*/
|
|
106
137
|
unsubscribe(instanceId: string): void;
|
|
107
138
|
/**
|
|
108
139
|
* Open (and, on drop, re-open) a persistent WebSocket link to a peer. Local
|
|
@@ -114,8 +145,6 @@ export declare class InterconnectService extends Service {
|
|
|
114
145
|
* @returns a handle closing the link and cancelling reconnection.
|
|
115
146
|
*/
|
|
116
147
|
link(instanceId: string, origin: string): WebSocketLinkHandle;
|
|
117
|
-
/** Remove a closed outbound link's state so a later `link` re-dials fresh. */
|
|
118
|
-
forgetLink(instanceId: string): void;
|
|
119
148
|
/** Push one serialized lifecycle fact out to every linked peer over WS. */
|
|
120
149
|
private fanout;
|
|
121
150
|
/** Push one fact over every live WebSocket link, dropping closed sockets. */
|
|
@@ -160,27 +189,36 @@ export declare class InterconnectService extends Service {
|
|
|
160
189
|
* when the sender asked and this receiver allows it.
|
|
161
190
|
*/
|
|
162
191
|
private deliver;
|
|
163
|
-
/**
|
|
164
|
-
* Inbound `reply` dispatch: forward a request to {link reply}, resolving the
|
|
165
|
-
* outbound sender for the named local session. Kept separate from {link
|
|
166
|
-
* deliver} so the two wire endpoints stay distinct in the request pipeline.
|
|
167
|
-
*/
|
|
168
|
-
private replyForSession;
|
|
169
192
|
private resolveToken;
|
|
170
|
-
|
|
171
|
-
resolveTokenForDial(): Promise<string | undefined>;
|
|
193
|
+
private resolveTokenForDial;
|
|
172
194
|
/** Inbound WebSocket upgrade: authenticate the bearer header, then accept. */
|
|
173
195
|
private handleUpgrade;
|
|
174
196
|
/**
|
|
175
197
|
* Install frame + liveness handling on one socket and add it to the live
|
|
176
198
|
* pool. Used by both the server half (accepted upgrade) and the client half
|
|
177
|
-
* (outbound dial), so a single socket carries events both directions.
|
|
199
|
+
* (outbound dial), so a single socket carries events both directions. Not a
|
|
200
|
+
* model-facing entry point; the outbound dial reaches it through a private
|
|
201
|
+
* closure.
|
|
202
|
+
* @param websocket - the accepted or dialed socket to install handlers on.
|
|
178
203
|
*/
|
|
179
|
-
attachSocket
|
|
204
|
+
private attachSocket;
|
|
180
205
|
/** Parse and route one inbound link frame, attributing events to the socket's announced peer. */
|
|
181
206
|
private handleFrame;
|
|
182
207
|
/** Write one frame to a socket, returning false when the socket cannot take it. */
|
|
183
208
|
private sendFrame;
|
|
184
209
|
}
|
|
210
|
+
/**
|
|
211
|
+
* Map one HTTP(S) peer origin to the WebSocket URL of its link route. Only
|
|
212
|
+
* the plain-HTTP schemes are rewritten to their WebSocket equivalents; an
|
|
213
|
+
* explicit `wss:` (or `ws:`) origin keeps its scheme, so a TLS peer link is
|
|
214
|
+
* never downgraded to plaintext. Any other scheme (ftp:, file:, ...) is
|
|
215
|
+
* rejected so a misconfigured origin fails loudly instead of feeding
|
|
216
|
+
* `new WebSocket` a URL it cannot dial.
|
|
217
|
+
* @param origin - peer origin as configured, e.g. `http://127.0.0.1:13080`.
|
|
218
|
+
* @returns the link URL, e.g. `ws://127.0.0.1:13080/interconnect/link`.
|
|
219
|
+
* @throws TypeError when the origin is not a valid absolute URL or maps to a
|
|
220
|
+
* non-WebSocket protocol.
|
|
221
|
+
*/
|
|
222
|
+
export declare function linkUrl(origin: string): URL;
|
|
185
223
|
export default InterconnectService;
|
|
186
224
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/interconnect/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,OAAO,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/interconnect/index.ts"],"names":[],"mappings":"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"}
|