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
|
@@ -603,6 +603,63 @@ function referencesRuntimeSecretStorage(value) {
|
|
|
603
603
|
return false;
|
|
604
604
|
}
|
|
605
605
|
|
|
606
|
+
// ../../packages/core/src/agents/explicit-agent-switch.ts
|
|
607
|
+
function escapeRegExp(value) {
|
|
608
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
609
|
+
}
|
|
610
|
+
function agentAliases(agent) {
|
|
611
|
+
switch (agent) {
|
|
612
|
+
case "codex":
|
|
613
|
+
return [
|
|
614
|
+
"codex",
|
|
615
|
+
"\uCF54\uB371\uC2A4",
|
|
616
|
+
"gpt-6-luna",
|
|
617
|
+
"gpt-6-sol",
|
|
618
|
+
"gpt-5.6-luna",
|
|
619
|
+
"gpt-5.6-terra",
|
|
620
|
+
"gpt-5.6-sol",
|
|
621
|
+
"gpt-6-astra"
|
|
622
|
+
];
|
|
623
|
+
case "claude":
|
|
624
|
+
return ["claude", "\uD074\uB85C\uB4DC", "sonnet", "opus", "fable"];
|
|
625
|
+
case "maestro":
|
|
626
|
+
return [
|
|
627
|
+
"maestro",
|
|
628
|
+
"\uB9C8\uC5D0\uC2A4\uD2B8\uB85C",
|
|
629
|
+
"\uBA54\uC2A4\uD2B8\uB85C",
|
|
630
|
+
"deepseek",
|
|
631
|
+
"deepseek-pro",
|
|
632
|
+
"kimi",
|
|
633
|
+
"kimi-pro",
|
|
634
|
+
"kimi-k3",
|
|
635
|
+
"kimi-code",
|
|
636
|
+
"kimi-k2.7-code",
|
|
637
|
+
"\uB525\uC2DC\uD06C",
|
|
638
|
+
"\uD0A4\uBBF8"
|
|
639
|
+
];
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
function hasExplicitAgentSwitchRequest(prompt, agent) {
|
|
643
|
+
if (!prompt?.trim())
|
|
644
|
+
return false;
|
|
645
|
+
const text = prompt.toLowerCase().replace(/\s+/g, " ").trim();
|
|
646
|
+
const target = `(?:${agentAliases(agent).map(escapeRegExp).join("|")})`;
|
|
647
|
+
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)";
|
|
648
|
+
const switchSubject = "(?:agent|runtime|model|\uC5D0\uC774\uC804\uD2B8|\uB7F0\uD0C0\uC784|\uBAA8\uB378)";
|
|
649
|
+
return [
|
|
650
|
+
new RegExp(`^/(?:agent|runtime)\\s+${target}(?:\\s|$)`, "iu"),
|
|
651
|
+
new RegExp(`${target}\\s*(?:\uB85C|\uC73C\uB85C)\\s*.{0,16}${switchVerb}`, "iu"),
|
|
652
|
+
new RegExp(`${switchSubject}.{0,24}${target}.{0,24}${switchVerb}`, "iu"),
|
|
653
|
+
new RegExp(`${switchVerb}.{0,24}${switchSubject}.{0,24}${target}`, "iu"),
|
|
654
|
+
new RegExp(`(?:switch|change|set|use).{0,24}${target}`, "iu")
|
|
655
|
+
].some((pattern) => pattern.test(text));
|
|
656
|
+
}
|
|
657
|
+
function explicitAgentSwitchTargets(prompt) {
|
|
658
|
+
if (!prompt?.trim())
|
|
659
|
+
return [];
|
|
660
|
+
return SUPPORTED_AGENTS.filter((agent) => hasExplicitAgentSwitchRequest(prompt, agent));
|
|
661
|
+
}
|
|
662
|
+
|
|
606
663
|
// ../../packages/core/src/mcp/canonical-bridge-config.ts
|
|
607
664
|
var registrations = [];
|
|
608
665
|
var turnLeases = new Map;
|
|
@@ -629,10 +686,189 @@ function canonicalMcpBridgeEnv(scope) {
|
|
|
629
686
|
|
|
630
687
|
// ../../packages/core/src/mcp/runtime-spec.ts
|
|
631
688
|
import { createHash, createHmac, timingSafeEqual } from "crypto";
|
|
689
|
+
|
|
690
|
+
// ../../packages/core/src/runtime/actor-topic-scope.ts
|
|
691
|
+
var ACTOR_TOPIC_SCOPE_LIMITS = Object.freeze({
|
|
692
|
+
maxIdsPerList: 200,
|
|
693
|
+
maxIdLength: 128,
|
|
694
|
+
maxSerializedBytes: 8 * 1024
|
|
695
|
+
});
|
|
696
|
+
var SCOPE_KEYS = ["visibleNodeTopicIds", "ownedNodeTopicIds"];
|
|
697
|
+
function idList(value, name) {
|
|
698
|
+
if (!Array.isArray(value))
|
|
699
|
+
return `${name} must be an array of topic ids`;
|
|
700
|
+
if (value.length > ACTOR_TOPIC_SCOPE_LIMITS.maxIdsPerList) {
|
|
701
|
+
return `${name} has ${value.length} ids; at most ${ACTOR_TOPIC_SCOPE_LIMITS.maxIdsPerList} are allowed`;
|
|
702
|
+
}
|
|
703
|
+
const ids = new Set;
|
|
704
|
+
for (const item of value) {
|
|
705
|
+
if (typeof item !== "string")
|
|
706
|
+
return `${name} must contain only strings`;
|
|
707
|
+
const id = item.trim();
|
|
708
|
+
if (!id)
|
|
709
|
+
return `${name} must not contain empty ids`;
|
|
710
|
+
if (id.length > ACTOR_TOPIC_SCOPE_LIMITS.maxIdLength) {
|
|
711
|
+
return `${name} contains an id longer than ${ACTOR_TOPIC_SCOPE_LIMITS.maxIdLength} characters`;
|
|
712
|
+
}
|
|
713
|
+
ids.add(id);
|
|
714
|
+
}
|
|
715
|
+
return [...ids];
|
|
716
|
+
}
|
|
717
|
+
function validateActorTopicScope(value) {
|
|
718
|
+
if (value === undefined)
|
|
719
|
+
return { ok: true, scope: undefined };
|
|
720
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
721
|
+
return {
|
|
722
|
+
ok: false,
|
|
723
|
+
error: "actorTopicScope must be { visibleNodeTopicIds: string[], ownedNodeTopicIds: string[] }"
|
|
724
|
+
};
|
|
725
|
+
}
|
|
726
|
+
const proto = Object.getPrototypeOf(value);
|
|
727
|
+
if (proto !== Object.prototype && proto !== null) {
|
|
728
|
+
return { ok: false, error: "actorTopicScope must be a plain object" };
|
|
729
|
+
}
|
|
730
|
+
const keys = Object.keys(value);
|
|
731
|
+
const unknown = keys.filter((key) => !SCOPE_KEYS.includes(key));
|
|
732
|
+
if (unknown.length || keys.length !== SCOPE_KEYS.length) {
|
|
733
|
+
return {
|
|
734
|
+
ok: false,
|
|
735
|
+
error: unknown.length ? `actorTopicScope has unexpected key(s): ${unknown.join(", ")}` : "actorTopicScope must have both visibleNodeTopicIds and ownedNodeTopicIds"
|
|
736
|
+
};
|
|
737
|
+
}
|
|
738
|
+
const record = value;
|
|
739
|
+
const visible = idList(record.visibleNodeTopicIds, "actorTopicScope.visibleNodeTopicIds");
|
|
740
|
+
if (typeof visible === "string")
|
|
741
|
+
return { ok: false, error: visible };
|
|
742
|
+
const owned = idList(record.ownedNodeTopicIds, "actorTopicScope.ownedNodeTopicIds");
|
|
743
|
+
if (typeof owned === "string")
|
|
744
|
+
return { ok: false, error: owned };
|
|
745
|
+
const scope = { visibleNodeTopicIds: visible, ownedNodeTopicIds: owned };
|
|
746
|
+
const bytes = Buffer.byteLength(JSON.stringify(scope), "utf-8");
|
|
747
|
+
if (bytes > ACTOR_TOPIC_SCOPE_LIMITS.maxSerializedBytes) {
|
|
748
|
+
return {
|
|
749
|
+
ok: false,
|
|
750
|
+
error: `actorTopicScope is ${bytes} bytes serialized; at most ${ACTOR_TOPIC_SCOPE_LIMITS.maxSerializedBytes} are allowed`
|
|
751
|
+
};
|
|
752
|
+
}
|
|
753
|
+
return { ok: true, scope };
|
|
754
|
+
}
|
|
755
|
+
function encodeActorTopicScopeArg(scope) {
|
|
756
|
+
const validated = validateActorTopicScope(scope);
|
|
757
|
+
if (!validated.ok)
|
|
758
|
+
throw new Error(validated.error);
|
|
759
|
+
if (!validated.scope)
|
|
760
|
+
throw new Error("actorTopicScope is required");
|
|
761
|
+
return Buffer.from(JSON.stringify(validated.scope), "utf-8").toString("base64url");
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
// ../../packages/core/src/runtime/remote-session-grant.ts
|
|
765
|
+
var REMOTE_SESSION_GRANT_LIMITS = Object.freeze({
|
|
766
|
+
maxHubUrlLength: 512,
|
|
767
|
+
maxCapabilityLength: 2 * 1024,
|
|
768
|
+
capabilityPrefix: "rsc1."
|
|
769
|
+
});
|
|
770
|
+
var GRANT_KEYS = ["hubUrl", "capability"];
|
|
771
|
+
var LOOPBACK_HOSTS = new Set(["127.0.0.1", "::1", "[::1]", "localhost"]);
|
|
772
|
+
function normalizeHubUrl(raw, name = "remoteSession.hubUrl") {
|
|
773
|
+
if (raw.length > REMOTE_SESSION_GRANT_LIMITS.maxHubUrlLength) {
|
|
774
|
+
return {
|
|
775
|
+
error: `${name} is longer than ${REMOTE_SESSION_GRANT_LIMITS.maxHubUrlLength} characters`
|
|
776
|
+
};
|
|
777
|
+
}
|
|
778
|
+
let url;
|
|
779
|
+
try {
|
|
780
|
+
url = new URL(raw);
|
|
781
|
+
} catch {
|
|
782
|
+
return { error: `${name} must be an absolute URL` };
|
|
783
|
+
}
|
|
784
|
+
if (url.username || url.password) {
|
|
785
|
+
return { error: `${name} must not carry credentials` };
|
|
786
|
+
}
|
|
787
|
+
if (url.search || url.hash || raw.includes("?") || raw.includes("#")) {
|
|
788
|
+
return { error: `${name} must not carry a query or fragment` };
|
|
789
|
+
}
|
|
790
|
+
if (url.protocol === "http:") {
|
|
791
|
+
if (!LOOPBACK_HOSTS.has(url.hostname)) {
|
|
792
|
+
return { error: `${name} must be https:// or a loopback http:// origin` };
|
|
793
|
+
}
|
|
794
|
+
} else if (url.protocol !== "https:") {
|
|
795
|
+
return { error: `${name} must be https:// or a loopback http:// origin` };
|
|
796
|
+
}
|
|
797
|
+
return { url: url.toString().replace(/\/+$/, "") };
|
|
798
|
+
}
|
|
799
|
+
var MAX_REMOTE_SESSION_REPLY_TOKEN_LENGTH = REMOTE_SESSION_GRANT_LIMITS.maxCapabilityLength;
|
|
800
|
+
function validateRemoteSessionGrant(value) {
|
|
801
|
+
if (value === undefined)
|
|
802
|
+
return { ok: true, grant: undefined };
|
|
803
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
804
|
+
return { ok: false, error: "remoteSession must be { hubUrl: string, capability: string }" };
|
|
805
|
+
}
|
|
806
|
+
const proto = Object.getPrototypeOf(value);
|
|
807
|
+
if (proto !== Object.prototype && proto !== null) {
|
|
808
|
+
return { ok: false, error: "remoteSession must be a plain object" };
|
|
809
|
+
}
|
|
810
|
+
const keys = Object.keys(value);
|
|
811
|
+
const unknown = keys.filter((key) => !GRANT_KEYS.includes(key));
|
|
812
|
+
if (unknown.length || keys.length !== GRANT_KEYS.length) {
|
|
813
|
+
return {
|
|
814
|
+
ok: false,
|
|
815
|
+
error: unknown.length ? `remoteSession has unexpected key(s): ${unknown.join(", ")}` : "remoteSession must have both hubUrl and capability"
|
|
816
|
+
};
|
|
817
|
+
}
|
|
818
|
+
const record = value;
|
|
819
|
+
if (typeof record.hubUrl !== "string" || !record.hubUrl.trim()) {
|
|
820
|
+
return { ok: false, error: "remoteSession.hubUrl must be a non-empty string" };
|
|
821
|
+
}
|
|
822
|
+
const hubUrl = normalizeHubUrl(record.hubUrl.trim());
|
|
823
|
+
if ("error" in hubUrl)
|
|
824
|
+
return { ok: false, error: hubUrl.error };
|
|
825
|
+
if (typeof record.capability !== "string" || !record.capability.trim()) {
|
|
826
|
+
return { ok: false, error: "remoteSession.capability must be a non-empty string" };
|
|
827
|
+
}
|
|
828
|
+
const capability = record.capability.trim();
|
|
829
|
+
if (capability.length > REMOTE_SESSION_GRANT_LIMITS.maxCapabilityLength) {
|
|
830
|
+
return {
|
|
831
|
+
ok: false,
|
|
832
|
+
error: `remoteSession.capability is ${capability.length} characters; at most ${REMOTE_SESSION_GRANT_LIMITS.maxCapabilityLength} are allowed`
|
|
833
|
+
};
|
|
834
|
+
}
|
|
835
|
+
if (!capability.startsWith(REMOTE_SESSION_GRANT_LIMITS.capabilityPrefix)) {
|
|
836
|
+
return {
|
|
837
|
+
ok: false,
|
|
838
|
+
error: `remoteSession.capability must start with "${REMOTE_SESSION_GRANT_LIMITS.capabilityPrefix}"`
|
|
839
|
+
};
|
|
840
|
+
}
|
|
841
|
+
if (!/^rsc1\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(capability)) {
|
|
842
|
+
return { ok: false, error: "remoteSession.capability is malformed" };
|
|
843
|
+
}
|
|
844
|
+
return { ok: true, grant: { hubUrl: hubUrl.url, capability } };
|
|
845
|
+
}
|
|
846
|
+
function encodeRemoteSessionGrantArg(grant) {
|
|
847
|
+
const validated = validateRemoteSessionGrant(grant);
|
|
848
|
+
if (!validated.ok)
|
|
849
|
+
throw new Error(validated.error);
|
|
850
|
+
if (!validated.grant)
|
|
851
|
+
throw new Error("remoteSession is required");
|
|
852
|
+
return Buffer.from(JSON.stringify(validated.grant), "utf-8").toString("base64url");
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
// ../../packages/core/src/mcp/runtime-spec.ts
|
|
632
856
|
var RUNTIME_MCP_KEY = "runtime";
|
|
633
857
|
var RUNTIME_MCP_BASE_PATH = "/mcp/runtime";
|
|
634
858
|
var TOKEN_TTL_MS = 4 * 60 * 60 * 1000;
|
|
635
859
|
var CLAUDE_MCP_TOOL_TIMEOUT_MS = 600000;
|
|
860
|
+
var MCP_URL_BUDGET_CHARS = 14 * 1024;
|
|
861
|
+
|
|
862
|
+
class McpUrlBudgetExceededError extends Error {
|
|
863
|
+
surface;
|
|
864
|
+
urlLength;
|
|
865
|
+
constructor(surface, urlLength) {
|
|
866
|
+
super(`built-in MCP URL for "${surface}" is ${urlLength} characters; the transport allows at most ${MCP_URL_BUDGET_CHARS}`);
|
|
867
|
+
this.surface = surface;
|
|
868
|
+
this.urlLength = urlLength;
|
|
869
|
+
this.name = "McpUrlBudgetExceededError";
|
|
870
|
+
}
|
|
871
|
+
}
|
|
636
872
|
var runtimePort = NEGOTIUM_PORT;
|
|
637
873
|
function encodeTokenPart(value) {
|
|
638
874
|
return Buffer.from(JSON.stringify(value), "utf-8").toString("base64url");
|
|
@@ -658,18 +894,26 @@ function issueHostedMcpToken(surface, ctx) {
|
|
|
658
894
|
return `${payloadPart}.${signTokenPayload(payloadPart)}`;
|
|
659
895
|
}
|
|
660
896
|
function buildRuntimeMcpSpec(agent, ctx) {
|
|
661
|
-
const token = issueRuntimeMcpToken(ctx);
|
|
662
897
|
const base = `http://127.0.0.1:${runtimePort}${RUNTIME_MCP_BASE_PATH}`;
|
|
663
|
-
const query = `token=${encodeURIComponent(
|
|
898
|
+
const query = `token=${encodeURIComponent(issueRuntimeMcpToken(ctx))}`;
|
|
899
|
+
const url = agent === "codex" ? `${base}/mcp?${query}` : `${base}/sse?${query}`;
|
|
900
|
+
assertMcpUrlWithinBudget(RUNTIME_MCP_KEY, url, ctx.topicId);
|
|
664
901
|
if (agent === "codex")
|
|
665
|
-
return { url
|
|
902
|
+
return { url };
|
|
666
903
|
return {
|
|
667
904
|
type: "sse",
|
|
668
|
-
url
|
|
905
|
+
url,
|
|
669
906
|
timeout: CLAUDE_MCP_TOOL_TIMEOUT_MS,
|
|
670
907
|
...agent === "maestro" ? { lifecycle: "turn" } : {}
|
|
671
908
|
};
|
|
672
909
|
}
|
|
910
|
+
function assertMcpUrlWithinBudget(surface, url, topicId) {
|
|
911
|
+
if (url.length <= MCP_URL_BUDGET_CHARS)
|
|
912
|
+
return;
|
|
913
|
+
const error = new McpUrlBudgetExceededError(surface, url.length);
|
|
914
|
+
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");
|
|
915
|
+
throw error;
|
|
916
|
+
}
|
|
673
917
|
function hostedMcpCacheIdentity(surface, ctx) {
|
|
674
918
|
let semanticContext;
|
|
675
919
|
switch (surface) {
|
|
@@ -700,6 +944,9 @@ function hostedMcpCacheIdentity(surface, ctx) {
|
|
|
700
944
|
case "session-comm":
|
|
701
945
|
semanticContext = {
|
|
702
946
|
userId: ctx.userId,
|
|
947
|
+
actorUserId: ctx.actorUserId ?? null,
|
|
948
|
+
actorTopicScope: ctx.actorTopicScope ?? null,
|
|
949
|
+
remoteSession: ctx.remoteSession ?? null,
|
|
703
950
|
topicTitle: ctx.topicTitle,
|
|
704
951
|
topicId: ctx.topicId ?? null,
|
|
705
952
|
subagentParentTopicId: ctx.subagentParentTopicId ?? null,
|
|
@@ -718,13 +965,15 @@ function buildHostedMcpSpec(agent, surface, ctx) {
|
|
|
718
965
|
const token = issueHostedMcpToken(surface, ctx);
|
|
719
966
|
const base = `http://127.0.0.1:${runtimePort}${RUNTIME_MCP_BASE_PATH}/${surface}`;
|
|
720
967
|
const query = `token=${encodeURIComponent(token)}`;
|
|
968
|
+
const url = agent === "codex" ? `${base}/mcp?${query}` : `${base}/sse?${query}`;
|
|
969
|
+
assertMcpUrlWithinBudget(surface, url, ctx.topicId);
|
|
721
970
|
if (agent === "codex")
|
|
722
|
-
return { url
|
|
723
|
-
const queryBound = surface === "session-comm" && (ctx.silent === true || ctx.peerBridge !== undefined);
|
|
971
|
+
return { url };
|
|
972
|
+
const queryBound = surface === "session-comm" && (ctx.silent === true || ctx.peerBridge !== undefined || ctx.remoteSession !== undefined);
|
|
724
973
|
const lifecycle = queryBound ? "turn" : surface === "session-comm" ? "session" : "process";
|
|
725
974
|
return {
|
|
726
975
|
type: "sse",
|
|
727
|
-
url
|
|
976
|
+
url,
|
|
728
977
|
timeout: CLAUDE_MCP_TOOL_TIMEOUT_MS,
|
|
729
978
|
...agent === "maestro" ? {
|
|
730
979
|
lifecycle,
|
|
@@ -1493,6 +1742,9 @@ function initializeApiTopicsSchema() {
|
|
|
1493
1742
|
if (!tableColumns("api_topics").has("subagent_report_mode")) {
|
|
1494
1743
|
db.exec("ALTER TABLE api_topics ADD COLUMN subagent_report_mode TEXT NOT NULL DEFAULT 'auto'");
|
|
1495
1744
|
}
|
|
1745
|
+
if (!tableColumns("api_topics").has("derived_by_user_id")) {
|
|
1746
|
+
db.exec("ALTER TABLE api_topics ADD COLUMN derived_by_user_id TEXT");
|
|
1747
|
+
}
|
|
1496
1748
|
if (!tableColumns("api_topics").has("memory_topic_id")) {
|
|
1497
1749
|
db.exec("ALTER TABLE api_topics ADD COLUMN memory_topic_id TEXT");
|
|
1498
1750
|
}
|
|
@@ -1584,6 +1836,7 @@ function rowToDto(r, participants = getTopicParticipants(r.id), tellTargets) {
|
|
|
1584
1836
|
memoryTopicId: r.memory_topic_id ?? undefined,
|
|
1585
1837
|
memoryKey: r.memory_key ?? undefined,
|
|
1586
1838
|
isFork: r.is_fork !== 0,
|
|
1839
|
+
...r.derived_by_user_id ? { derivedByUserId: r.derived_by_user_id } : {},
|
|
1587
1840
|
...r.is_subagent !== 0 ? { isSubagent: true } : {},
|
|
1588
1841
|
...r.is_subagent !== 0 ? {
|
|
1589
1842
|
subagentTellTargetIds: tellTargets ? tellTargets.get(r.id) ?? [] : listSubagentTellTargetIds(r.id)
|
|
@@ -1667,6 +1920,9 @@ function buildBuiltinMcpServer(surface, ctx, stdio) {
|
|
|
1667
1920
|
const agent = ctx.agent ?? FALLBACK_AGENT;
|
|
1668
1921
|
return buildHostedMcpSpec(agent, surface, {
|
|
1669
1922
|
userId: ctx.userId,
|
|
1923
|
+
...ctx.actorUserId ? { actorUserId: ctx.actorUserId } : {},
|
|
1924
|
+
...ctx.actorTopicScope ? { actorTopicScope: ctx.actorTopicScope } : {},
|
|
1925
|
+
...surface === "session-comm" && ctx.remoteSession ? { remoteSession: ctx.remoteSession } : {},
|
|
1670
1926
|
topicTitle: ctx.session,
|
|
1671
1927
|
...ctx.topicId ? { topicId: ctx.topicId } : {},
|
|
1672
1928
|
...ctx.queryId ? { queryId: ctx.queryId } : {},
|
|
@@ -1762,6 +2018,7 @@ var MCP_CATALOG = {
|
|
|
1762
2018
|
build({
|
|
1763
2019
|
userId,
|
|
1764
2020
|
actorUserId,
|
|
2021
|
+
actorTopicScope,
|
|
1765
2022
|
session,
|
|
1766
2023
|
topicId,
|
|
1767
2024
|
queryId,
|
|
@@ -1777,16 +2034,18 @@ var MCP_CATALOG = {
|
|
|
1777
2034
|
}) {
|
|
1778
2035
|
if (!topicId || !agent)
|
|
1779
2036
|
return null;
|
|
2037
|
+
const switchTargets = explicitAgentSwitchTargets(currentUserPrompt);
|
|
1780
2038
|
return buildRuntimeMcpSpec(agent, {
|
|
1781
2039
|
userId,
|
|
1782
2040
|
...actorUserId ? { actorUserId } : {},
|
|
2041
|
+
...actorTopicScope ? { actorTopicScope } : {},
|
|
1783
2042
|
topicId,
|
|
1784
2043
|
topicTitle: session,
|
|
1785
2044
|
queryId,
|
|
1786
2045
|
cwd: cwd ?? resolveTopicWorkspaceDir(topicId),
|
|
1787
2046
|
agent,
|
|
1788
2047
|
model,
|
|
1789
|
-
|
|
2048
|
+
...switchTargets.length ? { explicitAgentSwitchTargets: switchTargets } : {},
|
|
1790
2049
|
autoContinue,
|
|
1791
2050
|
visualTools,
|
|
1792
2051
|
fileDeliveryTools,
|
|
@@ -1856,6 +2115,9 @@ var MCP_CATALOG = {
|
|
|
1856
2115
|
build(ctx) {
|
|
1857
2116
|
const {
|
|
1858
2117
|
userId,
|
|
2118
|
+
actorUserId,
|
|
2119
|
+
actorTopicScope,
|
|
2120
|
+
remoteSession,
|
|
1859
2121
|
session,
|
|
1860
2122
|
topicId,
|
|
1861
2123
|
subagentParentTopicId,
|
|
@@ -1869,6 +2131,9 @@ var MCP_CATALOG = {
|
|
|
1869
2131
|
const cronSessionId = topicId ? getRegisteredCronSession(topicId, effectiveAgent)?.sessionId : undefined;
|
|
1870
2132
|
const args = [
|
|
1871
2133
|
`--user-id=${userId}`,
|
|
2134
|
+
...actorUserId ? [`--actor-user-id=${actorUserId}`] : [],
|
|
2135
|
+
...actorTopicScope ? [`--actor-topic-scope=${encodeActorTopicScopeArg(actorTopicScope)}`] : [],
|
|
2136
|
+
...remoteSession ? [`--remote-session-grant=${encodeRemoteSessionGrantArg(remoteSession)}`] : [],
|
|
1872
2137
|
`--topic=${session}`,
|
|
1873
2138
|
...topicId ? [`--topic-id=${topicId}`] : [],
|
|
1874
2139
|
...subagentParentTopicId ? [`--subagent-parent-topic-id=${subagentParentTopicId}`] : [],
|
|
@@ -2046,6 +2311,9 @@ function getManagerMcpServers(opts) {
|
|
|
2046
2311
|
const topicId = opts.topicId;
|
|
2047
2312
|
return buildScope("manager", {
|
|
2048
2313
|
userId: opts.userId,
|
|
2314
|
+
actorUserId: opts.actorUserId,
|
|
2315
|
+
actorTopicScope: opts.actorTopicScope,
|
|
2316
|
+
remoteSession: opts.remoteSession,
|
|
2049
2317
|
session: opts.session ?? "General",
|
|
2050
2318
|
topicId,
|
|
2051
2319
|
queryId: opts.queryId,
|
|
@@ -2065,6 +2333,8 @@ function getForumMcpServers(opts) {
|
|
|
2065
2333
|
const {
|
|
2066
2334
|
userId,
|
|
2067
2335
|
actorUserId,
|
|
2336
|
+
actorTopicScope,
|
|
2337
|
+
remoteSession,
|
|
2068
2338
|
vaultUserId,
|
|
2069
2339
|
session,
|
|
2070
2340
|
topicId,
|
|
@@ -2098,6 +2368,8 @@ function getForumMcpServers(opts) {
|
|
|
2098
2368
|
const base = buildScope("forum", {
|
|
2099
2369
|
userId,
|
|
2100
2370
|
actorUserId,
|
|
2371
|
+
actorTopicScope,
|
|
2372
|
+
remoteSession,
|
|
2101
2373
|
vaultUserId,
|
|
2102
2374
|
session,
|
|
2103
2375
|
topicId,
|
|
@@ -2178,6 +2450,9 @@ function getMcpServersForQuery(opts) {
|
|
|
2178
2450
|
if (opts.sessionType === "manager") {
|
|
2179
2451
|
return hideProviderIntrospectionForOtium(mergeHostMcpServers(getManagerMcpServers({
|
|
2180
2452
|
userId: opts.userId || "local",
|
|
2453
|
+
actorUserId: opts.actorUserId,
|
|
2454
|
+
actorTopicScope: opts.actorTopicScope,
|
|
2455
|
+
remoteSession: opts.remoteSession,
|
|
2181
2456
|
session: opts.session,
|
|
2182
2457
|
topicId: opts.topicId,
|
|
2183
2458
|
queryId: opts.queryId,
|
|
@@ -2196,6 +2471,8 @@ function getMcpServersForQuery(opts) {
|
|
|
2196
2471
|
return hideProviderIntrospectionForOtium(getForumMcpServers({
|
|
2197
2472
|
userId: opts.userId || "local",
|
|
2198
2473
|
actorUserId: opts.actorUserId,
|
|
2474
|
+
actorTopicScope: opts.actorTopicScope,
|
|
2475
|
+
remoteSession: opts.remoteSession,
|
|
2199
2476
|
vaultUserId: opts.vaultUserId,
|
|
2200
2477
|
session: opts.session || "default",
|
|
2201
2478
|
topicId: opts.topicId,
|
|
@@ -3024,4 +3301,4 @@ function formatDateBucket(d) {
|
|
|
3024
3301
|
|
|
3025
3302
|
export { __require, CLAUDE_EFFORT_VALUES, CODEX_EFFORT_VALUES, MAESTRO_EFFORT_VALUES, logger, MODEL_SONNET, MODEL_OPUS, MODEL_FABLE, configureRolloutHost, FIXTURES_DIR, clone, assertUuidLike, ensureCwdExists, extractChatPairs, parseJsonlText, writeJsonlFile, hostedCodexHomePath, extractLatestCodexPatchPreview, extractCodexPatchCallIds, readCodexPatchCallIds, readLatestCodexPatchPreview, extractLatestCodexContextUsage, readLatestCodexContextUsage, migrateCodexRolloutNativeMultiAgentMetadata, latestCodexRolloutPath, writeCodexRollout, decodeUuidV7Timestamp };
|
|
3026
3303
|
|
|
3027
|
-
//# debugId=
|
|
3304
|
+
//# debugId=402C1CFFD9AFF9A864756E2164756E21
|