@copilotkit/runtime 1.73.3 → 1.75.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/README.md +28 -0
  2. package/dist/agent/learned-skills.cjs.map +1 -1
  3. package/dist/agent/learned-skills.d.cts +1 -1
  4. package/dist/agent/learned-skills.d.mts +1 -1
  5. package/dist/agent/learned-skills.mjs.map +1 -1
  6. package/dist/internal/learned-skills.d.cts +2 -2
  7. package/dist/internal/learned-skills.d.mts +2 -2
  8. package/dist/package.cjs +1 -1
  9. package/dist/package.mjs +1 -1
  10. package/dist/v2/index.d.cts +2 -2
  11. package/dist/v2/index.d.mts +2 -2
  12. package/dist/v2/runtime/core/fetch-handler.cjs +4 -1
  13. package/dist/v2/runtime/core/fetch-handler.cjs.map +1 -1
  14. package/dist/v2/runtime/core/fetch-handler.mjs +4 -1
  15. package/dist/v2/runtime/core/fetch-handler.mjs.map +1 -1
  16. package/dist/v2/runtime/handlers/intelligence/memories.cjs +4 -1
  17. package/dist/v2/runtime/handlers/intelligence/memories.cjs.map +1 -1
  18. package/dist/v2/runtime/handlers/intelligence/memories.mjs +5 -2
  19. package/dist/v2/runtime/handlers/intelligence/memories.mjs.map +1 -1
  20. package/dist/v2/runtime/handlers/intelligence/thread-names.cjs +16 -2
  21. package/dist/v2/runtime/handlers/intelligence/thread-names.cjs.map +1 -1
  22. package/dist/v2/runtime/handlers/intelligence/thread-names.mjs +16 -2
  23. package/dist/v2/runtime/handlers/intelligence/thread-names.mjs.map +1 -1
  24. package/dist/v2/runtime/handlers/shared/agent-utils.cjs +17 -4
  25. package/dist/v2/runtime/handlers/shared/agent-utils.cjs.map +1 -1
  26. package/dist/v2/runtime/handlers/shared/agent-utils.mjs +18 -5
  27. package/dist/v2/runtime/handlers/shared/agent-utils.mjs.map +1 -1
  28. package/dist/v2/runtime/handlers/shared/memory-policy.cjs +43 -5
  29. package/dist/v2/runtime/handlers/shared/memory-policy.cjs.map +1 -1
  30. package/dist/v2/runtime/handlers/shared/memory-policy.mjs +43 -6
  31. package/dist/v2/runtime/handlers/shared/memory-policy.mjs.map +1 -1
  32. package/dist/v2/runtime/index.d.cts +1 -1
  33. package/dist/v2/runtime/index.d.cts.map +1 -1
  34. package/dist/v2/runtime/index.d.mts +1 -1
  35. package/dist/v2/runtime/index.d.mts.map +1 -1
  36. package/dist/v2/runtime/intelligence-platform/client.cjs +80 -0
  37. package/dist/v2/runtime/intelligence-platform/client.cjs.map +1 -1
  38. package/dist/v2/runtime/intelligence-platform/client.d.cts +3 -1
  39. package/dist/v2/runtime/intelligence-platform/client.d.cts.map +1 -1
  40. package/dist/v2/runtime/intelligence-platform/client.d.mts +3 -1
  41. package/dist/v2/runtime/intelligence-platform/client.d.mts.map +1 -1
  42. package/dist/v2/runtime/intelligence-platform/client.mjs +81 -1
  43. package/dist/v2/runtime/intelligence-platform/client.mjs.map +1 -1
  44. package/dist/v2/runtime/intelligence-platform/index.d.cts +1 -1
  45. package/dist/v2/runtime/intelligence-platform/index.d.mts +1 -1
  46. package/dist/v2/runtime/intelligence-platform/learned-skills.cjs +53 -0
  47. package/dist/v2/runtime/intelligence-platform/learned-skills.cjs.map +1 -1
  48. package/dist/v2/runtime/intelligence-platform/learned-skills.d.cts +11 -1
  49. package/dist/v2/runtime/intelligence-platform/learned-skills.d.cts.map +1 -1
  50. package/dist/v2/runtime/intelligence-platform/learned-skills.d.mts +11 -1
  51. package/dist/v2/runtime/intelligence-platform/learned-skills.d.mts.map +1 -1
  52. package/dist/v2/runtime/intelligence-platform/learned-skills.mjs +53 -1
  53. package/dist/v2/runtime/intelligence-platform/learned-skills.mjs.map +1 -1
  54. package/dist/v2/runtime/intelligence-platform/skill-registry/config.cjs +24 -6
  55. package/dist/v2/runtime/intelligence-platform/skill-registry/config.cjs.map +1 -1
  56. package/dist/v2/runtime/intelligence-platform/skill-registry/config.d.cts +28 -7
  57. package/dist/v2/runtime/intelligence-platform/skill-registry/config.d.cts.map +1 -1
  58. package/dist/v2/runtime/intelligence-platform/skill-registry/config.d.mts +28 -7
  59. package/dist/v2/runtime/intelligence-platform/skill-registry/config.d.mts.map +1 -1
  60. package/dist/v2/runtime/intelligence-platform/skill-registry/config.mjs +24 -6
  61. package/dist/v2/runtime/intelligence-platform/skill-registry/config.mjs.map +1 -1
  62. package/dist/v2/runtime/intelligence-platform/skill-registry/index.d.cts +1 -1
  63. package/dist/v2/runtime/intelligence-platform/skill-registry/index.d.mts +1 -1
  64. package/dist/v2/runtime/intelligence-platform/skill-registry/registry.cjs +120 -4
  65. package/dist/v2/runtime/intelligence-platform/skill-registry/registry.cjs.map +1 -1
  66. package/dist/v2/runtime/intelligence-platform/skill-registry/registry.d.cts +8 -2
  67. package/dist/v2/runtime/intelligence-platform/skill-registry/registry.d.cts.map +1 -1
  68. package/dist/v2/runtime/intelligence-platform/skill-registry/registry.d.mts +8 -2
  69. package/dist/v2/runtime/intelligence-platform/skill-registry/registry.d.mts.map +1 -1
  70. package/dist/v2/runtime/intelligence-platform/skill-registry/registry.mjs +119 -4
  71. package/dist/v2/runtime/intelligence-platform/skill-registry/registry.mjs.map +1 -1
  72. package/package.json +5 -5
@@ -54,7 +54,7 @@ async function generateThreadNameForNewThread({ runtime, request, agentId, sourc
54
54
  threadId: thread.id,
55
55
  userId,
56
56
  agentId,
57
- updates: { name: generatedTitle ?? FALLBACK_THREAD_TITLE }
57
+ updates: { name: generatedTitle ?? deriveFallbackTitleFromMessages(sourceInput.messages) }
58
58
  });
59
59
  }
60
60
  async function runTitleGenerationAttempt(params) {
@@ -131,12 +131,26 @@ function normalizeGeneratedTitle(rawTitle) {
131
131
  } catch {
132
132
  if (jsonLike) return null;
133
133
  }
134
- candidate = candidate.replace(/^["'`]+|["'`]+$/g, "").replace(/[*_#[\]()!~>|]+/g, "").replace(/[.!?,;:]+$/g, "").replace(/\s+/g, " ").trim();
134
+ candidate = cleanupTitleText(candidate);
135
135
  if (!candidate) return null;
136
136
  if (candidate.length > MAX_TITLE_LENGTH) candidate = candidate.slice(0, MAX_TITLE_LENGTH).trim();
137
137
  if (candidate.split(/\s+/).length > MAX_TITLE_WORDS) return null;
138
138
  return candidate;
139
139
  }
140
+ function cleanupTitleText(text) {
141
+ return text.replace(/^["'`]+|["'`]+$/g, "").replace(/[*_#[\]()!~>|]+/g, "").replace(/[.!?,;:]+$/g, "").replace(/\s+/g, " ").trim();
142
+ }
143
+ function deriveFallbackTitleFromMessages(messages) {
144
+ for (const message of messages ?? []) {
145
+ if (message.role !== "user") continue;
146
+ const cleaned = cleanupTitleText(stringifyMessageContent(message.content));
147
+ if (!cleaned) continue;
148
+ let title = cleaned.split(/\s+/).slice(0, MAX_TITLE_WORDS).join(" ");
149
+ if (title.length > MAX_TITLE_LENGTH) title = title.slice(0, MAX_TITLE_LENGTH).trim();
150
+ return title || FALLBACK_THREAD_TITLE;
151
+ }
152
+ return FALLBACK_THREAD_TITLE;
153
+ }
140
154
  function selectGeneratedTitleFromMessages(messages) {
141
155
  for (let index = messages.length - 1; index >= 0; index--) {
142
156
  const message = messages[index];
@@ -1 +1 @@
1
- {"version":3,"file":"thread-names.mjs","names":["randomUUID"],"sources":["../../../../../src/v2/runtime/handlers/intelligence/thread-names.ts"],"sourcesContent":["import type { Message, RunAgentInput } from \"@ag-ui/client\";\nimport { AbstractAgent } 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: { name: generatedTitle ?? FALLBACK_THREAD_TITLE },\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 = candidate\n .replace(/^[\"'`]+|[\"'`]+$/g, \"\")\n .replace(/[*_#[\\]()!~>|]+/g, \"\")\n .replace(/[.!?,;:]+$/g, \"\")\n .replace(/\\s+/g, \" \")\n .trim();\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 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":["randomUUID"],"sources":["../../../../../src/v2/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":";;;;;;;AAWA,MAAM,4BAA4B;CAChC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC,KAAK,KAAK;AAEZ,MAAM,mBAAmB;AACzB,MAAM,kBAAkB;AACxB,MAAM,0BAA0B;AAChC,MAAM,gCAAgC;AACtC,MAAM,wBAAwB;AAW9B,eAAsB,+BAA+B,EACnD,SACA,SACA,SACA,aACA,QACA,UAC0C;AAC1C,KAAI,CAAC,QAAQ,uBAAuB,cAAc,OAAO,KAAK,CAC5D;CAGF,MAAM,SAAS,uBAAuB,YAAY,SAAS;AAC3D,KAAI,CAAC,OACH;CAGF,IAAI,iBAAgC;AAEpC,MAAK,IAAI,UAAU,GAAG,WAAW,+BAA+B,UAC9D,KAAI;AACF,mBAAiB,MAAM,0BAA0B;GAC/C;GACA;GACA;GACA,UAAU,OAAO;GACjB;GACD,CAAC;AAEF,MAAI,eACF;AAGF,SAAO,KACL;GAAE;GAAS;GAAS,UAAU,OAAO;GAAI,EACzC,4DACD;UACM,OAAO;AACd,SAAO,KACL;GAAE,KAAK;GAAO;GAAS;GAAS,UAAU,OAAO;GAAI,EACrD,wCACD;;AAIL,OAAM,QAAQ,aAAa,aAAa;EACtC,UAAU,OAAO;EACjB;EACA;EACA,SAAS,EACP,MACE,kBAAkB,gCAAgC,YAAY,SAAS,EAC1E;EACF,CAAC;;AAGJ,eAAe,0BAA0B,QAMd;CACzB,MAAM,EAAE,SAAS,SAAS,SAAS,UAAU,WAAW;CACxD,MAAM,QAAQ,MAAM,qBAAqB,SAAS,SAAS,QAAQ;AACnE,KAAI,kBAAkB,MAAM,EAAE;AAC5B,SAAO,KACL;GAAE;GAAS;GAAU,EACrB,+DACD;AACD,SAAO;;AAGT,0BAAyB;EACvB;EACA;EACA;EACA;EACD,CAAC;CAEF,MAAM,WAAsB,CAC1B;EACE,IAAIA,cAAY;EAChB,MAAM;EACN,SAAS;EACV,EACD;EACE,IAAIA,cAAY;EAChB,MAAM;EACN,SAAS;EACV,CACF;AAED,OAAM,YAAY,SAAS;AAC3B,OAAM,SAAS,EAAE,CAAC;AAClB,OAAM,WAAWA,cAAY;CAG7B,MAAM,EAAE,gBAAgB,MAAM,MAAM,SAAS;EAC3C,OAAO,EAAE;EACT,SAAS,EAAE;EACX,gBAAgB,EAAE;EACnB,CAAC;AAEF,QAAO,iCAAiC,YAAY;;AAGtD,SAAS,uBACP,UACe;CACf,MAAM,cAAc,YAAY,EAAE,EAC/B,QAAQ,YACP;EAAC;EAAQ;EAAa;EAAU;EAAY,CAAC,SAAS,QAAQ,KAAK,CACpE,CACA,KAAK,YAAY;EAChB,MAAM,UAAU,wBAAwB,QAAQ,QAAQ;AACxD,MAAI,CAAC,QACH,QAAO;AAGT,SAAO,GAAG,QAAQ,KAAK,IAAI;GAC3B,CACD,QAAQ,YAA+B,CAAC,CAAC,QAAQ,CACjD,MAAM,CAAC,wBAAwB;AAElC,KAAI,WAAW,WAAW,EACxB,QAAO;AAGT,QAAO;EACL;EACA,WAAW,KAAK,KAAK;EACrB;EACD,CAAC,KAAK,OAAO;;AAGhB,SAAS,wBAAwB,SAAqC;AACpE,KAAI,OAAO,YAAY,SACrB,QAAO,QAAQ,MAAM;AAGvB,KAAI,WAAW,KACb,QAAO;AAGT,KAAI;AACF,SAAO,KAAK,UAAU,QAAQ,CAAC,MAAM;SAC/B;AACN,SAAO;;;AAIX,SAAS,wBAAwB,UAAiC;CAChE,IAAI,YAAY,SAAS,MAAM;AAC/B,KAAI,CAAC,UACH,QAAO;AAGT,aAAY,UACT,QAAQ,qBAAqB,GAAG,CAChC,QAAQ,WAAW,GAAG,CACtB,MAAM;CAET,MAAM,WAAW,WAAW,UAAU;AAEtC,KAAI;EACF,MAAM,SAAS,KAAK,MAAM,UAAU;AACpC,MAAI,OAAO,OAAO,UAAU,SAC1B,aAAY,OAAO;WACV,SACT,QAAO;SAEH;AACN,MAAI,SACF,QAAO;;AAIX,aAAY,iBAAiB,UAAU;AAEvC,KAAI,CAAC,UACH,QAAO;AAGT,KAAI,UAAU,SAAS,iBACrB,aAAY,UAAU,MAAM,GAAG,iBAAiB,CAAC,MAAM;AAGzD,KAAI,UAAU,MAAM,MAAM,CAAC,SAAS,gBAClC,QAAO;AAGT,QAAO;;AAGT,SAAS,iBAAiB,MAAsB;AAC9C,QAAO,KACJ,QAAQ,oBAAoB,GAAG,CAC/B,QAAQ,oBAAoB,GAAG,CAC/B,QAAQ,eAAe,GAAG,CAC1B,QAAQ,QAAQ,IAAI,CACpB,MAAM;;AAGX,SAAS,gCACP,UACQ;AACR,MAAK,MAAM,WAAW,YAAY,EAAE,EAAE;AACpC,MAAI,QAAQ,SAAS,OACnB;EAGF,MAAM,UAAU,iBAAiB,wBAAwB,QAAQ,QAAQ,CAAC;AAC1E,MAAI,CAAC,QACH;EAGF,IAAI,QAAQ,QAAQ,MAAM,MAAM,CAAC,MAAM,GAAG,gBAAgB,CAAC,KAAK,IAAI;AACpE,MAAI,MAAM,SAAS,iBACjB,SAAQ,MAAM,MAAM,GAAG,iBAAiB,CAAC,MAAM;AAGjD,SAAO,SAAS;;AAGlB,QAAO;;AAGT,SAAS,iCAAiC,UAAoC;AAC5E,MAAK,IAAI,QAAQ,SAAS,SAAS,GAAG,SAAS,GAAG,SAAS;EACzD,MAAM,UAAU,SAAS;AACzB,MAAI,QAAQ,SAAS,eAAe,OAAO,QAAQ,YAAY,SAC7D;EAGF,MAAM,QAAQ,wBAAwB,QAAQ,QAAQ;AACtD,MAAI,MACF,QAAO;;AAIX,QAAO;;AAGT,SAAS,WAAW,WAA4B;AAC9C,QACG,UAAU,WAAW,IAAI,IAAI,UAAU,SAAS,IAAI,IACpD,UAAU,WAAW,IAAI,IAAI,UAAU,SAAS,IAAI;;AAIzD,SAAS,cAAc,MAA0C;AAC/D,QAAO,OAAO,SAAS,YAAY,KAAK,MAAM,CAAC,SAAS"}
@@ -70,6 +70,11 @@ function configureAgentForRequest(params) {
70
70
  agent.headers = require_header_utils.mergeForwardableHeaders(agent.headers, request, runtime.forwardHeadersPolicy ?? require_header_utils.resolveForwardHeadersPolicy(void 0));
71
71
  }
72
72
  /**
73
+ * Shared by the two places a run meets a middleware-less agent: before Memory
74
+ * is resolved (nothing left to resolve) and after (Memory resolved to nothing).
75
+ */
76
+ const NO_MIDDLEWARE_WARNING = "CopilotKitIntelligence.enableEnterpriseLearning is enabled, but the agent does not support middleware (no `.use()` method); Intelligence tools were not attached for this run.";
77
+ /**
73
78
  * Attach CopilotKit Intelligence's MCP tools to the agent run when
74
79
  * `CopilotKitIntelligence` was constructed with
75
80
  * `enableEnterpriseLearning: true`. Uses `@ag-ui/mcp-middleware`, so the
@@ -92,10 +97,11 @@ function configureAgentForRequest(params) {
92
97
  async function attachIntelligenceEnterpriseLearning(params) {
93
98
  const { runtime, request } = params;
94
99
  const agent = params.agent;
95
- if (!require_runtime$1.isIntelligenceRuntime(runtime) || runtime.memory === void 0 && !runtime.intelligence?.ɵisEnterpriseLearningEnabled?.()) return;
96
- if (typeof agent.use !== "function") {
97
- if (runtime.memory) return require_json_response.errorResponse("Memory is configured, but this agent does not support middleware", 500);
98
- _copilotkit_shared.logger.warn("CopilotKitIntelligence.enableEnterpriseLearning is enabled, but the agent does not support middleware (no `.use()` method); Intelligence tools were not attached for this run.");
100
+ if (!require_runtime$1.isIntelligenceRuntime(runtime)) return;
101
+ const learningEnabled = runtime.intelligence?.ɵisEnterpriseLearningEnabled?.() === true;
102
+ if (runtime.memory === void 0 && !learningEnabled) return;
103
+ if (runtime.memory === void 0 && typeof agent.use !== "function") {
104
+ _copilotkit_shared.logger.warn(NO_MIDDLEWARE_WARNING);
99
105
  return;
100
106
  }
101
107
  const userResult = await require_resolve_intelligence_user.resolveIntelligenceUser({
@@ -105,6 +111,13 @@ async function attachIntelligenceEnterpriseLearning(params) {
105
111
  if (userResult instanceof Response) return userResult;
106
112
  const access = await require_memory_policy.resolveWebMemory(runtime, request, userResult, "agent");
107
113
  if (access instanceof Response) return access;
114
+ const memoryGranted = runtime.memory !== void 0 && require_memory_policy.grantAllowsMemory(access.grant);
115
+ if (!memoryGranted && !learningEnabled) return;
116
+ if (typeof agent.use !== "function") {
117
+ if (memoryGranted) return require_json_response.errorResponse("Memory is configured, but this agent does not support middleware", 500);
118
+ _copilotkit_shared.logger.warn(NO_MIDDLEWARE_WARNING);
119
+ return;
120
+ }
108
121
  agent.use(new _ag_ui_mcp_middleware.MCPMiddleware([{
109
122
  type: "http",
110
123
  url: `${runtime.intelligence.ɵgetApiUrl()}/mcp`,
@@ -1 +1 @@
1
- {"version":3,"file":"agent-utils.cjs","names":["resolveAgents","isA2UIEnabled","A2UIMiddleware","isIntelligenceRuntime","resolveMcpAppsServers","MCPAppsMiddleware","OpenGenerativeUIMiddleware","mergeForwardableHeaders","resolveForwardHeadersPolicy","errorResponse","resolveIntelligenceUser","resolveWebMemory","MCPMiddleware","INTELLIGENCE_USER_ID_HEADER","INTELLIGENCE_MEMORY_GRANT_HEADER","RunAgentInputSchema"],"sources":["../../../../../src/v2/runtime/handlers/shared/agent-utils.ts"],"sourcesContent":["import type { AbstractAgent, RunAgentInput } from \"@ag-ui/client\";\nimport { RunAgentInputSchema } from \"@ag-ui/client\";\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 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 { 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 /** 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 // 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 * 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 (\n !isIntelligenceRuntime(runtime) ||\n (runtime.memory === undefined &&\n !runtime.intelligence?.ɵisEnterpriseLearningEnabled?.())\n ) {\n return;\n }\n\n // Enterprise learning is enabled, but this agent's framework can't take\n // middleware — surface it rather than silently shipping a run with none\n // of the tools the operator opted into.\n if (typeof agent.use !== \"function\") {\n if (runtime.memory) {\n return errorResponse(\n \"Memory is configured, but this agent does not support middleware\",\n 500,\n );\n }\n logger.warn(\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 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 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\nexport async function parseRunRequest(\n request: Request,\n): Promise<RunAgentInput | Response> {\n try {\n const requestBody = await request.json();\n return RunAgentInputSchema.parse(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 = RunAgentInputSchema.parse(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","mergeForwardableHeaders","resolveForwardHeadersPolicy","resolveIntelligenceUser","resolveWebMemory","grantAllowsMemory","errorResponse","MCPMiddleware","INTELLIGENCE_USER_ID_HEADER","INTELLIGENCE_MEMORY_GRANT_HEADER","RunAgentInputSchema"],"sources":["../../../../../src/v2/runtime/handlers/shared/agent-utils.ts"],"sourcesContent":["import type { AbstractAgent, RunAgentInput } from \"@ag-ui/client\";\nimport { RunAgentInputSchema } from \"@ag-ui/client\";\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 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 /** 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 // 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\nexport async function parseRunRequest(\n request: Request,\n): Promise<RunAgentInput | Response> {\n try {\n const requestBody = await request.json();\n return RunAgentInputSchema.parse(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 = RunAgentInputSchema.parse(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,7 @@ import { INTELLIGENCE_MEMORY_GRANT_HEADER, INTELLIGENCE_USER_ID_HEADER } from ".
5
5
  import { resolveMcpAppsServers } from "./mcp-apps-servers.mjs";
6
6
  import { errorResponse } from "./json-response.mjs";
7
7
  import { resolveIntelligenceUser } from "./resolve-intelligence-user.mjs";
8
- import { resolveWebMemory } from "./memory-policy.mjs";
8
+ import { grantAllowsMemory, resolveWebMemory } from "./memory-policy.mjs";
9
9
  import { logger } from "@copilotkit/shared";
10
10
  import { RunAgentInputSchema } from "@ag-ui/client";
11
11
  import { MCPMiddleware } from "@ag-ui/mcp-middleware";
@@ -69,6 +69,11 @@ function configureAgentForRequest(params) {
69
69
  agent.headers = mergeForwardableHeaders(agent.headers, request, runtime.forwardHeadersPolicy ?? resolveForwardHeadersPolicy(void 0));
70
70
  }
71
71
  /**
72
+ * Shared by the two places a run meets a middleware-less agent: before Memory
73
+ * is resolved (nothing left to resolve) and after (Memory resolved to nothing).
74
+ */
75
+ const NO_MIDDLEWARE_WARNING = "CopilotKitIntelligence.enableEnterpriseLearning is enabled, but the agent does not support middleware (no `.use()` method); Intelligence tools were not attached for this run.";
76
+ /**
72
77
  * Attach CopilotKit Intelligence's MCP tools to the agent run when
73
78
  * `CopilotKitIntelligence` was constructed with
74
79
  * `enableEnterpriseLearning: true`. Uses `@ag-ui/mcp-middleware`, so the
@@ -91,10 +96,11 @@ function configureAgentForRequest(params) {
91
96
  async function attachIntelligenceEnterpriseLearning(params) {
92
97
  const { runtime, request } = params;
93
98
  const agent = params.agent;
94
- if (!isIntelligenceRuntime(runtime) || runtime.memory === void 0 && !runtime.intelligence?.ɵisEnterpriseLearningEnabled?.()) return;
95
- if (typeof agent.use !== "function") {
96
- if (runtime.memory) return errorResponse("Memory is configured, but this agent does not support middleware", 500);
97
- logger.warn("CopilotKitIntelligence.enableEnterpriseLearning is enabled, but the agent does not support middleware (no `.use()` method); Intelligence tools were not attached for this run.");
99
+ if (!isIntelligenceRuntime(runtime)) return;
100
+ const learningEnabled = runtime.intelligence?.ɵisEnterpriseLearningEnabled?.() === true;
101
+ if (runtime.memory === void 0 && !learningEnabled) return;
102
+ if (runtime.memory === void 0 && typeof agent.use !== "function") {
103
+ logger.warn(NO_MIDDLEWARE_WARNING);
98
104
  return;
99
105
  }
100
106
  const userResult = await resolveIntelligenceUser({
@@ -104,6 +110,13 @@ async function attachIntelligenceEnterpriseLearning(params) {
104
110
  if (userResult instanceof Response) return userResult;
105
111
  const access = await resolveWebMemory(runtime, request, userResult, "agent");
106
112
  if (access instanceof Response) return access;
113
+ const memoryGranted = runtime.memory !== void 0 && grantAllowsMemory(access.grant);
114
+ if (!memoryGranted && !learningEnabled) return;
115
+ if (typeof agent.use !== "function") {
116
+ if (memoryGranted) return errorResponse("Memory is configured, but this agent does not support middleware", 500);
117
+ logger.warn(NO_MIDDLEWARE_WARNING);
118
+ return;
119
+ }
107
120
  agent.use(new MCPMiddleware([{
108
121
  type: "http",
109
122
  url: `${runtime.intelligence.ɵgetApiUrl()}/mcp`,
@@ -1 +1 @@
1
- {"version":3,"file":"agent-utils.mjs","names":[],"sources":["../../../../../src/v2/runtime/handlers/shared/agent-utils.ts"],"sourcesContent":["import type { AbstractAgent, RunAgentInput } from \"@ag-ui/client\";\nimport { RunAgentInputSchema } from \"@ag-ui/client\";\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 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 { 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 /** 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 // 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 * 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 (\n !isIntelligenceRuntime(runtime) ||\n (runtime.memory === undefined &&\n !runtime.intelligence?.ɵisEnterpriseLearningEnabled?.())\n ) {\n return;\n }\n\n // Enterprise learning is enabled, but this agent's framework can't take\n // middleware — surface it rather than silently shipping a run with none\n // of the tools the operator opted into.\n if (typeof agent.use !== \"function\") {\n if (runtime.memory) {\n return errorResponse(\n \"Memory is configured, but this agent does not support middleware\",\n 500,\n );\n }\n logger.warn(\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 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 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\nexport async function parseRunRequest(\n request: Request,\n): Promise<RunAgentInput | Response> {\n try {\n const requestBody = await request.json();\n return RunAgentInputSchema.parse(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 = RunAgentInputSchema.parse(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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2DA,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,QAchC;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;;AAY/C,OAAM,UAAU,wBACd,MAAM,SACN,SAMA,QAAQ,wBAAwB,4BAA4B,OAAU,CACvE;;;;;;;;;;;;;;;;;;;;;;AAuBH,eAAsB,qCAAqC,QAI9B;CAC3B,MAAM,EAAE,SAAS,YAAY;CAC7B,MAAM,QAAQ,OAAO;AAErB,KACE,CAAC,sBAAsB,QAAQ,IAC9B,QAAQ,WAAW,UAClB,CAAC,QAAQ,cAAc,gCAAgC,CAEzD;AAMF,KAAI,OAAO,MAAM,QAAQ,YAAY;AACnC,MAAI,QAAQ,OACV,QAAO,cACL,oEACA,IACD;AAEH,SAAO,KACL,iLAGD;AACD;;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;AAEvC,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;;AAGH,eAAsB,gBACpB,SACmC;AACnC,KAAI;EACF,MAAM,cAAc,MAAM,QAAQ,MAAM;AACxC,SAAO,oBAAoB,MAAM,YAAY;UACtC,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,oBAAoB,MAAM,YAAY;EACpD,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/v2/runtime/handlers/shared/agent-utils.ts"],"sourcesContent":["import type { AbstractAgent, RunAgentInput } from \"@ag-ui/client\";\nimport { RunAgentInputSchema } from \"@ag-ui/client\";\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 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 /** 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 // 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\nexport async function parseRunRequest(\n request: Request,\n): Promise<RunAgentInput | Response> {\n try {\n const requestBody = await request.json();\n return RunAgentInputSchema.parse(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 = RunAgentInputSchema.parse(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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"}
@@ -7,7 +7,43 @@ const ACCESS = new Set([
7
7
  "read",
8
8
  "read-write"
9
9
  ]);
10
- /** Evaluates and validates one configured web Memory policy. */
10
+ /** What a policy that declines Memory entirely resolves to. */
11
+ const NO_MEMORY = Object.freeze({
12
+ user: "none",
13
+ project: "none"
14
+ });
15
+ /**
16
+ * True when a grant asks for any Memory operation at all.
17
+ *
18
+ * The web counterpart of `hasMemoryAccess` in `@copilotkit/channels-core`, and
19
+ * deliberately the same predicate: a grant with every scope at `"none"` means
20
+ * "this request gets no Memory", NOT "refuse this request". Channels has always
21
+ * read it that way — there both scopes are optional and default to `"none"`, so
22
+ * all-none is the grant you get by writing nothing, which could not coherently
23
+ * mean refusal.
24
+ */
25
+ function grantAllowsMemory(grant) {
26
+ return grant.user !== "none" || grant.project !== "none";
27
+ }
28
+ /**
29
+ * Evaluates and validates one configured web Memory policy.
30
+ *
31
+ * Resolving is separate from ACTING on the result, because the two callers want
32
+ * opposite things from a policy that grants nothing:
33
+ *
34
+ * - An agent run wants to proceed WITHOUT Memory tools. `memory.access` is a
35
+ * Memory policy, not an authorization gate on the conversation; a runtime
36
+ * that wants to reject the request outright has `beforeRequestMiddleware`
37
+ * for exactly that. Failing the run here means a deployment that switches
38
+ * Memory off for one tenant gets no assistant at all, and the failure
39
+ * surfaces as a bare run error rather than as anything a user can read.
40
+ * - The browser Memory routes want a 403. There the caller asked for memories
41
+ * specifically, so "you may not have them" is the honest answer, and an
42
+ * empty list would imply none exist.
43
+ *
44
+ * So this returns the grant (or a Response for a genuinely broken policy), and
45
+ * each call site applies `grantAllowsMemory` to its own case.
46
+ */
11
47
  async function resolveWebMemory(runtime, request, user, consumer) {
12
48
  if (!runtime.memory) return {
13
49
  user,
@@ -22,13 +58,14 @@ async function resolveWebMemory(runtime, request, user, consumer) {
22
58
  user,
23
59
  consumer
24
60
  });
25
- if (grant === null || grant.user === "none" && grant.project === "none") return require_json_response.errorResponse("Memory access denied", 403);
26
- if (!ACCESS.has(grant.user) || !ACCESS.has(grant.project)) return require_json_response.errorResponse("Memory policy returned an invalid grant", 500);
61
+ if (grant === void 0) return require_json_response.errorResponse("Memory policy returned an invalid grant", 500);
62
+ const resolved = grant ?? NO_MEMORY;
63
+ if (!ACCESS.has(resolved.user) || !ACCESS.has(resolved.project)) return require_json_response.errorResponse("Memory policy returned an invalid grant", 500);
27
64
  return {
28
65
  user,
29
66
  grant: {
30
- user: grant.user,
31
- project: grant.project
67
+ user: resolved.user,
68
+ project: resolved.project
32
69
  }
33
70
  };
34
71
  } catch {
@@ -37,5 +74,6 @@ async function resolveWebMemory(runtime, request, user, consumer) {
37
74
  }
38
75
 
39
76
  //#endregion
77
+ exports.grantAllowsMemory = grantAllowsMemory;
40
78
  exports.resolveWebMemory = resolveWebMemory;
41
79
  //# sourceMappingURL=memory-policy.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"memory-policy.cjs","names":["errorResponse"],"sources":["../../../../../src/v2/runtime/handlers/shared/memory-policy.ts"],"sourcesContent":["import type {\n CopilotIntelligenceRuntimeLike,\n CopilotRuntimeUser,\n MemoryConsumer,\n MemoryGrant,\n} from \"../../core/runtime\";\nimport { errorResponse } from \"./json-response\";\n\nconst ACCESS = new Set([\"none\", \"read\", \"read-write\"]);\n\nexport interface ResolvedWebMemory {\n readonly user: CopilotRuntimeUser;\n readonly grant: MemoryGrant;\n}\n\n/** Evaluates and validates one configured web Memory policy. */\nexport async function resolveWebMemory(\n runtime: CopilotIntelligenceRuntimeLike,\n request: Request,\n user: CopilotRuntimeUser,\n consumer: MemoryConsumer,\n): Promise<ResolvedWebMemory | Response> {\n if (!runtime.memory) {\n return {\n user,\n grant: { user: \"read-write\", project: \"read-write\" },\n };\n }\n\n try {\n const grant = await runtime.memory.access({ request, user, consumer });\n if (grant === null || (grant.user === \"none\" && grant.project === \"none\")) {\n return errorResponse(\"Memory access denied\", 403);\n }\n if (!ACCESS.has(grant.user) || !ACCESS.has(grant.project)) {\n return errorResponse(\"Memory policy returned an invalid grant\", 500);\n }\n return { user, grant: { user: grant.user, project: grant.project } };\n } catch {\n return errorResponse(\"Memory policy failed\", 500);\n }\n}\n"],"mappings":";;;;AAQA,MAAM,SAAS,IAAI,IAAI;CAAC;CAAQ;CAAQ;CAAa,CAAC;;AAQtD,eAAsB,iBACpB,SACA,SACA,MACA,UACuC;AACvC,KAAI,CAAC,QAAQ,OACX,QAAO;EACL;EACA,OAAO;GAAE,MAAM;GAAc,SAAS;GAAc;EACrD;AAGH,KAAI;EACF,MAAM,QAAQ,MAAM,QAAQ,OAAO,OAAO;GAAE;GAAS;GAAM;GAAU,CAAC;AACtE,MAAI,UAAU,QAAS,MAAM,SAAS,UAAU,MAAM,YAAY,OAChE,QAAOA,oCAAc,wBAAwB,IAAI;AAEnD,MAAI,CAAC,OAAO,IAAI,MAAM,KAAK,IAAI,CAAC,OAAO,IAAI,MAAM,QAAQ,CACvD,QAAOA,oCAAc,2CAA2C,IAAI;AAEtE,SAAO;GAAE;GAAM,OAAO;IAAE,MAAM,MAAM;IAAM,SAAS,MAAM;IAAS;GAAE;SAC9D;AACN,SAAOA,oCAAc,wBAAwB,IAAI"}
1
+ {"version":3,"file":"memory-policy.cjs","names":["errorResponse"],"sources":["../../../../../src/v2/runtime/handlers/shared/memory-policy.ts"],"sourcesContent":["import type {\n CopilotIntelligenceRuntimeLike,\n CopilotRuntimeUser,\n MemoryConsumer,\n MemoryGrant,\n} from \"../../core/runtime\";\nimport { errorResponse } from \"./json-response\";\n\nconst ACCESS = new Set([\"none\", \"read\", \"read-write\"]);\n\n/** What a policy that declines Memory entirely resolves to. */\nconst NO_MEMORY: MemoryGrant = Object.freeze({\n user: \"none\",\n project: \"none\",\n});\n\nexport interface ResolvedWebMemory {\n readonly user: CopilotRuntimeUser;\n readonly grant: MemoryGrant;\n}\n\n/**\n * True when a grant asks for any Memory operation at all.\n *\n * The web counterpart of `hasMemoryAccess` in `@copilotkit/channels-core`, and\n * deliberately the same predicate: a grant with every scope at `\"none\"` means\n * \"this request gets no Memory\", NOT \"refuse this request\". Channels has always\n * read it that way — there both scopes are optional and default to `\"none\"`, so\n * all-none is the grant you get by writing nothing, which could not coherently\n * mean refusal.\n */\nexport function grantAllowsMemory(grant: MemoryGrant): boolean {\n return grant.user !== \"none\" || grant.project !== \"none\";\n}\n\n/**\n * Evaluates and validates one configured web Memory policy.\n *\n * Resolving is separate from ACTING on the result, because the two callers want\n * opposite things from a policy that grants nothing:\n *\n * - An agent run wants to proceed WITHOUT Memory tools. `memory.access` is a\n * Memory policy, not an authorization gate on the conversation; a runtime\n * that wants to reject the request outright has `beforeRequestMiddleware`\n * for exactly that. Failing the run here means a deployment that switches\n * Memory off for one tenant gets no assistant at all, and the failure\n * surfaces as a bare run error rather than as anything a user can read.\n * - The browser Memory routes want a 403. There the caller asked for memories\n * specifically, so \"you may not have them\" is the honest answer, and an\n * empty list would imply none exist.\n *\n * So this returns the grant (or a Response for a genuinely broken policy), and\n * each call site applies `grantAllowsMemory` to its own case.\n */\nexport async function resolveWebMemory(\n runtime: CopilotIntelligenceRuntimeLike,\n request: Request,\n user: CopilotRuntimeUser,\n consumer: MemoryConsumer,\n): Promise<ResolvedWebMemory | Response> {\n if (!runtime.memory) {\n return {\n user,\n grant: { user: \"read-write\", project: \"read-write\" },\n };\n }\n\n try {\n const grant = await runtime.memory.access({ request, user, consumer });\n // `null` is the policy declining to grant anything, which is the same\n // outcome as an explicit all-none grant — not a distinct third state.\n //\n // `undefined` is NOT that. The contract is `MemoryGrant | null`, so a\n // missing return is a policy that is broken rather than restrictive — a\n // JavaScript caller who forgot one, or a branch that falls off the end.\n // Reading it as \"grant nothing\" would switch Memory off silently for the\n // exact deployments least able to notice; it fails loudly instead.\n if (grant === undefined) {\n return errorResponse(\"Memory policy returned an invalid grant\", 500);\n }\n const resolved = grant ?? NO_MEMORY;\n if (!ACCESS.has(resolved.user) || !ACCESS.has(resolved.project)) {\n return errorResponse(\"Memory policy returned an invalid grant\", 500);\n }\n return { user, grant: { user: resolved.user, project: resolved.project } };\n } catch {\n return errorResponse(\"Memory policy failed\", 500);\n }\n}\n"],"mappings":";;;;AAQA,MAAM,SAAS,IAAI,IAAI;CAAC;CAAQ;CAAQ;CAAa,CAAC;;AAGtD,MAAM,YAAyB,OAAO,OAAO;CAC3C,MAAM;CACN,SAAS;CACV,CAAC;;;;;;;;;;;AAiBF,SAAgB,kBAAkB,OAA6B;AAC7D,QAAO,MAAM,SAAS,UAAU,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;AAsBpD,eAAsB,iBACpB,SACA,SACA,MACA,UACuC;AACvC,KAAI,CAAC,QAAQ,OACX,QAAO;EACL;EACA,OAAO;GAAE,MAAM;GAAc,SAAS;GAAc;EACrD;AAGH,KAAI;EACF,MAAM,QAAQ,MAAM,QAAQ,OAAO,OAAO;GAAE;GAAS;GAAM;GAAU,CAAC;AAStE,MAAI,UAAU,OACZ,QAAOA,oCAAc,2CAA2C,IAAI;EAEtE,MAAM,WAAW,SAAS;AAC1B,MAAI,CAAC,OAAO,IAAI,SAAS,KAAK,IAAI,CAAC,OAAO,IAAI,SAAS,QAAQ,CAC7D,QAAOA,oCAAc,2CAA2C,IAAI;AAEtE,SAAO;GAAE;GAAM,OAAO;IAAE,MAAM,SAAS;IAAM,SAAS,SAAS;IAAS;GAAE;SACpE;AACN,SAAOA,oCAAc,wBAAwB,IAAI"}
@@ -7,7 +7,43 @@ const ACCESS = new Set([
7
7
  "read",
8
8
  "read-write"
9
9
  ]);
10
- /** Evaluates and validates one configured web Memory policy. */
10
+ /** What a policy that declines Memory entirely resolves to. */
11
+ const NO_MEMORY = Object.freeze({
12
+ user: "none",
13
+ project: "none"
14
+ });
15
+ /**
16
+ * True when a grant asks for any Memory operation at all.
17
+ *
18
+ * The web counterpart of `hasMemoryAccess` in `@copilotkit/channels-core`, and
19
+ * deliberately the same predicate: a grant with every scope at `"none"` means
20
+ * "this request gets no Memory", NOT "refuse this request". Channels has always
21
+ * read it that way — there both scopes are optional and default to `"none"`, so
22
+ * all-none is the grant you get by writing nothing, which could not coherently
23
+ * mean refusal.
24
+ */
25
+ function grantAllowsMemory(grant) {
26
+ return grant.user !== "none" || grant.project !== "none";
27
+ }
28
+ /**
29
+ * Evaluates and validates one configured web Memory policy.
30
+ *
31
+ * Resolving is separate from ACTING on the result, because the two callers want
32
+ * opposite things from a policy that grants nothing:
33
+ *
34
+ * - An agent run wants to proceed WITHOUT Memory tools. `memory.access` is a
35
+ * Memory policy, not an authorization gate on the conversation; a runtime
36
+ * that wants to reject the request outright has `beforeRequestMiddleware`
37
+ * for exactly that. Failing the run here means a deployment that switches
38
+ * Memory off for one tenant gets no assistant at all, and the failure
39
+ * surfaces as a bare run error rather than as anything a user can read.
40
+ * - The browser Memory routes want a 403. There the caller asked for memories
41
+ * specifically, so "you may not have them" is the honest answer, and an
42
+ * empty list would imply none exist.
43
+ *
44
+ * So this returns the grant (or a Response for a genuinely broken policy), and
45
+ * each call site applies `grantAllowsMemory` to its own case.
46
+ */
11
47
  async function resolveWebMemory(runtime, request, user, consumer) {
12
48
  if (!runtime.memory) return {
13
49
  user,
@@ -22,13 +58,14 @@ async function resolveWebMemory(runtime, request, user, consumer) {
22
58
  user,
23
59
  consumer
24
60
  });
25
- if (grant === null || grant.user === "none" && grant.project === "none") return errorResponse("Memory access denied", 403);
26
- if (!ACCESS.has(grant.user) || !ACCESS.has(grant.project)) return errorResponse("Memory policy returned an invalid grant", 500);
61
+ if (grant === void 0) return errorResponse("Memory policy returned an invalid grant", 500);
62
+ const resolved = grant ?? NO_MEMORY;
63
+ if (!ACCESS.has(resolved.user) || !ACCESS.has(resolved.project)) return errorResponse("Memory policy returned an invalid grant", 500);
27
64
  return {
28
65
  user,
29
66
  grant: {
30
- user: grant.user,
31
- project: grant.project
67
+ user: resolved.user,
68
+ project: resolved.project
32
69
  }
33
70
  };
34
71
  } catch {
@@ -37,5 +74,5 @@ async function resolveWebMemory(runtime, request, user, consumer) {
37
74
  }
38
75
 
39
76
  //#endregion
40
- export { resolveWebMemory };
77
+ export { grantAllowsMemory, resolveWebMemory };
41
78
  //# sourceMappingURL=memory-policy.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"memory-policy.mjs","names":[],"sources":["../../../../../src/v2/runtime/handlers/shared/memory-policy.ts"],"sourcesContent":["import type {\n CopilotIntelligenceRuntimeLike,\n CopilotRuntimeUser,\n MemoryConsumer,\n MemoryGrant,\n} from \"../../core/runtime\";\nimport { errorResponse } from \"./json-response\";\n\nconst ACCESS = new Set([\"none\", \"read\", \"read-write\"]);\n\nexport interface ResolvedWebMemory {\n readonly user: CopilotRuntimeUser;\n readonly grant: MemoryGrant;\n}\n\n/** Evaluates and validates one configured web Memory policy. */\nexport async function resolveWebMemory(\n runtime: CopilotIntelligenceRuntimeLike,\n request: Request,\n user: CopilotRuntimeUser,\n consumer: MemoryConsumer,\n): Promise<ResolvedWebMemory | Response> {\n if (!runtime.memory) {\n return {\n user,\n grant: { user: \"read-write\", project: \"read-write\" },\n };\n }\n\n try {\n const grant = await runtime.memory.access({ request, user, consumer });\n if (grant === null || (grant.user === \"none\" && grant.project === \"none\")) {\n return errorResponse(\"Memory access denied\", 403);\n }\n if (!ACCESS.has(grant.user) || !ACCESS.has(grant.project)) {\n return errorResponse(\"Memory policy returned an invalid grant\", 500);\n }\n return { user, grant: { user: grant.user, project: grant.project } };\n } catch {\n return errorResponse(\"Memory policy failed\", 500);\n }\n}\n"],"mappings":";;;;AAQA,MAAM,SAAS,IAAI,IAAI;CAAC;CAAQ;CAAQ;CAAa,CAAC;;AAQtD,eAAsB,iBACpB,SACA,SACA,MACA,UACuC;AACvC,KAAI,CAAC,QAAQ,OACX,QAAO;EACL;EACA,OAAO;GAAE,MAAM;GAAc,SAAS;GAAc;EACrD;AAGH,KAAI;EACF,MAAM,QAAQ,MAAM,QAAQ,OAAO,OAAO;GAAE;GAAS;GAAM;GAAU,CAAC;AACtE,MAAI,UAAU,QAAS,MAAM,SAAS,UAAU,MAAM,YAAY,OAChE,QAAO,cAAc,wBAAwB,IAAI;AAEnD,MAAI,CAAC,OAAO,IAAI,MAAM,KAAK,IAAI,CAAC,OAAO,IAAI,MAAM,QAAQ,CACvD,QAAO,cAAc,2CAA2C,IAAI;AAEtE,SAAO;GAAE;GAAM,OAAO;IAAE,MAAM,MAAM;IAAM,SAAS,MAAM;IAAS;GAAE;SAC9D;AACN,SAAO,cAAc,wBAAwB,IAAI"}
1
+ {"version":3,"file":"memory-policy.mjs","names":[],"sources":["../../../../../src/v2/runtime/handlers/shared/memory-policy.ts"],"sourcesContent":["import type {\n CopilotIntelligenceRuntimeLike,\n CopilotRuntimeUser,\n MemoryConsumer,\n MemoryGrant,\n} from \"../../core/runtime\";\nimport { errorResponse } from \"./json-response\";\n\nconst ACCESS = new Set([\"none\", \"read\", \"read-write\"]);\n\n/** What a policy that declines Memory entirely resolves to. */\nconst NO_MEMORY: MemoryGrant = Object.freeze({\n user: \"none\",\n project: \"none\",\n});\n\nexport interface ResolvedWebMemory {\n readonly user: CopilotRuntimeUser;\n readonly grant: MemoryGrant;\n}\n\n/**\n * True when a grant asks for any Memory operation at all.\n *\n * The web counterpart of `hasMemoryAccess` in `@copilotkit/channels-core`, and\n * deliberately the same predicate: a grant with every scope at `\"none\"` means\n * \"this request gets no Memory\", NOT \"refuse this request\". Channels has always\n * read it that way — there both scopes are optional and default to `\"none\"`, so\n * all-none is the grant you get by writing nothing, which could not coherently\n * mean refusal.\n */\nexport function grantAllowsMemory(grant: MemoryGrant): boolean {\n return grant.user !== \"none\" || grant.project !== \"none\";\n}\n\n/**\n * Evaluates and validates one configured web Memory policy.\n *\n * Resolving is separate from ACTING on the result, because the two callers want\n * opposite things from a policy that grants nothing:\n *\n * - An agent run wants to proceed WITHOUT Memory tools. `memory.access` is a\n * Memory policy, not an authorization gate on the conversation; a runtime\n * that wants to reject the request outright has `beforeRequestMiddleware`\n * for exactly that. Failing the run here means a deployment that switches\n * Memory off for one tenant gets no assistant at all, and the failure\n * surfaces as a bare run error rather than as anything a user can read.\n * - The browser Memory routes want a 403. There the caller asked for memories\n * specifically, so \"you may not have them\" is the honest answer, and an\n * empty list would imply none exist.\n *\n * So this returns the grant (or a Response for a genuinely broken policy), and\n * each call site applies `grantAllowsMemory` to its own case.\n */\nexport async function resolveWebMemory(\n runtime: CopilotIntelligenceRuntimeLike,\n request: Request,\n user: CopilotRuntimeUser,\n consumer: MemoryConsumer,\n): Promise<ResolvedWebMemory | Response> {\n if (!runtime.memory) {\n return {\n user,\n grant: { user: \"read-write\", project: \"read-write\" },\n };\n }\n\n try {\n const grant = await runtime.memory.access({ request, user, consumer });\n // `null` is the policy declining to grant anything, which is the same\n // outcome as an explicit all-none grant — not a distinct third state.\n //\n // `undefined` is NOT that. The contract is `MemoryGrant | null`, so a\n // missing return is a policy that is broken rather than restrictive — a\n // JavaScript caller who forgot one, or a branch that falls off the end.\n // Reading it as \"grant nothing\" would switch Memory off silently for the\n // exact deployments least able to notice; it fails loudly instead.\n if (grant === undefined) {\n return errorResponse(\"Memory policy returned an invalid grant\", 500);\n }\n const resolved = grant ?? NO_MEMORY;\n if (!ACCESS.has(resolved.user) || !ACCESS.has(resolved.project)) {\n return errorResponse(\"Memory policy returned an invalid grant\", 500);\n }\n return { user, grant: { user: resolved.user, project: resolved.project } };\n } catch {\n return errorResponse(\"Memory policy failed\", 500);\n }\n}\n"],"mappings":";;;;AAQA,MAAM,SAAS,IAAI,IAAI;CAAC;CAAQ;CAAQ;CAAa,CAAC;;AAGtD,MAAM,YAAyB,OAAO,OAAO;CAC3C,MAAM;CACN,SAAS;CACV,CAAC;;;;;;;;;;;AAiBF,SAAgB,kBAAkB,OAA6B;AAC7D,QAAO,MAAM,SAAS,UAAU,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;AAsBpD,eAAsB,iBACpB,SACA,SACA,MACA,UACuC;AACvC,KAAI,CAAC,QAAQ,OACX,QAAO;EACL;EACA,OAAO;GAAE,MAAM;GAAc,SAAS;GAAc;EACrD;AAGH,KAAI;EACF,MAAM,QAAQ,MAAM,QAAQ,OAAO,OAAO;GAAE;GAAS;GAAM;GAAU,CAAC;AAStE,MAAI,UAAU,OACZ,QAAO,cAAc,2CAA2C,IAAI;EAEtE,MAAM,WAAW,SAAS;AAC1B,MAAI,CAAC,OAAO,IAAI,SAAS,KAAK,IAAI,CAAC,OAAO,IAAI,SAAS,QAAQ,CAC7D,QAAO,cAAc,2CAA2C,IAAI;AAEtE,SAAO;GAAE;GAAM,OAAO;IAAE,MAAM,SAAS;IAAM,SAAS,SAAS;IAAS;GAAE;SACpE;AACN,SAAO,cAAc,wBAAwB,IAAI"}
@@ -1,7 +1,7 @@
1
1
 
2
2
  import { TranscribeFileOptions, TranscriptionService } from "./transcription-service/transcription-service.cjs";
3
3
  import { AgentRunner, AgentRunnerConnectRequest, AgentRunnerIsRunningRequest, AgentRunnerRunRequest, AgentRunnerStopRequest, LocalThreadEndpointRecord, LocalThreadEndpointRunner, supportsLocalThreadEndpoints } from "./runner/agent-runner.cjs";
4
- import { GetLearnedSkillsSnapshotRequest, LearnedSkillsError, LearnedSkillsErrorCode, LearnedSkillsSnapshotResult } from "./intelligence-platform/learned-skills.cjs";
4
+ import { GetLearnedSkillsSnapshotRequest, GetLearnedSkillsSnapshotsRequest, LearnedSkillsBatchResult, LearnedSkillsError, LearnedSkillsErrorCode, LearnedSkillsSnapshotResult } from "./intelligence-platform/learned-skills.cjs";
5
5
  import "./intelligence-platform/index.cjs";
6
6
  import { AgentFactoryContext, AgentsConfig, AgentsFactory, CopilotIntelligenceRuntime, CopilotIntelligenceRuntimeLike, CopilotIntelligenceRuntimeOptions, CopilotRuntime, CopilotRuntimeConstructor, CopilotRuntimeLike, CopilotRuntimeMemoryConfig, CopilotRuntimeOptions, CopilotSseRuntime, CopilotSseRuntimeLike, CopilotSseRuntimeOptions, IdentifyUserCallback, McpAppsConfig, McpAppsServerConfig, MemoryAccess, MemoryConsumer, MemoryGrant, OpenGenerativeUIConfig, OpenGenerativeUIOptions, RuntimeWithDeclaredChannels, VERSION, isA2UIEnabled, isIntelligenceRuntime, resolveAgents } from "./core/runtime.cjs";
7
7
  import { CopilotRuntimeLearningConfig, CopilotRuntimeLearningContext, CopilotRuntimeUser, GetLearningContainerId, LearningContainerSelectorInput } from "./core/learning.cjs";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../../../src/v2/runtime/index.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;KAyDY,wBAAA,IAA4B,MAAA;EACtC,OAAA,EAAS,OAAA;AAAA,MACL,OAAA,CAAQ,QAAA"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../../../src/v2/runtime/index.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;KA2DY,wBAAA,IAA4B,MAAA;EACtC,OAAA,EAAS,OAAA;AAAA,MACL,OAAA,CAAQ,QAAA"}
@@ -1,7 +1,7 @@
1
1
 
2
2
  import { TranscribeFileOptions, TranscriptionService } from "./transcription-service/transcription-service.mjs";
3
3
  import { AgentRunner, AgentRunnerConnectRequest, AgentRunnerIsRunningRequest, AgentRunnerRunRequest, AgentRunnerStopRequest, LocalThreadEndpointRecord, LocalThreadEndpointRunner, supportsLocalThreadEndpoints } from "./runner/agent-runner.mjs";
4
- import { GetLearnedSkillsSnapshotRequest, LearnedSkillsError, LearnedSkillsErrorCode, LearnedSkillsSnapshotResult } from "./intelligence-platform/learned-skills.mjs";
4
+ import { GetLearnedSkillsSnapshotRequest, GetLearnedSkillsSnapshotsRequest, LearnedSkillsBatchResult, LearnedSkillsError, LearnedSkillsErrorCode, LearnedSkillsSnapshotResult } from "./intelligence-platform/learned-skills.mjs";
5
5
  import "./intelligence-platform/index.mjs";
6
6
  import { AgentFactoryContext, AgentsConfig, AgentsFactory, CopilotIntelligenceRuntime, CopilotIntelligenceRuntimeLike, CopilotIntelligenceRuntimeOptions, CopilotRuntime, CopilotRuntimeConstructor, CopilotRuntimeLike, CopilotRuntimeMemoryConfig, CopilotRuntimeOptions, CopilotSseRuntime, CopilotSseRuntimeLike, CopilotSseRuntimeOptions, IdentifyUserCallback, McpAppsConfig, McpAppsServerConfig, MemoryAccess, MemoryConsumer, MemoryGrant, OpenGenerativeUIConfig, OpenGenerativeUIOptions, RuntimeWithDeclaredChannels, VERSION, isA2UIEnabled, isIntelligenceRuntime, resolveAgents } from "./core/runtime.mjs";
7
7
  import { CopilotRuntimeLearningConfig, CopilotRuntimeLearningContext, CopilotRuntimeUser, GetLearningContainerId, LearningContainerSelectorInput } from "./core/learning.mjs";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../../src/v2/runtime/index.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;KAyDY,wBAAA,IAA4B,MAAA;EACtC,OAAA,EAAS,OAAA;AAAA,MACL,OAAA,CAAQ,QAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../../src/v2/runtime/index.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;KA2DY,wBAAA,IAA4B,MAAA;EACtC,OAAA,EAAS,OAAA;AAAA,MACL,OAAA,CAAQ,QAAA"}