@zooid/context-mcp 0.12.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.js +44 -4
- package/dist/bin.js.map +1 -1
- package/dist/{chunk-ZY2GPHFX.js → chunk-IZ2JCKE4.js} +173 -14
- package/dist/chunk-IZ2JCKE4.js.map +1 -0
- package/dist/index.js +34 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/bin.ts +63 -9
- package/src/daemon-socket.test.ts +178 -18
- package/src/daemon-socket.ts +139 -12
- package/src/factory.test.ts +10 -0
- package/src/index.ts +3 -2
- package/src/integration.test.ts +99 -15
- package/src/mcp-server.test.ts +225 -21
- package/src/mcp-server.ts +87 -7
- package/src/socket-paths.test.ts +25 -0
- package/src/socket-paths.ts +29 -0
- package/src/spawn-registry.test.ts +14 -1
- package/src/spawn-registry.ts +29 -1
- package/src/types.ts +2 -0
- package/dist/chunk-ZY2GPHFX.js.map +0 -1
package/dist/bin.js
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
JSONRPCMessageSchema,
|
|
4
4
|
buildContextMcpServer,
|
|
5
5
|
callDaemon
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-IZ2JCKE4.js";
|
|
7
7
|
|
|
8
8
|
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
|
|
9
9
|
import process2 from "process";
|
|
@@ -125,10 +125,50 @@ var remoteProvider = {
|
|
|
125
125
|
method: "getThreadHistory",
|
|
126
126
|
params: { ...opts ?? {}, threadId }
|
|
127
127
|
}),
|
|
128
|
-
getChannelMembers: () => callDaemon(sockPath, {
|
|
129
|
-
|
|
128
|
+
getChannelMembers: () => callDaemon(sockPath, {
|
|
129
|
+
spawnId,
|
|
130
|
+
method: "getChannelMembers",
|
|
131
|
+
params: {}
|
|
132
|
+
}),
|
|
133
|
+
getRoomInfo: () => callDaemon(sockPath, {
|
|
134
|
+
spawnId,
|
|
135
|
+
method: "getRoomInfo",
|
|
136
|
+
params: {}
|
|
137
|
+
}),
|
|
138
|
+
getRooms: () => callDaemon(sockPath, {
|
|
139
|
+
spawnId,
|
|
140
|
+
method: "getRooms",
|
|
141
|
+
params: {}
|
|
142
|
+
}),
|
|
143
|
+
sendMessage: (input) => callDaemon(sockPath, {
|
|
144
|
+
spawnId,
|
|
145
|
+
method: "sendMessage",
|
|
146
|
+
params: input
|
|
147
|
+
})
|
|
148
|
+
};
|
|
149
|
+
var remoteTasks = {
|
|
150
|
+
startTasks: (_caller, input) => callDaemon(sockPath, {
|
|
151
|
+
spawnId,
|
|
152
|
+
method: "startTasks",
|
|
153
|
+
params: input
|
|
154
|
+
}),
|
|
155
|
+
completeTask: (_caller, input) => callDaemon(sockPath, {
|
|
156
|
+
spawnId,
|
|
157
|
+
method: "completeTask",
|
|
158
|
+
params: input
|
|
159
|
+
}),
|
|
160
|
+
describeRole: () => callDaemon(sockPath, {
|
|
161
|
+
spawnId,
|
|
162
|
+
method: "describeRole",
|
|
163
|
+
params: {}
|
|
164
|
+
})
|
|
130
165
|
};
|
|
131
|
-
var
|
|
166
|
+
var role = await callDaemon(sockPath, { spawnId, method: "describeRole", params: {} }).then((r) => r).catch(() => void 0);
|
|
167
|
+
var server = buildContextMcpServer({
|
|
168
|
+
resolve: async () => remoteProvider,
|
|
169
|
+
resolveTasks: async () => remoteTasks,
|
|
170
|
+
role
|
|
171
|
+
});
|
|
132
172
|
await server.connect(new StdioServerTransport());
|
|
133
173
|
process.stderr.write(`zooid-context-mcp: ready (spawnId=${spawnId})
|
|
134
174
|
`);
|
package/dist/bin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/src/server/stdio.ts","../../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/src/shared/stdio.ts","../src/bin.ts"],"sourcesContent":[null,null,"#!/usr/bin/env node\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { buildContextMcpServer } from './mcp-server.js'\nimport { callDaemon } from './daemon-socket.js'\nimport type {
|
|
1
|
+
{"version":3,"sources":["../../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/src/server/stdio.ts","../../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/src/shared/stdio.ts","../src/bin.ts"],"sourcesContent":[null,null,"#!/usr/bin/env node\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { buildContextMcpServer } from './mcp-server.js'\nimport { callDaemon } from './daemon-socket.js'\nimport type {\n StartTasksOutput,\n CompleteTaskOutput,\n TaskActions,\n TaskRole,\n TransportContextProvider,\n} from '@zooid/core'\n\nconst spawnIdIdx = process.argv.indexOf('--spawn-id')\nconst spawnId = spawnIdIdx >= 0 ? process.argv[spawnIdIdx + 1] : undefined\nconst sockPath = process.env.ZOOID_DAEMON_SOCK\nif (!spawnId || !sockPath) {\n process.stderr.write('zooid-context-mcp: --spawn-id and ZOOID_DAEMON_SOCK are required\\n')\n process.exit(2)\n}\nprocess.stderr.write(\n `zooid-context-mcp: starting (pid=${process.pid} spawnId=${spawnId} sock=${sockPath})\\n`,\n)\n\nconst remoteProvider: TransportContextProvider = {\n getRoomHistory: (_channelId, opts) =>\n callDaemon(sockPath, {\n spawnId,\n method: 'getRoomHistory',\n params: (opts ?? {}) as Record<string, unknown>,\n }) as Promise<Awaited<ReturnType<TransportContextProvider['getRoomHistory']>>>,\n getRecentThreads: (_channelId, opts) =>\n callDaemon(sockPath, {\n spawnId,\n method: 'getRecentThreads',\n params: (opts ?? {}) as Record<string, unknown>,\n }) as Promise<Awaited<ReturnType<TransportContextProvider['getRecentThreads']>>>,\n getThreadHistory: (_channelId, threadId, opts) =>\n callDaemon(sockPath, {\n spawnId,\n method: 'getThreadHistory',\n params: { ...(opts ?? {}), threadId } as Record<string, unknown>,\n }) as Promise<Awaited<ReturnType<TransportContextProvider['getThreadHistory']>>>,\n getChannelMembers: () =>\n callDaemon(sockPath, {\n spawnId,\n method: 'getChannelMembers',\n params: {},\n }) as Promise<Awaited<ReturnType<TransportContextProvider['getChannelMembers']>>>,\n getRoomInfo: () =>\n callDaemon(sockPath, {\n spawnId,\n method: 'getRoomInfo',\n params: {},\n }) as Promise<Awaited<ReturnType<TransportContextProvider['getRoomInfo']>>>,\n getRooms: () =>\n callDaemon(sockPath, {\n spawnId,\n method: 'getRooms',\n params: {},\n }) as Promise<Awaited<ReturnType<TransportContextProvider['getRooms']>>>,\n sendMessage: (input) =>\n callDaemon(sockPath, {\n spawnId,\n method: 'sendMessage',\n params: input as unknown as Record<string, unknown>,\n }) as Promise<Awaited<ReturnType<TransportContextProvider['sendMessage']>>>,\n}\n\nconst remoteTasks: TaskActions = {\n startTasks: (_caller, input) =>\n callDaemon(sockPath, {\n spawnId,\n method: 'startTasks',\n params: input as unknown as Record<string, unknown>,\n }) as Promise<StartTasksOutput>,\n completeTask: (_caller, input) =>\n callDaemon(sockPath, {\n spawnId,\n method: 'completeTask',\n params: input as unknown as Record<string, unknown>,\n }) as Promise<CompleteTaskOutput>,\n describeRole: () =>\n callDaemon(sockPath, {\n spawnId,\n method: 'describeRole',\n params: {},\n }) as Promise<TaskRole>,\n}\n\n// A failed role query yields undefined, which registers neither task tool —\n// the safe direction for MCP: the tools are additive, and a spawn that\n// cannot reach the daemon cannot usefully call them anyway ([[ZOD084]]).\nconst role = await callDaemon(sockPath, { spawnId, method: 'describeRole', params: {} })\n .then((r) => r as TaskRole)\n .catch(() => undefined)\n\nconst server = buildContextMcpServer({\n resolve: async () => remoteProvider,\n resolveTasks: async () => remoteTasks,\n role,\n})\nawait server.connect(new StdioServerTransport())\nprocess.stderr.write(`zooid-context-mcp: ready (spawnId=${spawnId})\\n`)\n"],"mappings":"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","names":["process","process"]}
|
|
@@ -21007,6 +21007,12 @@ var EMPTY_COMPLETION_RESULT = {
|
|
|
21007
21007
|
// src/mcp-server.ts
|
|
21008
21008
|
var MAX_LIMIT = 200;
|
|
21009
21009
|
var DEFAULT_LIMIT = 50;
|
|
21010
|
+
var CALLER_FROM_BINDING = {
|
|
21011
|
+
agentName: "",
|
|
21012
|
+
channelId: "",
|
|
21013
|
+
threadRoot: "",
|
|
21014
|
+
sessionKey: ""
|
|
21015
|
+
};
|
|
21010
21016
|
function buildContextMcpServer(opts) {
|
|
21011
21017
|
const server = new McpServer({ name: "zooid-context", version: "0.0.1" });
|
|
21012
21018
|
server.tool(
|
|
@@ -21019,10 +21025,45 @@ function buildContextMcpServer(opts) {
|
|
|
21019
21025
|
async ({ limit, before }) => {
|
|
21020
21026
|
const provider = await opts.resolve();
|
|
21021
21027
|
const clamped = Math.min(limit ?? DEFAULT_LIMIT, MAX_LIMIT);
|
|
21022
|
-
const page = await provider.getRoomHistory("", {
|
|
21028
|
+
const page = await provider.getRoomHistory("", {
|
|
21029
|
+
limit: clamped,
|
|
21030
|
+
before
|
|
21031
|
+
});
|
|
21023
21032
|
return { content: [{ type: "text", text: JSON.stringify(page) }] };
|
|
21024
21033
|
}
|
|
21025
21034
|
);
|
|
21035
|
+
if (opts.resolveTasks && opts.role?.can_start_task_threads) {
|
|
21036
|
+
server.tool(
|
|
21037
|
+
"zooid_start_task_threads",
|
|
21038
|
+
"Assign concurrent work to other agents in this room. Each task opens a separate thread. The return payload states how the result comes back \u2014 read `delivery` before deciding what to do next.",
|
|
21039
|
+
{
|
|
21040
|
+
tasks: external_exports.array(external_exports.object({ agent: external_exports.string(), prompt: external_exports.string() })).min(1),
|
|
21041
|
+
notify: external_exports.enum(["caller", "none"]).optional()
|
|
21042
|
+
},
|
|
21043
|
+
async ({ tasks, notify }) => {
|
|
21044
|
+
const out = await opts.resolveTasks().then(
|
|
21045
|
+
(actions) => actions.startTasks(CALLER_FROM_BINDING, {
|
|
21046
|
+
tasks,
|
|
21047
|
+
notify: notify ?? "caller"
|
|
21048
|
+
})
|
|
21049
|
+
);
|
|
21050
|
+
return { content: [{ type: "text", text: JSON.stringify(out) }] };
|
|
21051
|
+
}
|
|
21052
|
+
);
|
|
21053
|
+
}
|
|
21054
|
+
if (opts.resolveTasks && opts.role?.is_task_assignee) {
|
|
21055
|
+
server.tool(
|
|
21056
|
+
"zooid_complete_task",
|
|
21057
|
+
"Record an explicit result for the delegated task you were assigned.",
|
|
21058
|
+
{ summary: external_exports.string().min(1) },
|
|
21059
|
+
async ({ summary }) => {
|
|
21060
|
+
const out = await opts.resolveTasks().then(
|
|
21061
|
+
(actions) => actions.completeTask(CALLER_FROM_BINDING, { summary })
|
|
21062
|
+
);
|
|
21063
|
+
return { content: [{ type: "text", text: JSON.stringify(out) }] };
|
|
21064
|
+
}
|
|
21065
|
+
);
|
|
21066
|
+
}
|
|
21026
21067
|
server.tool(
|
|
21027
21068
|
"zooid_get_recent_threads",
|
|
21028
21069
|
"Scan-the-room overview: top-level messages and thread roots in the current room, newest first. Each entry has `reply_count` and `last_activity_at` so the agent can spot active conversations. Drill into a thread with `zooid_get_thread_history(thread_id)` where `thread_id` is the entry's `id`.",
|
|
@@ -21033,7 +21074,10 @@ function buildContextMcpServer(opts) {
|
|
|
21033
21074
|
async ({ limit, before }) => {
|
|
21034
21075
|
const provider = await opts.resolve();
|
|
21035
21076
|
const clamped = Math.min(limit ?? DEFAULT_LIMIT, MAX_LIMIT);
|
|
21036
|
-
const page = await provider.getRecentThreads("", {
|
|
21077
|
+
const page = await provider.getRecentThreads("", {
|
|
21078
|
+
limit: clamped,
|
|
21079
|
+
before
|
|
21080
|
+
});
|
|
21037
21081
|
return { content: [{ type: "text", text: JSON.stringify(page) }] };
|
|
21038
21082
|
}
|
|
21039
21083
|
);
|
|
@@ -21066,25 +21110,69 @@ function buildContextMcpServer(opts) {
|
|
|
21066
21110
|
}
|
|
21067
21111
|
);
|
|
21068
21112
|
server.tool(
|
|
21069
|
-
"
|
|
21113
|
+
"zooid_get_room_info",
|
|
21070
21114
|
"Describe the current room: id, display name, transport kind.",
|
|
21071
21115
|
{},
|
|
21072
21116
|
async () => {
|
|
21073
21117
|
const provider = await opts.resolve();
|
|
21074
|
-
const info = await provider.
|
|
21118
|
+
const info = await provider.getRoomInfo("");
|
|
21075
21119
|
return { content: [{ type: "text", text: JSON.stringify(info) }] };
|
|
21076
21120
|
}
|
|
21077
21121
|
);
|
|
21122
|
+
server.tool(
|
|
21123
|
+
"zooid_get_rooms",
|
|
21124
|
+
"List the rooms this agent is a member of. Valid targets for zooid_send_message.",
|
|
21125
|
+
{},
|
|
21126
|
+
async () => {
|
|
21127
|
+
const provider = await opts.resolve();
|
|
21128
|
+
const rooms = await provider.getRooms();
|
|
21129
|
+
return { content: [{ type: "text", text: JSON.stringify({ rooms }) }] };
|
|
21130
|
+
}
|
|
21131
|
+
);
|
|
21132
|
+
server.tool(
|
|
21133
|
+
"zooid_send_message",
|
|
21134
|
+
"Post a message into a room or thread this agent is bound to. Fire-and-forget: no assignee, no completion tracking, no notify. Use zooid_start_task_threads instead when the intent is delegation.",
|
|
21135
|
+
{
|
|
21136
|
+
room: external_exports.string(),
|
|
21137
|
+
thread_id: external_exports.string().optional(),
|
|
21138
|
+
text: external_exports.string()
|
|
21139
|
+
},
|
|
21140
|
+
async ({ room, thread_id, text }) => {
|
|
21141
|
+
const provider = await opts.resolve();
|
|
21142
|
+
const result = await provider.sendMessage({ room, thread_id, text });
|
|
21143
|
+
return { content: [{ type: "text", text: JSON.stringify(result) }] };
|
|
21144
|
+
}
|
|
21145
|
+
);
|
|
21078
21146
|
return server;
|
|
21079
21147
|
}
|
|
21080
21148
|
|
|
21149
|
+
// src/socket-paths.ts
|
|
21150
|
+
import { createHash } from "crypto";
|
|
21151
|
+
import { join } from "path";
|
|
21152
|
+
var SUN_PATH_MAX = process.platform === "darwin" ? 103 : 107;
|
|
21153
|
+
var BASENAME_LEN = 25;
|
|
21154
|
+
var MAX_RUN_DIR = SUN_PATH_MAX - 1 - BASENAME_LEN;
|
|
21155
|
+
function agentSocketPath(opts) {
|
|
21156
|
+
if (opts.runDir.length > MAX_RUN_DIR) {
|
|
21157
|
+
throw new Error(
|
|
21158
|
+
`[context-mcp] run dir ${opts.runDir} (${opts.runDir.length} bytes) exceeds the ${MAX_RUN_DIR}-byte limit \u2014 unix socket paths cap at ${SUN_PATH_MAX + 1} bytes. Move the data dir closer to the filesystem root.`
|
|
21159
|
+
);
|
|
21160
|
+
}
|
|
21161
|
+
const hash = createHash("sha256").update(opts.agentName).digest("hex").slice(0, 12);
|
|
21162
|
+
return join(opts.runDir, `context-${hash}.sock`);
|
|
21163
|
+
}
|
|
21164
|
+
|
|
21081
21165
|
// src/daemon-socket.ts
|
|
21082
21166
|
import { createServer, createConnection } from "net";
|
|
21083
21167
|
import { unlink } from "fs/promises";
|
|
21168
|
+
var NOT_OWNED = "binding not owned by caller";
|
|
21084
21169
|
async function startDaemonSocketServer(opts) {
|
|
21085
21170
|
await unlink(opts.sockPath).catch(() => {
|
|
21086
21171
|
});
|
|
21172
|
+
const open = /* @__PURE__ */ new Set();
|
|
21087
21173
|
const server = createServer((socket) => {
|
|
21174
|
+
open.add(socket);
|
|
21175
|
+
socket.on("close", () => open.delete(socket));
|
|
21088
21176
|
let buf = "";
|
|
21089
21177
|
socket.setEncoding("utf8");
|
|
21090
21178
|
socket.on("data", async (chunk) => {
|
|
@@ -21094,7 +21182,7 @@ async function startDaemonSocketServer(opts) {
|
|
|
21094
21182
|
const line = buf.slice(0, idx);
|
|
21095
21183
|
buf = buf.slice(idx + 1);
|
|
21096
21184
|
if (!line) continue;
|
|
21097
|
-
await handleLine(line, socket, opts.registry);
|
|
21185
|
+
await handleLine(line, socket, opts.registry, opts.agentName);
|
|
21098
21186
|
}
|
|
21099
21187
|
});
|
|
21100
21188
|
socket.on("error", () => {
|
|
@@ -21110,33 +21198,49 @@ async function startDaemonSocketServer(opts) {
|
|
|
21110
21198
|
return {
|
|
21111
21199
|
close: () => new Promise((resolve) => {
|
|
21112
21200
|
server.close(() => resolve());
|
|
21201
|
+
for (const socket of open) socket.destroy();
|
|
21202
|
+
open.clear();
|
|
21113
21203
|
})
|
|
21114
21204
|
};
|
|
21115
21205
|
}
|
|
21116
|
-
async function handleLine(line, socket, registry2) {
|
|
21206
|
+
async function handleLine(line, socket, registry2, callerAgent) {
|
|
21117
21207
|
let req;
|
|
21118
21208
|
try {
|
|
21119
21209
|
req = JSON.parse(line);
|
|
21120
21210
|
} catch {
|
|
21121
|
-
socket.write(
|
|
21211
|
+
socket.write(
|
|
21212
|
+
JSON.stringify({
|
|
21213
|
+
ok: false,
|
|
21214
|
+
error: "invalid json"
|
|
21215
|
+
}) + "\n"
|
|
21216
|
+
);
|
|
21122
21217
|
return;
|
|
21123
21218
|
}
|
|
21124
|
-
const binding = registry2.get(req.spawnId);
|
|
21219
|
+
const binding = req.spawnId ? registry2.get(req.spawnId) : req.acpSessionId ? registry2.getByAcpSession(req.acpSessionId) : void 0;
|
|
21125
21220
|
if (!binding) {
|
|
21221
|
+
const address = req.acpSessionId ? `session: ${req.acpSessionId}` : `spawn-id: ${req.spawnId ?? ""}`;
|
|
21126
21222
|
process.stderr.write(
|
|
21127
|
-
`[context-mcp] daemon: unknown
|
|
21223
|
+
`[context-mcp] daemon: unknown ${address} for method=${req.method}
|
|
21128
21224
|
`
|
|
21129
21225
|
);
|
|
21130
21226
|
socket.write(
|
|
21131
21227
|
JSON.stringify({
|
|
21132
21228
|
ok: false,
|
|
21133
|
-
error:
|
|
21229
|
+
error: NOT_OWNED
|
|
21134
21230
|
}) + "\n"
|
|
21135
21231
|
);
|
|
21136
21232
|
return;
|
|
21137
21233
|
}
|
|
21234
|
+
if (binding.agentName !== callerAgent) {
|
|
21235
|
+
process.stderr.write(
|
|
21236
|
+
`[context-mcp] daemon: refused ${req.method} \u2014 binding owned by ${binding.agentName}, caller is ${callerAgent}
|
|
21237
|
+
`
|
|
21238
|
+
);
|
|
21239
|
+
socket.write(JSON.stringify({ ok: false, error: NOT_OWNED }) + "\n");
|
|
21240
|
+
return;
|
|
21241
|
+
}
|
|
21138
21242
|
process.stderr.write(
|
|
21139
|
-
`[context-mcp] daemon: ${req.method} spawn=${
|
|
21243
|
+
`[context-mcp] daemon: ${req.method} spawn=${binding.spawnId.slice(0, 8)} agent=${binding.agentName}
|
|
21140
21244
|
`
|
|
21141
21245
|
);
|
|
21142
21246
|
try {
|
|
@@ -21151,8 +21255,32 @@ async function handleLine(line, socket, registry2) {
|
|
|
21151
21255
|
result = await binding.provider.getThreadHistory(channelId, threadId, req.params);
|
|
21152
21256
|
} else if (req.method === "getChannelMembers") {
|
|
21153
21257
|
result = await binding.provider.getChannelMembers(channelId);
|
|
21154
|
-
} else if (req.method === "
|
|
21155
|
-
result = await binding.provider.
|
|
21258
|
+
} else if (req.method === "getRoomInfo") {
|
|
21259
|
+
result = await binding.provider.getRoomInfo(channelId);
|
|
21260
|
+
} else if (req.method === "getRooms") {
|
|
21261
|
+
result = await binding.provider.getRooms();
|
|
21262
|
+
} else if (req.method === "sendMessage") {
|
|
21263
|
+
result = await binding.provider.sendMessage(
|
|
21264
|
+
req.params
|
|
21265
|
+
);
|
|
21266
|
+
} else if (req.method === "startTasks" || req.method === "completeTask" || req.method === "describeRole") {
|
|
21267
|
+
const actions = registry2.taskActions;
|
|
21268
|
+
if (!actions) {
|
|
21269
|
+
socket.write(
|
|
21270
|
+
JSON.stringify({
|
|
21271
|
+
ok: false,
|
|
21272
|
+
error: "task actions unavailable"
|
|
21273
|
+
}) + "\n"
|
|
21274
|
+
);
|
|
21275
|
+
return;
|
|
21276
|
+
}
|
|
21277
|
+
const caller = {
|
|
21278
|
+
agentName: binding.agentName,
|
|
21279
|
+
channelId,
|
|
21280
|
+
threadRoot: binding.threadRef.threadId,
|
|
21281
|
+
sessionKey: binding.sessionKey ?? binding.threadRef.threadId
|
|
21282
|
+
};
|
|
21283
|
+
result = req.method === "startTasks" ? await actions.startTasks(caller, req.params) : req.method === "completeTask" ? await actions.completeTask(caller, req.params) : await actions.describeRole(caller);
|
|
21156
21284
|
} else {
|
|
21157
21285
|
socket.write(
|
|
21158
21286
|
JSON.stringify({
|
|
@@ -21172,6 +21300,34 @@ async function handleLine(line, socket, registry2) {
|
|
|
21172
21300
|
);
|
|
21173
21301
|
}
|
|
21174
21302
|
}
|
|
21303
|
+
async function startAgentSocketServers(opts) {
|
|
21304
|
+
const listen = opts.listen ?? ((sockPath, agentName) => startDaemonSocketServer({ sockPath, registry: opts.registry, agentName }));
|
|
21305
|
+
const derived = opts.agentNames.map((agentName) => ({
|
|
21306
|
+
agentName,
|
|
21307
|
+
sockPath: agentSocketPath({ runDir: opts.runDir, agentName })
|
|
21308
|
+
}));
|
|
21309
|
+
const paths = {};
|
|
21310
|
+
const handles = [];
|
|
21311
|
+
for (const { agentName, sockPath } of derived) {
|
|
21312
|
+
try {
|
|
21313
|
+
const handle = await listen(sockPath, agentName);
|
|
21314
|
+
paths[agentName] = sockPath;
|
|
21315
|
+
handles.push({ handle, path: sockPath });
|
|
21316
|
+
} catch (err) {
|
|
21317
|
+
console.warn(`[context] socket bind failed for agent=${agentName}; context disabled for it:`, err);
|
|
21318
|
+
}
|
|
21319
|
+
}
|
|
21320
|
+
return {
|
|
21321
|
+
paths,
|
|
21322
|
+
close: async () => {
|
|
21323
|
+
for (const { handle, path } of handles) {
|
|
21324
|
+
await handle.close();
|
|
21325
|
+
await unlink(path).catch(() => {
|
|
21326
|
+
});
|
|
21327
|
+
}
|
|
21328
|
+
}
|
|
21329
|
+
};
|
|
21330
|
+
}
|
|
21175
21331
|
async function callDaemon(sockPath, req) {
|
|
21176
21332
|
return new Promise((resolve, reject) => {
|
|
21177
21333
|
const socket = createConnection(sockPath);
|
|
@@ -21202,7 +21358,10 @@ async function callDaemon(sockPath, req) {
|
|
|
21202
21358
|
export {
|
|
21203
21359
|
JSONRPCMessageSchema,
|
|
21204
21360
|
buildContextMcpServer,
|
|
21361
|
+
SUN_PATH_MAX,
|
|
21362
|
+
agentSocketPath,
|
|
21205
21363
|
startDaemonSocketServer,
|
|
21364
|
+
startAgentSocketServers,
|
|
21206
21365
|
callDaemon
|
|
21207
21366
|
};
|
|
21208
|
-
//# sourceMappingURL=chunk-
|
|
21367
|
+
//# sourceMappingURL=chunk-IZ2JCKE4.js.map
|