@copilotkit/runtime 2.0.0-rc.1 → 2.0.0-rc.3
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/index.cjs +14 -14
- package/dist/agent/index.cjs.map +1 -1
- package/dist/agent/index.d.cts.map +1 -1
- package/dist/agent/index.d.mts.map +1 -1
- package/dist/agent/index.mjs +15 -15
- package/dist/agent/index.mjs.map +1 -1
- package/dist/agent/url-download.cjs +10 -11
- package/dist/agent/url-download.cjs.map +1 -1
- package/dist/agent/url-download.d.cts.map +1 -1
- package/dist/agent/url-download.d.mts.map +1 -1
- package/dist/agent/url-download.mjs +10 -11
- package/dist/agent/url-download.mjs.map +1 -1
- package/dist/runtime/core/channel-manager.cjs +4 -4
- package/dist/runtime/core/channel-manager.cjs.map +1 -1
- package/dist/runtime/core/channel-manager.mjs +4 -4
- package/dist/runtime/core/channel-manager.mjs.map +1 -1
- package/dist/runtime/core/debug-event-bus.cjs +3 -1
- package/dist/runtime/core/debug-event-bus.cjs.map +1 -1
- package/dist/runtime/core/debug-event-bus.d.cts.map +1 -1
- package/dist/runtime/core/debug-event-bus.d.mts.map +1 -1
- package/dist/runtime/core/debug-event-bus.mjs +3 -1
- package/dist/runtime/core/debug-event-bus.mjs.map +1 -1
- package/dist/runtime/core/logger.cjs +2 -1
- package/dist/runtime/core/logger.cjs.map +1 -1
- package/dist/runtime/core/logger.d.cts.map +1 -1
- package/dist/runtime/core/logger.d.mts.map +1 -1
- package/dist/runtime/core/logger.mjs +2 -1
- package/dist/runtime/core/logger.mjs.map +1 -1
- package/dist/runtime/core/package-info.cjs +1 -1
- package/dist/runtime/core/package-info.mjs +1 -1
- package/dist/runtime/core/runtime.cjs +19 -5
- package/dist/runtime/core/runtime.cjs.map +1 -1
- package/dist/runtime/core/runtime.d.cts +19 -3
- package/dist/runtime/core/runtime.d.cts.map +1 -1
- package/dist/runtime/core/runtime.d.mts +19 -3
- package/dist/runtime/core/runtime.d.mts.map +1 -1
- package/dist/runtime/core/runtime.mjs +20 -6
- package/dist/runtime/core/runtime.mjs.map +1 -1
- package/dist/runtime/core/web-crypto.cjs +22 -0
- package/dist/runtime/core/web-crypto.cjs.map +1 -0
- package/dist/runtime/core/web-crypto.mjs +20 -0
- package/dist/runtime/core/web-crypto.mjs.map +1 -0
- package/dist/runtime/handlers/get-runtime-info.cjs +7 -6
- package/dist/runtime/handlers/get-runtime-info.cjs.map +1 -1
- package/dist/runtime/handlers/get-runtime-info.mjs +7 -6
- package/dist/runtime/handlers/get-runtime-info.mjs.map +1 -1
- package/dist/runtime/handlers/intelligence/thread-names.cjs +3 -4
- package/dist/runtime/handlers/intelligence/thread-names.cjs.map +1 -1
- package/dist/runtime/handlers/intelligence/thread-names.mjs +3 -4
- package/dist/runtime/handlers/intelligence/thread-names.mjs.map +1 -1
- package/dist/runtime/handlers/shared/agent-utils.cjs +1 -1
- package/dist/runtime/handlers/shared/agent-utils.cjs.map +1 -1
- package/dist/runtime/handlers/shared/agent-utils.mjs +2 -2
- package/dist/runtime/handlers/shared/agent-utils.mjs.map +1 -1
- package/dist/runtime/intelligence-platform/client.cjs +1 -2
- package/dist/runtime/intelligence-platform/client.cjs.map +1 -1
- package/dist/runtime/intelligence-platform/client.d.cts.map +1 -1
- package/dist/runtime/intelligence-platform/client.d.mts.map +1 -1
- package/dist/runtime/intelligence-platform/client.mjs +1 -2
- package/dist/runtime/intelligence-platform/client.mjs.map +1 -1
- package/dist/runtime/intelligence-platform/skill-registry/config.cjs +3 -1
- package/dist/runtime/intelligence-platform/skill-registry/config.cjs.map +1 -1
- package/dist/runtime/intelligence-platform/skill-registry/config.d.cts.map +1 -1
- package/dist/runtime/intelligence-platform/skill-registry/config.d.mts.map +1 -1
- package/dist/runtime/intelligence-platform/skill-registry/config.mjs +2 -1
- package/dist/runtime/intelligence-platform/skill-registry/config.mjs.map +1 -1
- package/dist/runtime/intelligence-platform/skill-registry/registry.cjs +4 -5
- package/dist/runtime/intelligence-platform/skill-registry/registry.cjs.map +1 -1
- package/dist/runtime/intelligence-platform/skill-registry/registry.d.cts.map +1 -1
- package/dist/runtime/intelligence-platform/skill-registry/registry.d.mts.map +1 -1
- package/dist/runtime/intelligence-platform/skill-registry/registry.mjs +4 -4
- package/dist/runtime/intelligence-platform/skill-registry/registry.mjs.map +1 -1
- package/dist/runtime/intelligence-platform/skill-registry/snapshot.cjs +3 -7
- package/dist/runtime/intelligence-platform/skill-registry/snapshot.cjs.map +1 -1
- package/dist/runtime/intelligence-platform/skill-registry/snapshot.d.cts.map +1 -1
- package/dist/runtime/intelligence-platform/skill-registry/snapshot.d.mts.map +1 -1
- package/dist/runtime/intelligence-platform/skill-registry/snapshot.mjs +3 -6
- package/dist/runtime/intelligence-platform/skill-registry/snapshot.mjs.map +1 -1
- package/dist/runtime/runner/intelligence.cjs +1 -2
- package/dist/runtime/runner/intelligence.cjs.map +1 -1
- package/dist/runtime/runner/intelligence.d.cts.map +1 -1
- package/dist/runtime/runner/intelligence.d.mts.map +1 -1
- package/dist/runtime/runner/intelligence.mjs +1 -2
- package/dist/runtime/runner/intelligence.mjs.map +1 -1
- package/dist/runtime/telemetry/disclosure.cjs +3 -1
- package/dist/runtime/telemetry/disclosure.cjs.map +1 -1
- package/dist/runtime/telemetry/disclosure.mjs +3 -1
- package/dist/runtime/telemetry/disclosure.mjs.map +1 -1
- package/dist/runtime/telemetry/telemetry-client.cjs +2 -2
- package/dist/runtime/telemetry/telemetry-client.cjs.map +1 -1
- package/dist/runtime/telemetry/telemetry-client.d.cts.map +1 -1
- package/dist/runtime/telemetry/telemetry-client.d.mts.map +1 -1
- package/dist/runtime/telemetry/telemetry-client.mjs +3 -3
- package/dist/runtime/telemetry/telemetry-client.mjs.map +1 -1
- package/package.json +3 -3
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { isHandlerResponse } from "../shared/json-response.mjs";
|
|
2
2
|
import { cloneAgentForRequest, configureAgentForRequest } from "../shared/agent-utils.mjs";
|
|
3
3
|
import { logger } from "@copilotkit/shared";
|
|
4
|
-
import { randomUUID as randomUUID$1 } from "node:crypto";
|
|
5
4
|
|
|
6
5
|
//#region src/runtime/handlers/intelligence/thread-names.ts
|
|
7
6
|
const THREAD_NAME_SYSTEM_PROMPT = [
|
|
@@ -73,17 +72,17 @@ async function runTitleGenerationAttempt(params) {
|
|
|
73
72
|
agent
|
|
74
73
|
});
|
|
75
74
|
const messages = [{
|
|
76
|
-
id: randomUUID
|
|
75
|
+
id: globalThis.crypto.randomUUID(),
|
|
77
76
|
role: "system",
|
|
78
77
|
content: THREAD_NAME_SYSTEM_PROMPT
|
|
79
78
|
}, {
|
|
80
|
-
id: randomUUID
|
|
79
|
+
id: globalThis.crypto.randomUUID(),
|
|
81
80
|
role: "user",
|
|
82
81
|
content: prompt
|
|
83
82
|
}];
|
|
84
83
|
agent.setMessages(messages);
|
|
85
84
|
agent.setState({});
|
|
86
|
-
agent.threadId = randomUUID
|
|
85
|
+
agent.threadId = globalThis.crypto.randomUUID();
|
|
87
86
|
const { newMessages } = await agent.runAgent({
|
|
88
87
|
tools: [],
|
|
89
88
|
context: [],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"thread-names.mjs","names":["randomUUID"],"sources":["../../../../src/runtime/handlers/intelligence/thread-names.ts"],"sourcesContent":["import type { Message, RunAgentInput } from \"@ag-ui/client\";\nimport { logger } from \"@copilotkit/shared\";\nimport { randomUUID } from \"node:crypto\";\nimport type { CopilotIntelligenceRuntimeLike } from \"../../core/runtime\";\nimport {\n cloneAgentForRequest,\n configureAgentForRequest,\n} from \"../shared/agent-utils\";\nimport type { ThreadSummary } from \"../../intelligence-platform\";\nimport { isHandlerResponse } from \"../shared/json-response\";\n\nconst THREAD_NAME_SYSTEM_PROMPT = [\n \"You generate short, specific conversation titles.\",\n 'Return JSON only in this exact shape: {\"title\":\"...\"}',\n \"The title must be 2 to 5 words.\",\n \"Use sentence case.\",\n \"No quotes.\",\n \"No emoji.\",\n \"No markdown characters or formatting.\",\n \"Do not use *, _, #, `, [, ], (, ), !, ~, >, or |.\",\n \"No trailing punctuation.\",\n \"No explanations.\",\n \"Do not call tools.\",\n].join(\"\\n\");\n\nconst MAX_TITLE_LENGTH = 80;\nconst MAX_TITLE_WORDS = 8;\nconst MAX_TRANSCRIPT_MESSAGES = 8;\nconst MAX_TITLE_GENERATION_ATTEMPTS = 3;\nconst FALLBACK_THREAD_TITLE = \"Untitled\";\n\ninterface GenerateThreadNameParams {\n runtime: CopilotIntelligenceRuntimeLike;\n request: Request;\n agentId: string;\n sourceInput: RunAgentInput;\n thread: ThreadSummary;\n userId: string;\n}\n\nexport async function generateThreadNameForNewThread({\n runtime,\n request,\n agentId,\n sourceInput,\n thread,\n userId,\n}: GenerateThreadNameParams): Promise<void> {\n if (!runtime.generateThreadNames || hasThreadName(thread.name)) {\n return;\n }\n\n const prompt = buildThreadTitlePrompt(sourceInput.messages);\n if (!prompt) {\n return;\n }\n\n let generatedTitle: string | null = null;\n\n for (let attempt = 1; attempt <= MAX_TITLE_GENERATION_ATTEMPTS; attempt++) {\n try {\n generatedTitle = await runTitleGenerationAttempt({\n runtime,\n request,\n agentId,\n threadId: thread.id,\n prompt,\n });\n\n if (generatedTitle) {\n break;\n }\n\n logger.warn(\n { agentId, attempt, threadId: thread.id },\n \"Thread name generation returned an empty or invalid title\",\n );\n } catch (error) {\n logger.warn(\n { err: error, agentId, attempt, threadId: thread.id },\n \"Thread name generation attempt failed\",\n );\n }\n }\n\n await runtime.intelligence.updateThread({\n threadId: thread.id,\n userId,\n agentId,\n updates: {\n name:\n generatedTitle ?? deriveFallbackTitleFromMessages(sourceInput.messages),\n },\n });\n}\n\nasync function runTitleGenerationAttempt(params: {\n runtime: CopilotIntelligenceRuntimeLike;\n request: Request;\n agentId: string;\n threadId: string;\n prompt: string;\n}): Promise<string | null> {\n const { runtime, request, agentId, threadId, prompt } = params;\n const agent = await cloneAgentForRequest(runtime, agentId, request);\n if (isHandlerResponse(agent)) {\n logger.warn(\n { agentId, threadId },\n \"Skipping thread naming because the agent could not be cloned\",\n );\n return null;\n }\n\n configureAgentForRequest({\n runtime,\n request,\n agentId,\n agent,\n });\n\n const messages: Message[] = [\n {\n id: randomUUID(),\n role: \"system\",\n content: THREAD_NAME_SYSTEM_PROMPT,\n },\n {\n id: randomUUID(),\n role: \"user\",\n content: prompt,\n },\n ];\n\n agent.setMessages(messages);\n agent.setState({});\n agent.threadId = randomUUID();\n // Messages and state are picked up from the agent itself (set above);\n // RunAgentParameters no longer accepts them directly.\n const { newMessages } = await agent.runAgent({\n tools: [],\n context: [],\n forwardedProps: {},\n });\n\n return selectGeneratedTitleFromMessages(newMessages);\n}\n\nfunction buildThreadTitlePrompt(\n messages: Message[] | undefined,\n): string | null {\n const transcript = (messages ?? [])\n .filter((message) =>\n [\"user\", \"assistant\", \"system\", \"developer\"].includes(message.role),\n )\n .map((message) => {\n const content = stringifyMessageContent(message.content);\n if (!content) {\n return null;\n }\n\n return `${message.role}: ${content}`;\n })\n .filter((message): message is string => !!message)\n .slice(-MAX_TRANSCRIPT_MESSAGES);\n\n if (transcript.length === 0) {\n return null;\n }\n\n return [\n \"Conversation:\",\n transcript.join(\"\\n\"),\n 'Generate a short title for the conversation above. Return JSON only in this exact shape: {\"title\":\"...\"}. Do not answer the conversation.',\n ].join(\"\\n\\n\");\n}\n\nfunction stringifyMessageContent(content: Message[\"content\"]): string {\n if (typeof content === \"string\") {\n return content.trim();\n }\n\n if (content == null) {\n return \"\";\n }\n\n try {\n return JSON.stringify(content).trim();\n } catch {\n return \"\";\n }\n}\n\nfunction normalizeGeneratedTitle(rawTitle: string): string | null {\n let candidate = rawTitle.trim();\n if (!candidate) {\n return null;\n }\n\n candidate = candidate\n .replace(/^```(?:json)?\\s*/i, \"\")\n .replace(/\\s*```$/, \"\")\n .trim();\n\n const jsonLike = isJsonLike(candidate);\n\n try {\n const parsed = JSON.parse(candidate) as { title?: unknown };\n if (typeof parsed.title === \"string\") {\n candidate = parsed.title;\n } else if (jsonLike) {\n return null;\n }\n } catch {\n if (jsonLike) {\n return null;\n }\n }\n\n candidate = cleanupTitleText(candidate);\n\n if (!candidate) {\n return null;\n }\n\n if (candidate.length > MAX_TITLE_LENGTH) {\n candidate = candidate.slice(0, MAX_TITLE_LENGTH).trim();\n }\n\n if (candidate.split(/\\s+/).length > MAX_TITLE_WORDS) {\n return null;\n }\n\n return candidate;\n}\n\nfunction cleanupTitleText(text: string): string {\n return text\n .replace(/^[\"'`]+|[\"'`]+$/g, \"\")\n .replace(/[*_#[\\]()!~>|]+/g, \"\")\n .replace(/[.!?,;:]+$/g, \"\")\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\nfunction deriveFallbackTitleFromMessages(\n messages: Message[] | undefined,\n): string {\n for (const message of messages ?? []) {\n if (message.role !== \"user\") {\n continue;\n }\n\n const cleaned = cleanupTitleText(stringifyMessageContent(message.content));\n if (!cleaned) {\n continue;\n }\n\n let title = cleaned.split(/\\s+/).slice(0, MAX_TITLE_WORDS).join(\" \");\n if (title.length > MAX_TITLE_LENGTH) {\n title = title.slice(0, MAX_TITLE_LENGTH).trim();\n }\n\n return title || FALLBACK_THREAD_TITLE;\n }\n\n return FALLBACK_THREAD_TITLE;\n}\n\nfunction selectGeneratedTitleFromMessages(messages: Message[]): string | null {\n for (let index = messages.length - 1; index >= 0; index--) {\n const message = messages[index];\n if (message.role !== \"assistant\" || typeof message.content !== \"string\") {\n continue;\n }\n\n const title = normalizeGeneratedTitle(message.content);\n if (title) {\n return title;\n }\n }\n\n return null;\n}\n\nfunction isJsonLike(candidate: string): boolean {\n return (\n (candidate.startsWith(\"{\") && candidate.endsWith(\"}\")) ||\n (candidate.startsWith(\"[\") && candidate.endsWith(\"]\"))\n );\n}\n\nfunction hasThreadName(name: string | null | undefined): boolean {\n return typeof name === \"string\" && name.trim().length > 0;\n}\n\n/** @internal Exported for testing only. */\nexport const ɵnormalizeGeneratedTitle = normalizeGeneratedTitle;\n/** @internal Exported for testing only. */\nexport const ɵselectGeneratedTitleFromMessages =\n selectGeneratedTitleFromMessages;\n/** @internal Exported for testing only. */\nexport const ɵbuildThreadTitlePrompt = buildThreadTitlePrompt;\n/** @internal Exported for testing only. */\nexport const ɵhasThreadName = hasThreadName;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"thread-names.mjs","names":[],"sources":["../../../../src/runtime/handlers/intelligence/thread-names.ts"],"sourcesContent":["import type { Message, RunAgentInput } from \"@ag-ui/client\";\nimport { logger } from \"@copilotkit/shared\";\nimport type { CopilotIntelligenceRuntimeLike } from \"../../core/runtime\";\nimport {\n cloneAgentForRequest,\n configureAgentForRequest,\n} from \"../shared/agent-utils\";\nimport type { ThreadSummary } from \"../../intelligence-platform\";\nimport { isHandlerResponse } from \"../shared/json-response\";\n\nconst THREAD_NAME_SYSTEM_PROMPT = [\n \"You generate short, specific conversation titles.\",\n 'Return JSON only in this exact shape: {\"title\":\"...\"}',\n \"The title must be 2 to 5 words.\",\n \"Use sentence case.\",\n \"No quotes.\",\n \"No emoji.\",\n \"No markdown characters or formatting.\",\n \"Do not use *, _, #, `, [, ], (, ), !, ~, >, or |.\",\n \"No trailing punctuation.\",\n \"No explanations.\",\n \"Do not call tools.\",\n].join(\"\\n\");\n\nconst MAX_TITLE_LENGTH = 80;\nconst MAX_TITLE_WORDS = 8;\nconst MAX_TRANSCRIPT_MESSAGES = 8;\nconst MAX_TITLE_GENERATION_ATTEMPTS = 3;\nconst FALLBACK_THREAD_TITLE = \"Untitled\";\n\ninterface GenerateThreadNameParams {\n runtime: CopilotIntelligenceRuntimeLike;\n request: Request;\n agentId: string;\n sourceInput: RunAgentInput;\n thread: ThreadSummary;\n userId: string;\n}\n\nexport async function generateThreadNameForNewThread({\n runtime,\n request,\n agentId,\n sourceInput,\n thread,\n userId,\n}: GenerateThreadNameParams): Promise<void> {\n if (!runtime.generateThreadNames || hasThreadName(thread.name)) {\n return;\n }\n\n const prompt = buildThreadTitlePrompt(sourceInput.messages);\n if (!prompt) {\n return;\n }\n\n let generatedTitle: string | null = null;\n\n for (let attempt = 1; attempt <= MAX_TITLE_GENERATION_ATTEMPTS; attempt++) {\n try {\n generatedTitle = await runTitleGenerationAttempt({\n runtime,\n request,\n agentId,\n threadId: thread.id,\n prompt,\n });\n\n if (generatedTitle) {\n break;\n }\n\n logger.warn(\n { agentId, attempt, threadId: thread.id },\n \"Thread name generation returned an empty or invalid title\",\n );\n } catch (error) {\n logger.warn(\n { err: error, agentId, attempt, threadId: thread.id },\n \"Thread name generation attempt failed\",\n );\n }\n }\n\n await runtime.intelligence.updateThread({\n threadId: thread.id,\n userId,\n agentId,\n updates: {\n name:\n generatedTitle ?? deriveFallbackTitleFromMessages(sourceInput.messages),\n },\n });\n}\n\nasync function runTitleGenerationAttempt(params: {\n runtime: CopilotIntelligenceRuntimeLike;\n request: Request;\n agentId: string;\n threadId: string;\n prompt: string;\n}): Promise<string | null> {\n const { runtime, request, agentId, threadId, prompt } = params;\n const agent = await cloneAgentForRequest(runtime, agentId, request);\n if (isHandlerResponse(agent)) {\n logger.warn(\n { agentId, threadId },\n \"Skipping thread naming because the agent could not be cloned\",\n );\n return null;\n }\n\n configureAgentForRequest({\n runtime,\n request,\n agentId,\n agent,\n });\n\n const messages: Message[] = [\n {\n id: globalThis.crypto.randomUUID(),\n role: \"system\",\n content: THREAD_NAME_SYSTEM_PROMPT,\n },\n {\n id: globalThis.crypto.randomUUID(),\n role: \"user\",\n content: prompt,\n },\n ];\n\n agent.setMessages(messages);\n agent.setState({});\n agent.threadId = globalThis.crypto.randomUUID();\n // Messages and state are picked up from the agent itself (set above);\n // RunAgentParameters no longer accepts them directly.\n const { newMessages } = await agent.runAgent({\n tools: [],\n context: [],\n forwardedProps: {},\n });\n\n return selectGeneratedTitleFromMessages(newMessages);\n}\n\nfunction buildThreadTitlePrompt(\n messages: Message[] | undefined,\n): string | null {\n const transcript = (messages ?? [])\n .filter((message) =>\n [\"user\", \"assistant\", \"system\", \"developer\"].includes(message.role),\n )\n .map((message) => {\n const content = stringifyMessageContent(message.content);\n if (!content) {\n return null;\n }\n\n return `${message.role}: ${content}`;\n })\n .filter((message): message is string => !!message)\n .slice(-MAX_TRANSCRIPT_MESSAGES);\n\n if (transcript.length === 0) {\n return null;\n }\n\n return [\n \"Conversation:\",\n transcript.join(\"\\n\"),\n 'Generate a short title for the conversation above. Return JSON only in this exact shape: {\"title\":\"...\"}. Do not answer the conversation.',\n ].join(\"\\n\\n\");\n}\n\nfunction stringifyMessageContent(content: Message[\"content\"]): string {\n if (typeof content === \"string\") {\n return content.trim();\n }\n\n if (content == null) {\n return \"\";\n }\n\n try {\n return JSON.stringify(content).trim();\n } catch {\n return \"\";\n }\n}\n\nfunction normalizeGeneratedTitle(rawTitle: string): string | null {\n let candidate = rawTitle.trim();\n if (!candidate) {\n return null;\n }\n\n candidate = candidate\n .replace(/^```(?:json)?\\s*/i, \"\")\n .replace(/\\s*```$/, \"\")\n .trim();\n\n const jsonLike = isJsonLike(candidate);\n\n try {\n const parsed = JSON.parse(candidate) as { title?: unknown };\n if (typeof parsed.title === \"string\") {\n candidate = parsed.title;\n } else if (jsonLike) {\n return null;\n }\n } catch {\n if (jsonLike) {\n return null;\n }\n }\n\n candidate = cleanupTitleText(candidate);\n\n if (!candidate) {\n return null;\n }\n\n if (candidate.length > MAX_TITLE_LENGTH) {\n candidate = candidate.slice(0, MAX_TITLE_LENGTH).trim();\n }\n\n if (candidate.split(/\\s+/).length > MAX_TITLE_WORDS) {\n return null;\n }\n\n return candidate;\n}\n\nfunction cleanupTitleText(text: string): string {\n return text\n .replace(/^[\"'`]+|[\"'`]+$/g, \"\")\n .replace(/[*_#[\\]()!~>|]+/g, \"\")\n .replace(/[.!?,;:]+$/g, \"\")\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\nfunction deriveFallbackTitleFromMessages(\n messages: Message[] | undefined,\n): string {\n for (const message of messages ?? []) {\n if (message.role !== \"user\") {\n continue;\n }\n\n const cleaned = cleanupTitleText(stringifyMessageContent(message.content));\n if (!cleaned) {\n continue;\n }\n\n let title = cleaned.split(/\\s+/).slice(0, MAX_TITLE_WORDS).join(\" \");\n if (title.length > MAX_TITLE_LENGTH) {\n title = title.slice(0, MAX_TITLE_LENGTH).trim();\n }\n\n return title || FALLBACK_THREAD_TITLE;\n }\n\n return FALLBACK_THREAD_TITLE;\n}\n\nfunction selectGeneratedTitleFromMessages(messages: Message[]): string | null {\n for (let index = messages.length - 1; index >= 0; index--) {\n const message = messages[index];\n if (message.role !== \"assistant\" || typeof message.content !== \"string\") {\n continue;\n }\n\n const title = normalizeGeneratedTitle(message.content);\n if (title) {\n return title;\n }\n }\n\n return null;\n}\n\nfunction isJsonLike(candidate: string): boolean {\n return (\n (candidate.startsWith(\"{\") && candidate.endsWith(\"}\")) ||\n (candidate.startsWith(\"[\") && candidate.endsWith(\"]\"))\n );\n}\n\nfunction hasThreadName(name: string | null | undefined): boolean {\n return typeof name === \"string\" && name.trim().length > 0;\n}\n\n/** @internal Exported for testing only. */\nexport const ɵnormalizeGeneratedTitle = normalizeGeneratedTitle;\n/** @internal Exported for testing only. */\nexport const ɵselectGeneratedTitleFromMessages =\n selectGeneratedTitleFromMessages;\n/** @internal Exported for testing only. */\nexport const ɵbuildThreadTitlePrompt = buildThreadTitlePrompt;\n/** @internal Exported for testing only. */\nexport const ɵhasThreadName = hasThreadName;\n"],"mappings":"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"}
|
|
@@ -136,7 +136,7 @@ async function attachIntelligenceEnterpriseLearning(params) {
|
|
|
136
136
|
}]));
|
|
137
137
|
}
|
|
138
138
|
function warnCompatibility(what, replacement) {
|
|
139
|
-
if (typeof process !== "undefined" && typeof
|
|
139
|
+
if (typeof process !== "undefined" && typeof (0, _copilotkit_shared.processEnv)() !== "undefined" && (0, _copilotkit_shared.processEnv)().SUPPRESS_TRANSFORMATION_WARNINGS) return;
|
|
140
140
|
console.warn(`[ag-ui][compat] Converting deprecated ${what} to ${replacement}. The old shape leaves the protocol after its shim window — see the repo-root DEPRECATIONS.md. Set SUPPRESS_TRANSFORMATION_WARNINGS=true to silence.`);
|
|
141
141
|
}
|
|
142
142
|
function isRecord(value) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-utils.cjs","names":["resolveAgents","isA2UIEnabled","A2UIMiddleware","isIntelligenceRuntime","resolveMcpAppsServers","MCPAppsMiddleware","OpenGenerativeUIMiddleware","GenerativeUIMiddleware","mergeForwardableHeaders","resolveForwardHeadersPolicy","resolveIntelligenceUser","resolveWebMemory","grantAllowsMemory","errorResponse","MCPMiddleware","INTELLIGENCE_USER_ID_HEADER","INTELLIGENCE_MEMORY_GRANT_HEADER","RunAgentInputSchema"],"sources":["../../../../src/runtime/handlers/shared/agent-utils.ts"],"sourcesContent":["import type { AbstractAgent, RunAgentInput } from \"@ag-ui/client\";\nimport { RunAgentInputSchema } from \"@ag-ui/core/schemas\";\nimport type { CopilotKitUIEnvelope } from \"@copilotkit/shared\";\nimport {\n A2UIMiddleware,\n OpenGenerativeUIMiddleware,\n} from \"@copilotkit/shared/event-transforms\";\nimport { MCPAppsMiddleware } from \"@ag-ui/mcp-apps-middleware\";\nimport { MCPMiddleware } from \"@ag-ui/mcp-middleware\";\nimport { GenerativeUIMiddleware } from \"../../generative-ui\";\nimport type { CopilotRuntimeLike } from \"../../core/runtime\";\nimport {\n isA2UIEnabled,\n isIntelligenceRuntime,\n resolveAgents,\n} from \"../../core/runtime\";\nimport {\n INTELLIGENCE_MEMORY_GRANT_HEADER,\n INTELLIGENCE_USER_ID_HEADER,\n} from \"../../intelligence-platform/client\";\nimport {\n mergeForwardableHeaders,\n resolveForwardHeadersPolicy,\n} from \"../header-utils\";\nimport { resolveMcpAppsServers } from \"./mcp-apps-servers\";\nimport { resolveIntelligenceUser } from \"./resolve-intelligence-user\";\nimport { grantAllowsMemory, resolveWebMemory } from \"./memory-policy\";\nimport { errorResponse } from \"./json-response\";\nimport { logger } from \"@copilotkit/shared\";\n\ntype MiddlewareCapableAgent = AbstractAgent & {\n use?: (middleware: unknown) => void;\n headers?: Record<string, string>;\n};\n\nexport interface RunAgentParameters {\n request: Request;\n runtime: CopilotRuntimeLike;\n agentId: string;\n}\n\nexport interface ConnectRequestBody extends RunAgentInput {\n lastSeenEventId?: string | null;\n}\n\n/**\n * Resolve `agentId` against the runtime's agents and return a per-request\n * clone of the matching agent.\n *\n * Dual return contract — both callers (`handle-run.ts`, `handle-connect.ts`)\n * depend on it:\n * - Returns a cloned `AbstractAgent` when the agent exists.\n * - Returns a 404 `Response` (`{ error: \"Agent not found\", ... }`) when the\n * agent is unknown. Callers MUST `instanceof Response`-check the result and\n * return it directly; this doubles as the connect/run path's agent-existence\n * guard, so skipping the check would let unknown agent ids slip through.\n *\n * The clone is what subsequent per-request mutation (middleware attach,\n * `agent.headers` merge) operates on, leaving the shared agent registration\n * untouched.\n */\nexport async function cloneAgentForRequest(\n runtime: CopilotRuntimeLike,\n agentId: string,\n request?: Request,\n): Promise<AbstractAgent | Response> {\n const agents = await resolveAgents(runtime.agents, request);\n\n if (!agents[agentId]) {\n return new Response(\n JSON.stringify({\n error: \"Agent not found\",\n message: `Agent '${agentId}' does not exist`,\n }),\n {\n status: 404,\n headers: { \"Content-Type\": \"application/json\" },\n },\n );\n }\n\n return (agents[agentId] as AbstractAgent).clone() as AbstractAgent;\n}\n\nexport function configureAgentForRequest(params: {\n runtime: CopilotRuntimeLike;\n request: Request;\n agentId: string;\n agent: AbstractAgent;\n /**\n * True when the React provider was given an A2UI catalog\n * (`<CopilotKit a2ui={{ catalog }}>`), forwarded per-run. A catalog alone is\n * enough to enable A2UI and inject the render tool — the developer no longer\n * has to also set `a2ui.injectA2UITool` on the runtime.\n */\n providerA2UIHasCatalog?: boolean;\n /**\n * The transport of the generative UI envelope that the client sent on this\n * run (`forwardedProps.copilotkit.ui`). Not set when the run has no envelope.\n */\n providerGenerativeUITransport?: CopilotKitUIEnvelope[\"metadata\"][\"extensions\"][\"copilotkit_transport\"];\n /** Retain proxy rejection even when no server is available to this agent. */\n isMcpProxyRequest?: boolean;\n}): void {\n const {\n runtime,\n request,\n agentId,\n providerA2UIHasCatalog,\n isMcpProxyRequest,\n } = params;\n const agent = params.agent as MiddlewareCapableAgent;\n\n // A2UI is on when the runtime explicitly enables it, OR when the provider\n // forwarded a catalog — but an explicit `enabled: false` always wins (we\n // provide a quick default, never override a deeper opt-out).\n const a2uiEnabledByCatalog =\n !!providerA2UIHasCatalog && runtime.a2ui?.enabled !== false;\n\n if (isA2UIEnabled(runtime.a2ui) || a2uiEnabledByCatalog) {\n // `enabled` is a CopilotKit-level switch, not an A2UIMiddleware option —\n // drop it (alongside the agent filter) before forwarding to the middleware.\n const {\n agents: targetAgents,\n enabled: _enabled,\n injectA2UITool,\n ...a2uiOptions\n } = runtime.a2ui ?? {};\n const shouldApply = !targetAgents || targetAgents.includes(agentId);\n if (shouldApply && typeof agent.use === \"function\") {\n agent.use(\n new A2UIMiddleware({\n ...a2uiOptions,\n // Default render-tool injection on when a catalog is present and the\n // developer hasn't set it explicitly. `??` means an explicit value\n // (including `false`) is always respected.\n injectA2UITool:\n injectA2UITool ?? (providerA2UIHasCatalog ? true : undefined),\n }),\n );\n }\n }\n\n if (isIntelligenceRuntime(runtime) && typeof agent.use === \"function\") {\n // Ordinary runs need no middleware without selected servers. Proxy requests\n // still need the upstream guard so they cannot fall through to the model.\n const mcpServers = resolveMcpAppsServers(\n runtime.mcpApps?.servers ?? [],\n agentId,\n );\n if (mcpServers.length > 0 || isMcpProxyRequest) {\n agent.use(\n new MCPAppsMiddleware({ mcpServers, discoveryFailureMode: \"throw\" }),\n );\n }\n } else if (runtime.mcpApps?.servers?.length) {\n const mcpServers = resolveMcpAppsServers(runtime.mcpApps.servers, agentId);\n\n if (mcpServers.length > 0 && typeof agent.use === \"function\") {\n agent.use(new MCPAppsMiddleware({ mcpServers }));\n }\n }\n\n if (runtime.openGenerativeUI) {\n const config = runtime.openGenerativeUI;\n const targetAgents = typeof config === \"object\" ? config.agents : undefined;\n const shouldApply = !targetAgents || targetAgents.includes(agentId);\n if (shouldApply && typeof agent.use === \"function\") {\n agent.use(new OpenGenerativeUIMiddleware());\n }\n }\n\n // A \"markdown\" envelope means the model writes ```a2ui fences, so the run\n // gets no render tool, even when the runtime turns generative UI on.\n const generativeUI = runtime.generativeUI;\n const transport = params.providerGenerativeUITransport;\n const isGenerativeUIRun =\n transport === \"tool\" || (transport !== \"markdown\" && !!generativeUI);\n if (\n isGenerativeUIRun &&\n generativeUI !== false &&\n typeof agent.use === \"function\"\n ) {\n const targetAgents =\n typeof generativeUI === \"object\" ? generativeUI.agents : undefined;\n if (!targetAgents || targetAgents.includes(agentId)) {\n agent.use(new GenerativeUIMiddleware());\n }\n }\n\n // Forward eligible inbound headers onto the outgoing agent call under the\n // runtime's resolved forwarding policy (`authorization` / custom `x-*`, with\n // known infra/proxy/platform headers stripped by the default denylist —\n // #5712), but let headers the server explicitly configured on the agent WIN\n // on collision (case-insensitively): a server-set service-to-service token\n // (e.g. an IAM bearer) must never be silently overridden by a\n // browser/edge/platform-injected inbound header. See `mergeForwardableHeaders`\n // for the casing/duplicate-key rationale and `shouldForwardHeader` for breadth.\n agent.headers = mergeForwardableHeaders(\n agent.headers,\n request,\n // `forwardHeadersPolicy` is optional on the published `CopilotRuntimeLike`\n // interface (non-breaking minor release). Concrete runtimes always set it;\n // a policy-less external implementor falls back to the default resolved\n // policy (default-on denylist) so behavior stays identical and never derefs\n // undefined.\n runtime.forwardHeadersPolicy ?? resolveForwardHeadersPolicy(undefined),\n );\n}\n\n/**\n * Shared by the two places a run meets a middleware-less agent: before Memory\n * is resolved (nothing left to resolve) and after (Memory resolved to nothing).\n */\nconst NO_MIDDLEWARE_WARNING =\n \"CopilotKitIntelligence.enableEnterpriseLearning is enabled, but the agent \" +\n \"does not support middleware (no `.use()` method); Intelligence tools were \" +\n \"not attached for this run.\";\n\n/**\n * Attach CopilotKit Intelligence's MCP tools to the agent run when\n * `CopilotKitIntelligence` was constructed with\n * `enableEnterpriseLearning: true`. Uses `@ag-ui/mcp-middleware`, so the\n * tools are available uniformly across agent frameworks (not just\n * `BuiltInAgent`).\n *\n * The middleware sits on a per-request agent clone, so the per-request\n * auth (Bearer apiKey + resolved user-id) is baked into the transport\n * headers at attach time. If user resolution fails, attachment is\n * skipped silently — the intelligence run handler will reject the\n * request with the same error. Note this means `identifyUser` is\n * resolved twice per learning-enabled run (here and in the run handler);\n * the callback is expected to be idempotent and side-effect-free.\n *\n * Intentionally split out from `configureAgentForRequest`: this is only\n * relevant to actual agent runs, not auxiliary flows like thread-name\n * generation (which has no need for MCP tools and shouldn't pay the\n * `listTools` round-trip).\n */\nexport async function attachIntelligenceEnterpriseLearning(params: {\n runtime: CopilotRuntimeLike;\n request: Request;\n agent: AbstractAgent;\n}): Promise<void | Response> {\n const { runtime, request } = params;\n const agent = params.agent as MiddlewareCapableAgent;\n\n if (!isIntelligenceRuntime(runtime)) return;\n\n const learningEnabled =\n runtime.intelligence?.ɵisEnterpriseLearningEnabled?.() === true;\n if (runtime.memory === undefined && !learningEnabled) return;\n\n // Nothing here is resolvable for an agent whose framework can't take\n // middleware and whose runtime configures no Memory — bail before paying for\n // `identifyUser`, so an enterprise-learning-only run keeps warning rather\n // than acquiring a new way to fail.\n if (runtime.memory === undefined && typeof agent.use !== \"function\") {\n logger.warn(NO_MIDDLEWARE_WARNING);\n return;\n }\n\n const userResult = await resolveIntelligenceUser({ runtime, request });\n if (userResult instanceof Response) return userResult;\n const access = await resolveWebMemory(runtime, request, userResult, \"agent\");\n if (access instanceof Response) return access;\n\n const memoryGranted =\n runtime.memory !== undefined && grantAllowsMemory(access.grant);\n\n // A policy that grants no scope means this run gets no Memory — it does NOT\n // mean the run is refused. Attach nothing and let the conversation proceed,\n // exactly as a Channel does when its grant asks for nothing\n // (`hasMemoryAccess` in @copilotkit/channels-core). Returning a 403 here\n // instead fails the whole run, so switching Memory off for one tenant would\n // leave that tenant with no assistant, and the only signal is a run error the\n // chat surface has no reason to render.\n //\n // Enterprise learning rides the SAME MCP server, so \"no Memory\" must not cost\n // an operator the learning tools too. When it is on, attach anyway and let\n // Intelligence filter: it registers one Memory tool per granted scope and\n // none at all for an all-none grant, leaving the learning tools untouched.\n if (!memoryGranted && !learningEnabled) return;\n\n // Whatever is left to attach needs middleware. Failing the run is right only\n // when Memory was actually granted and cannot be delivered; a run that merely\n // wanted learning tools warns and proceeds, as it always has.\n if (typeof agent.use !== \"function\") {\n if (memoryGranted) {\n return errorResponse(\n \"Memory is configured, but this agent does not support middleware\",\n 500,\n );\n }\n logger.warn(NO_MIDDLEWARE_WARNING);\n return;\n }\n\n agent.use(\n new MCPMiddleware([\n {\n type: \"http\",\n url: `${runtime.intelligence.ɵgetApiUrl()}/mcp`,\n serverId: \"intelligence\",\n headers: {\n Authorization: `Bearer ${runtime.intelligence.ɵgetApiKey()}`,\n [INTELLIGENCE_USER_ID_HEADER]: userResult.id,\n ...(runtime.memory\n ? {\n [INTELLIGENCE_MEMORY_GRANT_HEADER]: JSON.stringify(\n access.grant,\n ),\n }\n : {}),\n },\n },\n ]),\n );\n}\n\n// Intentional local exception: HTTP request parsing runs before AG-UI's event\n// compatibility boundary. Mirror its historically accepted optional-null rules\n// and its legacy binary-part upgrade here, without depending on a new public\n// AG-UI helper (AG-UI does not export one). Keep these aligned\n// with client/src/middleware/compatibility-boundary.ts and AG-UI's migration guide.\n// Required nulls and nulls within application data must remain untouched.\nfunction warnCompatibility(what: string, replacement: string) {\n if (\n typeof process !== \"undefined\" &&\n typeof process.env !== \"undefined\" &&\n process.env.SUPPRESS_TRANSFORMATION_WARNINGS\n )\n return;\n console.warn(\n `[ag-ui][compat] Converting deprecated ${what} to ${replacement}. The old shape leaves the protocol after its shim window — see the repo-root DEPRECATIONS.md. Set SUPPRESS_TRANSFORMATION_WARNINGS=true to silence.`,\n );\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction omitLegacyNull(\n value: unknown,\n field: string,\n context: string,\n): unknown {\n if (!isRecord(value) || value[field] !== null) return value;\n warnCompatibility(`${context}.${field}: null`, \"an absent field\");\n const { [field]: _null, ...rest } = value;\n return rest;\n}\n\nfunction mapProtocolArray(\n value: unknown,\n field: string,\n normalize: (entry: unknown) => unknown,\n): unknown {\n if (!isRecord(value) || !Array.isArray(value[field])) return value;\n const original = value[field];\n const entries = original.map(normalize);\n return entries.some((entry, index) => entry !== original[index])\n ? { ...value, [field]: entries }\n : value;\n}\n\nfunction mediaTypeFor(\n mimeType: string,\n): \"image\" | \"audio\" | \"video\" | \"document\" {\n if (mimeType.startsWith(\"image/\")) return \"image\";\n if (mimeType.startsWith(\"audio/\")) return \"audio\";\n if (mimeType.startsWith(\"video/\")) return \"video\";\n return \"document\";\n}\n\nfunction sameSource(part: unknown, converted: Record<string, unknown>) {\n if (!isRecord(part) || part.type !== converted.type) return false;\n const a = part.source;\n const b = converted.source as Record<string, unknown>;\n return (\n isRecord(a) &&\n a.type === b.type &&\n a.value === b.value &&\n a.mimeType === b.mimeType\n );\n}\n\n/**\n * The 0.x `{ type: \"binary\" }` part, which 1.0 retired and main accepted.\n * Mirrors AG-UI's outgoing upgrade (client/src/middleware/legacy-content.ts):\n * data or url becomes the media part its mime type names, and a binary part\n * that only mirrors a modern part already in the message is dropped. A part\n * with only an `id` has no 1.0 form; it is dropped with a warning instead of\n * failing the whole request, which is what BuiltInAgent already did with it.\n */\nfunction upgradeLegacyBinaryParts(content: unknown[]): unknown[] {\n return content.flatMap((part) => {\n if (\n !isRecord(part) ||\n part.type !== \"binary\" ||\n typeof part.mimeType !== \"string\"\n )\n return [part];\n const kind =\n typeof part.data === \"string\"\n ? \"data\"\n : typeof part.url === \"string\"\n ? \"url\"\n : null;\n if (kind === null) {\n console.warn(\n \"[CopilotKit] Dropping a legacy binary content part that has no data or url; AG-UI 1.0 has no equivalent for it.\",\n );\n return [];\n }\n warnCompatibility(\"binary input content\", \"the modern media content part\");\n const converted: Record<string, unknown> = {\n type: mediaTypeFor(part.mimeType),\n source: {\n type: kind,\n value: kind === \"data\" ? part.data : part.url,\n mimeType: part.mimeType,\n },\n ...(typeof part.filename === \"string\"\n ? { metadata: { filename: part.filename } }\n : {}),\n };\n return content.some((other) => sameSource(other, converted))\n ? []\n : [converted];\n });\n}\n\nfunction normalizeLegacyMessageContent(message: unknown): unknown {\n const upgraded =\n isRecord(message) &&\n Array.isArray(message.content) &&\n message.content.some((part) => isRecord(part) && part.type === \"binary\")\n ? {\n ...message,\n content: upgradeLegacyBinaryParts(message.content),\n }\n : message;\n return mapProtocolArray(upgraded, \"content\", (part) => {\n if (!isRecord(part)) return part;\n switch (part.type) {\n case \"image\":\n case \"audio\":\n case \"video\":\n case \"document\":\n return omitLegacyNull(part, \"metadata\", `${part.type} input content`);\n default:\n return part;\n }\n });\n}\n\nfunction normalizeLegacyRunAgentInput(input: unknown): unknown {\n let normalized = omitLegacyNull(input, \"forwardedProps\", \"RunAgentInput\");\n normalized = mapProtocolArray(normalized, \"tools\", (tool) =>\n omitLegacyNull(tool, \"parameters\", \"Tool\"),\n );\n normalized = mapProtocolArray(normalized, \"resume\", (entry) =>\n omitLegacyNull(entry, \"payload\", \"ResumeEntry\"),\n );\n return mapProtocolArray(\n normalized,\n \"messages\",\n normalizeLegacyMessageContent,\n );\n}\n\nfunction parseRunAgentInput(value: unknown): RunAgentInput {\n // With strictNullChecks disabled, Zod infers some required nested fields\n // (such as image.source) as optional. The schema still validates them.\n return RunAgentInputSchema.parse(\n normalizeLegacyRunAgentInput(value),\n ) as RunAgentInput;\n}\n\nexport async function parseRunRequest(\n request: Request,\n): Promise<RunAgentInput | Response> {\n try {\n const requestBody = await request.json();\n return parseRunAgentInput(requestBody);\n } catch (error) {\n logger.error(\"Invalid run request body:\", error);\n return new Response(\n JSON.stringify({\n error: \"Invalid request body\",\n details: error instanceof Error ? error.message : String(error),\n }),\n {\n status: 400,\n headers: { \"Content-Type\": \"application/json\" },\n },\n );\n }\n}\n\nexport async function parseConnectRequest(request: Request): Promise<\n | Response\n | {\n input: RunAgentInput;\n lastSeenEventId: string | null;\n }\n> {\n try {\n const requestBody = await request.json();\n const input = parseRunAgentInput(requestBody);\n let lastSeenEventId: string | null = null;\n\n if (\n \"lastSeenEventId\" in (requestBody as Record<string, unknown>) &&\n (typeof (requestBody as Record<string, unknown>).lastSeenEventId ===\n \"string\" ||\n (requestBody as Record<string, unknown>).lastSeenEventId === null)\n ) {\n lastSeenEventId =\n (requestBody as ConnectRequestBody).lastSeenEventId ?? null;\n }\n\n return { input, lastSeenEventId };\n } catch (error) {\n logger.error(\"Invalid connect request body:\", error);\n return new Response(\n JSON.stringify({\n error: \"Invalid request body\",\n details: error instanceof Error ? error.message : String(error),\n }),\n {\n status: 400,\n headers: { \"Content-Type\": \"application/json\" },\n },\n );\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"agent-utils.cjs","names":["resolveAgents","isA2UIEnabled","A2UIMiddleware","isIntelligenceRuntime","resolveMcpAppsServers","MCPAppsMiddleware","OpenGenerativeUIMiddleware","GenerativeUIMiddleware","mergeForwardableHeaders","resolveForwardHeadersPolicy","resolveIntelligenceUser","resolveWebMemory","grantAllowsMemory","errorResponse","MCPMiddleware","INTELLIGENCE_USER_ID_HEADER","INTELLIGENCE_MEMORY_GRANT_HEADER","RunAgentInputSchema"],"sources":["../../../../src/runtime/handlers/shared/agent-utils.ts"],"sourcesContent":["import type { AbstractAgent, RunAgentInput } from \"@ag-ui/client\";\nimport { RunAgentInputSchema } from \"@ag-ui/core/schemas\";\nimport type { CopilotKitUIEnvelope } from \"@copilotkit/shared\";\nimport {\n A2UIMiddleware,\n OpenGenerativeUIMiddleware,\n} from \"@copilotkit/shared/event-transforms\";\nimport { MCPAppsMiddleware } from \"@ag-ui/mcp-apps-middleware\";\nimport { MCPMiddleware } from \"@ag-ui/mcp-middleware\";\nimport { GenerativeUIMiddleware } from \"../../generative-ui\";\nimport type { CopilotRuntimeLike } from \"../../core/runtime\";\nimport {\n isA2UIEnabled,\n isIntelligenceRuntime,\n resolveAgents,\n} from \"../../core/runtime\";\nimport {\n INTELLIGENCE_MEMORY_GRANT_HEADER,\n INTELLIGENCE_USER_ID_HEADER,\n} from \"../../intelligence-platform/client\";\nimport {\n mergeForwardableHeaders,\n resolveForwardHeadersPolicy,\n} from \"../header-utils\";\nimport { resolveMcpAppsServers } from \"./mcp-apps-servers\";\nimport { resolveIntelligenceUser } from \"./resolve-intelligence-user\";\nimport { grantAllowsMemory, resolveWebMemory } from \"./memory-policy\";\nimport { errorResponse } from \"./json-response\";\nimport { logger, processEnv } from \"@copilotkit/shared\";\n\ntype MiddlewareCapableAgent = AbstractAgent & {\n use?: (middleware: unknown) => void;\n headers?: Record<string, string>;\n};\n\nexport interface RunAgentParameters {\n request: Request;\n runtime: CopilotRuntimeLike;\n agentId: string;\n}\n\nexport interface ConnectRequestBody extends RunAgentInput {\n lastSeenEventId?: string | null;\n}\n\n/**\n * Resolve `agentId` against the runtime's agents and return a per-request\n * clone of the matching agent.\n *\n * Dual return contract — both callers (`handle-run.ts`, `handle-connect.ts`)\n * depend on it:\n * - Returns a cloned `AbstractAgent` when the agent exists.\n * - Returns a 404 `Response` (`{ error: \"Agent not found\", ... }`) when the\n * agent is unknown. Callers MUST `instanceof Response`-check the result and\n * return it directly; this doubles as the connect/run path's agent-existence\n * guard, so skipping the check would let unknown agent ids slip through.\n *\n * The clone is what subsequent per-request mutation (middleware attach,\n * `agent.headers` merge) operates on, leaving the shared agent registration\n * untouched.\n */\nexport async function cloneAgentForRequest(\n runtime: CopilotRuntimeLike,\n agentId: string,\n request?: Request,\n): Promise<AbstractAgent | Response> {\n const agents = await resolveAgents(runtime.agents, request);\n\n if (!agents[agentId]) {\n return new Response(\n JSON.stringify({\n error: \"Agent not found\",\n message: `Agent '${agentId}' does not exist`,\n }),\n {\n status: 404,\n headers: { \"Content-Type\": \"application/json\" },\n },\n );\n }\n\n return (agents[agentId] as AbstractAgent).clone() as AbstractAgent;\n}\n\nexport function configureAgentForRequest(params: {\n runtime: CopilotRuntimeLike;\n request: Request;\n agentId: string;\n agent: AbstractAgent;\n /**\n * True when the React provider was given an A2UI catalog\n * (`<CopilotKit a2ui={{ catalog }}>`), forwarded per-run. A catalog alone is\n * enough to enable A2UI and inject the render tool — the developer no longer\n * has to also set `a2ui.injectA2UITool` on the runtime.\n */\n providerA2UIHasCatalog?: boolean;\n /**\n * The transport of the generative UI envelope that the client sent on this\n * run (`forwardedProps.copilotkit.ui`). Not set when the run has no envelope.\n */\n providerGenerativeUITransport?: CopilotKitUIEnvelope[\"metadata\"][\"extensions\"][\"copilotkit_transport\"];\n /** Retain proxy rejection even when no server is available to this agent. */\n isMcpProxyRequest?: boolean;\n}): void {\n const {\n runtime,\n request,\n agentId,\n providerA2UIHasCatalog,\n isMcpProxyRequest,\n } = params;\n const agent = params.agent as MiddlewareCapableAgent;\n\n // A2UI is on when the runtime explicitly enables it, OR when the provider\n // forwarded a catalog — but an explicit `enabled: false` always wins (we\n // provide a quick default, never override a deeper opt-out).\n const a2uiEnabledByCatalog =\n !!providerA2UIHasCatalog && runtime.a2ui?.enabled !== false;\n\n if (isA2UIEnabled(runtime.a2ui) || a2uiEnabledByCatalog) {\n // `enabled` is a CopilotKit-level switch, not an A2UIMiddleware option —\n // drop it (alongside the agent filter) before forwarding to the middleware.\n const {\n agents: targetAgents,\n enabled: _enabled,\n injectA2UITool,\n ...a2uiOptions\n } = runtime.a2ui ?? {};\n const shouldApply = !targetAgents || targetAgents.includes(agentId);\n if (shouldApply && typeof agent.use === \"function\") {\n agent.use(\n new A2UIMiddleware({\n ...a2uiOptions,\n // Default render-tool injection on when a catalog is present and the\n // developer hasn't set it explicitly. `??` means an explicit value\n // (including `false`) is always respected.\n injectA2UITool:\n injectA2UITool ?? (providerA2UIHasCatalog ? true : undefined),\n }),\n );\n }\n }\n\n if (isIntelligenceRuntime(runtime) && typeof agent.use === \"function\") {\n // Ordinary runs need no middleware without selected servers. Proxy requests\n // still need the upstream guard so they cannot fall through to the model.\n const mcpServers = resolveMcpAppsServers(\n runtime.mcpApps?.servers ?? [],\n agentId,\n );\n if (mcpServers.length > 0 || isMcpProxyRequest) {\n agent.use(\n new MCPAppsMiddleware({ mcpServers, discoveryFailureMode: \"throw\" }),\n );\n }\n } else if (runtime.mcpApps?.servers?.length) {\n const mcpServers = resolveMcpAppsServers(runtime.mcpApps.servers, agentId);\n\n if (mcpServers.length > 0 && typeof agent.use === \"function\") {\n agent.use(new MCPAppsMiddleware({ mcpServers }));\n }\n }\n\n if (runtime.openGenerativeUI) {\n const config = runtime.openGenerativeUI;\n const targetAgents = typeof config === \"object\" ? config.agents : undefined;\n const shouldApply = !targetAgents || targetAgents.includes(agentId);\n if (shouldApply && typeof agent.use === \"function\") {\n agent.use(new OpenGenerativeUIMiddleware());\n }\n }\n\n // A \"markdown\" envelope means the model writes ```a2ui fences, so the run\n // gets no render tool, even when the runtime turns generative UI on.\n const generativeUI = runtime.generativeUI;\n const transport = params.providerGenerativeUITransport;\n const isGenerativeUIRun =\n transport === \"tool\" || (transport !== \"markdown\" && !!generativeUI);\n if (\n isGenerativeUIRun &&\n generativeUI !== false &&\n typeof agent.use === \"function\"\n ) {\n const targetAgents =\n typeof generativeUI === \"object\" ? generativeUI.agents : undefined;\n if (!targetAgents || targetAgents.includes(agentId)) {\n agent.use(new GenerativeUIMiddleware());\n }\n }\n\n // Forward eligible inbound headers onto the outgoing agent call under the\n // runtime's resolved forwarding policy (`authorization` / custom `x-*`, with\n // known infra/proxy/platform headers stripped by the default denylist —\n // #5712), but let headers the server explicitly configured on the agent WIN\n // on collision (case-insensitively): a server-set service-to-service token\n // (e.g. an IAM bearer) must never be silently overridden by a\n // browser/edge/platform-injected inbound header. See `mergeForwardableHeaders`\n // for the casing/duplicate-key rationale and `shouldForwardHeader` for breadth.\n agent.headers = mergeForwardableHeaders(\n agent.headers,\n request,\n // `forwardHeadersPolicy` is optional on the published `CopilotRuntimeLike`\n // interface (non-breaking minor release). Concrete runtimes always set it;\n // a policy-less external implementor falls back to the default resolved\n // policy (default-on denylist) so behavior stays identical and never derefs\n // undefined.\n runtime.forwardHeadersPolicy ?? resolveForwardHeadersPolicy(undefined),\n );\n}\n\n/**\n * Shared by the two places a run meets a middleware-less agent: before Memory\n * is resolved (nothing left to resolve) and after (Memory resolved to nothing).\n */\nconst NO_MIDDLEWARE_WARNING =\n \"CopilotKitIntelligence.enableEnterpriseLearning is enabled, but the agent \" +\n \"does not support middleware (no `.use()` method); Intelligence tools were \" +\n \"not attached for this run.\";\n\n/**\n * Attach CopilotKit Intelligence's MCP tools to the agent run when\n * `CopilotKitIntelligence` was constructed with\n * `enableEnterpriseLearning: true`. Uses `@ag-ui/mcp-middleware`, so the\n * tools are available uniformly across agent frameworks (not just\n * `BuiltInAgent`).\n *\n * The middleware sits on a per-request agent clone, so the per-request\n * auth (Bearer apiKey + resolved user-id) is baked into the transport\n * headers at attach time. If user resolution fails, attachment is\n * skipped silently — the intelligence run handler will reject the\n * request with the same error. Note this means `identifyUser` is\n * resolved twice per learning-enabled run (here and in the run handler);\n * the callback is expected to be idempotent and side-effect-free.\n *\n * Intentionally split out from `configureAgentForRequest`: this is only\n * relevant to actual agent runs, not auxiliary flows like thread-name\n * generation (which has no need for MCP tools and shouldn't pay the\n * `listTools` round-trip).\n */\nexport async function attachIntelligenceEnterpriseLearning(params: {\n runtime: CopilotRuntimeLike;\n request: Request;\n agent: AbstractAgent;\n}): Promise<void | Response> {\n const { runtime, request } = params;\n const agent = params.agent as MiddlewareCapableAgent;\n\n if (!isIntelligenceRuntime(runtime)) return;\n\n const learningEnabled =\n runtime.intelligence?.ɵisEnterpriseLearningEnabled?.() === true;\n if (runtime.memory === undefined && !learningEnabled) return;\n\n // Nothing here is resolvable for an agent whose framework can't take\n // middleware and whose runtime configures no Memory — bail before paying for\n // `identifyUser`, so an enterprise-learning-only run keeps warning rather\n // than acquiring a new way to fail.\n if (runtime.memory === undefined && typeof agent.use !== \"function\") {\n logger.warn(NO_MIDDLEWARE_WARNING);\n return;\n }\n\n const userResult = await resolveIntelligenceUser({ runtime, request });\n if (userResult instanceof Response) return userResult;\n const access = await resolveWebMemory(runtime, request, userResult, \"agent\");\n if (access instanceof Response) return access;\n\n const memoryGranted =\n runtime.memory !== undefined && grantAllowsMemory(access.grant);\n\n // A policy that grants no scope means this run gets no Memory — it does NOT\n // mean the run is refused. Attach nothing and let the conversation proceed,\n // exactly as a Channel does when its grant asks for nothing\n // (`hasMemoryAccess` in @copilotkit/channels-core). Returning a 403 here\n // instead fails the whole run, so switching Memory off for one tenant would\n // leave that tenant with no assistant, and the only signal is a run error the\n // chat surface has no reason to render.\n //\n // Enterprise learning rides the SAME MCP server, so \"no Memory\" must not cost\n // an operator the learning tools too. When it is on, attach anyway and let\n // Intelligence filter: it registers one Memory tool per granted scope and\n // none at all for an all-none grant, leaving the learning tools untouched.\n if (!memoryGranted && !learningEnabled) return;\n\n // Whatever is left to attach needs middleware. Failing the run is right only\n // when Memory was actually granted and cannot be delivered; a run that merely\n // wanted learning tools warns and proceeds, as it always has.\n if (typeof agent.use !== \"function\") {\n if (memoryGranted) {\n return errorResponse(\n \"Memory is configured, but this agent does not support middleware\",\n 500,\n );\n }\n logger.warn(NO_MIDDLEWARE_WARNING);\n return;\n }\n\n agent.use(\n new MCPMiddleware([\n {\n type: \"http\",\n url: `${runtime.intelligence.ɵgetApiUrl()}/mcp`,\n serverId: \"intelligence\",\n headers: {\n Authorization: `Bearer ${runtime.intelligence.ɵgetApiKey()}`,\n [INTELLIGENCE_USER_ID_HEADER]: userResult.id,\n ...(runtime.memory\n ? {\n [INTELLIGENCE_MEMORY_GRANT_HEADER]: JSON.stringify(\n access.grant,\n ),\n }\n : {}),\n },\n },\n ]),\n );\n}\n\n// Intentional local exception: HTTP request parsing runs before AG-UI's event\n// compatibility boundary. Mirror its historically accepted optional-null rules\n// and its legacy binary-part upgrade here, without depending on a new public\n// AG-UI helper (AG-UI does not export one). Keep these aligned\n// with client/src/middleware/compatibility-boundary.ts and AG-UI's migration guide.\n// Required nulls and nulls within application data must remain untouched.\nfunction warnCompatibility(what: string, replacement: string) {\n if (\n typeof process !== \"undefined\" &&\n typeof processEnv() !== \"undefined\" &&\n processEnv().SUPPRESS_TRANSFORMATION_WARNINGS\n )\n return;\n console.warn(\n `[ag-ui][compat] Converting deprecated ${what} to ${replacement}. The old shape leaves the protocol after its shim window — see the repo-root DEPRECATIONS.md. Set SUPPRESS_TRANSFORMATION_WARNINGS=true to silence.`,\n );\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction omitLegacyNull(\n value: unknown,\n field: string,\n context: string,\n): unknown {\n if (!isRecord(value) || value[field] !== null) return value;\n warnCompatibility(`${context}.${field}: null`, \"an absent field\");\n const { [field]: _null, ...rest } = value;\n return rest;\n}\n\nfunction mapProtocolArray(\n value: unknown,\n field: string,\n normalize: (entry: unknown) => unknown,\n): unknown {\n if (!isRecord(value) || !Array.isArray(value[field])) return value;\n const original = value[field];\n const entries = original.map(normalize);\n return entries.some((entry, index) => entry !== original[index])\n ? { ...value, [field]: entries }\n : value;\n}\n\nfunction mediaTypeFor(\n mimeType: string,\n): \"image\" | \"audio\" | \"video\" | \"document\" {\n if (mimeType.startsWith(\"image/\")) return \"image\";\n if (mimeType.startsWith(\"audio/\")) return \"audio\";\n if (mimeType.startsWith(\"video/\")) return \"video\";\n return \"document\";\n}\n\nfunction sameSource(part: unknown, converted: Record<string, unknown>) {\n if (!isRecord(part) || part.type !== converted.type) return false;\n const a = part.source;\n const b = converted.source as Record<string, unknown>;\n return (\n isRecord(a) &&\n a.type === b.type &&\n a.value === b.value &&\n a.mimeType === b.mimeType\n );\n}\n\n/**\n * The 0.x `{ type: \"binary\" }` part, which 1.0 retired and main accepted.\n * Mirrors AG-UI's outgoing upgrade (client/src/middleware/legacy-content.ts):\n * data or url becomes the media part its mime type names, and a binary part\n * that only mirrors a modern part already in the message is dropped. A part\n * with only an `id` has no 1.0 form; it is dropped with a warning instead of\n * failing the whole request, which is what BuiltInAgent already did with it.\n */\nfunction upgradeLegacyBinaryParts(content: unknown[]): unknown[] {\n return content.flatMap((part) => {\n if (\n !isRecord(part) ||\n part.type !== \"binary\" ||\n typeof part.mimeType !== \"string\"\n )\n return [part];\n const kind =\n typeof part.data === \"string\"\n ? \"data\"\n : typeof part.url === \"string\"\n ? \"url\"\n : null;\n if (kind === null) {\n console.warn(\n \"[CopilotKit] Dropping a legacy binary content part that has no data or url; AG-UI 1.0 has no equivalent for it.\",\n );\n return [];\n }\n warnCompatibility(\"binary input content\", \"the modern media content part\");\n const converted: Record<string, unknown> = {\n type: mediaTypeFor(part.mimeType),\n source: {\n type: kind,\n value: kind === \"data\" ? part.data : part.url,\n mimeType: part.mimeType,\n },\n ...(typeof part.filename === \"string\"\n ? { metadata: { filename: part.filename } }\n : {}),\n };\n return content.some((other) => sameSource(other, converted))\n ? []\n : [converted];\n });\n}\n\nfunction normalizeLegacyMessageContent(message: unknown): unknown {\n const upgraded =\n isRecord(message) &&\n Array.isArray(message.content) &&\n message.content.some((part) => isRecord(part) && part.type === \"binary\")\n ? {\n ...message,\n content: upgradeLegacyBinaryParts(message.content),\n }\n : message;\n return mapProtocolArray(upgraded, \"content\", (part) => {\n if (!isRecord(part)) return part;\n switch (part.type) {\n case \"image\":\n case \"audio\":\n case \"video\":\n case \"document\":\n return omitLegacyNull(part, \"metadata\", `${part.type} input content`);\n default:\n return part;\n }\n });\n}\n\nfunction normalizeLegacyRunAgentInput(input: unknown): unknown {\n let normalized = omitLegacyNull(input, \"forwardedProps\", \"RunAgentInput\");\n normalized = mapProtocolArray(normalized, \"tools\", (tool) =>\n omitLegacyNull(tool, \"parameters\", \"Tool\"),\n );\n normalized = mapProtocolArray(normalized, \"resume\", (entry) =>\n omitLegacyNull(entry, \"payload\", \"ResumeEntry\"),\n );\n return mapProtocolArray(\n normalized,\n \"messages\",\n normalizeLegacyMessageContent,\n );\n}\n\nfunction parseRunAgentInput(value: unknown): RunAgentInput {\n // With strictNullChecks disabled, Zod infers some required nested fields\n // (such as image.source) as optional. The schema still validates them.\n return RunAgentInputSchema.parse(\n normalizeLegacyRunAgentInput(value),\n ) as RunAgentInput;\n}\n\nexport async function parseRunRequest(\n request: Request,\n): Promise<RunAgentInput | Response> {\n try {\n const requestBody = await request.json();\n return parseRunAgentInput(requestBody);\n } catch (error) {\n logger.error(\"Invalid run request body:\", error);\n return new Response(\n JSON.stringify({\n error: \"Invalid request body\",\n details: error instanceof Error ? error.message : String(error),\n }),\n {\n status: 400,\n headers: { \"Content-Type\": \"application/json\" },\n },\n );\n }\n}\n\nexport async function parseConnectRequest(request: Request): Promise<\n | Response\n | {\n input: RunAgentInput;\n lastSeenEventId: string | null;\n }\n> {\n try {\n const requestBody = await request.json();\n const input = parseRunAgentInput(requestBody);\n let lastSeenEventId: string | null = null;\n\n if (\n \"lastSeenEventId\" in (requestBody as Record<string, unknown>) &&\n (typeof (requestBody as Record<string, unknown>).lastSeenEventId ===\n \"string\" ||\n (requestBody as Record<string, unknown>).lastSeenEventId === null)\n ) {\n lastSeenEventId =\n (requestBody as ConnectRequestBody).lastSeenEventId ?? null;\n }\n\n return { input, lastSeenEventId };\n } catch (error) {\n logger.error(\"Invalid connect request body:\", error);\n return new Response(\n JSON.stringify({\n error: \"Invalid request body\",\n details: error instanceof Error ? error.message : String(error),\n }),\n {\n status: 400,\n headers: { \"Content-Type\": \"application/json\" },\n },\n );\n }\n}\n"],"mappings":"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"}
|
|
@@ -6,7 +6,7 @@ import { isA2UIEnabled, isIntelligenceRuntime, resolveAgents } from "../../core/
|
|
|
6
6
|
import { GenerativeUIMiddleware } from "../../generative-ui/generative-ui-middleware.mjs";
|
|
7
7
|
import { resolveMcpAppsServers } from "./mcp-apps-servers.mjs";
|
|
8
8
|
import { grantAllowsMemory, resolveWebMemory } from "./memory-policy.mjs";
|
|
9
|
-
import { logger } from "@copilotkit/shared";
|
|
9
|
+
import { logger, processEnv } from "@copilotkit/shared";
|
|
10
10
|
import { MCPMiddleware } from "@ag-ui/mcp-middleware";
|
|
11
11
|
import { RunAgentInputSchema } from "@ag-ui/core/schemas";
|
|
12
12
|
import { A2UIMiddleware, OpenGenerativeUIMiddleware } from "@copilotkit/shared/event-transforms";
|
|
@@ -135,7 +135,7 @@ async function attachIntelligenceEnterpriseLearning(params) {
|
|
|
135
135
|
}]));
|
|
136
136
|
}
|
|
137
137
|
function warnCompatibility(what, replacement) {
|
|
138
|
-
if (typeof process !== "undefined" && typeof
|
|
138
|
+
if (typeof process !== "undefined" && typeof processEnv() !== "undefined" && processEnv().SUPPRESS_TRANSFORMATION_WARNINGS) return;
|
|
139
139
|
console.warn(`[ag-ui][compat] Converting deprecated ${what} to ${replacement}. The old shape leaves the protocol after its shim window — see the repo-root DEPRECATIONS.md. Set SUPPRESS_TRANSFORMATION_WARNINGS=true to silence.`);
|
|
140
140
|
}
|
|
141
141
|
function isRecord(value) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-utils.mjs","names":[],"sources":["../../../../src/runtime/handlers/shared/agent-utils.ts"],"sourcesContent":["import type { AbstractAgent, RunAgentInput } from \"@ag-ui/client\";\nimport { RunAgentInputSchema } from \"@ag-ui/core/schemas\";\nimport type { CopilotKitUIEnvelope } from \"@copilotkit/shared\";\nimport {\n A2UIMiddleware,\n OpenGenerativeUIMiddleware,\n} from \"@copilotkit/shared/event-transforms\";\nimport { MCPAppsMiddleware } from \"@ag-ui/mcp-apps-middleware\";\nimport { MCPMiddleware } from \"@ag-ui/mcp-middleware\";\nimport { GenerativeUIMiddleware } from \"../../generative-ui\";\nimport type { CopilotRuntimeLike } from \"../../core/runtime\";\nimport {\n isA2UIEnabled,\n isIntelligenceRuntime,\n resolveAgents,\n} from \"../../core/runtime\";\nimport {\n INTELLIGENCE_MEMORY_GRANT_HEADER,\n INTELLIGENCE_USER_ID_HEADER,\n} from \"../../intelligence-platform/client\";\nimport {\n mergeForwardableHeaders,\n resolveForwardHeadersPolicy,\n} from \"../header-utils\";\nimport { resolveMcpAppsServers } from \"./mcp-apps-servers\";\nimport { resolveIntelligenceUser } from \"./resolve-intelligence-user\";\nimport { grantAllowsMemory, resolveWebMemory } from \"./memory-policy\";\nimport { errorResponse } from \"./json-response\";\nimport { logger } from \"@copilotkit/shared\";\n\ntype MiddlewareCapableAgent = AbstractAgent & {\n use?: (middleware: unknown) => void;\n headers?: Record<string, string>;\n};\n\nexport interface RunAgentParameters {\n request: Request;\n runtime: CopilotRuntimeLike;\n agentId: string;\n}\n\nexport interface ConnectRequestBody extends RunAgentInput {\n lastSeenEventId?: string | null;\n}\n\n/**\n * Resolve `agentId` against the runtime's agents and return a per-request\n * clone of the matching agent.\n *\n * Dual return contract — both callers (`handle-run.ts`, `handle-connect.ts`)\n * depend on it:\n * - Returns a cloned `AbstractAgent` when the agent exists.\n * - Returns a 404 `Response` (`{ error: \"Agent not found\", ... }`) when the\n * agent is unknown. Callers MUST `instanceof Response`-check the result and\n * return it directly; this doubles as the connect/run path's agent-existence\n * guard, so skipping the check would let unknown agent ids slip through.\n *\n * The clone is what subsequent per-request mutation (middleware attach,\n * `agent.headers` merge) operates on, leaving the shared agent registration\n * untouched.\n */\nexport async function cloneAgentForRequest(\n runtime: CopilotRuntimeLike,\n agentId: string,\n request?: Request,\n): Promise<AbstractAgent | Response> {\n const agents = await resolveAgents(runtime.agents, request);\n\n if (!agents[agentId]) {\n return new Response(\n JSON.stringify({\n error: \"Agent not found\",\n message: `Agent '${agentId}' does not exist`,\n }),\n {\n status: 404,\n headers: { \"Content-Type\": \"application/json\" },\n },\n );\n }\n\n return (agents[agentId] as AbstractAgent).clone() as AbstractAgent;\n}\n\nexport function configureAgentForRequest(params: {\n runtime: CopilotRuntimeLike;\n request: Request;\n agentId: string;\n agent: AbstractAgent;\n /**\n * True when the React provider was given an A2UI catalog\n * (`<CopilotKit a2ui={{ catalog }}>`), forwarded per-run. A catalog alone is\n * enough to enable A2UI and inject the render tool — the developer no longer\n * has to also set `a2ui.injectA2UITool` on the runtime.\n */\n providerA2UIHasCatalog?: boolean;\n /**\n * The transport of the generative UI envelope that the client sent on this\n * run (`forwardedProps.copilotkit.ui`). Not set when the run has no envelope.\n */\n providerGenerativeUITransport?: CopilotKitUIEnvelope[\"metadata\"][\"extensions\"][\"copilotkit_transport\"];\n /** Retain proxy rejection even when no server is available to this agent. */\n isMcpProxyRequest?: boolean;\n}): void {\n const {\n runtime,\n request,\n agentId,\n providerA2UIHasCatalog,\n isMcpProxyRequest,\n } = params;\n const agent = params.agent as MiddlewareCapableAgent;\n\n // A2UI is on when the runtime explicitly enables it, OR when the provider\n // forwarded a catalog — but an explicit `enabled: false` always wins (we\n // provide a quick default, never override a deeper opt-out).\n const a2uiEnabledByCatalog =\n !!providerA2UIHasCatalog && runtime.a2ui?.enabled !== false;\n\n if (isA2UIEnabled(runtime.a2ui) || a2uiEnabledByCatalog) {\n // `enabled` is a CopilotKit-level switch, not an A2UIMiddleware option —\n // drop it (alongside the agent filter) before forwarding to the middleware.\n const {\n agents: targetAgents,\n enabled: _enabled,\n injectA2UITool,\n ...a2uiOptions\n } = runtime.a2ui ?? {};\n const shouldApply = !targetAgents || targetAgents.includes(agentId);\n if (shouldApply && typeof agent.use === \"function\") {\n agent.use(\n new A2UIMiddleware({\n ...a2uiOptions,\n // Default render-tool injection on when a catalog is present and the\n // developer hasn't set it explicitly. `??` means an explicit value\n // (including `false`) is always respected.\n injectA2UITool:\n injectA2UITool ?? (providerA2UIHasCatalog ? true : undefined),\n }),\n );\n }\n }\n\n if (isIntelligenceRuntime(runtime) && typeof agent.use === \"function\") {\n // Ordinary runs need no middleware without selected servers. Proxy requests\n // still need the upstream guard so they cannot fall through to the model.\n const mcpServers = resolveMcpAppsServers(\n runtime.mcpApps?.servers ?? [],\n agentId,\n );\n if (mcpServers.length > 0 || isMcpProxyRequest) {\n agent.use(\n new MCPAppsMiddleware({ mcpServers, discoveryFailureMode: \"throw\" }),\n );\n }\n } else if (runtime.mcpApps?.servers?.length) {\n const mcpServers = resolveMcpAppsServers(runtime.mcpApps.servers, agentId);\n\n if (mcpServers.length > 0 && typeof agent.use === \"function\") {\n agent.use(new MCPAppsMiddleware({ mcpServers }));\n }\n }\n\n if (runtime.openGenerativeUI) {\n const config = runtime.openGenerativeUI;\n const targetAgents = typeof config === \"object\" ? config.agents : undefined;\n const shouldApply = !targetAgents || targetAgents.includes(agentId);\n if (shouldApply && typeof agent.use === \"function\") {\n agent.use(new OpenGenerativeUIMiddleware());\n }\n }\n\n // A \"markdown\" envelope means the model writes ```a2ui fences, so the run\n // gets no render tool, even when the runtime turns generative UI on.\n const generativeUI = runtime.generativeUI;\n const transport = params.providerGenerativeUITransport;\n const isGenerativeUIRun =\n transport === \"tool\" || (transport !== \"markdown\" && !!generativeUI);\n if (\n isGenerativeUIRun &&\n generativeUI !== false &&\n typeof agent.use === \"function\"\n ) {\n const targetAgents =\n typeof generativeUI === \"object\" ? generativeUI.agents : undefined;\n if (!targetAgents || targetAgents.includes(agentId)) {\n agent.use(new GenerativeUIMiddleware());\n }\n }\n\n // Forward eligible inbound headers onto the outgoing agent call under the\n // runtime's resolved forwarding policy (`authorization` / custom `x-*`, with\n // known infra/proxy/platform headers stripped by the default denylist —\n // #5712), but let headers the server explicitly configured on the agent WIN\n // on collision (case-insensitively): a server-set service-to-service token\n // (e.g. an IAM bearer) must never be silently overridden by a\n // browser/edge/platform-injected inbound header. See `mergeForwardableHeaders`\n // for the casing/duplicate-key rationale and `shouldForwardHeader` for breadth.\n agent.headers = mergeForwardableHeaders(\n agent.headers,\n request,\n // `forwardHeadersPolicy` is optional on the published `CopilotRuntimeLike`\n // interface (non-breaking minor release). Concrete runtimes always set it;\n // a policy-less external implementor falls back to the default resolved\n // policy (default-on denylist) so behavior stays identical and never derefs\n // undefined.\n runtime.forwardHeadersPolicy ?? resolveForwardHeadersPolicy(undefined),\n );\n}\n\n/**\n * Shared by the two places a run meets a middleware-less agent: before Memory\n * is resolved (nothing left to resolve) and after (Memory resolved to nothing).\n */\nconst NO_MIDDLEWARE_WARNING =\n \"CopilotKitIntelligence.enableEnterpriseLearning is enabled, but the agent \" +\n \"does not support middleware (no `.use()` method); Intelligence tools were \" +\n \"not attached for this run.\";\n\n/**\n * Attach CopilotKit Intelligence's MCP tools to the agent run when\n * `CopilotKitIntelligence` was constructed with\n * `enableEnterpriseLearning: true`. Uses `@ag-ui/mcp-middleware`, so the\n * tools are available uniformly across agent frameworks (not just\n * `BuiltInAgent`).\n *\n * The middleware sits on a per-request agent clone, so the per-request\n * auth (Bearer apiKey + resolved user-id) is baked into the transport\n * headers at attach time. If user resolution fails, attachment is\n * skipped silently — the intelligence run handler will reject the\n * request with the same error. Note this means `identifyUser` is\n * resolved twice per learning-enabled run (here and in the run handler);\n * the callback is expected to be idempotent and side-effect-free.\n *\n * Intentionally split out from `configureAgentForRequest`: this is only\n * relevant to actual agent runs, not auxiliary flows like thread-name\n * generation (which has no need for MCP tools and shouldn't pay the\n * `listTools` round-trip).\n */\nexport async function attachIntelligenceEnterpriseLearning(params: {\n runtime: CopilotRuntimeLike;\n request: Request;\n agent: AbstractAgent;\n}): Promise<void | Response> {\n const { runtime, request } = params;\n const agent = params.agent as MiddlewareCapableAgent;\n\n if (!isIntelligenceRuntime(runtime)) return;\n\n const learningEnabled =\n runtime.intelligence?.ɵisEnterpriseLearningEnabled?.() === true;\n if (runtime.memory === undefined && !learningEnabled) return;\n\n // Nothing here is resolvable for an agent whose framework can't take\n // middleware and whose runtime configures no Memory — bail before paying for\n // `identifyUser`, so an enterprise-learning-only run keeps warning rather\n // than acquiring a new way to fail.\n if (runtime.memory === undefined && typeof agent.use !== \"function\") {\n logger.warn(NO_MIDDLEWARE_WARNING);\n return;\n }\n\n const userResult = await resolveIntelligenceUser({ runtime, request });\n if (userResult instanceof Response) return userResult;\n const access = await resolveWebMemory(runtime, request, userResult, \"agent\");\n if (access instanceof Response) return access;\n\n const memoryGranted =\n runtime.memory !== undefined && grantAllowsMemory(access.grant);\n\n // A policy that grants no scope means this run gets no Memory — it does NOT\n // mean the run is refused. Attach nothing and let the conversation proceed,\n // exactly as a Channel does when its grant asks for nothing\n // (`hasMemoryAccess` in @copilotkit/channels-core). Returning a 403 here\n // instead fails the whole run, so switching Memory off for one tenant would\n // leave that tenant with no assistant, and the only signal is a run error the\n // chat surface has no reason to render.\n //\n // Enterprise learning rides the SAME MCP server, so \"no Memory\" must not cost\n // an operator the learning tools too. When it is on, attach anyway and let\n // Intelligence filter: it registers one Memory tool per granted scope and\n // none at all for an all-none grant, leaving the learning tools untouched.\n if (!memoryGranted && !learningEnabled) return;\n\n // Whatever is left to attach needs middleware. Failing the run is right only\n // when Memory was actually granted and cannot be delivered; a run that merely\n // wanted learning tools warns and proceeds, as it always has.\n if (typeof agent.use !== \"function\") {\n if (memoryGranted) {\n return errorResponse(\n \"Memory is configured, but this agent does not support middleware\",\n 500,\n );\n }\n logger.warn(NO_MIDDLEWARE_WARNING);\n return;\n }\n\n agent.use(\n new MCPMiddleware([\n {\n type: \"http\",\n url: `${runtime.intelligence.ɵgetApiUrl()}/mcp`,\n serverId: \"intelligence\",\n headers: {\n Authorization: `Bearer ${runtime.intelligence.ɵgetApiKey()}`,\n [INTELLIGENCE_USER_ID_HEADER]: userResult.id,\n ...(runtime.memory\n ? {\n [INTELLIGENCE_MEMORY_GRANT_HEADER]: JSON.stringify(\n access.grant,\n ),\n }\n : {}),\n },\n },\n ]),\n );\n}\n\n// Intentional local exception: HTTP request parsing runs before AG-UI's event\n// compatibility boundary. Mirror its historically accepted optional-null rules\n// and its legacy binary-part upgrade here, without depending on a new public\n// AG-UI helper (AG-UI does not export one). Keep these aligned\n// with client/src/middleware/compatibility-boundary.ts and AG-UI's migration guide.\n// Required nulls and nulls within application data must remain untouched.\nfunction warnCompatibility(what: string, replacement: string) {\n if (\n typeof process !== \"undefined\" &&\n typeof process.env !== \"undefined\" &&\n process.env.SUPPRESS_TRANSFORMATION_WARNINGS\n )\n return;\n console.warn(\n `[ag-ui][compat] Converting deprecated ${what} to ${replacement}. The old shape leaves the protocol after its shim window — see the repo-root DEPRECATIONS.md. Set SUPPRESS_TRANSFORMATION_WARNINGS=true to silence.`,\n );\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction omitLegacyNull(\n value: unknown,\n field: string,\n context: string,\n): unknown {\n if (!isRecord(value) || value[field] !== null) return value;\n warnCompatibility(`${context}.${field}: null`, \"an absent field\");\n const { [field]: _null, ...rest } = value;\n return rest;\n}\n\nfunction mapProtocolArray(\n value: unknown,\n field: string,\n normalize: (entry: unknown) => unknown,\n): unknown {\n if (!isRecord(value) || !Array.isArray(value[field])) return value;\n const original = value[field];\n const entries = original.map(normalize);\n return entries.some((entry, index) => entry !== original[index])\n ? { ...value, [field]: entries }\n : value;\n}\n\nfunction mediaTypeFor(\n mimeType: string,\n): \"image\" | \"audio\" | \"video\" | \"document\" {\n if (mimeType.startsWith(\"image/\")) return \"image\";\n if (mimeType.startsWith(\"audio/\")) return \"audio\";\n if (mimeType.startsWith(\"video/\")) return \"video\";\n return \"document\";\n}\n\nfunction sameSource(part: unknown, converted: Record<string, unknown>) {\n if (!isRecord(part) || part.type !== converted.type) return false;\n const a = part.source;\n const b = converted.source as Record<string, unknown>;\n return (\n isRecord(a) &&\n a.type === b.type &&\n a.value === b.value &&\n a.mimeType === b.mimeType\n );\n}\n\n/**\n * The 0.x `{ type: \"binary\" }` part, which 1.0 retired and main accepted.\n * Mirrors AG-UI's outgoing upgrade (client/src/middleware/legacy-content.ts):\n * data or url becomes the media part its mime type names, and a binary part\n * that only mirrors a modern part already in the message is dropped. A part\n * with only an `id` has no 1.0 form; it is dropped with a warning instead of\n * failing the whole request, which is what BuiltInAgent already did with it.\n */\nfunction upgradeLegacyBinaryParts(content: unknown[]): unknown[] {\n return content.flatMap((part) => {\n if (\n !isRecord(part) ||\n part.type !== \"binary\" ||\n typeof part.mimeType !== \"string\"\n )\n return [part];\n const kind =\n typeof part.data === \"string\"\n ? \"data\"\n : typeof part.url === \"string\"\n ? \"url\"\n : null;\n if (kind === null) {\n console.warn(\n \"[CopilotKit] Dropping a legacy binary content part that has no data or url; AG-UI 1.0 has no equivalent for it.\",\n );\n return [];\n }\n warnCompatibility(\"binary input content\", \"the modern media content part\");\n const converted: Record<string, unknown> = {\n type: mediaTypeFor(part.mimeType),\n source: {\n type: kind,\n value: kind === \"data\" ? part.data : part.url,\n mimeType: part.mimeType,\n },\n ...(typeof part.filename === \"string\"\n ? { metadata: { filename: part.filename } }\n : {}),\n };\n return content.some((other) => sameSource(other, converted))\n ? []\n : [converted];\n });\n}\n\nfunction normalizeLegacyMessageContent(message: unknown): unknown {\n const upgraded =\n isRecord(message) &&\n Array.isArray(message.content) &&\n message.content.some((part) => isRecord(part) && part.type === \"binary\")\n ? {\n ...message,\n content: upgradeLegacyBinaryParts(message.content),\n }\n : message;\n return mapProtocolArray(upgraded, \"content\", (part) => {\n if (!isRecord(part)) return part;\n switch (part.type) {\n case \"image\":\n case \"audio\":\n case \"video\":\n case \"document\":\n return omitLegacyNull(part, \"metadata\", `${part.type} input content`);\n default:\n return part;\n }\n });\n}\n\nfunction normalizeLegacyRunAgentInput(input: unknown): unknown {\n let normalized = omitLegacyNull(input, \"forwardedProps\", \"RunAgentInput\");\n normalized = mapProtocolArray(normalized, \"tools\", (tool) =>\n omitLegacyNull(tool, \"parameters\", \"Tool\"),\n );\n normalized = mapProtocolArray(normalized, \"resume\", (entry) =>\n omitLegacyNull(entry, \"payload\", \"ResumeEntry\"),\n );\n return mapProtocolArray(\n normalized,\n \"messages\",\n normalizeLegacyMessageContent,\n );\n}\n\nfunction parseRunAgentInput(value: unknown): RunAgentInput {\n // With strictNullChecks disabled, Zod infers some required nested fields\n // (such as image.source) as optional. The schema still validates them.\n return RunAgentInputSchema.parse(\n normalizeLegacyRunAgentInput(value),\n ) as RunAgentInput;\n}\n\nexport async function parseRunRequest(\n request: Request,\n): Promise<RunAgentInput | Response> {\n try {\n const requestBody = await request.json();\n return parseRunAgentInput(requestBody);\n } catch (error) {\n logger.error(\"Invalid run request body:\", error);\n return new Response(\n JSON.stringify({\n error: \"Invalid request body\",\n details: error instanceof Error ? error.message : String(error),\n }),\n {\n status: 400,\n headers: { \"Content-Type\": \"application/json\" },\n },\n );\n }\n}\n\nexport async function parseConnectRequest(request: Request): Promise<\n | Response\n | {\n input: RunAgentInput;\n lastSeenEventId: string | null;\n }\n> {\n try {\n const requestBody = await request.json();\n const input = parseRunAgentInput(requestBody);\n let lastSeenEventId: string | null = null;\n\n if (\n \"lastSeenEventId\" in (requestBody as Record<string, unknown>) &&\n (typeof (requestBody as Record<string, unknown>).lastSeenEventId ===\n \"string\" ||\n (requestBody as Record<string, unknown>).lastSeenEventId === null)\n ) {\n lastSeenEventId =\n (requestBody as ConnectRequestBody).lastSeenEventId ?? null;\n }\n\n return { input, lastSeenEventId };\n } catch (error) {\n logger.error(\"Invalid connect request body:\", error);\n return new Response(\n JSON.stringify({\n error: \"Invalid request body\",\n details: error instanceof Error ? error.message : String(error),\n }),\n {\n status: 400,\n headers: { \"Content-Type\": \"application/json\" },\n },\n );\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6DA,eAAsB,qBACpB,SACA,SACA,SACmC;CACnC,MAAM,SAAS,MAAM,cAAc,QAAQ,QAAQ,QAAQ;AAE3D,KAAI,CAAC,OAAO,SACV,QAAO,IAAI,SACT,KAAK,UAAU;EACb,OAAO;EACP,SAAS,UAAU,QAAQ;EAC5B,CAAC,EACF;EACE,QAAQ;EACR,SAAS,EAAE,gBAAgB,oBAAoB;EAChD,CACF;AAGH,QAAQ,OAAO,SAA2B,OAAO;;AAGnD,SAAgB,yBAAyB,QAmBhC;CACP,MAAM,EACJ,SACA,SACA,SACA,wBACA,sBACE;CACJ,MAAM,QAAQ,OAAO;CAKrB,MAAM,uBACJ,CAAC,CAAC,0BAA0B,QAAQ,MAAM,YAAY;AAExD,KAAI,cAAc,QAAQ,KAAK,IAAI,sBAAsB;EAGvD,MAAM,EACJ,QAAQ,cACR,SAAS,UACT,gBACA,GAAG,gBACD,QAAQ,QAAQ,EAAE;AAEtB,OADoB,CAAC,gBAAgB,aAAa,SAAS,QAAQ,KAChD,OAAO,MAAM,QAAQ,WACtC,OAAM,IACJ,IAAI,eAAe;GACjB,GAAG;GAIH,gBACE,mBAAmB,yBAAyB,OAAO;GACtD,CAAC,CACH;;AAIL,KAAI,sBAAsB,QAAQ,IAAI,OAAO,MAAM,QAAQ,YAAY;EAGrE,MAAM,aAAa,sBACjB,QAAQ,SAAS,WAAW,EAAE,EAC9B,QACD;AACD,MAAI,WAAW,SAAS,KAAK,kBAC3B,OAAM,IACJ,IAAI,kBAAkB;GAAE;GAAY,sBAAsB;GAAS,CAAC,CACrE;YAEM,QAAQ,SAAS,SAAS,QAAQ;EAC3C,MAAM,aAAa,sBAAsB,QAAQ,QAAQ,SAAS,QAAQ;AAE1E,MAAI,WAAW,SAAS,KAAK,OAAO,MAAM,QAAQ,WAChD,OAAM,IAAI,IAAI,kBAAkB,EAAE,YAAY,CAAC,CAAC;;AAIpD,KAAI,QAAQ,kBAAkB;EAC5B,MAAM,SAAS,QAAQ;EACvB,MAAM,eAAe,OAAO,WAAW,WAAW,OAAO,SAAS;AAElE,OADoB,CAAC,gBAAgB,aAAa,SAAS,QAAQ,KAChD,OAAO,MAAM,QAAQ,WACtC,OAAM,IAAI,IAAI,4BAA4B,CAAC;;CAM/C,MAAM,eAAe,QAAQ;CAC7B,MAAM,YAAY,OAAO;AAGzB,MADE,cAAc,UAAW,cAAc,cAAc,CAAC,CAAC,iBAGvD,iBAAiB,SACjB,OAAO,MAAM,QAAQ,YACrB;EACA,MAAM,eACJ,OAAO,iBAAiB,WAAW,aAAa,SAAS;AAC3D,MAAI,CAAC,gBAAgB,aAAa,SAAS,QAAQ,CACjD,OAAM,IAAI,IAAI,wBAAwB,CAAC;;AAY3C,OAAM,UAAU,wBACd,MAAM,SACN,SAMA,QAAQ,wBAAwB,4BAA4B,OAAU,CACvE;;;;;;AAOH,MAAM,wBACJ;;;;;;;;;;;;;;;;;;;;;AAwBF,eAAsB,qCAAqC,QAI9B;CAC3B,MAAM,EAAE,SAAS,YAAY;CAC7B,MAAM,QAAQ,OAAO;AAErB,KAAI,CAAC,sBAAsB,QAAQ,CAAE;CAErC,MAAM,kBACJ,QAAQ,cAAc,gCAAgC,KAAK;AAC7D,KAAI,QAAQ,WAAW,UAAa,CAAC,gBAAiB;AAMtD,KAAI,QAAQ,WAAW,UAAa,OAAO,MAAM,QAAQ,YAAY;AACnE,SAAO,KAAK,sBAAsB;AAClC;;CAGF,MAAM,aAAa,MAAM,wBAAwB;EAAE;EAAS;EAAS,CAAC;AACtE,KAAI,sBAAsB,SAAU,QAAO;CAC3C,MAAM,SAAS,MAAM,iBAAiB,SAAS,SAAS,YAAY,QAAQ;AAC5E,KAAI,kBAAkB,SAAU,QAAO;CAEvC,MAAM,gBACJ,QAAQ,WAAW,UAAa,kBAAkB,OAAO,MAAM;AAcjE,KAAI,CAAC,iBAAiB,CAAC,gBAAiB;AAKxC,KAAI,OAAO,MAAM,QAAQ,YAAY;AACnC,MAAI,cACF,QAAO,cACL,oEACA,IACD;AAEH,SAAO,KAAK,sBAAsB;AAClC;;AAGF,OAAM,IACJ,IAAI,cAAc,CAChB;EACE,MAAM;EACN,KAAK,GAAG,QAAQ,aAAa,YAAY,CAAC;EAC1C,UAAU;EACV,SAAS;GACP,eAAe,UAAU,QAAQ,aAAa,YAAY;IACzD,8BAA8B,WAAW;GAC1C,GAAI,QAAQ,SACR,GACG,mCAAmC,KAAK,UACvC,OAAO,MACR,EACF,GACD,EAAE;GACP;EACF,CACF,CAAC,CACH;;AASH,SAAS,kBAAkB,MAAc,aAAqB;AAC5D,KACE,OAAO,YAAY,eACnB,OAAO,QAAQ,QAAQ,eACvB,QAAQ,IAAI,iCAEZ;AACF,SAAQ,KACN,yCAAyC,KAAK,MAAM,YAAY,sJACjE;;AAGH,SAAS,SAAS,OAAkD;AAClE,QAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,MAAM;;AAG7E,SAAS,eACP,OACA,OACA,SACS;AACT,KAAI,CAAC,SAAS,MAAM,IAAI,MAAM,WAAW,KAAM,QAAO;AACtD,mBAAkB,GAAG,QAAQ,GAAG,MAAM,SAAS,kBAAkB;CACjE,MAAM,GAAG,QAAQ,OAAO,GAAG,SAAS;AACpC,QAAO;;AAGT,SAAS,iBACP,OACA,OACA,WACS;AACT,KAAI,CAAC,SAAS,MAAM,IAAI,CAAC,MAAM,QAAQ,MAAM,OAAO,CAAE,QAAO;CAC7D,MAAM,WAAW,MAAM;CACvB,MAAM,UAAU,SAAS,IAAI,UAAU;AACvC,QAAO,QAAQ,MAAM,OAAO,UAAU,UAAU,SAAS,OAAO,GAC5D;EAAE,GAAG;GAAQ,QAAQ;EAAS,GAC9B;;AAGN,SAAS,aACP,UAC0C;AAC1C,KAAI,SAAS,WAAW,SAAS,CAAE,QAAO;AAC1C,KAAI,SAAS,WAAW,SAAS,CAAE,QAAO;AAC1C,KAAI,SAAS,WAAW,SAAS,CAAE,QAAO;AAC1C,QAAO;;AAGT,SAAS,WAAW,MAAe,WAAoC;AACrE,KAAI,CAAC,SAAS,KAAK,IAAI,KAAK,SAAS,UAAU,KAAM,QAAO;CAC5D,MAAM,IAAI,KAAK;CACf,MAAM,IAAI,UAAU;AACpB,QACE,SAAS,EAAE,IACX,EAAE,SAAS,EAAE,QACb,EAAE,UAAU,EAAE,SACd,EAAE,aAAa,EAAE;;;;;;;;;;AAYrB,SAAS,yBAAyB,SAA+B;AAC/D,QAAO,QAAQ,SAAS,SAAS;AAC/B,MACE,CAAC,SAAS,KAAK,IACf,KAAK,SAAS,YACd,OAAO,KAAK,aAAa,SAEzB,QAAO,CAAC,KAAK;EACf,MAAM,OACJ,OAAO,KAAK,SAAS,WACjB,SACA,OAAO,KAAK,QAAQ,WAClB,QACA;AACR,MAAI,SAAS,MAAM;AACjB,WAAQ,KACN,kHACD;AACD,UAAO,EAAE;;AAEX,oBAAkB,wBAAwB,gCAAgC;EAC1E,MAAM,YAAqC;GACzC,MAAM,aAAa,KAAK,SAAS;GACjC,QAAQ;IACN,MAAM;IACN,OAAO,SAAS,SAAS,KAAK,OAAO,KAAK;IAC1C,UAAU,KAAK;IAChB;GACD,GAAI,OAAO,KAAK,aAAa,WACzB,EAAE,UAAU,EAAE,UAAU,KAAK,UAAU,EAAE,GACzC,EAAE;GACP;AACD,SAAO,QAAQ,MAAM,UAAU,WAAW,OAAO,UAAU,CAAC,GACxD,EAAE,GACF,CAAC,UAAU;GACf;;AAGJ,SAAS,8BAA8B,SAA2B;AAUhE,QAAO,iBARL,SAAS,QAAQ,IACjB,MAAM,QAAQ,QAAQ,QAAQ,IAC9B,QAAQ,QAAQ,MAAM,SAAS,SAAS,KAAK,IAAI,KAAK,SAAS,SAAS,GACpE;EACE,GAAG;EACH,SAAS,yBAAyB,QAAQ,QAAQ;EACnD,GACD,SAC4B,YAAY,SAAS;AACrD,MAAI,CAAC,SAAS,KAAK,CAAE,QAAO;AAC5B,UAAQ,KAAK,MAAb;GACE,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK,WACH,QAAO,eAAe,MAAM,YAAY,GAAG,KAAK,KAAK,gBAAgB;GACvE,QACE,QAAO;;GAEX;;AAGJ,SAAS,6BAA6B,OAAyB;CAC7D,IAAI,aAAa,eAAe,OAAO,kBAAkB,gBAAgB;AACzE,cAAa,iBAAiB,YAAY,UAAU,SAClD,eAAe,MAAM,cAAc,OAAO,CAC3C;AACD,cAAa,iBAAiB,YAAY,WAAW,UACnD,eAAe,OAAO,WAAW,cAAc,CAChD;AACD,QAAO,iBACL,YACA,YACA,8BACD;;AAGH,SAAS,mBAAmB,OAA+B;AAGzD,QAAO,oBAAoB,MACzB,6BAA6B,MAAM,CACpC;;AAGH,eAAsB,gBACpB,SACmC;AACnC,KAAI;AAEF,SAAO,mBADa,MAAM,QAAQ,MAAM,CACF;UAC/B,OAAO;AACd,SAAO,MAAM,6BAA6B,MAAM;AAChD,SAAO,IAAI,SACT,KAAK,UAAU;GACb,OAAO;GACP,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;GAChE,CAAC,EACF;GACE,QAAQ;GACR,SAAS,EAAE,gBAAgB,oBAAoB;GAChD,CACF;;;AAIL,eAAsB,oBAAoB,SAMxC;AACA,KAAI;EACF,MAAM,cAAc,MAAM,QAAQ,MAAM;EACxC,MAAM,QAAQ,mBAAmB,YAAY;EAC7C,IAAI,kBAAiC;AAErC,MACE,qBAAsB,gBACrB,OAAQ,YAAwC,oBAC/C,YACC,YAAwC,oBAAoB,MAE/D,mBACG,YAAmC,mBAAmB;AAG3D,SAAO;GAAE;GAAO;GAAiB;UAC1B,OAAO;AACd,SAAO,MAAM,iCAAiC,MAAM;AACpD,SAAO,IAAI,SACT,KAAK,UAAU;GACb,OAAO;GACP,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;GAChE,CAAC,EACF;GACE,QAAQ;GACR,SAAS,EAAE,gBAAgB,oBAAoB;GAChD,CACF"}
|
|
1
|
+
{"version":3,"file":"agent-utils.mjs","names":[],"sources":["../../../../src/runtime/handlers/shared/agent-utils.ts"],"sourcesContent":["import type { AbstractAgent, RunAgentInput } from \"@ag-ui/client\";\nimport { RunAgentInputSchema } from \"@ag-ui/core/schemas\";\nimport type { CopilotKitUIEnvelope } from \"@copilotkit/shared\";\nimport {\n A2UIMiddleware,\n OpenGenerativeUIMiddleware,\n} from \"@copilotkit/shared/event-transforms\";\nimport { MCPAppsMiddleware } from \"@ag-ui/mcp-apps-middleware\";\nimport { MCPMiddleware } from \"@ag-ui/mcp-middleware\";\nimport { GenerativeUIMiddleware } from \"../../generative-ui\";\nimport type { CopilotRuntimeLike } from \"../../core/runtime\";\nimport {\n isA2UIEnabled,\n isIntelligenceRuntime,\n resolveAgents,\n} from \"../../core/runtime\";\nimport {\n INTELLIGENCE_MEMORY_GRANT_HEADER,\n INTELLIGENCE_USER_ID_HEADER,\n} from \"../../intelligence-platform/client\";\nimport {\n mergeForwardableHeaders,\n resolveForwardHeadersPolicy,\n} from \"../header-utils\";\nimport { resolveMcpAppsServers } from \"./mcp-apps-servers\";\nimport { resolveIntelligenceUser } from \"./resolve-intelligence-user\";\nimport { grantAllowsMemory, resolveWebMemory } from \"./memory-policy\";\nimport { errorResponse } from \"./json-response\";\nimport { logger, processEnv } from \"@copilotkit/shared\";\n\ntype MiddlewareCapableAgent = AbstractAgent & {\n use?: (middleware: unknown) => void;\n headers?: Record<string, string>;\n};\n\nexport interface RunAgentParameters {\n request: Request;\n runtime: CopilotRuntimeLike;\n agentId: string;\n}\n\nexport interface ConnectRequestBody extends RunAgentInput {\n lastSeenEventId?: string | null;\n}\n\n/**\n * Resolve `agentId` against the runtime's agents and return a per-request\n * clone of the matching agent.\n *\n * Dual return contract — both callers (`handle-run.ts`, `handle-connect.ts`)\n * depend on it:\n * - Returns a cloned `AbstractAgent` when the agent exists.\n * - Returns a 404 `Response` (`{ error: \"Agent not found\", ... }`) when the\n * agent is unknown. Callers MUST `instanceof Response`-check the result and\n * return it directly; this doubles as the connect/run path's agent-existence\n * guard, so skipping the check would let unknown agent ids slip through.\n *\n * The clone is what subsequent per-request mutation (middleware attach,\n * `agent.headers` merge) operates on, leaving the shared agent registration\n * untouched.\n */\nexport async function cloneAgentForRequest(\n runtime: CopilotRuntimeLike,\n agentId: string,\n request?: Request,\n): Promise<AbstractAgent | Response> {\n const agents = await resolveAgents(runtime.agents, request);\n\n if (!agents[agentId]) {\n return new Response(\n JSON.stringify({\n error: \"Agent not found\",\n message: `Agent '${agentId}' does not exist`,\n }),\n {\n status: 404,\n headers: { \"Content-Type\": \"application/json\" },\n },\n );\n }\n\n return (agents[agentId] as AbstractAgent).clone() as AbstractAgent;\n}\n\nexport function configureAgentForRequest(params: {\n runtime: CopilotRuntimeLike;\n request: Request;\n agentId: string;\n agent: AbstractAgent;\n /**\n * True when the React provider was given an A2UI catalog\n * (`<CopilotKit a2ui={{ catalog }}>`), forwarded per-run. A catalog alone is\n * enough to enable A2UI and inject the render tool — the developer no longer\n * has to also set `a2ui.injectA2UITool` on the runtime.\n */\n providerA2UIHasCatalog?: boolean;\n /**\n * The transport of the generative UI envelope that the client sent on this\n * run (`forwardedProps.copilotkit.ui`). Not set when the run has no envelope.\n */\n providerGenerativeUITransport?: CopilotKitUIEnvelope[\"metadata\"][\"extensions\"][\"copilotkit_transport\"];\n /** Retain proxy rejection even when no server is available to this agent. */\n isMcpProxyRequest?: boolean;\n}): void {\n const {\n runtime,\n request,\n agentId,\n providerA2UIHasCatalog,\n isMcpProxyRequest,\n } = params;\n const agent = params.agent as MiddlewareCapableAgent;\n\n // A2UI is on when the runtime explicitly enables it, OR when the provider\n // forwarded a catalog — but an explicit `enabled: false` always wins (we\n // provide a quick default, never override a deeper opt-out).\n const a2uiEnabledByCatalog =\n !!providerA2UIHasCatalog && runtime.a2ui?.enabled !== false;\n\n if (isA2UIEnabled(runtime.a2ui) || a2uiEnabledByCatalog) {\n // `enabled` is a CopilotKit-level switch, not an A2UIMiddleware option —\n // drop it (alongside the agent filter) before forwarding to the middleware.\n const {\n agents: targetAgents,\n enabled: _enabled,\n injectA2UITool,\n ...a2uiOptions\n } = runtime.a2ui ?? {};\n const shouldApply = !targetAgents || targetAgents.includes(agentId);\n if (shouldApply && typeof agent.use === \"function\") {\n agent.use(\n new A2UIMiddleware({\n ...a2uiOptions,\n // Default render-tool injection on when a catalog is present and the\n // developer hasn't set it explicitly. `??` means an explicit value\n // (including `false`) is always respected.\n injectA2UITool:\n injectA2UITool ?? (providerA2UIHasCatalog ? true : undefined),\n }),\n );\n }\n }\n\n if (isIntelligenceRuntime(runtime) && typeof agent.use === \"function\") {\n // Ordinary runs need no middleware without selected servers. Proxy requests\n // still need the upstream guard so they cannot fall through to the model.\n const mcpServers = resolveMcpAppsServers(\n runtime.mcpApps?.servers ?? [],\n agentId,\n );\n if (mcpServers.length > 0 || isMcpProxyRequest) {\n agent.use(\n new MCPAppsMiddleware({ mcpServers, discoveryFailureMode: \"throw\" }),\n );\n }\n } else if (runtime.mcpApps?.servers?.length) {\n const mcpServers = resolveMcpAppsServers(runtime.mcpApps.servers, agentId);\n\n if (mcpServers.length > 0 && typeof agent.use === \"function\") {\n agent.use(new MCPAppsMiddleware({ mcpServers }));\n }\n }\n\n if (runtime.openGenerativeUI) {\n const config = runtime.openGenerativeUI;\n const targetAgents = typeof config === \"object\" ? config.agents : undefined;\n const shouldApply = !targetAgents || targetAgents.includes(agentId);\n if (shouldApply && typeof agent.use === \"function\") {\n agent.use(new OpenGenerativeUIMiddleware());\n }\n }\n\n // A \"markdown\" envelope means the model writes ```a2ui fences, so the run\n // gets no render tool, even when the runtime turns generative UI on.\n const generativeUI = runtime.generativeUI;\n const transport = params.providerGenerativeUITransport;\n const isGenerativeUIRun =\n transport === \"tool\" || (transport !== \"markdown\" && !!generativeUI);\n if (\n isGenerativeUIRun &&\n generativeUI !== false &&\n typeof agent.use === \"function\"\n ) {\n const targetAgents =\n typeof generativeUI === \"object\" ? generativeUI.agents : undefined;\n if (!targetAgents || targetAgents.includes(agentId)) {\n agent.use(new GenerativeUIMiddleware());\n }\n }\n\n // Forward eligible inbound headers onto the outgoing agent call under the\n // runtime's resolved forwarding policy (`authorization` / custom `x-*`, with\n // known infra/proxy/platform headers stripped by the default denylist —\n // #5712), but let headers the server explicitly configured on the agent WIN\n // on collision (case-insensitively): a server-set service-to-service token\n // (e.g. an IAM bearer) must never be silently overridden by a\n // browser/edge/platform-injected inbound header. See `mergeForwardableHeaders`\n // for the casing/duplicate-key rationale and `shouldForwardHeader` for breadth.\n agent.headers = mergeForwardableHeaders(\n agent.headers,\n request,\n // `forwardHeadersPolicy` is optional on the published `CopilotRuntimeLike`\n // interface (non-breaking minor release). Concrete runtimes always set it;\n // a policy-less external implementor falls back to the default resolved\n // policy (default-on denylist) so behavior stays identical and never derefs\n // undefined.\n runtime.forwardHeadersPolicy ?? resolveForwardHeadersPolicy(undefined),\n );\n}\n\n/**\n * Shared by the two places a run meets a middleware-less agent: before Memory\n * is resolved (nothing left to resolve) and after (Memory resolved to nothing).\n */\nconst NO_MIDDLEWARE_WARNING =\n \"CopilotKitIntelligence.enableEnterpriseLearning is enabled, but the agent \" +\n \"does not support middleware (no `.use()` method); Intelligence tools were \" +\n \"not attached for this run.\";\n\n/**\n * Attach CopilotKit Intelligence's MCP tools to the agent run when\n * `CopilotKitIntelligence` was constructed with\n * `enableEnterpriseLearning: true`. Uses `@ag-ui/mcp-middleware`, so the\n * tools are available uniformly across agent frameworks (not just\n * `BuiltInAgent`).\n *\n * The middleware sits on a per-request agent clone, so the per-request\n * auth (Bearer apiKey + resolved user-id) is baked into the transport\n * headers at attach time. If user resolution fails, attachment is\n * skipped silently — the intelligence run handler will reject the\n * request with the same error. Note this means `identifyUser` is\n * resolved twice per learning-enabled run (here and in the run handler);\n * the callback is expected to be idempotent and side-effect-free.\n *\n * Intentionally split out from `configureAgentForRequest`: this is only\n * relevant to actual agent runs, not auxiliary flows like thread-name\n * generation (which has no need for MCP tools and shouldn't pay the\n * `listTools` round-trip).\n */\nexport async function attachIntelligenceEnterpriseLearning(params: {\n runtime: CopilotRuntimeLike;\n request: Request;\n agent: AbstractAgent;\n}): Promise<void | Response> {\n const { runtime, request } = params;\n const agent = params.agent as MiddlewareCapableAgent;\n\n if (!isIntelligenceRuntime(runtime)) return;\n\n const learningEnabled =\n runtime.intelligence?.ɵisEnterpriseLearningEnabled?.() === true;\n if (runtime.memory === undefined && !learningEnabled) return;\n\n // Nothing here is resolvable for an agent whose framework can't take\n // middleware and whose runtime configures no Memory — bail before paying for\n // `identifyUser`, so an enterprise-learning-only run keeps warning rather\n // than acquiring a new way to fail.\n if (runtime.memory === undefined && typeof agent.use !== \"function\") {\n logger.warn(NO_MIDDLEWARE_WARNING);\n return;\n }\n\n const userResult = await resolveIntelligenceUser({ runtime, request });\n if (userResult instanceof Response) return userResult;\n const access = await resolveWebMemory(runtime, request, userResult, \"agent\");\n if (access instanceof Response) return access;\n\n const memoryGranted =\n runtime.memory !== undefined && grantAllowsMemory(access.grant);\n\n // A policy that grants no scope means this run gets no Memory — it does NOT\n // mean the run is refused. Attach nothing and let the conversation proceed,\n // exactly as a Channel does when its grant asks for nothing\n // (`hasMemoryAccess` in @copilotkit/channels-core). Returning a 403 here\n // instead fails the whole run, so switching Memory off for one tenant would\n // leave that tenant with no assistant, and the only signal is a run error the\n // chat surface has no reason to render.\n //\n // Enterprise learning rides the SAME MCP server, so \"no Memory\" must not cost\n // an operator the learning tools too. When it is on, attach anyway and let\n // Intelligence filter: it registers one Memory tool per granted scope and\n // none at all for an all-none grant, leaving the learning tools untouched.\n if (!memoryGranted && !learningEnabled) return;\n\n // Whatever is left to attach needs middleware. Failing the run is right only\n // when Memory was actually granted and cannot be delivered; a run that merely\n // wanted learning tools warns and proceeds, as it always has.\n if (typeof agent.use !== \"function\") {\n if (memoryGranted) {\n return errorResponse(\n \"Memory is configured, but this agent does not support middleware\",\n 500,\n );\n }\n logger.warn(NO_MIDDLEWARE_WARNING);\n return;\n }\n\n agent.use(\n new MCPMiddleware([\n {\n type: \"http\",\n url: `${runtime.intelligence.ɵgetApiUrl()}/mcp`,\n serverId: \"intelligence\",\n headers: {\n Authorization: `Bearer ${runtime.intelligence.ɵgetApiKey()}`,\n [INTELLIGENCE_USER_ID_HEADER]: userResult.id,\n ...(runtime.memory\n ? {\n [INTELLIGENCE_MEMORY_GRANT_HEADER]: JSON.stringify(\n access.grant,\n ),\n }\n : {}),\n },\n },\n ]),\n );\n}\n\n// Intentional local exception: HTTP request parsing runs before AG-UI's event\n// compatibility boundary. Mirror its historically accepted optional-null rules\n// and its legacy binary-part upgrade here, without depending on a new public\n// AG-UI helper (AG-UI does not export one). Keep these aligned\n// with client/src/middleware/compatibility-boundary.ts and AG-UI's migration guide.\n// Required nulls and nulls within application data must remain untouched.\nfunction warnCompatibility(what: string, replacement: string) {\n if (\n typeof process !== \"undefined\" &&\n typeof processEnv() !== \"undefined\" &&\n processEnv().SUPPRESS_TRANSFORMATION_WARNINGS\n )\n return;\n console.warn(\n `[ag-ui][compat] Converting deprecated ${what} to ${replacement}. The old shape leaves the protocol after its shim window — see the repo-root DEPRECATIONS.md. Set SUPPRESS_TRANSFORMATION_WARNINGS=true to silence.`,\n );\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction omitLegacyNull(\n value: unknown,\n field: string,\n context: string,\n): unknown {\n if (!isRecord(value) || value[field] !== null) return value;\n warnCompatibility(`${context}.${field}: null`, \"an absent field\");\n const { [field]: _null, ...rest } = value;\n return rest;\n}\n\nfunction mapProtocolArray(\n value: unknown,\n field: string,\n normalize: (entry: unknown) => unknown,\n): unknown {\n if (!isRecord(value) || !Array.isArray(value[field])) return value;\n const original = value[field];\n const entries = original.map(normalize);\n return entries.some((entry, index) => entry !== original[index])\n ? { ...value, [field]: entries }\n : value;\n}\n\nfunction mediaTypeFor(\n mimeType: string,\n): \"image\" | \"audio\" | \"video\" | \"document\" {\n if (mimeType.startsWith(\"image/\")) return \"image\";\n if (mimeType.startsWith(\"audio/\")) return \"audio\";\n if (mimeType.startsWith(\"video/\")) return \"video\";\n return \"document\";\n}\n\nfunction sameSource(part: unknown, converted: Record<string, unknown>) {\n if (!isRecord(part) || part.type !== converted.type) return false;\n const a = part.source;\n const b = converted.source as Record<string, unknown>;\n return (\n isRecord(a) &&\n a.type === b.type &&\n a.value === b.value &&\n a.mimeType === b.mimeType\n );\n}\n\n/**\n * The 0.x `{ type: \"binary\" }` part, which 1.0 retired and main accepted.\n * Mirrors AG-UI's outgoing upgrade (client/src/middleware/legacy-content.ts):\n * data or url becomes the media part its mime type names, and a binary part\n * that only mirrors a modern part already in the message is dropped. A part\n * with only an `id` has no 1.0 form; it is dropped with a warning instead of\n * failing the whole request, which is what BuiltInAgent already did with it.\n */\nfunction upgradeLegacyBinaryParts(content: unknown[]): unknown[] {\n return content.flatMap((part) => {\n if (\n !isRecord(part) ||\n part.type !== \"binary\" ||\n typeof part.mimeType !== \"string\"\n )\n return [part];\n const kind =\n typeof part.data === \"string\"\n ? \"data\"\n : typeof part.url === \"string\"\n ? \"url\"\n : null;\n if (kind === null) {\n console.warn(\n \"[CopilotKit] Dropping a legacy binary content part that has no data or url; AG-UI 1.0 has no equivalent for it.\",\n );\n return [];\n }\n warnCompatibility(\"binary input content\", \"the modern media content part\");\n const converted: Record<string, unknown> = {\n type: mediaTypeFor(part.mimeType),\n source: {\n type: kind,\n value: kind === \"data\" ? part.data : part.url,\n mimeType: part.mimeType,\n },\n ...(typeof part.filename === \"string\"\n ? { metadata: { filename: part.filename } }\n : {}),\n };\n return content.some((other) => sameSource(other, converted))\n ? []\n : [converted];\n });\n}\n\nfunction normalizeLegacyMessageContent(message: unknown): unknown {\n const upgraded =\n isRecord(message) &&\n Array.isArray(message.content) &&\n message.content.some((part) => isRecord(part) && part.type === \"binary\")\n ? {\n ...message,\n content: upgradeLegacyBinaryParts(message.content),\n }\n : message;\n return mapProtocolArray(upgraded, \"content\", (part) => {\n if (!isRecord(part)) return part;\n switch (part.type) {\n case \"image\":\n case \"audio\":\n case \"video\":\n case \"document\":\n return omitLegacyNull(part, \"metadata\", `${part.type} input content`);\n default:\n return part;\n }\n });\n}\n\nfunction normalizeLegacyRunAgentInput(input: unknown): unknown {\n let normalized = omitLegacyNull(input, \"forwardedProps\", \"RunAgentInput\");\n normalized = mapProtocolArray(normalized, \"tools\", (tool) =>\n omitLegacyNull(tool, \"parameters\", \"Tool\"),\n );\n normalized = mapProtocolArray(normalized, \"resume\", (entry) =>\n omitLegacyNull(entry, \"payload\", \"ResumeEntry\"),\n );\n return mapProtocolArray(\n normalized,\n \"messages\",\n normalizeLegacyMessageContent,\n );\n}\n\nfunction parseRunAgentInput(value: unknown): RunAgentInput {\n // With strictNullChecks disabled, Zod infers some required nested fields\n // (such as image.source) as optional. The schema still validates them.\n return RunAgentInputSchema.parse(\n normalizeLegacyRunAgentInput(value),\n ) as RunAgentInput;\n}\n\nexport async function parseRunRequest(\n request: Request,\n): Promise<RunAgentInput | Response> {\n try {\n const requestBody = await request.json();\n return parseRunAgentInput(requestBody);\n } catch (error) {\n logger.error(\"Invalid run request body:\", error);\n return new Response(\n JSON.stringify({\n error: \"Invalid request body\",\n details: error instanceof Error ? error.message : String(error),\n }),\n {\n status: 400,\n headers: { \"Content-Type\": \"application/json\" },\n },\n );\n }\n}\n\nexport async function parseConnectRequest(request: Request): Promise<\n | Response\n | {\n input: RunAgentInput;\n lastSeenEventId: string | null;\n }\n> {\n try {\n const requestBody = await request.json();\n const input = parseRunAgentInput(requestBody);\n let lastSeenEventId: string | null = null;\n\n if (\n \"lastSeenEventId\" in (requestBody as Record<string, unknown>) &&\n (typeof (requestBody as Record<string, unknown>).lastSeenEventId ===\n \"string\" ||\n (requestBody as Record<string, unknown>).lastSeenEventId === null)\n ) {\n lastSeenEventId =\n (requestBody as ConnectRequestBody).lastSeenEventId ?? null;\n }\n\n return { input, lastSeenEventId };\n } catch (error) {\n logger.error(\"Invalid connect request body:\", error);\n return new Response(\n JSON.stringify({\n error: \"Invalid request body\",\n details: error instanceof Error ? error.message : String(error),\n }),\n {\n status: 400,\n headers: { \"Content-Type\": \"application/json\" },\n },\n );\n }\n}\n"],"mappings":"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"}
|
|
@@ -5,7 +5,6 @@ const require_trajectories = require('./trajectories.cjs');
|
|
|
5
5
|
const require_learned_skills = require('./learned-skills.cjs');
|
|
6
6
|
let _copilotkit_shared = require("@copilotkit/shared");
|
|
7
7
|
let zod = require("zod");
|
|
8
|
-
let crypto = require("crypto");
|
|
9
8
|
|
|
10
9
|
//#region src/runtime/intelligence-platform/client.ts
|
|
11
10
|
/** Let a confirmed HTTP denial survive an error body that never completes. */
|
|
@@ -1203,7 +1202,7 @@ var CopilotKitIntelligence = class {
|
|
|
1203
1202
|
* caller's typed result).
|
|
1204
1203
|
*/
|
|
1205
1204
|
async annotate(params) {
|
|
1206
|
-
const clientEventId = params.clientEventId ??
|
|
1205
|
+
const clientEventId = params.clientEventId ?? globalThis.crypto.randomUUID();
|
|
1207
1206
|
const path = `/connector/annotate/${encodeURIComponent(clientEventId)}`;
|
|
1208
1207
|
const body = {
|
|
1209
1208
|
type: params.type,
|