@agent-native/core 0.49.22 → 0.49.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/production-agent.d.ts +1 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +15 -0
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/tool-search.d.ts.map +1 -1
- package/dist/agent/tool-search.js +32 -7
- package/dist/agent/tool-search.js.map +1 -1
- package/dist/cli/connect.d.ts +2 -3
- package/dist/cli/connect.d.ts.map +1 -1
- package/dist/cli/connect.js +60 -37
- package/dist/cli/connect.js.map +1 -1
- package/dist/cli/pr-visual-recap-workflow.d.ts +5 -7
- package/dist/cli/pr-visual-recap-workflow.d.ts.map +1 -1
- package/dist/cli/pr-visual-recap-workflow.js +5 -7
- package/dist/cli/pr-visual-recap-workflow.js.map +1 -1
- package/dist/cli/recap.d.ts +44 -52
- package/dist/cli/recap.d.ts.map +1 -1
- package/dist/cli/recap.js +441 -414
- package/dist/cli/recap.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +6 -3
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +1 -1
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +23 -3
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/agent-chat.d.ts +8 -0
- package/dist/client/agent-chat.d.ts.map +1 -1
- package/dist/client/agent-chat.js +43 -1
- package/dist/client/agent-chat.js.map +1 -1
- package/dist/client/blocks/library/AnnotatedCodeBlock.d.ts.map +1 -1
- package/dist/client/blocks/library/AnnotatedCodeBlock.js +4 -1
- package/dist/client/blocks/library/AnnotatedCodeBlock.js.map +1 -1
- package/dist/client/blocks/library/DiffBlock.d.ts.map +1 -1
- package/dist/client/blocks/library/DiffBlock.js +20 -7
- package/dist/client/blocks/library/DiffBlock.js.map +1 -1
- package/dist/client/blocks/library/annotation-rail.js +5 -5
- package/dist/client/blocks/library/annotation-rail.js.map +1 -1
- package/dist/client/builder-frame.d.ts +2 -0
- package/dist/client/builder-frame.d.ts.map +1 -1
- package/dist/client/builder-frame.js +2 -0
- package/dist/client/builder-frame.js.map +1 -1
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +15 -2
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/mcp-app-host.d.ts +3 -0
- package/dist/client/mcp-app-host.d.ts.map +1 -1
- package/dist/client/mcp-app-host.js +13 -0
- package/dist/client/mcp-app-host.js.map +1 -1
- package/dist/coding-tools/run-code.d.ts.map +1 -1
- package/dist/coding-tools/run-code.js +69 -17
- package/dist/coding-tools/run-code.js.map +1 -1
- package/dist/integrations/plugin.d.ts.map +1 -1
- package/dist/integrations/plugin.js +2 -0
- package/dist/integrations/plugin.js.map +1 -1
- package/dist/mcp/build-server.d.ts +12 -10
- package/dist/mcp/build-server.d.ts.map +1 -1
- package/dist/mcp/build-server.js +53 -89
- package/dist/mcp/build-server.js.map +1 -1
- package/dist/mcp/connect-route.d.ts.map +1 -1
- package/dist/mcp/connect-route.js +5 -4
- package/dist/mcp/connect-route.js.map +1 -1
- package/dist/mcp/oauth-token.d.ts +6 -5
- package/dist/mcp/oauth-token.d.ts.map +1 -1
- package/dist/mcp/oauth-token.js.map +1 -1
- package/dist/mcp/stdio.d.ts.map +1 -1
- package/dist/mcp/stdio.js +9 -2
- package/dist/mcp/stdio.js.map +1 -1
- package/dist/provider-api/staging.d.ts.map +1 -1
- package/dist/provider-api/staging.js +6 -4
- package/dist/provider-api/staging.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts +10 -7
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/docs/content/actions.md +1 -1
- package/docs/content/external-agents.md +53 -40
- package/docs/content/mcp-protocol.md +16 -11
- package/docs/content/pr-visual-recap.md +1 -1
- package/package.json +1 -1
|
@@ -15,11 +15,14 @@ export interface McpAppModelContextUpdate {
|
|
|
15
15
|
content?: McpAppModelContextContentPart[];
|
|
16
16
|
structuredContent?: unknown;
|
|
17
17
|
}
|
|
18
|
+
export type McpAppHostRequestMode = "act" | "plan";
|
|
18
19
|
export interface McpAppHostChatMessage {
|
|
19
20
|
message: string;
|
|
20
21
|
context?: string;
|
|
21
22
|
content?: McpAppModelContextContentPart[];
|
|
22
23
|
structuredContent?: unknown;
|
|
24
|
+
mode?: McpAppHostRequestMode;
|
|
25
|
+
requestMode?: McpAppHostRequestMode;
|
|
23
26
|
}
|
|
24
27
|
export interface McpAppHostCapabilities {
|
|
25
28
|
updateModelContext?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-app-host.d.ts","sourceRoot":"","sources":["../../src/client/mcp-app-host.ts"],"names":[],"mappings":"AAeA,eAAO,MAAM,uCAAuC;;;;;;CAM1C,CAAC;AAEX,MAAM,MAAM,gCAAgC,GAC1C,CAAC,OAAO,uCAAuC,CAAC,CAAC,MAAM,OAAO,uCAAuC,CAAC,CAAC;AAEzG,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,KAAK,GAAG,YAAY,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAEhF,MAAM,WAAW,6BAA6B;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,CAAC,EAAE,6BAA6B,EAAE,CAAC;IAC1C,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,6BAA6B,EAAE,CAAC;IAC1C,iBAAiB,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"mcp-app-host.d.ts","sourceRoot":"","sources":["../../src/client/mcp-app-host.ts"],"names":[],"mappings":"AAeA,eAAO,MAAM,uCAAuC;;;;;;CAM1C,CAAC;AAEX,MAAM,MAAM,gCAAgC,GAC1C,CAAC,OAAO,uCAAuC,CAAC,CAAC,MAAM,OAAO,uCAAuC,CAAC,CAAC;AAEzG,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,KAAK,GAAG,YAAY,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAEhF,MAAM,WAAW,6BAA6B;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,CAAC,EAAE,6BAA6B,EAAE,CAAC;IAC1C,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,MAAM,qBAAqB,GAAG,KAAK,GAAG,MAAM,CAAC;AAEnD,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,6BAA6B,EAAE,CAAC;IAC1C,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,IAAI,CAAC,EAAE,qBAAqB,CAAC;IAC7B,WAAW,CAAC,EAAE,qBAAqB,CAAC;CACrC;AAED,MAAM,WAAW,sBAAsB;IACrC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACnC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,YAAY,CAAC,EAAE,sBAAsB,CAAC;IACtC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAClC,YAAY,EAAE,sBAAsB,GAAG,IAAI,CAAC;IAC5C,OAAO,EAAE,OAAO,CAAC;CAClB;AAkfD,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,qBAAqB,GAC1B,OAAO,CAAC,OAAO,CAAC,GAAG,KAAK,CAuE1B;AAED,wBAAgB,oBAAoB,IAAI,yBAAyB,CAKhE;AAED,wBAAgB,oBAAoB,IAAI,yBAAyB,CAYhE;AAED,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,wBAAwB,GAC/B,OAAO,CAAC,OAAO,CAAC,GAAG,KAAK,CAU1B;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,KAAK,CAKxE;AAED,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,OAAO,CAAC,GAAG,KAAK,CAM1B;AAID,oDAAoD;AACpD,wBAAgB,wBAAwB,IAAI,IAAI,CAQ/C"}
|
|
@@ -247,6 +247,7 @@ function postHostRequest(type, data) {
|
|
|
247
247
|
function postWrapperHostChat(chat) {
|
|
248
248
|
ensureListener();
|
|
249
249
|
const id = requestId();
|
|
250
|
+
const requestMode = normalizeMcpAppHostRequestMode(chat.requestMode ?? chat.mode);
|
|
250
251
|
return new Promise((resolve) => {
|
|
251
252
|
const timeout = setTimeout(() => {
|
|
252
253
|
pending.delete(id);
|
|
@@ -261,6 +262,7 @@ function postWrapperHostChat(chat) {
|
|
|
261
262
|
message: chat.message,
|
|
262
263
|
context: chat.context?.trim() || "",
|
|
263
264
|
submit: true,
|
|
265
|
+
...(requestMode ? { mode: requestMode, requestMode } : {}),
|
|
264
266
|
...(chat.content?.length ? { content: chat.content } : {}),
|
|
265
267
|
...(chat.structuredContent !== undefined
|
|
266
268
|
? { structuredContent: chat.structuredContent }
|
|
@@ -286,6 +288,9 @@ function readOpenAiBridge() {
|
|
|
286
288
|
function objectValue(value) {
|
|
287
289
|
return isRecord(value) ? value : {};
|
|
288
290
|
}
|
|
291
|
+
function normalizeMcpAppHostRequestMode(value) {
|
|
292
|
+
return value === "act" || value === "plan" ? value : undefined;
|
|
293
|
+
}
|
|
289
294
|
function postJsonRpcNotification(method, params) {
|
|
290
295
|
if (!isInChildFrame())
|
|
291
296
|
return;
|
|
@@ -407,6 +412,10 @@ export function sendMcpAppHostMessage(chat) {
|
|
|
407
412
|
return (async () => {
|
|
408
413
|
const openAiBridge = readOpenAiBridge();
|
|
409
414
|
const context = chat.context?.trim() || null;
|
|
415
|
+
const requestMode = normalizeMcpAppHostRequestMode(chat.requestMode ?? chat.mode);
|
|
416
|
+
const requestModePayload = requestMode
|
|
417
|
+
? { mode: requestMode, requestMode }
|
|
418
|
+
: {};
|
|
410
419
|
const content = chat.content?.length
|
|
411
420
|
? chat.content
|
|
412
421
|
: [{ type: "text", text: chat.message }];
|
|
@@ -425,6 +434,7 @@ export function sendMcpAppHostMessage(chat) {
|
|
|
425
434
|
agentNativeChatContext: context,
|
|
426
435
|
agentNativeModelContext: {
|
|
427
436
|
content: contextContent,
|
|
437
|
+
...requestModePayload,
|
|
428
438
|
...(chat.structuredContent !== undefined
|
|
429
439
|
? { structuredContent: chat.structuredContent }
|
|
430
440
|
: {}),
|
|
@@ -434,6 +444,7 @@ export function sendMcpAppHostMessage(chat) {
|
|
|
434
444
|
await openAiBridge.sendFollowUpMessage({
|
|
435
445
|
prompt: chat.message,
|
|
436
446
|
scrollToBottom: true,
|
|
447
|
+
...requestModePayload,
|
|
437
448
|
});
|
|
438
449
|
return true;
|
|
439
450
|
}
|
|
@@ -441,6 +452,7 @@ export function sendMcpAppHostMessage(chat) {
|
|
|
441
452
|
try {
|
|
442
453
|
await postJsonRpcRequest("ui/update-model-context", {
|
|
443
454
|
content: contextContent,
|
|
455
|
+
...requestModePayload,
|
|
444
456
|
...(chat.structuredContent !== undefined
|
|
445
457
|
? { structuredContent: chat.structuredContent }
|
|
446
458
|
: {}),
|
|
@@ -453,6 +465,7 @@ export function sendMcpAppHostMessage(chat) {
|
|
|
453
465
|
await postJsonRpcRequest("ui/message", {
|
|
454
466
|
role: "user",
|
|
455
467
|
content,
|
|
468
|
+
...requestModePayload,
|
|
456
469
|
});
|
|
457
470
|
return true;
|
|
458
471
|
})().catch(() => false);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-app-host.js","sourceRoot":"","sources":["../../src/client/mcp-app-host.ts"],"names":[],"mappings":"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","sourcesContent":["import { useSyncExternalStore } from \"react\";\nimport { getFrameOrigin } from \"./frame.js\";\nimport {\n getEmbedAuthToken,\n isEmbedAuthActive,\n markEmbedMcpChatBridgeActive,\n isEmbedMcpChatBridgeActive,\n readEmbedMcpChatBridgeFlagFromUrl,\n} from \"./embed-auth.js\";\nimport {\n EMBED_MODE_QUERY_PARAM,\n EMBED_TOKEN_QUERY_PARAM,\n MCP_APP_CHAT_BRIDGE_QUERY_PARAM,\n} from \"../shared/embed-auth.js\";\n\nexport const AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES = {\n HOST_CONTEXT: \"agentNative.mcpHostContext\",\n UPDATE_MODEL_CONTEXT: \"agentNative.mcpHost.updateModelContext\",\n OPEN_LINK: \"agentNative.mcpHost.openLink\",\n REQUEST_DISPLAY_MODE: \"agentNative.mcpHost.requestDisplayMode\",\n RESPONSE: \"agentNative.mcpHost.response\",\n} as const;\n\nexport type AgentNativeMcpAppHostMessageType =\n (typeof AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES)[keyof typeof AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES];\n\nexport type McpAppDisplayMode = \"inline\" | \"pip\" | \"fullscreen\" | (string & {});\n\nexport interface McpAppModelContextContentPart {\n type: string;\n [key: string]: unknown;\n}\n\nexport interface McpAppModelContextUpdate {\n content?: McpAppModelContextContentPart[];\n structuredContent?: unknown;\n}\n\nexport interface McpAppHostChatMessage {\n message: string;\n context?: string;\n content?: McpAppModelContextContentPart[];\n structuredContent?: unknown;\n}\n\nexport interface McpAppHostCapabilities {\n updateModelContext?: boolean;\n openLink?: boolean;\n displayModes?: McpAppDisplayMode[];\n [key: string]: unknown;\n}\n\nexport interface McpAppHostContext {\n capabilities?: McpAppHostCapabilities;\n [key: string]: unknown;\n}\n\nexport interface McpAppHostContextSnapshot {\n context: McpAppHostContext | null;\n capabilities: McpAppHostCapabilities | null;\n version: unknown;\n}\n\ntype PendingRequest = {\n resolve: (ok: boolean) => void;\n timeout: ReturnType<typeof setTimeout>;\n};\n\ntype PendingJsonRpcRequest = {\n resolve: (result: unknown) => void;\n reject: (error: Error) => void;\n timeout: ReturnType<typeof setTimeout>;\n};\n\ntype HostContextMessage = {\n type: typeof AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES.HOST_CONTEXT;\n data?: {\n context?: unknown;\n capabilities?: unknown;\n version?: unknown;\n };\n};\n\ntype HostResponseMessage = {\n type: typeof AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES.RESPONSE;\n data?: {\n requestId?: unknown;\n ok?: unknown;\n result?: unknown;\n error?: unknown;\n };\n};\n\nconst REQUEST_TIMEOUT_MS = 5000;\nconst DIRECT_MCP_APP_PROTOCOL_VERSION = \"2026-01-26\";\n\nlet snapshot: McpAppHostContextSnapshot = {\n context: null,\n capabilities: null,\n version: null,\n};\nconst EMPTY_HOST_CONTEXT_SNAPSHOT: McpAppHostContextSnapshot = {\n context: null,\n capabilities: null,\n version: null,\n};\nconst listeners = new Set<() => void>();\nconst pending = new Map<string, PendingRequest>();\nconst jsonRpcPending = new Map<string, PendingJsonRpcRequest>();\nlet directMcpAppInit: Promise<boolean> | null = null;\nlet listenerInstalled = false;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction isBrowserWindow(): boolean {\n return (\n typeof window !== \"undefined\" && typeof window.postMessage === \"function\"\n );\n}\n\nfunction isInChildFrame(): boolean {\n if (!isBrowserWindow()) return false;\n try {\n return window.parent !== window;\n } catch {\n return false;\n }\n}\n\nfunction isMcpAppBridgeEnabled(): boolean {\n if (!isBrowserWindow()) return false;\n if (readEmbedMcpChatBridgeFlagFromUrl()) markEmbedMcpChatBridgeActive();\n if (isEmbedMcpChatBridgeActive() && isEmbedAuthActive()) return true;\n const params = new URLSearchParams(window.location.search || \"\");\n return (\n params.get(EMBED_MODE_QUERY_PARAM) === \"1\" &&\n (params.has(EMBED_TOKEN_QUERY_PARAM) || Boolean(getEmbedAuthToken())) &&\n params.get(MCP_APP_CHAT_BRIDGE_QUERY_PARAM) === \"1\"\n );\n}\n\nfunction isClaudeMcpContentHost(): boolean {\n if (!isBrowserWindow()) return false;\n try {\n return /(^|\\.)claudemcpcontent\\.com$/i.test(window.location.hostname || \"\");\n } catch {\n return false;\n }\n}\n\nfunction hasWrapperBridge(): boolean {\n if (!isBrowserWindow()) return false;\n const params = new URLSearchParams(window.location.search || \"\");\n const mode =\n params.get(\"embedMode\") ??\n params.get(\"renderMode\") ??\n params.get(\"embed_mode\") ??\n \"\";\n if (mode === \"iframe\" || mode === \"nested\") return true;\n if (params.get(\"nested\") === \"1\" || params.get(\"frame\") === \"iframe\") {\n return true;\n }\n if (isClaudeMcpContentHost()) return false;\n return Boolean(getFrameOrigin());\n}\n\nfunction isTrustedParentMessage(event: MessageEvent): boolean {\n if (!isInChildFrame()) return false;\n if (event.source !== window.parent) return false;\n // Defense in depth: once the parent's real origin is known (captured from the\n // browser-stamped event.origin during the frameOrigin handshake, so it can't\n // be spoofed), also require inbound messages to come from that origin. When\n // it isn't known yet (null) or is opaque (\"null\"), fall back to source-only.\n const expectedOrigin = getFrameOrigin();\n if (expectedOrigin && expectedOrigin !== \"null\") {\n return event.origin === expectedOrigin;\n }\n return true;\n}\n\nfunction requestId(): string {\n return `mcp-host-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;\n}\n\nfunction jsonRpcRequestId(): string {\n return `mcp-ui-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;\n}\n\nfunction notify() {\n for (const listener of listeners) listener();\n}\n\nfunction updateSnapshot(data: HostContextMessage[\"data\"]): void {\n if (!isRecord(data)) return;\n snapshot = {\n context: isRecord(data.context)\n ? (data.context as McpAppHostContext)\n : snapshot.context,\n capabilities: isRecord(data.capabilities)\n ? (data.capabilities as McpAppHostCapabilities)\n : snapshot.capabilities,\n version: data.version !== undefined ? data.version : snapshot.version,\n };\n notify();\n}\n\nfunction updateSnapshotFromInitialize(result: unknown): void {\n if (!isRecord(result)) return;\n updateSnapshot({\n context: result.hostContext,\n capabilities: result.hostCapabilities,\n version: result.hostInfo ?? result.protocolVersion,\n });\n}\n\nfunction updateSnapshotFromOpenAiBridge(bridge: OpenAiAppBridge): void {\n updateSnapshot({\n context: {\n displayMode: bridge.displayMode,\n availableDisplayModes:\n typeof bridge.requestDisplayMode === \"function\"\n ? [\"inline\", \"fullscreen\", \"pip\"]\n : [],\n maxHeight: bridge.maxHeight,\n locale: bridge.locale,\n theme: bridge.theme,\n view: bridge.view,\n },\n capabilities: {\n updateModelContext: typeof bridge.setWidgetState === \"function\",\n openLink: typeof bridge.openExternal === \"function\",\n displayModes:\n typeof bridge.requestDisplayMode === \"function\"\n ? [\"inline\", \"fullscreen\", \"pip\"]\n : [],\n openai: true,\n },\n version: bridge.userAgent,\n });\n}\n\nfunction resolvePending(data: HostResponseMessage[\"data\"]): void {\n if (!isRecord(data) || typeof data.requestId !== \"string\") return;\n const request = pending.get(data.requestId);\n if (!request) return;\n pending.delete(data.requestId);\n clearTimeout(request.timeout);\n request.resolve(data.ok === true);\n}\n\nfunction resolveJsonRpc(data: Record<string, unknown>): void {\n const id = typeof data.id === \"string\" ? data.id : String(data.id ?? \"\");\n if (!id) return;\n const request = jsonRpcPending.get(id);\n if (!request) return;\n jsonRpcPending.delete(id);\n clearTimeout(request.timeout);\n if (isRecord(data.error)) {\n const message =\n typeof data.error.message === \"string\"\n ? data.error.message\n : \"MCP Apps host request failed.\";\n request.reject(new Error(message));\n return;\n }\n request.resolve(data.result ?? {});\n}\n\nfunction handleJsonRpcNotification(message: Record<string, unknown>): void {\n if (message.method !== \"ui/notifications/host-context-changed\") return;\n updateSnapshot({\n context: isRecord(message.params) ? message.params : undefined,\n });\n}\n\nfunction onMessage(event: MessageEvent): void {\n if (!isTrustedParentMessage(event)) return;\n const message = event.data;\n if (!isRecord(message)) return;\n\n if (message.type === AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES.HOST_CONTEXT) {\n updateSnapshot((message as HostContextMessage).data);\n return;\n }\n\n if (message.type === AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES.RESPONSE) {\n resolvePending((message as HostResponseMessage).data);\n return;\n }\n\n if (message.jsonrpc === \"2.0\") {\n if (\"id\" in message && (\"result\" in message || \"error\" in message)) {\n resolveJsonRpc(message);\n return;\n }\n if (typeof message.method === \"string\") {\n handleJsonRpcNotification(message);\n }\n }\n}\n\nfunction ensureListener(): void {\n if (!isBrowserWindow() || listenerInstalled) return;\n window.addEventListener(\"message\", onMessage);\n listenerInstalled = true;\n}\n\nfunction postHostRequest(\n type:\n | typeof AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES.UPDATE_MODEL_CONTEXT\n | typeof AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES.OPEN_LINK\n | typeof AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES.REQUEST_DISPLAY_MODE,\n data: Record<string, unknown>,\n): Promise<boolean> | false {\n ensureListener();\n if (!isInChildFrame() || !isMcpAppBridgeEnabled()) return false;\n\n if (!hasWrapperBridge()) {\n return postDirectHostRequest(type, data);\n }\n\n const id =\n typeof data.requestId === \"string\" && data.requestId\n ? data.requestId\n : requestId();\n const payload = { ...data, requestId: id };\n\n return new Promise((resolve) => {\n const timeout = setTimeout(() => {\n pending.delete(id);\n resolve(false);\n }, REQUEST_TIMEOUT_MS);\n pending.set(id, { resolve, timeout });\n\n try {\n window.parent.postMessage({ type, data: payload }, \"*\");\n } catch {\n pending.delete(id);\n clearTimeout(timeout);\n resolve(false);\n }\n });\n}\n\nfunction postWrapperHostChat(chat: McpAppHostChatMessage): Promise<boolean> {\n ensureListener();\n const id = requestId();\n return new Promise((resolve) => {\n const timeout = setTimeout(() => {\n pending.delete(id);\n resolve(false);\n }, REQUEST_TIMEOUT_MS);\n pending.set(id, { resolve, timeout });\n\n try {\n window.parent.postMessage(\n {\n type: \"agentNative.submitChat\",\n data: {\n requestId: id,\n message: chat.message,\n context: chat.context?.trim() || \"\",\n submit: true,\n ...(chat.content?.length ? { content: chat.content } : {}),\n ...(chat.structuredContent !== undefined\n ? { structuredContent: chat.structuredContent }\n : {}),\n },\n },\n \"*\",\n );\n } catch {\n pending.delete(id);\n clearTimeout(timeout);\n resolve(false);\n }\n });\n}\n\ninterface OpenAiAppBridge {\n widgetState?: unknown;\n displayMode?: unknown;\n maxHeight?: unknown;\n locale?: unknown;\n theme?: unknown;\n view?: unknown;\n userAgent?: unknown;\n setWidgetState?: (state: unknown) => void;\n sendFollowUpMessage?: (args: {\n prompt: string;\n scrollToBottom?: boolean;\n }) => unknown | Promise<unknown>;\n openExternal?: (args: {\n href: string;\n redirectUrl?: boolean;\n }) => unknown | Promise<unknown>;\n requestDisplayMode?: (args: {\n mode: McpAppDisplayMode;\n }) => unknown | Promise<unknown>;\n}\n\nfunction readOpenAiBridge(): OpenAiAppBridge | null {\n if (!isBrowserWindow()) return null;\n const bridge = (window as unknown as { openai?: unknown }).openai;\n return bridge && typeof bridge === \"object\"\n ? (bridge as OpenAiAppBridge)\n : null;\n}\n\nfunction objectValue(value: unknown): Record<string, unknown> {\n return isRecord(value) ? value : {};\n}\n\nfunction postJsonRpcNotification(method: string, params?: unknown): void {\n if (!isInChildFrame()) return;\n try {\n window.parent.postMessage({ jsonrpc: \"2.0\", method, params }, \"*\");\n } catch {\n // Best-effort lifecycle notification.\n }\n}\n\nfunction postJsonRpcRequest(\n method: string,\n params?: unknown,\n): Promise<unknown> | false {\n ensureListener();\n if (!isInChildFrame()) return false;\n\n const id = jsonRpcRequestId();\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n jsonRpcPending.delete(id);\n reject(new Error(\"MCP Apps host did not respond.\"));\n }, REQUEST_TIMEOUT_MS);\n jsonRpcPending.set(id, { resolve, reject, timeout });\n\n try {\n window.parent.postMessage({ jsonrpc: \"2.0\", id, method, params }, \"*\");\n } catch (err) {\n jsonRpcPending.delete(id);\n clearTimeout(timeout);\n reject(err instanceof Error ? err : new Error(String(err)));\n }\n });\n}\n\nasync function ensureDirectMcpAppInitialized(): Promise<boolean> {\n if (!isInChildFrame() || !isMcpAppBridgeEnabled()) return false;\n if (hasWrapperBridge()) return true;\n\n const openAiBridge = readOpenAiBridge();\n if (openAiBridge) {\n updateSnapshotFromOpenAiBridge(openAiBridge);\n return true;\n }\n\n if (!directMcpAppInit) {\n directMcpAppInit = (async () => {\n const result = await postJsonRpcRequest(\"ui/initialize\", {\n protocolVersion: DIRECT_MCP_APP_PROTOCOL_VERSION,\n appInfo: { name: \"Agent Native App\", version: \"1.0.0\" },\n appCapabilities: {\n availableDisplayModes: [\"inline\", \"fullscreen\", \"pip\"],\n },\n });\n updateSnapshotFromInitialize(result);\n postJsonRpcNotification(\"ui/notifications/initialized\", {});\n return true;\n })().catch(() => {\n // Reset so the next call retries the handshake. Otherwise one timed-out\n // ui/initialize (e.g. host briefly unresponsive) leaves a permanently\n // resolved `Promise<false>` cached here, and every later bridge call\n // fails until full page reload.\n directMcpAppInit = null;\n return false as boolean;\n });\n }\n\n return directMcpAppInit;\n}\n\nasync function waitForDirectMcpAppInitialized(): Promise<void> {\n const ok = await ensureDirectMcpAppInitialized();\n if (!ok) throw new Error(\"MCP Apps host bridge is not available.\");\n}\n\nasync function postDirectHostRequest(\n type:\n | typeof AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES.UPDATE_MODEL_CONTEXT\n | typeof AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES.OPEN_LINK\n | typeof AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES.REQUEST_DISPLAY_MODE,\n data: Record<string, unknown>,\n): Promise<boolean> {\n const openAiBridge = readOpenAiBridge();\n if (openAiBridge) {\n updateSnapshotFromOpenAiBridge(openAiBridge);\n if (\n type === AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES.UPDATE_MODEL_CONTEXT &&\n typeof openAiBridge.setWidgetState === \"function\"\n ) {\n openAiBridge.setWidgetState({\n ...objectValue(openAiBridge.widgetState),\n agentNativeModelContext: {\n ...(Array.isArray(data.content) ? { content: data.content } : {}),\n ...(data.structuredContent !== undefined\n ? { structuredContent: data.structuredContent }\n : {}),\n },\n });\n return true;\n }\n if (\n type === AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES.OPEN_LINK &&\n typeof openAiBridge.openExternal === \"function\" &&\n typeof data.url === \"string\"\n ) {\n await openAiBridge.openExternal({\n href: data.url,\n redirectUrl: false,\n });\n return true;\n }\n if (\n type === AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES.REQUEST_DISPLAY_MODE &&\n typeof openAiBridge.requestDisplayMode === \"function\" &&\n typeof data.mode === \"string\"\n ) {\n await openAiBridge.requestDisplayMode({ mode: data.mode });\n updateSnapshotFromOpenAiBridge(openAiBridge);\n return true;\n }\n }\n\n await waitForDirectMcpAppInitialized();\n const method =\n type === AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES.UPDATE_MODEL_CONTEXT\n ? \"ui/update-model-context\"\n : type === AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES.OPEN_LINK\n ? \"ui/open-link\"\n : \"ui/request-display-mode\";\n await postJsonRpcRequest(method, data);\n return true;\n}\n\nexport function sendMcpAppHostMessage(\n chat: McpAppHostChatMessage,\n): Promise<boolean> | false {\n if (!chat.message.trim() || !isInChildFrame() || !isMcpAppBridgeEnabled()) {\n return false;\n }\n\n if (hasWrapperBridge()) return postWrapperHostChat(chat);\n\n return (async () => {\n const openAiBridge = readOpenAiBridge();\n const context = chat.context?.trim() || null;\n const content = chat.content?.length\n ? chat.content\n : [{ type: \"text\", text: chat.message }];\n const contextContent = context\n ? [\n { type: \"text\", text: context },\n ...content.filter((part) => part && part.type !== \"text\"),\n ]\n : content.filter((part) => part && part.type !== \"text\");\n if (\n openAiBridge &&\n typeof openAiBridge.sendFollowUpMessage === \"function\"\n ) {\n updateSnapshotFromOpenAiBridge(openAiBridge);\n if (typeof openAiBridge.setWidgetState === \"function\") {\n openAiBridge.setWidgetState({\n ...objectValue(openAiBridge.widgetState),\n agentNativeChatContext: context,\n agentNativeModelContext: {\n content: contextContent,\n ...(chat.structuredContent !== undefined\n ? { structuredContent: chat.structuredContent }\n : {}),\n },\n });\n }\n await openAiBridge.sendFollowUpMessage({\n prompt: chat.message,\n scrollToBottom: true,\n });\n return true;\n }\n\n await waitForDirectMcpAppInitialized();\n try {\n await postJsonRpcRequest(\"ui/update-model-context\", {\n content: contextContent,\n ...(chat.structuredContent !== undefined\n ? { structuredContent: chat.structuredContent }\n : {}),\n });\n } catch {\n // Best effort: a host without model-context support should still receive\n // the visible chat message.\n }\n await postJsonRpcRequest(\"ui/message\", {\n role: \"user\",\n content,\n });\n return true;\n })().catch(() => false);\n}\n\nexport function getMcpAppHostContext(): McpAppHostContextSnapshot {\n ensureListener();\n const bridge = readOpenAiBridge();\n if (bridge) updateSnapshotFromOpenAiBridge(bridge);\n return snapshot;\n}\n\nexport function useMcpAppHostContext(): McpAppHostContextSnapshot {\n ensureListener();\n return useSyncExternalStore(\n (listener) => {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n () => snapshot,\n () => EMPTY_HOST_CONTEXT_SNAPSHOT,\n );\n}\n\nexport function updateMcpAppModelContext(\n update: McpAppModelContextUpdate,\n): Promise<boolean> | false {\n return postHostRequest(\n AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES.UPDATE_MODEL_CONTEXT,\n {\n ...(Array.isArray(update.content) ? { content: update.content } : {}),\n ...(update.structuredContent !== undefined\n ? { structuredContent: update.structuredContent }\n : {}),\n },\n );\n}\n\nexport function openMcpAppHostLink(url: string): Promise<boolean> | false {\n if (!url) return false;\n return postHostRequest(AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES.OPEN_LINK, {\n url,\n });\n}\n\nexport function requestMcpAppDisplayMode(\n mode: McpAppDisplayMode,\n): Promise<boolean> | false {\n if (!mode) return false;\n return postHostRequest(\n AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES.REQUEST_DISPLAY_MODE,\n { mode },\n );\n}\n\nensureListener();\n\n/** Internal test helper. Do not use in app code. */\nexport function _resetMcpAppHostForTests(): void {\n for (const request of pending.values()) clearTimeout(request.timeout);\n for (const request of jsonRpcPending.values()) clearTimeout(request.timeout);\n pending.clear();\n jsonRpcPending.clear();\n directMcpAppInit = null;\n snapshot = { context: null, capabilities: null, version: null };\n listeners.clear();\n}\n\nif (isBrowserWindow()) {\n window.addEventListener(\n \"openai:set_globals\",\n () => {\n const bridge = readOpenAiBridge();\n if (bridge) updateSnapshotFromOpenAiBridge(bridge);\n },\n { passive: true },\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"mcp-app-host.js","sourceRoot":"","sources":["../../src/client/mcp-app-host.ts"],"names":[],"mappings":"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","sourcesContent":["import { useSyncExternalStore } from \"react\";\nimport { getFrameOrigin } from \"./frame.js\";\nimport {\n getEmbedAuthToken,\n isEmbedAuthActive,\n markEmbedMcpChatBridgeActive,\n isEmbedMcpChatBridgeActive,\n readEmbedMcpChatBridgeFlagFromUrl,\n} from \"./embed-auth.js\";\nimport {\n EMBED_MODE_QUERY_PARAM,\n EMBED_TOKEN_QUERY_PARAM,\n MCP_APP_CHAT_BRIDGE_QUERY_PARAM,\n} from \"../shared/embed-auth.js\";\n\nexport const AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES = {\n HOST_CONTEXT: \"agentNative.mcpHostContext\",\n UPDATE_MODEL_CONTEXT: \"agentNative.mcpHost.updateModelContext\",\n OPEN_LINK: \"agentNative.mcpHost.openLink\",\n REQUEST_DISPLAY_MODE: \"agentNative.mcpHost.requestDisplayMode\",\n RESPONSE: \"agentNative.mcpHost.response\",\n} as const;\n\nexport type AgentNativeMcpAppHostMessageType =\n (typeof AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES)[keyof typeof AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES];\n\nexport type McpAppDisplayMode = \"inline\" | \"pip\" | \"fullscreen\" | (string & {});\n\nexport interface McpAppModelContextContentPart {\n type: string;\n [key: string]: unknown;\n}\n\nexport interface McpAppModelContextUpdate {\n content?: McpAppModelContextContentPart[];\n structuredContent?: unknown;\n}\n\nexport type McpAppHostRequestMode = \"act\" | \"plan\";\n\nexport interface McpAppHostChatMessage {\n message: string;\n context?: string;\n content?: McpAppModelContextContentPart[];\n structuredContent?: unknown;\n mode?: McpAppHostRequestMode;\n requestMode?: McpAppHostRequestMode;\n}\n\nexport interface McpAppHostCapabilities {\n updateModelContext?: boolean;\n openLink?: boolean;\n displayModes?: McpAppDisplayMode[];\n [key: string]: unknown;\n}\n\nexport interface McpAppHostContext {\n capabilities?: McpAppHostCapabilities;\n [key: string]: unknown;\n}\n\nexport interface McpAppHostContextSnapshot {\n context: McpAppHostContext | null;\n capabilities: McpAppHostCapabilities | null;\n version: unknown;\n}\n\ntype PendingRequest = {\n resolve: (ok: boolean) => void;\n timeout: ReturnType<typeof setTimeout>;\n};\n\ntype PendingJsonRpcRequest = {\n resolve: (result: unknown) => void;\n reject: (error: Error) => void;\n timeout: ReturnType<typeof setTimeout>;\n};\n\ntype HostContextMessage = {\n type: typeof AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES.HOST_CONTEXT;\n data?: {\n context?: unknown;\n capabilities?: unknown;\n version?: unknown;\n };\n};\n\ntype HostResponseMessage = {\n type: typeof AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES.RESPONSE;\n data?: {\n requestId?: unknown;\n ok?: unknown;\n result?: unknown;\n error?: unknown;\n };\n};\n\nconst REQUEST_TIMEOUT_MS = 5000;\nconst DIRECT_MCP_APP_PROTOCOL_VERSION = \"2026-01-26\";\n\nlet snapshot: McpAppHostContextSnapshot = {\n context: null,\n capabilities: null,\n version: null,\n};\nconst EMPTY_HOST_CONTEXT_SNAPSHOT: McpAppHostContextSnapshot = {\n context: null,\n capabilities: null,\n version: null,\n};\nconst listeners = new Set<() => void>();\nconst pending = new Map<string, PendingRequest>();\nconst jsonRpcPending = new Map<string, PendingJsonRpcRequest>();\nlet directMcpAppInit: Promise<boolean> | null = null;\nlet listenerInstalled = false;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction isBrowserWindow(): boolean {\n return (\n typeof window !== \"undefined\" && typeof window.postMessage === \"function\"\n );\n}\n\nfunction isInChildFrame(): boolean {\n if (!isBrowserWindow()) return false;\n try {\n return window.parent !== window;\n } catch {\n return false;\n }\n}\n\nfunction isMcpAppBridgeEnabled(): boolean {\n if (!isBrowserWindow()) return false;\n if (readEmbedMcpChatBridgeFlagFromUrl()) markEmbedMcpChatBridgeActive();\n if (isEmbedMcpChatBridgeActive() && isEmbedAuthActive()) return true;\n const params = new URLSearchParams(window.location.search || \"\");\n return (\n params.get(EMBED_MODE_QUERY_PARAM) === \"1\" &&\n (params.has(EMBED_TOKEN_QUERY_PARAM) || Boolean(getEmbedAuthToken())) &&\n params.get(MCP_APP_CHAT_BRIDGE_QUERY_PARAM) === \"1\"\n );\n}\n\nfunction isClaudeMcpContentHost(): boolean {\n if (!isBrowserWindow()) return false;\n try {\n return /(^|\\.)claudemcpcontent\\.com$/i.test(window.location.hostname || \"\");\n } catch {\n return false;\n }\n}\n\nfunction hasWrapperBridge(): boolean {\n if (!isBrowserWindow()) return false;\n const params = new URLSearchParams(window.location.search || \"\");\n const mode =\n params.get(\"embedMode\") ??\n params.get(\"renderMode\") ??\n params.get(\"embed_mode\") ??\n \"\";\n if (mode === \"iframe\" || mode === \"nested\") return true;\n if (params.get(\"nested\") === \"1\" || params.get(\"frame\") === \"iframe\") {\n return true;\n }\n if (isClaudeMcpContentHost()) return false;\n return Boolean(getFrameOrigin());\n}\n\nfunction isTrustedParentMessage(event: MessageEvent): boolean {\n if (!isInChildFrame()) return false;\n if (event.source !== window.parent) return false;\n // Defense in depth: once the parent's real origin is known (captured from the\n // browser-stamped event.origin during the frameOrigin handshake, so it can't\n // be spoofed), also require inbound messages to come from that origin. When\n // it isn't known yet (null) or is opaque (\"null\"), fall back to source-only.\n const expectedOrigin = getFrameOrigin();\n if (expectedOrigin && expectedOrigin !== \"null\") {\n return event.origin === expectedOrigin;\n }\n return true;\n}\n\nfunction requestId(): string {\n return `mcp-host-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;\n}\n\nfunction jsonRpcRequestId(): string {\n return `mcp-ui-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;\n}\n\nfunction notify() {\n for (const listener of listeners) listener();\n}\n\nfunction updateSnapshot(data: HostContextMessage[\"data\"]): void {\n if (!isRecord(data)) return;\n snapshot = {\n context: isRecord(data.context)\n ? (data.context as McpAppHostContext)\n : snapshot.context,\n capabilities: isRecord(data.capabilities)\n ? (data.capabilities as McpAppHostCapabilities)\n : snapshot.capabilities,\n version: data.version !== undefined ? data.version : snapshot.version,\n };\n notify();\n}\n\nfunction updateSnapshotFromInitialize(result: unknown): void {\n if (!isRecord(result)) return;\n updateSnapshot({\n context: result.hostContext,\n capabilities: result.hostCapabilities,\n version: result.hostInfo ?? result.protocolVersion,\n });\n}\n\nfunction updateSnapshotFromOpenAiBridge(bridge: OpenAiAppBridge): void {\n updateSnapshot({\n context: {\n displayMode: bridge.displayMode,\n availableDisplayModes:\n typeof bridge.requestDisplayMode === \"function\"\n ? [\"inline\", \"fullscreen\", \"pip\"]\n : [],\n maxHeight: bridge.maxHeight,\n locale: bridge.locale,\n theme: bridge.theme,\n view: bridge.view,\n },\n capabilities: {\n updateModelContext: typeof bridge.setWidgetState === \"function\",\n openLink: typeof bridge.openExternal === \"function\",\n displayModes:\n typeof bridge.requestDisplayMode === \"function\"\n ? [\"inline\", \"fullscreen\", \"pip\"]\n : [],\n openai: true,\n },\n version: bridge.userAgent,\n });\n}\n\nfunction resolvePending(data: HostResponseMessage[\"data\"]): void {\n if (!isRecord(data) || typeof data.requestId !== \"string\") return;\n const request = pending.get(data.requestId);\n if (!request) return;\n pending.delete(data.requestId);\n clearTimeout(request.timeout);\n request.resolve(data.ok === true);\n}\n\nfunction resolveJsonRpc(data: Record<string, unknown>): void {\n const id = typeof data.id === \"string\" ? data.id : String(data.id ?? \"\");\n if (!id) return;\n const request = jsonRpcPending.get(id);\n if (!request) return;\n jsonRpcPending.delete(id);\n clearTimeout(request.timeout);\n if (isRecord(data.error)) {\n const message =\n typeof data.error.message === \"string\"\n ? data.error.message\n : \"MCP Apps host request failed.\";\n request.reject(new Error(message));\n return;\n }\n request.resolve(data.result ?? {});\n}\n\nfunction handleJsonRpcNotification(message: Record<string, unknown>): void {\n if (message.method !== \"ui/notifications/host-context-changed\") return;\n updateSnapshot({\n context: isRecord(message.params) ? message.params : undefined,\n });\n}\n\nfunction onMessage(event: MessageEvent): void {\n if (!isTrustedParentMessage(event)) return;\n const message = event.data;\n if (!isRecord(message)) return;\n\n if (message.type === AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES.HOST_CONTEXT) {\n updateSnapshot((message as HostContextMessage).data);\n return;\n }\n\n if (message.type === AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES.RESPONSE) {\n resolvePending((message as HostResponseMessage).data);\n return;\n }\n\n if (message.jsonrpc === \"2.0\") {\n if (\"id\" in message && (\"result\" in message || \"error\" in message)) {\n resolveJsonRpc(message);\n return;\n }\n if (typeof message.method === \"string\") {\n handleJsonRpcNotification(message);\n }\n }\n}\n\nfunction ensureListener(): void {\n if (!isBrowserWindow() || listenerInstalled) return;\n window.addEventListener(\"message\", onMessage);\n listenerInstalled = true;\n}\n\nfunction postHostRequest(\n type:\n | typeof AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES.UPDATE_MODEL_CONTEXT\n | typeof AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES.OPEN_LINK\n | typeof AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES.REQUEST_DISPLAY_MODE,\n data: Record<string, unknown>,\n): Promise<boolean> | false {\n ensureListener();\n if (!isInChildFrame() || !isMcpAppBridgeEnabled()) return false;\n\n if (!hasWrapperBridge()) {\n return postDirectHostRequest(type, data);\n }\n\n const id =\n typeof data.requestId === \"string\" && data.requestId\n ? data.requestId\n : requestId();\n const payload = { ...data, requestId: id };\n\n return new Promise((resolve) => {\n const timeout = setTimeout(() => {\n pending.delete(id);\n resolve(false);\n }, REQUEST_TIMEOUT_MS);\n pending.set(id, { resolve, timeout });\n\n try {\n window.parent.postMessage({ type, data: payload }, \"*\");\n } catch {\n pending.delete(id);\n clearTimeout(timeout);\n resolve(false);\n }\n });\n}\n\nfunction postWrapperHostChat(chat: McpAppHostChatMessage): Promise<boolean> {\n ensureListener();\n const id = requestId();\n const requestMode = normalizeMcpAppHostRequestMode(\n chat.requestMode ?? chat.mode,\n );\n return new Promise((resolve) => {\n const timeout = setTimeout(() => {\n pending.delete(id);\n resolve(false);\n }, REQUEST_TIMEOUT_MS);\n pending.set(id, { resolve, timeout });\n\n try {\n window.parent.postMessage(\n {\n type: \"agentNative.submitChat\",\n data: {\n requestId: id,\n message: chat.message,\n context: chat.context?.trim() || \"\",\n submit: true,\n ...(requestMode ? { mode: requestMode, requestMode } : {}),\n ...(chat.content?.length ? { content: chat.content } : {}),\n ...(chat.structuredContent !== undefined\n ? { structuredContent: chat.structuredContent }\n : {}),\n },\n },\n \"*\",\n );\n } catch {\n pending.delete(id);\n clearTimeout(timeout);\n resolve(false);\n }\n });\n}\n\ninterface OpenAiAppBridge {\n widgetState?: unknown;\n displayMode?: unknown;\n maxHeight?: unknown;\n locale?: unknown;\n theme?: unknown;\n view?: unknown;\n userAgent?: unknown;\n setWidgetState?: (state: unknown) => void;\n sendFollowUpMessage?: (args: {\n prompt: string;\n scrollToBottom?: boolean;\n mode?: McpAppHostRequestMode;\n requestMode?: McpAppHostRequestMode;\n }) => unknown | Promise<unknown>;\n openExternal?: (args: {\n href: string;\n redirectUrl?: boolean;\n }) => unknown | Promise<unknown>;\n requestDisplayMode?: (args: {\n mode: McpAppDisplayMode;\n }) => unknown | Promise<unknown>;\n}\n\nfunction readOpenAiBridge(): OpenAiAppBridge | null {\n if (!isBrowserWindow()) return null;\n const bridge = (window as unknown as { openai?: unknown }).openai;\n return bridge && typeof bridge === \"object\"\n ? (bridge as OpenAiAppBridge)\n : null;\n}\n\nfunction objectValue(value: unknown): Record<string, unknown> {\n return isRecord(value) ? value : {};\n}\n\nfunction normalizeMcpAppHostRequestMode(\n value: unknown,\n): McpAppHostRequestMode | undefined {\n return value === \"act\" || value === \"plan\" ? value : undefined;\n}\n\nfunction postJsonRpcNotification(method: string, params?: unknown): void {\n if (!isInChildFrame()) return;\n try {\n window.parent.postMessage({ jsonrpc: \"2.0\", method, params }, \"*\");\n } catch {\n // Best-effort lifecycle notification.\n }\n}\n\nfunction postJsonRpcRequest(\n method: string,\n params?: unknown,\n): Promise<unknown> | false {\n ensureListener();\n if (!isInChildFrame()) return false;\n\n const id = jsonRpcRequestId();\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n jsonRpcPending.delete(id);\n reject(new Error(\"MCP Apps host did not respond.\"));\n }, REQUEST_TIMEOUT_MS);\n jsonRpcPending.set(id, { resolve, reject, timeout });\n\n try {\n window.parent.postMessage({ jsonrpc: \"2.0\", id, method, params }, \"*\");\n } catch (err) {\n jsonRpcPending.delete(id);\n clearTimeout(timeout);\n reject(err instanceof Error ? err : new Error(String(err)));\n }\n });\n}\n\nasync function ensureDirectMcpAppInitialized(): Promise<boolean> {\n if (!isInChildFrame() || !isMcpAppBridgeEnabled()) return false;\n if (hasWrapperBridge()) return true;\n\n const openAiBridge = readOpenAiBridge();\n if (openAiBridge) {\n updateSnapshotFromOpenAiBridge(openAiBridge);\n return true;\n }\n\n if (!directMcpAppInit) {\n directMcpAppInit = (async () => {\n const result = await postJsonRpcRequest(\"ui/initialize\", {\n protocolVersion: DIRECT_MCP_APP_PROTOCOL_VERSION,\n appInfo: { name: \"Agent Native App\", version: \"1.0.0\" },\n appCapabilities: {\n availableDisplayModes: [\"inline\", \"fullscreen\", \"pip\"],\n },\n });\n updateSnapshotFromInitialize(result);\n postJsonRpcNotification(\"ui/notifications/initialized\", {});\n return true;\n })().catch(() => {\n // Reset so the next call retries the handshake. Otherwise one timed-out\n // ui/initialize (e.g. host briefly unresponsive) leaves a permanently\n // resolved `Promise<false>` cached here, and every later bridge call\n // fails until full page reload.\n directMcpAppInit = null;\n return false as boolean;\n });\n }\n\n return directMcpAppInit;\n}\n\nasync function waitForDirectMcpAppInitialized(): Promise<void> {\n const ok = await ensureDirectMcpAppInitialized();\n if (!ok) throw new Error(\"MCP Apps host bridge is not available.\");\n}\n\nasync function postDirectHostRequest(\n type:\n | typeof AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES.UPDATE_MODEL_CONTEXT\n | typeof AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES.OPEN_LINK\n | typeof AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES.REQUEST_DISPLAY_MODE,\n data: Record<string, unknown>,\n): Promise<boolean> {\n const openAiBridge = readOpenAiBridge();\n if (openAiBridge) {\n updateSnapshotFromOpenAiBridge(openAiBridge);\n if (\n type === AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES.UPDATE_MODEL_CONTEXT &&\n typeof openAiBridge.setWidgetState === \"function\"\n ) {\n openAiBridge.setWidgetState({\n ...objectValue(openAiBridge.widgetState),\n agentNativeModelContext: {\n ...(Array.isArray(data.content) ? { content: data.content } : {}),\n ...(data.structuredContent !== undefined\n ? { structuredContent: data.structuredContent }\n : {}),\n },\n });\n return true;\n }\n if (\n type === AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES.OPEN_LINK &&\n typeof openAiBridge.openExternal === \"function\" &&\n typeof data.url === \"string\"\n ) {\n await openAiBridge.openExternal({\n href: data.url,\n redirectUrl: false,\n });\n return true;\n }\n if (\n type === AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES.REQUEST_DISPLAY_MODE &&\n typeof openAiBridge.requestDisplayMode === \"function\" &&\n typeof data.mode === \"string\"\n ) {\n await openAiBridge.requestDisplayMode({ mode: data.mode });\n updateSnapshotFromOpenAiBridge(openAiBridge);\n return true;\n }\n }\n\n await waitForDirectMcpAppInitialized();\n const method =\n type === AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES.UPDATE_MODEL_CONTEXT\n ? \"ui/update-model-context\"\n : type === AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES.OPEN_LINK\n ? \"ui/open-link\"\n : \"ui/request-display-mode\";\n await postJsonRpcRequest(method, data);\n return true;\n}\n\nexport function sendMcpAppHostMessage(\n chat: McpAppHostChatMessage,\n): Promise<boolean> | false {\n if (!chat.message.trim() || !isInChildFrame() || !isMcpAppBridgeEnabled()) {\n return false;\n }\n\n if (hasWrapperBridge()) return postWrapperHostChat(chat);\n\n return (async () => {\n const openAiBridge = readOpenAiBridge();\n const context = chat.context?.trim() || null;\n const requestMode = normalizeMcpAppHostRequestMode(\n chat.requestMode ?? chat.mode,\n );\n const requestModePayload = requestMode\n ? { mode: requestMode, requestMode }\n : {};\n const content = chat.content?.length\n ? chat.content\n : [{ type: \"text\", text: chat.message }];\n const contextContent = context\n ? [\n { type: \"text\", text: context },\n ...content.filter((part) => part && part.type !== \"text\"),\n ]\n : content.filter((part) => part && part.type !== \"text\");\n if (\n openAiBridge &&\n typeof openAiBridge.sendFollowUpMessage === \"function\"\n ) {\n updateSnapshotFromOpenAiBridge(openAiBridge);\n if (typeof openAiBridge.setWidgetState === \"function\") {\n openAiBridge.setWidgetState({\n ...objectValue(openAiBridge.widgetState),\n agentNativeChatContext: context,\n agentNativeModelContext: {\n content: contextContent,\n ...requestModePayload,\n ...(chat.structuredContent !== undefined\n ? { structuredContent: chat.structuredContent }\n : {}),\n },\n });\n }\n await openAiBridge.sendFollowUpMessage({\n prompt: chat.message,\n scrollToBottom: true,\n ...requestModePayload,\n });\n return true;\n }\n\n await waitForDirectMcpAppInitialized();\n try {\n await postJsonRpcRequest(\"ui/update-model-context\", {\n content: contextContent,\n ...requestModePayload,\n ...(chat.structuredContent !== undefined\n ? { structuredContent: chat.structuredContent }\n : {}),\n });\n } catch {\n // Best effort: a host without model-context support should still receive\n // the visible chat message.\n }\n await postJsonRpcRequest(\"ui/message\", {\n role: \"user\",\n content,\n ...requestModePayload,\n });\n return true;\n })().catch(() => false);\n}\n\nexport function getMcpAppHostContext(): McpAppHostContextSnapshot {\n ensureListener();\n const bridge = readOpenAiBridge();\n if (bridge) updateSnapshotFromOpenAiBridge(bridge);\n return snapshot;\n}\n\nexport function useMcpAppHostContext(): McpAppHostContextSnapshot {\n ensureListener();\n return useSyncExternalStore(\n (listener) => {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n () => snapshot,\n () => EMPTY_HOST_CONTEXT_SNAPSHOT,\n );\n}\n\nexport function updateMcpAppModelContext(\n update: McpAppModelContextUpdate,\n): Promise<boolean> | false {\n return postHostRequest(\n AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES.UPDATE_MODEL_CONTEXT,\n {\n ...(Array.isArray(update.content) ? { content: update.content } : {}),\n ...(update.structuredContent !== undefined\n ? { structuredContent: update.structuredContent }\n : {}),\n },\n );\n}\n\nexport function openMcpAppHostLink(url: string): Promise<boolean> | false {\n if (!url) return false;\n return postHostRequest(AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES.OPEN_LINK, {\n url,\n });\n}\n\nexport function requestMcpAppDisplayMode(\n mode: McpAppDisplayMode,\n): Promise<boolean> | false {\n if (!mode) return false;\n return postHostRequest(\n AGENT_NATIVE_MCP_APP_HOST_MESSAGE_TYPES.REQUEST_DISPLAY_MODE,\n { mode },\n );\n}\n\nensureListener();\n\n/** Internal test helper. Do not use in app code. */\nexport function _resetMcpAppHostForTests(): void {\n for (const request of pending.values()) clearTimeout(request.timeout);\n for (const request of jsonRpcPending.values()) clearTimeout(request.timeout);\n pending.clear();\n jsonRpcPending.clear();\n directMcpAppInit = null;\n snapshot = { context: null, capabilities: null, version: null };\n listeners.clear();\n}\n\nif (isBrowserWindow()) {\n window.addEventListener(\n \"openai:set_globals\",\n () => {\n const bridge = readOpenAiBridge();\n if (bridge) updateSnapshotFromOpenAiBridge(bridge);\n },\n { passive: true },\n );\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-code.d.ts","sourceRoot":"","sources":["../../src/coding-tools/run-code.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AASH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"run-code.d.ts","sourceRoot":"","sources":["../../src/coding-tools/run-code.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AASH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AA8DhE,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EAC7C,IAAI,GAAE,cAAmB,GACxB,WAAW,CAoMb"}
|
|
@@ -33,6 +33,22 @@ const DEFAULT_MAX_OUTPUT_CHARS = 50_000;
|
|
|
33
33
|
const MAX_OUTPUT_CHARS = 200_000;
|
|
34
34
|
/** Hard cap on bridge request bodies so sandboxed code can't exhaust parent memory. */
|
|
35
35
|
const BRIDGE_MAX_BODY_BYTES = 10 * 1024 * 1024;
|
|
36
|
+
function sandboxReadAllowPaths(tmpDir) {
|
|
37
|
+
const paths = new Set([tmpDir]);
|
|
38
|
+
try {
|
|
39
|
+
paths.add(fs.realpathSync(tmpDir));
|
|
40
|
+
}
|
|
41
|
+
catch { }
|
|
42
|
+
return [...paths];
|
|
43
|
+
}
|
|
44
|
+
function sandboxWriteAllowPaths(tmpDir) {
|
|
45
|
+
const paths = new Set([tmpDir]);
|
|
46
|
+
try {
|
|
47
|
+
paths.add(fs.realpathSync(tmpDir));
|
|
48
|
+
}
|
|
49
|
+
catch { }
|
|
50
|
+
return [...paths];
|
|
51
|
+
}
|
|
36
52
|
/**
|
|
37
53
|
* Resolve the Node permission-model flag supported by the current runtime,
|
|
38
54
|
* probing once and caching. Returns null when the permission model is
|
|
@@ -86,6 +102,8 @@ export function createRunCodeEntry(getActions, opts = {}) {
|
|
|
86
102
|
"Use this to fetch, join, aggregate, and reduce large datasets, returning only printed output to the conversation.",
|
|
87
103
|
"The sandbox runs with a scrubbed environment (no secrets) and, where the Node permission model is available, no filesystem access outside its own temp dir, no child processes, and no workers. Authenticated calls must go through the provided globals; direct network requests carry no credentials. Note: isolation is process-level (env scrub + Node permission model), not an OS-level container — outbound network from sandbox code is not blocked.",
|
|
88
104
|
"Available globals:",
|
|
105
|
+
" - `appAction(name, args?)` — call any registered agent-exposed read-only app action/tool and get its parsed result.",
|
|
106
|
+
" Use this to loop over app data readers and compose multi-source analyses without forcing every intermediate result into chat.",
|
|
89
107
|
" - `providerFetch(provider, path, init?)` — authenticated call to a registered provider via the provider-api-request action.",
|
|
90
108
|
" Returns the parsed JSON result (or throws on error).",
|
|
91
109
|
" Example: `const data = await providerFetch('hubspot', '/crm/v3/objects/contacts');`",
|
|
@@ -93,6 +111,7 @@ export function createRunCodeEntry(getActions, opts = {}) {
|
|
|
93
111
|
" Returns `{ status, body }` where body is the response text.",
|
|
94
112
|
" Example: `const { body } = await webFetch('https://api.example.com/data');`",
|
|
95
113
|
" - `workspaceRead(path, opts?)` — read a workspace file by path. Returns content string or null. opts: { offset?, maxChars? }.",
|
|
114
|
+
" - `workspaceReadMeta(path, opts?)` — read a workspace file with metadata such as sizeBytes, truncated, and nextOffset.",
|
|
96
115
|
" - `workspaceWrite(path, content, contentType?)` — create or overwrite a workspace file.",
|
|
97
116
|
" - `workspaceAppend(path, content)` — append text to a workspace file.",
|
|
98
117
|
" - `workspaceList(prefix?)` — list workspace files, returns [{ path, sizeBytes, contentType, updatedAt }].",
|
|
@@ -138,7 +157,8 @@ export function createRunCodeEntry(getActions, opts = {}) {
|
|
|
138
157
|
let tmpFile;
|
|
139
158
|
try {
|
|
140
159
|
// Write code to a temp ESM file (top-level await needs a module).
|
|
141
|
-
|
|
160
|
+
const tmpBaseDir = fs.realpathSync(os.tmpdir());
|
|
161
|
+
tmpDir = fs.mkdtempSync(path.join(tmpBaseDir, "agent-run-code-"));
|
|
142
162
|
tmpFile = path.join(tmpDir, "sandbox.mjs");
|
|
143
163
|
fs.writeFileSync(tmpFile, buildSandboxModule(code, bridgePort, bridgeToken), "utf8");
|
|
144
164
|
// Build scrubbed env — only safe POSIX vars, no secrets.
|
|
@@ -167,8 +187,8 @@ export function createRunCodeEntry(getActions, opts = {}) {
|
|
|
167
187
|
const nodeArgs = permissionFlag
|
|
168
188
|
? [
|
|
169
189
|
permissionFlag,
|
|
170
|
-
`--allow-fs-read=${
|
|
171
|
-
`--allow-fs-write=${
|
|
190
|
+
...sandboxReadAllowPaths(tmpDir).map((allowedPath) => `--allow-fs-read=${allowedPath}`),
|
|
191
|
+
...sandboxWriteAllowPaths(tmpDir).map((allowedPath) => `--allow-fs-write=${allowedPath}`),
|
|
172
192
|
tmpFile,
|
|
173
193
|
]
|
|
174
194
|
: [tmpFile];
|
|
@@ -304,14 +324,19 @@ function handleBridgeRequest(rawBody, actions, context, defaultTools, extraTools
|
|
|
304
324
|
return;
|
|
305
325
|
}
|
|
306
326
|
// Enforce allowlist.
|
|
307
|
-
|
|
327
|
+
const entry = actions[toolName];
|
|
328
|
+
const isReadOnlyAction = entry?.readOnly === true &&
|
|
329
|
+
entry.agentTool !== false &&
|
|
330
|
+
entry.toolCallable !== false;
|
|
331
|
+
if (!defaultTools.has(toolName) &&
|
|
332
|
+
!extraTools.has(toolName) &&
|
|
333
|
+
!isReadOnlyAction) {
|
|
308
334
|
res.writeHead(403, { "Content-Type": "application/json" });
|
|
309
335
|
res.end(JSON.stringify({
|
|
310
|
-
error: `Tool "${toolName}" is not
|
|
336
|
+
error: `Tool "${toolName}" is not an agent-exposed read-only action or sandbox bridge allowlisted tool.`,
|
|
311
337
|
}));
|
|
312
338
|
return;
|
|
313
339
|
}
|
|
314
|
-
const entry = actions[toolName];
|
|
315
340
|
if (!entry) {
|
|
316
341
|
res.writeHead(404, { "Content-Type": "application/json" });
|
|
317
342
|
res.end(JSON.stringify({ error: `Tool "${toolName}" is not registered.` }));
|
|
@@ -385,6 +410,19 @@ async function _bridgeCall(tool, args) {
|
|
|
385
410
|
});
|
|
386
411
|
}
|
|
387
412
|
|
|
413
|
+
function _parseBridgeResult(rawResult) {
|
|
414
|
+
if (typeof rawResult !== "string") return rawResult;
|
|
415
|
+
try { return JSON.parse(rawResult); } catch { return rawResult; }
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* Call any registered agent-exposed read-only app action/tool via the sandbox bridge.
|
|
420
|
+
* Mutating and explicitly hidden actions are blocked by the parent bridge.
|
|
421
|
+
*/
|
|
422
|
+
async function appAction(name, args = {}) {
|
|
423
|
+
return _parseBridgeResult(await _bridgeCall(name, args));
|
|
424
|
+
}
|
|
425
|
+
|
|
388
426
|
/**
|
|
389
427
|
* Call a provider API via the authenticated provider-api-request action.
|
|
390
428
|
* Returns the parsed JSON response body (or throws on error).
|
|
@@ -395,15 +433,22 @@ async function providerFetch(provider, apiPath, init = {}) {
|
|
|
395
433
|
provider,
|
|
396
434
|
path: apiPath,
|
|
397
435
|
method,
|
|
398
|
-
...(init.query ? { query:
|
|
399
|
-
...(init.body ? { body:
|
|
400
|
-
...(init.headers ? { headers:
|
|
436
|
+
...(init.query ? { query: init.query } : {}),
|
|
437
|
+
...(init.body ? { body: init.body } : {}),
|
|
438
|
+
...(init.headers ? { headers: init.headers } : {}),
|
|
439
|
+
...(init.auth ? { auth: init.auth } : {}),
|
|
440
|
+
...(init.connectionId ? { connectionId: init.connectionId } : {}),
|
|
441
|
+
...(init.accountId ? { accountId: init.accountId } : {}),
|
|
442
|
+
...(init.timeoutMs ? { timeoutMs: init.timeoutMs } : {}),
|
|
443
|
+
...(init.maxBytes ? { maxBytes: init.maxBytes } : {}),
|
|
444
|
+
...(init.stageAs ? { stageAs: init.stageAs } : {}),
|
|
445
|
+
...(init.itemsPath ? { itemsPath: init.itemsPath } : {}),
|
|
446
|
+
...(init.pagination ? { pagination: init.pagination } : {}),
|
|
447
|
+
...(init.saveToFile ? { saveToFile: init.saveToFile } : {}),
|
|
448
|
+
...(init.fetchAllPages ? { fetchAllPages: init.fetchAllPages } : {}),
|
|
401
449
|
});
|
|
402
450
|
// rawResult is the action's string output; parse it if it looks like JSON
|
|
403
|
-
let parsed = rawResult;
|
|
404
|
-
if (typeof parsed === "string") {
|
|
405
|
-
try { parsed = JSON.parse(parsed); } catch { return parsed; }
|
|
406
|
-
}
|
|
451
|
+
let parsed = _parseBridgeResult(rawResult);
|
|
407
452
|
// Unwrap the provider-api-request envelope ({ provider, request, response, guidance })
|
|
408
453
|
// so callers get the actual response body. fetchAllPages / saveToFile results
|
|
409
454
|
// (which have no \`response\` field) are returned as-is.
|
|
@@ -446,16 +491,23 @@ async function webFetch(url, init = {}) {
|
|
|
446
491
|
* Supports optional offset and maxChars for paging large files.
|
|
447
492
|
*/
|
|
448
493
|
async function workspaceRead(path, opts = {}) {
|
|
494
|
+
const parsed = await workspaceReadMeta(path, opts);
|
|
495
|
+
if (parsed && parsed.ok === false) return null;
|
|
496
|
+
return parsed && typeof parsed.content === "string" ? parsed.content : null;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
/**
|
|
500
|
+
* Read a workspace file by path and return the full metadata envelope.
|
|
501
|
+
* Use this when offset/maxChars paging or truncation status matters.
|
|
502
|
+
*/
|
|
503
|
+
async function workspaceReadMeta(path, opts = {}) {
|
|
449
504
|
const rawResult = await _bridgeCall("workspace-files", {
|
|
450
505
|
action: "read",
|
|
451
506
|
path,
|
|
452
507
|
...(opts.offset !== undefined ? { offset: opts.offset } : {}),
|
|
453
508
|
...(opts.maxChars !== undefined ? { maxChars: opts.maxChars } : {}),
|
|
454
509
|
});
|
|
455
|
-
|
|
456
|
-
try { parsed = typeof rawResult === "string" ? JSON.parse(rawResult) : rawResult; } catch { return rawResult; }
|
|
457
|
-
if (parsed && parsed.ok === false) return null;
|
|
458
|
-
return parsed && typeof parsed.content === "string" ? parsed.content : null;
|
|
510
|
+
return _parseBridgeResult(rawResult);
|
|
459
511
|
}
|
|
460
512
|
|
|
461
513
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-code.js","sourceRoot":"","sources":["../../src/coding-tools/run-code.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Sandboxed JavaScript execution tool for the agent.\n *\n * Executes user-supplied JavaScript in an isolated child process with:\n * - A scrubbed environment (no app secrets or env vars; only PATH/HOME/TMPDIR).\n * - A fresh temporary working directory.\n * - An ephemeral bridge HTTP server on 127.0.0.1 so the child can call\n * allowlisted registered tools (provider-api-request, web-request, etc.)\n * with the same request context as the parent — without leaking secrets.\n *\n * Security notes:\n * - The bridge token is a 32-byte random hex string generated per invocation.\n * - The bridge binds to 127.0.0.1 only; no external exposure.\n * - The allowlist of callable bridge tools is enforced server-side.\n * - Secret values are NEVER included in the env passed to the child.\n * - When the Node permission model is available (`--permission`, or\n * `--experimental-permission` on Node 20), the child is denied filesystem\n * access outside its own temp dir, child processes, workers, and native\n * addons. Outbound network from the child is NOT blocked by the permission\n * model; the env scrub means such requests carry no credentials, and all\n * authenticated calls must go through the bridge (which applies the\n * registered tools' host allowlists and SSRF guards).\n */\n\nimport crypto from \"node:crypto\";\nimport fs from \"node:fs\";\nimport http from \"node:http\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { spawn, spawnSync } from \"node:child_process\";\n\nimport type { ActionEntry } from \"../agent/production-agent.js\";\nimport type { ActionRunContext } from \"../action.js\";\n\nconst DEFAULT_TIMEOUT_MS = 120_000;\nconst MAX_TIMEOUT_MS = 600_000;\nconst DEFAULT_MAX_OUTPUT_CHARS = 50_000;\nconst MAX_OUTPUT_CHARS = 200_000;\n/** Hard cap on bridge request bodies so sandboxed code can't exhaust parent memory. */\nconst BRIDGE_MAX_BODY_BYTES = 10 * 1024 * 1024;\n\n/**\n * Resolve the Node permission-model flag supported by the current runtime,\n * probing once and caching. Returns null when the permission model is\n * unavailable (the sandbox then falls back to env-scrub isolation only).\n */\nlet cachedPermissionFlag: string | null | undefined;\nfunction resolvePermissionFlag(): string | null {\n if (cachedPermissionFlag !== undefined) return cachedPermissionFlag;\n for (const flag of [\"--permission\", \"--experimental-permission\"]) {\n try {\n const probe = spawnSync(\n process.execPath,\n [flag, \"-e\", \"process.exit(0)\"],\n { timeout: 10_000, stdio: \"ignore\" },\n );\n if (probe.status === 0) {\n cachedPermissionFlag = flag;\n return flag;\n }\n } catch {\n // Probe failure means the flag is unsupported; try the next one.\n }\n }\n cachedPermissionFlag = null;\n return null;\n}\n\n/** Tools callable via the sandbox bridge by default. */\nconst DEFAULT_BRIDGE_TOOLS = new Set([\n \"provider-api-request\",\n \"provider-api-docs\",\n \"provider-api-catalog\",\n \"web-request\",\n \"workspace-files\",\n]);\n\nexport interface RunCodeOptions {\n /**\n * Extra tool names (beyond the default set) that the sandbox bridge will\n * forward to the registered action registry.\n */\n bridgeTools?: string[];\n}\n\n/**\n * Create a `run-code` ActionEntry.\n *\n * @param getActions Supplier that returns the current action registry (called\n * at invocation time so updates are reflected).\n * @param opts Optional configuration.\n */\nexport function createRunCodeEntry(\n getActions: () => Record<string, ActionEntry>,\n opts: RunCodeOptions = {},\n): ActionEntry {\n const extraBridgeTools = new Set(opts.bridgeTools ?? []);\n\n return {\n readOnly: true,\n // Allow a generous per-call timeout so large analytics jobs don't hit the\n // agent-loop's default 60 s cap.\n timeoutMs: MAX_TIMEOUT_MS,\n maxResultChars: MAX_OUTPUT_CHARS,\n tool: {\n description: [\n \"Execute JavaScript (Node.js, ESM, top-level await supported) in an isolated sandbox.\",\n \"Use this to fetch, join, aggregate, and reduce large datasets, returning only printed output to the conversation.\",\n \"The sandbox runs with a scrubbed environment (no secrets) and, where the Node permission model is available, no filesystem access outside its own temp dir, no child processes, and no workers. Authenticated calls must go through the provided globals; direct network requests carry no credentials. Note: isolation is process-level (env scrub + Node permission model), not an OS-level container — outbound network from sandbox code is not blocked.\",\n \"Available globals:\",\n \" - `providerFetch(provider, path, init?)` — authenticated call to a registered provider via the provider-api-request action.\",\n \" Returns the parsed JSON result (or throws on error).\",\n \" Example: `const data = await providerFetch('hubspot', '/crm/v3/objects/contacts');`\",\n \" - `webFetch(url, init?)` — outbound HTTP request via the web-request action.\",\n \" Returns `{ status, body }` where body is the response text.\",\n \" Example: `const { body } = await webFetch('https://api.example.com/data');`\",\n \" - `workspaceRead(path, opts?)` — read a workspace file by path. Returns content string or null. opts: { offset?, maxChars? }.\",\n \" - `workspaceWrite(path, content, contentType?)` — create or overwrite a workspace file.\",\n \" - `workspaceAppend(path, content)` — append text to a workspace file.\",\n \" - `workspaceList(prefix?)` — list workspace files, returns [{ path, sizeBytes, contentType, updatedAt }].\",\n \"Print results with `console.log()`; only stdout+stderr are returned.\",\n \"Timeout defaults to 120 s (max 600 s). Output is truncated to 50 000 chars by default (max 200 000).\",\n ].join(\" \"),\n parameters: {\n type: \"object\",\n properties: {\n code: {\n type: \"string\",\n description:\n \"JavaScript source to execute. ESM syntax, top-level await allowed.\",\n },\n timeoutMs: {\n type: \"number\",\n description: `Execution timeout in milliseconds. Default: ${DEFAULT_TIMEOUT_MS}. Max: ${MAX_TIMEOUT_MS}.`,\n },\n maxOutputChars: {\n type: \"number\",\n description: `Maximum combined stdout+stderr characters to return. Default: ${DEFAULT_MAX_OUTPUT_CHARS}. Max: ${MAX_OUTPUT_CHARS}.`,\n },\n },\n required: [\"code\"],\n },\n },\n run: async (args: Record<string, string>, context?: ActionRunContext) => {\n const code = typeof args.code === \"string\" ? args.code : \"\";\n if (!code.trim()) return \"Error: code is required.\";\n\n const requestedTimeout = Number(args.timeoutMs);\n const timeoutMs =\n Number.isFinite(requestedTimeout) && requestedTimeout > 0\n ? Math.min(requestedTimeout, MAX_TIMEOUT_MS)\n : DEFAULT_TIMEOUT_MS;\n\n const requestedMaxOutput = Number(args.maxOutputChars);\n const maxOutputChars =\n Number.isFinite(requestedMaxOutput) && requestedMaxOutput > 0\n ? Math.min(requestedMaxOutput, MAX_OUTPUT_CHARS)\n : DEFAULT_MAX_OUTPUT_CHARS;\n\n const actions = getActions();\n const bridgeToken = crypto.randomBytes(32).toString(\"hex\");\n\n // Start bridge server — resolves once the server is listening.\n const {\n server,\n bridgePort,\n cleanup: cleanupBridge,\n } = await startBridgeServer(\n bridgeToken,\n actions,\n context,\n DEFAULT_BRIDGE_TOOLS,\n extraBridgeTools,\n );\n\n let tmpDir: string | undefined;\n let tmpFile: string | undefined;\n try {\n // Write code to a temp ESM file (top-level await needs a module).\n tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), \"agent-run-code-\"));\n tmpFile = path.join(tmpDir, \"sandbox.mjs\");\n fs.writeFileSync(\n tmpFile,\n buildSandboxModule(code, bridgePort, bridgeToken),\n \"utf8\",\n );\n\n // Build scrubbed env — only safe POSIX vars, no secrets.\n const safeEnv: Record<string, string> = {};\n for (const key of [\n \"PATH\",\n \"HOME\",\n \"TMPDIR\",\n \"TEMP\",\n \"TMP\",\n \"LANG\",\n \"LC_ALL\",\n ]) {\n if (process.env[key]) safeEnv[key] = process.env[key]!;\n }\n // Point TMPDIR inside the sandbox dir so in-sandbox temp writes stay\n // within the permission-model allow list.\n safeEnv.TMPDIR = tmpDir;\n safeEnv.TEMP = tmpDir;\n safeEnv.TMP = tmpDir;\n\n // Lock the child down with the Node permission model when available:\n // filesystem restricted to the sandbox temp dir, and child processes,\n // workers, and native addons denied entirely.\n const permissionFlag = resolvePermissionFlag();\n const nodeArgs = permissionFlag\n ? [\n permissionFlag,\n `--allow-fs-read=${tmpDir}`,\n `--allow-fs-write=${tmpDir}`,\n tmpFile,\n ]\n : [tmpFile];\n\n const child = spawn(process.execPath, nodeArgs, {\n cwd: tmpDir,\n env: safeEnv,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n\n let stdout = \"\";\n let stderr = \"\";\n let timedOut = false;\n\n const timer = setTimeout(() => {\n timedOut = true;\n child.kill(\"SIGTERM\");\n setTimeout(() => {\n try {\n child.kill(\"SIGKILL\");\n } catch {}\n }, 2_000);\n }, timeoutMs);\n\n child.stdout?.on(\"data\", (chunk: Buffer) => {\n stdout += chunk.toString();\n });\n child.stderr?.on(\"data\", (chunk: Buffer) => {\n stderr += chunk.toString();\n });\n\n const exitCode = await new Promise<number | null>((resolve, reject) => {\n child.once(\"error\", reject);\n child.once(\"exit\", resolve);\n });\n clearTimeout(timer);\n\n const combined =\n [\n stdout ? `stdout:\\n${stdout}` : \"\",\n stderr ? `stderr:\\n${stderr}` : \"\",\n ]\n .filter(Boolean)\n .join(\"\\n\\n\") || \"(no output)\";\n\n const lines: string[] = [];\n if (timedOut) lines.push(`timedOut: true (${timeoutMs}ms)`);\n if (exitCode !== 0 && exitCode !== null)\n lines.push(`exitCode: ${exitCode}`);\n lines.push(combined);\n\n const full = lines.join(\"\\n\\n\");\n if (full.length > maxOutputChars) {\n const truncated = full.slice(0, maxOutputChars);\n return `${truncated}\\n\\n...[truncated ${(full.length - maxOutputChars).toLocaleString()} chars]`;\n }\n return full;\n } finally {\n cleanupBridge();\n server.close();\n // Clean up temp files (best-effort).\n try {\n if (tmpFile) fs.rmSync(tmpFile, { force: true });\n if (tmpDir) fs.rmSync(tmpDir, { recursive: true, force: true });\n } catch {}\n }\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Bridge server\n// ---------------------------------------------------------------------------\n\ninterface BridgeResult {\n server: http.Server;\n bridgePort: number;\n cleanup: () => void;\n}\n\nasync function startBridgeServer(\n token: string,\n actions: Record<string, ActionEntry>,\n context: ActionRunContext | undefined,\n defaultTools: Set<string>,\n extraTools: Set<string>,\n): Promise<BridgeResult> {\n const server = http.createServer((req, res) => {\n if (req.method !== \"POST\" || req.url !== \"/tool\") {\n res.writeHead(404);\n res.end(\"Not found\");\n return;\n }\n\n // Validate bearer token — must match exactly.\n const authHeader = req.headers.authorization ?? \"\";\n if (authHeader !== `Bearer ${token}`) {\n res.writeHead(401);\n res.end(\"Unauthorized\");\n return;\n }\n\n let body = \"\";\n let receivedBytes = 0;\n let rejected = false;\n req.on(\"data\", (chunk: Buffer) => {\n receivedBytes += chunk.length;\n if (receivedBytes > BRIDGE_MAX_BODY_BYTES) {\n rejected = true;\n res.writeHead(413);\n res.end(\"Payload too large\");\n req.destroy();\n return;\n }\n body += chunk.toString();\n });\n req.on(\"end\", () => {\n if (rejected) return;\n handleBridgeRequest(\n body,\n actions,\n context,\n defaultTools,\n extraTools,\n res,\n );\n });\n req.on(\"error\", () => {\n res.writeHead(500);\n res.end(\"Request error\");\n });\n });\n\n await new Promise<void>((resolve, reject) => {\n server.once(\"error\", reject);\n server.listen(0, \"127.0.0.1\", () => resolve());\n });\n\n const addr = server.address() as { port: number };\n const bridgePort = addr.port;\n\n const cleanup = () => {\n try {\n server.close();\n } catch {}\n };\n\n return { server, bridgePort, cleanup };\n}\n\nfunction handleBridgeRequest(\n rawBody: string,\n actions: Record<string, ActionEntry>,\n context: ActionRunContext | undefined,\n defaultTools: Set<string>,\n extraTools: Set<string>,\n res: http.ServerResponse,\n): void {\n let parsed: { tool?: string; args?: Record<string, string> };\n try {\n parsed = JSON.parse(rawBody);\n } catch {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Invalid JSON body\" }));\n return;\n }\n\n const toolName = typeof parsed.tool === \"string\" ? parsed.tool.trim() : \"\";\n if (!toolName) {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Missing tool name\" }));\n return;\n }\n\n // Enforce allowlist.\n if (!defaultTools.has(toolName) && !extraTools.has(toolName)) {\n res.writeHead(403, { \"Content-Type\": \"application/json\" });\n res.end(\n JSON.stringify({\n error: `Tool \"${toolName}\" is not in the sandbox bridge allowlist.`,\n }),\n );\n return;\n }\n\n const entry = actions[toolName];\n if (!entry) {\n res.writeHead(404, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: `Tool \"${toolName}\" is not registered.` }));\n return;\n }\n\n const toolArgs = parsed.args ?? {};\n // Run the tool with the parent request context so auth/org/owner resolution\n // works exactly as it does in the normal agent loop.\n entry\n .run(toolArgs, context)\n .then((result: unknown) => {\n const body =\n typeof result === \"string\" ? result : JSON.stringify(result, null, 2);\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ result: body }));\n })\n .catch((err: unknown) => {\n const message = err instanceof Error ? err.message : String(err);\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: message }));\n });\n}\n\n// ---------------------------------------------------------------------------\n// Sandbox module template\n// ---------------------------------------------------------------------------\n\n/**\n * Wrap the user's code in an ESM module that:\n * 1. Defines `providerFetch` and `webFetch` helpers via the bridge.\n * 2. Runs the user's code as top-level await in an async IIFE.\n */\nfunction buildSandboxModule(\n userCode: string,\n bridgePort: number,\n bridgeToken: string,\n): string {\n return `\nimport { createRequire } from \"node:module\";\nconst require = createRequire(import.meta.url);\n\nconst _bridgeBase = \"http://127.0.0.1:${bridgePort}/tool\";\nconst _bridgeToken = \"${bridgeToken}\";\n\nasync function _bridgeCall(tool, args) {\n const http = await import(\"node:http\");\n return new Promise((resolve, reject) => {\n const body = JSON.stringify({ tool, args });\n const options = {\n hostname: \"127.0.0.1\",\n port: ${bridgePort},\n path: \"/tool\",\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"Content-Length\": Buffer.byteLength(body),\n \"Authorization\": \"Bearer \" + _bridgeToken,\n },\n };\n const req = http.request(options, (res) => {\n let data = \"\";\n res.on(\"data\", (chunk) => { data += chunk; });\n res.on(\"end\", () => {\n try {\n const parsed = JSON.parse(data);\n if (parsed.error) {\n reject(new Error(parsed.error));\n } else {\n resolve(parsed.result);\n }\n } catch (e) {\n reject(new Error(\"Bridge response parse error: \" + e.message));\n }\n });\n });\n req.on(\"error\", reject);\n req.end(body);\n });\n}\n\n/**\n * Call a provider API via the authenticated provider-api-request action.\n * Returns the parsed JSON response body (or throws on error).\n */\nasync function providerFetch(provider, apiPath, init = {}) {\n const method = (init.method || \"GET\").toUpperCase();\n const rawResult = await _bridgeCall(\"provider-api-request\", {\n provider,\n path: apiPath,\n method,\n ...(init.query ? { query: typeof init.query === \"string\" ? init.query : JSON.stringify(init.query) } : {}),\n ...(init.body ? { body: typeof init.body === \"string\" ? init.body : JSON.stringify(init.body) } : {}),\n ...(init.headers ? { headers: typeof init.headers === \"string\" ? init.headers : JSON.stringify(init.headers) } : {}),\n });\n // rawResult is the action's string output; parse it if it looks like JSON\n let parsed = rawResult;\n if (typeof parsed === \"string\") {\n try { parsed = JSON.parse(parsed); } catch { return parsed; }\n }\n // Unwrap the provider-api-request envelope ({ provider, request, response, guidance })\n // so callers get the actual response body. fetchAllPages / saveToFile results\n // (which have no \\`response\\` field) are returned as-is.\n if (parsed && typeof parsed === \"object\" && parsed.response && typeof parsed.response === \"object\") {\n const r = parsed.response;\n if (typeof r.status === \"number\" && r.status >= 400) {\n const detail = typeof r.text === \"string\" ? r.text : JSON.stringify(r.json ?? \"\");\n throw new Error(\\`Provider request failed (\\${r.status}): \\${String(detail).slice(0, 500)}\\`);\n }\n return r.json !== undefined ? r.json : r.text;\n }\n return parsed;\n}\n\n/**\n * Make an outbound HTTP request via the web-request action.\n * Returns an object \\`{ status, body }\\` where \\`body\\` is the response text.\n */\nasync function webFetch(url, init = {}) {\n const method = (init.method || \"GET\").toUpperCase();\n const rawResult = await _bridgeCall(\"web-request\", {\n url,\n method,\n ...(init.headers ? { headers: typeof init.headers === \"string\" ? init.headers : JSON.stringify(init.headers) } : {}),\n ...(init.body ? { body: typeof init.body === \"string\" ? init.body : JSON.stringify(init.body) } : {}),\n });\n // rawResult is \"HTTP <status> <statusText>\\\\n\\\\n<body>\"\n const statusMatch = typeof rawResult === \"string\" ? rawResult.match(/^HTTP (\\\\d+) [^\\\\n]*\\\\n\\\\n/) : null;\n if (statusMatch) {\n return {\n status: Number(statusMatch[1]),\n body: rawResult.slice(statusMatch[0].length),\n };\n }\n return { status: 0, body: rawResult };\n}\n\n/**\n * Read a workspace file by path. Returns the file content as a string, or null if not found.\n * Supports optional offset and maxChars for paging large files.\n */\nasync function workspaceRead(path, opts = {}) {\n const rawResult = await _bridgeCall(\"workspace-files\", {\n action: \"read\",\n path,\n ...(opts.offset !== undefined ? { offset: opts.offset } : {}),\n ...(opts.maxChars !== undefined ? { maxChars: opts.maxChars } : {}),\n });\n let parsed;\n try { parsed = typeof rawResult === \"string\" ? JSON.parse(rawResult) : rawResult; } catch { return rawResult; }\n if (parsed && parsed.ok === false) return null;\n return parsed && typeof parsed.content === \"string\" ? parsed.content : null;\n}\n\n/**\n * Write (create or overwrite) a workspace file.\n * \\`content\\` must be a string. Returns metadata { path, sizeBytes, updatedAt }.\n */\nasync function workspaceWrite(path, content, contentType = \"text/plain\") {\n const rawResult = await _bridgeCall(\"workspace-files\", {\n action: \"write\",\n path,\n content: typeof content === \"string\" ? content : JSON.stringify(content),\n contentType,\n });\n try { return typeof rawResult === \"string\" ? JSON.parse(rawResult) : rawResult; } catch { return rawResult; }\n}\n\n/**\n * Append text to a workspace file (creates if absent).\n */\nasync function workspaceAppend(path, content) {\n const rawResult = await _bridgeCall(\"workspace-files\", {\n action: \"append\",\n path,\n content: typeof content === \"string\" ? content : JSON.stringify(content),\n });\n try { return typeof rawResult === \"string\" ? JSON.parse(rawResult) : rawResult; } catch { return rawResult; }\n}\n\n/**\n * List workspace files, optionally filtered by path prefix.\n * Returns an array of { path, sizeBytes, contentType, updatedAt }.\n */\nasync function workspaceList(prefix) {\n const rawResult = await _bridgeCall(\"workspace-files\", {\n action: \"list\",\n ...(prefix ? { path: prefix } : {}),\n });\n const parsed = typeof rawResult === \"string\" ? JSON.parse(rawResult) : rawResult;\n if (parsed && Array.isArray(parsed.files)) return parsed.files;\n if (Array.isArray(parsed)) return parsed;\n throw new Error(\"workspaceList: unexpected result shape: \" + JSON.stringify(parsed).slice(0, 200));\n}\n\n// Run user code\n(async () => {\n${userCode}\n})().catch((err) => {\n console.error(\"Unhandled error:\", err?.message ?? String(err));\n process.exit(1);\n});\n`;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"run-code.js","sourceRoot":"","sources":["../../src/coding-tools/run-code.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Sandboxed JavaScript execution tool for the agent.\n *\n * Executes user-supplied JavaScript in an isolated child process with:\n * - A scrubbed environment (no app secrets or env vars; only PATH/HOME/TMPDIR).\n * - A fresh temporary working directory.\n * - An ephemeral bridge HTTP server on 127.0.0.1 so the child can call\n * allowlisted registered tools (provider-api-request, web-request, etc.)\n * with the same request context as the parent — without leaking secrets.\n *\n * Security notes:\n * - The bridge token is a 32-byte random hex string generated per invocation.\n * - The bridge binds to 127.0.0.1 only; no external exposure.\n * - The allowlist of callable bridge tools is enforced server-side.\n * - Secret values are NEVER included in the env passed to the child.\n * - When the Node permission model is available (`--permission`, or\n * `--experimental-permission` on Node 20), the child is denied filesystem\n * access outside its own temp dir, child processes, workers, and native\n * addons. Outbound network from the child is NOT blocked by the permission\n * model; the env scrub means such requests carry no credentials, and all\n * authenticated calls must go through the bridge (which applies the\n * registered tools' host allowlists and SSRF guards).\n */\n\nimport crypto from \"node:crypto\";\nimport fs from \"node:fs\";\nimport http from \"node:http\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { spawn, spawnSync } from \"node:child_process\";\n\nimport type { ActionEntry } from \"../agent/production-agent.js\";\nimport type { ActionRunContext } from \"../action.js\";\n\nconst DEFAULT_TIMEOUT_MS = 120_000;\nconst MAX_TIMEOUT_MS = 600_000;\nconst DEFAULT_MAX_OUTPUT_CHARS = 50_000;\nconst MAX_OUTPUT_CHARS = 200_000;\n/** Hard cap on bridge request bodies so sandboxed code can't exhaust parent memory. */\nconst BRIDGE_MAX_BODY_BYTES = 10 * 1024 * 1024;\n\nfunction sandboxReadAllowPaths(tmpDir: string): string[] {\n const paths = new Set<string>([tmpDir]);\n try {\n paths.add(fs.realpathSync(tmpDir));\n } catch {}\n return [...paths];\n}\n\nfunction sandboxWriteAllowPaths(tmpDir: string): string[] {\n const paths = new Set<string>([tmpDir]);\n try {\n paths.add(fs.realpathSync(tmpDir));\n } catch {}\n return [...paths];\n}\n\n/**\n * Resolve the Node permission-model flag supported by the current runtime,\n * probing once and caching. Returns null when the permission model is\n * unavailable (the sandbox then falls back to env-scrub isolation only).\n */\nlet cachedPermissionFlag: string | null | undefined;\nfunction resolvePermissionFlag(): string | null {\n if (cachedPermissionFlag !== undefined) return cachedPermissionFlag;\n for (const flag of [\"--permission\", \"--experimental-permission\"]) {\n try {\n const probe = spawnSync(\n process.execPath,\n [flag, \"-e\", \"process.exit(0)\"],\n { timeout: 10_000, stdio: \"ignore\" },\n );\n if (probe.status === 0) {\n cachedPermissionFlag = flag;\n return flag;\n }\n } catch {\n // Probe failure means the flag is unsupported; try the next one.\n }\n }\n cachedPermissionFlag = null;\n return null;\n}\n\n/** Tools callable via the sandbox bridge by default. */\nconst DEFAULT_BRIDGE_TOOLS = new Set([\n \"provider-api-request\",\n \"provider-api-docs\",\n \"provider-api-catalog\",\n \"web-request\",\n \"workspace-files\",\n]);\n\nexport interface RunCodeOptions {\n /**\n * Extra tool names (beyond the default set) that the sandbox bridge will\n * forward to the registered action registry.\n */\n bridgeTools?: string[];\n}\n\n/**\n * Create a `run-code` ActionEntry.\n *\n * @param getActions Supplier that returns the current action registry (called\n * at invocation time so updates are reflected).\n * @param opts Optional configuration.\n */\nexport function createRunCodeEntry(\n getActions: () => Record<string, ActionEntry>,\n opts: RunCodeOptions = {},\n): ActionEntry {\n const extraBridgeTools = new Set(opts.bridgeTools ?? []);\n\n return {\n readOnly: true,\n // Allow a generous per-call timeout so large analytics jobs don't hit the\n // agent-loop's default 60 s cap.\n timeoutMs: MAX_TIMEOUT_MS,\n maxResultChars: MAX_OUTPUT_CHARS,\n tool: {\n description: [\n \"Execute JavaScript (Node.js, ESM, top-level await supported) in an isolated sandbox.\",\n \"Use this to fetch, join, aggregate, and reduce large datasets, returning only printed output to the conversation.\",\n \"The sandbox runs with a scrubbed environment (no secrets) and, where the Node permission model is available, no filesystem access outside its own temp dir, no child processes, and no workers. Authenticated calls must go through the provided globals; direct network requests carry no credentials. Note: isolation is process-level (env scrub + Node permission model), not an OS-level container — outbound network from sandbox code is not blocked.\",\n \"Available globals:\",\n \" - `appAction(name, args?)` — call any registered agent-exposed read-only app action/tool and get its parsed result.\",\n \" Use this to loop over app data readers and compose multi-source analyses without forcing every intermediate result into chat.\",\n \" - `providerFetch(provider, path, init?)` — authenticated call to a registered provider via the provider-api-request action.\",\n \" Returns the parsed JSON result (or throws on error).\",\n \" Example: `const data = await providerFetch('hubspot', '/crm/v3/objects/contacts');`\",\n \" - `webFetch(url, init?)` — outbound HTTP request via the web-request action.\",\n \" Returns `{ status, body }` where body is the response text.\",\n \" Example: `const { body } = await webFetch('https://api.example.com/data');`\",\n \" - `workspaceRead(path, opts?)` — read a workspace file by path. Returns content string or null. opts: { offset?, maxChars? }.\",\n \" - `workspaceReadMeta(path, opts?)` — read a workspace file with metadata such as sizeBytes, truncated, and nextOffset.\",\n \" - `workspaceWrite(path, content, contentType?)` — create or overwrite a workspace file.\",\n \" - `workspaceAppend(path, content)` — append text to a workspace file.\",\n \" - `workspaceList(prefix?)` — list workspace files, returns [{ path, sizeBytes, contentType, updatedAt }].\",\n \"Print results with `console.log()`; only stdout+stderr are returned.\",\n \"Timeout defaults to 120 s (max 600 s). Output is truncated to 50 000 chars by default (max 200 000).\",\n ].join(\" \"),\n parameters: {\n type: \"object\",\n properties: {\n code: {\n type: \"string\",\n description:\n \"JavaScript source to execute. ESM syntax, top-level await allowed.\",\n },\n timeoutMs: {\n type: \"number\",\n description: `Execution timeout in milliseconds. Default: ${DEFAULT_TIMEOUT_MS}. Max: ${MAX_TIMEOUT_MS}.`,\n },\n maxOutputChars: {\n type: \"number\",\n description: `Maximum combined stdout+stderr characters to return. Default: ${DEFAULT_MAX_OUTPUT_CHARS}. Max: ${MAX_OUTPUT_CHARS}.`,\n },\n },\n required: [\"code\"],\n },\n },\n run: async (args: Record<string, string>, context?: ActionRunContext) => {\n const code = typeof args.code === \"string\" ? args.code : \"\";\n if (!code.trim()) return \"Error: code is required.\";\n\n const requestedTimeout = Number(args.timeoutMs);\n const timeoutMs =\n Number.isFinite(requestedTimeout) && requestedTimeout > 0\n ? Math.min(requestedTimeout, MAX_TIMEOUT_MS)\n : DEFAULT_TIMEOUT_MS;\n\n const requestedMaxOutput = Number(args.maxOutputChars);\n const maxOutputChars =\n Number.isFinite(requestedMaxOutput) && requestedMaxOutput > 0\n ? Math.min(requestedMaxOutput, MAX_OUTPUT_CHARS)\n : DEFAULT_MAX_OUTPUT_CHARS;\n\n const actions = getActions();\n const bridgeToken = crypto.randomBytes(32).toString(\"hex\");\n\n // Start bridge server — resolves once the server is listening.\n const {\n server,\n bridgePort,\n cleanup: cleanupBridge,\n } = await startBridgeServer(\n bridgeToken,\n actions,\n context,\n DEFAULT_BRIDGE_TOOLS,\n extraBridgeTools,\n );\n\n let tmpDir: string | undefined;\n let tmpFile: string | undefined;\n try {\n // Write code to a temp ESM file (top-level await needs a module).\n const tmpBaseDir = fs.realpathSync(os.tmpdir());\n tmpDir = fs.mkdtempSync(path.join(tmpBaseDir, \"agent-run-code-\"));\n tmpFile = path.join(tmpDir, \"sandbox.mjs\");\n fs.writeFileSync(\n tmpFile,\n buildSandboxModule(code, bridgePort, bridgeToken),\n \"utf8\",\n );\n\n // Build scrubbed env — only safe POSIX vars, no secrets.\n const safeEnv: Record<string, string> = {};\n for (const key of [\n \"PATH\",\n \"HOME\",\n \"TMPDIR\",\n \"TEMP\",\n \"TMP\",\n \"LANG\",\n \"LC_ALL\",\n ]) {\n if (process.env[key]) safeEnv[key] = process.env[key]!;\n }\n // Point TMPDIR inside the sandbox dir so in-sandbox temp writes stay\n // within the permission-model allow list.\n safeEnv.TMPDIR = tmpDir;\n safeEnv.TEMP = tmpDir;\n safeEnv.TMP = tmpDir;\n\n // Lock the child down with the Node permission model when available:\n // filesystem restricted to the sandbox temp dir, and child processes,\n // workers, and native addons denied entirely.\n const permissionFlag = resolvePermissionFlag();\n const nodeArgs = permissionFlag\n ? [\n permissionFlag,\n ...sandboxReadAllowPaths(tmpDir).map(\n (allowedPath) => `--allow-fs-read=${allowedPath}`,\n ),\n ...sandboxWriteAllowPaths(tmpDir).map(\n (allowedPath) => `--allow-fs-write=${allowedPath}`,\n ),\n tmpFile,\n ]\n : [tmpFile];\n\n const child = spawn(process.execPath, nodeArgs, {\n cwd: tmpDir,\n env: safeEnv,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n\n let stdout = \"\";\n let stderr = \"\";\n let timedOut = false;\n\n const timer = setTimeout(() => {\n timedOut = true;\n child.kill(\"SIGTERM\");\n setTimeout(() => {\n try {\n child.kill(\"SIGKILL\");\n } catch {}\n }, 2_000);\n }, timeoutMs);\n\n child.stdout?.on(\"data\", (chunk: Buffer) => {\n stdout += chunk.toString();\n });\n child.stderr?.on(\"data\", (chunk: Buffer) => {\n stderr += chunk.toString();\n });\n\n const exitCode = await new Promise<number | null>((resolve, reject) => {\n child.once(\"error\", reject);\n child.once(\"exit\", resolve);\n });\n clearTimeout(timer);\n\n const combined =\n [\n stdout ? `stdout:\\n${stdout}` : \"\",\n stderr ? `stderr:\\n${stderr}` : \"\",\n ]\n .filter(Boolean)\n .join(\"\\n\\n\") || \"(no output)\";\n\n const lines: string[] = [];\n if (timedOut) lines.push(`timedOut: true (${timeoutMs}ms)`);\n if (exitCode !== 0 && exitCode !== null)\n lines.push(`exitCode: ${exitCode}`);\n lines.push(combined);\n\n const full = lines.join(\"\\n\\n\");\n if (full.length > maxOutputChars) {\n const truncated = full.slice(0, maxOutputChars);\n return `${truncated}\\n\\n...[truncated ${(full.length - maxOutputChars).toLocaleString()} chars]`;\n }\n return full;\n } finally {\n cleanupBridge();\n server.close();\n // Clean up temp files (best-effort).\n try {\n if (tmpFile) fs.rmSync(tmpFile, { force: true });\n if (tmpDir) fs.rmSync(tmpDir, { recursive: true, force: true });\n } catch {}\n }\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Bridge server\n// ---------------------------------------------------------------------------\n\ninterface BridgeResult {\n server: http.Server;\n bridgePort: number;\n cleanup: () => void;\n}\n\nasync function startBridgeServer(\n token: string,\n actions: Record<string, ActionEntry>,\n context: ActionRunContext | undefined,\n defaultTools: Set<string>,\n extraTools: Set<string>,\n): Promise<BridgeResult> {\n const server = http.createServer((req, res) => {\n if (req.method !== \"POST\" || req.url !== \"/tool\") {\n res.writeHead(404);\n res.end(\"Not found\");\n return;\n }\n\n // Validate bearer token — must match exactly.\n const authHeader = req.headers.authorization ?? \"\";\n if (authHeader !== `Bearer ${token}`) {\n res.writeHead(401);\n res.end(\"Unauthorized\");\n return;\n }\n\n let body = \"\";\n let receivedBytes = 0;\n let rejected = false;\n req.on(\"data\", (chunk: Buffer) => {\n receivedBytes += chunk.length;\n if (receivedBytes > BRIDGE_MAX_BODY_BYTES) {\n rejected = true;\n res.writeHead(413);\n res.end(\"Payload too large\");\n req.destroy();\n return;\n }\n body += chunk.toString();\n });\n req.on(\"end\", () => {\n if (rejected) return;\n handleBridgeRequest(\n body,\n actions,\n context,\n defaultTools,\n extraTools,\n res,\n );\n });\n req.on(\"error\", () => {\n res.writeHead(500);\n res.end(\"Request error\");\n });\n });\n\n await new Promise<void>((resolve, reject) => {\n server.once(\"error\", reject);\n server.listen(0, \"127.0.0.1\", () => resolve());\n });\n\n const addr = server.address() as { port: number };\n const bridgePort = addr.port;\n\n const cleanup = () => {\n try {\n server.close();\n } catch {}\n };\n\n return { server, bridgePort, cleanup };\n}\n\nfunction handleBridgeRequest(\n rawBody: string,\n actions: Record<string, ActionEntry>,\n context: ActionRunContext | undefined,\n defaultTools: Set<string>,\n extraTools: Set<string>,\n res: http.ServerResponse,\n): void {\n let parsed: { tool?: string; args?: Record<string, string> };\n try {\n parsed = JSON.parse(rawBody);\n } catch {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Invalid JSON body\" }));\n return;\n }\n\n const toolName = typeof parsed.tool === \"string\" ? parsed.tool.trim() : \"\";\n if (!toolName) {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Missing tool name\" }));\n return;\n }\n\n // Enforce allowlist.\n const entry = actions[toolName];\n const isReadOnlyAction =\n entry?.readOnly === true &&\n entry.agentTool !== false &&\n entry.toolCallable !== false;\n if (\n !defaultTools.has(toolName) &&\n !extraTools.has(toolName) &&\n !isReadOnlyAction\n ) {\n res.writeHead(403, { \"Content-Type\": \"application/json\" });\n res.end(\n JSON.stringify({\n error: `Tool \"${toolName}\" is not an agent-exposed read-only action or sandbox bridge allowlisted tool.`,\n }),\n );\n return;\n }\n\n if (!entry) {\n res.writeHead(404, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: `Tool \"${toolName}\" is not registered.` }));\n return;\n }\n\n const toolArgs = parsed.args ?? {};\n // Run the tool with the parent request context so auth/org/owner resolution\n // works exactly as it does in the normal agent loop.\n entry\n .run(toolArgs, context)\n .then((result: unknown) => {\n const body =\n typeof result === \"string\" ? result : JSON.stringify(result, null, 2);\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ result: body }));\n })\n .catch((err: unknown) => {\n const message = err instanceof Error ? err.message : String(err);\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: message }));\n });\n}\n\n// ---------------------------------------------------------------------------\n// Sandbox module template\n// ---------------------------------------------------------------------------\n\n/**\n * Wrap the user's code in an ESM module that:\n * 1. Defines `providerFetch` and `webFetch` helpers via the bridge.\n * 2. Runs the user's code as top-level await in an async IIFE.\n */\nfunction buildSandboxModule(\n userCode: string,\n bridgePort: number,\n bridgeToken: string,\n): string {\n return `\nimport { createRequire } from \"node:module\";\nconst require = createRequire(import.meta.url);\n\nconst _bridgeBase = \"http://127.0.0.1:${bridgePort}/tool\";\nconst _bridgeToken = \"${bridgeToken}\";\n\nasync function _bridgeCall(tool, args) {\n const http = await import(\"node:http\");\n return new Promise((resolve, reject) => {\n const body = JSON.stringify({ tool, args });\n const options = {\n hostname: \"127.0.0.1\",\n port: ${bridgePort},\n path: \"/tool\",\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"Content-Length\": Buffer.byteLength(body),\n \"Authorization\": \"Bearer \" + _bridgeToken,\n },\n };\n const req = http.request(options, (res) => {\n let data = \"\";\n res.on(\"data\", (chunk) => { data += chunk; });\n res.on(\"end\", () => {\n try {\n const parsed = JSON.parse(data);\n if (parsed.error) {\n reject(new Error(parsed.error));\n } else {\n resolve(parsed.result);\n }\n } catch (e) {\n reject(new Error(\"Bridge response parse error: \" + e.message));\n }\n });\n });\n req.on(\"error\", reject);\n req.end(body);\n });\n}\n\nfunction _parseBridgeResult(rawResult) {\n if (typeof rawResult !== \"string\") return rawResult;\n try { return JSON.parse(rawResult); } catch { return rawResult; }\n}\n\n/**\n * Call any registered agent-exposed read-only app action/tool via the sandbox bridge.\n * Mutating and explicitly hidden actions are blocked by the parent bridge.\n */\nasync function appAction(name, args = {}) {\n return _parseBridgeResult(await _bridgeCall(name, args));\n}\n\n/**\n * Call a provider API via the authenticated provider-api-request action.\n * Returns the parsed JSON response body (or throws on error).\n */\nasync function providerFetch(provider, apiPath, init = {}) {\n const method = (init.method || \"GET\").toUpperCase();\n const rawResult = await _bridgeCall(\"provider-api-request\", {\n provider,\n path: apiPath,\n method,\n ...(init.query ? { query: init.query } : {}),\n ...(init.body ? { body: init.body } : {}),\n ...(init.headers ? { headers: init.headers } : {}),\n ...(init.auth ? { auth: init.auth } : {}),\n ...(init.connectionId ? { connectionId: init.connectionId } : {}),\n ...(init.accountId ? { accountId: init.accountId } : {}),\n ...(init.timeoutMs ? { timeoutMs: init.timeoutMs } : {}),\n ...(init.maxBytes ? { maxBytes: init.maxBytes } : {}),\n ...(init.stageAs ? { stageAs: init.stageAs } : {}),\n ...(init.itemsPath ? { itemsPath: init.itemsPath } : {}),\n ...(init.pagination ? { pagination: init.pagination } : {}),\n ...(init.saveToFile ? { saveToFile: init.saveToFile } : {}),\n ...(init.fetchAllPages ? { fetchAllPages: init.fetchAllPages } : {}),\n });\n // rawResult is the action's string output; parse it if it looks like JSON\n let parsed = _parseBridgeResult(rawResult);\n // Unwrap the provider-api-request envelope ({ provider, request, response, guidance })\n // so callers get the actual response body. fetchAllPages / saveToFile results\n // (which have no \\`response\\` field) are returned as-is.\n if (parsed && typeof parsed === \"object\" && parsed.response && typeof parsed.response === \"object\") {\n const r = parsed.response;\n if (typeof r.status === \"number\" && r.status >= 400) {\n const detail = typeof r.text === \"string\" ? r.text : JSON.stringify(r.json ?? \"\");\n throw new Error(\\`Provider request failed (\\${r.status}): \\${String(detail).slice(0, 500)}\\`);\n }\n return r.json !== undefined ? r.json : r.text;\n }\n return parsed;\n}\n\n/**\n * Make an outbound HTTP request via the web-request action.\n * Returns an object \\`{ status, body }\\` where \\`body\\` is the response text.\n */\nasync function webFetch(url, init = {}) {\n const method = (init.method || \"GET\").toUpperCase();\n const rawResult = await _bridgeCall(\"web-request\", {\n url,\n method,\n ...(init.headers ? { headers: typeof init.headers === \"string\" ? init.headers : JSON.stringify(init.headers) } : {}),\n ...(init.body ? { body: typeof init.body === \"string\" ? init.body : JSON.stringify(init.body) } : {}),\n });\n // rawResult is \"HTTP <status> <statusText>\\\\n\\\\n<body>\"\n const statusMatch = typeof rawResult === \"string\" ? rawResult.match(/^HTTP (\\\\d+) [^\\\\n]*\\\\n\\\\n/) : null;\n if (statusMatch) {\n return {\n status: Number(statusMatch[1]),\n body: rawResult.slice(statusMatch[0].length),\n };\n }\n return { status: 0, body: rawResult };\n}\n\n/**\n * Read a workspace file by path. Returns the file content as a string, or null if not found.\n * Supports optional offset and maxChars for paging large files.\n */\nasync function workspaceRead(path, opts = {}) {\n const parsed = await workspaceReadMeta(path, opts);\n if (parsed && parsed.ok === false) return null;\n return parsed && typeof parsed.content === \"string\" ? parsed.content : null;\n}\n\n/**\n * Read a workspace file by path and return the full metadata envelope.\n * Use this when offset/maxChars paging or truncation status matters.\n */\nasync function workspaceReadMeta(path, opts = {}) {\n const rawResult = await _bridgeCall(\"workspace-files\", {\n action: \"read\",\n path,\n ...(opts.offset !== undefined ? { offset: opts.offset } : {}),\n ...(opts.maxChars !== undefined ? { maxChars: opts.maxChars } : {}),\n });\n return _parseBridgeResult(rawResult);\n}\n\n/**\n * Write (create or overwrite) a workspace file.\n * \\`content\\` must be a string. Returns metadata { path, sizeBytes, updatedAt }.\n */\nasync function workspaceWrite(path, content, contentType = \"text/plain\") {\n const rawResult = await _bridgeCall(\"workspace-files\", {\n action: \"write\",\n path,\n content: typeof content === \"string\" ? content : JSON.stringify(content),\n contentType,\n });\n try { return typeof rawResult === \"string\" ? JSON.parse(rawResult) : rawResult; } catch { return rawResult; }\n}\n\n/**\n * Append text to a workspace file (creates if absent).\n */\nasync function workspaceAppend(path, content) {\n const rawResult = await _bridgeCall(\"workspace-files\", {\n action: \"append\",\n path,\n content: typeof content === \"string\" ? content : JSON.stringify(content),\n });\n try { return typeof rawResult === \"string\" ? JSON.parse(rawResult) : rawResult; } catch { return rawResult; }\n}\n\n/**\n * List workspace files, optionally filtered by path prefix.\n * Returns an array of { path, sizeBytes, contentType, updatedAt }.\n */\nasync function workspaceList(prefix) {\n const rawResult = await _bridgeCall(\"workspace-files\", {\n action: \"list\",\n ...(prefix ? { path: prefix } : {}),\n });\n const parsed = typeof rawResult === \"string\" ? JSON.parse(rawResult) : rawResult;\n if (parsed && Array.isArray(parsed.files)) return parsed.files;\n if (Array.isArray(parsed)) return parsed;\n throw new Error(\"workspaceList: unexpected result shape: \" + JSON.stringify(parsed).slice(0, 200));\n}\n\n// Run user code\n(async () => {\n${userCode}\n})().catch((err) => {\n console.error(\"Unhandled error:\", err?.message ?? String(err));\n process.exit(1);\n});\n`;\n}\n"]}
|