dsh-interconnect 0.11.6 → 0.11.8
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
|
@@ -55,9 +55,10 @@ session-b07326da-… [running]
|
|
|
55
55
|
只列 live session 是有意的:`send` 能到达的正好是这些。对端存在但没有运行 agent 的 session
|
|
56
56
|
不会出现在列表里,也收不到消息。
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
答案有双重上限:行数(`MAX_LISTED_SESSIONS`,100 行)与字节预算(`MAX_LIST_ROWS_BYTES`,等于链路
|
|
59
|
+
帧上限减去 4 KiB 的 `query-result` 信封)。整帧必须待在链路的帧上限内,ws 对超限帧会直接关闭
|
|
60
|
+
链路,所以 live session 极多、或标题很长时,对端只回答能装下的前若干行,而不是把传输打断。
|
|
61
|
+
ping 与 list 的答复还会按调用方问的 kind 校验形状,形状不符按「无答复」处理(对应 `unreachable`)。
|
|
61
62
|
|
|
62
63
|
### 回复(`reply`)
|
|
63
64
|
|
|
@@ -265,7 +266,7 @@ pnpm run build # esbuild → lib/
|
|
|
265
266
|
|
|
266
267
|
## 验证
|
|
267
268
|
|
|
268
|
-
-
|
|
269
|
+
- 163/163 单测通过(服务 + 工具 + skill,含 wire 校验、畸形帧、心跳/池清理、结果帧按 kind 绑定与投影、list 的行数与字节双上限等回归用例);
|
|
269
270
|
类型检查、构建均干净。
|
|
270
271
|
- 已在两台机器之间实测双向互通:消息投递、WebSocket 事件推流、以及 agent 经
|
|
271
272
|
`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.8",
|
|
5
5
|
"entry": {
|
|
6
6
|
"name": "dsh-interconnect/interconnect",
|
|
7
7
|
"inject": ["agents", "credentials"]
|
|
@@ -43,12 +43,12 @@ function apply(ctx) {
|
|
|
43
43
|
const interconnect = ctx.interconnect;
|
|
44
44
|
ctx.tools.register(defineTool({
|
|
45
45
|
name: "interconnect_send",
|
|
46
|
-
description: 'Deliver one text message to a live session on another DSH instance (same machine, another machine, or another session)
|
|
46
|
+
description: 'Deliver one text message to a live session on another DSH instance (same machine, another machine, or another session). 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.',
|
|
47
47
|
parameters: {
|
|
48
48
|
instanceId: {
|
|
49
49
|
type: "string",
|
|
50
50
|
required: true,
|
|
51
|
-
description: "The peer instance id to deliver to, as configured
|
|
51
|
+
description: "The peer instance id to deliver to, as configured for this instance's interconnect peers."
|
|
52
52
|
},
|
|
53
53
|
sessionId: {
|
|
54
54
|
type: "string",
|
|
@@ -145,7 +145,7 @@ function apply(ctx) {
|
|
|
145
145
|
}));
|
|
146
146
|
ctx.tools.register(defineTool({
|
|
147
147
|
name: "interconnect_list",
|
|
148
|
-
description: "List the live sessions on a peer DSH instance, so a message can be addressed without knowing a session id in advance. Every returned sessionId is a valid interconnect_send target at the time of the call. Only sessions with a running agent appear
|
|
148
|
+
description: "List the live sessions on a peer DSH instance, so a message can be addressed without knowing a session id in advance. Every returned sessionId is a valid interconnect_send target at the time of the call. Only sessions with a running agent appear, and a long listing stops at a size bound, so a live session missing from it may simply not fit; reaching a persisted session requires interconnect_send with resume set.",
|
|
149
149
|
parameters: {
|
|
150
150
|
instanceId: {
|
|
151
151
|
type: "string",
|
|
@@ -234,7 +234,7 @@ function apply(ctx) {
|
|
|
234
234
|
}
|
|
235
235
|
const text = (() => {
|
|
236
236
|
if (value.reason === "no-sender-known") {
|
|
237
|
-
return "not delivered:
|
|
237
|
+
return "not delivered: no sender identity is known to reply to";
|
|
238
238
|
}
|
|
239
239
|
if (value.reason === "session-owned-by-subagent") {
|
|
240
240
|
return "not delivered: the recorded sender's session belongs to a subagent and its parent agent owns delivery";
|
|
@@ -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,\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; the profile layer that enables cross-instance handoff mounts the\n * service, these tools, and the companion skill together.\n * @module @deepseek-ai/dsh-experimental-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\n // is the caller's to re-choose, while an unreachable peer is a delivery\n // outcome rather than 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 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; a call without one\n // attaches no sender rather than an empty identity the peer would record\n // as a reply target.\n ...(sessionId === undefined ? {} : { sender: interconnect.selfSender(String(sessionId)) }),\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 sessions with a running agent appear; reaching a persisted one that is '\n + 'not listed requires interconnect_send with resume set.',\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 sending instance id and 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 // No executing session means no recorded sender to reply to; the\n // closer existing reason states that, and its render text names the\n // missing sender identity instead of a dead remote session.\n return { delivered: false, instance: 'unknown', reason: 'no-sender-known' }\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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
|
|
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; the profile layer that enables cross-instance handoff mounts the\n * service, these tools, and the companion skill together.\n * @module @deepseek-ai/dsh-experimental-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). '\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 for this instance\\'s '\n + 'interconnect peers.',\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\n // is the caller's to re-choose, while an unreachable peer is a delivery\n // outcome rather than 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 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; a call without one\n // attaches no sender rather than an empty identity the peer would record\n // as a reply target.\n ...(sessionId === undefined ? {} : { sender: interconnect.selfSender(String(sessionId)) }),\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 sessions with a running agent appear, and a long listing stops at a '\n + 'size bound, so a live session missing from it may simply not fit; reaching a persisted session '\n + 'requires interconnect_send with resume set.',\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 sending instance id and 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: no sender identity is known to reply to'\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 // No executing session means no recorded sender to reply to; the\n // closer existing reason states that, and its render text names the\n // missing sender identity instead of a dead remote session.\n return { delivered: false, instance: 'unknown', reason: 'no-sender-known' }\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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tool-interconnect/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAK7C,0BAA0B;AAC1B,eAAO,MAAM,IAAI,sBAAsB,CAAA;AAEvC,uDAAuD;AACvD,eAAO,MAAM,MAAM,UAA4B,CAAA;AA6C/C;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tool-interconnect/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAK7C,0BAA0B;AAC1B,eAAO,MAAM,IAAI,sBAAsB,CAAA;AAEvC,uDAAuD;AACvD,eAAO,MAAM,MAAM,UAA4B,CAAA;AA6C/C;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAwRxC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-interconnect",
|
|
3
3
|
"description": "Cross-instance message/event handoff plugins for DeepSeek Harness (DSH): interconnect service + model-facing tools + companion skill",
|
|
4
|
-
"version": "0.11.
|
|
4
|
+
"version": "0.11.8",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "lib/index.js",
|