negotium 0.19.2 → 0.20.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/agent-helpers.js +1146 -212
- package/dist/agent-helpers.js.map +27 -19
- package/dist/background-bash.js.map +1 -1
- package/dist/browser-runtime.js.map +1 -1
- package/dist/{chunk-kkftbxh2.js → chunk-7he9nzfa.js} +1 -1
- package/dist/{chunk-55dd0xw7.js → chunk-ad6xqvqy.js} +2 -2
- package/dist/{chunk-55dd0xw7.js.map → chunk-ad6xqvqy.js.map} +2 -2
- package/dist/{chunk-exqz8bez.js → chunk-hh3f0yr7.js} +3 -3
- package/dist/{chunk-exqz8bez.js.map → chunk-hh3f0yr7.js.map} +2 -2
- package/dist/{chunk-aqqmzmft.js → chunk-nm59q3em.js} +1 -1
- package/dist/{chunk-cv7vdsrn.js → chunk-w3c6fc0p.js} +286 -9
- package/dist/{chunk-cv7vdsrn.js.map → chunk-w3c6fc0p.js.map} +10 -7
- package/dist/hosted-agent.js +290 -12
- package/dist/hosted-agent.js.map +10 -7
- package/dist/main.js +4599 -2724
- package/dist/main.js.map +49 -38
- package/dist/mcp-factories.js +1166 -162
- package/dist/mcp-factories.js.map +27 -19
- package/dist/media.js.map +1 -1
- package/dist/prompts.js.map +1 -1
- package/dist/query-runtime.js.map +3 -3
- package/dist/registry.js +3 -3
- package/dist/rollout.js +2 -2
- package/dist/runtime/src/agents/explicit-agent-switch.ts +101 -0
- package/dist/runtime/src/agents/mcp-tools/spawn-subagent.ts +126 -43
- package/dist/runtime/src/agents/public-helpers.ts +5 -0
- package/dist/runtime/src/agents/self-config-core.ts +28 -58
- package/dist/runtime/src/application/submit-runtime-gateway-turn.ts +34 -8
- package/dist/runtime/src/index.ts +75 -0
- package/dist/runtime/src/mcp/peer-bridge.ts +6 -1
- package/dist/runtime/src/mcp/runtime-spec.ts +145 -10
- package/dist/runtime/src/mcp/session-comm/actor-policy.ts +87 -0
- package/dist/runtime/src/mcp/session-comm/context.ts +42 -1
- package/dist/runtime/src/mcp/session-comm/default-host.ts +178 -2
- package/dist/runtime/src/mcp/session-comm/hub-remote-session.ts +553 -0
- package/dist/runtime/src/mcp/session-comm/limits.ts +8 -0
- package/dist/runtime/src/mcp/session-comm/peer-forward.ts +78 -3
- package/dist/runtime/src/mcp/session-comm/server.ts +167 -4
- package/dist/runtime/src/mcp/session-comm/topic-catalog.ts +7 -0
- package/dist/runtime/src/mcp/session-comm/topics.ts +32 -10
- package/dist/runtime/src/mcp-runtime-host.ts +2 -1
- package/dist/runtime/src/node-host.ts +26 -0
- package/dist/runtime/src/platform/mcp-config.ts +56 -2
- package/dist/runtime/src/query/active-rooms.ts +6 -0
- package/dist/runtime/src/runtime/actor-topic-reach.ts +85 -0
- package/dist/runtime/src/runtime/actor-topic-scope.ts +175 -0
- package/dist/runtime/src/runtime/ask-callbacks.ts +73 -20
- package/dist/runtime/src/runtime/gateway-capabilities.ts +22 -0
- package/dist/runtime/src/runtime/remote-session-grant.ts +221 -0
- package/dist/runtime/src/runtime/remote-session-inbox.ts +476 -0
- package/dist/runtime/src/runtime/remote-session-reply-outbox.ts +156 -0
- package/dist/runtime/src/runtime/turn-runner.ts +157 -33
- package/dist/runtime/src/runtime-gateway.ts +20 -0
- package/dist/runtime/src/storage/api-topics.ts +22 -3
- package/dist/runtime/src/storage/remote-session.ts +526 -0
- package/dist/runtime/src/storage/runtime-turn-requests.ts +75 -2
- package/dist/runtime/src/topics/derive.ts +3 -0
- package/dist/runtime/src/types/api.ts +6 -0
- package/dist/runtime/src/types.ts +42 -0
- package/dist/runtime/src/version.ts +1 -1
- package/dist/runtime-gateway.js.map +2 -2
- package/dist/runtime-helpers.js.map +1 -1
- package/dist/storage.js +16 -4
- package/dist/storage.js.map +4 -4
- package/dist/types/packages/core/src/agents/explicit-agent-switch.d.ts +26 -0
- package/dist/types/packages/core/src/agents/mcp-tools/spawn-subagent.d.ts +12 -2
- package/dist/types/packages/core/src/agents/public-helpers.d.ts +1 -0
- package/dist/types/packages/core/src/agents/self-config-core.d.ts +15 -1
- package/dist/types/packages/core/src/mcp/peer-bridge.d.ts +6 -1
- package/dist/types/packages/core/src/mcp/runtime-spec.d.ts +69 -2
- package/dist/types/packages/core/src/mcp/session-comm/context.d.ts +17 -1
- package/dist/types/packages/core/src/mcp/session-comm/hub-remote-session.d.ts +149 -0
- package/dist/types/packages/core/src/mcp/session-comm/limits.d.ts +8 -0
- package/dist/types/packages/core/src/mcp/session-comm/peer-forward.d.ts +23 -2
- package/dist/types/packages/core/src/mcp/session-comm/topic-catalog.d.ts +6 -0
- package/dist/types/packages/core/src/platform/mcp-config.d.ts +10 -1
- package/dist/types/packages/core/src/query/active-rooms.d.ts +6 -0
- package/dist/types/packages/core/src/runtime/actor-topic-reach.d.ts +49 -0
- package/dist/types/packages/core/src/runtime/actor-topic-scope.d.ts +91 -0
- package/dist/types/packages/core/src/runtime/ask-callbacks.d.ts +8 -2
- package/dist/types/packages/core/src/runtime/remote-session-grant.d.ts +91 -0
- package/dist/types/packages/core/src/runtime/remote-session-inbox.d.ts +83 -0
- package/dist/types/packages/core/src/runtime/remote-session-reply-outbox.d.ts +37 -0
- package/dist/types/packages/core/src/runtime/turn-runner.d.ts +22 -3
- package/dist/types/packages/core/src/runtime-gateway.d.ts +20 -0
- package/dist/types/packages/core/src/storage/api-topics.d.ts +3 -0
- package/dist/types/packages/core/src/storage/remote-session.d.ts +135 -0
- package/dist/types/packages/core/src/storage/runtime-turn-requests.d.ts +12 -1
- package/dist/types/packages/core/src/topics/derive.d.ts +2 -0
- package/dist/types/packages/core/src/types/api.d.ts +6 -0
- package/dist/types/packages/core/src/types.d.ts +40 -0
- package/dist/types/packages/core/src/version.d.ts +1 -1
- package/dist/vault.js.map +1 -1
- package/package.json +1 -1
- /package/dist/{chunk-kkftbxh2.js.map → chunk-7he9nzfa.js.map} +0 -0
- /package/dist/{chunk-aqqmzmft.js.map → chunk-nm59q3em.js.map} +0 -0
package/dist/hosted-agent.js
CHANGED
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
RUN_DIR,
|
|
27
27
|
SESSION_COMM_SERVER,
|
|
28
28
|
SESSION_WORKSPACE_DIR,
|
|
29
|
+
SUPPORTED_AGENTS,
|
|
29
30
|
SYSTEM_HEALTH_SERVER,
|
|
30
31
|
TASK_SERVER,
|
|
31
32
|
TOKEN_STATS_SERVER,
|
|
@@ -41,7 +42,7 @@ import {
|
|
|
41
42
|
logger,
|
|
42
43
|
resolveFallbackAgent,
|
|
43
44
|
resolveTopicWorkspaceDir
|
|
44
|
-
} from "./chunk-
|
|
45
|
+
} from "./chunk-ad6xqvqy.js";
|
|
45
46
|
import {
|
|
46
47
|
__require
|
|
47
48
|
} from "./chunk-2mx7fq49.js";
|
|
@@ -260,12 +261,248 @@ function referencesRuntimeSecretStorage(value) {
|
|
|
260
261
|
return false;
|
|
261
262
|
}
|
|
262
263
|
|
|
264
|
+
// ../../packages/core/src/agents/explicit-agent-switch.ts
|
|
265
|
+
function escapeRegExp(value) {
|
|
266
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
267
|
+
}
|
|
268
|
+
function agentAliases(agent) {
|
|
269
|
+
switch (agent) {
|
|
270
|
+
case "codex":
|
|
271
|
+
return [
|
|
272
|
+
"codex",
|
|
273
|
+
"\uCF54\uB371\uC2A4",
|
|
274
|
+
"gpt-6-luna",
|
|
275
|
+
"gpt-6-sol",
|
|
276
|
+
"gpt-5.6-luna",
|
|
277
|
+
"gpt-5.6-terra",
|
|
278
|
+
"gpt-5.6-sol",
|
|
279
|
+
"gpt-6-astra"
|
|
280
|
+
];
|
|
281
|
+
case "claude":
|
|
282
|
+
return ["claude", "\uD074\uB85C\uB4DC", "sonnet", "opus", "fable"];
|
|
283
|
+
case "maestro":
|
|
284
|
+
return [
|
|
285
|
+
"maestro",
|
|
286
|
+
"\uB9C8\uC5D0\uC2A4\uD2B8\uB85C",
|
|
287
|
+
"\uBA54\uC2A4\uD2B8\uB85C",
|
|
288
|
+
"deepseek",
|
|
289
|
+
"deepseek-pro",
|
|
290
|
+
"kimi",
|
|
291
|
+
"kimi-pro",
|
|
292
|
+
"kimi-k3",
|
|
293
|
+
"kimi-code",
|
|
294
|
+
"kimi-k2.7-code",
|
|
295
|
+
"\uB525\uC2DC\uD06C",
|
|
296
|
+
"\uD0A4\uBBF8"
|
|
297
|
+
];
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
function hasExplicitAgentSwitchRequest(prompt, agent) {
|
|
301
|
+
if (!prompt?.trim())
|
|
302
|
+
return false;
|
|
303
|
+
const text = prompt.toLowerCase().replace(/\s+/g, " ").trim();
|
|
304
|
+
const target = `(?:${agentAliases(agent).map(escapeRegExp).join("|")})`;
|
|
305
|
+
const switchVerb = "(?:\uBC14\uAFD4|\uBC14\uAFD4\uC918|\uBCC0\uACBD|\uBCC0\uACBD\uD574|\uC804\uD658|\uC804\uD658\uD574|\uC124\uC815|\uC124\uC815\uD574|\uC368\uC918|\uC0AC\uC6A9|\uAC00|switch|change|set|use)";
|
|
306
|
+
const switchSubject = "(?:agent|runtime|model|\uC5D0\uC774\uC804\uD2B8|\uB7F0\uD0C0\uC784|\uBAA8\uB378)";
|
|
307
|
+
return [
|
|
308
|
+
new RegExp(`^/(?:agent|runtime)\\s+${target}(?:\\s|$)`, "iu"),
|
|
309
|
+
new RegExp(`${target}\\s*(?:\uB85C|\uC73C\uB85C)\\s*.{0,16}${switchVerb}`, "iu"),
|
|
310
|
+
new RegExp(`${switchSubject}.{0,24}${target}.{0,24}${switchVerb}`, "iu"),
|
|
311
|
+
new RegExp(`${switchVerb}.{0,24}${switchSubject}.{0,24}${target}`, "iu"),
|
|
312
|
+
new RegExp(`(?:switch|change|set|use).{0,24}${target}`, "iu")
|
|
313
|
+
].some((pattern) => pattern.test(text));
|
|
314
|
+
}
|
|
315
|
+
function explicitAgentSwitchTargets(prompt) {
|
|
316
|
+
if (!prompt?.trim())
|
|
317
|
+
return [];
|
|
318
|
+
return SUPPORTED_AGENTS.filter((agent) => hasExplicitAgentSwitchRequest(prompt, agent));
|
|
319
|
+
}
|
|
320
|
+
|
|
263
321
|
// ../../packages/core/src/mcp/runtime-spec.ts
|
|
264
322
|
import { createHash, createHmac, timingSafeEqual } from "crypto";
|
|
323
|
+
|
|
324
|
+
// ../../packages/core/src/runtime/actor-topic-scope.ts
|
|
325
|
+
var ACTOR_TOPIC_SCOPE_LIMITS = Object.freeze({
|
|
326
|
+
maxIdsPerList: 200,
|
|
327
|
+
maxIdLength: 128,
|
|
328
|
+
maxSerializedBytes: 8 * 1024
|
|
329
|
+
});
|
|
330
|
+
var SCOPE_KEYS = ["visibleNodeTopicIds", "ownedNodeTopicIds"];
|
|
331
|
+
function idList(value, name) {
|
|
332
|
+
if (!Array.isArray(value))
|
|
333
|
+
return `${name} must be an array of topic ids`;
|
|
334
|
+
if (value.length > ACTOR_TOPIC_SCOPE_LIMITS.maxIdsPerList) {
|
|
335
|
+
return `${name} has ${value.length} ids; at most ${ACTOR_TOPIC_SCOPE_LIMITS.maxIdsPerList} are allowed`;
|
|
336
|
+
}
|
|
337
|
+
const ids = new Set;
|
|
338
|
+
for (const item of value) {
|
|
339
|
+
if (typeof item !== "string")
|
|
340
|
+
return `${name} must contain only strings`;
|
|
341
|
+
const id = item.trim();
|
|
342
|
+
if (!id)
|
|
343
|
+
return `${name} must not contain empty ids`;
|
|
344
|
+
if (id.length > ACTOR_TOPIC_SCOPE_LIMITS.maxIdLength) {
|
|
345
|
+
return `${name} contains an id longer than ${ACTOR_TOPIC_SCOPE_LIMITS.maxIdLength} characters`;
|
|
346
|
+
}
|
|
347
|
+
ids.add(id);
|
|
348
|
+
}
|
|
349
|
+
return [...ids];
|
|
350
|
+
}
|
|
351
|
+
function validateActorTopicScope(value) {
|
|
352
|
+
if (value === undefined)
|
|
353
|
+
return { ok: true, scope: undefined };
|
|
354
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
355
|
+
return {
|
|
356
|
+
ok: false,
|
|
357
|
+
error: "actorTopicScope must be { visibleNodeTopicIds: string[], ownedNodeTopicIds: string[] }"
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
const proto = Object.getPrototypeOf(value);
|
|
361
|
+
if (proto !== Object.prototype && proto !== null) {
|
|
362
|
+
return { ok: false, error: "actorTopicScope must be a plain object" };
|
|
363
|
+
}
|
|
364
|
+
const keys = Object.keys(value);
|
|
365
|
+
const unknown = keys.filter((key) => !SCOPE_KEYS.includes(key));
|
|
366
|
+
if (unknown.length || keys.length !== SCOPE_KEYS.length) {
|
|
367
|
+
return {
|
|
368
|
+
ok: false,
|
|
369
|
+
error: unknown.length ? `actorTopicScope has unexpected key(s): ${unknown.join(", ")}` : "actorTopicScope must have both visibleNodeTopicIds and ownedNodeTopicIds"
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
const record = value;
|
|
373
|
+
const visible = idList(record.visibleNodeTopicIds, "actorTopicScope.visibleNodeTopicIds");
|
|
374
|
+
if (typeof visible === "string")
|
|
375
|
+
return { ok: false, error: visible };
|
|
376
|
+
const owned = idList(record.ownedNodeTopicIds, "actorTopicScope.ownedNodeTopicIds");
|
|
377
|
+
if (typeof owned === "string")
|
|
378
|
+
return { ok: false, error: owned };
|
|
379
|
+
const scope = { visibleNodeTopicIds: visible, ownedNodeTopicIds: owned };
|
|
380
|
+
const bytes = Buffer.byteLength(JSON.stringify(scope), "utf-8");
|
|
381
|
+
if (bytes > ACTOR_TOPIC_SCOPE_LIMITS.maxSerializedBytes) {
|
|
382
|
+
return {
|
|
383
|
+
ok: false,
|
|
384
|
+
error: `actorTopicScope is ${bytes} bytes serialized; at most ${ACTOR_TOPIC_SCOPE_LIMITS.maxSerializedBytes} are allowed`
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
return { ok: true, scope };
|
|
388
|
+
}
|
|
389
|
+
function encodeActorTopicScopeArg(scope) {
|
|
390
|
+
const validated = validateActorTopicScope(scope);
|
|
391
|
+
if (!validated.ok)
|
|
392
|
+
throw new Error(validated.error);
|
|
393
|
+
if (!validated.scope)
|
|
394
|
+
throw new Error("actorTopicScope is required");
|
|
395
|
+
return Buffer.from(JSON.stringify(validated.scope), "utf-8").toString("base64url");
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
// ../../packages/core/src/runtime/remote-session-grant.ts
|
|
399
|
+
var REMOTE_SESSION_GRANT_LIMITS = Object.freeze({
|
|
400
|
+
maxHubUrlLength: 512,
|
|
401
|
+
maxCapabilityLength: 2 * 1024,
|
|
402
|
+
capabilityPrefix: "rsc1."
|
|
403
|
+
});
|
|
404
|
+
var GRANT_KEYS = ["hubUrl", "capability"];
|
|
405
|
+
var LOOPBACK_HOSTS = new Set(["127.0.0.1", "::1", "[::1]", "localhost"]);
|
|
406
|
+
function normalizeHubUrl(raw, name = "remoteSession.hubUrl") {
|
|
407
|
+
if (raw.length > REMOTE_SESSION_GRANT_LIMITS.maxHubUrlLength) {
|
|
408
|
+
return {
|
|
409
|
+
error: `${name} is longer than ${REMOTE_SESSION_GRANT_LIMITS.maxHubUrlLength} characters`
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
let url;
|
|
413
|
+
try {
|
|
414
|
+
url = new URL(raw);
|
|
415
|
+
} catch {
|
|
416
|
+
return { error: `${name} must be an absolute URL` };
|
|
417
|
+
}
|
|
418
|
+
if (url.username || url.password) {
|
|
419
|
+
return { error: `${name} must not carry credentials` };
|
|
420
|
+
}
|
|
421
|
+
if (url.search || url.hash || raw.includes("?") || raw.includes("#")) {
|
|
422
|
+
return { error: `${name} must not carry a query or fragment` };
|
|
423
|
+
}
|
|
424
|
+
if (url.protocol === "http:") {
|
|
425
|
+
if (!LOOPBACK_HOSTS.has(url.hostname)) {
|
|
426
|
+
return { error: `${name} must be https:// or a loopback http:// origin` };
|
|
427
|
+
}
|
|
428
|
+
} else if (url.protocol !== "https:") {
|
|
429
|
+
return { error: `${name} must be https:// or a loopback http:// origin` };
|
|
430
|
+
}
|
|
431
|
+
return { url: url.toString().replace(/\/+$/, "") };
|
|
432
|
+
}
|
|
433
|
+
var MAX_REMOTE_SESSION_REPLY_TOKEN_LENGTH = REMOTE_SESSION_GRANT_LIMITS.maxCapabilityLength;
|
|
434
|
+
function validateRemoteSessionGrant(value) {
|
|
435
|
+
if (value === undefined)
|
|
436
|
+
return { ok: true, grant: undefined };
|
|
437
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
438
|
+
return { ok: false, error: "remoteSession must be { hubUrl: string, capability: string }" };
|
|
439
|
+
}
|
|
440
|
+
const proto = Object.getPrototypeOf(value);
|
|
441
|
+
if (proto !== Object.prototype && proto !== null) {
|
|
442
|
+
return { ok: false, error: "remoteSession must be a plain object" };
|
|
443
|
+
}
|
|
444
|
+
const keys = Object.keys(value);
|
|
445
|
+
const unknown = keys.filter((key) => !GRANT_KEYS.includes(key));
|
|
446
|
+
if (unknown.length || keys.length !== GRANT_KEYS.length) {
|
|
447
|
+
return {
|
|
448
|
+
ok: false,
|
|
449
|
+
error: unknown.length ? `remoteSession has unexpected key(s): ${unknown.join(", ")}` : "remoteSession must have both hubUrl and capability"
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
const record = value;
|
|
453
|
+
if (typeof record.hubUrl !== "string" || !record.hubUrl.trim()) {
|
|
454
|
+
return { ok: false, error: "remoteSession.hubUrl must be a non-empty string" };
|
|
455
|
+
}
|
|
456
|
+
const hubUrl = normalizeHubUrl(record.hubUrl.trim());
|
|
457
|
+
if ("error" in hubUrl)
|
|
458
|
+
return { ok: false, error: hubUrl.error };
|
|
459
|
+
if (typeof record.capability !== "string" || !record.capability.trim()) {
|
|
460
|
+
return { ok: false, error: "remoteSession.capability must be a non-empty string" };
|
|
461
|
+
}
|
|
462
|
+
const capability = record.capability.trim();
|
|
463
|
+
if (capability.length > REMOTE_SESSION_GRANT_LIMITS.maxCapabilityLength) {
|
|
464
|
+
return {
|
|
465
|
+
ok: false,
|
|
466
|
+
error: `remoteSession.capability is ${capability.length} characters; at most ${REMOTE_SESSION_GRANT_LIMITS.maxCapabilityLength} are allowed`
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
if (!capability.startsWith(REMOTE_SESSION_GRANT_LIMITS.capabilityPrefix)) {
|
|
470
|
+
return {
|
|
471
|
+
ok: false,
|
|
472
|
+
error: `remoteSession.capability must start with "${REMOTE_SESSION_GRANT_LIMITS.capabilityPrefix}"`
|
|
473
|
+
};
|
|
474
|
+
}
|
|
475
|
+
if (!/^rsc1\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(capability)) {
|
|
476
|
+
return { ok: false, error: "remoteSession.capability is malformed" };
|
|
477
|
+
}
|
|
478
|
+
return { ok: true, grant: { hubUrl: hubUrl.url, capability } };
|
|
479
|
+
}
|
|
480
|
+
function encodeRemoteSessionGrantArg(grant) {
|
|
481
|
+
const validated = validateRemoteSessionGrant(grant);
|
|
482
|
+
if (!validated.ok)
|
|
483
|
+
throw new Error(validated.error);
|
|
484
|
+
if (!validated.grant)
|
|
485
|
+
throw new Error("remoteSession is required");
|
|
486
|
+
return Buffer.from(JSON.stringify(validated.grant), "utf-8").toString("base64url");
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
// ../../packages/core/src/mcp/runtime-spec.ts
|
|
265
490
|
var RUNTIME_MCP_KEY = "runtime";
|
|
266
491
|
var RUNTIME_MCP_BASE_PATH = "/mcp/runtime";
|
|
267
492
|
var TOKEN_TTL_MS = 4 * 60 * 60 * 1000;
|
|
268
493
|
var CLAUDE_MCP_TOOL_TIMEOUT_MS = 600000;
|
|
494
|
+
var MCP_URL_BUDGET_CHARS = 14 * 1024;
|
|
495
|
+
|
|
496
|
+
class McpUrlBudgetExceededError extends Error {
|
|
497
|
+
surface;
|
|
498
|
+
urlLength;
|
|
499
|
+
constructor(surface, urlLength) {
|
|
500
|
+
super(`built-in MCP URL for "${surface}" is ${urlLength} characters; the transport allows at most ${MCP_URL_BUDGET_CHARS}`);
|
|
501
|
+
this.surface = surface;
|
|
502
|
+
this.urlLength = urlLength;
|
|
503
|
+
this.name = "McpUrlBudgetExceededError";
|
|
504
|
+
}
|
|
505
|
+
}
|
|
269
506
|
var runtimePort = NEGOTIUM_PORT;
|
|
270
507
|
function encodeTokenPart(value) {
|
|
271
508
|
return Buffer.from(JSON.stringify(value), "utf-8").toString("base64url");
|
|
@@ -291,18 +528,26 @@ function issueHostedMcpToken(surface, ctx) {
|
|
|
291
528
|
return `${payloadPart}.${signTokenPayload(payloadPart)}`;
|
|
292
529
|
}
|
|
293
530
|
function buildRuntimeMcpSpec(agent, ctx) {
|
|
294
|
-
const token = issueRuntimeMcpToken(ctx);
|
|
295
531
|
const base = `http://127.0.0.1:${runtimePort}${RUNTIME_MCP_BASE_PATH}`;
|
|
296
|
-
const query = `token=${encodeURIComponent(
|
|
532
|
+
const query = `token=${encodeURIComponent(issueRuntimeMcpToken(ctx))}`;
|
|
533
|
+
const url = agent === "codex" ? `${base}/mcp?${query}` : `${base}/sse?${query}`;
|
|
534
|
+
assertMcpUrlWithinBudget(RUNTIME_MCP_KEY, url, ctx.topicId);
|
|
297
535
|
if (agent === "codex")
|
|
298
|
-
return { url
|
|
536
|
+
return { url };
|
|
299
537
|
return {
|
|
300
538
|
type: "sse",
|
|
301
|
-
url
|
|
539
|
+
url,
|
|
302
540
|
timeout: CLAUDE_MCP_TOOL_TIMEOUT_MS,
|
|
303
541
|
...agent === "maestro" ? { lifecycle: "turn" } : {}
|
|
304
542
|
};
|
|
305
543
|
}
|
|
544
|
+
function assertMcpUrlWithinBudget(surface, url, topicId) {
|
|
545
|
+
if (url.length <= MCP_URL_BUDGET_CHARS)
|
|
546
|
+
return;
|
|
547
|
+
const error = new McpUrlBudgetExceededError(surface, url.length);
|
|
548
|
+
logger.error({ topicId, surface, urlLength: url.length, budget: MCP_URL_BUDGET_CHARS }, "built-in MCP URL exceeds the transport budget; refusing to mint the token");
|
|
549
|
+
throw error;
|
|
550
|
+
}
|
|
306
551
|
function hostedMcpCacheIdentity(surface, ctx) {
|
|
307
552
|
let semanticContext;
|
|
308
553
|
switch (surface) {
|
|
@@ -333,6 +578,9 @@ function hostedMcpCacheIdentity(surface, ctx) {
|
|
|
333
578
|
case "session-comm":
|
|
334
579
|
semanticContext = {
|
|
335
580
|
userId: ctx.userId,
|
|
581
|
+
actorUserId: ctx.actorUserId ?? null,
|
|
582
|
+
actorTopicScope: ctx.actorTopicScope ?? null,
|
|
583
|
+
remoteSession: ctx.remoteSession ?? null,
|
|
336
584
|
topicTitle: ctx.topicTitle,
|
|
337
585
|
topicId: ctx.topicId ?? null,
|
|
338
586
|
subagentParentTopicId: ctx.subagentParentTopicId ?? null,
|
|
@@ -351,13 +599,15 @@ function buildHostedMcpSpec(agent, surface, ctx) {
|
|
|
351
599
|
const token = issueHostedMcpToken(surface, ctx);
|
|
352
600
|
const base = `http://127.0.0.1:${runtimePort}${RUNTIME_MCP_BASE_PATH}/${surface}`;
|
|
353
601
|
const query = `token=${encodeURIComponent(token)}`;
|
|
602
|
+
const url = agent === "codex" ? `${base}/mcp?${query}` : `${base}/sse?${query}`;
|
|
603
|
+
assertMcpUrlWithinBudget(surface, url, ctx.topicId);
|
|
354
604
|
if (agent === "codex")
|
|
355
|
-
return { url
|
|
356
|
-
const queryBound = surface === "session-comm" && (ctx.silent === true || ctx.peerBridge !== undefined);
|
|
605
|
+
return { url };
|
|
606
|
+
const queryBound = surface === "session-comm" && (ctx.silent === true || ctx.peerBridge !== undefined || ctx.remoteSession !== undefined);
|
|
357
607
|
const lifecycle = queryBound ? "turn" : surface === "session-comm" ? "session" : "process";
|
|
358
608
|
return {
|
|
359
609
|
type: "sse",
|
|
360
|
-
url
|
|
610
|
+
url,
|
|
361
611
|
timeout: CLAUDE_MCP_TOOL_TIMEOUT_MS,
|
|
362
612
|
...agent === "maestro" ? {
|
|
363
613
|
lifecycle,
|
|
@@ -1126,6 +1376,9 @@ function initializeApiTopicsSchema() {
|
|
|
1126
1376
|
if (!tableColumns("api_topics").has("subagent_report_mode")) {
|
|
1127
1377
|
db.exec("ALTER TABLE api_topics ADD COLUMN subagent_report_mode TEXT NOT NULL DEFAULT 'auto'");
|
|
1128
1378
|
}
|
|
1379
|
+
if (!tableColumns("api_topics").has("derived_by_user_id")) {
|
|
1380
|
+
db.exec("ALTER TABLE api_topics ADD COLUMN derived_by_user_id TEXT");
|
|
1381
|
+
}
|
|
1129
1382
|
if (!tableColumns("api_topics").has("memory_topic_id")) {
|
|
1130
1383
|
db.exec("ALTER TABLE api_topics ADD COLUMN memory_topic_id TEXT");
|
|
1131
1384
|
}
|
|
@@ -1217,6 +1470,7 @@ function rowToDto(r, participants = getTopicParticipants(r.id), tellTargets) {
|
|
|
1217
1470
|
memoryTopicId: r.memory_topic_id ?? undefined,
|
|
1218
1471
|
memoryKey: r.memory_key ?? undefined,
|
|
1219
1472
|
isFork: r.is_fork !== 0,
|
|
1473
|
+
...r.derived_by_user_id ? { derivedByUserId: r.derived_by_user_id } : {},
|
|
1220
1474
|
...r.is_subagent !== 0 ? { isSubagent: true } : {},
|
|
1221
1475
|
...r.is_subagent !== 0 ? {
|
|
1222
1476
|
subagentTellTargetIds: tellTargets ? tellTargets.get(r.id) ?? [] : listSubagentTellTargetIds(r.id)
|
|
@@ -1300,6 +1554,9 @@ function buildBuiltinMcpServer(surface, ctx, stdio) {
|
|
|
1300
1554
|
const agent = ctx.agent ?? FALLBACK_AGENT;
|
|
1301
1555
|
return buildHostedMcpSpec(agent, surface, {
|
|
1302
1556
|
userId: ctx.userId,
|
|
1557
|
+
...ctx.actorUserId ? { actorUserId: ctx.actorUserId } : {},
|
|
1558
|
+
...ctx.actorTopicScope ? { actorTopicScope: ctx.actorTopicScope } : {},
|
|
1559
|
+
...surface === "session-comm" && ctx.remoteSession ? { remoteSession: ctx.remoteSession } : {},
|
|
1303
1560
|
topicTitle: ctx.session,
|
|
1304
1561
|
...ctx.topicId ? { topicId: ctx.topicId } : {},
|
|
1305
1562
|
...ctx.queryId ? { queryId: ctx.queryId } : {},
|
|
@@ -1395,6 +1652,7 @@ var MCP_CATALOG = {
|
|
|
1395
1652
|
build({
|
|
1396
1653
|
userId,
|
|
1397
1654
|
actorUserId,
|
|
1655
|
+
actorTopicScope,
|
|
1398
1656
|
session,
|
|
1399
1657
|
topicId,
|
|
1400
1658
|
queryId,
|
|
@@ -1410,16 +1668,18 @@ var MCP_CATALOG = {
|
|
|
1410
1668
|
}) {
|
|
1411
1669
|
if (!topicId || !agent)
|
|
1412
1670
|
return null;
|
|
1671
|
+
const switchTargets = explicitAgentSwitchTargets(currentUserPrompt);
|
|
1413
1672
|
return buildRuntimeMcpSpec(agent, {
|
|
1414
1673
|
userId,
|
|
1415
1674
|
...actorUserId ? { actorUserId } : {},
|
|
1675
|
+
...actorTopicScope ? { actorTopicScope } : {},
|
|
1416
1676
|
topicId,
|
|
1417
1677
|
topicTitle: session,
|
|
1418
1678
|
queryId,
|
|
1419
1679
|
cwd: cwd ?? resolveTopicWorkspaceDir(topicId),
|
|
1420
1680
|
agent,
|
|
1421
1681
|
model,
|
|
1422
|
-
|
|
1682
|
+
...switchTargets.length ? { explicitAgentSwitchTargets: switchTargets } : {},
|
|
1423
1683
|
autoContinue,
|
|
1424
1684
|
visualTools,
|
|
1425
1685
|
fileDeliveryTools,
|
|
@@ -1489,6 +1749,9 @@ var MCP_CATALOG = {
|
|
|
1489
1749
|
build(ctx) {
|
|
1490
1750
|
const {
|
|
1491
1751
|
userId,
|
|
1752
|
+
actorUserId,
|
|
1753
|
+
actorTopicScope,
|
|
1754
|
+
remoteSession,
|
|
1492
1755
|
session,
|
|
1493
1756
|
topicId,
|
|
1494
1757
|
subagentParentTopicId,
|
|
@@ -1502,6 +1765,9 @@ var MCP_CATALOG = {
|
|
|
1502
1765
|
const cronSessionId = topicId ? getRegisteredCronSession(topicId, effectiveAgent)?.sessionId : undefined;
|
|
1503
1766
|
const args = [
|
|
1504
1767
|
`--user-id=${userId}`,
|
|
1768
|
+
...actorUserId ? [`--actor-user-id=${actorUserId}`] : [],
|
|
1769
|
+
...actorTopicScope ? [`--actor-topic-scope=${encodeActorTopicScopeArg(actorTopicScope)}`] : [],
|
|
1770
|
+
...remoteSession ? [`--remote-session-grant=${encodeRemoteSessionGrantArg(remoteSession)}`] : [],
|
|
1505
1771
|
`--topic=${session}`,
|
|
1506
1772
|
...topicId ? [`--topic-id=${topicId}`] : [],
|
|
1507
1773
|
...subagentParentTopicId ? [`--subagent-parent-topic-id=${subagentParentTopicId}`] : [],
|
|
@@ -1679,6 +1945,9 @@ function getManagerMcpServers(opts) {
|
|
|
1679
1945
|
const topicId = opts.topicId;
|
|
1680
1946
|
return buildScope("manager", {
|
|
1681
1947
|
userId: opts.userId,
|
|
1948
|
+
actorUserId: opts.actorUserId,
|
|
1949
|
+
actorTopicScope: opts.actorTopicScope,
|
|
1950
|
+
remoteSession: opts.remoteSession,
|
|
1682
1951
|
session: opts.session ?? "General",
|
|
1683
1952
|
topicId,
|
|
1684
1953
|
queryId: opts.queryId,
|
|
@@ -1698,6 +1967,8 @@ function getForumMcpServers(opts) {
|
|
|
1698
1967
|
const {
|
|
1699
1968
|
userId,
|
|
1700
1969
|
actorUserId,
|
|
1970
|
+
actorTopicScope,
|
|
1971
|
+
remoteSession,
|
|
1701
1972
|
vaultUserId,
|
|
1702
1973
|
session,
|
|
1703
1974
|
topicId,
|
|
@@ -1731,6 +2002,8 @@ function getForumMcpServers(opts) {
|
|
|
1731
2002
|
const base = buildScope("forum", {
|
|
1732
2003
|
userId,
|
|
1733
2004
|
actorUserId,
|
|
2005
|
+
actorTopicScope,
|
|
2006
|
+
remoteSession,
|
|
1734
2007
|
vaultUserId,
|
|
1735
2008
|
session,
|
|
1736
2009
|
topicId,
|
|
@@ -1811,6 +2084,9 @@ function getMcpServersForQuery(opts) {
|
|
|
1811
2084
|
if (opts.sessionType === "manager") {
|
|
1812
2085
|
return hideProviderIntrospectionForOtium(mergeHostMcpServers(getManagerMcpServers({
|
|
1813
2086
|
userId: opts.userId || "local",
|
|
2087
|
+
actorUserId: opts.actorUserId,
|
|
2088
|
+
actorTopicScope: opts.actorTopicScope,
|
|
2089
|
+
remoteSession: opts.remoteSession,
|
|
1814
2090
|
session: opts.session,
|
|
1815
2091
|
topicId: opts.topicId,
|
|
1816
2092
|
queryId: opts.queryId,
|
|
@@ -1829,6 +2105,8 @@ function getMcpServersForQuery(opts) {
|
|
|
1829
2105
|
return hideProviderIntrospectionForOtium(getForumMcpServers({
|
|
1830
2106
|
userId: opts.userId || "local",
|
|
1831
2107
|
actorUserId: opts.actorUserId,
|
|
2108
|
+
actorTopicScope: opts.actorTopicScope,
|
|
2109
|
+
remoteSession: opts.remoteSession,
|
|
1832
2110
|
vaultUserId: opts.vaultUserId,
|
|
1833
2111
|
session: opts.session || "default",
|
|
1834
2112
|
topicId: opts.topicId,
|
|
@@ -2726,7 +3004,7 @@ import { tmpdir } from "os";
|
|
|
2726
3004
|
import { dirname as dirname5, join as join3 } from "path";
|
|
2727
3005
|
|
|
2728
3006
|
// ../../packages/core/src/version.ts
|
|
2729
|
-
var NEGOTIUM_VERSION = "0.
|
|
3007
|
+
var NEGOTIUM_VERSION = "0.20.0";
|
|
2730
3008
|
|
|
2731
3009
|
// ../../packages/core/src/agents/codex-native-multi-agent.ts
|
|
2732
3010
|
var moduleRequire = createRequire(import.meta.url);
|
|
@@ -3455,7 +3733,7 @@ async function createCodexVaultHookBridge(userId) {
|
|
|
3455
3733
|
});
|
|
3456
3734
|
restrictIpcEndpoint(socketPath);
|
|
3457
3735
|
if (IS_WINDOWS2) {
|
|
3458
|
-
const { BINARIES_DIR } = await import("./chunk-
|
|
3736
|
+
const { BINARIES_DIR } = await import("./chunk-7he9nzfa.js");
|
|
3459
3737
|
const cached = await ensureCodexWindowsWrapperExe(join5(BINARIES_DIR, "codex-hook-wrapper"));
|
|
3460
3738
|
await copyFile(cached, wrapperPath);
|
|
3461
3739
|
await writeFile2(join5(root, "codex-with-hooks.cfg"), [process.execPath, codexCliScriptPath(), socketPath, token].join(`
|
|
@@ -4769,4 +5047,4 @@ export {
|
|
|
4769
5047
|
buildClaudeDisallowedTools
|
|
4770
5048
|
};
|
|
4771
5049
|
|
|
4772
|
-
//# debugId=
|
|
5050
|
+
//# debugId=977679FF27CBA61D64756E2164756E21
|