@agent-vm/mcp-portal 0.0.74 → 0.0.77
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/mcp-portal.js +4 -4
- package/dist/cli/index.d.ts +2 -2
- package/dist/cli/index.js +1 -1
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.js +4 -4
- package/dist/index.d.ts +39 -2
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -3
- package/dist/mcp-proxy/index.d.ts +2 -2
- package/dist/mcp-proxy/index.js +1 -1
- package/dist/{portal-core-BPSvDGvi.js → portal-core-CDuWxYvB.js} +26 -17
- package/dist/portal-core-CDuWxYvB.js.map +1 -0
- package/dist/{portal-core-CZQI7Ob6.d.ts → portal-core-CF0bfgCX.d.ts} +19 -2
- package/dist/portal-core-CF0bfgCX.d.ts.map +1 -0
- package/dist/{portal-session-DG2CUjIo.d.ts → portal-session-B7no2T4L.d.ts} +17 -2
- package/dist/{portal-session-DG2CUjIo.d.ts.map → portal-session-B7no2T4L.d.ts.map} +1 -1
- package/dist/{portal-tools-DKci1szO.js → portal-tools-CtFO3ruN.js} +25 -8
- package/dist/portal-tools-CtFO3ruN.js.map +1 -0
- package/dist/{resolve-agent-identity-FQL02YdW.d.ts → resolve-agent-identity-ChAD0AFH.d.ts} +3 -3
- package/dist/{resolve-agent-identity-FQL02YdW.d.ts.map → resolve-agent-identity-ChAD0AFH.d.ts.map} +1 -1
- package/dist/{resolve-agent-identity-DnC_Pmnh.js → resolve-agent-identity-EEpzTBFI.js} +3 -3
- package/dist/{resolve-agent-identity-DnC_Pmnh.js.map → resolve-agent-identity-EEpzTBFI.js.map} +1 -1
- package/dist/{serve-command-CV1s-Eln.js → serve-command-Dsak3REg.js} +4 -4
- package/dist/{serve-command-CV1s-Eln.js.map → serve-command-Dsak3REg.js.map} +1 -1
- package/dist/{upstream-mcp-client-runtime-DbPkS6Rk.js → upstream-mcp-client-runtime-BNF9xPCw.js} +59 -11
- package/dist/upstream-mcp-client-runtime-BNF9xPCw.js.map +1 -0
- package/dist/upstream-response-middleware-1MZnAD9C.d.ts.map +1 -1
- package/dist/{upstream-response-middleware-BjUWZ2G8.js → upstream-response-middleware-CpMgDGMh.js} +53 -2
- package/dist/upstream-response-middleware-CpMgDGMh.js.map +1 -0
- package/package.json +3 -3
- package/dist/portal-core-BPSvDGvi.js.map +0 -1
- package/dist/portal-core-CZQI7Ob6.d.ts.map +0 -1
- package/dist/portal-tools-DKci1szO.js.map +0 -1
- package/dist/upstream-mcp-client-runtime-DbPkS6Rk.js.map +0 -1
- package/dist/upstream-response-middleware-BjUWZ2G8.js.map +0 -1
package/dist/{upstream-mcp-client-runtime-DbPkS6Rk.js → upstream-mcp-client-runtime-BNF9xPCw.js}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { a as portalToolRecordSchema, r as encodeToolRef } from "./zod-schema-loader-yNekKNpm.js";
|
|
2
|
-
import { a as redactUpstreamCatalogValue,
|
|
2
|
+
import { a as redactUpstreamCatalogValue, d as isUpstreamMcpError, f as messageFromUnknownError, h as createToolSummary, i as redactThrownError, l as createUpstreamMcpError, m as upstreamMcpFailureDetailsFromUnknown, o as redactUpstreamResponse, p as transportSummaryFromServer, u as formatUpstreamMcpFailureMessage, v as portalAgentScopeKey, y as resolvePortalAccessPolicy } from "./upstream-response-middleware-CpMgDGMh.js";
|
|
3
3
|
import { createHash } from "node:crypto";
|
|
4
4
|
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
5
5
|
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
|
|
@@ -306,8 +306,18 @@ function portalToolFromMcpTool(namespace, tool) {
|
|
|
306
306
|
function createSourceHash(tools) {
|
|
307
307
|
return createHash("sha256").update(JSON.stringify(tools)).digest("hex");
|
|
308
308
|
}
|
|
309
|
-
function
|
|
310
|
-
|
|
309
|
+
function discoveryFailureFromError(namespace, error) {
|
|
310
|
+
const upstreamDetails = upstreamMcpFailureDetailsFromUnknown(error);
|
|
311
|
+
if (upstreamDetails !== null) return {
|
|
312
|
+
...upstreamDetails,
|
|
313
|
+
message: formatUpstreamMcpFailureMessage(upstreamDetails),
|
|
314
|
+
namespace
|
|
315
|
+
};
|
|
316
|
+
return {
|
|
317
|
+
kind: "upstream_discovery_failed",
|
|
318
|
+
message: messageFromUnknownError(error),
|
|
319
|
+
namespace
|
|
320
|
+
};
|
|
311
321
|
}
|
|
312
322
|
function createPortalSessionManager(options) {
|
|
313
323
|
const sessions = /* @__PURE__ */ new Map();
|
|
@@ -345,10 +355,7 @@ function createPortalSessionManager(options) {
|
|
|
345
355
|
for (const [index, namespaceToolGroup] of namespaceToolGroups.entries()) {
|
|
346
356
|
if (namespaceToolGroup.status === "rejected") {
|
|
347
357
|
const namespace = allowedNamespaces[index] ?? "unknown";
|
|
348
|
-
discoveryFailures.push(
|
|
349
|
-
message: messageFromError(namespaceToolGroup.reason),
|
|
350
|
-
namespace
|
|
351
|
-
});
|
|
358
|
+
discoveryFailures.push(discoveryFailureFromError(namespace, namespaceToolGroup.reason));
|
|
352
359
|
continue;
|
|
353
360
|
}
|
|
354
361
|
const { mcpTools, namespace } = namespaceToolGroup.value;
|
|
@@ -519,6 +526,9 @@ function redactionValuesFromServer(server) {
|
|
|
519
526
|
function timeoutMsForServer(server) {
|
|
520
527
|
return server.connectionTimeoutMs ?? defaultConnectionTimeoutMs;
|
|
521
528
|
}
|
|
529
|
+
function elapsedMsSince(startedAt) {
|
|
530
|
+
return Math.max(0, Date.now() - startedAt);
|
|
531
|
+
}
|
|
522
532
|
function assertUpstreamResponseSize(value, maxResponseBytes) {
|
|
523
533
|
const serialized = JSON.stringify(value);
|
|
524
534
|
if (serialized === void 0) return;
|
|
@@ -637,6 +647,7 @@ function createUpstreamMcpClientRuntime(options) {
|
|
|
637
647
|
const client = createClient();
|
|
638
648
|
const transport = createTransport(transportKind === "sse" && server.transport !== "stdio" ? withRemoteHeaders(server) : withStdioRuntimeEnv(server), transportKind);
|
|
639
649
|
const timeoutAbort = createRuntimeAbortSignal(void 0);
|
|
650
|
+
const startedAt = Date.now();
|
|
640
651
|
try {
|
|
641
652
|
await withTimeout(client.connect(transport, { signal: timeoutAbort.signal }), {
|
|
642
653
|
onTimeout: timeoutAbort.abortTimeout,
|
|
@@ -647,7 +658,17 @@ function createUpstreamMcpClientRuntime(options) {
|
|
|
647
658
|
} catch (error) {
|
|
648
659
|
const redactedError = redactThrownError(error, { exactValues: redactionValues });
|
|
649
660
|
await closeClientAfterFailureOnce(client);
|
|
650
|
-
|
|
661
|
+
const structuredError = createUpstreamMcpError({
|
|
662
|
+
attemptTransport: transportKind,
|
|
663
|
+
causeMessage: messageFromUnknownError(redactedError),
|
|
664
|
+
elapsedMs: elapsedMsSince(startedAt),
|
|
665
|
+
namespace: server.namespace,
|
|
666
|
+
operation: `MCP ${transportKind} connect for namespace "${server.namespace}"`,
|
|
667
|
+
phase: "connect",
|
|
668
|
+
timeoutMs: timeoutMsForServer(server),
|
|
669
|
+
transport: transportSummaryFromServer(server, transportKind)
|
|
670
|
+
});
|
|
671
|
+
return tryAttempt(attemptIndex + 1, structuredError);
|
|
651
672
|
} finally {
|
|
652
673
|
timeoutAbort.dispose();
|
|
653
674
|
}
|
|
@@ -694,6 +715,7 @@ function createUpstreamMcpClientRuntime(options) {
|
|
|
694
715
|
async callTool(call) {
|
|
695
716
|
const key = cacheKey(call.agentScopeId, call.namespace);
|
|
696
717
|
let client = null;
|
|
718
|
+
const startedAt = Date.now();
|
|
697
719
|
try {
|
|
698
720
|
client = await getClient(call.agentScopeId, call.namespace);
|
|
699
721
|
const server = serversByNamespace.get(call.namespace);
|
|
@@ -726,7 +748,20 @@ function createUpstreamMcpClientRuntime(options) {
|
|
|
726
748
|
if (isCallerAbortError(error, call.signal)) throw redactThrownError(error, { exactValues: redactionValues });
|
|
727
749
|
clients.delete(key);
|
|
728
750
|
await closeClientAfterFailureOnce(client);
|
|
729
|
-
|
|
751
|
+
if (isUpstreamMcpError(error)) throw error;
|
|
752
|
+
const redactedError = redactThrownError(error, { exactValues: redactionValues });
|
|
753
|
+
const server = serversByNamespace.get(call.namespace);
|
|
754
|
+
if (server !== void 0) throw createUpstreamMcpError({
|
|
755
|
+
causeMessage: messageFromUnknownError(redactedError),
|
|
756
|
+
elapsedMs: elapsedMsSince(startedAt),
|
|
757
|
+
namespace: call.namespace,
|
|
758
|
+
operation: `MCP callTool ${call.namespace}.${call.toolName}`,
|
|
759
|
+
phase: "call_tool",
|
|
760
|
+
timeoutMs: timeoutMsForServer(server),
|
|
761
|
+
toolName: call.toolName,
|
|
762
|
+
transport: transportSummaryFromServer(server)
|
|
763
|
+
});
|
|
764
|
+
throw redactedError;
|
|
730
765
|
}
|
|
731
766
|
},
|
|
732
767
|
async closeAgentScope(agentScopeId) {
|
|
@@ -762,6 +797,7 @@ function createUpstreamMcpClientRuntime(options) {
|
|
|
762
797
|
async listTools(call) {
|
|
763
798
|
const key = cacheKey(call.agentScopeId, call.namespace);
|
|
764
799
|
let client = null;
|
|
800
|
+
const startedAt = Date.now();
|
|
765
801
|
try {
|
|
766
802
|
client = await getClient(call.agentScopeId, call.namespace);
|
|
767
803
|
const server = serversByNamespace.get(call.namespace);
|
|
@@ -774,7 +810,19 @@ function createUpstreamMcpClientRuntime(options) {
|
|
|
774
810
|
} catch (error) {
|
|
775
811
|
clients.delete(key);
|
|
776
812
|
await closeClientAfterFailureOnce(client);
|
|
777
|
-
|
|
813
|
+
if (isUpstreamMcpError(error)) throw error;
|
|
814
|
+
const redactedError = redactThrownError(error, { exactValues: redactionValues });
|
|
815
|
+
const server = serversByNamespace.get(call.namespace);
|
|
816
|
+
if (server !== void 0) throw createUpstreamMcpError({
|
|
817
|
+
causeMessage: messageFromUnknownError(redactedError),
|
|
818
|
+
elapsedMs: elapsedMsSince(startedAt),
|
|
819
|
+
namespace: call.namespace,
|
|
820
|
+
operation: "MCP listTools",
|
|
821
|
+
phase: "list_tools",
|
|
822
|
+
timeoutMs: timeoutMsForServer(server),
|
|
823
|
+
transport: transportSummaryFromServer(server)
|
|
824
|
+
});
|
|
825
|
+
throw redactedError;
|
|
778
826
|
}
|
|
779
827
|
}
|
|
780
828
|
};
|
|
@@ -782,4 +830,4 @@ function createUpstreamMcpClientRuntime(options) {
|
|
|
782
830
|
//#endregion
|
|
783
831
|
export { createSearchIndex as i, createPortalSessionManager as n, buildToolGraph as r, createUpstreamMcpClientRuntime as t };
|
|
784
832
|
|
|
785
|
-
//# sourceMappingURL=upstream-mcp-client-runtime-
|
|
833
|
+
//# sourceMappingURL=upstream-mcp-client-runtime-BNF9xPCw.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upstream-mcp-client-runtime-BNF9xPCw.js","names":[],"sources":["../src/search-index.ts","../src/tool-graph.ts","../src/portal-session.ts","../src/upstream-mcp-client-runtime.ts"],"sourcesContent":["import { portalToolRecordSchema, type PortalToolRecord } from './catalog-types.js';\nimport type { JsonObject, JsonValue } from './json-schema.js';\nimport type { ToolGraph, ToolRelationship } from './tool-graph.js';\nimport { createToolSummary, type ToolSummary } from './tool-summary.js';\n\nexport interface SearchQuery {\n\treadonly limit: number;\n\treadonly namespaces?: readonly string[];\n\treadonly query?: string;\n}\n\nexport interface SearchResultSet {\n\treadonly results: readonly ToolSearchResult[];\n}\n\nexport interface SearchIndex {\n\treadonly search: (query: SearchQuery) => SearchResultSet;\n}\n\ninterface SearchEntry {\n\treadonly inputFields: readonly string[];\n\treadonly relationshipHints: readonly ToolRelationshipHint[];\n\treadonly searchText: string;\n\treadonly summary: ToolSearchResult;\n}\n\nexport interface ToolRelationshipHint {\n\treadonly field?: string;\n\treadonly reason: string;\n\treadonly sourceToolRef: string;\n\treadonly type: ToolRelationship['type'];\n}\n\nexport interface ToolSearchResult extends ToolSummary {\n\treadonly relationshipHints?: readonly ToolRelationshipHint[];\n\treadonly schemaFieldMatches?: readonly string[];\n}\n\nfunction collectSchemaText(value: JsonValue, parts: string[]): void {\n\tif (Array.isArray(value)) {\n\t\tfor (const item of value) {\n\t\t\tcollectSchemaText(item, parts);\n\t\t}\n\t\treturn;\n\t}\n\n\tif (typeof value !== 'object' || value === null) {\n\t\tif (typeof value === 'string') {\n\t\t\tparts.push(value);\n\t\t}\n\t\treturn;\n\t}\n\n\tfor (const [key, childValue] of Object.entries(value)) {\n\t\tparts.push(key);\n\t\tcollectSchemaText(childValue, parts);\n\t}\n}\n\nfunction normalizeSearchText(text: string): string {\n\treturn text.toLowerCase().replace(/[_-]/g, ' ');\n}\n\nfunction buildSearchText(tool: PortalToolRecord): string {\n\tconst parts = [tool.namespace, tool.toolName, tool.title ?? '', tool.description ?? ''];\n\tcollectSchemaText(tool.inputSchema, parts);\n\tif (tool.outputSchema) {\n\t\tcollectSchemaText(tool.outputSchema, parts);\n\t}\n\n\treturn normalizeSearchText(parts.join(' '));\n}\n\nfunction propertiesFromSchema(schema: JsonObject): readonly string[] {\n\tconst properties = schema.properties;\n\tif (typeof properties !== 'object' || properties === null || Array.isArray(properties)) {\n\t\treturn [];\n\t}\n\n\treturn Object.keys(properties).toSorted();\n}\n\nfunction createRelationshipHints(\n\ttool: PortalToolRecord,\n\trelationships: readonly ToolRelationship[],\n): readonly ToolRelationshipHint[] {\n\tconst targetToolRef = createToolSummary(tool).toolRef;\n\n\treturn relationships\n\t\t.filter((relationship) => relationship.to.toolRef === targetToolRef)\n\t\t.map((relationship) =>\n\t\t\trelationship.field === undefined\n\t\t\t\t? {\n\t\t\t\t\t\treason: relationship.reason,\n\t\t\t\t\t\tsourceToolRef: relationship.from.toolRef,\n\t\t\t\t\t\ttype: relationship.type,\n\t\t\t\t\t}\n\t\t\t\t: {\n\t\t\t\t\t\tfield: relationship.field,\n\t\t\t\t\t\treason: relationship.reason,\n\t\t\t\t\t\tsourceToolRef: relationship.from.toolRef,\n\t\t\t\t\t\ttype: relationship.type,\n\t\t\t\t\t},\n\t\t)\n\t\t.toSorted((left, right) => {\n\t\t\tconst typeOrder = left.type.localeCompare(right.type);\n\t\t\tif (typeOrder !== 0) {\n\t\t\t\treturn typeOrder;\n\t\t\t}\n\t\t\treturn left.sourceToolRef.localeCompare(right.sourceToolRef);\n\t\t});\n}\n\nfunction scopedSkillText(toolRef: string, graph?: ToolGraph): string {\n\tif (!graph) {\n\t\treturn '';\n\t}\n\n\treturn graph.skills\n\t\t.filter((skill) => skill.toolRefs.includes(toolRef))\n\t\t.map((skill) => [skill.title, skill.description ?? '', ...skill.tags].join(' '))\n\t\t.join(' ');\n}\n\nfunction scoreEntry(entry: SearchEntry, terms: readonly string[]): number {\n\tlet score = 0;\n\tfor (const term of terms) {\n\t\tif (entry.searchText.includes(term)) {\n\t\t\tscore += 1;\n\t\t}\n\t}\n\n\treturn score;\n}\n\nfunction compareSummaries(left: ToolSummary, right: ToolSummary): number {\n\tconst namespaceOrder = left.namespace.localeCompare(right.namespace);\n\tif (namespaceOrder !== 0) {\n\t\treturn namespaceOrder;\n\t}\n\n\treturn left.toolName.localeCompare(right.toolName);\n}\n\nfunction withRelationshipHints(\n\tsummary: ToolSummary,\n\trelationshipHints: readonly ToolRelationshipHint[],\n): ToolSearchResult {\n\tif (relationshipHints.length === 0) {\n\t\treturn summary;\n\t}\n\n\treturn {\n\t\t...(summary.description !== undefined ? { description: summary.description } : {}),\n\t\tinput: summary.input,\n\t\tnamespace: summary.namespace,\n\t\t...(summary.output !== undefined ? { output: summary.output } : {}),\n\t\trelationshipHints,\n\t\tsafety: summary.safety,\n\t\t...(summary.title !== undefined ? { title: summary.title } : {}),\n\t\ttoolName: summary.toolName,\n\t\ttoolRef: summary.toolRef,\n\t};\n}\n\nfunction withSchemaFieldMatches(\n\tsummary: ToolSearchResult,\n\tschemaFieldMatches: readonly string[],\n): ToolSearchResult {\n\tif (schemaFieldMatches.length === 0) {\n\t\treturn summary;\n\t}\n\n\treturn {\n\t\t...(summary.description !== undefined ? { description: summary.description } : {}),\n\t\tinput: summary.input,\n\t\tnamespace: summary.namespace,\n\t\t...(summary.output !== undefined ? { output: summary.output } : {}),\n\t\t...(summary.relationshipHints !== undefined\n\t\t\t? { relationshipHints: summary.relationshipHints }\n\t\t\t: {}),\n\t\tsafety: summary.safety,\n\t\tschemaFieldMatches,\n\t\t...(summary.title !== undefined ? { title: summary.title } : {}),\n\t\ttoolName: summary.toolName,\n\t\ttoolRef: summary.toolRef,\n\t};\n}\n\nexport function createSearchIndex(\n\ttools: readonly PortalToolRecord[],\n\tgraph?: ToolGraph,\n): SearchIndex {\n\tconst entries = tools\n\t\t.map((tool) => portalToolRecordSchema.parse(tool))\n\t\t.map((tool) => {\n\t\t\tconst summary = createToolSummary(tool);\n\t\t\tconst relationshipHints = createRelationshipHints(tool, graph?.relationships ?? []);\n\t\t\tconst inputFields = propertiesFromSchema(tool.inputSchema);\n\t\t\tconst relationText = relationshipHints\n\t\t\t\t.map((hint) => [hint.field ?? '', hint.reason, hint.sourceToolRef, hint.type].join(' '))\n\t\t\t\t.join(' ');\n\t\t\tconst skillText = scopedSkillText(summary.toolRef, graph);\n\n\t\t\treturn {\n\t\t\t\tinputFields,\n\t\t\t\trelationshipHints,\n\t\t\t\tsearchText: normalizeSearchText([buildSearchText(tool), relationText, skillText].join(' ')),\n\t\t\t\tsummary: withRelationshipHints(summary, relationshipHints),\n\t\t\t};\n\t\t})\n\t\t.toSorted((left, right) => compareSummaries(left.summary, right.summary));\n\n\treturn {\n\t\tsearch(query: SearchQuery): SearchResultSet {\n\t\t\tconst limit = Math.max(0, Math.floor(query.limit));\n\t\t\tconst namespaceFilter = new Set(query.namespaces ?? []);\n\t\t\tconst terms = normalizeSearchText(query.query ?? '')\n\t\t\t\t.split(/\\s+/)\n\t\t\t\t.map((term) => term.trim())\n\t\t\t\t.filter(Boolean);\n\t\t\tconst scoredEntries = entries\n\t\t\t\t.filter(\n\t\t\t\t\t(entry) => namespaceFilter.size === 0 || namespaceFilter.has(entry.summary.namespace),\n\t\t\t\t)\n\t\t\t\t.map((entry) => ({ entry, score: terms.length === 0 ? 1 : scoreEntry(entry, terms) }))\n\t\t\t\t.filter(({ score }) => score > 0)\n\t\t\t\t.toSorted((left, right) => {\n\t\t\t\t\tif (right.score !== left.score) {\n\t\t\t\t\t\treturn right.score - left.score;\n\t\t\t\t\t}\n\t\t\t\t\treturn compareSummaries(left.entry.summary, right.entry.summary);\n\t\t\t\t});\n\n\t\t\tconst results = scoredEntries.slice(0, limit).map(({ entry }) => {\n\t\t\t\tconst schemaFieldMatches = entry.inputFields\n\t\t\t\t\t.filter((fieldName) =>\n\t\t\t\t\t\tterms.some((term) => normalizeSearchText(fieldName).includes(term)),\n\t\t\t\t\t)\n\t\t\t\t\t.toSorted();\n\n\t\t\t\treturn withSchemaFieldMatches(entry.summary, schemaFieldMatches);\n\t\t\t});\n\n\t\t\treturn { results };\n\t\t},\n\t};\n}\n","import { portalToolRecordSchema, type PortalToolRecord } from './catalog-types.js';\nimport type { JsonObject } from './json-schema.js';\nimport { encodeToolRef, type ToolIdentity } from './tool-ref.js';\n\nexport type ToolRelationshipType = 'entity' | 'schema-field' | 'skill';\n\nexport interface ToolRelationshipEndpoint extends ToolIdentity {\n\treadonly toolRef: string;\n}\n\nexport interface ToolRelationship {\n\treadonly field?: string;\n\treadonly from: ToolRelationshipEndpoint;\n\treadonly reason: string;\n\treadonly to: ToolRelationshipEndpoint;\n\treadonly type: ToolRelationshipType;\n}\n\nexport interface SkillGraphInput {\n\treadonly description?: string;\n\treadonly tags?: readonly string[];\n\treadonly title: string;\n\treadonly toolRefs: readonly string[];\n}\n\nexport interface ScopedSkillGraphEntry {\n\treadonly description?: string;\n\treadonly tags: readonly string[];\n\treadonly title: string;\n\treadonly toolRefs: readonly string[];\n}\n\nexport interface ToolGraphInput {\n\treadonly skills?: readonly SkillGraphInput[];\n\treadonly tools: readonly PortalToolRecord[];\n}\n\nexport interface ToolGraph {\n\treadonly relationships: readonly ToolRelationship[];\n\treadonly skills: readonly ScopedSkillGraphEntry[];\n}\n\ninterface GraphTool {\n\treadonly entityNames: readonly string[];\n\treadonly inputFields: readonly string[];\n\treadonly outputFields: readonly string[];\n\treadonly record: PortalToolRecord;\n\treadonly ref: ToolRelationshipEndpoint;\n}\n\nconst genericLinkFields = new Set(['id', 'name', 'title', 'url', 'uri']);\n\nfunction compareCodePoint(left: string, right: string): number {\n\tif (left < right) {\n\t\treturn -1;\n\t}\n\tif (left > right) {\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n\nfunction objectPropertiesFromSchema(schema: JsonObject | undefined): readonly string[] {\n\tif (!schema) {\n\t\treturn [];\n\t}\n\n\tconst properties = schema.properties;\n\tif (typeof properties !== 'object' || properties === null || Array.isArray(properties)) {\n\t\treturn [];\n\t}\n\n\treturn Object.keys(properties).toSorted();\n}\n\nfunction collectEntityNames(schema: JsonObject | undefined): readonly string[] {\n\tif (!schema) {\n\t\treturn [];\n\t}\n\n\tconst names: string[] = [];\n\tconst schemaId = schema.$id;\n\tconst title = schema.title;\n\tconst entityName = schema.entityName;\n\tif (typeof schemaId === 'string' && schemaId.length > 0) {\n\t\tnames.push(schemaId);\n\t}\n\tif (typeof title === 'string' && title.length > 0) {\n\t\tnames.push(title);\n\t}\n\tif (typeof entityName === 'string' && entityName.length > 0) {\n\t\tnames.push(entityName);\n\t}\n\n\treturn names.map((name) => name.toLowerCase()).toSorted();\n}\n\nfunction createGraphTool(tool: PortalToolRecord): GraphTool {\n\tconst record = portalToolRecordSchema.parse(tool);\n\tconst toolRef = encodeToolRef({ namespace: record.namespace, toolName: record.toolName });\n\n\treturn {\n\t\tentityNames: [\n\t\t\t...collectEntityNames(record.inputSchema),\n\t\t\t...collectEntityNames(record.outputSchema),\n\t\t].toSorted(),\n\t\tinputFields: objectPropertiesFromSchema(record.inputSchema),\n\t\toutputFields: objectPropertiesFromSchema(record.outputSchema),\n\t\trecord,\n\t\tref: {\n\t\t\tnamespace: record.namespace,\n\t\t\ttoolName: record.toolName,\n\t\t\ttoolRef,\n\t\t},\n\t};\n}\n\nfunction sharesEntity(left: GraphTool, right: GraphTool): boolean {\n\tconst rightEntities = new Set(right.entityNames);\n\treturn left.entityNames.some((entityName) => rightEntities.has(entityName));\n}\n\nfunction shouldLinkField(field: string, fromTool: GraphTool, toTool: GraphTool): boolean {\n\tif (!genericLinkFields.has(field.toLowerCase())) {\n\t\treturn true;\n\t}\n\n\treturn fromTool.record.namespace === toTool.record.namespace && sharesEntity(fromTool, toTool);\n}\n\nfunction createSchemaRelationships(tools: readonly GraphTool[]): readonly ToolRelationship[] {\n\tconst relationships: ToolRelationship[] = [];\n\n\tfor (const fromTool of tools) {\n\t\tfor (const toTool of tools) {\n\t\t\tif (fromTool.ref.toolRef === toTool.ref.toolRef) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst inputFields = new Set(toTool.inputFields);\n\t\t\tfor (const field of fromTool.outputFields) {\n\t\t\t\tif (!inputFields.has(field) || !shouldLinkField(field, fromTool, toTool)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\trelationships.push({\n\t\t\t\t\tfield,\n\t\t\t\t\tfrom: fromTool.ref,\n\t\t\t\t\treason: `Output field \"${field}\" matches input field \"${field}\".`,\n\t\t\t\t\tto: toTool.ref,\n\t\t\t\t\ttype: 'schema-field',\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\treturn relationships;\n}\n\nfunction createEntityRelationships(tools: readonly GraphTool[]): readonly ToolRelationship[] {\n\tconst relationships: ToolRelationship[] = [];\n\tfor (const fromTool of tools) {\n\t\tfor (const toTool of tools) {\n\t\t\tif (fromTool.ref.toolRef === toTool.ref.toolRef || !sharesEntity(fromTool, toTool)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\trelationships.push({\n\t\t\t\tfrom: fromTool.ref,\n\t\t\t\treason: 'Tools declare a shared schema entity through title, $id, or entityName.',\n\t\t\t\tto: toTool.ref,\n\t\t\t\ttype: 'entity',\n\t\t\t});\n\t\t}\n\t}\n\treturn relationships;\n}\n\nfunction createSkillEntries(\n\tskills: readonly SkillGraphInput[],\n\tallowedToolRefs: ReadonlySet<string>,\n): readonly ScopedSkillGraphEntry[] {\n\tconst entries: ScopedSkillGraphEntry[] = [];\n\tfor (const skill of skills) {\n\t\tconst scopedToolRefs = skill.toolRefs\n\t\t\t.filter((toolRef) => allowedToolRefs.has(toolRef))\n\t\t\t.toSorted();\n\t\tif (scopedToolRefs.length === 0) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tentries.push({\n\t\t\t...(skill.description !== undefined ? { description: skill.description } : {}),\n\t\t\ttags: [...(skill.tags ?? [])].toSorted(),\n\t\t\ttitle: skill.title,\n\t\t\ttoolRefs: scopedToolRefs,\n\t\t});\n\t}\n\n\treturn entries.toSorted((left, right) => left.title.localeCompare(right.title));\n}\n\nfunction createSkillRelationships(\n\tskills: readonly ScopedSkillGraphEntry[],\n\ttoolsByRef: ReadonlyMap<string, GraphTool>,\n): readonly ToolRelationship[] {\n\tconst relationships: ToolRelationship[] = [];\n\tfor (const skill of skills) {\n\t\tfor (const fromToolRef of skill.toolRefs) {\n\t\t\tfor (const toToolRef of skill.toolRefs) {\n\t\t\t\tif (fromToolRef === toToolRef) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst fromTool = toolsByRef.get(fromToolRef);\n\t\t\t\tconst toTool = toolsByRef.get(toToolRef);\n\t\t\t\tif (!fromTool || !toTool) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\trelationships.push({\n\t\t\t\t\tfrom: fromTool.ref,\n\t\t\t\t\treason: `Both tools are referenced by skill \"${skill.title}\".`,\n\t\t\t\t\tto: toTool.ref,\n\t\t\t\t\ttype: 'skill',\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\treturn relationships;\n}\n\nfunction compareRelationships(left: ToolRelationship, right: ToolRelationship): number {\n\tconst typeOrder = compareCodePoint(left.type, right.type);\n\tif (typeOrder !== 0) {\n\t\treturn typeOrder;\n\t}\n\n\tconst targetOrder = compareCodePoint(left.to.toolRef, right.to.toolRef);\n\tif (targetOrder !== 0) {\n\t\treturn targetOrder;\n\t}\n\n\treturn compareCodePoint(left.from.toolRef, right.from.toolRef);\n}\n\nexport function buildToolGraph(input: ToolGraphInput): ToolGraph {\n\tconst tools = input.tools\n\t\t.map((tool) => createGraphTool(tool))\n\t\t.toSorted((left, right) => compareCodePoint(left.ref.toolRef, right.ref.toolRef));\n\tconst allowedToolRefs = new Set(tools.map((tool) => tool.ref.toolRef));\n\tconst skills = createSkillEntries(input.skills ?? [], allowedToolRefs);\n\tconst toolsByRef = new Map(tools.map((tool) => [tool.ref.toolRef, tool]));\n\n\treturn {\n\t\trelationships: [\n\t\t\t...createEntityRelationships(tools),\n\t\t\t...createSchemaRelationships(tools),\n\t\t\t...createSkillRelationships(skills, toolsByRef),\n\t\t].toSorted(compareRelationships),\n\t\tskills,\n\t};\n}\n","import { createHash } from 'node:crypto';\n\nimport type { Tool } from '@modelcontextprotocol/sdk/types.js';\n\nimport { portalToolRecordSchema, type PortalToolRecord } from './catalog-types.js';\nimport {\n\tresolvePortalAccessPolicy,\n\tportalAgentScopeKey,\n\ttype PortalAccessPolicyConfig,\n\ttype PortalAgentIdentity,\n\ttype PortalToolSelector,\n} from './portal-access-policy.js';\nimport { createSearchIndex, type SearchIndex } from './search-index.js';\nimport { buildToolGraph, type SkillGraphInput, type ToolGraph } from './tool-graph.js';\nimport {\n\tformatUpstreamMcpFailureMessage,\n\tmessageFromUnknownError,\n\tupstreamMcpFailureDetailsFromUnknown,\n} from './upstream-mcp-errors.js';\n\nexport interface PortalCatalogSnapshot {\n\treadonly agentScopeId: string;\n\treadonly discoveryFailures: readonly PortalDiscoveryFailure[];\n\treadonly generatedAt: string;\n\treadonly sourceHash: string;\n\treadonly tools: readonly PortalToolRecord[];\n}\n\nexport interface PortalDiscoveryFailure {\n\treadonly causeMessage?: string;\n\treadonly elapsedMs?: number;\n\treadonly hint?: string;\n\treadonly kind: string;\n\treadonly message: string;\n\treadonly namespace: string;\n\treadonly operation?: string;\n\treadonly phase?: string;\n\treadonly timeoutMs?: number;\n\treadonly toolName?: string;\n\treadonly transport?: unknown;\n}\n\nexport interface PortalSession {\n\treadonly catalog: PortalCatalogSnapshot;\n\treadonly graph: ToolGraph;\n\treadonly identity: PortalAgentIdentity;\n\treadonly searchIndex: SearchIndex;\n}\n\nexport interface PortalSessionRuntime {\n\treadonly closeAgentScope: (agentScopeId: string) => Promise<void> | void;\n\treadonly closeSession?: (scopeKey: string) => Promise<void> | void;\n\treadonly listTools: (call: {\n\t\treadonly agentScopeId: string;\n\t\treadonly namespace: string;\n\t}) => Promise<readonly Tool[]>;\n}\n\nexport interface PortalSessionManagerOptions {\n\treadonly accessPolicy: PortalAccessPolicyConfig;\n\treadonly catalogTtlMs: number;\n\treadonly discoveryFailures?: readonly PortalDiscoveryFailure[];\n\treadonly now?: () => number;\n\treadonly runtime: PortalSessionRuntime;\n\treadonly skills?: readonly SkillGraphInput[];\n\treadonly upstreamNamespaces: readonly string[];\n}\n\nexport interface PortalSessionManager {\n\treadonly getSession: (identity: PortalAgentIdentity) => Promise<PortalSession>;\n\treadonly invalidateAgentScope: (agentScopeId: string) => Promise<void>;\n\treadonly invalidateSession: (identity: PortalAgentIdentity) => Promise<void>;\n}\n\ninterface CachedPortalSession {\n\treadonly expiresAt: number;\n\treadonly session: PortalSession;\n}\n\nfunction isHiddenTool(tool: PortalToolRecord, hiddenTools: readonly PortalToolSelector[]): boolean {\n\treturn hiddenTools.some(\n\t\t(hiddenTool) =>\n\t\t\thiddenTool.namespace === tool.namespace && hiddenTool.toolName === tool.toolName,\n\t);\n}\n\nfunction isEnabledTool(\n\ttool: PortalToolRecord,\n\tenabledTools: readonly PortalToolSelector[],\n): boolean {\n\tif (enabledTools.length === 0) {\n\t\treturn true;\n\t}\n\treturn enabledTools.some(\n\t\t(enabledTool) =>\n\t\t\tenabledTool.namespace === tool.namespace && enabledTool.toolName === tool.toolName,\n\t);\n}\n\nfunction portalToolFromMcpTool(namespace: string, tool: Tool): PortalToolRecord {\n\treturn portalToolRecordSchema.parse({\n\t\t...(tool.annotations !== undefined ? { annotations: tool.annotations } : {}),\n\t\t...(tool.description !== undefined ? { description: tool.description } : {}),\n\t\tinputSchema: tool.inputSchema,\n\t\tnamespace,\n\t\t...(tool.outputSchema !== undefined ? { outputSchema: tool.outputSchema } : {}),\n\t\t...(tool.title !== undefined ? { title: tool.title } : {}),\n\t\ttoolName: tool.name,\n\t});\n}\n\nfunction createSourceHash(tools: readonly PortalToolRecord[]): string {\n\treturn createHash('sha256').update(JSON.stringify(tools)).digest('hex');\n}\n\nfunction discoveryFailureFromError(namespace: string, error: unknown): PortalDiscoveryFailure {\n\tconst upstreamDetails = upstreamMcpFailureDetailsFromUnknown(error);\n\tif (upstreamDetails !== null) {\n\t\treturn {\n\t\t\t...upstreamDetails,\n\t\t\tmessage: formatUpstreamMcpFailureMessage(upstreamDetails),\n\t\t\tnamespace,\n\t\t};\n\t}\n\treturn {\n\t\tkind: 'upstream_discovery_failed',\n\t\tmessage: messageFromUnknownError(error),\n\t\tnamespace,\n\t};\n}\n\nexport function createPortalSessionManager(\n\toptions: PortalSessionManagerOptions,\n): PortalSessionManager {\n\tconst sessions = new Map<string, CachedPortalSession>();\n\tconst agentScopeGenerations = new Map<string, number>();\n\tconst getNow = options.now ?? (() => Date.now());\n\n\tfunction generationForAgentScope(agentScopeId: string): number {\n\t\treturn agentScopeGenerations.get(agentScopeId) ?? 0;\n\t}\n\n\tfunction incrementAgentScopeGeneration(agentScopeId: string): void {\n\t\tagentScopeGenerations.set(agentScopeId, generationForAgentScope(agentScopeId) + 1);\n\t}\n\n\tfunction generationForScope(scopeKey: string): number {\n\t\tconst agentScopeId = scopeKey.split('\\n', 1)[0] ?? scopeKey;\n\t\treturn (agentScopeGenerations.get(scopeKey) ?? 0) + generationForAgentScope(agentScopeId);\n\t}\n\n\tfunction incrementScopeGeneration(scopeKey: string): void {\n\t\tagentScopeGenerations.set(scopeKey, generationForScope(scopeKey) + 1);\n\t}\n\n\tasync function buildSession(identity: PortalAgentIdentity): Promise<PortalSession> {\n\t\tconst policy = resolvePortalAccessPolicy({\n\t\t\tconfig: options.accessPolicy,\n\t\t\tidentity,\n\t\t\tupstreamNamespaces: options.upstreamNamespaces,\n\t\t});\n\t\tconst tools: PortalToolRecord[] = [];\n\t\tconst discoveryFailures: PortalDiscoveryFailure[] = [...(options.discoveryFailures ?? [])];\n\t\tconst allowedNamespaces = policy.allowedNamespaces;\n\n\t\tconst namespaceToolGroups = await Promise.allSettled(\n\t\t\tallowedNamespaces.map(async (namespace) => ({\n\t\t\t\tmcpTools: await options.runtime.listTools({\n\t\t\t\t\tagentScopeId: portalAgentScopeKey(identity),\n\t\t\t\t\tnamespace,\n\t\t\t\t}),\n\t\t\t\tnamespace,\n\t\t\t})),\n\t\t);\n\t\tfor (const [index, namespaceToolGroup] of namespaceToolGroups.entries()) {\n\t\t\tif (namespaceToolGroup.status === 'rejected') {\n\t\t\t\tconst namespace = allowedNamespaces[index] ?? 'unknown';\n\t\t\t\tdiscoveryFailures.push(discoveryFailureFromError(namespace, namespaceToolGroup.reason));\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst { mcpTools, namespace } = namespaceToolGroup.value;\n\t\t\tfor (const mcpTool of mcpTools) {\n\t\t\t\tconst portalTool = portalToolFromMcpTool(namespace, mcpTool);\n\t\t\t\tif (\n\t\t\t\t\tisEnabledTool(portalTool, policy.enabledTools) &&\n\t\t\t\t\t!isHiddenTool(portalTool, policy.hiddenTools)\n\t\t\t\t) {\n\t\t\t\t\ttools.push(portalTool);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst sortedTools = tools.toSorted((left, right) => {\n\t\t\tconst namespaceOrder = left.namespace.localeCompare(right.namespace);\n\t\t\treturn namespaceOrder === 0 ? left.toolName.localeCompare(right.toolName) : namespaceOrder;\n\t\t});\n\t\tconst graph = buildToolGraph({ skills: options.skills ?? [], tools: sortedTools });\n\t\tconst catalog = {\n\t\t\tagentScopeId: identity.agentScopeId,\n\t\t\tdiscoveryFailures,\n\t\t\tgeneratedAt: new Date(getNow()).toISOString(),\n\t\t\tsourceHash: createSourceHash(sortedTools),\n\t\t\ttools: sortedTools,\n\t\t};\n\n\t\treturn {\n\t\t\tcatalog,\n\t\t\tgraph,\n\t\t\tidentity,\n\t\t\tsearchIndex: createSearchIndex(sortedTools, graph),\n\t\t};\n\t}\n\n\treturn {\n\t\tasync getSession(identity: PortalAgentIdentity): Promise<PortalSession> {\n\t\t\tconst key = portalAgentScopeKey(identity);\n\t\t\tconst now = getNow();\n\t\t\tconst cached = sessions.get(key);\n\t\t\tif (cached && cached.expiresAt > now) {\n\t\t\t\treturn cached.session;\n\t\t\t}\n\n\t\t\tconst generation = generationForScope(key);\n\t\t\tconst session = await buildSession(identity);\n\t\t\tif (\n\t\t\t\tgenerationForScope(key) === generation &&\n\t\t\t\tsession.catalog.discoveryFailures.length === 0\n\t\t\t) {\n\t\t\t\tsessions.set(key, { expiresAt: now + options.catalogTtlMs, session });\n\t\t\t}\n\t\t\treturn session;\n\t\t},\n\t\tasync invalidateAgentScope(agentScopeId: string): Promise<void> {\n\t\t\tincrementAgentScopeGeneration(agentScopeId);\n\t\t\tfor (const key of sessions.keys()) {\n\t\t\t\tif (key === agentScopeId || key.startsWith(`${agentScopeId}\\n`)) {\n\t\t\t\t\tsessions.delete(key);\n\t\t\t\t}\n\t\t\t}\n\t\t\tawait options.runtime.closeAgentScope(agentScopeId);\n\t\t},\n\t\tasync invalidateSession(identity: PortalAgentIdentity): Promise<void> {\n\t\t\tconst scopeKey = portalAgentScopeKey(identity);\n\t\t\tincrementScopeGeneration(scopeKey);\n\t\t\tsessions.delete(scopeKey);\n\t\t\tif (options.runtime.closeSession) {\n\t\t\t\tawait options.runtime.closeSession(scopeKey);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait options.runtime.closeAgentScope(scopeKey);\n\t\t},\n\t};\n}\n","import { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport {\n\tSSEClientTransport,\n\ttype SSEClientTransportOptions,\n} from '@modelcontextprotocol/sdk/client/sse.js';\nimport { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';\nimport {\n\tStreamableHTTPClientTransport,\n\ttype StreamableHTTPClientTransportOptions,\n} from '@modelcontextprotocol/sdk/client/streamableHttp.js';\nimport { normalizeHeaders, type Transport } from '@modelcontextprotocol/sdk/shared/transport.js';\nimport { ToolSchema, type Progress, type Tool } from '@modelcontextprotocol/sdk/types.js';\n\nimport type { JsonObject } from './json-schema.js';\nimport {\n\tcreateUpstreamMcpError,\n\tisUpstreamMcpError,\n\tmessageFromUnknownError,\n\ttransportSummaryFromServer,\n} from './upstream-mcp-errors.js';\nimport {\n\tredactThrownError,\n\tredactUpstreamCatalogValue,\n\tredactUpstreamResponse,\n} from './upstream-response-middleware.js';\n\nexport type UpstreamMcpTransportKind = 'auto-http' | 'sse' | 'stdio' | 'streamable-http';\n\ninterface BaseUpstreamMcpServer {\n\treadonly connectionTimeoutMs?: number;\n\treadonly namespace: string;\n\treadonly transport: UpstreamMcpTransportKind;\n}\n\nexport interface RemoteUpstreamMcpServer extends BaseUpstreamMcpServer {\n\treadonly eventSourceInit?: SSEClientTransportOptions['eventSourceInit'];\n\treadonly headers?: Readonly<Record<string, string>>;\n\treadonly requestInit?: RequestInit;\n\treadonly transport: 'auto-http' | 'sse' | 'streamable-http';\n\treadonly url: string;\n}\n\nexport interface StdioUpstreamMcpServer extends BaseUpstreamMcpServer {\n\treadonly args?: readonly string[];\n\treadonly command: string;\n\treadonly cwd?: string;\n\treadonly env?: Readonly<Record<string, string>>;\n\treadonly transport: 'stdio';\n}\n\nexport type NormalizedUpstreamMcpServer = RemoteUpstreamMcpServer | StdioUpstreamMcpServer;\n\nexport interface ListToolsCall {\n\treadonly agentScopeId: string;\n\treadonly namespace: string;\n}\n\nexport interface UpstreamToolCall {\n\treadonly arguments: JsonObject;\n\treadonly agentScopeId: string;\n\treadonly namespace: string;\n\treadonly onEvent?: (event: UpstreamToolEvent) => Promise<void> | void;\n\treadonly requestId?: string;\n\treadonly signal?: AbortSignal;\n\treadonly toolName: string;\n}\n\nexport type UpstreamToolEvent =\n\t| {\n\t\t\treadonly kind: 'progress';\n\t\t\treadonly message?: string;\n\t\t\treadonly progress: number;\n\t\t\treadonly total?: number;\n\t }\n\t// Extension event for runtimes that can source request-correlated MCP notifications.\n\t// The stock SDK callTool bridge currently emits real progress via RequestOptions.onprogress.\n\t| {\n\t\t\treadonly kind: 'upstream_notification';\n\t\t\treadonly method: string;\n\t\t\treadonly params: unknown;\n\t }\n\t// Extension event for runtimes that can source incremental content before the final result.\n\t| {\n\t\t\treadonly content:\n\t\t\t\t| { readonly text: string; readonly type: 'text' }\n\t\t\t\t| { readonly type: 'json'; readonly value: unknown };\n\t\t\treadonly kind: 'partial_content';\n\t };\n\nexport type UpstreamMcpProgress = Progress;\n\nexport interface UpstreamListToolsResult {\n\treadonly nextCursor?: string | undefined;\n\treadonly tools: readonly Tool[];\n}\n\nexport interface UpstreamMcpClientLike {\n\treadonly callTool: (\n\t\tparams: {\n\t\t\treadonly arguments: JsonObject;\n\t\t\treadonly name: string;\n\t\t},\n\t\tresultSchema?: unknown,\n\t\toptions?: {\n\t\t\treadonly onprogress?: (progress: UpstreamMcpProgress) => void;\n\t\t\treadonly signal?: AbortSignal;\n\t\t},\n\t) => Promise<unknown>;\n\treadonly close: () => Promise<void> | void;\n\treadonly connect: (\n\t\ttransport: unknown,\n\t\toptions?: { readonly signal?: AbortSignal },\n\t) => Promise<void>;\n\treadonly listTools: (\n\t\tparams?: { readonly cursor?: string },\n\t\toptions?: { readonly signal?: AbortSignal },\n\t) => Promise<UpstreamListToolsResult>;\n}\n\nexport interface UpstreamMcpRuntimeOptions {\n\treadonly additionalRedactionValues?: readonly string[];\n\treadonly createClient?: () => UpstreamMcpClientLike;\n\treadonly createTransport?: (\n\t\tserver: NormalizedUpstreamMcpServer,\n\t\ttransport: Exclude<UpstreamMcpTransportKind, 'auto-http'>,\n\t) => unknown;\n\treadonly maxResponseBytes?: number;\n\treadonly onCloseError?: (error: Error, context: UpstreamMcpCloseErrorContext) => void;\n\treadonly servers: readonly NormalizedUpstreamMcpServer[];\n}\n\nexport interface UpstreamMcpCloseErrorContext {\n\treadonly agentScopeId: string;\n\treadonly namespace?: string;\n}\n\nexport interface UpstreamMcpClientRuntime {\n\treadonly callTool: (call: UpstreamToolCall) => Promise<unknown>;\n\treadonly closeAgentScope: (agentScopeId: string) => Promise<void>;\n\treadonly closeSession: (scopeKey: string) => Promise<void>;\n\treadonly listTools: (call: ListToolsCall) => Promise<readonly Tool[]>;\n}\n\ninterface CachedClient {\n\treadonly client: UpstreamMcpClientLike;\n}\n\ninterface PendingClient {\n\treadonly generation: number;\n\treadonly promise: Promise<UpstreamMcpClientLike>;\n}\n\nconst defaultConnectionTimeoutMs = 30_000;\nconst defaultMaxResponseBytes = 4 * 1_024 * 1_024;\nconst inheritedStdioRuntimeEnvNames = [\n\t'NODE_EXTRA_CA_CERTS',\n\t'NODE_OPTIONS',\n\t'REQUESTS_CA_BUNDLE',\n\t'SSL_CERT_FILE',\n\t'UV_CACHE_DIR',\n] as const;\n\nfunction isObjectRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction isTransport(value: unknown): value is Transport {\n\treturn (\n\t\tisObjectRecord(value) &&\n\t\ttypeof value.start === 'function' &&\n\t\ttypeof value.send === 'function' &&\n\t\ttypeof value.close === 'function'\n\t);\n}\n\nfunction createSdkClient(): UpstreamMcpClientLike {\n\tconst client = new Client({ name: 'mcp-portal', version: '1.0.0' });\n\treturn {\n\t\tcallTool: async (params, _resultSchema, options) =>\n\t\t\tawait client.callTool(params, undefined, options),\n\t\tclose: async () => {\n\t\t\tawait client.close();\n\t\t},\n\t\tconnect: async (transport, options) => {\n\t\t\tif (!isTransport(transport)) {\n\t\t\t\tthrow new Error('SDK MCP client requires a valid MCP transport.');\n\t\t\t}\n\t\t\tawait client.connect(transport, options);\n\t\t},\n\t\tlistTools: async (params, options) => {\n\t\t\tconst result = await client.listTools(params, options);\n\t\t\treturn {\n\t\t\t\t...(result.nextCursor !== undefined ? { nextCursor: result.nextCursor } : {}),\n\t\t\t\ttools: result.tools,\n\t\t\t};\n\t\t},\n\t};\n}\n\nfunction inheritedStdioRuntimeEnv(): Readonly<Record<string, string>> {\n\tconst inheritedEnv: Record<string, string> = {};\n\tfor (const name of inheritedStdioRuntimeEnvNames) {\n\t\tconst value = process.env[name];\n\t\tif (value !== undefined && value.length > 0) {\n\t\t\tinheritedEnv[name] = value;\n\t\t}\n\t}\n\treturn inheritedEnv;\n}\n\nfunction withStdioRuntimeEnv(server: NormalizedUpstreamMcpServer): NormalizedUpstreamMcpServer {\n\tif (server.transport !== 'stdio') {\n\t\treturn server;\n\t}\n\n\treturn {\n\t\t...server,\n\t\tenv: { ...inheritedStdioRuntimeEnv(), ...server.env },\n\t};\n}\n\nfunction withRemoteHeaders(server: RemoteUpstreamMcpServer): RemoteUpstreamMcpServer {\n\tif (!server.headers) {\n\t\treturn server;\n\t}\n\n\treturn {\n\t\t...server,\n\t\trequestInit: {\n\t\t\t...server.requestInit,\n\t\t\theaders: {\n\t\t\t\t...normalizeHeaders(server.requestInit?.headers),\n\t\t\t\t...server.headers,\n\t\t\t},\n\t\t},\n\t};\n}\n\nfunction createSdkTransport(\n\tserver: NormalizedUpstreamMcpServer,\n\ttransport: Exclude<UpstreamMcpTransportKind, 'auto-http'>,\n): unknown {\n\tif (transport === 'stdio') {\n\t\tif (server.transport !== 'stdio') {\n\t\t\tthrow new Error('Stdio transport requires stdio server config.');\n\t\t}\n\n\t\treturn new StdioClientTransport({\n\t\t\t...(server.args ? { args: [...server.args] } : {}),\n\t\t\tcommand: server.command,\n\t\t\t...(server.cwd !== undefined ? { cwd: server.cwd } : {}),\n\t\t\t...(server.env ? { env: { ...server.env } } : {}),\n\t\t});\n\t}\n\n\tif (server.transport === 'stdio') {\n\t\tthrow new Error('Remote transport requires remote server config.');\n\t}\n\n\tconst remoteServer = withRemoteHeaders(server);\n\tif (transport === 'sse') {\n\t\tconst options: SSEClientTransportOptions = {};\n\t\tif (remoteServer.eventSourceInit !== undefined) {\n\t\t\toptions.eventSourceInit = remoteServer.eventSourceInit;\n\t\t}\n\t\tif (remoteServer.requestInit !== undefined) {\n\t\t\toptions.requestInit = remoteServer.requestInit;\n\t\t}\n\t\treturn new SSEClientTransport(new URL(remoteServer.url), options);\n\t}\n\n\tconst options: StreamableHTTPClientTransportOptions = {};\n\tif (remoteServer.requestInit !== undefined) {\n\t\toptions.requestInit = remoteServer.requestInit;\n\t}\n\treturn new StreamableHTTPClientTransport(new URL(remoteServer.url), options);\n}\n\nfunction cacheKey(agentScopeId: string, namespace: string): string {\n\treturn `${agentScopeId}\\n${namespace}`;\n}\n\nfunction rootAgentScopeId(agentScopeId: string): string {\n\treturn agentScopeId.split('\\n', 1)[0] ?? agentScopeId;\n}\n\nfunction transportAttempts(\n\tserver: NormalizedUpstreamMcpServer,\n): readonly Exclude<UpstreamMcpTransportKind, 'auto-http'>[] {\n\tif (server.transport === 'auto-http') {\n\t\treturn ['streamable-http', 'sse'];\n\t}\n\n\treturn [server.transport];\n}\n\nfunction redactionValuesFromServer(server: NormalizedUpstreamMcpServer): readonly string[] {\n\tif (server.transport === 'stdio') {\n\t\treturn Object.values(server.env ?? {}).filter((value) => value.length > 0);\n\t}\n\n\treturn Object.values(server.headers ?? {}).filter((value) => value.length > 0);\n}\n\nfunction timeoutMsForServer(server: NormalizedUpstreamMcpServer): number {\n\treturn server.connectionTimeoutMs ?? defaultConnectionTimeoutMs;\n}\n\nfunction elapsedMsSince(startedAt: number): number {\n\treturn Math.max(0, Date.now() - startedAt);\n}\n\nfunction assertUpstreamResponseSize(value: unknown, maxResponseBytes: number): void {\n\tconst serialized = JSON.stringify(value);\n\tif (serialized === undefined) {\n\t\treturn;\n\t}\n\tconst byteLength = Buffer.byteLength(serialized, 'utf8');\n\tif (byteLength > maxResponseBytes) {\n\t\tthrow new Error(\n\t\t\t`MCP upstream response exceeded ${String(maxResponseBytes)} bytes (${String(byteLength)} bytes).`,\n\t\t);\n\t}\n}\n\nfunction isAbortError(error: unknown): boolean {\n\treturn error instanceof Error && error.name === 'AbortError';\n}\n\nfunction isCallerAbortError(error: unknown, signal: AbortSignal | undefined): boolean {\n\treturn signal?.aborted === true && (error === signal.reason || isAbortError(error));\n}\n\nasync function withTimeout<TResult>(\n\tpromise: Promise<TResult>,\n\tprops: {\n\t\treadonly onTimeout?: (error: Error) => void;\n\t\treadonly operation: string;\n\t\treadonly timeoutMs: number;\n\t},\n): Promise<TResult> {\n\tlet timeout: NodeJS.Timeout | undefined;\n\ttry {\n\t\treturn await Promise.race([\n\t\t\tpromise,\n\t\t\tnew Promise<never>((_resolve, reject) => {\n\t\t\t\ttimeout = setTimeout(() => {\n\t\t\t\t\tconst error = new Error(`${props.operation} timed out after ${props.timeoutMs}ms.`);\n\t\t\t\t\tprops.onTimeout?.(error);\n\t\t\t\t\treject(error);\n\t\t\t\t}, props.timeoutMs);\n\t\t\t}),\n\t\t]);\n\t} finally {\n\t\tif (timeout) {\n\t\t\tclearTimeout(timeout);\n\t\t}\n\t}\n}\n\nfunction createRuntimeAbortSignal(parentSignal: AbortSignal | undefined): {\n\treadonly abortTimeout: (error: Error) => void;\n\treadonly dispose: () => void;\n\treadonly signal: AbortSignal;\n} {\n\tconst controller = new AbortController();\n\tconst abortFromParent = (): void => {\n\t\tif (!controller.signal.aborted) {\n\t\t\tcontroller.abort(parentSignal?.reason);\n\t\t}\n\t};\n\tif (parentSignal?.aborted) {\n\t\tabortFromParent();\n\t} else {\n\t\tparentSignal?.addEventListener('abort', abortFromParent, { once: true });\n\t}\n\n\treturn {\n\t\tabortTimeout: (error) => {\n\t\t\tif (!controller.signal.aborted) {\n\t\t\t\tcontroller.abort(error);\n\t\t\t}\n\t\t},\n\t\tdispose: () => {\n\t\t\tparentSignal?.removeEventListener('abort', abortFromParent);\n\t\t},\n\t\tsignal: controller.signal,\n\t};\n}\n\nasync function listAllTools(\n\tclient: UpstreamMcpClientLike,\n\tcursor: string | undefined,\n\tcollectedTools: readonly Tool[],\n\ttimeoutAbort: {\n\t\treadonly abortTimeout: (error: Error) => void;\n\t\treadonly signal: AbortSignal;\n\t},\n\ttimeoutMs: number,\n): Promise<readonly Tool[]> {\n\tconst result = await withTimeout(\n\t\tclient.listTools(cursor ? { cursor } : undefined, { signal: timeoutAbort.signal }),\n\t\t{\n\t\t\tonTimeout: timeoutAbort.abortTimeout,\n\t\t\toperation: 'MCP listTools',\n\t\t\ttimeoutMs,\n\t\t},\n\t);\n\tconst nextTools = [...collectedTools, ...result.tools];\n\treturn result.nextCursor\n\t\t? listAllTools(client, result.nextCursor, nextTools, timeoutAbort, timeoutMs)\n\t\t: nextTools;\n}\n\nasync function closeClientAfterFailure(client: UpstreamMcpClientLike | null): Promise<void> {\n\tif (!client) {\n\t\treturn;\n\t}\n\ttry {\n\t\tawait client.close();\n\t} catch {\n\t\t// Preserve the original upstream failure; close errors are best-effort cleanup.\n\t}\n}\n\nasync function closeClientForTeardown(\n\tclient: UpstreamMcpClientLike | null,\n\tprops: {\n\t\treadonly context: UpstreamMcpCloseErrorContext;\n\t\treadonly onCloseError?:\n\t\t\t| ((error: Error, context: UpstreamMcpCloseErrorContext) => void)\n\t\t\t| undefined;\n\t},\n): Promise<void> {\n\tif (!client) {\n\t\treturn;\n\t}\n\ttry {\n\t\tawait client.close();\n\t} catch (error) {\n\t\tprops.onCloseError?.(redactThrownError(error), props.context);\n\t}\n}\n\nfunction closeErrorContextFromCacheKey(cacheKeyValue: string): UpstreamMcpCloseErrorContext {\n\tconst keyParts = cacheKeyValue.split('\\n');\n\tconst namespace = keyParts.length > 1 ? keyParts[keyParts.length - 1] : undefined;\n\tconst agentScopeId =\n\t\tnamespace !== undefined ? keyParts.slice(0, keyParts.length - 1).join('\\n') : cacheKeyValue;\n\treturn {\n\t\tagentScopeId,\n\t\t...(namespace !== undefined ? { namespace } : {}),\n\t};\n}\n\nfunction redactToolCatalog(\n\ttools: readonly Tool[],\n\toptions: { readonly exactValues: readonly string[] },\n): readonly Tool[] {\n\treturn tools.map((tool) => ToolSchema.parse(redactUpstreamCatalogValue(tool, options)));\n}\n\nexport function createUpstreamMcpClientRuntime(\n\toptions: UpstreamMcpRuntimeOptions,\n): UpstreamMcpClientRuntime {\n\tconst serversByNamespace = new Map(options.servers.map((server) => [server.namespace, server]));\n\tconst clients = new Map<string, CachedClient>();\n\tconst pendingClients = new Map<string, PendingClient>();\n\tconst agentScopeGenerations = new Map<string, number>();\n\tconst closedClients = new WeakSet<UpstreamMcpClientLike>();\n\tconst createClient = options.createClient ?? createSdkClient;\n\tconst createTransport = options.createTransport ?? createSdkTransport;\n\tconst maxResponseBytes = options.maxResponseBytes ?? defaultMaxResponseBytes;\n\tconst redactionValues = [\n\t\t...(options.additionalRedactionValues ?? []),\n\t\t...options.servers.flatMap((server) => redactionValuesFromServer(server)),\n\t];\n\n\tfunction generationForAgentScope(agentScopeId: string): number {\n\t\treturn (\n\t\t\tagentScopeGenerations.get(agentScopeId) ??\n\t\t\tagentScopeGenerations.get(rootAgentScopeId(agentScopeId)) ??\n\t\t\t0\n\t\t);\n\t}\n\n\tfunction incrementAgentScopeGeneration(agentScopeId: string): void {\n\t\tconst rootAgentScope = rootAgentScopeId(agentScopeId);\n\t\tagentScopeGenerations.set(rootAgentScope, (agentScopeGenerations.get(rootAgentScope) ?? 0) + 1);\n\t}\n\n\tfunction incrementScopeGeneration(scopeKey: string): void {\n\t\tagentScopeGenerations.set(scopeKey, (agentScopeGenerations.get(scopeKey) ?? 0) + 1);\n\t}\n\n\tasync function closeClientAfterFailureOnce(client: UpstreamMcpClientLike | null): Promise<void> {\n\t\tif (!client || closedClients.has(client)) {\n\t\t\treturn;\n\t\t}\n\t\tclosedClients.add(client);\n\t\tawait closeClientAfterFailure(client);\n\t}\n\n\tasync function closeClientForTeardownOnce(\n\t\tclient: UpstreamMcpClientLike | null,\n\t\tcontext: UpstreamMcpCloseErrorContext,\n\t): Promise<void> {\n\t\tif (!client || closedClients.has(client)) {\n\t\t\treturn;\n\t\t}\n\t\tclosedClients.add(client);\n\t\tawait closeClientForTeardown(client, {\n\t\t\tcontext,\n\t\t\tonCloseError: options.onCloseError,\n\t\t});\n\t}\n\n\tasync function createConnectedClient(\n\t\tserver: NormalizedUpstreamMcpServer,\n\t): Promise<UpstreamMcpClientLike> {\n\t\tconst attempts = transportAttempts(server);\n\t\tasync function tryAttempt(\n\t\t\tattemptIndex: number,\n\t\t\tlastError: Error | null,\n\t\t): Promise<UpstreamMcpClientLike> {\n\t\t\tconst transportKind = attempts[attemptIndex];\n\t\t\tif (transportKind === undefined) {\n\t\t\t\tthrow (\n\t\t\t\t\tlastError ??\n\t\t\t\t\tnew Error(`Could not connect to upstream MCP namespace \"${server.namespace}\".`)\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst client = createClient();\n\t\t\tconst transportServer =\n\t\t\t\ttransportKind === 'sse' && server.transport !== 'stdio'\n\t\t\t\t\t? withRemoteHeaders(server)\n\t\t\t\t\t: withStdioRuntimeEnv(server);\n\t\t\tconst transport = createTransport(transportServer, transportKind);\n\t\t\tconst timeoutAbort = createRuntimeAbortSignal(undefined);\n\t\t\tconst startedAt = Date.now();\n\t\t\ttry {\n\t\t\t\tawait withTimeout(client.connect(transport, { signal: timeoutAbort.signal }), {\n\t\t\t\t\tonTimeout: timeoutAbort.abortTimeout,\n\t\t\t\t\toperation: `MCP ${transportKind} connect for namespace \"${server.namespace}\"`,\n\t\t\t\t\ttimeoutMs: timeoutMsForServer(server),\n\t\t\t\t});\n\t\t\t\treturn client;\n\t\t\t} catch (error) {\n\t\t\t\tconst redactedError = redactThrownError(error, { exactValues: redactionValues });\n\t\t\t\tawait closeClientAfterFailureOnce(client);\n\t\t\t\tconst structuredError = createUpstreamMcpError({\n\t\t\t\t\tattemptTransport: transportKind,\n\t\t\t\t\tcauseMessage: messageFromUnknownError(redactedError),\n\t\t\t\t\telapsedMs: elapsedMsSince(startedAt),\n\t\t\t\t\tnamespace: server.namespace,\n\t\t\t\t\toperation: `MCP ${transportKind} connect for namespace \"${server.namespace}\"`,\n\t\t\t\t\tphase: 'connect',\n\t\t\t\t\ttimeoutMs: timeoutMsForServer(server),\n\t\t\t\t\ttransport: transportSummaryFromServer(server, transportKind),\n\t\t\t\t});\n\t\t\t\treturn tryAttempt(attemptIndex + 1, structuredError);\n\t\t\t} finally {\n\t\t\t\ttimeoutAbort.dispose();\n\t\t\t}\n\t\t}\n\n\t\treturn tryAttempt(0, null);\n\t}\n\n\tasync function getClient(\n\t\tagentScopeId: string,\n\t\tnamespace: string,\n\t): Promise<UpstreamMcpClientLike> {\n\t\tconst key = cacheKey(agentScopeId, namespace);\n\t\tconst cachedClient = clients.get(key);\n\t\tif (cachedClient) {\n\t\t\treturn cachedClient.client;\n\t\t}\n\t\tconst pendingClient = pendingClients.get(key);\n\t\tconst generation = generationForAgentScope(agentScopeId);\n\t\tif (pendingClient && pendingClient.generation === generation) {\n\t\t\treturn pendingClient.promise;\n\t\t}\n\t\tif (pendingClient) {\n\t\t\tpendingClients.delete(key);\n\t\t\tvoid pendingClient.promise.then(closeClientAfterFailureOnce, () => undefined);\n\t\t}\n\n\t\tconst server = serversByNamespace.get(namespace);\n\t\tif (!server) {\n\t\t\tthrow new Error(`Unknown upstream MCP namespace \"${namespace}\".`);\n\t\t}\n\n\t\tconst pending = createConnectedClient(server);\n\t\tconst pendingRecord = { generation, promise: pending } satisfies PendingClient;\n\t\tpendingClients.set(key, pendingRecord);\n\t\ttry {\n\t\t\tconst client = await pending;\n\t\t\tif (generationForAgentScope(agentScopeId) !== generation) {\n\t\t\t\tawait closeClientAfterFailureOnce(client);\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`MCP client for agent scope \"${rootAgentScopeId(agentScopeId)}\" was invalidated.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tclients.set(key, { client });\n\t\t\tif (generationForAgentScope(agentScopeId) !== generation) {\n\t\t\t\tif (clients.get(key)?.client === client) {\n\t\t\t\t\tclients.delete(key);\n\t\t\t\t}\n\t\t\t\tawait closeClientAfterFailureOnce(client);\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`MCP client for agent scope \"${rootAgentScopeId(agentScopeId)}\" was invalidated.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn client;\n\t\t} finally {\n\t\t\tif (pendingClients.get(key) === pendingRecord) {\n\t\t\t\tpendingClients.delete(key);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tasync callTool(call: UpstreamToolCall): Promise<unknown> {\n\t\t\tconst key = cacheKey(call.agentScopeId, call.namespace);\n\t\t\tlet client: UpstreamMcpClientLike | null = null;\n\t\t\tconst startedAt = Date.now();\n\t\t\ttry {\n\t\t\t\tclient = await getClient(call.agentScopeId, call.namespace);\n\t\t\t\tconst server = serversByNamespace.get(call.namespace);\n\t\t\t\tconst timeoutAbort = createRuntimeAbortSignal(call.signal);\n\t\t\t\ttry {\n\t\t\t\t\tconst upstreamResult = await withTimeout(\n\t\t\t\t\t\tclient.callTool({ arguments: call.arguments, name: call.toolName }, undefined, {\n\t\t\t\t\t\t\tonprogress: (progress) => {\n\t\t\t\t\t\t\t\tvoid call.onEvent?.({\n\t\t\t\t\t\t\t\t\tkind: 'progress',\n\t\t\t\t\t\t\t\t\t...(progress.message !== undefined ? { message: progress.message } : {}),\n\t\t\t\t\t\t\t\t\tprogress: progress.progress,\n\t\t\t\t\t\t\t\t\t...(progress.total !== undefined ? { total: progress.total } : {}),\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tsignal: timeoutAbort.signal,\n\t\t\t\t\t\t}),\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tonTimeout: timeoutAbort.abortTimeout,\n\t\t\t\t\t\t\toperation: `MCP callTool ${call.namespace}.${call.toolName}`,\n\t\t\t\t\t\t\ttimeoutMs: server ? timeoutMsForServer(server) : defaultConnectionTimeoutMs,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t\tassertUpstreamResponseSize(upstreamResult, maxResponseBytes);\n\t\t\t\t\treturn redactUpstreamResponse(upstreamResult, { exactValues: redactionValues });\n\t\t\t\t} finally {\n\t\t\t\t\ttimeoutAbort.dispose();\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tif (isCallerAbortError(error, call.signal)) {\n\t\t\t\t\tthrow redactThrownError(error, { exactValues: redactionValues });\n\t\t\t\t}\n\t\t\t\tclients.delete(key);\n\t\t\t\tawait closeClientAfterFailureOnce(client);\n\t\t\t\tif (isUpstreamMcpError(error)) {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tconst redactedError = redactThrownError(error, { exactValues: redactionValues });\n\t\t\t\tconst server = serversByNamespace.get(call.namespace);\n\t\t\t\tif (server !== undefined) {\n\t\t\t\t\tthrow createUpstreamMcpError({\n\t\t\t\t\t\tcauseMessage: messageFromUnknownError(redactedError),\n\t\t\t\t\t\telapsedMs: elapsedMsSince(startedAt),\n\t\t\t\t\t\tnamespace: call.namespace,\n\t\t\t\t\t\toperation: `MCP callTool ${call.namespace}.${call.toolName}`,\n\t\t\t\t\t\tphase: 'call_tool',\n\t\t\t\t\t\ttimeoutMs: timeoutMsForServer(server),\n\t\t\t\t\t\ttoolName: call.toolName,\n\t\t\t\t\t\ttransport: transportSummaryFromServer(server),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tthrow redactedError;\n\t\t\t}\n\t\t},\n\t\tasync closeAgentScope(agentScopeId: string): Promise<void> {\n\t\t\tincrementAgentScopeGeneration(agentScopeId);\n\t\t\tconst closePromises: Promise<void>[] = [];\n\t\t\tfor (const [key, cachedClient] of clients.entries()) {\n\t\t\t\tif (key !== agentScopeId && !key.startsWith(`${agentScopeId}\\n`)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tclients.delete(key);\n\t\t\t\tclosePromises.push(\n\t\t\t\t\tcloseClientForTeardownOnce(cachedClient.client, closeErrorContextFromCacheKey(key)),\n\t\t\t\t);\n\t\t\t}\n\t\t\tfor (const [key, pendingClient] of pendingClients.entries()) {\n\t\t\t\tif (key !== agentScopeId && !key.startsWith(`${agentScopeId}\\n`)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tpendingClients.delete(key);\n\t\t\t\tclosePromises.push(\n\t\t\t\t\tpendingClient.promise.then(\n\t\t\t\t\t\t(client) => closeClientForTeardownOnce(client, closeErrorContextFromCacheKey(key)),\n\t\t\t\t\t\t() => undefined,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t\tawait Promise.all(closePromises);\n\t\t},\n\t\tasync closeSession(scopeKey: string): Promise<void> {\n\t\t\tincrementScopeGeneration(scopeKey);\n\t\t\tconst closePromises: Promise<void>[] = [];\n\t\t\tfor (const [key, cachedClient] of clients.entries()) {\n\t\t\t\tif (key !== scopeKey && !key.startsWith(`${scopeKey}\\n`)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tclients.delete(key);\n\t\t\t\tclosePromises.push(\n\t\t\t\t\tcloseClientForTeardownOnce(cachedClient.client, closeErrorContextFromCacheKey(key)),\n\t\t\t\t);\n\t\t\t}\n\t\t\tfor (const [key, pendingClient] of pendingClients.entries()) {\n\t\t\t\tif (key !== scopeKey && !key.startsWith(`${scopeKey}\\n`)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tpendingClients.delete(key);\n\t\t\t\tclosePromises.push(\n\t\t\t\t\tpendingClient.promise.then(\n\t\t\t\t\t\t(client) => closeClientForTeardownOnce(client, closeErrorContextFromCacheKey(key)),\n\t\t\t\t\t\t() => undefined,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t\tawait Promise.all(closePromises);\n\t\t},\n\t\tasync listTools(call: ListToolsCall): Promise<readonly Tool[]> {\n\t\t\tconst key = cacheKey(call.agentScopeId, call.namespace);\n\t\t\tlet client: UpstreamMcpClientLike | null = null;\n\t\t\tconst startedAt = Date.now();\n\t\t\ttry {\n\t\t\t\tclient = await getClient(call.agentScopeId, call.namespace);\n\t\t\t\tconst server = serversByNamespace.get(call.namespace);\n\t\t\t\tconst timeoutAbort = createRuntimeAbortSignal(undefined);\n\t\t\t\ttry {\n\t\t\t\t\treturn redactToolCatalog(\n\t\t\t\t\t\tawait listAllTools(\n\t\t\t\t\t\t\tclient,\n\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\t[],\n\t\t\t\t\t\t\ttimeoutAbort,\n\t\t\t\t\t\t\tserver ? timeoutMsForServer(server) : defaultConnectionTimeoutMs,\n\t\t\t\t\t\t),\n\t\t\t\t\t\t{ exactValues: redactionValues },\n\t\t\t\t\t);\n\t\t\t\t} finally {\n\t\t\t\t\ttimeoutAbort.dispose();\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tclients.delete(key);\n\t\t\t\tawait closeClientAfterFailureOnce(client);\n\t\t\t\tif (isUpstreamMcpError(error)) {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tconst redactedError = redactThrownError(error, { exactValues: redactionValues });\n\t\t\t\tconst server = serversByNamespace.get(call.namespace);\n\t\t\t\tif (server !== undefined) {\n\t\t\t\t\tthrow createUpstreamMcpError({\n\t\t\t\t\t\tcauseMessage: messageFromUnknownError(redactedError),\n\t\t\t\t\t\telapsedMs: elapsedMsSince(startedAt),\n\t\t\t\t\t\tnamespace: call.namespace,\n\t\t\t\t\t\toperation: 'MCP listTools',\n\t\t\t\t\t\tphase: 'list_tools',\n\t\t\t\t\t\ttimeoutMs: timeoutMsForServer(server),\n\t\t\t\t\t\ttransport: transportSummaryFromServer(server),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tthrow redactedError;\n\t\t\t}\n\t\t},\n\t};\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upstream-response-middleware-1MZnAD9C.d.ts","names":[],"sources":["../src/upstream-mcp-client-runtime.ts","../src/upstream-response-middleware.ts"],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"upstream-response-middleware-1MZnAD9C.d.ts","names":[],"sources":["../src/upstream-mcp-client-runtime.ts","../src/upstream-response-middleware.ts"],"mappings":"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"}
|
package/dist/{upstream-response-middleware-BjUWZ2G8.js → upstream-response-middleware-CpMgDGMh.js}
RENAMED
|
@@ -88,6 +88,57 @@ function createToolSummary(tool) {
|
|
|
88
88
|
};
|
|
89
89
|
}
|
|
90
90
|
//#endregion
|
|
91
|
+
//#region src/upstream-mcp-errors.ts
|
|
92
|
+
var UpstreamMcpError = class extends Error {
|
|
93
|
+
details;
|
|
94
|
+
constructor(details) {
|
|
95
|
+
super(formatUpstreamMcpFailureMessage(details));
|
|
96
|
+
this.name = "UpstreamMcpError";
|
|
97
|
+
this.details = details;
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
function messageFromUnknownError(error) {
|
|
101
|
+
if (error instanceof Error) return error.message;
|
|
102
|
+
if (typeof error === "string") return error;
|
|
103
|
+
return String(error);
|
|
104
|
+
}
|
|
105
|
+
function isUpstreamMcpError(error) {
|
|
106
|
+
return error instanceof UpstreamMcpError;
|
|
107
|
+
}
|
|
108
|
+
function transportSummaryFromServer(server, attemptTransport) {
|
|
109
|
+
if (server.transport === "stdio") return {
|
|
110
|
+
argCount: server.args?.length ?? 0,
|
|
111
|
+
command: server.command,
|
|
112
|
+
...server.cwd !== void 0 ? { cwd: server.cwd } : {},
|
|
113
|
+
kind: "stdio"
|
|
114
|
+
};
|
|
115
|
+
return {
|
|
116
|
+
kind: attemptTransport === "sse" ? "sse" : "streamable-http",
|
|
117
|
+
url: server.url
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
function hintForFailure(details) {
|
|
121
|
+
if (details.phase === "connect" && details.transport.kind === "stdio") return "stdio MCP command failed before tool discovery; verify command, package bin name, gateway PATH, and arg count.";
|
|
122
|
+
if (details.phase === "connect" && details.transport.kind !== "stdio") return "remote MCP connection failed; verify URL, auth header, network egress, and transport kind.";
|
|
123
|
+
if (details.phase === "list_tools") return "MCP provider connected but tool discovery failed; run agent-vm validate --mcp-live for the configured namespace.";
|
|
124
|
+
if (details.phase === "call_tool") return "MCP provider accepted discovery but the tool call failed; inspect the tool arguments and upstream provider response.";
|
|
125
|
+
}
|
|
126
|
+
function createUpstreamMcpError(details) {
|
|
127
|
+
const hint = hintForFailure(details);
|
|
128
|
+
return new UpstreamMcpError({
|
|
129
|
+
...details,
|
|
130
|
+
...hint !== void 0 ? { hint } : {},
|
|
131
|
+
kind: "upstream_mcp_failed"
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
function upstreamMcpFailureDetailsFromUnknown(error) {
|
|
135
|
+
return isUpstreamMcpError(error) ? error.details : null;
|
|
136
|
+
}
|
|
137
|
+
function formatUpstreamMcpFailureMessage(details) {
|
|
138
|
+
const toolSuffix = details.toolName === void 0 ? "" : ` ${details.toolName}`;
|
|
139
|
+
return `${details.namespace}: ${details.phase}${toolSuffix} failed: ${details.causeMessage}`;
|
|
140
|
+
}
|
|
141
|
+
//#endregion
|
|
91
142
|
//#region src/upstream-response-middleware.ts
|
|
92
143
|
const credentialPatterns = [
|
|
93
144
|
/\bBearer\s+[A-Za-z0-9._~+/=-]+/gi,
|
|
@@ -167,6 +218,6 @@ function toRedactedJsonValue(value, options = {}) {
|
|
|
167
218
|
return null;
|
|
168
219
|
}
|
|
169
220
|
//#endregion
|
|
170
|
-
export { redactUpstreamCatalogValue as a,
|
|
221
|
+
export { createPortalAgentIdentity as _, redactUpstreamCatalogValue as a, UpstreamMcpError as c, isUpstreamMcpError as d, messageFromUnknownError as f, summarizeJsonSchema as g, createToolSummary as h, redactThrownError as i, createUpstreamMcpError as l, upstreamMcpFailureDetailsFromUnknown as m, redactCredentialText as n, redactUpstreamResponse as o, transportSummaryFromServer as p, redactExactCredentialText as r, toRedactedJsonValue as s, isCredentialConfigKey as t, formatUpstreamMcpFailureMessage as u, portalAgentScopeKey as v, resolvePortalAccessPolicy as y };
|
|
171
222
|
|
|
172
|
-
//# sourceMappingURL=upstream-response-middleware-
|
|
223
|
+
//# sourceMappingURL=upstream-response-middleware-CpMgDGMh.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upstream-response-middleware-CpMgDGMh.js","names":[],"sources":["../src/portal-access-policy.ts","../src/tool-summary.ts","../src/upstream-mcp-errors.ts","../src/upstream-response-middleware.ts"],"sourcesContent":["const portalAgentIdentityBrand = Symbol('PortalAgentIdentity');\n\nexport type PortalAgentIdentity = {\n\treadonly agentId: string;\n\t// `agentScopeId` is the upstream session/cache boundary. Most current adapters scope it\n\t// per agent, but the core keeps it separate so a future adapter can isolate per session\n\t// without changing the authorization identity.\n\treadonly agentScopeId: string;\n\treadonly authSubject?: string;\n\treadonly sessionId?: string;\n\treadonly sessionKey?: string;\n\treadonly source: PortalAgentScopeSource;\n\treadonly [portalAgentIdentityBrand]: true;\n};\n\nexport type PortalAgentScopeSource = 'cli-operator' | 'mcp-proxy-bearer' | 'openclaw-trusted';\n\nexport interface PortalToolSelector {\n\treadonly namespace: string;\n\treadonly toolName: string;\n}\n\nexport type PortalDefaultPolicy = 'allow-all' | 'deny-all';\n\nexport interface PortalAccessPolicyConfig {\n\treadonly defaultPolicy?: PortalDefaultPolicy;\n\treadonly enabledNamespaces?: readonly string[];\n\treadonly enabledNamespacesByAgent: Readonly<Record<string, readonly string[]>>;\n\treadonly enabledToolsByAgent?: Readonly<Record<string, readonly PortalToolSelector[]>>;\n\treadonly hiddenToolsByAgent: Readonly<Record<string, readonly PortalToolSelector[]>>;\n}\n\nexport interface ResolvedPortalAccessPolicy {\n\treadonly allowedNamespaces: readonly string[];\n\treadonly enabledTools: readonly PortalToolSelector[];\n\treadonly hiddenTools: readonly PortalToolSelector[];\n}\n\nexport function createPortalAgentIdentity(input: {\n\treadonly agentId: string;\n\treadonly agentScopeId: string;\n\treadonly authSubject?: string;\n\treadonly sessionId?: string;\n\treadonly sessionKey?: string;\n\treadonly source: PortalAgentScopeSource;\n}): PortalAgentIdentity {\n\tvalidateIdentitySegment('agentId', input.agentId);\n\tvalidateIdentitySegment('agentScopeId', input.agentScopeId);\n\tif (input.sessionId !== undefined) {\n\t\tvalidateIdentitySegment('sessionId', input.sessionId);\n\t}\n\tif (input.sessionKey !== undefined) {\n\t\tvalidateIdentitySegment('sessionKey', input.sessionKey);\n\t}\n\tif (input.authSubject !== undefined) {\n\t\tvalidateIdentitySegment('authSubject', input.authSubject);\n\t}\n\treturn {\n\t\tagentId: input.agentId,\n\t\tagentScopeId: input.agentScopeId,\n\t\t...(input.authSubject !== undefined ? { authSubject: input.authSubject } : {}),\n\t\t...(input.sessionId !== undefined ? { sessionId: input.sessionId } : {}),\n\t\t...(input.sessionKey !== undefined ? { sessionKey: input.sessionKey } : {}),\n\t\tsource: input.source,\n\t\t[portalAgentIdentityBrand]: true,\n\t};\n}\n\nfunction validateIdentitySegment(name: string, value: string): void {\n\tif (value.length === 0) {\n\t\tthrow new Error(`MCP Portal ${name} must not be empty.`);\n\t}\n\tfor (let index = 0; index < value.length; index += 1) {\n\t\tconst codePoint = value.charCodeAt(index);\n\t\tif (codePoint < 32 || codePoint === 127 || codePoint === 0x2028 || codePoint === 0x2029) {\n\t\t\tthrow new Error(`MCP Portal ${name} must not contain control characters.`);\n\t\t}\n\t}\n}\n\nexport function portalAgentScopeKey(identity: PortalAgentIdentity): string {\n\tconst sessionScope = identity.sessionId ?? identity.sessionKey;\n\treturn sessionScope ? `${identity.agentScopeId}\\n${sessionScope}` : identity.agentScopeId;\n}\n\nfunction sortToolSelectors(\n\tselectors: readonly PortalToolSelector[],\n): readonly PortalToolSelector[] {\n\treturn [...selectors].toSorted((left, right) => {\n\t\tconst namespaceOrder = left.namespace.localeCompare(right.namespace);\n\t\treturn namespaceOrder === 0 ? left.toolName.localeCompare(right.toolName) : namespaceOrder;\n\t});\n}\n\nexport function resolvePortalAccessPolicy(props: {\n\treadonly config: PortalAccessPolicyConfig;\n\treadonly identity: PortalAgentIdentity;\n\treadonly upstreamNamespaces: readonly string[];\n}): ResolvedPortalAccessPolicy {\n\tconst agentNamespaces = props.config.enabledNamespacesByAgent[props.identity.agentId];\n\tconst globalNamespaces = props.config.enabledNamespaces;\n\tconst selectedNamespaces =\n\t\tagentNamespaces ??\n\t\tglobalNamespaces ??\n\t\t(props.config.defaultPolicy === 'allow-all' ? props.upstreamNamespaces : []);\n\tconst upstreamNamespaceSet = new Set(props.upstreamNamespaces);\n\n\treturn {\n\t\tallowedNamespaces: selectedNamespaces\n\t\t\t.filter((namespace) => upstreamNamespaceSet.has(namespace))\n\t\t\t.toSorted(),\n\t\tenabledTools: sortToolSelectors(\n\t\t\tprops.config.enabledToolsByAgent?.[props.identity.agentId] ?? [],\n\t\t),\n\t\thiddenTools: sortToolSelectors(props.config.hiddenToolsByAgent[props.identity.agentId] ?? []),\n\t};\n}\n","import { portalToolRecordSchema, type PortalToolRecord } from './catalog-types.js';\nimport type { JsonObject } from './json-schema.js';\nimport { encodeToolRef } from './tool-ref.js';\n\nexport interface ToolSchemaSummary {\n\treadonly optional: readonly string[];\n\treadonly propertyCount: number;\n\treadonly required: readonly string[];\n\treadonly type: string;\n}\n\nexport interface ToolSafetySummary {\n\treadonly destructiveHint?: boolean;\n\treadonly readOnlyHint?: boolean;\n}\n\nexport type ToolSchemaHintNext = 'call_ready' | 'describe_before_call';\n\nexport interface ToolSchemaHint {\n\treadonly message: string;\n\treadonly next: ToolSchemaHintNext;\n}\n\nexport interface ToolSummary {\n\treadonly description?: string;\n\treadonly input: ToolSchemaSummary;\n\treadonly namespace: string;\n\treadonly output?: ToolSchemaSummary;\n\treadonly safety: ToolSafetySummary;\n\treadonly schemaHint?: ToolSchemaHint;\n\treadonly title?: string;\n\treadonly toolName: string;\n\treadonly toolRef: string;\n}\n\nfunction stringArrayFromValue(value: unknown): readonly string[] {\n\tif (!Array.isArray(value)) {\n\t\treturn [];\n\t}\n\n\treturn value.filter((entry): entry is string => typeof entry === 'string').toSorted();\n}\n\nfunction objectPropertiesFromSchema(schema: JsonObject): readonly string[] {\n\tconst properties = schema.properties;\n\tif (typeof properties !== 'object' || properties === null || Array.isArray(properties)) {\n\t\treturn [];\n\t}\n\n\treturn Object.keys(properties).toSorted();\n}\n\nexport function summarizeJsonSchema(schema: JsonObject): ToolSchemaSummary {\n\tconst properties = objectPropertiesFromSchema(schema);\n\tconst required = stringArrayFromValue(schema.required);\n\tconst requiredSet = new Set(required);\n\tconst optional = properties.filter((propertyName) => !requiredSet.has(propertyName));\n\n\treturn {\n\t\toptional,\n\t\tpropertyCount: properties.length,\n\t\trequired,\n\t\ttype: typeof schema.type === 'string' ? schema.type : 'unknown',\n\t};\n}\n\nexport function createToolSummary(tool: PortalToolRecord): ToolSummary {\n\tconst parsed = portalToolRecordSchema.parse(tool);\n\tconst safety = {\n\t\t...(parsed.annotations?.destructiveHint !== undefined\n\t\t\t? { destructiveHint: parsed.annotations.destructiveHint }\n\t\t\t: {}),\n\t\t...(parsed.annotations?.readOnlyHint !== undefined\n\t\t\t? { readOnlyHint: parsed.annotations.readOnlyHint }\n\t\t\t: {}),\n\t};\n\n\treturn {\n\t\t...(parsed.description !== undefined ? { description: parsed.description } : {}),\n\t\tinput: summarizeJsonSchema(parsed.inputSchema),\n\t\tnamespace: parsed.namespace,\n\t\t...(parsed.outputSchema ? { output: summarizeJsonSchema(parsed.outputSchema) } : {}),\n\t\tsafety,\n\t\t...(parsed.title !== undefined ? { title: parsed.title } : {}),\n\t\ttoolName: parsed.toolName,\n\t\ttoolRef: encodeToolRef({ namespace: parsed.namespace, toolName: parsed.toolName }),\n\t};\n}\n","import type {\n\tNormalizedUpstreamMcpServer,\n\tUpstreamMcpTransportKind,\n} from './upstream-mcp-client-runtime.js';\n\nexport type UpstreamMcpFailurePhase = 'call_tool' | 'connect' | 'list_tools';\n\nexport type UpstreamMcpTransportSummary =\n\t| {\n\t\t\treadonly argCount: number;\n\t\t\treadonly command: string;\n\t\t\treadonly cwd?: string;\n\t\t\treadonly kind: 'stdio';\n\t }\n\t| {\n\t\t\treadonly kind: Exclude<UpstreamMcpTransportKind, 'auto-http' | 'stdio'>;\n\t\t\treadonly url: string;\n\t };\n\nexport interface UpstreamMcpFailureDetails {\n\treadonly attemptTransport?: Exclude<UpstreamMcpTransportKind, 'auto-http'>;\n\treadonly causeMessage: string;\n\treadonly elapsedMs: number;\n\treadonly hint?: string;\n\treadonly kind: 'upstream_mcp_failed';\n\treadonly namespace: string;\n\treadonly operation: string;\n\treadonly phase: UpstreamMcpFailurePhase;\n\treadonly timeoutMs?: number;\n\treadonly toolName?: string;\n\treadonly transport: UpstreamMcpTransportSummary;\n}\n\nexport class UpstreamMcpError extends Error {\n\treadonly details: UpstreamMcpFailureDetails;\n\n\tconstructor(details: UpstreamMcpFailureDetails) {\n\t\tsuper(formatUpstreamMcpFailureMessage(details));\n\t\tthis.name = 'UpstreamMcpError';\n\t\tthis.details = details;\n\t}\n}\n\nexport function messageFromUnknownError(error: unknown): string {\n\tif (error instanceof Error) {\n\t\treturn error.message;\n\t}\n\tif (typeof error === 'string') {\n\t\treturn error;\n\t}\n\treturn String(error);\n}\n\nexport function isUpstreamMcpError(error: unknown): error is UpstreamMcpError {\n\treturn error instanceof UpstreamMcpError;\n}\n\nexport function transportSummaryFromServer(\n\tserver: NormalizedUpstreamMcpServer,\n\tattemptTransport?: Exclude<UpstreamMcpTransportKind, 'auto-http'>,\n): UpstreamMcpTransportSummary {\n\tif (server.transport === 'stdio') {\n\t\treturn {\n\t\t\targCount: server.args?.length ?? 0,\n\t\t\tcommand: server.command,\n\t\t\t...(server.cwd !== undefined ? { cwd: server.cwd } : {}),\n\t\t\tkind: 'stdio',\n\t\t};\n\t}\n\n\treturn {\n\t\tkind: attemptTransport === 'sse' ? 'sse' : 'streamable-http',\n\t\turl: server.url,\n\t};\n}\n\nfunction hintForFailure(\n\tdetails: Omit<UpstreamMcpFailureDetails, 'hint' | 'kind'>,\n): string | undefined {\n\tif (details.phase === 'connect' && details.transport.kind === 'stdio') {\n\t\treturn 'stdio MCP command failed before tool discovery; verify command, package bin name, gateway PATH, and arg count.';\n\t}\n\tif (details.phase === 'connect' && details.transport.kind !== 'stdio') {\n\t\treturn 'remote MCP connection failed; verify URL, auth header, network egress, and transport kind.';\n\t}\n\tif (details.phase === 'list_tools') {\n\t\treturn 'MCP provider connected but tool discovery failed; run agent-vm validate --mcp-live for the configured namespace.';\n\t}\n\tif (details.phase === 'call_tool') {\n\t\treturn 'MCP provider accepted discovery but the tool call failed; inspect the tool arguments and upstream provider response.';\n\t}\n\treturn undefined;\n}\n\nexport function createUpstreamMcpError(\n\tdetails: Omit<UpstreamMcpFailureDetails, 'hint' | 'kind'>,\n): UpstreamMcpError {\n\tconst hint = hintForFailure(details);\n\treturn new UpstreamMcpError({\n\t\t...details,\n\t\t...(hint !== undefined ? { hint } : {}),\n\t\tkind: 'upstream_mcp_failed',\n\t});\n}\n\nexport function upstreamMcpFailureDetailsFromUnknown(\n\terror: unknown,\n): UpstreamMcpFailureDetails | null {\n\treturn isUpstreamMcpError(error) ? error.details : null;\n}\n\nexport function formatUpstreamMcpFailureMessage(details: UpstreamMcpFailureDetails): string {\n\tconst toolSuffix = details.toolName === undefined ? '' : ` ${details.toolName}`;\n\treturn `${details.namespace}: ${details.phase}${toolSuffix} failed: ${details.causeMessage}`;\n}\n","import type { JsonValue } from './json-schema.js';\n\nconst credentialPatterns = [\n\t/\\bBearer\\s+[A-Za-z0-9._~+/=-]+/gi,\n\t/\\bBasic\\s+[A-Za-z0-9._~+/=-]+/gi,\n\t/\\b(api[_-]?key|token|password|secret)=([^&\\s]+)/gi,\n];\n\nexport interface RedactionOptions {\n\treadonly exactValues?: readonly string[];\n}\n\nexport function isCredentialConfigKey(key: string): boolean {\n\tconst normalizedKey = key.toLowerCase().replace(/[^a-z0-9]/g, '');\n\treturn (\n\t\tnormalizedKey === 'auth' ||\n\t\tnormalizedKey === 'authorization' ||\n\t\tnormalizedKey === 'apikey' ||\n\t\tnormalizedKey.endsWith('apikey') ||\n\t\tnormalizedKey.endsWith('token') ||\n\t\tnormalizedKey.endsWith('password') ||\n\t\tnormalizedKey.endsWith('secret')\n\t);\n}\n\nfunction redactExactValues(text: string, exactValues: readonly string[]): string {\n\treturn exactValues\n\t\t.filter((value) => value.length > 0)\n\t\t.reduce((currentText, value) => currentText.split(value).join('[REDACTED]'), text);\n}\n\nexport function redactExactCredentialText(text: string, options: RedactionOptions = {}): string {\n\treturn redactExactValues(text, options.exactValues ?? []);\n}\n\nexport function redactCredentialText(text: string, options: RedactionOptions = {}): string {\n\tconst patternRedactedText = credentialPatterns.reduce(\n\t\t(current, pattern) => current.replace(pattern, '[REDACTED]'),\n\t\ttext,\n\t);\n\treturn redactExactValues(patternRedactedText, options.exactValues ?? []);\n}\n\nfunction redactJsonValue(value: unknown, options: RedactionOptions, keyHint?: string): unknown {\n\tif (typeof value === 'string') {\n\t\treturn keyHint && isCredentialConfigKey(keyHint)\n\t\t\t? '[REDACTED]'\n\t\t\t: redactCredentialText(value, options);\n\t}\n\n\tif (Array.isArray(value)) {\n\t\treturn value.map((entry) => redactJsonValue(entry, options));\n\t}\n\n\tif (typeof value !== 'object' || value === null) {\n\t\treturn value;\n\t}\n\n\treturn Object.fromEntries(\n\t\tObject.entries(value).map(([key, childValue]) => [\n\t\t\tkey,\n\t\t\tredactJsonValue(childValue, options, key),\n\t\t]),\n\t);\n}\n\nfunction redactExactJsonValue(value: unknown, options: RedactionOptions): unknown {\n\tif (typeof value === 'string') {\n\t\treturn redactExactCredentialText(value, options);\n\t}\n\n\tif (Array.isArray(value)) {\n\t\treturn value.map((entry) => redactExactJsonValue(entry, options));\n\t}\n\n\tif (typeof value !== 'object' || value === null) {\n\t\treturn value;\n\t}\n\n\treturn Object.fromEntries(\n\t\tObject.entries(value).map(([key, childValue]) => [\n\t\t\tkey,\n\t\t\tredactExactJsonValue(childValue, options),\n\t\t]),\n\t);\n}\n\nfunction isJsonValue(value: unknown): value is JsonValue {\n\tif (\n\t\tvalue === null ||\n\t\ttypeof value === 'string' ||\n\t\ttypeof value === 'number' ||\n\t\ttypeof value === 'boolean'\n\t) {\n\t\treturn true;\n\t}\n\n\tif (Array.isArray(value)) {\n\t\treturn value.every(isJsonValue);\n\t}\n\n\tif (typeof value !== 'object') {\n\t\treturn false;\n\t}\n\n\treturn Object.values(value).every(isJsonValue);\n}\n\nexport function redactUpstreamResponse(response: unknown, options: RedactionOptions = {}): unknown {\n\treturn redactJsonValue(response, options);\n}\n\nexport function redactUpstreamCatalogValue(\n\tresponse: unknown,\n\toptions: RedactionOptions = {},\n): unknown {\n\treturn redactExactJsonValue(response, options);\n}\n\nfunction copyRedactedErrorField(props: {\n\treadonly source: Error;\n\treadonly target: Error;\n\treadonly fieldName: string;\n\treadonly options: RedactionOptions;\n}): void {\n\tconst descriptor = Object.getOwnPropertyDescriptor(props.source, props.fieldName);\n\tif (!descriptor || !('value' in descriptor)) {\n\t\treturn;\n\t}\n\tObject.defineProperty(props.target, props.fieldName, {\n\t\t...descriptor,\n\t\tvalue: redactJsonValue(descriptor.value, props.options),\n\t});\n}\n\nexport function redactThrownError(error: unknown, options: RedactionOptions = {}): Error {\n\tconst message = error instanceof Error ? error.message : String(error);\n\tif (!(error instanceof Error)) {\n\t\treturn new Error(redactCredentialText(message, options));\n\t}\n\n\tconst rawCause = 'cause' in error ? error.cause : undefined;\n\tconst redactedCause =\n\t\trawCause === undefined || rawCause === error\n\t\t\t? undefined\n\t\t\t: rawCause instanceof Error\n\t\t\t\t? redactThrownError(rawCause, options)\n\t\t\t\t: redactJsonValue(rawCause, options);\n\tconst redactedError =\n\t\tredactedCause === undefined\n\t\t\t? new Error(redactCredentialText(message, options))\n\t\t\t: new Error(redactCredentialText(message, options), { cause: redactedCause });\n\tredactedError.name = error.name;\n\tif (error.stack) {\n\t\tredactedError.stack = redactCredentialText(error.stack, options);\n\t}\n\tcopyRedactedErrorField({ fieldName: 'code', options, source: error, target: redactedError });\n\tcopyRedactedErrorField({ fieldName: 'data', options, source: error, target: redactedError });\n\treturn redactedError;\n}\n\nexport function toRedactedJsonValue(value: unknown, options: RedactionOptions = {}): JsonValue {\n\tconst redacted = redactJsonValue(value, options);\n\tif (isJsonValue(redacted)) {\n\t\treturn redacted;\n\t}\n\n\treturn null;\n}\n"],"mappings":";;AAAA,MAAM,2BAA2B,OAAO,sBAAsB;AAsC9D,SAAgB,0BAA0B,OAOlB;CACvB,wBAAwB,WAAW,MAAM,QAAQ;CACjD,wBAAwB,gBAAgB,MAAM,aAAa;CAC3D,IAAI,MAAM,cAAc,KAAA,GACvB,wBAAwB,aAAa,MAAM,UAAU;CAEtD,IAAI,MAAM,eAAe,KAAA,GACxB,wBAAwB,cAAc,MAAM,WAAW;CAExD,IAAI,MAAM,gBAAgB,KAAA,GACzB,wBAAwB,eAAe,MAAM,YAAY;CAE1D,OAAO;EACN,SAAS,MAAM;EACf,cAAc,MAAM;EACpB,GAAI,MAAM,gBAAgB,KAAA,IAAY,EAAE,aAAa,MAAM,aAAa,GAAG,EAAE;EAC7E,GAAI,MAAM,cAAc,KAAA,IAAY,EAAE,WAAW,MAAM,WAAW,GAAG,EAAE;EACvE,GAAI,MAAM,eAAe,KAAA,IAAY,EAAE,YAAY,MAAM,YAAY,GAAG,EAAE;EAC1E,QAAQ,MAAM;GACb,2BAA2B;EAC5B;;AAGF,SAAS,wBAAwB,MAAc,OAAqB;CACnE,IAAI,MAAM,WAAW,GACpB,MAAM,IAAI,MAAM,cAAc,KAAK,qBAAqB;CAEzD,KAAK,IAAI,QAAQ,GAAG,QAAQ,MAAM,QAAQ,SAAS,GAAG;EACrD,MAAM,YAAY,MAAM,WAAW,MAAM;EACzC,IAAI,YAAY,MAAM,cAAc,OAAO,cAAc,QAAU,cAAc,MAChF,MAAM,IAAI,MAAM,cAAc,KAAK,uCAAuC;;;AAK7E,SAAgB,oBAAoB,UAAuC;CAC1E,MAAM,eAAe,SAAS,aAAa,SAAS;CACpD,OAAO,eAAe,GAAG,SAAS,aAAa,IAAI,iBAAiB,SAAS;;AAG9E,SAAS,kBACR,WACgC;CAChC,OAAO,CAAC,GAAG,UAAU,CAAC,UAAU,MAAM,UAAU;EAC/C,MAAM,iBAAiB,KAAK,UAAU,cAAc,MAAM,UAAU;EACpE,OAAO,mBAAmB,IAAI,KAAK,SAAS,cAAc,MAAM,SAAS,GAAG;GAC3E;;AAGH,SAAgB,0BAA0B,OAIX;CAC9B,MAAM,kBAAkB,MAAM,OAAO,yBAAyB,MAAM,SAAS;CAC7E,MAAM,mBAAmB,MAAM,OAAO;CACtC,MAAM,qBACL,mBACA,qBACC,MAAM,OAAO,kBAAkB,cAAc,MAAM,qBAAqB,EAAE;CAC5E,MAAM,uBAAuB,IAAI,IAAI,MAAM,mBAAmB;CAE9D,OAAO;EACN,mBAAmB,mBACjB,QAAQ,cAAc,qBAAqB,IAAI,UAAU,CAAC,CAC1D,UAAU;EACZ,cAAc,kBACb,MAAM,OAAO,sBAAsB,MAAM,SAAS,YAAY,EAAE,CAChE;EACD,aAAa,kBAAkB,MAAM,OAAO,mBAAmB,MAAM,SAAS,YAAY,EAAE,CAAC;EAC7F;;;;AChFF,SAAS,qBAAqB,OAAmC;CAChE,IAAI,CAAC,MAAM,QAAQ,MAAM,EACxB,OAAO,EAAE;CAGV,OAAO,MAAM,QAAQ,UAA2B,OAAO,UAAU,SAAS,CAAC,UAAU;;AAGtF,SAAS,2BAA2B,QAAuC;CAC1E,MAAM,aAAa,OAAO;CAC1B,IAAI,OAAO,eAAe,YAAY,eAAe,QAAQ,MAAM,QAAQ,WAAW,EACrF,OAAO,EAAE;CAGV,OAAO,OAAO,KAAK,WAAW,CAAC,UAAU;;AAG1C,SAAgB,oBAAoB,QAAuC;CAC1E,MAAM,aAAa,2BAA2B,OAAO;CACrD,MAAM,WAAW,qBAAqB,OAAO,SAAS;CACtD,MAAM,cAAc,IAAI,IAAI,SAAS;CAGrC,OAAO;EACN,UAHgB,WAAW,QAAQ,iBAAiB,CAAC,YAAY,IAAI,aAAa,CAG1E;EACR,eAAe,WAAW;EAC1B;EACA,MAAM,OAAO,OAAO,SAAS,WAAW,OAAO,OAAO;EACtD;;AAGF,SAAgB,kBAAkB,MAAqC;CACtE,MAAM,SAAS,uBAAuB,MAAM,KAAK;CACjD,MAAM,SAAS;EACd,GAAI,OAAO,aAAa,oBAAoB,KAAA,IACzC,EAAE,iBAAiB,OAAO,YAAY,iBAAiB,GACvD,EAAE;EACL,GAAI,OAAO,aAAa,iBAAiB,KAAA,IACtC,EAAE,cAAc,OAAO,YAAY,cAAc,GACjD,EAAE;EACL;CAED,OAAO;EACN,GAAI,OAAO,gBAAgB,KAAA,IAAY,EAAE,aAAa,OAAO,aAAa,GAAG,EAAE;EAC/E,OAAO,oBAAoB,OAAO,YAAY;EAC9C,WAAW,OAAO;EAClB,GAAI,OAAO,eAAe,EAAE,QAAQ,oBAAoB,OAAO,aAAa,EAAE,GAAG,EAAE;EACnF;EACA,GAAI,OAAO,UAAU,KAAA,IAAY,EAAE,OAAO,OAAO,OAAO,GAAG,EAAE;EAC7D,UAAU,OAAO;EACjB,SAAS,cAAc;GAAE,WAAW,OAAO;GAAW,UAAU,OAAO;GAAU,CAAC;EAClF;;;;ACrDF,IAAa,mBAAb,cAAsC,MAAM;CAC3C;CAEA,YAAY,SAAoC;EAC/C,MAAM,gCAAgC,QAAQ,CAAC;EAC/C,KAAK,OAAO;EACZ,KAAK,UAAU;;;AAIjB,SAAgB,wBAAwB,OAAwB;CAC/D,IAAI,iBAAiB,OACpB,OAAO,MAAM;CAEd,IAAI,OAAO,UAAU,UACpB,OAAO;CAER,OAAO,OAAO,MAAM;;AAGrB,SAAgB,mBAAmB,OAA2C;CAC7E,OAAO,iBAAiB;;AAGzB,SAAgB,2BACf,QACA,kBAC8B;CAC9B,IAAI,OAAO,cAAc,SACxB,OAAO;EACN,UAAU,OAAO,MAAM,UAAU;EACjC,SAAS,OAAO;EAChB,GAAI,OAAO,QAAQ,KAAA,IAAY,EAAE,KAAK,OAAO,KAAK,GAAG,EAAE;EACvD,MAAM;EACN;CAGF,OAAO;EACN,MAAM,qBAAqB,QAAQ,QAAQ;EAC3C,KAAK,OAAO;EACZ;;AAGF,SAAS,eACR,SACqB;CACrB,IAAI,QAAQ,UAAU,aAAa,QAAQ,UAAU,SAAS,SAC7D,OAAO;CAER,IAAI,QAAQ,UAAU,aAAa,QAAQ,UAAU,SAAS,SAC7D,OAAO;CAER,IAAI,QAAQ,UAAU,cACrB,OAAO;CAER,IAAI,QAAQ,UAAU,aACrB,OAAO;;AAKT,SAAgB,uBACf,SACmB;CACnB,MAAM,OAAO,eAAe,QAAQ;CACpC,OAAO,IAAI,iBAAiB;EAC3B,GAAG;EACH,GAAI,SAAS,KAAA,IAAY,EAAE,MAAM,GAAG,EAAE;EACtC,MAAM;EACN,CAAC;;AAGH,SAAgB,qCACf,OACmC;CACnC,OAAO,mBAAmB,MAAM,GAAG,MAAM,UAAU;;AAGpD,SAAgB,gCAAgC,SAA4C;CAC3F,MAAM,aAAa,QAAQ,aAAa,KAAA,IAAY,KAAK,IAAI,QAAQ;CACrE,OAAO,GAAG,QAAQ,UAAU,IAAI,QAAQ,QAAQ,WAAW,WAAW,QAAQ;;;;AC/G/E,MAAM,qBAAqB;CAC1B;CACA;CACA;CACA;AAMD,SAAgB,sBAAsB,KAAsB;CAC3D,MAAM,gBAAgB,IAAI,aAAa,CAAC,QAAQ,cAAc,GAAG;CACjE,OACC,kBAAkB,UAClB,kBAAkB,mBAClB,kBAAkB,YAClB,cAAc,SAAS,SAAS,IAChC,cAAc,SAAS,QAAQ,IAC/B,cAAc,SAAS,WAAW,IAClC,cAAc,SAAS,SAAS;;AAIlC,SAAS,kBAAkB,MAAc,aAAwC;CAChF,OAAO,YACL,QAAQ,UAAU,MAAM,SAAS,EAAE,CACnC,QAAQ,aAAa,UAAU,YAAY,MAAM,MAAM,CAAC,KAAK,aAAa,EAAE,KAAK;;AAGpF,SAAgB,0BAA0B,MAAc,UAA4B,EAAE,EAAU;CAC/F,OAAO,kBAAkB,MAAM,QAAQ,eAAe,EAAE,CAAC;;AAG1D,SAAgB,qBAAqB,MAAc,UAA4B,EAAE,EAAU;CAK1F,OAAO,kBAJqB,mBAAmB,QAC7C,SAAS,YAAY,QAAQ,QAAQ,SAAS,aAAa,EAC5D,KAE2C,EAAE,QAAQ,eAAe,EAAE,CAAC;;AAGzE,SAAS,gBAAgB,OAAgB,SAA2B,SAA2B;CAC9F,IAAI,OAAO,UAAU,UACpB,OAAO,WAAW,sBAAsB,QAAQ,GAC7C,eACA,qBAAqB,OAAO,QAAQ;CAGxC,IAAI,MAAM,QAAQ,MAAM,EACvB,OAAO,MAAM,KAAK,UAAU,gBAAgB,OAAO,QAAQ,CAAC;CAG7D,IAAI,OAAO,UAAU,YAAY,UAAU,MAC1C,OAAO;CAGR,OAAO,OAAO,YACb,OAAO,QAAQ,MAAM,CAAC,KAAK,CAAC,KAAK,gBAAgB,CAChD,KACA,gBAAgB,YAAY,SAAS,IAAI,CACzC,CAAC,CACF;;AAGF,SAAS,qBAAqB,OAAgB,SAAoC;CACjF,IAAI,OAAO,UAAU,UACpB,OAAO,0BAA0B,OAAO,QAAQ;CAGjD,IAAI,MAAM,QAAQ,MAAM,EACvB,OAAO,MAAM,KAAK,UAAU,qBAAqB,OAAO,QAAQ,CAAC;CAGlE,IAAI,OAAO,UAAU,YAAY,UAAU,MAC1C,OAAO;CAGR,OAAO,OAAO,YACb,OAAO,QAAQ,MAAM,CAAC,KAAK,CAAC,KAAK,gBAAgB,CAChD,KACA,qBAAqB,YAAY,QAAQ,CACzC,CAAC,CACF;;AAGF,SAAS,YAAY,OAAoC;CACxD,IACC,UAAU,QACV,OAAO,UAAU,YACjB,OAAO,UAAU,YACjB,OAAO,UAAU,WAEjB,OAAO;CAGR,IAAI,MAAM,QAAQ,MAAM,EACvB,OAAO,MAAM,MAAM,YAAY;CAGhC,IAAI,OAAO,UAAU,UACpB,OAAO;CAGR,OAAO,OAAO,OAAO,MAAM,CAAC,MAAM,YAAY;;AAG/C,SAAgB,uBAAuB,UAAmB,UAA4B,EAAE,EAAW;CAClG,OAAO,gBAAgB,UAAU,QAAQ;;AAG1C,SAAgB,2BACf,UACA,UAA4B,EAAE,EACpB;CACV,OAAO,qBAAqB,UAAU,QAAQ;;AAG/C,SAAS,uBAAuB,OAKvB;CACR,MAAM,aAAa,OAAO,yBAAyB,MAAM,QAAQ,MAAM,UAAU;CACjF,IAAI,CAAC,cAAc,EAAE,WAAW,aAC/B;CAED,OAAO,eAAe,MAAM,QAAQ,MAAM,WAAW;EACpD,GAAG;EACH,OAAO,gBAAgB,WAAW,OAAO,MAAM,QAAQ;EACvD,CAAC;;AAGH,SAAgB,kBAAkB,OAAgB,UAA4B,EAAE,EAAS;CACxF,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;CACtE,IAAI,EAAE,iBAAiB,QACtB,OAAO,IAAI,MAAM,qBAAqB,SAAS,QAAQ,CAAC;CAGzD,MAAM,WAAW,WAAW,QAAQ,MAAM,QAAQ,KAAA;CAClD,MAAM,gBACL,aAAa,KAAA,KAAa,aAAa,QACpC,KAAA,IACA,oBAAoB,QACnB,kBAAkB,UAAU,QAAQ,GACpC,gBAAgB,UAAU,QAAQ;CACvC,MAAM,gBACL,kBAAkB,KAAA,IACf,IAAI,MAAM,qBAAqB,SAAS,QAAQ,CAAC,GACjD,IAAI,MAAM,qBAAqB,SAAS,QAAQ,EAAE,EAAE,OAAO,eAAe,CAAC;CAC/E,cAAc,OAAO,MAAM;CAC3B,IAAI,MAAM,OACT,cAAc,QAAQ,qBAAqB,MAAM,OAAO,QAAQ;CAEjE,uBAAuB;EAAE,WAAW;EAAQ;EAAS,QAAQ;EAAO,QAAQ;EAAe,CAAC;CAC5F,uBAAuB;EAAE,WAAW;EAAQ;EAAS,QAAQ;EAAO,QAAQ;EAAe,CAAC;CAC5F,OAAO;;AAGR,SAAgB,oBAAoB,OAAgB,UAA4B,EAAE,EAAa;CAC9F,MAAM,WAAW,gBAAgB,OAAO,QAAQ;CAChD,IAAI,YAAY,SAAS,EACxB,OAAO;CAGR,OAAO"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-vm/mcp-portal",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.77",
|
|
4
4
|
"description": "Agent-scoped MCP Portal server and TypeScript helpers for composable upstream MCP tools.",
|
|
5
5
|
"homepage": "https://github.com/ShravanSunder/agent-vm#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -69,8 +69,8 @@
|
|
|
69
69
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
70
70
|
"hono": "^4.12.18",
|
|
71
71
|
"zod": "^4.4.3",
|
|
72
|
-
"@agent-vm/config-contracts": "0.0.
|
|
73
|
-
"@agent-vm/secret-management": "0.0.
|
|
72
|
+
"@agent-vm/config-contracts": "0.0.77",
|
|
73
|
+
"@agent-vm/secret-management": "0.0.77"
|
|
74
74
|
},
|
|
75
75
|
"devDependencies": {
|
|
76
76
|
"vitest": "^4.1.5"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"portal-core-BPSvDGvi.js","names":[],"sources":["../src/core/provider-runtime.ts","../src/core/portal-core.ts"],"sourcesContent":["import {\n\tmcpConfigToResolvedProviders,\n\ttype McpConfig,\n\ttype ResolvedMcpProvider,\n\ttype SecretValue,\n} from '@agent-vm/config-contracts';\n\nimport type { NormalizedUpstreamMcpServer } from '../upstream-mcp-client-runtime.js';\n\nexport interface ResolveUpstreamServersProps {\n\treadonly config: McpConfig;\n\treadonly resolveSecret: (secret: SecretValue) => Promise<string>;\n}\n\nasync function resolveProviderSecretRecord(\n\tsecrets: Readonly<Record<string, SecretValue>>,\n\tresolveSecret: (secret: SecretValue) => Promise<string>,\n): Promise<Readonly<Record<string, string>>> {\n\tconst resolvedEntries = await Promise.all(\n\t\tObject.entries(secrets).map(\n\t\t\tasync ([name, secret]) => [name, await resolveSecret(secret)] as const,\n\t\t),\n\t);\n\treturn Object.fromEntries(resolvedEntries);\n}\n\nasync function resolveUpstreamServer(\n\tprovider: ResolvedMcpProvider,\n\tresolveSecret: (secret: SecretValue) => Promise<string>,\n): Promise<NormalizedUpstreamMcpServer> {\n\tif (provider.transport === 'stdio') {\n\t\treturn {\n\t\t\targs: provider.args,\n\t\t\tcommand: provider.command,\n\t\t\t...(provider.cwd === undefined ? {} : { cwd: provider.cwd }),\n\t\t\tenv: await resolveProviderSecretRecord(provider.env, resolveSecret),\n\t\t\tnamespace: provider.namespace,\n\t\t\ttransport: 'stdio',\n\t\t};\n\t}\n\n\treturn {\n\t\theaders: await resolveProviderSecretRecord(provider.headers, resolveSecret),\n\t\tnamespace: provider.namespace,\n\t\ttransport: provider.transport,\n\t\turl: provider.url,\n\t};\n}\n\nexport async function resolveUpstreamServers(\n\tprops: ResolveUpstreamServersProps,\n): Promise<readonly NormalizedUpstreamMcpServer[]> {\n\treturn await Promise.all(\n\t\tmcpConfigToResolvedProviders(props.config).map(async (provider) =>\n\t\t\tresolveUpstreamServer(provider, props.resolveSecret),\n\t\t),\n\t);\n}\n","import type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport { z } from 'zod';\n\nimport { jsonObjectSchema } from '../json-schema.js';\nimport {\n\tcreatePortalAgentIdentity,\n\tresolvePortalAccessPolicy,\n\ttype PortalAccessPolicyConfig,\n\ttype PortalAgentIdentity,\n\ttype PortalAgentScopeSource,\n} from '../portal-access-policy.js';\nimport {\n\tcreatePortalSessionManager,\n\ttype PortalSessionManager,\n\ttype PortalSessionRuntime,\n} from '../portal-session.js';\nimport type { SkillGraphInput } from '../tool-graph.js';\nimport {\n\tcreatePortalToolHandlers,\n\tportalToolInputSchemas,\n\ttype PortalApprovalCall,\n\ttype PortalBatchDiagnostic,\n\ttype PortalBatchResult,\n\ttype PortalToolResult,\n\ttype PortalToolRuntime,\n} from './portal-tools.js';\n\nexport type PortalAgentScope = PortalAgentIdentity;\n\nexport type PortalCoreToolName =\n\t| 'mcp_portal_list'\n\t| 'mcp_portal_search'\n\t| 'mcp_portal_describe'\n\t| 'mcp_portal_call';\n\nexport interface PortalAuditEvent {\n\treadonly kind: string;\n\treadonly message: string;\n\treadonly namespace?: string;\n}\n\nexport interface PortalCoreResult {\n\treadonly auditEvents?: readonly PortalAuditEvent[];\n\treadonly content: readonly PortalCoreContentBlock[];\n\treadonly items: readonly PortalCoreItemResult[];\n\treadonly structuredContent?: unknown;\n}\n\nexport type PortalCoreItemResult =\n\t| {\n\t\t\treadonly content: readonly PortalCoreContentBlock[];\n\t\t\treadonly requestId: string;\n\t\t\treadonly status: 'success';\n\t\t\treadonly structuredContent?: unknown;\n\t }\n\t| {\n\t\t\treadonly error: PortalCoreItemError;\n\t\t\treadonly requestId: string;\n\t\t\treadonly status: 'failed';\n\t };\n\nexport interface PortalCoreItemError {\n\treadonly code: string;\n\treadonly message: string;\n\treadonly namespace?: string;\n\treadonly toolName?: string;\n}\n\nexport type PortalCoreContentBlock =\n\t| { readonly text: string; readonly type: 'text' }\n\t| { readonly type: 'json'; readonly value: unknown };\n\nexport type PortalCoreEvent =\n\t| {\n\t\t\treadonly kind: 'started';\n\t\t\treadonly toolName: PortalCoreToolName;\n\t }\n\t| {\n\t\t\treadonly kind: 'item_started';\n\t\t\treadonly namespace?: string;\n\t\t\treadonly requestId: string;\n\t\t\treadonly toolName?: string;\n\t }\n\t| {\n\t\t\treadonly kind: 'progress';\n\t\t\treadonly message?: string;\n\t\t\treadonly progress?: number;\n\t\t\treadonly requestId?: string;\n\t\t\treadonly total?: number;\n\t }\n\t| {\n\t\t\treadonly kind: 'upstream_notification';\n\t\t\treadonly method: string;\n\t\t\treadonly params: unknown;\n\t\t\treadonly requestId?: string;\n\t }\n\t| {\n\t\t\treadonly content: PortalCoreContentBlock;\n\t\t\treadonly kind: 'partial_content';\n\t\t\treadonly requestId?: string;\n\t }\n\t| {\n\t\t\treadonly kind: 'item_completed';\n\t\t\treadonly requestId: string;\n\t\t\treadonly result: Extract<PortalCoreItemResult, { readonly status: 'success' }>;\n\t }\n\t| {\n\t\t\treadonly error: PortalCoreItemError;\n\t\t\treadonly kind: 'item_failed';\n\t\t\treadonly requestId: string;\n\t }\n\t| {\n\t\t\treadonly kind: 'completed';\n\t\t\treadonly result: PortalCoreResult;\n\t }\n\t| {\n\t\t\treadonly error: unknown;\n\t\t\treadonly kind: 'failed';\n\t };\n\nexport interface PortalCoreStreamCall {\n\treadonly input: unknown;\n\treadonly scope: PortalAgentScope;\n\treadonly signal?: AbortSignal;\n\treadonly toolName: PortalCoreToolName;\n}\n\nconst maxQueuedPortalCoreEvents = 1_024;\nconst maxPortalCoreEventBytes = 256 * 1_024;\n\nexport interface PortalCoreCollectOptions {\n\treadonly onEvent?: (event: PortalCoreEvent) => Promise<void> | void;\n}\n\nexport interface PortalCoreRuntime extends PortalSessionRuntime {\n\treadonly callUpstreamTool: PortalToolRuntime['callUpstreamTool'];\n}\n\nexport type PortalApprovalEvaluator = NonNullable<PortalToolRuntime['approval']>;\n\ninterface CreatePortalCoreBaseProps {\n\treadonly accessPolicy: PortalAccessPolicyConfig;\n\treadonly catalogTtlMs: number;\n\treadonly runtime: PortalCoreRuntime;\n\treadonly skills?: readonly SkillGraphInput[];\n\treadonly upstreamNamespaces: readonly string[];\n}\n\nexport type CreatePortalCoreProps =\n\t| (CreatePortalCoreBaseProps & {\n\t\t\treadonly approval: PortalApprovalEvaluator;\n\t\t\treadonly approvalTrustBoundary?: never;\n\t })\n\t| (CreatePortalCoreBaseProps & {\n\t\t\treadonly approval?: never;\n\t\t\treadonly approvalTrustBoundary: 'openclaw-before-tool-call-hook';\n\t });\n\nexport interface PortalCore {\n\treadonly approval: {\n\t\treadonly evaluateCalls: (\n\t\t\tcalls: readonly PortalApprovalCall[],\n\t\t\tscope: PortalAgentScope,\n\t\t\tapprovalToken: string | undefined,\n\t\t) => ReturnType<PortalApprovalEvaluator>;\n\t};\n\treadonly callStream: (call: PortalCoreStreamCall) => AsyncIterable<PortalCoreEvent>;\n\treadonly close: () => Promise<void>;\n\treadonly collectPortalCoreResult: typeof collectPortalCoreResult;\n\treadonly createAgentScope: (input: {\n\t\treadonly agentId: string;\n\t\treadonly agentScopeId: string;\n\t\treadonly authSubject?: string;\n\t\treadonly sessionId?: string;\n\t\treadonly sessionKey?: string;\n\t\treadonly source: PortalAgentScopeSource;\n\t}) => PortalAgentScope;\n\treadonly describeTools: (scope: PortalAgentScope) => readonly PortalCoreToolDescriptor[];\n\treadonly invalidateAgentScope: (agentScopeId: string) => Promise<void>;\n\treadonly invalidateSession: (scope: PortalAgentScope) => Promise<void>;\n\treadonly upstreamNamespaces: readonly string[];\n}\n\nexport interface PortalCoreToolDescriptor {\n\treadonly description: string;\n\treadonly inputSchema: Tool['inputSchema'];\n\treadonly name: PortalCoreToolName;\n}\n\nconst portalCallRequestSchema = z\n\t.object({\n\t\targuments: jsonObjectSchema,\n\t\tid: z.string().min(1),\n\t\tnamespace: z.string().min(1),\n\t\ttoolName: z.string().min(1),\n\t})\n\t.strict();\nconst portalCallInputSchema = z\n\t.object({\n\t\tcalls: z.array(portalCallRequestSchema).min(1),\n\t\tportalApprovalToken: z.string().min(1).optional(),\n\t})\n\t.strict();\n\nfunction diagnosticsToAuditEvents(\n\tdiagnostics: readonly PortalBatchDiagnostic[],\n): readonly PortalAuditEvent[] {\n\treturn diagnostics.map((diagnostic) => ({\n\t\tkind: diagnostic.kind,\n\t\tmessage: diagnostic.message,\n\t\t...(diagnostic.namespace !== undefined ? { namespace: diagnostic.namespace } : {}),\n\t}));\n}\n\nfunction isUnknownRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction errorRecordFromUnknown(error: unknown): Record<string, unknown> {\n\treturn isUnknownRecord(error) ? error : {};\n}\n\nfunction messageFromUnknown(error: unknown): string {\n\tif (error instanceof Error) {\n\t\treturn error.message;\n\t}\n\tconst record = errorRecordFromUnknown(error);\n\tconst message = record.message;\n\treturn typeof message === 'string' ? message : String(error);\n}\n\nfunction errorFromAbortSignal(signal: AbortSignal): Error {\n\tconst reason: unknown = signal.reason;\n\treturn reason instanceof Error ? reason : new Error('MCP Portal core stream aborted.');\n}\n\nfunction throwIfAborted(signal: AbortSignal | undefined): void {\n\tif (signal?.aborted) {\n\t\tthrow errorFromAbortSignal(signal);\n\t}\n}\n\nfunction assertPortalCoreEventSize(event: PortalCoreEvent): void {\n\tconst serialized = JSON.stringify(event);\n\tif (serialized === undefined) {\n\t\treturn;\n\t}\n\tconst byteLength = Buffer.byteLength(serialized, 'utf8');\n\tif (byteLength > maxPortalCoreEventBytes) {\n\t\tthrow new Error(\n\t\t\t`MCP Portal core event exceeded ${String(maxPortalCoreEventBytes)} bytes (${String(byteLength)} bytes).`,\n\t\t);\n\t}\n}\n\nfunction waitForQueuedCoreEvent(props: {\n\treadonly setNotifyQueuedEvent: (notify: (() => void) | undefined) => void;\n\treadonly signal?: AbortSignal;\n}): Promise<void> {\n\tif (props.signal === undefined) {\n\t\treturn new Promise<void>((resolve) => {\n\t\t\tprops.setNotifyQueuedEvent(resolve);\n\t\t});\n\t}\n\tconst signal = props.signal;\n\treturn new Promise<void>((resolve, reject) => {\n\t\tlet settled = false;\n\t\tconst settle = (complete: () => void): void => {\n\t\t\tif (settled) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsettled = true;\n\t\t\tsignal.removeEventListener('abort', onAbort);\n\t\t\tprops.setNotifyQueuedEvent(undefined);\n\t\t\tcomplete();\n\t\t};\n\t\tconst onNotify = (): void => {\n\t\t\tsettle(resolve);\n\t\t};\n\t\tconst onAbort = (): void => {\n\t\t\tsettle(() => reject(errorFromAbortSignal(signal)));\n\t\t};\n\t\tprops.setNotifyQueuedEvent(onNotify);\n\t\tsignal.addEventListener('abort', onAbort, { once: true });\n\t\tif (signal.aborted) {\n\t\t\tonAbort();\n\t\t}\n\t});\n}\n\nfunction itemErrorFromPortalResult(result: PortalToolResult): PortalCoreItemError {\n\tif (result.ok) {\n\t\tthrow new Error('Cannot convert successful portal result into an item error.');\n\t}\n\tconst errorRecord = errorRecordFromUnknown(result.error);\n\tconst kind = errorRecord.kind;\n\tconst namespace = errorRecord.namespace;\n\tconst toolName = errorRecord.toolName;\n\n\treturn {\n\t\tcode: typeof kind === 'string' ? kind : 'portal_item_failed',\n\t\tmessage: messageFromUnknown(result.error),\n\t\t...(typeof namespace === 'string' ? { namespace } : {}),\n\t\t...(typeof toolName === 'string' ? { toolName } : {}),\n\t};\n}\n\nfunction itemResultFromPortalToolResult(\n\trequestId: string,\n\tresult: PortalToolResult,\n): PortalCoreItemResult {\n\tif (!result.ok) {\n\t\treturn {\n\t\t\terror: itemErrorFromPortalResult(result),\n\t\t\trequestId,\n\t\t\tstatus: 'failed',\n\t\t};\n\t}\n\n\treturn {\n\t\tcontent: [{ type: 'json', value: result.output }],\n\t\trequestId,\n\t\tstatus: 'success',\n\t\tstructuredContent: result.output,\n\t};\n}\n\nfunction scalarBatchResultToCoreResult(batchResult: PortalBatchResult): PortalCoreResult {\n\treturn {\n\t\tauditEvents: diagnosticsToAuditEvents(batchResult.diagnostics),\n\t\tcontent: [{ type: 'json', value: batchResult }],\n\t\titems: [],\n\t\tstructuredContent: batchResult,\n\t};\n}\n\nfunction batchItemsToCoreResult(props: {\n\treadonly diagnostics: readonly PortalBatchDiagnostic[];\n\treadonly items: readonly PortalCoreItemResult[];\n}): PortalCoreResult {\n\treturn {\n\t\tauditEvents: diagnosticsToAuditEvents(props.diagnostics),\n\t\tcontent: [],\n\t\titems: props.items,\n\t};\n}\n\nfunction namespaceDescription(namespaces: readonly string[]): string {\n\treturn namespaces.length === 0\n\t\t? 'No upstream MCP namespaces are authorized for this agent scope.'\n\t\t: `Authorized MCP namespaces for this agent scope: ${namespaces.join(', ')}.`;\n}\n\nexport function listPortalCoreToolDescriptors(\n\tnamespaces: readonly string[] = [],\n): readonly PortalCoreToolDescriptor[] {\n\tconst scopeDescription = namespaceDescription(namespaces);\n\treturn [\n\t\t{\n\t\t\tdescription: `List authorized MCP namespaces and compact tool summaries. ${scopeDescription}`,\n\t\t\tinputSchema: portalToolInputSchemas.mcp_portal_list,\n\t\t\tname: 'mcp_portal_list',\n\t\t},\n\t\t{\n\t\t\tdescription: `Search the caller scoped MCP Portal index. ${scopeDescription}`,\n\t\t\tinputSchema: portalToolInputSchemas.mcp_portal_search,\n\t\t\tname: 'mcp_portal_search',\n\t\t},\n\t\t{\n\t\t\tdescription: `Describe exact MCP tool schemas and optional TypeScript/Zod helpers. ${scopeDescription}`,\n\t\t\tinputSchema: portalToolInputSchemas.mcp_portal_describe,\n\t\t\tname: 'mcp_portal_describe',\n\t\t},\n\t\t{\n\t\t\tdescription: `Validate and call an authorized upstream MCP tool by namespace and toolName. ${scopeDescription}`,\n\t\t\tinputSchema: portalToolInputSchemas.mcp_portal_call,\n\t\t\tname: 'mcp_portal_call',\n\t\t},\n\t];\n}\n\nexport async function collectPortalCoreResult(\n\tevents: AsyncIterable<PortalCoreEvent>,\n\toptions: PortalCoreCollectOptions = {},\n): Promise<PortalCoreResult> {\n\tlet result: PortalCoreResult | undefined;\n\tfor await (const event of events) {\n\t\tawait options.onEvent?.(event);\n\t\tif (event.kind === 'completed') {\n\t\t\tresult = event.result;\n\t\t}\n\t\tif (event.kind === 'failed') {\n\t\t\tthrow event.error;\n\t\t}\n\t}\n\tif (result === undefined) {\n\t\tthrow new Error('MCP Portal core stream ended without a completed event.');\n\t}\n\treturn result;\n}\n\nasync function* scalarToolStream(props: {\n\treadonly input: unknown;\n\treadonly scope: PortalAgentScope;\n\treadonly signal?: AbortSignal;\n\treadonly sessionManager: PortalSessionManager;\n\treadonly toolName: Exclude<PortalCoreToolName, 'mcp_portal_call'>;\n\treadonly toolRuntime: PortalToolRuntime;\n}): AsyncIterable<PortalCoreEvent> {\n\tconst handlers = createPortalToolHandlers(props.toolRuntime);\n\tconst handler =\n\t\tprops.toolName === 'mcp_portal_list'\n\t\t\t? handlers.list\n\t\t\t: props.toolName === 'mcp_portal_search'\n\t\t\t\t? handlers.search\n\t\t\t\t: handlers.describe;\n\tthrowIfAborted(props.signal);\n\tconst batchResult = await handler({ identity: props.scope, input: props.input });\n\tthrowIfAborted(props.signal);\n\tyield { kind: 'completed', result: scalarBatchResultToCoreResult(batchResult) };\n}\n\nasync function* callToolStream(props: {\n\treadonly input: unknown;\n\treadonly scope: PortalAgentScope;\n\treadonly signal?: AbortSignal;\n\treadonly toolRuntime: PortalToolRuntime;\n}): AsyncIterable<PortalCoreEvent> {\n\tconst parsedInput = portalCallInputSchema.safeParse(props.input);\n\tconst queuedEvents: PortalCoreEvent[] = [];\n\tlet notifyQueuedEvent: (() => void) | undefined;\n\tlet executionDone = false;\n\tconst pushEvent = (event: PortalCoreEvent): void => {\n\t\tassertPortalCoreEventSize(event);\n\t\tif (queuedEvents.length >= maxQueuedPortalCoreEvents) {\n\t\t\tthrow new Error(`MCP Portal core event queue exceeded ${maxQueuedPortalCoreEvents} events.`);\n\t\t}\n\t\tqueuedEvents.push(event);\n\t\tnotifyQueuedEvent?.();\n\t\tnotifyQueuedEvent = undefined;\n\t};\n\tconst streamingToolRuntime: PortalToolRuntime = {\n\t\t...props.toolRuntime,\n\t\tcallUpstreamTool: async (call) => {\n\t\t\tthrowIfAborted(props.signal);\n\t\t\tpushEvent({\n\t\t\t\tkind: 'item_started',\n\t\t\t\tnamespace: call.namespace,\n\t\t\t\trequestId: call.requestId,\n\t\t\t\ttoolName: call.toolName,\n\t\t\t});\n\t\t\tpushEvent({\n\t\t\t\tkind: 'progress',\n\t\t\t\tmessage: `Calling upstream MCP tool ${call.namespace}.${call.toolName}.`,\n\t\t\t\trequestId: call.requestId,\n\t\t\t});\n\t\t\treturn await props.toolRuntime.callUpstreamTool({\n\t\t\t\t...call,\n\t\t\t\t...(props.signal !== undefined ? { signal: props.signal } : {}),\n\t\t\t\tonEvent: (event) => {\n\t\t\t\t\tif (event.kind === 'progress') {\n\t\t\t\t\t\tpushEvent({\n\t\t\t\t\t\t\tkind: 'progress',\n\t\t\t\t\t\t\t...(event.message !== undefined ? { message: event.message } : {}),\n\t\t\t\t\t\t\t...(event.progress !== undefined ? { progress: event.progress } : {}),\n\t\t\t\t\t\t\trequestId: call.requestId,\n\t\t\t\t\t\t\t...(event.total !== undefined ? { total: event.total } : {}),\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (event.kind === 'partial_content') {\n\t\t\t\t\t\tpushEvent({\n\t\t\t\t\t\t\tcontent: event.content,\n\t\t\t\t\t\t\tkind: 'partial_content',\n\t\t\t\t\t\t\trequestId: call.requestId,\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tpushEvent({\n\t\t\t\t\t\tkind: 'upstream_notification',\n\t\t\t\t\t\tmethod: event.method,\n\t\t\t\t\t\tparams: event.params,\n\t\t\t\t\t\trequestId: call.requestId,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t};\n\tconst handlers = createPortalToolHandlers(streamingToolRuntime);\n\tif (!parsedInput.success) {\n\t\tconst batchResult = await handlers.call({ identity: props.scope, input: props.input });\n\t\tyield { kind: 'completed', result: scalarBatchResultToCoreResult(batchResult) };\n\t\treturn;\n\t}\n\n\tconst itemResults: PortalCoreItemResult[] = [];\n\tconst batchResultPromise = handlers\n\t\t.call({\n\t\t\tidentity: props.scope,\n\t\t\tinput: props.input,\n\t\t})\n\t\t.finally(() => {\n\t\t\texecutionDone = true;\n\t\t\tnotifyQueuedEvent?.();\n\t\t\tnotifyQueuedEvent = undefined;\n\t\t});\n\tconst hasPendingExecutionEvents = (): boolean => !executionDone || queuedEvents.length > 0;\n\twhile (hasPendingExecutionEvents()) {\n\t\tconst event = queuedEvents.shift();\n\t\tif (event !== undefined) {\n\t\t\tyield event;\n\t\t\tcontinue;\n\t\t}\n\t\tthrowIfAborted(props.signal);\n\t\t// Streaming consumes events as they arrive; there is no parallel work to collect here.\n\t\t// eslint-disable-next-line no-await-in-loop\n\t\tawait waitForQueuedCoreEvent({\n\t\t\tsetNotifyQueuedEvent: (notify) => {\n\t\t\t\tnotifyQueuedEvent = notify;\n\t\t\t},\n\t\t\t...(props.signal !== undefined ? { signal: props.signal } : {}),\n\t\t});\n\t}\n\tconst batchResult = await batchResultPromise;\n\tthrowIfAborted(props.signal);\n\tif (batchResult.errors.length > 0) {\n\t\tyield { kind: 'completed', result: scalarBatchResultToCoreResult(batchResult) };\n\t\treturn;\n\t}\n\tfor (const request of parsedInput.data.calls) {\n\t\tconst portalResult = batchResult.results[request.id];\n\t\tconst itemResult =\n\t\t\tportalResult === undefined\n\t\t\t\t? ({\n\t\t\t\t\t\terror: {\n\t\t\t\t\t\t\tcode: 'portal_item_missing',\n\t\t\t\t\t\t\tmessage: `MCP Portal did not return a result for request \"${request.id}\".`,\n\t\t\t\t\t\t\tnamespace: request.namespace,\n\t\t\t\t\t\t\ttoolName: request.toolName,\n\t\t\t\t\t\t},\n\t\t\t\t\t\trequestId: request.id,\n\t\t\t\t\t\tstatus: 'failed',\n\t\t\t\t\t} satisfies PortalCoreItemResult)\n\t\t\t\t: itemResultFromPortalToolResult(request.id, portalResult);\n\t\titemResults.push(itemResult);\n\t\tif (itemResult.status === 'success') {\n\t\t\tyield { kind: 'item_completed', requestId: request.id, result: itemResult };\n\t\t} else {\n\t\t\tyield { error: itemResult.error, kind: 'item_failed', requestId: request.id };\n\t\t}\n\t}\n\n\tyield {\n\t\tkind: 'completed',\n\t\tresult: batchItemsToCoreResult({ diagnostics: batchResult.diagnostics, items: itemResults }),\n\t};\n}\n\nexport function createPortalCore(props: CreatePortalCoreProps): PortalCore {\n\tconst sessionManager = createPortalSessionManager({\n\t\taccessPolicy: props.accessPolicy,\n\t\tcatalogTtlMs: props.catalogTtlMs,\n\t\truntime: props.runtime,\n\t\t...(props.skills !== undefined ? { skills: props.skills } : {}),\n\t\tupstreamNamespaces: props.upstreamNamespaces,\n\t});\n\tconst createdAgentScopeIds = new Set<string>();\n\tconst approval: PortalApprovalEvaluator =\n\t\tprops.approval ??\n\t\t(() => {\n\t\t\tif (props.approvalTrustBoundary === 'openclaw-before-tool-call-hook') {\n\t\t\t\treturn { kind: 'allow' };\n\t\t\t}\n\t\t\tthrow new Error('MCP Portal approval evaluation is not configured.');\n\t\t});\n\tconst toolRuntime: PortalToolRuntime = {\n\t\tapproval,\n\t\tcallUpstreamTool: props.runtime.callUpstreamTool,\n\t\tgetSession: sessionManager.getSession,\n\t};\n\n\tasync function* callStream(call: PortalCoreStreamCall): AsyncIterable<PortalCoreEvent> {\n\t\ttry {\n\t\t\tthrowIfAborted(call.signal);\n\t\t\tyield { kind: 'started', toolName: call.toolName };\n\t\t\tthrowIfAborted(call.signal);\n\t\t\tif (call.toolName === 'mcp_portal_call') {\n\t\t\t\tyield* callToolStream({\n\t\t\t\t\tinput: call.input,\n\t\t\t\t\tscope: call.scope,\n\t\t\t\t\t...(call.signal !== undefined ? { signal: call.signal } : {}),\n\t\t\t\t\ttoolRuntime,\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tyield* scalarToolStream({\n\t\t\t\tinput: call.input,\n\t\t\t\tscope: call.scope,\n\t\t\t\t...(call.signal !== undefined ? { signal: call.signal } : {}),\n\t\t\t\tsessionManager,\n\t\t\t\ttoolName: call.toolName,\n\t\t\t\ttoolRuntime,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tyield { error, kind: 'failed' };\n\t\t}\n\t}\n\n\treturn {\n\t\tapproval: {\n\t\t\tevaluateCalls: (calls, scope, approvalToken) => approval(calls, scope, approvalToken),\n\t\t},\n\t\tcallStream,\n\t\tclose: async () => {\n\t\t\tawait Promise.all(\n\t\t\t\t[...createdAgentScopeIds].map((agentScopeId) =>\n\t\t\t\t\tsessionManager.invalidateAgentScope(agentScopeId),\n\t\t\t\t),\n\t\t\t);\n\t\t},\n\t\tcollectPortalCoreResult,\n\t\tcreateAgentScope: (input) => {\n\t\t\tconst scope = createPortalAgentIdentity(input);\n\t\t\tcreatedAgentScopeIds.add(scope.agentScopeId);\n\t\t\treturn scope;\n\t\t},\n\t\tdescribeTools: (scope) => {\n\t\t\tconst policy = resolvePortalAccessPolicy({\n\t\t\t\tconfig: props.accessPolicy,\n\t\t\t\tidentity: scope,\n\t\t\t\tupstreamNamespaces: props.upstreamNamespaces,\n\t\t\t});\n\t\t\treturn listPortalCoreToolDescriptors(policy.allowedNamespaces);\n\t\t},\n\t\tinvalidateAgentScope: async (agentScopeId) => {\n\t\t\tcreatedAgentScopeIds.delete(agentScopeId);\n\t\t\tawait sessionManager.invalidateAgentScope(agentScopeId);\n\t\t},\n\t\tinvalidateSession: async (scope) => {\n\t\t\tawait sessionManager.invalidateSession(scope);\n\t\t},\n\t\tupstreamNamespaces: props.upstreamNamespaces,\n\t};\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"portal-core-CZQI7Ob6.d.ts","names":[],"sources":["../src/core/portal-tools.ts","../src/core/portal-core.ts"],"mappings":"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"}
|