@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.
- package/README.md +28 -0
- package/dist/agent/learned-skills.cjs.map +1 -1
- package/dist/agent/learned-skills.d.cts +1 -1
- package/dist/agent/learned-skills.d.mts +1 -1
- package/dist/agent/learned-skills.mjs.map +1 -1
- package/dist/internal/learned-skills.d.cts +2 -2
- package/dist/internal/learned-skills.d.mts +2 -2
- package/dist/package.cjs +1 -1
- package/dist/package.mjs +1 -1
- package/dist/v2/index.d.cts +2 -2
- package/dist/v2/index.d.mts +2 -2
- package/dist/v2/runtime/core/fetch-handler.cjs +4 -1
- package/dist/v2/runtime/core/fetch-handler.cjs.map +1 -1
- package/dist/v2/runtime/core/fetch-handler.mjs +4 -1
- package/dist/v2/runtime/core/fetch-handler.mjs.map +1 -1
- package/dist/v2/runtime/handlers/intelligence/memories.cjs +4 -1
- package/dist/v2/runtime/handlers/intelligence/memories.cjs.map +1 -1
- package/dist/v2/runtime/handlers/intelligence/memories.mjs +5 -2
- package/dist/v2/runtime/handlers/intelligence/memories.mjs.map +1 -1
- package/dist/v2/runtime/handlers/intelligence/thread-names.cjs +16 -2
- package/dist/v2/runtime/handlers/intelligence/thread-names.cjs.map +1 -1
- package/dist/v2/runtime/handlers/intelligence/thread-names.mjs +16 -2
- package/dist/v2/runtime/handlers/intelligence/thread-names.mjs.map +1 -1
- package/dist/v2/runtime/handlers/shared/agent-utils.cjs +17 -4
- package/dist/v2/runtime/handlers/shared/agent-utils.cjs.map +1 -1
- package/dist/v2/runtime/handlers/shared/agent-utils.mjs +18 -5
- package/dist/v2/runtime/handlers/shared/agent-utils.mjs.map +1 -1
- package/dist/v2/runtime/handlers/shared/memory-policy.cjs +43 -5
- package/dist/v2/runtime/handlers/shared/memory-policy.cjs.map +1 -1
- package/dist/v2/runtime/handlers/shared/memory-policy.mjs +43 -6
- package/dist/v2/runtime/handlers/shared/memory-policy.mjs.map +1 -1
- package/dist/v2/runtime/index.d.cts +1 -1
- package/dist/v2/runtime/index.d.cts.map +1 -1
- package/dist/v2/runtime/index.d.mts +1 -1
- package/dist/v2/runtime/index.d.mts.map +1 -1
- package/dist/v2/runtime/intelligence-platform/client.cjs +80 -0
- package/dist/v2/runtime/intelligence-platform/client.cjs.map +1 -1
- package/dist/v2/runtime/intelligence-platform/client.d.cts +3 -1
- package/dist/v2/runtime/intelligence-platform/client.d.cts.map +1 -1
- package/dist/v2/runtime/intelligence-platform/client.d.mts +3 -1
- package/dist/v2/runtime/intelligence-platform/client.d.mts.map +1 -1
- package/dist/v2/runtime/intelligence-platform/client.mjs +81 -1
- package/dist/v2/runtime/intelligence-platform/client.mjs.map +1 -1
- package/dist/v2/runtime/intelligence-platform/index.d.cts +1 -1
- package/dist/v2/runtime/intelligence-platform/index.d.mts +1 -1
- package/dist/v2/runtime/intelligence-platform/learned-skills.cjs +53 -0
- package/dist/v2/runtime/intelligence-platform/learned-skills.cjs.map +1 -1
- package/dist/v2/runtime/intelligence-platform/learned-skills.d.cts +11 -1
- package/dist/v2/runtime/intelligence-platform/learned-skills.d.cts.map +1 -1
- package/dist/v2/runtime/intelligence-platform/learned-skills.d.mts +11 -1
- package/dist/v2/runtime/intelligence-platform/learned-skills.d.mts.map +1 -1
- package/dist/v2/runtime/intelligence-platform/learned-skills.mjs +53 -1
- package/dist/v2/runtime/intelligence-platform/learned-skills.mjs.map +1 -1
- package/dist/v2/runtime/intelligence-platform/skill-registry/config.cjs +24 -6
- package/dist/v2/runtime/intelligence-platform/skill-registry/config.cjs.map +1 -1
- package/dist/v2/runtime/intelligence-platform/skill-registry/config.d.cts +28 -7
- package/dist/v2/runtime/intelligence-platform/skill-registry/config.d.cts.map +1 -1
- package/dist/v2/runtime/intelligence-platform/skill-registry/config.d.mts +28 -7
- package/dist/v2/runtime/intelligence-platform/skill-registry/config.d.mts.map +1 -1
- package/dist/v2/runtime/intelligence-platform/skill-registry/config.mjs +24 -6
- package/dist/v2/runtime/intelligence-platform/skill-registry/config.mjs.map +1 -1
- package/dist/v2/runtime/intelligence-platform/skill-registry/index.d.cts +1 -1
- package/dist/v2/runtime/intelligence-platform/skill-registry/index.d.mts +1 -1
- package/dist/v2/runtime/intelligence-platform/skill-registry/registry.cjs +120 -4
- package/dist/v2/runtime/intelligence-platform/skill-registry/registry.cjs.map +1 -1
- package/dist/v2/runtime/intelligence-platform/skill-registry/registry.d.cts +8 -2
- package/dist/v2/runtime/intelligence-platform/skill-registry/registry.d.cts.map +1 -1
- package/dist/v2/runtime/intelligence-platform/skill-registry/registry.d.mts +8 -2
- package/dist/v2/runtime/intelligence-platform/skill-registry/registry.d.mts.map +1 -1
- package/dist/v2/runtime/intelligence-platform/skill-registry/registry.mjs +119 -4
- package/dist/v2/runtime/intelligence-platform/skill-registry/registry.mjs.map +1 -1
- 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 ??
|
|
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
|
|
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":"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"}
|
|
@@ -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)
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
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)
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
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":"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"}
|
|
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
|
-
/**
|
|
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 ===
|
|
26
|
-
|
|
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:
|
|
31
|
-
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
|
|
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
|
-
/**
|
|
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 ===
|
|
26
|
-
|
|
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:
|
|
31
|
-
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
|
|
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":";;;;;;;;;;;;;;;;;;;;;;;;
|
|
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":";;;;;;;;;;;;;;;;;;;;;;;;
|
|
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"}
|