@copilotkit/runtime 1.59.3 → 1.59.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/dist/agent/index.cjs +0 -18
  2. package/dist/agent/index.cjs.map +1 -1
  3. package/dist/agent/index.d.cts.map +1 -1
  4. package/dist/agent/index.d.mts.map +1 -1
  5. package/dist/agent/index.mjs +0 -18
  6. package/dist/agent/index.mjs.map +1 -1
  7. package/dist/package.cjs +4 -3
  8. package/dist/package.mjs +4 -3
  9. package/dist/v2/runtime/core/fetch-handler.cjs +5 -0
  10. package/dist/v2/runtime/core/fetch-handler.cjs.map +1 -1
  11. package/dist/v2/runtime/core/fetch-handler.d.cts.map +1 -1
  12. package/dist/v2/runtime/core/fetch-handler.d.mts.map +1 -1
  13. package/dist/v2/runtime/core/fetch-handler.mjs +5 -0
  14. package/dist/v2/runtime/core/fetch-handler.mjs.map +1 -1
  15. package/dist/v2/runtime/core/fetch-router.cjs +1 -0
  16. package/dist/v2/runtime/core/fetch-router.cjs.map +1 -1
  17. package/dist/v2/runtime/core/fetch-router.mjs +1 -0
  18. package/dist/v2/runtime/core/fetch-router.mjs.map +1 -1
  19. package/dist/v2/runtime/core/hooks.cjs.map +1 -1
  20. package/dist/v2/runtime/core/hooks.d.cts +2 -0
  21. package/dist/v2/runtime/core/hooks.d.cts.map +1 -1
  22. package/dist/v2/runtime/core/hooks.d.mts +2 -0
  23. package/dist/v2/runtime/core/hooks.d.mts.map +1 -1
  24. package/dist/v2/runtime/core/hooks.mjs.map +1 -1
  25. package/dist/v2/runtime/handlers/handle-run.cjs +5 -0
  26. package/dist/v2/runtime/handlers/handle-run.cjs.map +1 -1
  27. package/dist/v2/runtime/handlers/handle-run.mjs +6 -1
  28. package/dist/v2/runtime/handlers/handle-run.mjs.map +1 -1
  29. package/dist/v2/runtime/handlers/intelligence/annotate.cjs +84 -0
  30. package/dist/v2/runtime/handlers/intelligence/annotate.cjs.map +1 -0
  31. package/dist/v2/runtime/handlers/intelligence/annotate.mjs +83 -0
  32. package/dist/v2/runtime/handlers/intelligence/annotate.mjs.map +1 -0
  33. package/dist/v2/runtime/handlers/intelligence/run.cjs +2 -16
  34. package/dist/v2/runtime/handlers/intelligence/run.cjs.map +1 -1
  35. package/dist/v2/runtime/handlers/intelligence/run.mjs +2 -16
  36. package/dist/v2/runtime/handlers/intelligence/run.mjs.map +1 -1
  37. package/dist/v2/runtime/handlers/intelligence/thread-names.cjs +1 -1
  38. package/dist/v2/runtime/handlers/intelligence/thread-names.mjs +1 -1
  39. package/dist/v2/runtime/handlers/shared/agent-utils.cjs +47 -0
  40. package/dist/v2/runtime/handlers/shared/agent-utils.cjs.map +1 -1
  41. package/dist/v2/runtime/handlers/shared/agent-utils.mjs +48 -2
  42. package/dist/v2/runtime/handlers/shared/agent-utils.mjs.map +1 -1
  43. package/dist/v2/runtime/intelligence-platform/client.cjs +51 -11
  44. package/dist/v2/runtime/intelligence-platform/client.cjs.map +1 -1
  45. package/dist/v2/runtime/intelligence-platform/client.d.cts +81 -13
  46. package/dist/v2/runtime/intelligence-platform/client.d.cts.map +1 -1
  47. package/dist/v2/runtime/intelligence-platform/client.d.mts +81 -13
  48. package/dist/v2/runtime/intelligence-platform/client.d.mts.map +1 -1
  49. package/dist/v2/runtime/intelligence-platform/client.mjs +51 -11
  50. package/dist/v2/runtime/intelligence-platform/client.mjs.map +1 -1
  51. package/package.json +5 -4
@@ -0,0 +1 @@
1
+ {"version":3,"file":"annotate.mjs","names":[],"sources":["../../../../../src/v2/runtime/handlers/intelligence/annotate.ts"],"sourcesContent":["import { logger } from \"@copilotkit/shared\";\nimport type {\n CopilotIntelligenceRuntimeLike,\n CopilotRuntimeLike,\n} from \"../../core/runtime\";\nimport { isIntelligenceRuntime } from \"../../core/runtime\";\nimport { PlatformRequestError } from \"../../intelligence-platform/client\";\nimport { errorResponse, isHandlerResponse } from \"../shared/json-response\";\nimport { resolveIntelligenceUser } from \"../shared/resolve-intelligence-user\";\n\ninterface AnnotateHandlerParams {\n runtime: CopilotRuntimeLike;\n request: Request;\n}\n\ninterface AnnotateBody {\n /** Discriminator identifying the annotation type (e.g. `\"user_action\"`). */\n type: string;\n /** Type-specific payload. Shape varies by `type`. */\n payload?: unknown;\n /** The thread the annotation is associated with. */\n threadId: string;\n /** Caller-supplied idempotency key. Optional — platform auto-generates one when absent. */\n clientEventId?: string;\n /** ISO-8601 client-asserted timestamp. Defaults to server NOW() when absent. */\n occurredAt?: string;\n}\n\nasync function parseJsonBody(\n request: Request,\n): Promise<Record<string, unknown> | Response> {\n try {\n return (await request.json()) as Record<string, unknown>;\n } catch (error) {\n logger.error({ err: error }, \"Malformed JSON in annotate body\");\n return errorResponse(\"Invalid request body\", 400);\n }\n}\n\nfunction requireIntelligenceRuntime(\n runtime: CopilotRuntimeLike,\n): CopilotIntelligenceRuntimeLike | Response {\n if (!isIntelligenceRuntime(runtime)) {\n return errorResponse(\n \"Missing CopilotKitIntelligence configuration. annotate requires a CopilotKitIntelligence instance to be provided in CopilotRuntime options.\",\n 422,\n );\n }\n return runtime;\n}\n\nfunction isNonEmptyString(value: unknown): value is string {\n return typeof value === \"string\" && value.length > 0;\n}\n\n/**\n * `POST /annotate` handler.\n *\n * Three-tier flow:\n * recordAnnotation() (frontend lib; called by useLearnFromUserAction / useLearningContainers)\n * → POST ${runtimeUrl}/annotate\n * → this handler resolves the Intel user from BFF auth\n * → intelligence.annotate(...)\n * → PUT ${apiUrl}/connector/annotate/:clientEventId\n *\n * The frontend hook may auto-generate a UUID `clientEventId` per call\n * so retries are idempotent end-to-end (the platform collapses to the\n * original row).\n */\nexport async function handleAnnotate({\n runtime,\n request,\n}: AnnotateHandlerParams): Promise<Response> {\n const intelligenceRuntime = requireIntelligenceRuntime(runtime);\n if (isHandlerResponse(intelligenceRuntime)) return intelligenceRuntime;\n\n const body = await parseJsonBody(request);\n if (isHandlerResponse(body)) return body;\n\n const user = await resolveIntelligenceUser({\n runtime: intelligenceRuntime,\n request,\n });\n if (isHandlerResponse(user)) return user;\n\n const parsed = parseAnnotateBody(body);\n if (isHandlerResponse(parsed)) return parsed;\n\n try {\n const result = await intelligenceRuntime.intelligence.annotate({\n userId: user.id,\n threadId: parsed.threadId,\n type: parsed.type,\n payload: parsed.payload,\n clientEventId: parsed.clientEventId,\n occurredAt: parsed.occurredAt,\n });\n return new Response(JSON.stringify(result), {\n status: 200,\n headers: { \"Content-Type\": \"application/json\" },\n });\n } catch (err) {\n logger.error({ err }, \"annotate: platform call failed\");\n // Forward the platform's HTTP status when it's a client error\n // (4xx) so the SDK author sees an actionable response instead of\n // a generic 502. 5xx and non-platform errors collapse to 502\n // (\"Bad Gateway\") because the upstream is genuinely at fault.\n if (\n err instanceof PlatformRequestError &&\n err.status >= 400 &&\n err.status < 500\n ) {\n return errorResponse(err.message, err.status);\n }\n return errorResponse(\"Failed to annotate\", 502);\n }\n}\n\nfunction parseAnnotateBody(\n body: Record<string, unknown>,\n): AnnotateBody | Response {\n if (!isNonEmptyString(body.threadId)) {\n return errorResponse(\"Valid threadId is required\", 400);\n }\n if (!isNonEmptyString(body.type)) {\n return errorResponse(\"Valid type is required\", 400);\n }\n return {\n type: body.type,\n payload: body.payload,\n threadId: body.threadId,\n clientEventId: isNonEmptyString(body.clientEventId)\n ? body.clientEventId\n : undefined,\n occurredAt: isNonEmptyString(body.occurredAt) ? body.occurredAt : undefined,\n };\n}\n"],"mappings":";;;;;;;;AA4BA,eAAe,cACb,SAC6C;AAC7C,KAAI;AACF,SAAQ,MAAM,QAAQ,MAAM;UACrB,OAAO;AACd,SAAO,MAAM,EAAE,KAAK,OAAO,EAAE,kCAAkC;AAC/D,SAAO,cAAc,wBAAwB,IAAI;;;AAIrD,SAAS,2BACP,SAC2C;AAC3C,KAAI,CAAC,sBAAsB,QAAQ,CACjC,QAAO,cACL,+IACA,IACD;AAEH,QAAO;;AAGT,SAAS,iBAAiB,OAAiC;AACzD,QAAO,OAAO,UAAU,YAAY,MAAM,SAAS;;;;;;;;;;;;;;;;AAiBrD,eAAsB,eAAe,EACnC,SACA,WAC2C;CAC3C,MAAM,sBAAsB,2BAA2B,QAAQ;AAC/D,KAAI,kBAAkB,oBAAoB,CAAE,QAAO;CAEnD,MAAM,OAAO,MAAM,cAAc,QAAQ;AACzC,KAAI,kBAAkB,KAAK,CAAE,QAAO;CAEpC,MAAM,OAAO,MAAM,wBAAwB;EACzC,SAAS;EACT;EACD,CAAC;AACF,KAAI,kBAAkB,KAAK,CAAE,QAAO;CAEpC,MAAM,SAAS,kBAAkB,KAAK;AACtC,KAAI,kBAAkB,OAAO,CAAE,QAAO;AAEtC,KAAI;EACF,MAAM,SAAS,MAAM,oBAAoB,aAAa,SAAS;GAC7D,QAAQ,KAAK;GACb,UAAU,OAAO;GACjB,MAAM,OAAO;GACb,SAAS,OAAO;GAChB,eAAe,OAAO;GACtB,YAAY,OAAO;GACpB,CAAC;AACF,SAAO,IAAI,SAAS,KAAK,UAAU,OAAO,EAAE;GAC1C,QAAQ;GACR,SAAS,EAAE,gBAAgB,oBAAoB;GAChD,CAAC;UACK,KAAK;AACZ,SAAO,MAAM,EAAE,KAAK,EAAE,iCAAiC;AAKvD,MACE,eAAe,wBACf,IAAI,UAAU,OACd,IAAI,SAAS,IAEb,QAAO,cAAc,IAAI,SAAS,IAAI,OAAO;AAE/C,SAAO,cAAc,sBAAsB,IAAI;;;AAInD,SAAS,kBACP,MACyB;AACzB,KAAI,CAAC,iBAAiB,KAAK,SAAS,CAClC,QAAO,cAAc,8BAA8B,IAAI;AAEzD,KAAI,CAAC,iBAAiB,KAAK,KAAK,CAC9B,QAAO,cAAc,0BAA0B,IAAI;AAErD,QAAO;EACL,MAAM,KAAK;EACX,SAAS,KAAK;EACd,UAAU,KAAK;EACf,eAAe,iBAAiB,KAAK,cAAc,GAC/C,KAAK,gBACL;EACJ,YAAY,iBAAiB,KAAK,WAAW,GAAG,KAAK,aAAa;EACnE"}
@@ -2,8 +2,8 @@ require("reflect-metadata");
2
2
  const require_runtime = require('../../../../_virtual/_rolldown/runtime.cjs');
3
3
  const require_telemetry_client = require('../../telemetry/telemetry-client.cjs');
4
4
  const require_json_response = require('../shared/json-response.cjs');
5
- const require_thread_names = require('./thread-names.cjs');
6
5
  const require_resolve_intelligence_user = require('../shared/resolve-intelligence-user.cjs');
6
+ const require_thread_names = require('./thread-names.cjs');
7
7
  let _copilotkit_shared = require("@copilotkit/shared");
8
8
  let _ag_ui_client = require("@ag-ui/client");
9
9
 
@@ -86,24 +86,10 @@ async function handleIntelligenceRun({ runtime, request, agentId, agent, input }
86
86
  message: "Intelligence platform did not return canonical threadId, runId, and joinToken"
87
87
  }, { status: 502 });
88
88
  }
89
- const upstreamAuth = input.forwardedProps?.auth ?? {};
90
- const copilotkitIntelligenceAuth = runtime.intelligence.ɵisMcpServerEnabled?.() ? { copilotkitIntelligence: {
91
- userId,
92
- apiKey: runtime.intelligence.ɵgetApiKey(),
93
- mcpUrl: `${runtime.intelligence.ɵgetApiUrl()}/mcp`
94
- } } : {};
95
- const mergedAuth = {
96
- ...upstreamAuth,
97
- ...copilotkitIntelligenceAuth
98
- };
99
89
  const canonicalInput = {
100
90
  ...input,
101
91
  threadId: canonicalThreadId,
102
- runId: canonicalRunId,
103
- forwardedProps: {
104
- ...input.forwardedProps,
105
- ...Object.keys(mergedAuth).length > 0 ? { auth: mergedAuth } : {}
106
- }
92
+ runId: canonicalRunId
107
93
  };
108
94
  let persistedInputMessages;
109
95
  if (Array.isArray(input.messages)) try {
@@ -1 +1 @@
1
- {"version":3,"file":"run.cjs","names":["resolveIntelligenceUser","isHandlerResponse","generateThreadNameForNewThread","EventType"],"sources":["../../../../../src/v2/runtime/handlers/intelligence/run.ts"],"sourcesContent":["import type {\n AbstractAgent,\n BaseEvent,\n Message,\n RunAgentInput,\n} from \"@ag-ui/client\";\nimport { EventType } from \"@ag-ui/client\";\nimport type { CopilotIntelligenceRuntimeLike } from \"../../core/runtime\";\nimport { generateThreadNameForNewThread } from \"./thread-names\";\nimport { logger } from \"@copilotkit/shared\";\nimport { telemetry } from \"../../telemetry\";\nimport { resolveIntelligenceUser } from \"../shared/resolve-intelligence-user\";\nimport { isHandlerResponse } from \"../shared/json-response\";\nimport type { AgentRunnerRunRequest } from \"../../runner/agent-runner\";\nimport type { Observable } from \"rxjs\";\n\n/**\n * Builds browser-facing realtime connection metadata owned by the runtime.\n */\nfunction buildRealtimeConnectionInfo(params: {\n clientUrl: string;\n threadId: string;\n}): { clientUrl: string; topic: string } {\n return {\n clientUrl: params.clientUrl,\n topic: `thread:${params.threadId}`,\n };\n}\n\ninterface RunnerStartupBoundary {\n events: Observable<BaseEvent>;\n startup: Promise<void>;\n}\n\ninterface RunnerWithStartupBoundary {\n runWithStartupBoundary(request: AgentRunnerRunRequest): RunnerStartupBoundary;\n}\n\nfunction hasRunnerStartupBoundary(\n runner: CopilotIntelligenceRuntimeLike[\"runner\"],\n): runner is CopilotIntelligenceRuntimeLike[\"runner\"] &\n RunnerWithStartupBoundary {\n const candidate = runner as { runWithStartupBoundary?: unknown };\n\n return (\n typeof candidate.runWithStartupBoundary === \"function\" &&\n (Object.prototype.hasOwnProperty.call(runner, \"runWithStartupBoundary\") ||\n Object.prototype.hasOwnProperty.call(runner, \"threads\"))\n );\n}\n\ninterface HandleIntelligenceRunParams {\n runtime: CopilotIntelligenceRuntimeLike;\n request: Request;\n agentId: string;\n agent: AbstractAgent;\n input: RunAgentInput;\n}\n\nexport async function handleIntelligenceRun({\n runtime,\n request,\n agentId,\n agent,\n input,\n}: HandleIntelligenceRunParams): Promise<Response> {\n if (!runtime.intelligence) {\n return Response.json(\n {\n error: \"Intelligence not configured\",\n message: \"Intelligence mode requires a CopilotKitIntelligence\",\n },\n { status: 500 },\n );\n }\n\n const user = await resolveIntelligenceUser({ runtime, request });\n if (isHandlerResponse(user)) {\n return user;\n }\n const userId = user.id;\n\n try {\n const { thread, created } = await runtime.intelligence.getOrCreateThread({\n threadId: input.threadId,\n userId,\n agentId,\n });\n\n if (created && runtime.generateThreadNames && !thread.name?.trim()) {\n void generateThreadNameForNewThread({\n runtime,\n request,\n agentId,\n sourceInput: input,\n thread,\n userId,\n }).catch((nameError) => {\n logger.error(\"Failed to generate thread name:\", nameError);\n });\n }\n } catch (error) {\n logger.error(\"Failed to get or create thread:\", error);\n return Response.json(\n {\n error: \"Failed to initialize thread\",\n },\n { status: 502 },\n );\n }\n\n let canonicalThreadId = input.threadId;\n let canonicalRunId = input.runId;\n let joinToken: string | undefined;\n try {\n const lockResult = await runtime.intelligence.ɵacquireThreadLock({\n threadId: input.threadId,\n runId: input.runId,\n userId,\n agentId,\n ...(runtime.lockKeyPrefix !== undefined\n ? { lockKeyPrefix: runtime.lockKeyPrefix }\n : {}),\n ttlSeconds: runtime.lockTtlSeconds,\n });\n canonicalThreadId = lockResult.threadId;\n canonicalRunId = lockResult.runId;\n joinToken = lockResult.joinToken;\n } catch (error) {\n logger.error(\"Thread lock denied:\", error);\n return Response.json(\n {\n error: \"Thread lock denied\",\n },\n { status: 409 },\n );\n }\n\n const cleanupLock = (reason: string): Promise<void> =>\n runtime.intelligence\n .ɵcleanupThreadLock({\n threadId: canonicalThreadId || input.threadId,\n runId: canonicalRunId || input.runId,\n })\n .catch((cleanupError) => {\n logger.error(\n { err: cleanupError, reason },\n \"Failed to cleanup thread lock\",\n );\n });\n\n if (!canonicalThreadId || !canonicalRunId || !joinToken) {\n await cleanupLock(\"malformed-lock-response\");\n return Response.json(\n {\n error: \"Run connection credentials not available\",\n message:\n \"Intelligence platform did not return canonical threadId, runId, and joinToken\",\n },\n { status: 502 },\n );\n }\n\n // When Intelligence has `mcpServer: true`, hand the agent the per-request\n // bits it needs to attach the platform's MCP server: the resolved user-id,\n // the project Bearer (`apiKey`), and the MCP URL. These ride through\n // `forwardedProps.auth.copilotkitIntelligence` so the agent doesn't need a\n // typed reference to the Intelligence client. `BuiltInAgent` reads the\n // bag and builds a per-request MCP config with a closure-baked fetch;\n // non-BuiltInAgent agents naturally ignore the key. The `auth` namespace\n // is the convention for credentials that downstream redaction policies\n // strip before durable storage and FE replay.\n const upstreamAuth =\n (input.forwardedProps as { auth?: Record<string, unknown> } | undefined)\n ?.auth ?? {};\n const copilotkitIntelligenceAuth =\n runtime.intelligence.ɵisMcpServerEnabled?.()\n ? {\n copilotkitIntelligence: {\n userId,\n apiKey: runtime.intelligence.ɵgetApiKey(),\n mcpUrl: `${runtime.intelligence.ɵgetApiUrl()}/mcp`,\n },\n }\n : {};\n const mergedAuth = { ...upstreamAuth, ...copilotkitIntelligenceAuth };\n\n const canonicalInput: RunAgentInput = {\n ...input,\n threadId: canonicalThreadId,\n runId: canonicalRunId,\n forwardedProps: {\n ...input.forwardedProps,\n ...(Object.keys(mergedAuth).length > 0 ? { auth: mergedAuth } : {}),\n },\n };\n\n let persistedInputMessages: Message[] | undefined;\n if (Array.isArray(input.messages)) {\n try {\n const history = await runtime.intelligence.getThreadMessages({\n threadId: canonicalThreadId,\n });\n const historicMessageIds = new Set(\n history.messages.map((message) => message.id),\n );\n persistedInputMessages = input.messages.filter(\n (message) => !historicMessageIds.has(message.id),\n );\n } catch (error) {\n logger.error(\"Thread history lookup failed:\", error);\n await cleanupLock(\"thread-history-lookup-failed\");\n return Response.json(\n {\n error: \"Thread history lookup failed\",\n },\n { status: 502 },\n );\n }\n }\n\n telemetry.capture(\"oss.runtime.agent_execution_stream_started\", {});\n\n // Start heartbeat timer to renew the thread lock.\n let heartbeatTimer: ReturnType<typeof setInterval> | undefined;\n heartbeatTimer = setInterval(() => {\n runtime.intelligence\n .ɵrenewThreadLock({\n threadId: canonicalThreadId,\n runId: canonicalRunId,\n ttlSeconds: runtime.lockTtlSeconds,\n ...(runtime.lockKeyPrefix !== undefined\n ? { lockKeyPrefix: runtime.lockKeyPrefix }\n : {}),\n })\n .catch((err) => {\n logger.error(\"Failed to renew thread lock:\", err);\n clearHeartbeat();\n try {\n agent.abortRun();\n } catch (abortError) {\n logger.error(\n \"Failed to abort agent after lock renewal failure:\",\n abortError,\n );\n }\n });\n }, runtime.lockHeartbeatIntervalSeconds * 1_000);\n\n const clearHeartbeat = () => {\n if (heartbeatTimer !== undefined) {\n clearInterval(heartbeatTimer);\n heartbeatTimer = undefined;\n }\n };\n\n const runStarted = { current: false };\n let immediateStartupErrorMessage: string | undefined;\n let immediateStartupCleanup: Promise<void> | undefined;\n\n const runRequest: AgentRunnerRunRequest = {\n threadId: canonicalThreadId,\n agent,\n input: canonicalInput,\n ...(persistedInputMessages !== undefined ? { persistedInputMessages } : {}),\n };\n\n try {\n const runStart = hasRunnerStartupBoundary(runtime.runner)\n ? runtime.runner.runWithStartupBoundary(runRequest)\n : {\n events: runtime.runner.run(runRequest),\n startup: Promise.resolve(),\n };\n\n runStart.events.subscribe({\n next: (event: BaseEvent) => {\n if (event.type === EventType.RUN_STARTED) {\n runStarted.current = true;\n }\n if (event.type === EventType.RUN_ERROR && !runStarted.current) {\n clearHeartbeat();\n immediateStartupErrorMessage =\n \"message\" in event && typeof event.message === \"string\"\n ? event.message\n : \"Runner failed before the run started\";\n immediateStartupCleanup = cleanupLock(\"runner-start-failed\");\n }\n },\n error: (error) => {\n clearHeartbeat();\n if (!runStarted.current) {\n immediateStartupErrorMessage =\n error instanceof Error ? error.message : String(error);\n immediateStartupCleanup = cleanupLock(\"runner-start-error\");\n } else {\n cleanupLock(\"runner-error\");\n }\n telemetry.capture(\"oss.runtime.agent_execution_stream_errored\", {\n error: error instanceof Error ? error.message : String(error),\n });\n logger.error(\"Error running agent:\", error);\n },\n complete: () => {\n clearHeartbeat();\n telemetry.capture(\"oss.runtime.agent_execution_stream_ended\", {});\n },\n });\n\n await runStart.startup;\n } catch (error) {\n clearHeartbeat();\n await (immediateStartupCleanup ?? cleanupLock(\"runner-start-threw\"));\n logger.error(\"Error starting agent runner:\", error);\n return Response.json(\n {\n error: \"Failed to start runner\",\n message: error instanceof Error ? error.message : String(error),\n },\n { status: 502 },\n );\n }\n\n if (immediateStartupErrorMessage) {\n await immediateStartupCleanup;\n return Response.json(\n {\n error: \"Failed to start runner\",\n message: immediateStartupErrorMessage,\n },\n { status: 502 },\n );\n }\n\n // IntelligenceAgentRunner resolves this boundary after Phoenix channel join.\n // Other runner implementations fall back to construction/subscription errors.\n return Response.json(\n {\n threadId: canonicalThreadId,\n runId: canonicalRunId,\n joinToken,\n realtime: buildRealtimeConnectionInfo({\n clientUrl: runtime.intelligence.ɵgetClientWsUrl(),\n threadId: canonicalThreadId,\n }),\n },\n {\n headers: { \"Cache-Control\": \"no-cache\" },\n },\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"run.cjs","names":["resolveIntelligenceUser","isHandlerResponse","generateThreadNameForNewThread","EventType"],"sources":["../../../../../src/v2/runtime/handlers/intelligence/run.ts"],"sourcesContent":["import type {\n AbstractAgent,\n BaseEvent,\n Message,\n RunAgentInput,\n} from \"@ag-ui/client\";\nimport { EventType } from \"@ag-ui/client\";\nimport type { CopilotIntelligenceRuntimeLike } from \"../../core/runtime\";\nimport { generateThreadNameForNewThread } from \"./thread-names\";\nimport { logger } from \"@copilotkit/shared\";\nimport { telemetry } from \"../../telemetry\";\nimport { resolveIntelligenceUser } from \"../shared/resolve-intelligence-user\";\nimport { isHandlerResponse } from \"../shared/json-response\";\nimport type { AgentRunnerRunRequest } from \"../../runner/agent-runner\";\nimport type { Observable } from \"rxjs\";\n\n/**\n * Builds browser-facing realtime connection metadata owned by the runtime.\n */\nfunction buildRealtimeConnectionInfo(params: {\n clientUrl: string;\n threadId: string;\n}): { clientUrl: string; topic: string } {\n return {\n clientUrl: params.clientUrl,\n topic: `thread:${params.threadId}`,\n };\n}\n\ninterface RunnerStartupBoundary {\n events: Observable<BaseEvent>;\n startup: Promise<void>;\n}\n\ninterface RunnerWithStartupBoundary {\n runWithStartupBoundary(request: AgentRunnerRunRequest): RunnerStartupBoundary;\n}\n\nfunction hasRunnerStartupBoundary(\n runner: CopilotIntelligenceRuntimeLike[\"runner\"],\n): runner is CopilotIntelligenceRuntimeLike[\"runner\"] &\n RunnerWithStartupBoundary {\n const candidate = runner as { runWithStartupBoundary?: unknown };\n\n return (\n typeof candidate.runWithStartupBoundary === \"function\" &&\n (Object.prototype.hasOwnProperty.call(runner, \"runWithStartupBoundary\") ||\n Object.prototype.hasOwnProperty.call(runner, \"threads\"))\n );\n}\n\ninterface HandleIntelligenceRunParams {\n runtime: CopilotIntelligenceRuntimeLike;\n request: Request;\n agentId: string;\n agent: AbstractAgent;\n input: RunAgentInput;\n}\n\nexport async function handleIntelligenceRun({\n runtime,\n request,\n agentId,\n agent,\n input,\n}: HandleIntelligenceRunParams): Promise<Response> {\n if (!runtime.intelligence) {\n return Response.json(\n {\n error: \"Intelligence not configured\",\n message: \"Intelligence mode requires a CopilotKitIntelligence\",\n },\n { status: 500 },\n );\n }\n\n const user = await resolveIntelligenceUser({ runtime, request });\n if (isHandlerResponse(user)) {\n return user;\n }\n const userId = user.id;\n\n try {\n const { thread, created } = await runtime.intelligence.getOrCreateThread({\n threadId: input.threadId,\n userId,\n agentId,\n });\n\n if (created && runtime.generateThreadNames && !thread.name?.trim()) {\n void generateThreadNameForNewThread({\n runtime,\n request,\n agentId,\n sourceInput: input,\n thread,\n userId,\n }).catch((nameError) => {\n logger.error(\"Failed to generate thread name:\", nameError);\n });\n }\n } catch (error) {\n logger.error(\"Failed to get or create thread:\", error);\n return Response.json(\n {\n error: \"Failed to initialize thread\",\n },\n { status: 502 },\n );\n }\n\n let canonicalThreadId = input.threadId;\n let canonicalRunId = input.runId;\n let joinToken: string | undefined;\n try {\n const lockResult = await runtime.intelligence.ɵacquireThreadLock({\n threadId: input.threadId,\n runId: input.runId,\n userId,\n agentId,\n ...(runtime.lockKeyPrefix !== undefined\n ? { lockKeyPrefix: runtime.lockKeyPrefix }\n : {}),\n ttlSeconds: runtime.lockTtlSeconds,\n });\n canonicalThreadId = lockResult.threadId;\n canonicalRunId = lockResult.runId;\n joinToken = lockResult.joinToken;\n } catch (error) {\n logger.error(\"Thread lock denied:\", error);\n return Response.json(\n {\n error: \"Thread lock denied\",\n },\n { status: 409 },\n );\n }\n\n const cleanupLock = (reason: string): Promise<void> =>\n runtime.intelligence\n .ɵcleanupThreadLock({\n threadId: canonicalThreadId || input.threadId,\n runId: canonicalRunId || input.runId,\n })\n .catch((cleanupError) => {\n logger.error(\n { err: cleanupError, reason },\n \"Failed to cleanup thread lock\",\n );\n });\n\n if (!canonicalThreadId || !canonicalRunId || !joinToken) {\n await cleanupLock(\"malformed-lock-response\");\n return Response.json(\n {\n error: \"Run connection credentials not available\",\n message:\n \"Intelligence platform did not return canonical threadId, runId, and joinToken\",\n },\n { status: 502 },\n );\n }\n\n const canonicalInput: RunAgentInput = {\n ...input,\n threadId: canonicalThreadId,\n runId: canonicalRunId,\n };\n\n let persistedInputMessages: Message[] | undefined;\n if (Array.isArray(input.messages)) {\n try {\n const history = await runtime.intelligence.getThreadMessages({\n threadId: canonicalThreadId,\n });\n const historicMessageIds = new Set(\n history.messages.map((message) => message.id),\n );\n persistedInputMessages = input.messages.filter(\n (message) => !historicMessageIds.has(message.id),\n );\n } catch (error) {\n logger.error(\"Thread history lookup failed:\", error);\n await cleanupLock(\"thread-history-lookup-failed\");\n return Response.json(\n {\n error: \"Thread history lookup failed\",\n },\n { status: 502 },\n );\n }\n }\n\n telemetry.capture(\"oss.runtime.agent_execution_stream_started\", {});\n\n // Start heartbeat timer to renew the thread lock.\n let heartbeatTimer: ReturnType<typeof setInterval> | undefined;\n heartbeatTimer = setInterval(() => {\n runtime.intelligence\n .ɵrenewThreadLock({\n threadId: canonicalThreadId,\n runId: canonicalRunId,\n ttlSeconds: runtime.lockTtlSeconds,\n ...(runtime.lockKeyPrefix !== undefined\n ? { lockKeyPrefix: runtime.lockKeyPrefix }\n : {}),\n })\n .catch((err) => {\n logger.error(\"Failed to renew thread lock:\", err);\n clearHeartbeat();\n try {\n agent.abortRun();\n } catch (abortError) {\n logger.error(\n \"Failed to abort agent after lock renewal failure:\",\n abortError,\n );\n }\n });\n }, runtime.lockHeartbeatIntervalSeconds * 1_000);\n\n const clearHeartbeat = () => {\n if (heartbeatTimer !== undefined) {\n clearInterval(heartbeatTimer);\n heartbeatTimer = undefined;\n }\n };\n\n const runStarted = { current: false };\n let immediateStartupErrorMessage: string | undefined;\n let immediateStartupCleanup: Promise<void> | undefined;\n\n const runRequest: AgentRunnerRunRequest = {\n threadId: canonicalThreadId,\n agent,\n input: canonicalInput,\n ...(persistedInputMessages !== undefined ? { persistedInputMessages } : {}),\n };\n\n try {\n const runStart = hasRunnerStartupBoundary(runtime.runner)\n ? runtime.runner.runWithStartupBoundary(runRequest)\n : {\n events: runtime.runner.run(runRequest),\n startup: Promise.resolve(),\n };\n\n runStart.events.subscribe({\n next: (event: BaseEvent) => {\n if (event.type === EventType.RUN_STARTED) {\n runStarted.current = true;\n }\n if (event.type === EventType.RUN_ERROR && !runStarted.current) {\n clearHeartbeat();\n immediateStartupErrorMessage =\n \"message\" in event && typeof event.message === \"string\"\n ? event.message\n : \"Runner failed before the run started\";\n immediateStartupCleanup = cleanupLock(\"runner-start-failed\");\n }\n },\n error: (error) => {\n clearHeartbeat();\n if (!runStarted.current) {\n immediateStartupErrorMessage =\n error instanceof Error ? error.message : String(error);\n immediateStartupCleanup = cleanupLock(\"runner-start-error\");\n } else {\n cleanupLock(\"runner-error\");\n }\n telemetry.capture(\"oss.runtime.agent_execution_stream_errored\", {\n error: error instanceof Error ? error.message : String(error),\n });\n logger.error(\"Error running agent:\", error);\n },\n complete: () => {\n clearHeartbeat();\n telemetry.capture(\"oss.runtime.agent_execution_stream_ended\", {});\n },\n });\n\n await runStart.startup;\n } catch (error) {\n clearHeartbeat();\n await (immediateStartupCleanup ?? cleanupLock(\"runner-start-threw\"));\n logger.error(\"Error starting agent runner:\", error);\n return Response.json(\n {\n error: \"Failed to start runner\",\n message: error instanceof Error ? error.message : String(error),\n },\n { status: 502 },\n );\n }\n\n if (immediateStartupErrorMessage) {\n await immediateStartupCleanup;\n return Response.json(\n {\n error: \"Failed to start runner\",\n message: immediateStartupErrorMessage,\n },\n { status: 502 },\n );\n }\n\n // IntelligenceAgentRunner resolves this boundary after Phoenix channel join.\n // Other runner implementations fall back to construction/subscription errors.\n return Response.json(\n {\n threadId: canonicalThreadId,\n runId: canonicalRunId,\n joinToken,\n realtime: buildRealtimeConnectionInfo({\n clientUrl: runtime.intelligence.ɵgetClientWsUrl(),\n threadId: canonicalThreadId,\n }),\n },\n {\n headers: { \"Cache-Control\": \"no-cache\" },\n },\n );\n}\n"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  import "reflect-metadata";
2
2
  import telemetry from "../../telemetry/telemetry-client.mjs";
3
3
  import { isHandlerResponse } from "../shared/json-response.mjs";
4
- import { generateThreadNameForNewThread } from "./thread-names.mjs";
5
4
  import { resolveIntelligenceUser } from "../shared/resolve-intelligence-user.mjs";
5
+ import { generateThreadNameForNewThread } from "./thread-names.mjs";
6
6
  import { logger } from "@copilotkit/shared";
7
7
  import { EventType } from "@ag-ui/client";
8
8
 
@@ -85,24 +85,10 @@ async function handleIntelligenceRun({ runtime, request, agentId, agent, input }
85
85
  message: "Intelligence platform did not return canonical threadId, runId, and joinToken"
86
86
  }, { status: 502 });
87
87
  }
88
- const upstreamAuth = input.forwardedProps?.auth ?? {};
89
- const copilotkitIntelligenceAuth = runtime.intelligence.ɵisMcpServerEnabled?.() ? { copilotkitIntelligence: {
90
- userId,
91
- apiKey: runtime.intelligence.ɵgetApiKey(),
92
- mcpUrl: `${runtime.intelligence.ɵgetApiUrl()}/mcp`
93
- } } : {};
94
- const mergedAuth = {
95
- ...upstreamAuth,
96
- ...copilotkitIntelligenceAuth
97
- };
98
88
  const canonicalInput = {
99
89
  ...input,
100
90
  threadId: canonicalThreadId,
101
- runId: canonicalRunId,
102
- forwardedProps: {
103
- ...input.forwardedProps,
104
- ...Object.keys(mergedAuth).length > 0 ? { auth: mergedAuth } : {}
105
- }
91
+ runId: canonicalRunId
106
92
  };
107
93
  let persistedInputMessages;
108
94
  if (Array.isArray(input.messages)) try {
@@ -1 +1 @@
1
- {"version":3,"file":"run.mjs","names":[],"sources":["../../../../../src/v2/runtime/handlers/intelligence/run.ts"],"sourcesContent":["import type {\n AbstractAgent,\n BaseEvent,\n Message,\n RunAgentInput,\n} from \"@ag-ui/client\";\nimport { EventType } from \"@ag-ui/client\";\nimport type { CopilotIntelligenceRuntimeLike } from \"../../core/runtime\";\nimport { generateThreadNameForNewThread } from \"./thread-names\";\nimport { logger } from \"@copilotkit/shared\";\nimport { telemetry } from \"../../telemetry\";\nimport { resolveIntelligenceUser } from \"../shared/resolve-intelligence-user\";\nimport { isHandlerResponse } from \"../shared/json-response\";\nimport type { AgentRunnerRunRequest } from \"../../runner/agent-runner\";\nimport type { Observable } from \"rxjs\";\n\n/**\n * Builds browser-facing realtime connection metadata owned by the runtime.\n */\nfunction buildRealtimeConnectionInfo(params: {\n clientUrl: string;\n threadId: string;\n}): { clientUrl: string; topic: string } {\n return {\n clientUrl: params.clientUrl,\n topic: `thread:${params.threadId}`,\n };\n}\n\ninterface RunnerStartupBoundary {\n events: Observable<BaseEvent>;\n startup: Promise<void>;\n}\n\ninterface RunnerWithStartupBoundary {\n runWithStartupBoundary(request: AgentRunnerRunRequest): RunnerStartupBoundary;\n}\n\nfunction hasRunnerStartupBoundary(\n runner: CopilotIntelligenceRuntimeLike[\"runner\"],\n): runner is CopilotIntelligenceRuntimeLike[\"runner\"] &\n RunnerWithStartupBoundary {\n const candidate = runner as { runWithStartupBoundary?: unknown };\n\n return (\n typeof candidate.runWithStartupBoundary === \"function\" &&\n (Object.prototype.hasOwnProperty.call(runner, \"runWithStartupBoundary\") ||\n Object.prototype.hasOwnProperty.call(runner, \"threads\"))\n );\n}\n\ninterface HandleIntelligenceRunParams {\n runtime: CopilotIntelligenceRuntimeLike;\n request: Request;\n agentId: string;\n agent: AbstractAgent;\n input: RunAgentInput;\n}\n\nexport async function handleIntelligenceRun({\n runtime,\n request,\n agentId,\n agent,\n input,\n}: HandleIntelligenceRunParams): Promise<Response> {\n if (!runtime.intelligence) {\n return Response.json(\n {\n error: \"Intelligence not configured\",\n message: \"Intelligence mode requires a CopilotKitIntelligence\",\n },\n { status: 500 },\n );\n }\n\n const user = await resolveIntelligenceUser({ runtime, request });\n if (isHandlerResponse(user)) {\n return user;\n }\n const userId = user.id;\n\n try {\n const { thread, created } = await runtime.intelligence.getOrCreateThread({\n threadId: input.threadId,\n userId,\n agentId,\n });\n\n if (created && runtime.generateThreadNames && !thread.name?.trim()) {\n void generateThreadNameForNewThread({\n runtime,\n request,\n agentId,\n sourceInput: input,\n thread,\n userId,\n }).catch((nameError) => {\n logger.error(\"Failed to generate thread name:\", nameError);\n });\n }\n } catch (error) {\n logger.error(\"Failed to get or create thread:\", error);\n return Response.json(\n {\n error: \"Failed to initialize thread\",\n },\n { status: 502 },\n );\n }\n\n let canonicalThreadId = input.threadId;\n let canonicalRunId = input.runId;\n let joinToken: string | undefined;\n try {\n const lockResult = await runtime.intelligence.ɵacquireThreadLock({\n threadId: input.threadId,\n runId: input.runId,\n userId,\n agentId,\n ...(runtime.lockKeyPrefix !== undefined\n ? { lockKeyPrefix: runtime.lockKeyPrefix }\n : {}),\n ttlSeconds: runtime.lockTtlSeconds,\n });\n canonicalThreadId = lockResult.threadId;\n canonicalRunId = lockResult.runId;\n joinToken = lockResult.joinToken;\n } catch (error) {\n logger.error(\"Thread lock denied:\", error);\n return Response.json(\n {\n error: \"Thread lock denied\",\n },\n { status: 409 },\n );\n }\n\n const cleanupLock = (reason: string): Promise<void> =>\n runtime.intelligence\n .ɵcleanupThreadLock({\n threadId: canonicalThreadId || input.threadId,\n runId: canonicalRunId || input.runId,\n })\n .catch((cleanupError) => {\n logger.error(\n { err: cleanupError, reason },\n \"Failed to cleanup thread lock\",\n );\n });\n\n if (!canonicalThreadId || !canonicalRunId || !joinToken) {\n await cleanupLock(\"malformed-lock-response\");\n return Response.json(\n {\n error: \"Run connection credentials not available\",\n message:\n \"Intelligence platform did not return canonical threadId, runId, and joinToken\",\n },\n { status: 502 },\n );\n }\n\n // When Intelligence has `mcpServer: true`, hand the agent the per-request\n // bits it needs to attach the platform's MCP server: the resolved user-id,\n // the project Bearer (`apiKey`), and the MCP URL. These ride through\n // `forwardedProps.auth.copilotkitIntelligence` so the agent doesn't need a\n // typed reference to the Intelligence client. `BuiltInAgent` reads the\n // bag and builds a per-request MCP config with a closure-baked fetch;\n // non-BuiltInAgent agents naturally ignore the key. The `auth` namespace\n // is the convention for credentials that downstream redaction policies\n // strip before durable storage and FE replay.\n const upstreamAuth =\n (input.forwardedProps as { auth?: Record<string, unknown> } | undefined)\n ?.auth ?? {};\n const copilotkitIntelligenceAuth =\n runtime.intelligence.ɵisMcpServerEnabled?.()\n ? {\n copilotkitIntelligence: {\n userId,\n apiKey: runtime.intelligence.ɵgetApiKey(),\n mcpUrl: `${runtime.intelligence.ɵgetApiUrl()}/mcp`,\n },\n }\n : {};\n const mergedAuth = { ...upstreamAuth, ...copilotkitIntelligenceAuth };\n\n const canonicalInput: RunAgentInput = {\n ...input,\n threadId: canonicalThreadId,\n runId: canonicalRunId,\n forwardedProps: {\n ...input.forwardedProps,\n ...(Object.keys(mergedAuth).length > 0 ? { auth: mergedAuth } : {}),\n },\n };\n\n let persistedInputMessages: Message[] | undefined;\n if (Array.isArray(input.messages)) {\n try {\n const history = await runtime.intelligence.getThreadMessages({\n threadId: canonicalThreadId,\n });\n const historicMessageIds = new Set(\n history.messages.map((message) => message.id),\n );\n persistedInputMessages = input.messages.filter(\n (message) => !historicMessageIds.has(message.id),\n );\n } catch (error) {\n logger.error(\"Thread history lookup failed:\", error);\n await cleanupLock(\"thread-history-lookup-failed\");\n return Response.json(\n {\n error: \"Thread history lookup failed\",\n },\n { status: 502 },\n );\n }\n }\n\n telemetry.capture(\"oss.runtime.agent_execution_stream_started\", {});\n\n // Start heartbeat timer to renew the thread lock.\n let heartbeatTimer: ReturnType<typeof setInterval> | undefined;\n heartbeatTimer = setInterval(() => {\n runtime.intelligence\n .ɵrenewThreadLock({\n threadId: canonicalThreadId,\n runId: canonicalRunId,\n ttlSeconds: runtime.lockTtlSeconds,\n ...(runtime.lockKeyPrefix !== undefined\n ? { lockKeyPrefix: runtime.lockKeyPrefix }\n : {}),\n })\n .catch((err) => {\n logger.error(\"Failed to renew thread lock:\", err);\n clearHeartbeat();\n try {\n agent.abortRun();\n } catch (abortError) {\n logger.error(\n \"Failed to abort agent after lock renewal failure:\",\n abortError,\n );\n }\n });\n }, runtime.lockHeartbeatIntervalSeconds * 1_000);\n\n const clearHeartbeat = () => {\n if (heartbeatTimer !== undefined) {\n clearInterval(heartbeatTimer);\n heartbeatTimer = undefined;\n }\n };\n\n const runStarted = { current: false };\n let immediateStartupErrorMessage: string | undefined;\n let immediateStartupCleanup: Promise<void> | undefined;\n\n const runRequest: AgentRunnerRunRequest = {\n threadId: canonicalThreadId,\n agent,\n input: canonicalInput,\n ...(persistedInputMessages !== undefined ? { persistedInputMessages } : {}),\n };\n\n try {\n const runStart = hasRunnerStartupBoundary(runtime.runner)\n ? runtime.runner.runWithStartupBoundary(runRequest)\n : {\n events: runtime.runner.run(runRequest),\n startup: Promise.resolve(),\n };\n\n runStart.events.subscribe({\n next: (event: BaseEvent) => {\n if (event.type === EventType.RUN_STARTED) {\n runStarted.current = true;\n }\n if (event.type === EventType.RUN_ERROR && !runStarted.current) {\n clearHeartbeat();\n immediateStartupErrorMessage =\n \"message\" in event && typeof event.message === \"string\"\n ? event.message\n : \"Runner failed before the run started\";\n immediateStartupCleanup = cleanupLock(\"runner-start-failed\");\n }\n },\n error: (error) => {\n clearHeartbeat();\n if (!runStarted.current) {\n immediateStartupErrorMessage =\n error instanceof Error ? error.message : String(error);\n immediateStartupCleanup = cleanupLock(\"runner-start-error\");\n } else {\n cleanupLock(\"runner-error\");\n }\n telemetry.capture(\"oss.runtime.agent_execution_stream_errored\", {\n error: error instanceof Error ? error.message : String(error),\n });\n logger.error(\"Error running agent:\", error);\n },\n complete: () => {\n clearHeartbeat();\n telemetry.capture(\"oss.runtime.agent_execution_stream_ended\", {});\n },\n });\n\n await runStart.startup;\n } catch (error) {\n clearHeartbeat();\n await (immediateStartupCleanup ?? cleanupLock(\"runner-start-threw\"));\n logger.error(\"Error starting agent runner:\", error);\n return Response.json(\n {\n error: \"Failed to start runner\",\n message: error instanceof Error ? error.message : String(error),\n },\n { status: 502 },\n );\n }\n\n if (immediateStartupErrorMessage) {\n await immediateStartupCleanup;\n return Response.json(\n {\n error: \"Failed to start runner\",\n message: immediateStartupErrorMessage,\n },\n { status: 502 },\n );\n }\n\n // IntelligenceAgentRunner resolves this boundary after Phoenix channel join.\n // Other runner implementations fall back to construction/subscription errors.\n return Response.json(\n {\n threadId: canonicalThreadId,\n runId: canonicalRunId,\n joinToken,\n realtime: buildRealtimeConnectionInfo({\n clientUrl: runtime.intelligence.ɵgetClientWsUrl(),\n threadId: canonicalThreadId,\n }),\n },\n {\n headers: { \"Cache-Control\": \"no-cache\" },\n },\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"run.mjs","names":[],"sources":["../../../../../src/v2/runtime/handlers/intelligence/run.ts"],"sourcesContent":["import type {\n AbstractAgent,\n BaseEvent,\n Message,\n RunAgentInput,\n} from \"@ag-ui/client\";\nimport { EventType } from \"@ag-ui/client\";\nimport type { CopilotIntelligenceRuntimeLike } from \"../../core/runtime\";\nimport { generateThreadNameForNewThread } from \"./thread-names\";\nimport { logger } from \"@copilotkit/shared\";\nimport { telemetry } from \"../../telemetry\";\nimport { resolveIntelligenceUser } from \"../shared/resolve-intelligence-user\";\nimport { isHandlerResponse } from \"../shared/json-response\";\nimport type { AgentRunnerRunRequest } from \"../../runner/agent-runner\";\nimport type { Observable } from \"rxjs\";\n\n/**\n * Builds browser-facing realtime connection metadata owned by the runtime.\n */\nfunction buildRealtimeConnectionInfo(params: {\n clientUrl: string;\n threadId: string;\n}): { clientUrl: string; topic: string } {\n return {\n clientUrl: params.clientUrl,\n topic: `thread:${params.threadId}`,\n };\n}\n\ninterface RunnerStartupBoundary {\n events: Observable<BaseEvent>;\n startup: Promise<void>;\n}\n\ninterface RunnerWithStartupBoundary {\n runWithStartupBoundary(request: AgentRunnerRunRequest): RunnerStartupBoundary;\n}\n\nfunction hasRunnerStartupBoundary(\n runner: CopilotIntelligenceRuntimeLike[\"runner\"],\n): runner is CopilotIntelligenceRuntimeLike[\"runner\"] &\n RunnerWithStartupBoundary {\n const candidate = runner as { runWithStartupBoundary?: unknown };\n\n return (\n typeof candidate.runWithStartupBoundary === \"function\" &&\n (Object.prototype.hasOwnProperty.call(runner, \"runWithStartupBoundary\") ||\n Object.prototype.hasOwnProperty.call(runner, \"threads\"))\n );\n}\n\ninterface HandleIntelligenceRunParams {\n runtime: CopilotIntelligenceRuntimeLike;\n request: Request;\n agentId: string;\n agent: AbstractAgent;\n input: RunAgentInput;\n}\n\nexport async function handleIntelligenceRun({\n runtime,\n request,\n agentId,\n agent,\n input,\n}: HandleIntelligenceRunParams): Promise<Response> {\n if (!runtime.intelligence) {\n return Response.json(\n {\n error: \"Intelligence not configured\",\n message: \"Intelligence mode requires a CopilotKitIntelligence\",\n },\n { status: 500 },\n );\n }\n\n const user = await resolveIntelligenceUser({ runtime, request });\n if (isHandlerResponse(user)) {\n return user;\n }\n const userId = user.id;\n\n try {\n const { thread, created } = await runtime.intelligence.getOrCreateThread({\n threadId: input.threadId,\n userId,\n agentId,\n });\n\n if (created && runtime.generateThreadNames && !thread.name?.trim()) {\n void generateThreadNameForNewThread({\n runtime,\n request,\n agentId,\n sourceInput: input,\n thread,\n userId,\n }).catch((nameError) => {\n logger.error(\"Failed to generate thread name:\", nameError);\n });\n }\n } catch (error) {\n logger.error(\"Failed to get or create thread:\", error);\n return Response.json(\n {\n error: \"Failed to initialize thread\",\n },\n { status: 502 },\n );\n }\n\n let canonicalThreadId = input.threadId;\n let canonicalRunId = input.runId;\n let joinToken: string | undefined;\n try {\n const lockResult = await runtime.intelligence.ɵacquireThreadLock({\n threadId: input.threadId,\n runId: input.runId,\n userId,\n agentId,\n ...(runtime.lockKeyPrefix !== undefined\n ? { lockKeyPrefix: runtime.lockKeyPrefix }\n : {}),\n ttlSeconds: runtime.lockTtlSeconds,\n });\n canonicalThreadId = lockResult.threadId;\n canonicalRunId = lockResult.runId;\n joinToken = lockResult.joinToken;\n } catch (error) {\n logger.error(\"Thread lock denied:\", error);\n return Response.json(\n {\n error: \"Thread lock denied\",\n },\n { status: 409 },\n );\n }\n\n const cleanupLock = (reason: string): Promise<void> =>\n runtime.intelligence\n .ɵcleanupThreadLock({\n threadId: canonicalThreadId || input.threadId,\n runId: canonicalRunId || input.runId,\n })\n .catch((cleanupError) => {\n logger.error(\n { err: cleanupError, reason },\n \"Failed to cleanup thread lock\",\n );\n });\n\n if (!canonicalThreadId || !canonicalRunId || !joinToken) {\n await cleanupLock(\"malformed-lock-response\");\n return Response.json(\n {\n error: \"Run connection credentials not available\",\n message:\n \"Intelligence platform did not return canonical threadId, runId, and joinToken\",\n },\n { status: 502 },\n );\n }\n\n const canonicalInput: RunAgentInput = {\n ...input,\n threadId: canonicalThreadId,\n runId: canonicalRunId,\n };\n\n let persistedInputMessages: Message[] | undefined;\n if (Array.isArray(input.messages)) {\n try {\n const history = await runtime.intelligence.getThreadMessages({\n threadId: canonicalThreadId,\n });\n const historicMessageIds = new Set(\n history.messages.map((message) => message.id),\n );\n persistedInputMessages = input.messages.filter(\n (message) => !historicMessageIds.has(message.id),\n );\n } catch (error) {\n logger.error(\"Thread history lookup failed:\", error);\n await cleanupLock(\"thread-history-lookup-failed\");\n return Response.json(\n {\n error: \"Thread history lookup failed\",\n },\n { status: 502 },\n );\n }\n }\n\n telemetry.capture(\"oss.runtime.agent_execution_stream_started\", {});\n\n // Start heartbeat timer to renew the thread lock.\n let heartbeatTimer: ReturnType<typeof setInterval> | undefined;\n heartbeatTimer = setInterval(() => {\n runtime.intelligence\n .ɵrenewThreadLock({\n threadId: canonicalThreadId,\n runId: canonicalRunId,\n ttlSeconds: runtime.lockTtlSeconds,\n ...(runtime.lockKeyPrefix !== undefined\n ? { lockKeyPrefix: runtime.lockKeyPrefix }\n : {}),\n })\n .catch((err) => {\n logger.error(\"Failed to renew thread lock:\", err);\n clearHeartbeat();\n try {\n agent.abortRun();\n } catch (abortError) {\n logger.error(\n \"Failed to abort agent after lock renewal failure:\",\n abortError,\n );\n }\n });\n }, runtime.lockHeartbeatIntervalSeconds * 1_000);\n\n const clearHeartbeat = () => {\n if (heartbeatTimer !== undefined) {\n clearInterval(heartbeatTimer);\n heartbeatTimer = undefined;\n }\n };\n\n const runStarted = { current: false };\n let immediateStartupErrorMessage: string | undefined;\n let immediateStartupCleanup: Promise<void> | undefined;\n\n const runRequest: AgentRunnerRunRequest = {\n threadId: canonicalThreadId,\n agent,\n input: canonicalInput,\n ...(persistedInputMessages !== undefined ? { persistedInputMessages } : {}),\n };\n\n try {\n const runStart = hasRunnerStartupBoundary(runtime.runner)\n ? runtime.runner.runWithStartupBoundary(runRequest)\n : {\n events: runtime.runner.run(runRequest),\n startup: Promise.resolve(),\n };\n\n runStart.events.subscribe({\n next: (event: BaseEvent) => {\n if (event.type === EventType.RUN_STARTED) {\n runStarted.current = true;\n }\n if (event.type === EventType.RUN_ERROR && !runStarted.current) {\n clearHeartbeat();\n immediateStartupErrorMessage =\n \"message\" in event && typeof event.message === \"string\"\n ? event.message\n : \"Runner failed before the run started\";\n immediateStartupCleanup = cleanupLock(\"runner-start-failed\");\n }\n },\n error: (error) => {\n clearHeartbeat();\n if (!runStarted.current) {\n immediateStartupErrorMessage =\n error instanceof Error ? error.message : String(error);\n immediateStartupCleanup = cleanupLock(\"runner-start-error\");\n } else {\n cleanupLock(\"runner-error\");\n }\n telemetry.capture(\"oss.runtime.agent_execution_stream_errored\", {\n error: error instanceof Error ? error.message : String(error),\n });\n logger.error(\"Error running agent:\", error);\n },\n complete: () => {\n clearHeartbeat();\n telemetry.capture(\"oss.runtime.agent_execution_stream_ended\", {});\n },\n });\n\n await runStart.startup;\n } catch (error) {\n clearHeartbeat();\n await (immediateStartupCleanup ?? cleanupLock(\"runner-start-threw\"));\n logger.error(\"Error starting agent runner:\", error);\n return Response.json(\n {\n error: \"Failed to start runner\",\n message: error instanceof Error ? error.message : String(error),\n },\n { status: 502 },\n );\n }\n\n if (immediateStartupErrorMessage) {\n await immediateStartupCleanup;\n return Response.json(\n {\n error: \"Failed to start runner\",\n message: immediateStartupErrorMessage,\n },\n { status: 502 },\n );\n }\n\n // IntelligenceAgentRunner resolves this boundary after Phoenix channel join.\n // Other runner implementations fall back to construction/subscription errors.\n return Response.json(\n {\n threadId: canonicalThreadId,\n runId: canonicalRunId,\n joinToken,\n realtime: buildRealtimeConnectionInfo({\n clientUrl: runtime.intelligence.ɵgetClientWsUrl(),\n threadId: canonicalThreadId,\n }),\n },\n {\n headers: { \"Cache-Control\": \"no-cache\" },\n },\n );\n}\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  require("reflect-metadata");
2
2
  const require_runtime = require('../../../../_virtual/_rolldown/runtime.cjs');
3
- const require_agent_utils = require('../shared/agent-utils.cjs');
4
3
  const require_json_response = require('../shared/json-response.cjs');
4
+ const require_agent_utils = require('../shared/agent-utils.cjs');
5
5
  let _copilotkit_shared = require("@copilotkit/shared");
6
6
  let node_crypto = require("node:crypto");
7
7
 
@@ -1,6 +1,6 @@
1
1
  import "reflect-metadata";
2
- import { cloneAgentForRequest, configureAgentForRequest } from "../shared/agent-utils.mjs";
3
2
  import { isHandlerResponse } from "../shared/json-response.mjs";
3
+ import { cloneAgentForRequest, configureAgentForRequest } from "../shared/agent-utils.mjs";
4
4
  import { logger } from "@copilotkit/shared";
5
5
  import { randomUUID as randomUUID$1 } from "node:crypto";
6
6
 
@@ -2,11 +2,14 @@ require("reflect-metadata");
2
2
  const require_runtime = require('../../../../_virtual/_rolldown/runtime.cjs');
3
3
  const require_runtime$1 = require('../../core/runtime.cjs');
4
4
  const require_open_generative_ui_middleware = require('../../open-generative-ui-middleware.cjs');
5
+ const require_client = require('../../intelligence-platform/client.cjs');
5
6
  const require_header_utils = require('../header-utils.cjs');
7
+ const require_resolve_intelligence_user = require('./resolve-intelligence-user.cjs');
6
8
  let _copilotkit_shared = require("@copilotkit/shared");
7
9
  let _ag_ui_client = require("@ag-ui/client");
8
10
  let _ag_ui_a2ui_middleware = require("@ag-ui/a2ui-middleware");
9
11
  let _ag_ui_mcp_apps_middleware = require("@ag-ui/mcp-apps-middleware");
12
+ let _ag_ui_mcp_middleware = require("@ag-ui/mcp-middleware");
10
13
 
11
14
  //#region src/v2/runtime/handlers/shared/agent-utils.ts
12
15
  async function cloneAgentForRequest(runtime, agentId, request) {
@@ -45,6 +48,49 @@ function configureAgentForRequest(params) {
45
48
  ...require_header_utils.extractForwardableHeaders(request)
46
49
  };
47
50
  }
51
+ /**
52
+ * Attach the Intelligence platform's MCP tools to the agent run when
53
+ * `CopilotKitIntelligence` was constructed with
54
+ * `enableEnterpriseLearning: true`. Uses `@ag-ui/mcp-middleware`, so the
55
+ * tools are available uniformly across agent frameworks (not just
56
+ * `BuiltInAgent`).
57
+ *
58
+ * The middleware sits on a per-request agent clone, so the per-request
59
+ * auth (Bearer apiKey + resolved user-id) is baked into the transport
60
+ * headers at attach time. If user resolution fails, attachment is
61
+ * skipped silently — the intelligence run handler will reject the
62
+ * request with the same error. Note this means `identifyUser` is
63
+ * resolved twice per learning-enabled run (here and in the run handler);
64
+ * the callback is expected to be idempotent and side-effect-free.
65
+ *
66
+ * Intentionally split out from `configureAgentForRequest`: this is only
67
+ * relevant to actual agent runs, not auxiliary flows like thread-name
68
+ * generation (which has no need for MCP tools and shouldn't pay the
69
+ * `listTools` round-trip).
70
+ */
71
+ async function attachIntelligenceEnterpriseLearning(params) {
72
+ const { runtime, request } = params;
73
+ const agent = params.agent;
74
+ if (!require_runtime$1.isIntelligenceRuntime(runtime) || !runtime.intelligence?.ɵisEnterpriseLearningEnabled?.()) return;
75
+ if (typeof agent.use !== "function") {
76
+ _copilotkit_shared.logger.warn("CopilotKitIntelligence.enableEnterpriseLearning is enabled, but the agent does not support middleware (no `.use()` method); Intelligence tools were not attached for this run.");
77
+ return;
78
+ }
79
+ const userResult = await require_resolve_intelligence_user.resolveIntelligenceUser({
80
+ runtime,
81
+ request
82
+ });
83
+ if (userResult instanceof Response) return;
84
+ agent.use(new _ag_ui_mcp_middleware.MCPMiddleware([{
85
+ type: "http",
86
+ url: `${runtime.intelligence.ɵgetApiUrl()}/mcp`,
87
+ serverId: "intelligence",
88
+ headers: {
89
+ Authorization: `Bearer ${runtime.intelligence.ɵgetApiKey()}`,
90
+ [require_client.INTELLIGENCE_USER_ID_HEADER]: userResult.id
91
+ }
92
+ }]));
93
+ }
48
94
  async function parseRunRequest(request) {
49
95
  try {
50
96
  const requestBody = await request.json();
@@ -83,6 +129,7 @@ async function parseConnectRequest(request) {
83
129
  }
84
130
 
85
131
  //#endregion
132
+ exports.attachIntelligenceEnterpriseLearning = attachIntelligenceEnterpriseLearning;
86
133
  exports.cloneAgentForRequest = cloneAgentForRequest;
87
134
  exports.configureAgentForRequest = configureAgentForRequest;
88
135
  exports.parseConnectRequest = parseConnectRequest;
@@ -1 +1 @@
1
- {"version":3,"file":"agent-utils.cjs","names":["resolveAgents","A2UIMiddleware","MCPAppsMiddleware","OpenGenerativeUIMiddleware","extractForwardableHeaders","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 { A2UIMiddleware } from \"@ag-ui/a2ui-middleware\";\nimport { MCPAppsMiddleware } from \"@ag-ui/mcp-apps-middleware\";\nimport type { CopilotRuntimeLike } from \"../../core/runtime\";\nimport { resolveAgents } from \"../../core/runtime\";\nimport { OpenGenerativeUIMiddleware } from \"../../open-generative-ui-middleware\";\nimport { extractForwardableHeaders } from \"../header-utils\";\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\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}): void {\n const { runtime, request, agentId } = params;\n const agent = params.agent as MiddlewareCapableAgent;\n\n if (runtime.a2ui) {\n const { agents: targetAgents, ...a2uiOptions } = runtime.a2ui;\n const shouldApply = !targetAgents || targetAgents.includes(agentId);\n if (shouldApply && typeof agent.use === \"function\") {\n agent.use(new A2UIMiddleware(a2uiOptions));\n }\n }\n\n if (runtime.mcpApps?.servers?.length) {\n const mcpServers = runtime.mcpApps.servers\n .filter((server) => !server.agentId || server.agentId === agentId)\n .map((server) => {\n const mcpServer = { ...server };\n delete mcpServer.agentId;\n return mcpServer;\n });\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 agent.headers = {\n ...agent.headers,\n ...extractForwardableHeaders(request),\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":";;;;;;;;;;;AAyBA,eAAsB,qBACpB,SACA,SACA,SACmC;CACnC,MAAM,SAAS,MAAMA,gCAAc,QAAQ,QAAQ,QAAQ;AAE3D,KAAI,CAAC,OAAO,SACV,QAAO,IAAI,SACT,KAAK,UAAU;EACb,OAAO;EACP,SAAS,UAAU,QAAQ;EAC5B,CAAC,EACF;EACE,QAAQ;EACR,SAAS,EAAE,gBAAgB,oBAAoB;EAChD,CACF;AAGH,QAAQ,OAAO,SAA2B,OAAO;;AAGnD,SAAgB,yBAAyB,QAKhC;CACP,MAAM,EAAE,SAAS,SAAS,YAAY;CACtC,MAAM,QAAQ,OAAO;AAErB,KAAI,QAAQ,MAAM;EAChB,MAAM,EAAE,QAAQ,cAAc,GAAG,gBAAgB,QAAQ;AAEzD,OADoB,CAAC,gBAAgB,aAAa,SAAS,QAAQ,KAChD,OAAO,MAAM,QAAQ,WACtC,OAAM,IAAI,IAAIC,sCAAe,YAAY,CAAC;;AAI9C,KAAI,QAAQ,SAAS,SAAS,QAAQ;EACpC,MAAM,aAAa,QAAQ,QAAQ,QAChC,QAAQ,WAAW,CAAC,OAAO,WAAW,OAAO,YAAY,QAAQ,CACjE,KAAK,WAAW;GACf,MAAM,YAAY,EAAE,GAAG,QAAQ;AAC/B,UAAO,UAAU;AACjB,UAAO;IACP;AAEJ,MAAI,WAAW,SAAS,KAAK,OAAO,MAAM,QAAQ,WAChD,OAAM,IAAI,IAAIC,6CAAkB,EAAE,YAAY,CAAC,CAAC;;AAIpD,KAAI,QAAQ,kBAAkB;EAC5B,MAAM,SAAS,QAAQ;EACvB,MAAM,eAAe,OAAO,WAAW,WAAW,OAAO,SAAS;AAElE,OADoB,CAAC,gBAAgB,aAAa,SAAS,QAAQ,KAChD,OAAO,MAAM,QAAQ,WACtC,OAAM,IAAI,IAAIC,kEAA4B,CAAC;;AAI/C,OAAM,UAAU;EACd,GAAG,MAAM;EACT,GAAGC,+CAA0B,QAAQ;EACtC;;AAGH,eAAsB,gBACpB,SACmC;AACnC,KAAI;EACF,MAAM,cAAc,MAAM,QAAQ,MAAM;AACxC,SAAOC,kCAAoB,MAAM,YAAY;UACtC,OAAO;AACd,4BAAO,MAAM,6BAA6B,MAAM;AAChD,SAAO,IAAI,SACT,KAAK,UAAU;GACb,OAAO;GACP,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;GAChE,CAAC,EACF;GACE,QAAQ;GACR,SAAS,EAAE,gBAAgB,oBAAoB;GAChD,CACF;;;AAIL,eAAsB,oBAAoB,SAMxC;AACA,KAAI;EACF,MAAM,cAAc,MAAM,QAAQ,MAAM;EACxC,MAAM,QAAQA,kCAAoB,MAAM,YAAY;EACpD,IAAI,kBAAiC;AAErC,MACE,qBAAsB,gBACrB,OAAQ,YAAwC,oBAC/C,YACC,YAAwC,oBAAoB,MAE/D,mBACG,YAAmC,mBAAmB;AAG3D,SAAO;GAAE;GAAO;GAAiB;UAC1B,OAAO;AACd,4BAAO,MAAM,iCAAiC,MAAM;AACpD,SAAO,IAAI,SACT,KAAK,UAAU;GACb,OAAO;GACP,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;GAChE,CAAC,EACF;GACE,QAAQ;GACR,SAAS,EAAE,gBAAgB,oBAAoB;GAChD,CACF"}
1
+ {"version":3,"file":"agent-utils.cjs","names":["resolveAgents","A2UIMiddleware","MCPAppsMiddleware","OpenGenerativeUIMiddleware","extractForwardableHeaders","isIntelligenceRuntime","resolveIntelligenceUser","MCPMiddleware","INTELLIGENCE_USER_ID_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 { A2UIMiddleware } from \"@ag-ui/a2ui-middleware\";\nimport { MCPAppsMiddleware } from \"@ag-ui/mcp-apps-middleware\";\nimport { MCPMiddleware } from \"@ag-ui/mcp-middleware\";\nimport type { CopilotRuntimeLike } from \"../../core/runtime\";\nimport { isIntelligenceRuntime, resolveAgents } from \"../../core/runtime\";\nimport { OpenGenerativeUIMiddleware } from \"../../open-generative-ui-middleware\";\nimport { INTELLIGENCE_USER_ID_HEADER } from \"../../intelligence-platform/client\";\nimport { extractForwardableHeaders } from \"../header-utils\";\nimport { resolveIntelligenceUser } from \"./resolve-intelligence-user\";\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\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}): void {\n const { runtime, request, agentId } = params;\n const agent = params.agent as MiddlewareCapableAgent;\n\n if (runtime.a2ui) {\n const { agents: targetAgents, ...a2uiOptions } = runtime.a2ui;\n const shouldApply = !targetAgents || targetAgents.includes(agentId);\n if (shouldApply && typeof agent.use === \"function\") {\n agent.use(new A2UIMiddleware(a2uiOptions));\n }\n }\n\n if (runtime.mcpApps?.servers?.length) {\n const mcpServers = runtime.mcpApps.servers\n .filter((server) => !server.agentId || server.agentId === agentId)\n .map((server) => {\n const mcpServer = { ...server };\n delete mcpServer.agentId;\n return mcpServer;\n });\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 agent.headers = {\n ...agent.headers,\n ...extractForwardableHeaders(request),\n };\n}\n\n/**\n * Attach the Intelligence platform'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> {\n const { runtime, request } = params;\n const agent = params.agent as MiddlewareCapableAgent;\n\n if (\n !isIntelligenceRuntime(runtime) ||\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 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;\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 },\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,11 +1,14 @@
1
1
  import "reflect-metadata";
2
- import { resolveAgents } from "../../core/runtime.mjs";
2
+ import { isIntelligenceRuntime, resolveAgents } from "../../core/runtime.mjs";
3
3
  import { OpenGenerativeUIMiddleware } from "../../open-generative-ui-middleware.mjs";
4
+ import { INTELLIGENCE_USER_ID_HEADER } from "../../intelligence-platform/client.mjs";
4
5
  import { extractForwardableHeaders } from "../header-utils.mjs";
6
+ import { resolveIntelligenceUser } from "./resolve-intelligence-user.mjs";
5
7
  import { logger } from "@copilotkit/shared";
6
8
  import { RunAgentInputSchema } from "@ag-ui/client";
7
9
  import { A2UIMiddleware } from "@ag-ui/a2ui-middleware";
8
10
  import { MCPAppsMiddleware } from "@ag-ui/mcp-apps-middleware";
11
+ import { MCPMiddleware } from "@ag-ui/mcp-middleware";
9
12
 
10
13
  //#region src/v2/runtime/handlers/shared/agent-utils.ts
11
14
  async function cloneAgentForRequest(runtime, agentId, request) {
@@ -44,6 +47,49 @@ function configureAgentForRequest(params) {
44
47
  ...extractForwardableHeaders(request)
45
48
  };
46
49
  }
50
+ /**
51
+ * Attach the Intelligence platform's MCP tools to the agent run when
52
+ * `CopilotKitIntelligence` was constructed with
53
+ * `enableEnterpriseLearning: true`. Uses `@ag-ui/mcp-middleware`, so the
54
+ * tools are available uniformly across agent frameworks (not just
55
+ * `BuiltInAgent`).
56
+ *
57
+ * The middleware sits on a per-request agent clone, so the per-request
58
+ * auth (Bearer apiKey + resolved user-id) is baked into the transport
59
+ * headers at attach time. If user resolution fails, attachment is
60
+ * skipped silently — the intelligence run handler will reject the
61
+ * request with the same error. Note this means `identifyUser` is
62
+ * resolved twice per learning-enabled run (here and in the run handler);
63
+ * the callback is expected to be idempotent and side-effect-free.
64
+ *
65
+ * Intentionally split out from `configureAgentForRequest`: this is only
66
+ * relevant to actual agent runs, not auxiliary flows like thread-name
67
+ * generation (which has no need for MCP tools and shouldn't pay the
68
+ * `listTools` round-trip).
69
+ */
70
+ async function attachIntelligenceEnterpriseLearning(params) {
71
+ const { runtime, request } = params;
72
+ const agent = params.agent;
73
+ if (!isIntelligenceRuntime(runtime) || !runtime.intelligence?.ɵisEnterpriseLearningEnabled?.()) return;
74
+ if (typeof agent.use !== "function") {
75
+ logger.warn("CopilotKitIntelligence.enableEnterpriseLearning is enabled, but the agent does not support middleware (no `.use()` method); Intelligence tools were not attached for this run.");
76
+ return;
77
+ }
78
+ const userResult = await resolveIntelligenceUser({
79
+ runtime,
80
+ request
81
+ });
82
+ if (userResult instanceof Response) return;
83
+ agent.use(new MCPMiddleware([{
84
+ type: "http",
85
+ url: `${runtime.intelligence.ɵgetApiUrl()}/mcp`,
86
+ serverId: "intelligence",
87
+ headers: {
88
+ Authorization: `Bearer ${runtime.intelligence.ɵgetApiKey()}`,
89
+ [INTELLIGENCE_USER_ID_HEADER]: userResult.id
90
+ }
91
+ }]));
92
+ }
47
93
  async function parseRunRequest(request) {
48
94
  try {
49
95
  const requestBody = await request.json();
@@ -82,5 +128,5 @@ async function parseConnectRequest(request) {
82
128
  }
83
129
 
84
130
  //#endregion
85
- export { cloneAgentForRequest, configureAgentForRequest, parseConnectRequest, parseRunRequest };
131
+ export { attachIntelligenceEnterpriseLearning, cloneAgentForRequest, configureAgentForRequest, parseConnectRequest, parseRunRequest };
86
132
  //# sourceMappingURL=agent-utils.mjs.map
@@ -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 { A2UIMiddleware } from \"@ag-ui/a2ui-middleware\";\nimport { MCPAppsMiddleware } from \"@ag-ui/mcp-apps-middleware\";\nimport type { CopilotRuntimeLike } from \"../../core/runtime\";\nimport { resolveAgents } from \"../../core/runtime\";\nimport { OpenGenerativeUIMiddleware } from \"../../open-generative-ui-middleware\";\nimport { extractForwardableHeaders } from \"../header-utils\";\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\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}): void {\n const { runtime, request, agentId } = params;\n const agent = params.agent as MiddlewareCapableAgent;\n\n if (runtime.a2ui) {\n const { agents: targetAgents, ...a2uiOptions } = runtime.a2ui;\n const shouldApply = !targetAgents || targetAgents.includes(agentId);\n if (shouldApply && typeof agent.use === \"function\") {\n agent.use(new A2UIMiddleware(a2uiOptions));\n }\n }\n\n if (runtime.mcpApps?.servers?.length) {\n const mcpServers = runtime.mcpApps.servers\n .filter((server) => !server.agentId || server.agentId === agentId)\n .map((server) => {\n const mcpServer = { ...server };\n delete mcpServer.agentId;\n return mcpServer;\n });\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 agent.headers = {\n ...agent.headers,\n ...extractForwardableHeaders(request),\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":";;;;;;;;;;AAyBA,eAAsB,qBACpB,SACA,SACA,SACmC;CACnC,MAAM,SAAS,MAAM,cAAc,QAAQ,QAAQ,QAAQ;AAE3D,KAAI,CAAC,OAAO,SACV,QAAO,IAAI,SACT,KAAK,UAAU;EACb,OAAO;EACP,SAAS,UAAU,QAAQ;EAC5B,CAAC,EACF;EACE,QAAQ;EACR,SAAS,EAAE,gBAAgB,oBAAoB;EAChD,CACF;AAGH,QAAQ,OAAO,SAA2B,OAAO;;AAGnD,SAAgB,yBAAyB,QAKhC;CACP,MAAM,EAAE,SAAS,SAAS,YAAY;CACtC,MAAM,QAAQ,OAAO;AAErB,KAAI,QAAQ,MAAM;EAChB,MAAM,EAAE,QAAQ,cAAc,GAAG,gBAAgB,QAAQ;AAEzD,OADoB,CAAC,gBAAgB,aAAa,SAAS,QAAQ,KAChD,OAAO,MAAM,QAAQ,WACtC,OAAM,IAAI,IAAI,eAAe,YAAY,CAAC;;AAI9C,KAAI,QAAQ,SAAS,SAAS,QAAQ;EACpC,MAAM,aAAa,QAAQ,QAAQ,QAChC,QAAQ,WAAW,CAAC,OAAO,WAAW,OAAO,YAAY,QAAQ,CACjE,KAAK,WAAW;GACf,MAAM,YAAY,EAAE,GAAG,QAAQ;AAC/B,UAAO,UAAU;AACjB,UAAO;IACP;AAEJ,MAAI,WAAW,SAAS,KAAK,OAAO,MAAM,QAAQ,WAChD,OAAM,IAAI,IAAI,kBAAkB,EAAE,YAAY,CAAC,CAAC;;AAIpD,KAAI,QAAQ,kBAAkB;EAC5B,MAAM,SAAS,QAAQ;EACvB,MAAM,eAAe,OAAO,WAAW,WAAW,OAAO,SAAS;AAElE,OADoB,CAAC,gBAAgB,aAAa,SAAS,QAAQ,KAChD,OAAO,MAAM,QAAQ,WACtC,OAAM,IAAI,IAAI,4BAA4B,CAAC;;AAI/C,OAAM,UAAU;EACd,GAAG,MAAM;EACT,GAAG,0BAA0B,QAAQ;EACtC;;AAGH,eAAsB,gBACpB,SACmC;AACnC,KAAI;EACF,MAAM,cAAc,MAAM,QAAQ,MAAM;AACxC,SAAO,oBAAoB,MAAM,YAAY;UACtC,OAAO;AACd,SAAO,MAAM,6BAA6B,MAAM;AAChD,SAAO,IAAI,SACT,KAAK,UAAU;GACb,OAAO;GACP,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;GAChE,CAAC,EACF;GACE,QAAQ;GACR,SAAS,EAAE,gBAAgB,oBAAoB;GAChD,CACF;;;AAIL,eAAsB,oBAAoB,SAMxC;AACA,KAAI;EACF,MAAM,cAAc,MAAM,QAAQ,MAAM;EACxC,MAAM,QAAQ,oBAAoB,MAAM,YAAY;EACpD,IAAI,kBAAiC;AAErC,MACE,qBAAsB,gBACrB,OAAQ,YAAwC,oBAC/C,YACC,YAAwC,oBAAoB,MAE/D,mBACG,YAAmC,mBAAmB;AAG3D,SAAO;GAAE;GAAO;GAAiB;UAC1B,OAAO;AACd,SAAO,MAAM,iCAAiC,MAAM;AACpD,SAAO,IAAI,SACT,KAAK,UAAU;GACb,OAAO;GACP,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;GAChE,CAAC,EACF;GACE,QAAQ;GACR,SAAS,EAAE,gBAAgB,oBAAoB;GAChD,CACF"}
1
+ {"version":3,"file":"agent-utils.mjs","names":[],"sources":["../../../../../src/v2/runtime/handlers/shared/agent-utils.ts"],"sourcesContent":["import type { AbstractAgent, RunAgentInput } from \"@ag-ui/client\";\nimport { RunAgentInputSchema } from \"@ag-ui/client\";\nimport { A2UIMiddleware } from \"@ag-ui/a2ui-middleware\";\nimport { MCPAppsMiddleware } from \"@ag-ui/mcp-apps-middleware\";\nimport { MCPMiddleware } from \"@ag-ui/mcp-middleware\";\nimport type { CopilotRuntimeLike } from \"../../core/runtime\";\nimport { isIntelligenceRuntime, resolveAgents } from \"../../core/runtime\";\nimport { OpenGenerativeUIMiddleware } from \"../../open-generative-ui-middleware\";\nimport { INTELLIGENCE_USER_ID_HEADER } from \"../../intelligence-platform/client\";\nimport { extractForwardableHeaders } from \"../header-utils\";\nimport { resolveIntelligenceUser } from \"./resolve-intelligence-user\";\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\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}): void {\n const { runtime, request, agentId } = params;\n const agent = params.agent as MiddlewareCapableAgent;\n\n if (runtime.a2ui) {\n const { agents: targetAgents, ...a2uiOptions } = runtime.a2ui;\n const shouldApply = !targetAgents || targetAgents.includes(agentId);\n if (shouldApply && typeof agent.use === \"function\") {\n agent.use(new A2UIMiddleware(a2uiOptions));\n }\n }\n\n if (runtime.mcpApps?.servers?.length) {\n const mcpServers = runtime.mcpApps.servers\n .filter((server) => !server.agentId || server.agentId === agentId)\n .map((server) => {\n const mcpServer = { ...server };\n delete mcpServer.agentId;\n return mcpServer;\n });\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 agent.headers = {\n ...agent.headers,\n ...extractForwardableHeaders(request),\n };\n}\n\n/**\n * Attach the Intelligence platform'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> {\n const { runtime, request } = params;\n const agent = params.agent as MiddlewareCapableAgent;\n\n if (\n !isIntelligenceRuntime(runtime) ||\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 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;\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 },\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,15 +1,16 @@
1
1
  require("reflect-metadata");
2
2
  const require_runtime = require('../../../_virtual/_rolldown/runtime.cjs');
3
3
  let _copilotkit_shared = require("@copilotkit/shared");
4
+ let crypto = require("crypto");
4
5
 
5
6
  //#region src/v2/runtime/intelligence-platform/client.ts
6
7
  /**
7
8
  * Header name carrying the per-call end-user identity that the CopilotKit
8
- * Intelligence `/mcp` endpoint requires. Internal CopilotKit machinery — the
9
- * runtime stamps this onto `agent.headers` after `identifyUser` resolves,
10
- * and the auto-attach in `configureAgentForRequest` reads it back to gate
11
- * MCP-server attachment and to populate the outbound `X-Cpki-User-Id`
12
- * header on every MCP request. Not part of the public user API.
9
+ * Intelligence `/mcp` endpoint requires. Internal CopilotKit machinery —
10
+ * `attachIntelligenceEnterpriseLearning` resolves the user via `identifyUser`
11
+ * and bakes this header onto the `MCPMiddleware`'s transport config, so every
12
+ * outbound MCP request stamps `X-Cpki-User-Id: <userId>`. Not part of the
13
+ * public user API.
13
14
  *
14
15
  * @internal
15
16
  */
@@ -43,7 +44,7 @@ var CopilotKitIntelligence = class {
43
44
  #runnerWsUrl;
44
45
  #clientWsUrl;
45
46
  #apiKey;
46
- #mcpServerEnabled;
47
+ #enterpriseLearningEnabled;
47
48
  #threadCreatedListeners = /* @__PURE__ */ new Set();
48
49
  #threadUpdatedListeners = /* @__PURE__ */ new Set();
49
50
  #threadDeletedListeners = /* @__PURE__ */ new Set();
@@ -53,7 +54,7 @@ var CopilotKitIntelligence = class {
53
54
  this.#runnerWsUrl = deriveRunnerWsUrl(intelligenceWsUrl);
54
55
  this.#clientWsUrl = deriveClientWsUrl(intelligenceWsUrl);
55
56
  this.#apiKey = config.apiKey;
56
- this.#mcpServerEnabled = config.mcpServer ?? false;
57
+ this.#enterpriseLearningEnabled = config.enableEnterpriseLearning ?? false;
57
58
  if (config.onThreadCreated) this.onThreadCreated(config.onThreadCreated);
58
59
  if (config.onThreadUpdated) this.onThreadUpdated(config.onThreadUpdated);
59
60
  if (config.onThreadDeleted) this.onThreadDeleted(config.onThreadDeleted);
@@ -125,13 +126,13 @@ var CopilotKitIntelligence = class {
125
126
  ɵgetRunnerAuthToken() {
126
127
  return this.#apiKey;
127
128
  }
128
- /** @internal Used by the runtime's auto-attach to populate `Authorization`. */
129
+ /** @internal Used by `attachIntelligenceEnterpriseLearning` to populate `Authorization`. */
129
130
  ɵgetApiKey() {
130
131
  return this.#apiKey;
131
132
  }
132
- /** @internal Used by the runtime's auto-attach to gate MCP attachment. */
133
- ɵisMcpServerEnabled() {
134
- return this.#mcpServerEnabled;
133
+ /** @internal Used by `attachIntelligenceEnterpriseLearning` to gate MCP attachment. */
134
+ ɵisEnterpriseLearningEnabled() {
135
+ return this.#enterpriseLearningEnabled;
135
136
  }
136
137
  async #request(method, path, body) {
137
138
  const url = `${this.#apiUrl}${path}`;
@@ -341,6 +342,45 @@ var CopilotKitIntelligence = class {
341
342
  await this.#request("DELETE", `/api/threads/${encodeURIComponent(params.threadId)}`, { reason: `Deleted via CopilotKit runtime (userId=${params.userId}, agentId=${params.agentId})` });
342
343
  this.#invokeLifecycleCallback("onThreadDeleted", params);
343
344
  }
345
+ /**
346
+ * Annotate a thread event on the Intelligence platform's general annotation
347
+ * endpoint (`PUT /connector/annotate/:clientEventId`).
348
+ *
349
+ * This is the generalized replacement for the old
350
+ * `PUT /connector/user-actions/record/:clientEventId` endpoint. It supports
351
+ * multiple annotation types via the `type` discriminator:
352
+ * - `"user_action"` — records a user UI interaction for the self-learning loop.
353
+ * - `"set_learning_containers"` — sets the learning containers for a thread.
354
+ *
355
+ * `userId` must be resolved on the runtime side before calling this — the
356
+ * platform prefixes it with the project id from the API key.
357
+ *
358
+ * Always hits the idempotent `PUT /connector/annotate/:clientEventId`
359
+ * endpoint. A retry with the same `clientEventId` returns
360
+ * `{ id: <original>, duplicate: true }` instead of creating a new row.
361
+ * When `clientEventId` is omitted, a UUID is auto-generated for this call.
362
+ *
363
+ * @throws {@link PlatformRequestError} on non-2xx responses, OR when the
364
+ * platform returns an empty 2xx body (which would otherwise corrupt the
365
+ * caller's typed result).
366
+ */
367
+ async annotate(params) {
368
+ const clientEventId = params.clientEventId ?? (0, crypto.randomUUID)();
369
+ const path = `/connector/annotate/${encodeURIComponent(clientEventId)}`;
370
+ const body = {
371
+ type: params.type,
372
+ userId: params.userId,
373
+ threadId: params.threadId
374
+ };
375
+ if (params.payload !== void 0) body.payload = params.payload;
376
+ if (params.occurredAt !== void 0) body.occurredAt = params.occurredAt;
377
+ const response = await this.#request("PUT", path, body);
378
+ if (response == null) {
379
+ _copilotkit_shared.logger.error({ path }, "annotate: Intelligence platform returned 200 with empty or null body");
380
+ throw new PlatformRequestError("annotate: empty or null response body from Intelligence platform", 502);
381
+ }
382
+ return response;
383
+ }
344
384
  async ɵacquireThreadLock(params) {
345
385
  return this.#request("POST", `/api/threads/${encodeURIComponent(params.threadId)}/lock`, {
346
386
  runId: params.runId,