dsh-interconnect 0.5.0 → 0.6.1
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 +80 -13
- package/lib/index.js +54 -10
- package/lib/interconnect/index.js +54 -10
- package/lib/interconnect/index.js.map +2 -2
- package/lib/tool-interconnect/index.js +20 -2
- package/lib/tool-interconnect/index.js.map +2 -2
- package/lib/types/interconnect/index.d.ts +19 -1
- package/lib/types/interconnect/index.d.ts.map +1 -1
- package/lib/types/interconnect/types.d.ts +30 -2
- package/lib/types/interconnect/types.d.ts.map +1 -1
- package/lib/types/tool-interconnect/index.d.ts.map +1 -1
- package/package.json +3 -1
|
@@ -26,6 +26,10 @@ function apply(ctx) {
|
|
|
26
26
|
type: "string",
|
|
27
27
|
enum: ["followup", "steer", "inject"],
|
|
28
28
|
description: "How the message reaches the target agent. `followup` queues it as its own turn behind whatever that agent is doing now. `steer` cuts into the nearest step boundary of a running turn, so an urgent message does not wait for that turn to end. `inject` seeds context without waking an idle agent, so it may sit unread. Omit to use the receiver's configured default."
|
|
29
|
+
},
|
|
30
|
+
resume: {
|
|
31
|
+
type: "boolean",
|
|
32
|
+
description: `Wake the target session if it is persisted but has no running agent. Off by default because delivery to a woken session starts a real agent turn \u2014 a billed model call with that session's full toolset \u2014 in a conversation nobody is watching. Prefer interconnect_list and an already-live target; set this only when that specific session must be reached. The receiver may refuse, answering reason "resume-refused".`
|
|
29
33
|
}
|
|
30
34
|
},
|
|
31
35
|
output: {
|
|
@@ -46,7 +50,20 @@ function apply(ctx) {
|
|
|
46
50
|
text: `delivered to ${value.instance}${value.delivery === void 0 ? "" : ` via ${value.delivery}`}`
|
|
47
51
|
}];
|
|
48
52
|
}
|
|
49
|
-
const text =
|
|
53
|
+
const text = (() => {
|
|
54
|
+
switch (value.reason) {
|
|
55
|
+
case "unreachable":
|
|
56
|
+
return `not delivered: ${value.instance} did not answer (unreachable or unauthorized)`;
|
|
57
|
+
case "resume-refused":
|
|
58
|
+
return `not delivered: ${value.instance} does not allow waking persisted sessions`;
|
|
59
|
+
case "resume-failed":
|
|
60
|
+
return `not delivered: could not wake "${_args.sessionId}" on ${value.instance} (no such persisted session, or another owner holds it)`;
|
|
61
|
+
case "session-owned-by-subagent":
|
|
62
|
+
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
|
+
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`;
|
|
65
|
+
}
|
|
66
|
+
})();
|
|
50
67
|
return [{ type: "text", text }];
|
|
51
68
|
}
|
|
52
69
|
},
|
|
@@ -55,7 +72,8 @@ function apply(ctx) {
|
|
|
55
72
|
baseUrl: args.baseUrl,
|
|
56
73
|
sessionId: args.sessionId,
|
|
57
74
|
text: args.text,
|
|
58
|
-
...args.delivery === void 0 ? {} : { delivery: args.delivery }
|
|
75
|
+
...args.delivery === void 0 ? {} : { delivery: args.delivery },
|
|
76
|
+
...args.resume === void 0 ? {} : { resume: args.resume }
|
|
59
77
|
});
|
|
60
78
|
return {
|
|
61
79
|
delivered: result.delivered,
|
|
@@ -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 parameters: {\n baseUrl: {\n type: 'string',\n required: true,\n description: 'Receiver instance origin, e.g. http://127.0.0.1:3080 or http://peer-host:9001.',\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 },\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 = value.reason
|
|
5
|
-
"mappings": ";AAaA,SAAS,kBAAkB;AAKpB,IAAM,SAAS,CAAC,gBAAgB,OAAO;AAOvC,SAAS,MAAM,KAAoB;AACxC,QAAM,eAAe,IAAI;AAEzB,MAAI,MAAM,SAAS,WAAW;AAAA,IAC5B,MAAM;AAAA,IACN,aAAa;AAAA,IAKb,YAAY;AAAA,MACV,SAAS;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,QACV,aAAa;AAAA,MACf;AAAA,MACA,WAAW;AAAA,QACT,MAAM;AAAA,QACN,UAAU;AAAA,QACV,aAAa;AAAA,MACf;AAAA,MACA,MAAM;AAAA,QACJ,MAAM;AAAA,QACN,UAAU;AAAA,QACV,aAAa;AAAA,MACf;AAAA,MACA,UAAU;AAAA,QACR,MAAM;AAAA,QACN,MAAM,CAAC,YAAY,SAAS,QAAQ;AAAA,QACpC,aAAa;AAAA,MAKf;AAAA,IACF;AAAA,IACA,QAAQ;AAAA,MACN,QAAQ;AAAA,QACN,MAAM;AAAA,QACN,sBAAsB;AAAA,QACtB,YAAY;AAAA,UACV,WAAW,EAAE,MAAM,WAAW,UAAU,KAAK;AAAA,UAC7C,UAAU,EAAE,MAAM,UAAU,UAAU,KAAK;AAAA,UAC3C,UAAU,EAAE,MAAM,SAAS;AAAA,UAC3B,QAAQ,EAAE,MAAM,SAAS;AAAA,QAC3B;AAAA,MACF;AAAA,MACA,QAAQ,CAAC,OAAO,UAAU;AACxB,YAAI,MAAM,WAAW;AACnB,iBAAO,CAAC;AAAA,YACN,MAAM;AAAA,YACN,MAAM,gBAAgB,MAAM,QAAQ,GAAG,MAAM,aAAa,SAAY,KAAK,QAAQ,MAAM,QAAQ,EAAE;AAAA,UACrG,CAAC;AAAA,QACH;AAKA,cAAM,
|
|
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 parameters: {\n baseUrl: {\n type: 'string',\n required: true,\n description: 'Receiver instance origin, e.g. http://127.0.0.1:3080 or http://peer-host:9001.',\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) {\n const result = await interconnect.send({\n baseUrl: args.baseUrl,\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 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 baseUrl: {\n type: 'string',\n required: true,\n description: 'Peer instance origin, e.g. http://127.0.0.1:3080.',\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.baseUrl)\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 baseUrl: {\n type: 'string',\n required: true,\n description: 'Peer instance origin, e.g. http://127.0.0.1:3080.',\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.baseUrl)\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"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -41,6 +41,7 @@ export declare class InterconnectService extends Service {
|
|
|
41
41
|
private readonly instanceId;
|
|
42
42
|
private readonly requestTimeoutMs;
|
|
43
43
|
private readonly delivery;
|
|
44
|
+
private readonly allowResume;
|
|
44
45
|
private readonly peers;
|
|
45
46
|
private readonly subscriptions;
|
|
46
47
|
private readonly server;
|
|
@@ -100,7 +101,24 @@ export declare class InterconnectService extends Service {
|
|
|
100
101
|
* matches how the Host's own session listing treats its projection column.
|
|
101
102
|
*/
|
|
102
103
|
private listSessions;
|
|
103
|
-
/**
|
|
104
|
+
/**
|
|
105
|
+
* Resolve a session that is not currently live, when the sender asked to wake
|
|
106
|
+
* it. Returns the agent, or the reason it stays undelivered.
|
|
107
|
+
*
|
|
108
|
+
* The resume is delegated to the Host's configured `agent` lookup rather than
|
|
109
|
+
* calling `ctx.agents.resume()` here, and that is the whole point: a handle
|
|
110
|
+
* from `resume()` is owned by the CALLING context, so resuming on this
|
|
111
|
+
* plugin's fiber would tear the session down again the moment the plugin
|
|
112
|
+
* unloads (measured: the same call through the root context leaves it alive).
|
|
113
|
+
* The Host's resolver owns it instead, and it also composes the preset the
|
|
114
|
+
* session recorded — so a woken agent comes back with the toolset its history
|
|
115
|
+
* was produced under, not an empty one.
|
|
116
|
+
*/
|
|
117
|
+
private wake;
|
|
118
|
+
/**
|
|
119
|
+
* Deliver one message to a live local session, waking a persisted one only
|
|
120
|
+
* when the sender asked and this receiver allows it.
|
|
121
|
+
*/
|
|
104
122
|
private deliver;
|
|
105
123
|
/** POST one business call to a peer instance; undefined on transport/auth failure. */
|
|
106
124
|
private post;
|
|
@@ -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,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/interconnect/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -44,17 +44,36 @@ export interface SendPayload {
|
|
|
44
44
|
* a running turn. Absent leaves the receiver's configured default in force.
|
|
45
45
|
*/
|
|
46
46
|
readonly delivery?: DeliveryMode;
|
|
47
|
+
/**
|
|
48
|
+
* Ask the receiver to wake a persisted session that has no running agent.
|
|
49
|
+
*
|
|
50
|
+
* Opt-in, and deliberately not the default: delivery to a woken session runs
|
|
51
|
+
* a real agent turn — a billed model call whose assembly carries that
|
|
52
|
+
* session's full toolset — inside a conversation its owner is not watching
|
|
53
|
+
* and cannot interrupt. That is categorically more than nudging an already
|
|
54
|
+
* open session, so the sender must ask for it explicitly. The receiver can
|
|
55
|
+
* still refuse via `Config.allowResume`, because the cost lands on its
|
|
56
|
+
* machine.
|
|
57
|
+
*/
|
|
58
|
+
readonly resume?: boolean;
|
|
47
59
|
}
|
|
48
60
|
/**
|
|
49
61
|
* Why a `send` did not deliver. `delivered: false` alone cannot be acted on,
|
|
50
|
-
* because the
|
|
62
|
+
* because the causes need different responses:
|
|
51
63
|
* - `session-not-live` — the receiver answered; that session has no running
|
|
52
64
|
* agent. Retrying the same id is futile until it is opened, so the caller
|
|
53
65
|
* should list live sessions and pick another target.
|
|
54
66
|
* - `unreachable` — no usable answer from the receiver (transport failure, or
|
|
55
67
|
* auth rejected). The target may well be fine, so retrying can succeed.
|
|
68
|
+
* - `resume-refused` — the sender asked to wake a persisted session and this
|
|
69
|
+
* receiver does not allow it. Retrying with `resume` set changes nothing.
|
|
70
|
+
* - `resume-failed` — waking was allowed and attempted but did not yield a live
|
|
71
|
+
* agent (no persisted session under that id, or another owner holds it).
|
|
72
|
+
* - `session-owned-by-subagent` — the session is reserved to subagent routing,
|
|
73
|
+
* so its parent agent owns delivery. Injecting here would race that parent;
|
|
74
|
+
* the sender must reach the child through its parent instead.
|
|
56
75
|
*/
|
|
57
|
-
export type SendFailure = 'session-not-live' | 'unreachable';
|
|
76
|
+
export type SendFailure = 'session-not-live' | 'unreachable' | 'resume-refused' | 'resume-failed' | 'session-owned-by-subagent';
|
|
58
77
|
/** Business result of a `send` endpoint call. */
|
|
59
78
|
export interface SendResult {
|
|
60
79
|
/** True when the target session is live on the receiving instance and the message was delivered. */
|
|
@@ -117,6 +136,8 @@ export interface SendRequest {
|
|
|
117
136
|
readonly text: string;
|
|
118
137
|
/** Per-message delivery override forwarded to the receiver. */
|
|
119
138
|
readonly delivery?: DeliveryMode;
|
|
139
|
+
/** Ask the receiver to wake a persisted session; see {@link SendPayload.resume}. */
|
|
140
|
+
readonly resume?: boolean;
|
|
120
141
|
}
|
|
121
142
|
/**
|
|
122
143
|
* One serializable lifecycle fact pushed from an emitting instance to its
|
|
@@ -196,5 +217,12 @@ export interface Config {
|
|
|
196
217
|
* override. See {@link DeliveryMode} for what each mode does.
|
|
197
218
|
*/
|
|
198
219
|
readonly delivery?: DeliveryMode;
|
|
220
|
+
/**
|
|
221
|
+
* Whether this instance honours a sender's `resume` request. Defaults to
|
|
222
|
+
* true: the sender must opt in per message anyway, and this switch exists so
|
|
223
|
+
* the side that pays — waking a session runs a billed model turn with that
|
|
224
|
+
* session's tools on THIS machine — can refuse outright.
|
|
225
|
+
*/
|
|
226
|
+
readonly allowResume?: boolean;
|
|
199
227
|
}
|
|
200
228
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/interconnect/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;GAGG;AACH,eAAO,MAAM,oBAAoB,kBAAkB,CAAA;AAEnD;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,2BAA2B,CAAA;AAE9D;;;;;;;;;;GAUG;AACH,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG,OAAO,GAAG,QAAQ,CAAA;AAE1D;;;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,QAAQ,CAAC,EAAE,YAAY,CAAA;
|
|
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;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAK7C,uDAAuD;AACvD,eAAO,MAAM,MAAM,UAA4B,CAAA;AAE/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;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAK7C,uDAAuD;AACvD,eAAO,MAAM,MAAM,UAA4B,CAAA;AAE/C;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CA0MxC"}
|
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",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.6.1",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "lib/index.js",
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
"peerDependencies": {
|
|
43
43
|
"@deepseek-ai/cordis": "*",
|
|
44
44
|
"@deepseek-ai/dsh-agent": "*",
|
|
45
|
+
"@deepseek-ai/dsh-api-remotes": "*",
|
|
45
46
|
"@deepseek-ai/dsh-credentials": "*",
|
|
46
47
|
"@deepseek-ai/dsh-llm": "*",
|
|
47
48
|
"@deepseek-ai/dsh-session": "*",
|
|
@@ -57,6 +58,7 @@
|
|
|
57
58
|
"@deepseek-ai/cordis": "link:../dsh/vendor/cordis",
|
|
58
59
|
"@deepseek-ai/schemastery": "link:../dsh/vendor/schemastery",
|
|
59
60
|
"@deepseek-ai/dsh-agent": "link:../dsh/packages/core/agent",
|
|
61
|
+
"@deepseek-ai/dsh-api-remotes": "link:../dsh/packages/api/remotes",
|
|
60
62
|
"@deepseek-ai/dsh-credentials": "link:../dsh/packages/credentials/credentials",
|
|
61
63
|
"@deepseek-ai/dsh-llm": "link:../dsh/packages/llm/llm",
|
|
62
64
|
"@deepseek-ai/dsh-session": "link:../dsh/packages/core/session",
|