dsh-interconnect 0.11.3 → 0.11.5
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/assets/dsh-interconnect.md +2 -2
- package/dsh.plugin.json +1 -1
- package/lib/index.js +47 -21
- package/lib/interconnect/index.js +47 -21
- package/lib/interconnect/index.js.map +2 -2
- package/lib/tool-interconnect/index.js +4 -3
- package/lib/tool-interconnect/index.js.map +2 -2
- package/lib/types/interconnect/index.d.ts +9 -0
- package/lib/types/interconnect/index.d.ts.map +1 -1
- package/lib/types/interconnect/types.d.ts +12 -7
- 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
|
@@ -98,14 +98,15 @@ function apply(ctx) {
|
|
|
98
98
|
},
|
|
99
99
|
async execute(args, exec) {
|
|
100
100
|
const sessionId = exec.agent?.session.id;
|
|
101
|
-
const self = interconnect.selfSender(sessionId === void 0 ? "" : String(sessionId));
|
|
102
101
|
const result = await raceSignal(exec.signal, interconnect.send({
|
|
103
102
|
instanceId: args.instanceId,
|
|
104
103
|
sessionId: args.sessionId,
|
|
105
104
|
text: args.text,
|
|
106
105
|
// Attribute this instance as the sender so the peer can reply back. The
|
|
107
|
-
// calling session id comes from the executing agent
|
|
108
|
-
sender
|
|
106
|
+
// calling session id comes from the executing agent; a call without one
|
|
107
|
+
// attaches no sender rather than an empty identity the peer would record
|
|
108
|
+
// as a reply target.
|
|
109
|
+
...sessionId === void 0 ? {} : { sender: interconnect.selfSender(String(sessionId)) },
|
|
109
110
|
...args.delivery === void 0 ? {} : { delivery: args.delivery },
|
|
110
111
|
...args.resume === void 0 ? {} : { resume: args.resume }
|
|
111
112
|
}));
|
|
@@ -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 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 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 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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
|
|
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 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
|
}
|
|
@@ -187,6 +187,15 @@ export declare class InterconnectService extends Service {
|
|
|
187
187
|
*/
|
|
188
188
|
private deliver;
|
|
189
189
|
private resolveToken;
|
|
190
|
+
/**
|
|
191
|
+
* Answer one refused upgrade and close its socket. `socket.end()` alone only
|
|
192
|
+
* half-closes the connection: a client that keeps its own writing side open
|
|
193
|
+
* (a socket created with `allowHalfOpen`) leaves the connection live, and a
|
|
194
|
+
* refused socket never enters the link pool, so nothing else would reap it.
|
|
195
|
+
* @param socket - the refused upgrade socket.
|
|
196
|
+
* @param response - the complete HTTP response sent to the client.
|
|
197
|
+
*/
|
|
198
|
+
private refuseUpgrade;
|
|
190
199
|
/** Inbound WebSocket upgrade: authenticate the bearer header, then accept. */
|
|
191
200
|
private handleUpgrade;
|
|
192
201
|
/**
|
|
@@ -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,EAAiB,MAAM,qBAAqB,CAAA;AAUrE,OAAO,CAAC,MAAM,0BAA0B,CAAA;AAGxC,OAAO,EACL,KAAK,MAAM,EAEX,KAAK,iBAAiB,EAItB,KAAK,UAAU,EACf,KAAK,UAAU,EAEf,KAAK,YAAY,EAEjB,KAAK,UAAU,EACf,KAAK,WAAW,EAEhB,KAAK,cAAc,EAEnB,KAAK,mBAAmB,EACzB,MAAM,YAAY,CAAA;AAgCnB,mBAAmB,YAAY,CAAA;AAE/B;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,2BAA2B,CAAA;AAE9D,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,OAAO;QACf,YAAY,EAAE,mBAAmB,CAAA;KAClC;IACD,UAAU,MAAM;QACd;;;;;;;WAOG;QACH,oBAAoB,CAAC,YAAY,EAAE,iBAAiB,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;KAC1E;CACF;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/interconnect/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -99,9 +99,9 @@ export type SendResult = {
|
|
|
99
99
|
/** Echoed receiver instance id (diagnostic; never trusted for routing). */
|
|
100
100
|
readonly instance: string;
|
|
101
101
|
/**
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
102
|
+
* The mode actually used, so a sender can tell whether its requested override
|
|
103
|
+
* took effect.
|
|
104
|
+
*/
|
|
105
105
|
readonly delivery?: DeliveryMode;
|
|
106
106
|
} | {
|
|
107
107
|
/** False when the target session was not reached. */
|
|
@@ -109,9 +109,9 @@ export type SendResult = {
|
|
|
109
109
|
/** Echoed receiver instance id (diagnostic; never trusted for routing). */
|
|
110
110
|
readonly instance: string;
|
|
111
111
|
/**
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
112
|
+
* Why delivery failed, so a caller can distinguish "wrong target" from
|
|
113
|
+
* "receiver unreachable" instead of guessing from a bare boolean.
|
|
114
|
+
*/
|
|
115
115
|
readonly reason: SendFailure;
|
|
116
116
|
};
|
|
117
117
|
/** Business result of a `ping` endpoint call. */
|
|
@@ -286,7 +286,12 @@ export interface WebSocketLinkHandle {
|
|
|
286
286
|
}
|
|
287
287
|
/** Service config bound by the Composition loader. */
|
|
288
288
|
export interface Config {
|
|
289
|
-
/**
|
|
289
|
+
/**
|
|
290
|
+
* Self-reported id of this instance, echoed in ping/send results for diagnostics.
|
|
291
|
+
* It must be unique across the mesh: lifecycle fan-out addresses links by this
|
|
292
|
+
* announcement, so two instances sharing one id receive events on only one of
|
|
293
|
+
* their links.
|
|
294
|
+
*/
|
|
290
295
|
readonly instanceId: string;
|
|
291
296
|
/** Request timeout for outbound deliveries, in milliseconds. */
|
|
292
297
|
readonly requestTimeoutMs: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/interconnect/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH;;;;;;;;;;GAUG;AACH,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG,OAAO,GAAG,QAAQ,CAAA;AAE1D;;;;;;;;;GASG;AACH,MAAM,WAAW,cAAc;IAC7B,yEAAyE;IACzE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,2EAA2E;IAC3E,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAC3B;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,mDAAmD;IACnD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,0DAA0D;IAC1D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,cAAc,CAAA;IAChC;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,YAAY,CAAA;IAChC;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAC1B;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,MAAM,WAAW,GAAG,kBAAkB,GAAG,aAAa,GAAG,gBAAgB,GAAG,eAAe,GAAG,2BAA2B,GAAG,iBAAiB,CAAA;AAEnJ;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAClB;IACA,oGAAoG;IACpG,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAA;IACxB,2EAA2E;IAC3E,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB;;;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/interconnect/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -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,CAoRxC"}
|
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.5",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "lib/index.js",
|