@copilotkit/runtime 1.81.0 → 1.82.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/dist/agent/index.cjs +10 -7
  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 +10 -7
  6. package/dist/agent/index.mjs.map +1 -1
  7. package/dist/lib/runtime/telemetry-agent-runner.cjs +1 -1
  8. package/dist/lib/runtime/telemetry-agent-runner.cjs.map +1 -1
  9. package/dist/lib/runtime/telemetry-agent-runner.d.cts.map +1 -1
  10. package/dist/lib/runtime/telemetry-agent-runner.d.mts.map +1 -1
  11. package/dist/lib/runtime/telemetry-agent-runner.mjs +1 -1
  12. package/dist/lib/runtime/telemetry-agent-runner.mjs.map +1 -1
  13. package/dist/package.cjs +1 -1
  14. package/dist/package.mjs +1 -1
  15. package/dist/v2/runtime/core/channel-manager.cjs +1 -0
  16. package/dist/v2/runtime/core/channel-manager.cjs.map +1 -1
  17. package/dist/v2/runtime/core/channel-manager.mjs +1 -0
  18. package/dist/v2/runtime/core/channel-manager.mjs.map +1 -1
  19. package/dist/v2/runtime/core/fetch-handler.cjs +1 -1
  20. package/dist/v2/runtime/core/fetch-handler.cjs.map +1 -1
  21. package/dist/v2/runtime/core/fetch-handler.mjs +1 -1
  22. package/dist/v2/runtime/core/fetch-handler.mjs.map +1 -1
  23. package/dist/v2/runtime/core/package-info.cjs +1 -1
  24. package/dist/v2/runtime/core/package-info.mjs +1 -1
  25. package/dist/v2/runtime/handlers/intelligence/run.cjs +3 -0
  26. package/dist/v2/runtime/handlers/intelligence/run.cjs.map +1 -1
  27. package/dist/v2/runtime/handlers/intelligence/run.mjs +3 -0
  28. package/dist/v2/runtime/handlers/intelligence/run.mjs.map +1 -1
  29. package/dist/v2/runtime/handlers/shared/mcp-apps-servers.cjs +2 -1
  30. package/dist/v2/runtime/handlers/shared/mcp-apps-servers.cjs.map +1 -1
  31. package/dist/v2/runtime/handlers/shared/mcp-apps-servers.mjs +3 -1
  32. package/dist/v2/runtime/handlers/shared/mcp-apps-servers.mjs.map +1 -1
  33. package/dist/v2/runtime/handlers/shared/sse-response.cjs +1 -1
  34. package/dist/v2/runtime/handlers/shared/sse-response.cjs.map +1 -1
  35. package/dist/v2/runtime/handlers/shared/sse-response.mjs +1 -1
  36. package/dist/v2/runtime/handlers/shared/sse-response.mjs.map +1 -1
  37. package/dist/v2/runtime/intelligence-platform/client.cjs +1 -0
  38. package/dist/v2/runtime/intelligence-platform/client.cjs.map +1 -1
  39. package/dist/v2/runtime/intelligence-platform/client.d.cts +5 -0
  40. package/dist/v2/runtime/intelligence-platform/client.d.cts.map +1 -1
  41. package/dist/v2/runtime/intelligence-platform/client.d.mts +5 -0
  42. package/dist/v2/runtime/intelligence-platform/client.d.mts.map +1 -1
  43. package/dist/v2/runtime/intelligence-platform/client.mjs +1 -0
  44. package/dist/v2/runtime/intelligence-platform/client.mjs.map +1 -1
  45. package/dist/v2/runtime/telemetry/telemetry-client.cjs +1 -1
  46. package/dist/v2/runtime/telemetry/telemetry-client.cjs.map +1 -1
  47. package/dist/v2/runtime/telemetry/telemetry-client.mjs +1 -1
  48. package/dist/v2/runtime/telemetry/telemetry-client.mjs.map +1 -1
  49. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"run.cjs","names":["telemetry","resolveIntelligenceUser","isHandlerResponse","resolveLearningContainerSelector","resolveLearningContainerId","generateThreadNameForNewThread","getPlatformErrorStatus","startThreadLockHeartbeat","getRuntimeErrorReporter","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\";\nimport { getRuntimeErrorReporter } from \"../../core/runtime-error-reporter\";\nimport type { RuntimeErrorPhase } from \"../../core/runtime-error-reporter\";\nimport {\n resolveLearningContainerId,\n resolveLearningContainerSelector,\n} from \"../../core/learning\";\nimport { getPlatformErrorStatus } from \"../shared/intelligence-utils\";\nimport { startThreadLockHeartbeat } from \"../../intelligence-platform/thread-lock-heartbeat\";\nimport type { ThreadSummary } from \"../../intelligence-platform\";\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 startTime?: number;\n}\n\nexport async function handleIntelligenceRun({\n runtime,\n request,\n agentId,\n agent,\n input,\n startTime,\n}: HandleIntelligenceRunParams): Promise<Response> {\n const runtimeTelemetry = runtime.telemetry ?? telemetry;\n\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 const proxyRequest = (\n input.forwardedProps as Record<string, unknown> | undefined\n )?.__proxiedMCPRequest;\n const isDirectResourceRead =\n input.forwardedProps?.__copilotkitMcpResourceReadOnly === true &&\n proxyRequest &&\n typeof proxyRequest === \"object\" &&\n (proxyRequest as { method?: unknown }).method === \"resources/read\";\n\n let learningContainerId: string | undefined;\n try {\n const selector = runtime.intelligence.ɵgetLearningContainerId?.();\n learningContainerId = selector\n ? await resolveLearningContainerSelector(selector, {\n surface: \"web\",\n user,\n agentId,\n input,\n })\n : await resolveLearningContainerId(runtime.learning, {\n surface: \"web\",\n request,\n threadId: input.threadId,\n runId: input.runId,\n agentId,\n userId,\n });\n } catch (error) {\n logger.error(\"Failed to resolve Learning Container:\", error);\n return Response.json(\n { error: \"Failed to resolve Learning Container\" },\n { status: 500 },\n );\n }\n\n let thread: ThreadSummary;\n try {\n const initialized = await runtime.intelligence.getOrCreateThread({\n threadId: input.threadId,\n userId,\n agentId,\n ...(learningContainerId !== undefined ? { learningContainerId } : {}),\n });\n thread = initialized.thread;\n const { created } = initialized;\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 const platformStatus = getPlatformErrorStatus(error);\n return Response.json(\n {\n error: \"Failed to initialize thread\",\n },\n {\n status:\n platformStatus !== undefined &&\n platformStatus >= 400 &&\n platformStatus < 500\n ? platformStatus\n : 502,\n },\n );\n }\n\n // MCP App resources are presentation data. Initialize the thread through the\n // usual path, then fetch without claiming its mutation lock so an approval\n // can continue while the resource server is still answering.\n if (isDirectResourceRead) {\n try {\n if (thread.agentId && thread.agentId !== agentId) {\n return Response.json(\n { error: \"Thread belongs to another agent\" },\n { status: 403 },\n );\n }\n agent.threadId = thread.id;\n const run = await agent.runAgent({\n runId: input.runId,\n tools: input.tools,\n context: input.context,\n forwardedProps: input.forwardedProps,\n });\n return Response.json({\n kind: \"mcp-resource-read\",\n threadId: thread.id,\n runId: input.runId,\n result: run.result ?? null,\n });\n } catch (error) {\n logger.error(\"MCP resource read failed:\", error);\n const status = getPlatformErrorStatus(error);\n return Response.json(\n { error: \"MCP resource read failed\" },\n { status: status && status >= 400 && status < 500 ? status : 502 },\n );\n }\n }\n\n let canonicalThreadId = input.threadId;\n let canonicalRunId = input.runId;\n let joinToken: string | undefined;\n let backendThreadId: string | undefined;\n let lockTtlSeconds: number | undefined;\n let lockRequestedAt = 0;\n try {\n // The platform starts the lock's TTL when it handles the request, so time\n // the lifetime from the send rather than from the response.\n lockRequestedAt = Date.now();\n const lockResult = await runtime.intelligence.ɵacquireThreadLock({\n supportsBackendThreadId: true,\n threadId: input.threadId,\n runId: input.runId,\n userId,\n agentId,\n ...(learningContainerId !== undefined ? { learningContainerId } : {}),\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 backendThreadId = lockResult.backendThreadId;\n lockTtlSeconds = lockResult.ttlSeconds;\n } catch (error) {\n logger.error(\"Thread lock denied:\", error);\n const platformStatus = getPlatformErrorStatus(error);\n return Response.json(\n {\n error: \"Thread lock denied\",\n },\n {\n status: platformStatus === 409 ? 409 : 502,\n },\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 historicMessageIds = new Set(\n await runtime.intelligence.ɵgetThreadMessageIds({\n threadId: canonicalThreadId,\n userId,\n }),\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 runtimeTelemetry.capture(\"oss.runtime.agent_execution_stream_started\", {});\n\n // Keep the thread lock alive while the run executes. Transient renewal\n // failures are retried within the lock's remaining TTL; only a lost lock\n // (or running out of time) aborts the run.\n const heartbeat = startThreadLockHeartbeat({\n renew: (signal) =>\n runtime.intelligence.ɵrenewThreadLock({\n threadId: canonicalThreadId,\n runId: canonicalRunId,\n ttlSeconds: runtime.lockTtlSeconds,\n ...(runtime.lockKeyPrefix !== undefined\n ? { lockKeyPrefix: runtime.lockKeyPrefix }\n : {}),\n signal,\n }),\n intervalMs: runtime.lockHeartbeatIntervalSeconds * 1_000,\n fallbackTtlSeconds: runtime.lockTtlSeconds,\n // The acquire round trip and the history lookup above both run between\n // the lock request and now, so pass the lifetime the platform set minus\n // the time already spent.\n initialTtlSeconds:\n lockTtlSeconds === undefined\n ? undefined\n : lockTtlSeconds - (Date.now() - lockRequestedAt) / 1_000,\n onLost: (err) => {\n logger.error(\"Failed to renew thread lock:\", err);\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 });\n\n const clearHeartbeat = () => {\n heartbeat.stop();\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 ...(backendThreadId === undefined ? {} : { backendThreadId }),\n agent,\n input: canonicalInput,\n ...(persistedInputMessages !== undefined ? { persistedInputMessages } : {}),\n };\n\n const runtimeErrorReporter = getRuntimeErrorReporter(runtime);\n let agentErrorReported = false;\n const reportAgentError = (error: unknown, phase: RuntimeErrorPhase) => {\n if (agentErrorReported) return;\n agentErrorReported = true;\n // Analytics describes the outcome; only the application-owned reporter\n // receives diagnostics that may contain customer or upstream content.\n runtimeTelemetry.capture(\"oss.runtime.agent_execution_stream_errored\", {\n error: \"AGENT_EXECUTION_FAILED\",\n });\n runtimeErrorReporter?.report({\n request,\n error,\n operation: \"agent.run\",\n agentId,\n threadId: canonicalThreadId,\n runId: canonicalRunId,\n phase,\n startTime,\n });\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) {\n const message =\n \"message\" in event && typeof event.message === \"string\"\n ? event.message\n : \"Runner failed before the run started\";\n reportAgentError(\n new Error(message),\n runStarted.current\n ? \"intelligence.subscription\"\n : \"intelligence.startup\",\n );\n if (!runStarted.current) {\n clearHeartbeat();\n immediateStartupErrorMessage = message;\n immediateStartupCleanup = cleanupLock(\"runner-start-failed\");\n }\n }\n },\n error: (error) => {\n reportAgentError(\n error,\n runStarted.current\n ? \"intelligence.subscription\"\n : \"intelligence.startup\",\n );\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 logger.error(\"Error running agent:\", error);\n },\n complete: () => {\n clearHeartbeat();\n // Preserve the existing completion count even when the stream contains\n // RUN_ERROR. Failure reporting is separate and carries only a safe code.\n runtimeTelemetry.capture(\n \"oss.runtime.agent_execution_stream_ended\",\n {},\n );\n },\n });\n\n await runStart.startup;\n } catch (error) {\n reportAgentError(error, \"intelligence.startup\");\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":["telemetry","resolveIntelligenceUser","isHandlerResponse","resolveLearningContainerSelector","resolveLearningContainerId","generateThreadNameForNewThread","getPlatformErrorStatus","startThreadLockHeartbeat","getRuntimeErrorReporter","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\";\nimport { getRuntimeErrorReporter } from \"../../core/runtime-error-reporter\";\nimport type { RuntimeErrorPhase } from \"../../core/runtime-error-reporter\";\nimport {\n resolveLearningContainerId,\n resolveLearningContainerSelector,\n} from \"../../core/learning\";\nimport { getPlatformErrorStatus } from \"../shared/intelligence-utils\";\nimport { startThreadLockHeartbeat } from \"../../intelligence-platform/thread-lock-heartbeat\";\nimport type { ThreadSummary } from \"../../intelligence-platform\";\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 startTime?: number;\n}\n\nexport async function handleIntelligenceRun({\n runtime,\n request,\n agentId,\n agent,\n input,\n startTime,\n}: HandleIntelligenceRunParams): Promise<Response> {\n const runtimeTelemetry = runtime.telemetry ?? telemetry;\n\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 const proxyRequest = (\n input.forwardedProps as Record<string, unknown> | undefined\n )?.__proxiedMCPRequest;\n const isDirectResourceRead =\n input.forwardedProps?.__copilotkitMcpResourceReadOnly === true &&\n proxyRequest &&\n typeof proxyRequest === \"object\" &&\n (proxyRequest as { method?: unknown }).method === \"resources/read\";\n\n // CopilotKit core sends one request ID across a request's follow-up runs\n // and resumes. Older clients send none, and the platform then uses the run ID.\n const forwardedRequestId = input.forwardedProps?.__copilotkitRequestId;\n const requestId =\n typeof forwardedRequestId === \"string\" && forwardedRequestId.length > 0\n ? forwardedRequestId\n : undefined;\n\n let learningContainerId: string | undefined;\n try {\n const selector = runtime.intelligence.ɵgetLearningContainerId?.();\n learningContainerId = selector\n ? await resolveLearningContainerSelector(selector, {\n surface: \"web\",\n user,\n agentId,\n input,\n })\n : await resolveLearningContainerId(runtime.learning, {\n surface: \"web\",\n request,\n threadId: input.threadId,\n runId: input.runId,\n agentId,\n userId,\n });\n } catch (error) {\n logger.error(\"Failed to resolve Learning Container:\", error);\n return Response.json(\n { error: \"Failed to resolve Learning Container\" },\n { status: 500 },\n );\n }\n\n let thread: ThreadSummary;\n try {\n const initialized = await runtime.intelligence.getOrCreateThread({\n threadId: input.threadId,\n userId,\n agentId,\n ...(learningContainerId !== undefined ? { learningContainerId } : {}),\n });\n thread = initialized.thread;\n const { created } = initialized;\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 const platformStatus = getPlatformErrorStatus(error);\n return Response.json(\n {\n error: \"Failed to initialize thread\",\n },\n {\n status:\n platformStatus !== undefined &&\n platformStatus >= 400 &&\n platformStatus < 500\n ? platformStatus\n : 502,\n },\n );\n }\n\n // MCP App resources are presentation data. Initialize the thread through the\n // usual path, then fetch without claiming its mutation lock so an approval\n // can continue while the resource server is still answering.\n if (isDirectResourceRead) {\n try {\n if (thread.agentId && thread.agentId !== agentId) {\n return Response.json(\n { error: \"Thread belongs to another agent\" },\n { status: 403 },\n );\n }\n agent.threadId = thread.id;\n const run = await agent.runAgent({\n runId: input.runId,\n tools: input.tools,\n context: input.context,\n forwardedProps: input.forwardedProps,\n });\n return Response.json({\n kind: \"mcp-resource-read\",\n threadId: thread.id,\n runId: input.runId,\n result: run.result ?? null,\n });\n } catch (error) {\n logger.error(\"MCP resource read failed:\", error);\n const status = getPlatformErrorStatus(error);\n return Response.json(\n { error: \"MCP resource read failed\" },\n { status: status && status >= 400 && status < 500 ? status : 502 },\n );\n }\n }\n\n let canonicalThreadId = input.threadId;\n let canonicalRunId = input.runId;\n let joinToken: string | undefined;\n let backendThreadId: string | undefined;\n let lockTtlSeconds: number | undefined;\n let lockRequestedAt = 0;\n try {\n // The platform starts the lock's TTL when it handles the request, so time\n // the lifetime from the send rather than from the response.\n lockRequestedAt = Date.now();\n const lockResult = await runtime.intelligence.ɵacquireThreadLock({\n supportsBackendThreadId: true,\n threadId: input.threadId,\n runId: input.runId,\n userId,\n agentId,\n ...(learningContainerId !== undefined ? { learningContainerId } : {}),\n ...(requestId !== undefined ? { requestId } : {}),\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 backendThreadId = lockResult.backendThreadId;\n lockTtlSeconds = lockResult.ttlSeconds;\n } catch (error) {\n logger.error(\"Thread lock denied:\", error);\n const platformStatus = getPlatformErrorStatus(error);\n return Response.json(\n {\n error: \"Thread lock denied\",\n },\n {\n status: platformStatus === 409 ? 409 : 502,\n },\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 historicMessageIds = new Set(\n await runtime.intelligence.ɵgetThreadMessageIds({\n threadId: canonicalThreadId,\n userId,\n }),\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 runtimeTelemetry.capture(\"oss.runtime.agent_execution_stream_started\", {});\n\n // Keep the thread lock alive while the run executes. Transient renewal\n // failures are retried within the lock's remaining TTL; only a lost lock\n // (or running out of time) aborts the run.\n const heartbeat = startThreadLockHeartbeat({\n renew: (signal) =>\n runtime.intelligence.ɵrenewThreadLock({\n threadId: canonicalThreadId,\n runId: canonicalRunId,\n ttlSeconds: runtime.lockTtlSeconds,\n ...(runtime.lockKeyPrefix !== undefined\n ? { lockKeyPrefix: runtime.lockKeyPrefix }\n : {}),\n signal,\n }),\n intervalMs: runtime.lockHeartbeatIntervalSeconds * 1_000,\n fallbackTtlSeconds: runtime.lockTtlSeconds,\n // The acquire round trip and the history lookup above both run between\n // the lock request and now, so pass the lifetime the platform set minus\n // the time already spent.\n initialTtlSeconds:\n lockTtlSeconds === undefined\n ? undefined\n : lockTtlSeconds - (Date.now() - lockRequestedAt) / 1_000,\n onLost: (err) => {\n logger.error(\"Failed to renew thread lock:\", err);\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 });\n\n const clearHeartbeat = () => {\n heartbeat.stop();\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 ...(backendThreadId === undefined ? {} : { backendThreadId }),\n agent,\n input: canonicalInput,\n ...(persistedInputMessages !== undefined ? { persistedInputMessages } : {}),\n };\n\n const runtimeErrorReporter = getRuntimeErrorReporter(runtime);\n let agentErrorReported = false;\n const reportAgentError = (error: unknown, phase: RuntimeErrorPhase) => {\n if (agentErrorReported) return;\n agentErrorReported = true;\n // Analytics describes the outcome; only the application-owned reporter\n // receives diagnostics that may contain customer or upstream content.\n runtimeTelemetry.capture(\"oss.runtime.agent_execution_stream_errored\", {\n error: \"AGENT_EXECUTION_FAILED\",\n });\n runtimeErrorReporter?.report({\n request,\n error,\n operation: \"agent.run\",\n agentId,\n threadId: canonicalThreadId,\n runId: canonicalRunId,\n phase,\n startTime,\n });\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) {\n const message =\n \"message\" in event && typeof event.message === \"string\"\n ? event.message\n : \"Runner failed before the run started\";\n reportAgentError(\n new Error(message),\n runStarted.current\n ? \"intelligence.subscription\"\n : \"intelligence.startup\",\n );\n if (!runStarted.current) {\n clearHeartbeat();\n immediateStartupErrorMessage = message;\n immediateStartupCleanup = cleanupLock(\"runner-start-failed\");\n }\n }\n },\n error: (error) => {\n reportAgentError(\n error,\n runStarted.current\n ? \"intelligence.subscription\"\n : \"intelligence.startup\",\n );\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 logger.error(\"Error running agent:\", error);\n },\n complete: () => {\n clearHeartbeat();\n // Preserve the existing completion count even when the stream contains\n // RUN_ERROR. Failure reporting is separate and carries only a safe code.\n runtimeTelemetry.capture(\n \"oss.runtime.agent_execution_stream_ended\",\n {},\n );\n },\n });\n\n await runStart.startup;\n } catch (error) {\n reportAgentError(error, \"intelligence.startup\");\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":";;;;;;;;;;;;;;;;;AA4BA,SAAS,4BAA4B,QAGI;AACvC,QAAO;EACL,WAAW,OAAO;EAClB,OAAO,UAAU,OAAO;EACzB;;AAYH,SAAS,yBACP,QAE0B;AAG1B,QACE,OAHgB,OAGC,2BAA2B,eAC3C,OAAO,UAAU,eAAe,KAAK,QAAQ,yBAAyB,IACrE,OAAO,UAAU,eAAe,KAAK,QAAQ,UAAU;;AAa7D,eAAsB,sBAAsB,EAC1C,SACA,SACA,SACA,OACA,OACA,aACiD;CACjD,MAAM,mBAAmB,QAAQ,aAAaA;AAE9C,KAAI,CAAC,QAAQ,aACX,QAAO,SAAS,KACd;EACE,OAAO;EACP,SAAS;EACV,EACD,EAAE,QAAQ,KAAK,CAChB;CAGH,MAAM,OAAO,MAAMC,0DAAwB;EAAE;EAAS;EAAS,CAAC;AAChE,KAAIC,wCAAkB,KAAK,CACzB,QAAO;CAET,MAAM,SAAS,KAAK;CAEpB,MAAM,eACJ,MAAM,gBACL;CACH,MAAM,uBACJ,MAAM,gBAAgB,oCAAoC,QAC1D,gBACA,OAAO,iBAAiB,YACvB,aAAsC,WAAW;CAIpD,MAAM,qBAAqB,MAAM,gBAAgB;CACjD,MAAM,YACJ,OAAO,uBAAuB,YAAY,mBAAmB,SAAS,IAClE,qBACA;CAEN,IAAI;AACJ,KAAI;EACF,MAAM,WAAW,QAAQ,aAAa,2BAA2B;AACjE,wBAAsB,WAClB,MAAMC,kDAAiC,UAAU;GAC/C,SAAS;GACT;GACA;GACA;GACD,CAAC,GACF,MAAMC,4CAA2B,QAAQ,UAAU;GACjD,SAAS;GACT;GACA,UAAU,MAAM;GAChB,OAAO,MAAM;GACb;GACA;GACD,CAAC;UACC,OAAO;AACd,4BAAO,MAAM,yCAAyC,MAAM;AAC5D,SAAO,SAAS,KACd,EAAE,OAAO,wCAAwC,EACjD,EAAE,QAAQ,KAAK,CAChB;;CAGH,IAAI;AACJ,KAAI;EACF,MAAM,cAAc,MAAM,QAAQ,aAAa,kBAAkB;GAC/D,UAAU,MAAM;GAChB;GACA;GACA,GAAI,wBAAwB,SAAY,EAAE,qBAAqB,GAAG,EAAE;GACrE,CAAC;AACF,WAAS,YAAY;EACrB,MAAM,EAAE,YAAY;AAEpB,MAAI,WAAW,QAAQ,uBAAuB,CAAC,OAAO,MAAM,MAAM,CAChE,CAAKC,oDAA+B;GAClC;GACA;GACA;GACA,aAAa;GACb;GACA;GACD,CAAC,CAAC,OAAO,cAAc;AACtB,6BAAO,MAAM,mCAAmC,UAAU;IAC1D;UAEG,OAAO;AACd,4BAAO,MAAM,mCAAmC,MAAM;EACtD,MAAM,iBAAiBC,kDAAuB,MAAM;AACpD,SAAO,SAAS,KACd,EACE,OAAO,+BACR,EACD,EACE,QACE,mBAAmB,UACnB,kBAAkB,OAClB,iBAAiB,MACb,iBACA,KACP,CACF;;AAMH,KAAI,qBACF,KAAI;AACF,MAAI,OAAO,WAAW,OAAO,YAAY,QACvC,QAAO,SAAS,KACd,EAAE,OAAO,mCAAmC,EAC5C,EAAE,QAAQ,KAAK,CAChB;AAEH,QAAM,WAAW,OAAO;EACxB,MAAM,MAAM,MAAM,MAAM,SAAS;GAC/B,OAAO,MAAM;GACb,OAAO,MAAM;GACb,SAAS,MAAM;GACf,gBAAgB,MAAM;GACvB,CAAC;AACF,SAAO,SAAS,KAAK;GACnB,MAAM;GACN,UAAU,OAAO;GACjB,OAAO,MAAM;GACb,QAAQ,IAAI,UAAU;GACvB,CAAC;UACK,OAAO;AACd,4BAAO,MAAM,6BAA6B,MAAM;EAChD,MAAM,SAASA,kDAAuB,MAAM;AAC5C,SAAO,SAAS,KACd,EAAE,OAAO,4BAA4B,EACrC,EAAE,QAAQ,UAAU,UAAU,OAAO,SAAS,MAAM,SAAS,KAAK,CACnE;;CAIL,IAAI,oBAAoB,MAAM;CAC9B,IAAI,iBAAiB,MAAM;CAC3B,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI,kBAAkB;AACtB,KAAI;AAGF,oBAAkB,KAAK,KAAK;EAC5B,MAAM,aAAa,MAAM,QAAQ,aAAa,mBAAmB;GAC/D,yBAAyB;GACzB,UAAU,MAAM;GAChB,OAAO,MAAM;GACb;GACA;GACA,GAAI,wBAAwB,SAAY,EAAE,qBAAqB,GAAG,EAAE;GACpE,GAAI,cAAc,SAAY,EAAE,WAAW,GAAG,EAAE;GAChD,GAAI,QAAQ,kBAAkB,SAC1B,EAAE,eAAe,QAAQ,eAAe,GACxC,EAAE;GACN,YAAY,QAAQ;GACrB,CAAC;AACF,sBAAoB,WAAW;AAC/B,mBAAiB,WAAW;AAC5B,cAAY,WAAW;AACvB,oBAAkB,WAAW;AAC7B,mBAAiB,WAAW;UACrB,OAAO;AACd,4BAAO,MAAM,uBAAuB,MAAM;EAC1C,MAAM,iBAAiBA,kDAAuB,MAAM;AACpD,SAAO,SAAS,KACd,EACE,OAAO,sBACR,EACD,EACE,QAAQ,mBAAmB,MAAM,MAAM,KACxC,CACF;;CAGH,MAAM,eAAe,WACnB,QAAQ,aACL,mBAAmB;EAClB,UAAU,qBAAqB,MAAM;EACrC,OAAO,kBAAkB,MAAM;EAChC,CAAC,CACD,OAAO,iBAAiB;AACvB,4BAAO,MACL;GAAE,KAAK;GAAc;GAAQ,EAC7B,gCACD;GACD;AAEN,KAAI,CAAC,qBAAqB,CAAC,kBAAkB,CAAC,WAAW;AACvD,QAAM,YAAY,0BAA0B;AAC5C,SAAO,SAAS,KACd;GACE,OAAO;GACP,SACE;GACH,EACD,EAAE,QAAQ,KAAK,CAChB;;CAGH,MAAM,iBAAgC;EACpC,GAAG;EACH,UAAU;EACV,OAAO;EACR;CAED,IAAI;AACJ,KAAI,MAAM,QAAQ,MAAM,SAAS,CAC/B,KAAI;EACF,MAAM,qBAAqB,IAAI,IAC7B,MAAM,QAAQ,aAAa,qBAAqB;GAC9C,UAAU;GACV;GACD,CAAC,CACH;AACD,2BAAyB,MAAM,SAAS,QACrC,YAAY,CAAC,mBAAmB,IAAI,QAAQ,GAAG,CACjD;UACM,OAAO;AACd,4BAAO,MAAM,iCAAiC,MAAM;AACpD,QAAM,YAAY,+BAA+B;AACjD,SAAO,SAAS,KACd,EACE,OAAO,gCACR,EACD,EAAE,QAAQ,KAAK,CAChB;;AAIL,kBAAiB,QAAQ,8CAA8C,EAAE,CAAC;CAK1E,MAAM,YAAYC,uDAAyB;EACzC,QAAQ,WACN,QAAQ,aAAa,iBAAiB;GACpC,UAAU;GACV,OAAO;GACP,YAAY,QAAQ;GACpB,GAAI,QAAQ,kBAAkB,SAC1B,EAAE,eAAe,QAAQ,eAAe,GACxC,EAAE;GACN;GACD,CAAC;EACJ,YAAY,QAAQ,+BAA+B;EACnD,oBAAoB,QAAQ;EAI5B,mBACE,mBAAmB,SACf,SACA,kBAAkB,KAAK,KAAK,GAAG,mBAAmB;EACxD,SAAS,QAAQ;AACf,6BAAO,MAAM,gCAAgC,IAAI;AACjD,OAAI;AACF,UAAM,UAAU;YACT,YAAY;AACnB,8BAAO,MACL,qDACA,WACD;;;EAGN,CAAC;CAEF,MAAM,uBAAuB;AAC3B,YAAU,MAAM;;CAGlB,MAAM,aAAa,EAAE,SAAS,OAAO;CACrC,IAAI;CACJ,IAAI;CAEJ,MAAM,aAAoC;EACxC,UAAU;EACV,GAAI,oBAAoB,SAAY,EAAE,GAAG,EAAE,iBAAiB;EAC5D;EACA,OAAO;EACP,GAAI,2BAA2B,SAAY,EAAE,wBAAwB,GAAG,EAAE;EAC3E;CAED,MAAM,uBAAuBC,uDAAwB,QAAQ;CAC7D,IAAI,qBAAqB;CACzB,MAAM,oBAAoB,OAAgB,UAA6B;AACrE,MAAI,mBAAoB;AACxB,uBAAqB;AAGrB,mBAAiB,QAAQ,8CAA8C,EACrE,OAAO,0BACR,CAAC;AACF,wBAAsB,OAAO;GAC3B;GACA;GACA,WAAW;GACX;GACA,UAAU;GACV,OAAO;GACP;GACA;GACD,CAAC;;AAGJ,KAAI;EACF,MAAM,WAAW,yBAAyB,QAAQ,OAAO,GACrD,QAAQ,OAAO,uBAAuB,WAAW,GACjD;GACE,QAAQ,QAAQ,OAAO,IAAI,WAAW;GACtC,SAAS,QAAQ,SAAS;GAC3B;AAEL,WAAS,OAAO,UAAU;GACxB,OAAO,UAAqB;AAC1B,QAAI,MAAM,SAASC,wBAAU,YAC3B,YAAW,UAAU;AAEvB,QAAI,MAAM,SAASA,wBAAU,WAAW;KACtC,MAAM,UACJ,aAAa,SAAS,OAAO,MAAM,YAAY,WAC3C,MAAM,UACN;AACN,sBACE,IAAI,MAAM,QAAQ,EAClB,WAAW,UACP,8BACA,uBACL;AACD,SAAI,CAAC,WAAW,SAAS;AACvB,sBAAgB;AAChB,qCAA+B;AAC/B,gCAA0B,YAAY,sBAAsB;;;;GAIlE,QAAQ,UAAU;AAChB,qBACE,OACA,WAAW,UACP,8BACA,uBACL;AACD,oBAAgB;AAChB,QAAI,CAAC,WAAW,SAAS;AACvB,oCACE,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AACxD,+BAA0B,YAAY,qBAAqB;UAE3D,aAAY,eAAe;AAE7B,8BAAO,MAAM,wBAAwB,MAAM;;GAE7C,gBAAgB;AACd,oBAAgB;AAGhB,qBAAiB,QACf,4CACA,EAAE,CACH;;GAEJ,CAAC;AAEF,QAAM,SAAS;UACR,OAAO;AACd,mBAAiB,OAAO,uBAAuB;AAC/C,kBAAgB;AAChB,SAAO,2BAA2B,YAAY,qBAAqB;AACnE,4BAAO,MAAM,gCAAgC,MAAM;AACnD,SAAO,SAAS,KACd;GACE,OAAO;GACP,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;GAChE,EACD,EAAE,QAAQ,KAAK,CAChB;;AAGH,KAAI,8BAA8B;AAChC,QAAM;AACN,SAAO,SAAS,KACd;GACE,OAAO;GACP,SAAS;GACV,EACD,EAAE,QAAQ,KAAK,CAChB;;AAKH,QAAO,SAAS,KACd;EACE,UAAU;EACV,OAAO;EACP;EACA,UAAU,4BAA4B;GACpC,WAAW,QAAQ,aAAa,iBAAiB;GACjD,UAAU;GACX,CAAC;EACH,EACD,EACE,SAAS,EAAE,iBAAiB,YAAY,EACzC,CACF"}
@@ -37,6 +37,8 @@ async function handleIntelligenceRun({ runtime, request, agentId, agent, input,
37
37
  const userId = user.id;
38
38
  const proxyRequest = input.forwardedProps?.__proxiedMCPRequest;
39
39
  const isDirectResourceRead = input.forwardedProps?.__copilotkitMcpResourceReadOnly === true && proxyRequest && typeof proxyRequest === "object" && proxyRequest.method === "resources/read";
40
+ const forwardedRequestId = input.forwardedProps?.__copilotkitRequestId;
41
+ const requestId = typeof forwardedRequestId === "string" && forwardedRequestId.length > 0 ? forwardedRequestId : void 0;
40
42
  let learningContainerId;
41
43
  try {
42
44
  const selector = runtime.intelligence.ɵgetLearningContainerId?.();
@@ -117,6 +119,7 @@ async function handleIntelligenceRun({ runtime, request, agentId, agent, input,
117
119
  userId,
118
120
  agentId,
119
121
  ...learningContainerId !== void 0 ? { learningContainerId } : {},
122
+ ...requestId !== void 0 ? { requestId } : {},
120
123
  ...runtime.lockKeyPrefix !== void 0 ? { lockKeyPrefix: runtime.lockKeyPrefix } : {},
121
124
  ttlSeconds: runtime.lockTtlSeconds
122
125
  });
@@ -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\";\nimport { getRuntimeErrorReporter } from \"../../core/runtime-error-reporter\";\nimport type { RuntimeErrorPhase } from \"../../core/runtime-error-reporter\";\nimport {\n resolveLearningContainerId,\n resolveLearningContainerSelector,\n} from \"../../core/learning\";\nimport { getPlatformErrorStatus } from \"../shared/intelligence-utils\";\nimport { startThreadLockHeartbeat } from \"../../intelligence-platform/thread-lock-heartbeat\";\nimport type { ThreadSummary } from \"../../intelligence-platform\";\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 startTime?: number;\n}\n\nexport async function handleIntelligenceRun({\n runtime,\n request,\n agentId,\n agent,\n input,\n startTime,\n}: HandleIntelligenceRunParams): Promise<Response> {\n const runtimeTelemetry = runtime.telemetry ?? telemetry;\n\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 const proxyRequest = (\n input.forwardedProps as Record<string, unknown> | undefined\n )?.__proxiedMCPRequest;\n const isDirectResourceRead =\n input.forwardedProps?.__copilotkitMcpResourceReadOnly === true &&\n proxyRequest &&\n typeof proxyRequest === \"object\" &&\n (proxyRequest as { method?: unknown }).method === \"resources/read\";\n\n let learningContainerId: string | undefined;\n try {\n const selector = runtime.intelligence.ɵgetLearningContainerId?.();\n learningContainerId = selector\n ? await resolveLearningContainerSelector(selector, {\n surface: \"web\",\n user,\n agentId,\n input,\n })\n : await resolveLearningContainerId(runtime.learning, {\n surface: \"web\",\n request,\n threadId: input.threadId,\n runId: input.runId,\n agentId,\n userId,\n });\n } catch (error) {\n logger.error(\"Failed to resolve Learning Container:\", error);\n return Response.json(\n { error: \"Failed to resolve Learning Container\" },\n { status: 500 },\n );\n }\n\n let thread: ThreadSummary;\n try {\n const initialized = await runtime.intelligence.getOrCreateThread({\n threadId: input.threadId,\n userId,\n agentId,\n ...(learningContainerId !== undefined ? { learningContainerId } : {}),\n });\n thread = initialized.thread;\n const { created } = initialized;\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 const platformStatus = getPlatformErrorStatus(error);\n return Response.json(\n {\n error: \"Failed to initialize thread\",\n },\n {\n status:\n platformStatus !== undefined &&\n platformStatus >= 400 &&\n platformStatus < 500\n ? platformStatus\n : 502,\n },\n );\n }\n\n // MCP App resources are presentation data. Initialize the thread through the\n // usual path, then fetch without claiming its mutation lock so an approval\n // can continue while the resource server is still answering.\n if (isDirectResourceRead) {\n try {\n if (thread.agentId && thread.agentId !== agentId) {\n return Response.json(\n { error: \"Thread belongs to another agent\" },\n { status: 403 },\n );\n }\n agent.threadId = thread.id;\n const run = await agent.runAgent({\n runId: input.runId,\n tools: input.tools,\n context: input.context,\n forwardedProps: input.forwardedProps,\n });\n return Response.json({\n kind: \"mcp-resource-read\",\n threadId: thread.id,\n runId: input.runId,\n result: run.result ?? null,\n });\n } catch (error) {\n logger.error(\"MCP resource read failed:\", error);\n const status = getPlatformErrorStatus(error);\n return Response.json(\n { error: \"MCP resource read failed\" },\n { status: status && status >= 400 && status < 500 ? status : 502 },\n );\n }\n }\n\n let canonicalThreadId = input.threadId;\n let canonicalRunId = input.runId;\n let joinToken: string | undefined;\n let backendThreadId: string | undefined;\n let lockTtlSeconds: number | undefined;\n let lockRequestedAt = 0;\n try {\n // The platform starts the lock's TTL when it handles the request, so time\n // the lifetime from the send rather than from the response.\n lockRequestedAt = Date.now();\n const lockResult = await runtime.intelligence.ɵacquireThreadLock({\n supportsBackendThreadId: true,\n threadId: input.threadId,\n runId: input.runId,\n userId,\n agentId,\n ...(learningContainerId !== undefined ? { learningContainerId } : {}),\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 backendThreadId = lockResult.backendThreadId;\n lockTtlSeconds = lockResult.ttlSeconds;\n } catch (error) {\n logger.error(\"Thread lock denied:\", error);\n const platformStatus = getPlatformErrorStatus(error);\n return Response.json(\n {\n error: \"Thread lock denied\",\n },\n {\n status: platformStatus === 409 ? 409 : 502,\n },\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 historicMessageIds = new Set(\n await runtime.intelligence.ɵgetThreadMessageIds({\n threadId: canonicalThreadId,\n userId,\n }),\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 runtimeTelemetry.capture(\"oss.runtime.agent_execution_stream_started\", {});\n\n // Keep the thread lock alive while the run executes. Transient renewal\n // failures are retried within the lock's remaining TTL; only a lost lock\n // (or running out of time) aborts the run.\n const heartbeat = startThreadLockHeartbeat({\n renew: (signal) =>\n runtime.intelligence.ɵrenewThreadLock({\n threadId: canonicalThreadId,\n runId: canonicalRunId,\n ttlSeconds: runtime.lockTtlSeconds,\n ...(runtime.lockKeyPrefix !== undefined\n ? { lockKeyPrefix: runtime.lockKeyPrefix }\n : {}),\n signal,\n }),\n intervalMs: runtime.lockHeartbeatIntervalSeconds * 1_000,\n fallbackTtlSeconds: runtime.lockTtlSeconds,\n // The acquire round trip and the history lookup above both run between\n // the lock request and now, so pass the lifetime the platform set minus\n // the time already spent.\n initialTtlSeconds:\n lockTtlSeconds === undefined\n ? undefined\n : lockTtlSeconds - (Date.now() - lockRequestedAt) / 1_000,\n onLost: (err) => {\n logger.error(\"Failed to renew thread lock:\", err);\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 });\n\n const clearHeartbeat = () => {\n heartbeat.stop();\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 ...(backendThreadId === undefined ? {} : { backendThreadId }),\n agent,\n input: canonicalInput,\n ...(persistedInputMessages !== undefined ? { persistedInputMessages } : {}),\n };\n\n const runtimeErrorReporter = getRuntimeErrorReporter(runtime);\n let agentErrorReported = false;\n const reportAgentError = (error: unknown, phase: RuntimeErrorPhase) => {\n if (agentErrorReported) return;\n agentErrorReported = true;\n // Analytics describes the outcome; only the application-owned reporter\n // receives diagnostics that may contain customer or upstream content.\n runtimeTelemetry.capture(\"oss.runtime.agent_execution_stream_errored\", {\n error: \"AGENT_EXECUTION_FAILED\",\n });\n runtimeErrorReporter?.report({\n request,\n error,\n operation: \"agent.run\",\n agentId,\n threadId: canonicalThreadId,\n runId: canonicalRunId,\n phase,\n startTime,\n });\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) {\n const message =\n \"message\" in event && typeof event.message === \"string\"\n ? event.message\n : \"Runner failed before the run started\";\n reportAgentError(\n new Error(message),\n runStarted.current\n ? \"intelligence.subscription\"\n : \"intelligence.startup\",\n );\n if (!runStarted.current) {\n clearHeartbeat();\n immediateStartupErrorMessage = message;\n immediateStartupCleanup = cleanupLock(\"runner-start-failed\");\n }\n }\n },\n error: (error) => {\n reportAgentError(\n error,\n runStarted.current\n ? \"intelligence.subscription\"\n : \"intelligence.startup\",\n );\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 logger.error(\"Error running agent:\", error);\n },\n complete: () => {\n clearHeartbeat();\n // Preserve the existing completion count even when the stream contains\n // RUN_ERROR. Failure reporting is separate and carries only a safe code.\n runtimeTelemetry.capture(\n \"oss.runtime.agent_execution_stream_ended\",\n {},\n );\n },\n });\n\n await runStart.startup;\n } catch (error) {\n reportAgentError(error, \"intelligence.startup\");\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\";\nimport { getRuntimeErrorReporter } from \"../../core/runtime-error-reporter\";\nimport type { RuntimeErrorPhase } from \"../../core/runtime-error-reporter\";\nimport {\n resolveLearningContainerId,\n resolveLearningContainerSelector,\n} from \"../../core/learning\";\nimport { getPlatformErrorStatus } from \"../shared/intelligence-utils\";\nimport { startThreadLockHeartbeat } from \"../../intelligence-platform/thread-lock-heartbeat\";\nimport type { ThreadSummary } from \"../../intelligence-platform\";\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 startTime?: number;\n}\n\nexport async function handleIntelligenceRun({\n runtime,\n request,\n agentId,\n agent,\n input,\n startTime,\n}: HandleIntelligenceRunParams): Promise<Response> {\n const runtimeTelemetry = runtime.telemetry ?? telemetry;\n\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 const proxyRequest = (\n input.forwardedProps as Record<string, unknown> | undefined\n )?.__proxiedMCPRequest;\n const isDirectResourceRead =\n input.forwardedProps?.__copilotkitMcpResourceReadOnly === true &&\n proxyRequest &&\n typeof proxyRequest === \"object\" &&\n (proxyRequest as { method?: unknown }).method === \"resources/read\";\n\n // CopilotKit core sends one request ID across a request's follow-up runs\n // and resumes. Older clients send none, and the platform then uses the run ID.\n const forwardedRequestId = input.forwardedProps?.__copilotkitRequestId;\n const requestId =\n typeof forwardedRequestId === \"string\" && forwardedRequestId.length > 0\n ? forwardedRequestId\n : undefined;\n\n let learningContainerId: string | undefined;\n try {\n const selector = runtime.intelligence.ɵgetLearningContainerId?.();\n learningContainerId = selector\n ? await resolveLearningContainerSelector(selector, {\n surface: \"web\",\n user,\n agentId,\n input,\n })\n : await resolveLearningContainerId(runtime.learning, {\n surface: \"web\",\n request,\n threadId: input.threadId,\n runId: input.runId,\n agentId,\n userId,\n });\n } catch (error) {\n logger.error(\"Failed to resolve Learning Container:\", error);\n return Response.json(\n { error: \"Failed to resolve Learning Container\" },\n { status: 500 },\n );\n }\n\n let thread: ThreadSummary;\n try {\n const initialized = await runtime.intelligence.getOrCreateThread({\n threadId: input.threadId,\n userId,\n agentId,\n ...(learningContainerId !== undefined ? { learningContainerId } : {}),\n });\n thread = initialized.thread;\n const { created } = initialized;\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 const platformStatus = getPlatformErrorStatus(error);\n return Response.json(\n {\n error: \"Failed to initialize thread\",\n },\n {\n status:\n platformStatus !== undefined &&\n platformStatus >= 400 &&\n platformStatus < 500\n ? platformStatus\n : 502,\n },\n );\n }\n\n // MCP App resources are presentation data. Initialize the thread through the\n // usual path, then fetch without claiming its mutation lock so an approval\n // can continue while the resource server is still answering.\n if (isDirectResourceRead) {\n try {\n if (thread.agentId && thread.agentId !== agentId) {\n return Response.json(\n { error: \"Thread belongs to another agent\" },\n { status: 403 },\n );\n }\n agent.threadId = thread.id;\n const run = await agent.runAgent({\n runId: input.runId,\n tools: input.tools,\n context: input.context,\n forwardedProps: input.forwardedProps,\n });\n return Response.json({\n kind: \"mcp-resource-read\",\n threadId: thread.id,\n runId: input.runId,\n result: run.result ?? null,\n });\n } catch (error) {\n logger.error(\"MCP resource read failed:\", error);\n const status = getPlatformErrorStatus(error);\n return Response.json(\n { error: \"MCP resource read failed\" },\n { status: status && status >= 400 && status < 500 ? status : 502 },\n );\n }\n }\n\n let canonicalThreadId = input.threadId;\n let canonicalRunId = input.runId;\n let joinToken: string | undefined;\n let backendThreadId: string | undefined;\n let lockTtlSeconds: number | undefined;\n let lockRequestedAt = 0;\n try {\n // The platform starts the lock's TTL when it handles the request, so time\n // the lifetime from the send rather than from the response.\n lockRequestedAt = Date.now();\n const lockResult = await runtime.intelligence.ɵacquireThreadLock({\n supportsBackendThreadId: true,\n threadId: input.threadId,\n runId: input.runId,\n userId,\n agentId,\n ...(learningContainerId !== undefined ? { learningContainerId } : {}),\n ...(requestId !== undefined ? { requestId } : {}),\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 backendThreadId = lockResult.backendThreadId;\n lockTtlSeconds = lockResult.ttlSeconds;\n } catch (error) {\n logger.error(\"Thread lock denied:\", error);\n const platformStatus = getPlatformErrorStatus(error);\n return Response.json(\n {\n error: \"Thread lock denied\",\n },\n {\n status: platformStatus === 409 ? 409 : 502,\n },\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 historicMessageIds = new Set(\n await runtime.intelligence.ɵgetThreadMessageIds({\n threadId: canonicalThreadId,\n userId,\n }),\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 runtimeTelemetry.capture(\"oss.runtime.agent_execution_stream_started\", {});\n\n // Keep the thread lock alive while the run executes. Transient renewal\n // failures are retried within the lock's remaining TTL; only a lost lock\n // (or running out of time) aborts the run.\n const heartbeat = startThreadLockHeartbeat({\n renew: (signal) =>\n runtime.intelligence.ɵrenewThreadLock({\n threadId: canonicalThreadId,\n runId: canonicalRunId,\n ttlSeconds: runtime.lockTtlSeconds,\n ...(runtime.lockKeyPrefix !== undefined\n ? { lockKeyPrefix: runtime.lockKeyPrefix }\n : {}),\n signal,\n }),\n intervalMs: runtime.lockHeartbeatIntervalSeconds * 1_000,\n fallbackTtlSeconds: runtime.lockTtlSeconds,\n // The acquire round trip and the history lookup above both run between\n // the lock request and now, so pass the lifetime the platform set minus\n // the time already spent.\n initialTtlSeconds:\n lockTtlSeconds === undefined\n ? undefined\n : lockTtlSeconds - (Date.now() - lockRequestedAt) / 1_000,\n onLost: (err) => {\n logger.error(\"Failed to renew thread lock:\", err);\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 });\n\n const clearHeartbeat = () => {\n heartbeat.stop();\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 ...(backendThreadId === undefined ? {} : { backendThreadId }),\n agent,\n input: canonicalInput,\n ...(persistedInputMessages !== undefined ? { persistedInputMessages } : {}),\n };\n\n const runtimeErrorReporter = getRuntimeErrorReporter(runtime);\n let agentErrorReported = false;\n const reportAgentError = (error: unknown, phase: RuntimeErrorPhase) => {\n if (agentErrorReported) return;\n agentErrorReported = true;\n // Analytics describes the outcome; only the application-owned reporter\n // receives diagnostics that may contain customer or upstream content.\n runtimeTelemetry.capture(\"oss.runtime.agent_execution_stream_errored\", {\n error: \"AGENT_EXECUTION_FAILED\",\n });\n runtimeErrorReporter?.report({\n request,\n error,\n operation: \"agent.run\",\n agentId,\n threadId: canonicalThreadId,\n runId: canonicalRunId,\n phase,\n startTime,\n });\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) {\n const message =\n \"message\" in event && typeof event.message === \"string\"\n ? event.message\n : \"Runner failed before the run started\";\n reportAgentError(\n new Error(message),\n runStarted.current\n ? \"intelligence.subscription\"\n : \"intelligence.startup\",\n );\n if (!runStarted.current) {\n clearHeartbeat();\n immediateStartupErrorMessage = message;\n immediateStartupCleanup = cleanupLock(\"runner-start-failed\");\n }\n }\n },\n error: (error) => {\n reportAgentError(\n error,\n runStarted.current\n ? \"intelligence.subscription\"\n : \"intelligence.startup\",\n );\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 logger.error(\"Error running agent:\", error);\n },\n complete: () => {\n clearHeartbeat();\n // Preserve the existing completion count even when the stream contains\n // RUN_ERROR. Failure reporting is separate and carries only a safe code.\n runtimeTelemetry.capture(\n \"oss.runtime.agent_execution_stream_ended\",\n {},\n );\n },\n });\n\n await runStart.startup;\n } catch (error) {\n reportAgentError(error, \"intelligence.startup\");\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":";;;;;;;;;;;;;;;;AA4BA,SAAS,4BAA4B,QAGI;AACvC,QAAO;EACL,WAAW,OAAO;EAClB,OAAO,UAAU,OAAO;EACzB;;AAYH,SAAS,yBACP,QAE0B;AAG1B,QACE,OAHgB,OAGC,2BAA2B,eAC3C,OAAO,UAAU,eAAe,KAAK,QAAQ,yBAAyB,IACrE,OAAO,UAAU,eAAe,KAAK,QAAQ,UAAU;;AAa7D,eAAsB,sBAAsB,EAC1C,SACA,SACA,SACA,OACA,OACA,aACiD;CACjD,MAAM,mBAAmB,QAAQ,aAAa;AAE9C,KAAI,CAAC,QAAQ,aACX,QAAO,SAAS,KACd;EACE,OAAO;EACP,SAAS;EACV,EACD,EAAE,QAAQ,KAAK,CAChB;CAGH,MAAM,OAAO,MAAM,wBAAwB;EAAE;EAAS;EAAS,CAAC;AAChE,KAAI,kBAAkB,KAAK,CACzB,QAAO;CAET,MAAM,SAAS,KAAK;CAEpB,MAAM,eACJ,MAAM,gBACL;CACH,MAAM,uBACJ,MAAM,gBAAgB,oCAAoC,QAC1D,gBACA,OAAO,iBAAiB,YACvB,aAAsC,WAAW;CAIpD,MAAM,qBAAqB,MAAM,gBAAgB;CACjD,MAAM,YACJ,OAAO,uBAAuB,YAAY,mBAAmB,SAAS,IAClE,qBACA;CAEN,IAAI;AACJ,KAAI;EACF,MAAM,WAAW,QAAQ,aAAa,2BAA2B;AACjE,wBAAsB,WAClB,MAAM,iCAAiC,UAAU;GAC/C,SAAS;GACT;GACA;GACA;GACD,CAAC,GACF,MAAM,2BAA2B,QAAQ,UAAU;GACjD,SAAS;GACT;GACA,UAAU,MAAM;GAChB,OAAO,MAAM;GACb;GACA;GACD,CAAC;UACC,OAAO;AACd,SAAO,MAAM,yCAAyC,MAAM;AAC5D,SAAO,SAAS,KACd,EAAE,OAAO,wCAAwC,EACjD,EAAE,QAAQ,KAAK,CAChB;;CAGH,IAAI;AACJ,KAAI;EACF,MAAM,cAAc,MAAM,QAAQ,aAAa,kBAAkB;GAC/D,UAAU,MAAM;GAChB;GACA;GACA,GAAI,wBAAwB,SAAY,EAAE,qBAAqB,GAAG,EAAE;GACrE,CAAC;AACF,WAAS,YAAY;EACrB,MAAM,EAAE,YAAY;AAEpB,MAAI,WAAW,QAAQ,uBAAuB,CAAC,OAAO,MAAM,MAAM,CAChE,CAAK,+BAA+B;GAClC;GACA;GACA;GACA,aAAa;GACb;GACA;GACD,CAAC,CAAC,OAAO,cAAc;AACtB,UAAO,MAAM,mCAAmC,UAAU;IAC1D;UAEG,OAAO;AACd,SAAO,MAAM,mCAAmC,MAAM;EACtD,MAAM,iBAAiB,uBAAuB,MAAM;AACpD,SAAO,SAAS,KACd,EACE,OAAO,+BACR,EACD,EACE,QACE,mBAAmB,UACnB,kBAAkB,OAClB,iBAAiB,MACb,iBACA,KACP,CACF;;AAMH,KAAI,qBACF,KAAI;AACF,MAAI,OAAO,WAAW,OAAO,YAAY,QACvC,QAAO,SAAS,KACd,EAAE,OAAO,mCAAmC,EAC5C,EAAE,QAAQ,KAAK,CAChB;AAEH,QAAM,WAAW,OAAO;EACxB,MAAM,MAAM,MAAM,MAAM,SAAS;GAC/B,OAAO,MAAM;GACb,OAAO,MAAM;GACb,SAAS,MAAM;GACf,gBAAgB,MAAM;GACvB,CAAC;AACF,SAAO,SAAS,KAAK;GACnB,MAAM;GACN,UAAU,OAAO;GACjB,OAAO,MAAM;GACb,QAAQ,IAAI,UAAU;GACvB,CAAC;UACK,OAAO;AACd,SAAO,MAAM,6BAA6B,MAAM;EAChD,MAAM,SAAS,uBAAuB,MAAM;AAC5C,SAAO,SAAS,KACd,EAAE,OAAO,4BAA4B,EACrC,EAAE,QAAQ,UAAU,UAAU,OAAO,SAAS,MAAM,SAAS,KAAK,CACnE;;CAIL,IAAI,oBAAoB,MAAM;CAC9B,IAAI,iBAAiB,MAAM;CAC3B,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI,kBAAkB;AACtB,KAAI;AAGF,oBAAkB,KAAK,KAAK;EAC5B,MAAM,aAAa,MAAM,QAAQ,aAAa,mBAAmB;GAC/D,yBAAyB;GACzB,UAAU,MAAM;GAChB,OAAO,MAAM;GACb;GACA;GACA,GAAI,wBAAwB,SAAY,EAAE,qBAAqB,GAAG,EAAE;GACpE,GAAI,cAAc,SAAY,EAAE,WAAW,GAAG,EAAE;GAChD,GAAI,QAAQ,kBAAkB,SAC1B,EAAE,eAAe,QAAQ,eAAe,GACxC,EAAE;GACN,YAAY,QAAQ;GACrB,CAAC;AACF,sBAAoB,WAAW;AAC/B,mBAAiB,WAAW;AAC5B,cAAY,WAAW;AACvB,oBAAkB,WAAW;AAC7B,mBAAiB,WAAW;UACrB,OAAO;AACd,SAAO,MAAM,uBAAuB,MAAM;EAC1C,MAAM,iBAAiB,uBAAuB,MAAM;AACpD,SAAO,SAAS,KACd,EACE,OAAO,sBACR,EACD,EACE,QAAQ,mBAAmB,MAAM,MAAM,KACxC,CACF;;CAGH,MAAM,eAAe,WACnB,QAAQ,aACL,mBAAmB;EAClB,UAAU,qBAAqB,MAAM;EACrC,OAAO,kBAAkB,MAAM;EAChC,CAAC,CACD,OAAO,iBAAiB;AACvB,SAAO,MACL;GAAE,KAAK;GAAc;GAAQ,EAC7B,gCACD;GACD;AAEN,KAAI,CAAC,qBAAqB,CAAC,kBAAkB,CAAC,WAAW;AACvD,QAAM,YAAY,0BAA0B;AAC5C,SAAO,SAAS,KACd;GACE,OAAO;GACP,SACE;GACH,EACD,EAAE,QAAQ,KAAK,CAChB;;CAGH,MAAM,iBAAgC;EACpC,GAAG;EACH,UAAU;EACV,OAAO;EACR;CAED,IAAI;AACJ,KAAI,MAAM,QAAQ,MAAM,SAAS,CAC/B,KAAI;EACF,MAAM,qBAAqB,IAAI,IAC7B,MAAM,QAAQ,aAAa,qBAAqB;GAC9C,UAAU;GACV;GACD,CAAC,CACH;AACD,2BAAyB,MAAM,SAAS,QACrC,YAAY,CAAC,mBAAmB,IAAI,QAAQ,GAAG,CACjD;UACM,OAAO;AACd,SAAO,MAAM,iCAAiC,MAAM;AACpD,QAAM,YAAY,+BAA+B;AACjD,SAAO,SAAS,KACd,EACE,OAAO,gCACR,EACD,EAAE,QAAQ,KAAK,CAChB;;AAIL,kBAAiB,QAAQ,8CAA8C,EAAE,CAAC;CAK1E,MAAM,YAAY,yBAAyB;EACzC,QAAQ,WACN,QAAQ,aAAa,iBAAiB;GACpC,UAAU;GACV,OAAO;GACP,YAAY,QAAQ;GACpB,GAAI,QAAQ,kBAAkB,SAC1B,EAAE,eAAe,QAAQ,eAAe,GACxC,EAAE;GACN;GACD,CAAC;EACJ,YAAY,QAAQ,+BAA+B;EACnD,oBAAoB,QAAQ;EAI5B,mBACE,mBAAmB,SACf,SACA,kBAAkB,KAAK,KAAK,GAAG,mBAAmB;EACxD,SAAS,QAAQ;AACf,UAAO,MAAM,gCAAgC,IAAI;AACjD,OAAI;AACF,UAAM,UAAU;YACT,YAAY;AACnB,WAAO,MACL,qDACA,WACD;;;EAGN,CAAC;CAEF,MAAM,uBAAuB;AAC3B,YAAU,MAAM;;CAGlB,MAAM,aAAa,EAAE,SAAS,OAAO;CACrC,IAAI;CACJ,IAAI;CAEJ,MAAM,aAAoC;EACxC,UAAU;EACV,GAAI,oBAAoB,SAAY,EAAE,GAAG,EAAE,iBAAiB;EAC5D;EACA,OAAO;EACP,GAAI,2BAA2B,SAAY,EAAE,wBAAwB,GAAG,EAAE;EAC3E;CAED,MAAM,uBAAuB,wBAAwB,QAAQ;CAC7D,IAAI,qBAAqB;CACzB,MAAM,oBAAoB,OAAgB,UAA6B;AACrE,MAAI,mBAAoB;AACxB,uBAAqB;AAGrB,mBAAiB,QAAQ,8CAA8C,EACrE,OAAO,0BACR,CAAC;AACF,wBAAsB,OAAO;GAC3B;GACA;GACA,WAAW;GACX;GACA,UAAU;GACV,OAAO;GACP;GACA;GACD,CAAC;;AAGJ,KAAI;EACF,MAAM,WAAW,yBAAyB,QAAQ,OAAO,GACrD,QAAQ,OAAO,uBAAuB,WAAW,GACjD;GACE,QAAQ,QAAQ,OAAO,IAAI,WAAW;GACtC,SAAS,QAAQ,SAAS;GAC3B;AAEL,WAAS,OAAO,UAAU;GACxB,OAAO,UAAqB;AAC1B,QAAI,MAAM,SAAS,UAAU,YAC3B,YAAW,UAAU;AAEvB,QAAI,MAAM,SAAS,UAAU,WAAW;KACtC,MAAM,UACJ,aAAa,SAAS,OAAO,MAAM,YAAY,WAC3C,MAAM,UACN;AACN,sBACE,IAAI,MAAM,QAAQ,EAClB,WAAW,UACP,8BACA,uBACL;AACD,SAAI,CAAC,WAAW,SAAS;AACvB,sBAAgB;AAChB,qCAA+B;AAC/B,gCAA0B,YAAY,sBAAsB;;;;GAIlE,QAAQ,UAAU;AAChB,qBACE,OACA,WAAW,UACP,8BACA,uBACL;AACD,oBAAgB;AAChB,QAAI,CAAC,WAAW,SAAS;AACvB,oCACE,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AACxD,+BAA0B,YAAY,qBAAqB;UAE3D,aAAY,eAAe;AAE7B,WAAO,MAAM,wBAAwB,MAAM;;GAE7C,gBAAgB;AACd,oBAAgB;AAGhB,qBAAiB,QACf,4CACA,EAAE,CACH;;GAEJ,CAAC;AAEF,QAAM,SAAS;UACR,OAAO;AACd,mBAAiB,OAAO,uBAAuB;AAC/C,kBAAgB;AAChB,SAAO,2BAA2B,YAAY,qBAAqB;AACnE,SAAO,MAAM,gCAAgC,MAAM;AACnD,SAAO,SAAS,KACd;GACE,OAAO;GACP,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;GAChE,EACD,EAAE,QAAQ,KAAK,CAChB;;AAGH,KAAI,8BAA8B;AAChC,QAAM;AACN,SAAO,SAAS,KACd;GACE,OAAO;GACP,SAAS;GACV,EACD,EAAE,QAAQ,KAAK,CAChB;;AAKH,QAAO,SAAS,KACd;EACE,UAAU;EACV,OAAO;EACP;EACA,UAAU,4BAA4B;GACpC,WAAW,QAAQ,aAAa,iBAAiB;GACjD,UAAU;GACX,CAAC;EACH,EACD,EACE,SAAS,EAAE,iBAAiB,YAAY,EACzC,CACF"}
@@ -1,4 +1,5 @@
1
1
  require("reflect-metadata");
2
+ const require_mcp_client_cache = require('../../../../lib/runtime/mcp-client-cache.cjs');
2
3
 
3
4
  //#region src/v2/runtime/handlers/shared/mcp-apps-servers.ts
4
5
  const UNSUPPORTED_POLICY_KEYS = ["includeTools", "excludeTools"];
@@ -11,7 +12,7 @@ function resolveMcpAppsServers(servers, agentId) {
11
12
  const violations = [];
12
13
  for (const [index, server] of servers.entries()) {
13
14
  const config = server;
14
- for (const key of UNSUPPORTED_POLICY_KEYS) if (Object.prototype.hasOwnProperty.call(config, key) && config[key] !== void 0) violations.push(`${key} at server[${index}] (${server.serverId ?? server.url})`);
15
+ for (const key of UNSUPPORTED_POLICY_KEYS) if (Object.prototype.hasOwnProperty.call(config, key) && config[key] !== void 0) violations.push(`${key} at server[${index}] (${server.serverId ?? require_mcp_client_cache.describeEndpoint(server.url)})`);
15
16
  }
16
17
  if (violations.length > 0) throw new Error(`Unsupported MCP Apps tool policy: ${violations.join(", ")}. @ag-ui/mcp-apps-middleware owns per-server tool policy, and the release the runtime depends on does not support these keys; see ${MCP_APPS_POLICY_ISSUE}.`);
17
18
  return servers.filter((server) => !server.agentId || server.agentId === agentId).map(({ agentId: _agentId, ...server }) => server);
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-apps-servers.cjs","names":[],"sources":["../../../../../src/v2/runtime/handlers/shared/mcp-apps-servers.ts"],"sourcesContent":["import type { MCPClientConfig } from \"@ag-ui/mcp-apps-middleware\";\nimport type { McpAppsServerConfig } from \"../../core/runtime\";\n\nconst UNSUPPORTED_POLICY_KEYS = [\"includeTools\", \"excludeTools\"] as const;\nconst MCP_APPS_POLICY_ISSUE =\n \"https://github.com/CopilotKit/CopilotKit/issues/5930\";\n\n/**\n * Select the servers for an agent and validate the policy boundary owned by\n * the installed MCP Apps middleware.\n */\nexport function resolveMcpAppsServers(\n servers: readonly McpAppsServerConfig[],\n agentId: string,\n): MCPClientConfig[] {\n const violations: string[] = [];\n\n for (const [index, server] of servers.entries()) {\n const config = server as unknown as Record<string, unknown>;\n for (const key of UNSUPPORTED_POLICY_KEYS) {\n if (\n Object.prototype.hasOwnProperty.call(config, key) &&\n config[key] !== undefined\n ) {\n violations.push(\n `${key} at server[${index}] (${server.serverId ?? server.url})`,\n );\n }\n }\n }\n\n if (violations.length > 0) {\n throw new Error(\n `Unsupported MCP Apps tool policy: ${violations.join(\", \")}. ` +\n `@ag-ui/mcp-apps-middleware owns per-server tool policy, and the ` +\n `release the runtime depends on does not support these keys; see ` +\n `${MCP_APPS_POLICY_ISSUE}.`,\n );\n }\n\n return servers\n .filter((server) => !server.agentId || server.agentId === agentId)\n .map(({ agentId: _agentId, ...server }) => server as MCPClientConfig);\n}\n"],"mappings":";;;AAGA,MAAM,0BAA0B,CAAC,gBAAgB,eAAe;AAChE,MAAM,wBACJ;;;;;AAMF,SAAgB,sBACd,SACA,SACmB;CACnB,MAAM,aAAuB,EAAE;AAE/B,MAAK,MAAM,CAAC,OAAO,WAAW,QAAQ,SAAS,EAAE;EAC/C,MAAM,SAAS;AACf,OAAK,MAAM,OAAO,wBAChB,KACE,OAAO,UAAU,eAAe,KAAK,QAAQ,IAAI,IACjD,OAAO,SAAS,OAEhB,YAAW,KACT,GAAG,IAAI,aAAa,MAAM,KAAK,OAAO,YAAY,OAAO,IAAI,GAC9D;;AAKP,KAAI,WAAW,SAAS,EACtB,OAAM,IAAI,MACR,qCAAqC,WAAW,KAAK,KAAK,CAAC,oIAGtD,sBAAsB,GAC5B;AAGH,QAAO,QACJ,QAAQ,WAAW,CAAC,OAAO,WAAW,OAAO,YAAY,QAAQ,CACjE,KAAK,EAAE,SAAS,UAAU,GAAG,aAAa,OAA0B"}
1
+ {"version":3,"file":"mcp-apps-servers.cjs","names":["describeEndpoint"],"sources":["../../../../../src/v2/runtime/handlers/shared/mcp-apps-servers.ts"],"sourcesContent":["import type { MCPClientConfig } from \"@ag-ui/mcp-apps-middleware\";\nimport type { McpAppsServerConfig } from \"../../core/runtime\";\nimport { describeEndpoint } from \"../../../../v1-deprecated/lib/runtime/mcp-client-cache\";\n\nconst UNSUPPORTED_POLICY_KEYS = [\"includeTools\", \"excludeTools\"] as const;\nconst MCP_APPS_POLICY_ISSUE =\n \"https://github.com/CopilotKit/CopilotKit/issues/5930\";\n\n/**\n * Select the servers for an agent and validate the policy boundary owned by\n * the installed MCP Apps middleware.\n */\nexport function resolveMcpAppsServers(\n servers: readonly McpAppsServerConfig[],\n agentId: string,\n): MCPClientConfig[] {\n const violations: string[] = [];\n\n for (const [index, server] of servers.entries()) {\n const config = server as unknown as Record<string, unknown>;\n for (const key of UNSUPPORTED_POLICY_KEYS) {\n if (\n Object.prototype.hasOwnProperty.call(config, key) &&\n config[key] !== undefined\n ) {\n violations.push(\n `${key} at server[${index}] (${server.serverId ?? describeEndpoint(server.url)})`,\n );\n }\n }\n }\n\n if (violations.length > 0) {\n throw new Error(\n `Unsupported MCP Apps tool policy: ${violations.join(\", \")}. ` +\n `@ag-ui/mcp-apps-middleware owns per-server tool policy, and the ` +\n `release the runtime depends on does not support these keys; see ` +\n `${MCP_APPS_POLICY_ISSUE}.`,\n );\n }\n\n return servers\n .filter((server) => !server.agentId || server.agentId === agentId)\n .map(({ agentId: _agentId, ...server }) => server as MCPClientConfig);\n}\n"],"mappings":";;;;AAIA,MAAM,0BAA0B,CAAC,gBAAgB,eAAe;AAChE,MAAM,wBACJ;;;;;AAMF,SAAgB,sBACd,SACA,SACmB;CACnB,MAAM,aAAuB,EAAE;AAE/B,MAAK,MAAM,CAAC,OAAO,WAAW,QAAQ,SAAS,EAAE;EAC/C,MAAM,SAAS;AACf,OAAK,MAAM,OAAO,wBAChB,KACE,OAAO,UAAU,eAAe,KAAK,QAAQ,IAAI,IACjD,OAAO,SAAS,OAEhB,YAAW,KACT,GAAG,IAAI,aAAa,MAAM,KAAK,OAAO,YAAYA,0CAAiB,OAAO,IAAI,CAAC,GAChF;;AAKP,KAAI,WAAW,SAAS,EACtB,OAAM,IAAI,MACR,qCAAqC,WAAW,KAAK,KAAK,CAAC,oIAGtD,sBAAsB,GAC5B;AAGH,QAAO,QACJ,QAAQ,WAAW,CAAC,OAAO,WAAW,OAAO,YAAY,QAAQ,CACjE,KAAK,EAAE,SAAS,UAAU,GAAG,aAAa,OAA0B"}
@@ -1,4 +1,6 @@
1
1
  import "reflect-metadata";
2
+ import { describeEndpoint } from "../../../../lib/runtime/mcp-client-cache.mjs";
3
+
2
4
  //#region src/v2/runtime/handlers/shared/mcp-apps-servers.ts
3
5
  const UNSUPPORTED_POLICY_KEYS = ["includeTools", "excludeTools"];
4
6
  const MCP_APPS_POLICY_ISSUE = "https://github.com/CopilotKit/CopilotKit/issues/5930";
@@ -10,7 +12,7 @@ function resolveMcpAppsServers(servers, agentId) {
10
12
  const violations = [];
11
13
  for (const [index, server] of servers.entries()) {
12
14
  const config = server;
13
- for (const key of UNSUPPORTED_POLICY_KEYS) if (Object.prototype.hasOwnProperty.call(config, key) && config[key] !== void 0) violations.push(`${key} at server[${index}] (${server.serverId ?? server.url})`);
15
+ for (const key of UNSUPPORTED_POLICY_KEYS) if (Object.prototype.hasOwnProperty.call(config, key) && config[key] !== void 0) violations.push(`${key} at server[${index}] (${server.serverId ?? describeEndpoint(server.url)})`);
14
16
  }
15
17
  if (violations.length > 0) throw new Error(`Unsupported MCP Apps tool policy: ${violations.join(", ")}. @ag-ui/mcp-apps-middleware owns per-server tool policy, and the release the runtime depends on does not support these keys; see ${MCP_APPS_POLICY_ISSUE}.`);
16
18
  return servers.filter((server) => !server.agentId || server.agentId === agentId).map(({ agentId: _agentId, ...server }) => server);
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-apps-servers.mjs","names":[],"sources":["../../../../../src/v2/runtime/handlers/shared/mcp-apps-servers.ts"],"sourcesContent":["import type { MCPClientConfig } from \"@ag-ui/mcp-apps-middleware\";\nimport type { McpAppsServerConfig } from \"../../core/runtime\";\n\nconst UNSUPPORTED_POLICY_KEYS = [\"includeTools\", \"excludeTools\"] as const;\nconst MCP_APPS_POLICY_ISSUE =\n \"https://github.com/CopilotKit/CopilotKit/issues/5930\";\n\n/**\n * Select the servers for an agent and validate the policy boundary owned by\n * the installed MCP Apps middleware.\n */\nexport function resolveMcpAppsServers(\n servers: readonly McpAppsServerConfig[],\n agentId: string,\n): MCPClientConfig[] {\n const violations: string[] = [];\n\n for (const [index, server] of servers.entries()) {\n const config = server as unknown as Record<string, unknown>;\n for (const key of UNSUPPORTED_POLICY_KEYS) {\n if (\n Object.prototype.hasOwnProperty.call(config, key) &&\n config[key] !== undefined\n ) {\n violations.push(\n `${key} at server[${index}] (${server.serverId ?? server.url})`,\n );\n }\n }\n }\n\n if (violations.length > 0) {\n throw new Error(\n `Unsupported MCP Apps tool policy: ${violations.join(\", \")}. ` +\n `@ag-ui/mcp-apps-middleware owns per-server tool policy, and the ` +\n `release the runtime depends on does not support these keys; see ` +\n `${MCP_APPS_POLICY_ISSUE}.`,\n );\n }\n\n return servers\n .filter((server) => !server.agentId || server.agentId === agentId)\n .map(({ agentId: _agentId, ...server }) => server as MCPClientConfig);\n}\n"],"mappings":";;AAGA,MAAM,0BAA0B,CAAC,gBAAgB,eAAe;AAChE,MAAM,wBACJ;;;;;AAMF,SAAgB,sBACd,SACA,SACmB;CACnB,MAAM,aAAuB,EAAE;AAE/B,MAAK,MAAM,CAAC,OAAO,WAAW,QAAQ,SAAS,EAAE;EAC/C,MAAM,SAAS;AACf,OAAK,MAAM,OAAO,wBAChB,KACE,OAAO,UAAU,eAAe,KAAK,QAAQ,IAAI,IACjD,OAAO,SAAS,OAEhB,YAAW,KACT,GAAG,IAAI,aAAa,MAAM,KAAK,OAAO,YAAY,OAAO,IAAI,GAC9D;;AAKP,KAAI,WAAW,SAAS,EACtB,OAAM,IAAI,MACR,qCAAqC,WAAW,KAAK,KAAK,CAAC,oIAGtD,sBAAsB,GAC5B;AAGH,QAAO,QACJ,QAAQ,WAAW,CAAC,OAAO,WAAW,OAAO,YAAY,QAAQ,CACjE,KAAK,EAAE,SAAS,UAAU,GAAG,aAAa,OAA0B"}
1
+ {"version":3,"file":"mcp-apps-servers.mjs","names":[],"sources":["../../../../../src/v2/runtime/handlers/shared/mcp-apps-servers.ts"],"sourcesContent":["import type { MCPClientConfig } from \"@ag-ui/mcp-apps-middleware\";\nimport type { McpAppsServerConfig } from \"../../core/runtime\";\nimport { describeEndpoint } from \"../../../../v1-deprecated/lib/runtime/mcp-client-cache\";\n\nconst UNSUPPORTED_POLICY_KEYS = [\"includeTools\", \"excludeTools\"] as const;\nconst MCP_APPS_POLICY_ISSUE =\n \"https://github.com/CopilotKit/CopilotKit/issues/5930\";\n\n/**\n * Select the servers for an agent and validate the policy boundary owned by\n * the installed MCP Apps middleware.\n */\nexport function resolveMcpAppsServers(\n servers: readonly McpAppsServerConfig[],\n agentId: string,\n): MCPClientConfig[] {\n const violations: string[] = [];\n\n for (const [index, server] of servers.entries()) {\n const config = server as unknown as Record<string, unknown>;\n for (const key of UNSUPPORTED_POLICY_KEYS) {\n if (\n Object.prototype.hasOwnProperty.call(config, key) &&\n config[key] !== undefined\n ) {\n violations.push(\n `${key} at server[${index}] (${server.serverId ?? describeEndpoint(server.url)})`,\n );\n }\n }\n }\n\n if (violations.length > 0) {\n throw new Error(\n `Unsupported MCP Apps tool policy: ${violations.join(\", \")}. ` +\n `@ag-ui/mcp-apps-middleware owns per-server tool policy, and the ` +\n `release the runtime depends on does not support these keys; see ` +\n `${MCP_APPS_POLICY_ISSUE}.`,\n );\n }\n\n return servers\n .filter((server) => !server.agentId || server.agentId === agentId)\n .map(({ agentId: _agentId, ...server }) => server as MCPClientConfig);\n}\n"],"mappings":";;;;AAIA,MAAM,0BAA0B,CAAC,gBAAgB,eAAe;AAChE,MAAM,wBACJ;;;;;AAMF,SAAgB,sBACd,SACA,SACmB;CACnB,MAAM,aAAuB,EAAE;AAE/B,MAAK,MAAM,CAAC,OAAO,WAAW,QAAQ,SAAS,EAAE;EAC/C,MAAM,SAAS;AACf,OAAK,MAAM,OAAO,wBAChB,KACE,OAAO,UAAU,eAAe,KAAK,QAAQ,IAAI,IACjD,OAAO,SAAS,OAEhB,YAAW,KACT,GAAG,IAAI,aAAa,MAAM,KAAK,OAAO,YAAY,iBAAiB,OAAO,IAAI,CAAC,GAChF;;AAKP,KAAI,WAAW,SAAS,EACtB,OAAM,IAAI,MACR,qCAAqC,WAAW,KAAK,KAAK,CAAC,oIAGtD,sBAAsB,GAC5B;AAGH,QAAO,QACJ,QAAQ,WAAW,CAAC,OAAO,WAAW,OAAO,YAAY,QAAQ,CACjE,KAAK,EAAE,SAAS,UAAU,GAAG,aAAa,OAA0B"}
@@ -139,7 +139,7 @@ function createSseEventResponse({ request, observableFactory, debugEventBus, age
139
139
  reportAgentError(error, "sse.subscription");
140
140
  if (captureTelemetry) telemetry$1.capture("oss.runtime.agent_execution_stream_errored", {
141
141
  ...executionInfo,
142
- error: error instanceof Error ? error.message : String(error)
142
+ error: "AGENT_EXECUTION_FAILED"
143
143
  });
144
144
  if (debug?.lifecycle) debugLogger.debug({ error: error instanceof Error ? error.message : String(error) }, "SSE stream errored");
145
145
  logError(error);
@@ -1 +1 @@
1
- {"version":3,"file":"sse-response.cjs","names":["THREAD_ALREADY_RUNNING_ERROR_CODE","defaultTelemetry","resolveSseKeepAliveIntervalSeconds","EventEncoder","createLogger","EventType","keepAliveSse"],"sources":["../../../../../src/v2/runtime/handlers/shared/sse-response.ts"],"sourcesContent":["import { EventType } from \"@ag-ui/client\";\nimport type { BaseEvent } from \"@ag-ui/client\";\nimport { EventEncoder } from \"@ag-ui/encoder\";\nimport type { Observable, Subscription } from \"rxjs\";\nimport {\n keepAliveSse,\n resolveSseKeepAliveIntervalSeconds,\n} from \"./sse-keep-alive\";\nimport { THREAD_ALREADY_RUNNING_ERROR_CODE } from \"@copilotkit/shared\";\nimport type { ResolvedDebugConfig } from \"@copilotkit/shared\";\nimport { createLogger } from \"../../../../v1-deprecated/lib/logger\";\nimport type { CopilotRuntimeLogger } from \"../../../../v1-deprecated/lib/logger\";\nimport { telemetry as defaultTelemetry } from \"../../telemetry\";\nimport type { TelemetryCapture } from \"../../telemetry/telemetry-client\";\nimport type { AgentExecutionResponseInfo } from \"../../telemetry/events\";\nimport type { DebugEventBus } from \"../../core/debug-event-bus\";\nimport type {\n RuntimeErrorPhase,\n RuntimeErrorReporter,\n} from \"../../core/runtime-error-reporter\";\n\n/**\n * Whether a runner rejected the run because the thread is busy. Matches the\n * `code` of {@link ThreadAlreadyRunningError}, and the plain message that\n * custom runners copied from the built-in ones still throw.\n */\nfunction isThreadAlreadyRunning(error: unknown): boolean {\n return (\n error instanceof Error &&\n ((error as { code?: unknown }).code === THREAD_ALREADY_RUNNING_ERROR_CODE ||\n error.message === \"Thread already running\")\n );\n}\n\ninterface CreateSseEventResponseParams {\n request: Request;\n observableFactory: () =>\n | Promise<Observable<BaseEvent>>\n | Observable<BaseEvent>;\n debugEventBus?: DebugEventBus;\n agentId?: string;\n debug?: ResolvedDebugConfig;\n /** Pre-created logger instance to avoid creating a new pino logger per request. */\n logger?: CopilotRuntimeLogger;\n /** Runtime-bound telemetry capture. Falls back for external direct callers. */\n telemetry?: TelemetryCapture;\n /**\n * Execution facts known before the stream opens, merged under anything the\n * upstream reports as it runs. Carries `llmHostClass`, which is knowable\n * from the agent's configuration and never appears on a streamed event.\n */\n executionSeed?: AgentExecutionResponseInfo;\n /**\n * Whether to emit `oss.runtime.agent_execution_stream_*` telemetry for this\n * stream. Defaults to `true`. The stateless `/suggest` path sets this to\n * `false`: a suggestion is a side-effect-free structured completion, not a\n * tracked run, and under `available: \"always\"` it fires often enough to flood\n * run telemetry.\n */\n captureTelemetry?: boolean;\n runtimeErrorReporter?: RuntimeErrorReporter;\n startTime?: number;\n /**\n * Seconds of silence before a `: keep-alive` SSE comment is written.\n * `0` disables the keep-alive. Resolved by\n * {@link resolveSseKeepAliveIntervalSeconds}, which supplies the default\n * and enforces the timer bound for every caller.\n */\n keepAliveIntervalSeconds?: number;\n}\n\nexport function createSseEventResponse({\n request,\n observableFactory,\n debugEventBus,\n agentId,\n debug,\n logger,\n telemetry = defaultTelemetry,\n executionSeed,\n captureTelemetry = true,\n runtimeErrorReporter,\n startTime,\n keepAliveIntervalSeconds,\n}: CreateSseEventResponseParams): Response {\n const keepAliveSeconds = resolveSseKeepAliveIntervalSeconds(\n keepAliveIntervalSeconds,\n );\n const stream = new TransformStream();\n const writer = stream.writable.getWriter();\n const encoder = new EventEncoder();\n let streamClosed = false;\n // Set once the current run's RUN_FINISHED or RUN_ERROR has been queued for\n // the client. AG-UI allows nothing after either until the next RUN_STARTED,\n // so a later failure must not add a RUN_ERROR.\n let terminalEventWritten = false;\n let debugThreadId = \"\";\n let debugRunId = \"\";\n\n const debugLogger = debug?.enabled\n ? (logger ??\n createLogger({ level: \"debug\", component: \"copilotkit-debug\" }))\n : undefined;\n\n const closeStream = async () => {\n if (!streamClosed) {\n try {\n await writer.close();\n streamClosed = true;\n } catch {\n // Stream already closed.\n }\n }\n };\n\n // Report a failure to the client as a terminal RUN_ERROR. Without it the\n // client sees an empty stream that ends normally, so its run \"succeeds\"\n // with no reply and no error (e.g. \"Thread already running\" on a busy\n // thread). Only a busy thread is named, with a code clients can branch on;\n // anything else may carry internal detail, so the client gets a generic\n // message and the full error stays in the server log.\n const writeRunError = async (error: unknown) => {\n if (terminalEventWritten || streamClosed || request.signal.aborted) {\n return;\n }\n terminalEventWritten = true;\n const event = isThreadAlreadyRunning(error)\n ? {\n type: EventType.RUN_ERROR,\n message: \"Thread already running\",\n code: THREAD_ALREADY_RUNNING_ERROR_CODE,\n }\n : { type: EventType.RUN_ERROR, message: \"Agent run failed\" };\n // The inspector sees every streamed event, so it needs this one too or\n // the run it saw start never ends there. A run that never started has\n // no ids to file it under, so it is not sent.\n if (debugEventBus && debugRunId) {\n try {\n debugEventBus.broadcast(event as BaseEvent, {\n agentId: agentId ?? \"\",\n threadId: debugThreadId,\n runId: debugRunId,\n });\n } catch (broadcastError) {\n logError(broadcastError);\n }\n }\n try {\n await writer.write(encoder.encodeBinary(event as BaseEvent));\n } catch {\n // The client is already gone; closeStream() handles the rest.\n }\n };\n\n const logError = (error: unknown) => {\n console.error(\"Error running agent:\", error);\n console.error(\n \"Error stack:\",\n error instanceof Error ? error.stack : \"No stack trace\",\n );\n console.error(\"Error details:\", {\n name: error instanceof Error ? error.name : \"Unknown\",\n message: error instanceof Error ? error.message : String(error),\n cause: error instanceof Error ? error.cause : undefined,\n });\n };\n\n let subscription: Subscription | undefined;\n let agentErrorReported = false;\n\n const reportAgentError = (error: unknown, phase: RuntimeErrorPhase) => {\n if (agentErrorReported) return;\n agentErrorReported = true;\n runtimeErrorReporter?.report({\n request,\n error,\n operation: \"agent.run\",\n agentId,\n threadId: debugThreadId || undefined,\n runId: debugRunId || undefined,\n phase,\n startTime,\n });\n };\n\n (async () => {\n const observable = await observableFactory();\n\n if (captureTelemetry) {\n telemetry.capture(\"oss.runtime.agent_execution_stream_started\", {});\n }\n\n if (debug?.lifecycle) {\n debugLogger!.debug(\"SSE stream opened\");\n }\n\n let eventCount = 0;\n let loggedEventCount = 0;\n\n // Provider/model/LangGraph facts, scraped off raw upstream events as\n // they pass and reported once the stream finishes. This moved here from\n // the v1 TelemetryAgentRunner, which wrapped the runner purely to\n // collect it and emitted its own duplicate copy of every stream event\n // to carry it. v2 callers had no equivalent and reported `{}`.\n // Seeded rather than empty: `llmHostClass` comes from the agent's config,\n // not from the wire, so nothing streamed will ever fill it in. Scraped\n // fields still win, since `collectExecutionInfo` writes over this.\n const executionInfo: AgentExecutionResponseInfo = { ...executionSeed };\n\n subscription = observable.subscribe({\n next: async (event) => {\n collectExecutionInfo(event, executionInfo);\n\n // Extract threadId/runId from RUN_STARTED\n if (event.type === \"RUN_STARTED\") {\n const e = event as { threadId?: string; runId?: string };\n debugThreadId = e.threadId ?? \"\";\n debugRunId = e.runId ?? \"\";\n }\n\n if (event.type === \"RUN_ERROR\") {\n const e = event as {\n message?: unknown;\n threadId?: string;\n runId?: string;\n };\n debugThreadId = e.threadId ?? debugThreadId;\n debugRunId = e.runId ?? debugRunId;\n reportAgentError(\n new Error(\n typeof e.message === \"string\"\n ? e.message\n : \"Runner reported a run error\",\n ),\n \"sse.subscription\",\n );\n }\n\n // Broadcast to debug listeners BEFORE the stream-closed gate below.\n // Intentional: debug subscribers (e.g. the VS Code Inspector panel)\n // should still receive trailing events after the SSE client for\n // this request closed its connection — they're independent\n // consumers observing the underlying runtime, not the request's\n // response stream.\n //\n // Wrapped in try/catch so a buggy debug subscriber can't propagate\n // an exception into this observer — if the throw reached the\n // `next` callback it would get routed to `error` by RxJS, closing\n // the SSE stream for an unrelated reason. Log via `logError` and\n // move on.\n if (debugEventBus) {\n try {\n debugEventBus.broadcast(event, {\n agentId: agentId ?? \"\",\n threadId: debugThreadId,\n runId: debugRunId,\n });\n } catch (broadcastError) {\n logError(broadcastError);\n }\n }\n\n if (!request.signal.aborted && !streamClosed) {\n try {\n eventCount++;\n if (debug?.events) {\n loggedEventCount++;\n if (debug.verbose) {\n debugLogger!.debug({ event }, \"Event emitted\");\n } else {\n debugLogger!.debug(\n { type: event.type, ...summarizeEvent(event) },\n \"Event emitted\",\n );\n }\n }\n // /connect replays finished runs before the live one, so a new\n // RUN_STARTED reopens the stream for a RUN_ERROR.\n if (event.type === EventType.RUN_STARTED) {\n terminalEventWritten = false;\n } else if (\n event.type === EventType.RUN_FINISHED ||\n event.type === EventType.RUN_ERROR\n ) {\n terminalEventWritten = true;\n }\n await writer.write(encoder.encodeBinary(event));\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n streamClosed = true;\n } else {\n // Non-abort write failures (backpressure disconnects,\n // transform-stream exceptions, …) were previously swallowed\n // silently — `streamClosed` stayed `false` and the next\n // event re-attempted a broken writer. Log and mark the\n // stream closed so we stop trying.\n logError(error);\n streamClosed = true;\n }\n }\n }\n },\n error: async (error) => {\n reportAgentError(error, \"sse.subscription\");\n if (captureTelemetry) {\n telemetry.capture(\"oss.runtime.agent_execution_stream_errored\", {\n ...executionInfo,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n if (debug?.lifecycle) {\n debugLogger!.debug(\n { error: error instanceof Error ? error.message : String(error) },\n \"SSE stream errored\",\n );\n }\n logError(error);\n await writeRunError(error);\n await closeStream();\n },\n complete: async () => {\n if (captureTelemetry) {\n telemetry.capture(\n \"oss.runtime.agent_execution_stream_ended\",\n executionInfo,\n );\n }\n if (debug?.lifecycle) {\n debugLogger!.debug(\n { eventCount, loggedEventCount },\n \"SSE stream completed\",\n );\n }\n await closeStream();\n },\n });\n\n // If the client disconnected before the subscription was created,\n // unsubscribe immediately to avoid leaking the observable.\n if (request.signal.aborted) {\n subscription.unsubscribe();\n }\n })().catch(async (error) => {\n reportAgentError(error, \"sse.factory\");\n logError(error);\n await writeRunError(error);\n await closeStream();\n });\n\n request.signal.addEventListener(\"abort\", () => {\n subscription?.unsubscribe();\n });\n\n const body =\n keepAliveSeconds > 0\n ? keepAliveSse(stream.readable, keepAliveSeconds * 1_000)\n : stream.readable;\n\n return new Response(body, {\n status: 200,\n headers: {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n },\n });\n}\n\nfunction summarizeEvent(event: BaseEvent): Record<string, unknown> {\n const e = event as any;\n const summary: Record<string, unknown> = {};\n\n if (e.messageId) summary.messageId = e.messageId;\n if (e.toolCallId) summary.toolCallId = e.toolCallId;\n if (e.toolCallName) summary.toolCallName = e.toolCallName;\n if (e.role) summary.role = e.role;\n if (e.delta != null && typeof e.delta === \"string\")\n summary.deltaLength = e.delta.length;\n if (e.snapshot && typeof e.snapshot === \"object\")\n summary.snapshotKeys = Object.keys(e.snapshot);\n if (e.delta && Array.isArray(e.delta))\n summary.operationCount = e.delta.length;\n if (e.threadId) summary.threadId = e.threadId;\n if (e.runId) summary.runId = e.runId;\n if (e.message) summary.message = e.message;\n if (e.code) summary.code = e.code;\n if (e.stepName) summary.stepName = e.stepName;\n\n return summary;\n}\n\n/**\n * Accumulate provider, model, and LangGraph facts from one upstream event.\n *\n * Mutates rather than returns so the caller keeps one record across the whole\n * stream: these arrive on different events and the last one wins. Only fields\n * the upstream actually sent are set, so an agent that reports none leaves the\n * record empty and the stream events carry `{}` as before.\n *\n * `rawEvent` is the untransformed upstream payload, present on AG-UI events\n * that wrap one. Its shape is the provider's, not ours, hence the narrowing.\n */\nfunction collectExecutionInfo(\n event: BaseEvent,\n into: AgentExecutionResponseInfo,\n): void {\n const rawEvent = (\n event as {\n rawEvent?: {\n metadata?: Record<string, unknown>;\n data?: Record<string, unknown>;\n };\n }\n ).rawEvent;\n if (!rawEvent) return;\n\n const model = (rawEvent.data as { output?: { model?: string } } | undefined)\n ?.output?.model;\n if (model) {\n into.model = model;\n // Carried forward from the v1 implementation, which set both from the\n // same field. The upstream sends no separate provider name.\n into.provider = model;\n }\n\n const metadata = rawEvent.metadata as\n | { langgraph_host?: string; langgraph_version?: string }\n | undefined;\n if (metadata?.langgraph_host) into.langGraphHost = metadata.langgraph_host;\n if (metadata?.langgraph_version) {\n into.langGraphVersion = metadata.langgraph_version;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"sse-response.cjs","names":["THREAD_ALREADY_RUNNING_ERROR_CODE","defaultTelemetry","resolveSseKeepAliveIntervalSeconds","EventEncoder","createLogger","EventType","keepAliveSse"],"sources":["../../../../../src/v2/runtime/handlers/shared/sse-response.ts"],"sourcesContent":["import { EventType } from \"@ag-ui/client\";\nimport type { BaseEvent } from \"@ag-ui/client\";\nimport { EventEncoder } from \"@ag-ui/encoder\";\nimport type { Observable, Subscription } from \"rxjs\";\nimport {\n keepAliveSse,\n resolveSseKeepAliveIntervalSeconds,\n} from \"./sse-keep-alive\";\nimport { THREAD_ALREADY_RUNNING_ERROR_CODE } from \"@copilotkit/shared\";\nimport type { ResolvedDebugConfig } from \"@copilotkit/shared\";\nimport { createLogger } from \"../../../../v1-deprecated/lib/logger\";\nimport type { CopilotRuntimeLogger } from \"../../../../v1-deprecated/lib/logger\";\nimport { telemetry as defaultTelemetry } from \"../../telemetry\";\nimport type { TelemetryCapture } from \"../../telemetry/telemetry-client\";\nimport type { AgentExecutionResponseInfo } from \"../../telemetry/events\";\nimport type { DebugEventBus } from \"../../core/debug-event-bus\";\nimport type {\n RuntimeErrorPhase,\n RuntimeErrorReporter,\n} from \"../../core/runtime-error-reporter\";\n\n/**\n * Whether a runner rejected the run because the thread is busy. Matches the\n * `code` of {@link ThreadAlreadyRunningError}, and the plain message that\n * custom runners copied from the built-in ones still throw.\n */\nfunction isThreadAlreadyRunning(error: unknown): boolean {\n return (\n error instanceof Error &&\n ((error as { code?: unknown }).code === THREAD_ALREADY_RUNNING_ERROR_CODE ||\n error.message === \"Thread already running\")\n );\n}\n\ninterface CreateSseEventResponseParams {\n request: Request;\n observableFactory: () =>\n | Promise<Observable<BaseEvent>>\n | Observable<BaseEvent>;\n debugEventBus?: DebugEventBus;\n agentId?: string;\n debug?: ResolvedDebugConfig;\n /** Pre-created logger instance to avoid creating a new pino logger per request. */\n logger?: CopilotRuntimeLogger;\n /** Runtime-bound telemetry capture. Falls back for external direct callers. */\n telemetry?: TelemetryCapture;\n /**\n * Execution facts known before the stream opens, merged under anything the\n * upstream reports as it runs. Carries `llmHostClass`, which is knowable\n * from the agent's configuration and never appears on a streamed event.\n */\n executionSeed?: AgentExecutionResponseInfo;\n /**\n * Whether to emit `oss.runtime.agent_execution_stream_*` telemetry for this\n * stream. Defaults to `true`. The stateless `/suggest` path sets this to\n * `false`: a suggestion is a side-effect-free structured completion, not a\n * tracked run, and under `available: \"always\"` it fires often enough to flood\n * run telemetry.\n */\n captureTelemetry?: boolean;\n runtimeErrorReporter?: RuntimeErrorReporter;\n startTime?: number;\n /**\n * Seconds of silence before a `: keep-alive` SSE comment is written.\n * `0` disables the keep-alive. Resolved by\n * {@link resolveSseKeepAliveIntervalSeconds}, which supplies the default\n * and enforces the timer bound for every caller.\n */\n keepAliveIntervalSeconds?: number;\n}\n\nexport function createSseEventResponse({\n request,\n observableFactory,\n debugEventBus,\n agentId,\n debug,\n logger,\n telemetry = defaultTelemetry,\n executionSeed,\n captureTelemetry = true,\n runtimeErrorReporter,\n startTime,\n keepAliveIntervalSeconds,\n}: CreateSseEventResponseParams): Response {\n const keepAliveSeconds = resolveSseKeepAliveIntervalSeconds(\n keepAliveIntervalSeconds,\n );\n const stream = new TransformStream();\n const writer = stream.writable.getWriter();\n const encoder = new EventEncoder();\n let streamClosed = false;\n // Set once the current run's RUN_FINISHED or RUN_ERROR has been queued for\n // the client. AG-UI allows nothing after either until the next RUN_STARTED,\n // so a later failure must not add a RUN_ERROR.\n let terminalEventWritten = false;\n let debugThreadId = \"\";\n let debugRunId = \"\";\n\n const debugLogger = debug?.enabled\n ? (logger ??\n createLogger({ level: \"debug\", component: \"copilotkit-debug\" }))\n : undefined;\n\n const closeStream = async () => {\n if (!streamClosed) {\n try {\n await writer.close();\n streamClosed = true;\n } catch {\n // Stream already closed.\n }\n }\n };\n\n // Report a failure to the client as a terminal RUN_ERROR. Without it the\n // client sees an empty stream that ends normally, so its run \"succeeds\"\n // with no reply and no error (e.g. \"Thread already running\" on a busy\n // thread). Only a busy thread is named, with a code clients can branch on;\n // anything else may carry internal detail, so the client gets a generic\n // message and the full error stays in the server log.\n const writeRunError = async (error: unknown) => {\n if (terminalEventWritten || streamClosed || request.signal.aborted) {\n return;\n }\n terminalEventWritten = true;\n const event = isThreadAlreadyRunning(error)\n ? {\n type: EventType.RUN_ERROR,\n message: \"Thread already running\",\n code: THREAD_ALREADY_RUNNING_ERROR_CODE,\n }\n : { type: EventType.RUN_ERROR, message: \"Agent run failed\" };\n // The inspector sees every streamed event, so it needs this one too or\n // the run it saw start never ends there. A run that never started has\n // no ids to file it under, so it is not sent.\n if (debugEventBus && debugRunId) {\n try {\n debugEventBus.broadcast(event as BaseEvent, {\n agentId: agentId ?? \"\",\n threadId: debugThreadId,\n runId: debugRunId,\n });\n } catch (broadcastError) {\n logError(broadcastError);\n }\n }\n try {\n await writer.write(encoder.encodeBinary(event as BaseEvent));\n } catch {\n // The client is already gone; closeStream() handles the rest.\n }\n };\n\n const logError = (error: unknown) => {\n console.error(\"Error running agent:\", error);\n console.error(\n \"Error stack:\",\n error instanceof Error ? error.stack : \"No stack trace\",\n );\n console.error(\"Error details:\", {\n name: error instanceof Error ? error.name : \"Unknown\",\n message: error instanceof Error ? error.message : String(error),\n cause: error instanceof Error ? error.cause : undefined,\n });\n };\n\n let subscription: Subscription | undefined;\n let agentErrorReported = false;\n\n const reportAgentError = (error: unknown, phase: RuntimeErrorPhase) => {\n if (agentErrorReported) return;\n agentErrorReported = true;\n runtimeErrorReporter?.report({\n request,\n error,\n operation: \"agent.run\",\n agentId,\n threadId: debugThreadId || undefined,\n runId: debugRunId || undefined,\n phase,\n startTime,\n });\n };\n\n (async () => {\n const observable = await observableFactory();\n\n if (captureTelemetry) {\n telemetry.capture(\"oss.runtime.agent_execution_stream_started\", {});\n }\n\n if (debug?.lifecycle) {\n debugLogger!.debug(\"SSE stream opened\");\n }\n\n let eventCount = 0;\n let loggedEventCount = 0;\n\n // Provider/model/LangGraph facts, scraped off raw upstream events as\n // they pass and reported once the stream finishes. This moved here from\n // the v1 TelemetryAgentRunner, which wrapped the runner purely to\n // collect it and emitted its own duplicate copy of every stream event\n // to carry it. v2 callers had no equivalent and reported `{}`.\n // Seeded rather than empty: `llmHostClass` comes from the agent's config,\n // not from the wire, so nothing streamed will ever fill it in. Scraped\n // fields still win, since `collectExecutionInfo` writes over this.\n const executionInfo: AgentExecutionResponseInfo = { ...executionSeed };\n\n subscription = observable.subscribe({\n next: async (event) => {\n collectExecutionInfo(event, executionInfo);\n\n // Extract threadId/runId from RUN_STARTED\n if (event.type === \"RUN_STARTED\") {\n const e = event as { threadId?: string; runId?: string };\n debugThreadId = e.threadId ?? \"\";\n debugRunId = e.runId ?? \"\";\n }\n\n if (event.type === \"RUN_ERROR\") {\n const e = event as {\n message?: unknown;\n threadId?: string;\n runId?: string;\n };\n debugThreadId = e.threadId ?? debugThreadId;\n debugRunId = e.runId ?? debugRunId;\n reportAgentError(\n new Error(\n typeof e.message === \"string\"\n ? e.message\n : \"Runner reported a run error\",\n ),\n \"sse.subscription\",\n );\n }\n\n // Broadcast to debug listeners BEFORE the stream-closed gate below.\n // Intentional: debug subscribers (e.g. the VS Code Inspector panel)\n // should still receive trailing events after the SSE client for\n // this request closed its connection — they're independent\n // consumers observing the underlying runtime, not the request's\n // response stream.\n //\n // Wrapped in try/catch so a buggy debug subscriber can't propagate\n // an exception into this observer — if the throw reached the\n // `next` callback it would get routed to `error` by RxJS, closing\n // the SSE stream for an unrelated reason. Log via `logError` and\n // move on.\n if (debugEventBus) {\n try {\n debugEventBus.broadcast(event, {\n agentId: agentId ?? \"\",\n threadId: debugThreadId,\n runId: debugRunId,\n });\n } catch (broadcastError) {\n logError(broadcastError);\n }\n }\n\n if (!request.signal.aborted && !streamClosed) {\n try {\n eventCount++;\n if (debug?.events) {\n loggedEventCount++;\n if (debug.verbose) {\n debugLogger!.debug({ event }, \"Event emitted\");\n } else {\n debugLogger!.debug(\n { type: event.type, ...summarizeEvent(event) },\n \"Event emitted\",\n );\n }\n }\n // /connect replays finished runs before the live one, so a new\n // RUN_STARTED reopens the stream for a RUN_ERROR.\n if (event.type === EventType.RUN_STARTED) {\n terminalEventWritten = false;\n } else if (\n event.type === EventType.RUN_FINISHED ||\n event.type === EventType.RUN_ERROR\n ) {\n terminalEventWritten = true;\n }\n await writer.write(encoder.encodeBinary(event));\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n streamClosed = true;\n } else {\n // Non-abort write failures (backpressure disconnects,\n // transform-stream exceptions, …) were previously swallowed\n // silently — `streamClosed` stayed `false` and the next\n // event re-attempted a broken writer. Log and mark the\n // stream closed so we stop trying.\n logError(error);\n streamClosed = true;\n }\n }\n }\n },\n error: async (error) => {\n reportAgentError(error, \"sse.subscription\");\n if (captureTelemetry) {\n // Analytics gets the outcome, not the message: provider and tool\n // errors can quote prompts, arguments or URLs. Same as Intelligence.\n telemetry.capture(\"oss.runtime.agent_execution_stream_errored\", {\n ...executionInfo,\n error: \"AGENT_EXECUTION_FAILED\",\n });\n }\n if (debug?.lifecycle) {\n debugLogger!.debug(\n { error: error instanceof Error ? error.message : String(error) },\n \"SSE stream errored\",\n );\n }\n logError(error);\n await writeRunError(error);\n await closeStream();\n },\n complete: async () => {\n if (captureTelemetry) {\n telemetry.capture(\n \"oss.runtime.agent_execution_stream_ended\",\n executionInfo,\n );\n }\n if (debug?.lifecycle) {\n debugLogger!.debug(\n { eventCount, loggedEventCount },\n \"SSE stream completed\",\n );\n }\n await closeStream();\n },\n });\n\n // If the client disconnected before the subscription was created,\n // unsubscribe immediately to avoid leaking the observable.\n if (request.signal.aborted) {\n subscription.unsubscribe();\n }\n })().catch(async (error) => {\n reportAgentError(error, \"sse.factory\");\n logError(error);\n await writeRunError(error);\n await closeStream();\n });\n\n request.signal.addEventListener(\"abort\", () => {\n subscription?.unsubscribe();\n });\n\n const body =\n keepAliveSeconds > 0\n ? keepAliveSse(stream.readable, keepAliveSeconds * 1_000)\n : stream.readable;\n\n return new Response(body, {\n status: 200,\n headers: {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n },\n });\n}\n\nfunction summarizeEvent(event: BaseEvent): Record<string, unknown> {\n const e = event as any;\n const summary: Record<string, unknown> = {};\n\n if (e.messageId) summary.messageId = e.messageId;\n if (e.toolCallId) summary.toolCallId = e.toolCallId;\n if (e.toolCallName) summary.toolCallName = e.toolCallName;\n if (e.role) summary.role = e.role;\n if (e.delta != null && typeof e.delta === \"string\")\n summary.deltaLength = e.delta.length;\n if (e.snapshot && typeof e.snapshot === \"object\")\n summary.snapshotKeys = Object.keys(e.snapshot);\n if (e.delta && Array.isArray(e.delta))\n summary.operationCount = e.delta.length;\n if (e.threadId) summary.threadId = e.threadId;\n if (e.runId) summary.runId = e.runId;\n if (e.message) summary.message = e.message;\n if (e.code) summary.code = e.code;\n if (e.stepName) summary.stepName = e.stepName;\n\n return summary;\n}\n\n/**\n * Accumulate provider, model, and LangGraph facts from one upstream event.\n *\n * Mutates rather than returns so the caller keeps one record across the whole\n * stream: these arrive on different events and the last one wins. Only fields\n * the upstream actually sent are set, so an agent that reports none leaves the\n * record empty and the stream events carry `{}` as before.\n *\n * `rawEvent` is the untransformed upstream payload, present on AG-UI events\n * that wrap one. Its shape is the provider's, not ours, hence the narrowing.\n */\nfunction collectExecutionInfo(\n event: BaseEvent,\n into: AgentExecutionResponseInfo,\n): void {\n const rawEvent = (\n event as {\n rawEvent?: {\n metadata?: Record<string, unknown>;\n data?: Record<string, unknown>;\n };\n }\n ).rawEvent;\n if (!rawEvent) return;\n\n const model = (rawEvent.data as { output?: { model?: string } } | undefined)\n ?.output?.model;\n if (model) {\n into.model = model;\n // Carried forward from the v1 implementation, which set both from the\n // same field. The upstream sends no separate provider name.\n into.provider = model;\n }\n\n const metadata = rawEvent.metadata as\n | { langgraph_host?: string; langgraph_version?: string }\n | undefined;\n if (metadata?.langgraph_host) into.langGraphHost = metadata.langgraph_host;\n if (metadata?.langgraph_version) {\n into.langGraphVersion = metadata.langgraph_version;\n }\n}\n"],"mappings":"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"}
@@ -138,7 +138,7 @@ function createSseEventResponse({ request, observableFactory, debugEventBus, age
138
138
  reportAgentError(error, "sse.subscription");
139
139
  if (captureTelemetry) telemetry$1.capture("oss.runtime.agent_execution_stream_errored", {
140
140
  ...executionInfo,
141
- error: error instanceof Error ? error.message : String(error)
141
+ error: "AGENT_EXECUTION_FAILED"
142
142
  });
143
143
  if (debug?.lifecycle) debugLogger.debug({ error: error instanceof Error ? error.message : String(error) }, "SSE stream errored");
144
144
  logError(error);
@@ -1 +1 @@
1
- {"version":3,"file":"sse-response.mjs","names":["defaultTelemetry"],"sources":["../../../../../src/v2/runtime/handlers/shared/sse-response.ts"],"sourcesContent":["import { EventType } from \"@ag-ui/client\";\nimport type { BaseEvent } from \"@ag-ui/client\";\nimport { EventEncoder } from \"@ag-ui/encoder\";\nimport type { Observable, Subscription } from \"rxjs\";\nimport {\n keepAliveSse,\n resolveSseKeepAliveIntervalSeconds,\n} from \"./sse-keep-alive\";\nimport { THREAD_ALREADY_RUNNING_ERROR_CODE } from \"@copilotkit/shared\";\nimport type { ResolvedDebugConfig } from \"@copilotkit/shared\";\nimport { createLogger } from \"../../../../v1-deprecated/lib/logger\";\nimport type { CopilotRuntimeLogger } from \"../../../../v1-deprecated/lib/logger\";\nimport { telemetry as defaultTelemetry } from \"../../telemetry\";\nimport type { TelemetryCapture } from \"../../telemetry/telemetry-client\";\nimport type { AgentExecutionResponseInfo } from \"../../telemetry/events\";\nimport type { DebugEventBus } from \"../../core/debug-event-bus\";\nimport type {\n RuntimeErrorPhase,\n RuntimeErrorReporter,\n} from \"../../core/runtime-error-reporter\";\n\n/**\n * Whether a runner rejected the run because the thread is busy. Matches the\n * `code` of {@link ThreadAlreadyRunningError}, and the plain message that\n * custom runners copied from the built-in ones still throw.\n */\nfunction isThreadAlreadyRunning(error: unknown): boolean {\n return (\n error instanceof Error &&\n ((error as { code?: unknown }).code === THREAD_ALREADY_RUNNING_ERROR_CODE ||\n error.message === \"Thread already running\")\n );\n}\n\ninterface CreateSseEventResponseParams {\n request: Request;\n observableFactory: () =>\n | Promise<Observable<BaseEvent>>\n | Observable<BaseEvent>;\n debugEventBus?: DebugEventBus;\n agentId?: string;\n debug?: ResolvedDebugConfig;\n /** Pre-created logger instance to avoid creating a new pino logger per request. */\n logger?: CopilotRuntimeLogger;\n /** Runtime-bound telemetry capture. Falls back for external direct callers. */\n telemetry?: TelemetryCapture;\n /**\n * Execution facts known before the stream opens, merged under anything the\n * upstream reports as it runs. Carries `llmHostClass`, which is knowable\n * from the agent's configuration and never appears on a streamed event.\n */\n executionSeed?: AgentExecutionResponseInfo;\n /**\n * Whether to emit `oss.runtime.agent_execution_stream_*` telemetry for this\n * stream. Defaults to `true`. The stateless `/suggest` path sets this to\n * `false`: a suggestion is a side-effect-free structured completion, not a\n * tracked run, and under `available: \"always\"` it fires often enough to flood\n * run telemetry.\n */\n captureTelemetry?: boolean;\n runtimeErrorReporter?: RuntimeErrorReporter;\n startTime?: number;\n /**\n * Seconds of silence before a `: keep-alive` SSE comment is written.\n * `0` disables the keep-alive. Resolved by\n * {@link resolveSseKeepAliveIntervalSeconds}, which supplies the default\n * and enforces the timer bound for every caller.\n */\n keepAliveIntervalSeconds?: number;\n}\n\nexport function createSseEventResponse({\n request,\n observableFactory,\n debugEventBus,\n agentId,\n debug,\n logger,\n telemetry = defaultTelemetry,\n executionSeed,\n captureTelemetry = true,\n runtimeErrorReporter,\n startTime,\n keepAliveIntervalSeconds,\n}: CreateSseEventResponseParams): Response {\n const keepAliveSeconds = resolveSseKeepAliveIntervalSeconds(\n keepAliveIntervalSeconds,\n );\n const stream = new TransformStream();\n const writer = stream.writable.getWriter();\n const encoder = new EventEncoder();\n let streamClosed = false;\n // Set once the current run's RUN_FINISHED or RUN_ERROR has been queued for\n // the client. AG-UI allows nothing after either until the next RUN_STARTED,\n // so a later failure must not add a RUN_ERROR.\n let terminalEventWritten = false;\n let debugThreadId = \"\";\n let debugRunId = \"\";\n\n const debugLogger = debug?.enabled\n ? (logger ??\n createLogger({ level: \"debug\", component: \"copilotkit-debug\" }))\n : undefined;\n\n const closeStream = async () => {\n if (!streamClosed) {\n try {\n await writer.close();\n streamClosed = true;\n } catch {\n // Stream already closed.\n }\n }\n };\n\n // Report a failure to the client as a terminal RUN_ERROR. Without it the\n // client sees an empty stream that ends normally, so its run \"succeeds\"\n // with no reply and no error (e.g. \"Thread already running\" on a busy\n // thread). Only a busy thread is named, with a code clients can branch on;\n // anything else may carry internal detail, so the client gets a generic\n // message and the full error stays in the server log.\n const writeRunError = async (error: unknown) => {\n if (terminalEventWritten || streamClosed || request.signal.aborted) {\n return;\n }\n terminalEventWritten = true;\n const event = isThreadAlreadyRunning(error)\n ? {\n type: EventType.RUN_ERROR,\n message: \"Thread already running\",\n code: THREAD_ALREADY_RUNNING_ERROR_CODE,\n }\n : { type: EventType.RUN_ERROR, message: \"Agent run failed\" };\n // The inspector sees every streamed event, so it needs this one too or\n // the run it saw start never ends there. A run that never started has\n // no ids to file it under, so it is not sent.\n if (debugEventBus && debugRunId) {\n try {\n debugEventBus.broadcast(event as BaseEvent, {\n agentId: agentId ?? \"\",\n threadId: debugThreadId,\n runId: debugRunId,\n });\n } catch (broadcastError) {\n logError(broadcastError);\n }\n }\n try {\n await writer.write(encoder.encodeBinary(event as BaseEvent));\n } catch {\n // The client is already gone; closeStream() handles the rest.\n }\n };\n\n const logError = (error: unknown) => {\n console.error(\"Error running agent:\", error);\n console.error(\n \"Error stack:\",\n error instanceof Error ? error.stack : \"No stack trace\",\n );\n console.error(\"Error details:\", {\n name: error instanceof Error ? error.name : \"Unknown\",\n message: error instanceof Error ? error.message : String(error),\n cause: error instanceof Error ? error.cause : undefined,\n });\n };\n\n let subscription: Subscription | undefined;\n let agentErrorReported = false;\n\n const reportAgentError = (error: unknown, phase: RuntimeErrorPhase) => {\n if (agentErrorReported) return;\n agentErrorReported = true;\n runtimeErrorReporter?.report({\n request,\n error,\n operation: \"agent.run\",\n agentId,\n threadId: debugThreadId || undefined,\n runId: debugRunId || undefined,\n phase,\n startTime,\n });\n };\n\n (async () => {\n const observable = await observableFactory();\n\n if (captureTelemetry) {\n telemetry.capture(\"oss.runtime.agent_execution_stream_started\", {});\n }\n\n if (debug?.lifecycle) {\n debugLogger!.debug(\"SSE stream opened\");\n }\n\n let eventCount = 0;\n let loggedEventCount = 0;\n\n // Provider/model/LangGraph facts, scraped off raw upstream events as\n // they pass and reported once the stream finishes. This moved here from\n // the v1 TelemetryAgentRunner, which wrapped the runner purely to\n // collect it and emitted its own duplicate copy of every stream event\n // to carry it. v2 callers had no equivalent and reported `{}`.\n // Seeded rather than empty: `llmHostClass` comes from the agent's config,\n // not from the wire, so nothing streamed will ever fill it in. Scraped\n // fields still win, since `collectExecutionInfo` writes over this.\n const executionInfo: AgentExecutionResponseInfo = { ...executionSeed };\n\n subscription = observable.subscribe({\n next: async (event) => {\n collectExecutionInfo(event, executionInfo);\n\n // Extract threadId/runId from RUN_STARTED\n if (event.type === \"RUN_STARTED\") {\n const e = event as { threadId?: string; runId?: string };\n debugThreadId = e.threadId ?? \"\";\n debugRunId = e.runId ?? \"\";\n }\n\n if (event.type === \"RUN_ERROR\") {\n const e = event as {\n message?: unknown;\n threadId?: string;\n runId?: string;\n };\n debugThreadId = e.threadId ?? debugThreadId;\n debugRunId = e.runId ?? debugRunId;\n reportAgentError(\n new Error(\n typeof e.message === \"string\"\n ? e.message\n : \"Runner reported a run error\",\n ),\n \"sse.subscription\",\n );\n }\n\n // Broadcast to debug listeners BEFORE the stream-closed gate below.\n // Intentional: debug subscribers (e.g. the VS Code Inspector panel)\n // should still receive trailing events after the SSE client for\n // this request closed its connection — they're independent\n // consumers observing the underlying runtime, not the request's\n // response stream.\n //\n // Wrapped in try/catch so a buggy debug subscriber can't propagate\n // an exception into this observer — if the throw reached the\n // `next` callback it would get routed to `error` by RxJS, closing\n // the SSE stream for an unrelated reason. Log via `logError` and\n // move on.\n if (debugEventBus) {\n try {\n debugEventBus.broadcast(event, {\n agentId: agentId ?? \"\",\n threadId: debugThreadId,\n runId: debugRunId,\n });\n } catch (broadcastError) {\n logError(broadcastError);\n }\n }\n\n if (!request.signal.aborted && !streamClosed) {\n try {\n eventCount++;\n if (debug?.events) {\n loggedEventCount++;\n if (debug.verbose) {\n debugLogger!.debug({ event }, \"Event emitted\");\n } else {\n debugLogger!.debug(\n { type: event.type, ...summarizeEvent(event) },\n \"Event emitted\",\n );\n }\n }\n // /connect replays finished runs before the live one, so a new\n // RUN_STARTED reopens the stream for a RUN_ERROR.\n if (event.type === EventType.RUN_STARTED) {\n terminalEventWritten = false;\n } else if (\n event.type === EventType.RUN_FINISHED ||\n event.type === EventType.RUN_ERROR\n ) {\n terminalEventWritten = true;\n }\n await writer.write(encoder.encodeBinary(event));\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n streamClosed = true;\n } else {\n // Non-abort write failures (backpressure disconnects,\n // transform-stream exceptions, …) were previously swallowed\n // silently — `streamClosed` stayed `false` and the next\n // event re-attempted a broken writer. Log and mark the\n // stream closed so we stop trying.\n logError(error);\n streamClosed = true;\n }\n }\n }\n },\n error: async (error) => {\n reportAgentError(error, \"sse.subscription\");\n if (captureTelemetry) {\n telemetry.capture(\"oss.runtime.agent_execution_stream_errored\", {\n ...executionInfo,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n if (debug?.lifecycle) {\n debugLogger!.debug(\n { error: error instanceof Error ? error.message : String(error) },\n \"SSE stream errored\",\n );\n }\n logError(error);\n await writeRunError(error);\n await closeStream();\n },\n complete: async () => {\n if (captureTelemetry) {\n telemetry.capture(\n \"oss.runtime.agent_execution_stream_ended\",\n executionInfo,\n );\n }\n if (debug?.lifecycle) {\n debugLogger!.debug(\n { eventCount, loggedEventCount },\n \"SSE stream completed\",\n );\n }\n await closeStream();\n },\n });\n\n // If the client disconnected before the subscription was created,\n // unsubscribe immediately to avoid leaking the observable.\n if (request.signal.aborted) {\n subscription.unsubscribe();\n }\n })().catch(async (error) => {\n reportAgentError(error, \"sse.factory\");\n logError(error);\n await writeRunError(error);\n await closeStream();\n });\n\n request.signal.addEventListener(\"abort\", () => {\n subscription?.unsubscribe();\n });\n\n const body =\n keepAliveSeconds > 0\n ? keepAliveSse(stream.readable, keepAliveSeconds * 1_000)\n : stream.readable;\n\n return new Response(body, {\n status: 200,\n headers: {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n },\n });\n}\n\nfunction summarizeEvent(event: BaseEvent): Record<string, unknown> {\n const e = event as any;\n const summary: Record<string, unknown> = {};\n\n if (e.messageId) summary.messageId = e.messageId;\n if (e.toolCallId) summary.toolCallId = e.toolCallId;\n if (e.toolCallName) summary.toolCallName = e.toolCallName;\n if (e.role) summary.role = e.role;\n if (e.delta != null && typeof e.delta === \"string\")\n summary.deltaLength = e.delta.length;\n if (e.snapshot && typeof e.snapshot === \"object\")\n summary.snapshotKeys = Object.keys(e.snapshot);\n if (e.delta && Array.isArray(e.delta))\n summary.operationCount = e.delta.length;\n if (e.threadId) summary.threadId = e.threadId;\n if (e.runId) summary.runId = e.runId;\n if (e.message) summary.message = e.message;\n if (e.code) summary.code = e.code;\n if (e.stepName) summary.stepName = e.stepName;\n\n return summary;\n}\n\n/**\n * Accumulate provider, model, and LangGraph facts from one upstream event.\n *\n * Mutates rather than returns so the caller keeps one record across the whole\n * stream: these arrive on different events and the last one wins. Only fields\n * the upstream actually sent are set, so an agent that reports none leaves the\n * record empty and the stream events carry `{}` as before.\n *\n * `rawEvent` is the untransformed upstream payload, present on AG-UI events\n * that wrap one. Its shape is the provider's, not ours, hence the narrowing.\n */\nfunction collectExecutionInfo(\n event: BaseEvent,\n into: AgentExecutionResponseInfo,\n): void {\n const rawEvent = (\n event as {\n rawEvent?: {\n metadata?: Record<string, unknown>;\n data?: Record<string, unknown>;\n };\n }\n ).rawEvent;\n if (!rawEvent) return;\n\n const model = (rawEvent.data as { output?: { model?: string } } | undefined)\n ?.output?.model;\n if (model) {\n into.model = model;\n // Carried forward from the v1 implementation, which set both from the\n // same field. The upstream sends no separate provider name.\n into.provider = model;\n }\n\n const metadata = rawEvent.metadata as\n | { langgraph_host?: string; langgraph_version?: string }\n | undefined;\n if (metadata?.langgraph_host) into.langGraphHost = metadata.langgraph_host;\n if (metadata?.langgraph_version) {\n into.langGraphVersion = metadata.langgraph_version;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"sse-response.mjs","names":["defaultTelemetry"],"sources":["../../../../../src/v2/runtime/handlers/shared/sse-response.ts"],"sourcesContent":["import { EventType } from \"@ag-ui/client\";\nimport type { BaseEvent } from \"@ag-ui/client\";\nimport { EventEncoder } from \"@ag-ui/encoder\";\nimport type { Observable, Subscription } from \"rxjs\";\nimport {\n keepAliveSse,\n resolveSseKeepAliveIntervalSeconds,\n} from \"./sse-keep-alive\";\nimport { THREAD_ALREADY_RUNNING_ERROR_CODE } from \"@copilotkit/shared\";\nimport type { ResolvedDebugConfig } from \"@copilotkit/shared\";\nimport { createLogger } from \"../../../../v1-deprecated/lib/logger\";\nimport type { CopilotRuntimeLogger } from \"../../../../v1-deprecated/lib/logger\";\nimport { telemetry as defaultTelemetry } from \"../../telemetry\";\nimport type { TelemetryCapture } from \"../../telemetry/telemetry-client\";\nimport type { AgentExecutionResponseInfo } from \"../../telemetry/events\";\nimport type { DebugEventBus } from \"../../core/debug-event-bus\";\nimport type {\n RuntimeErrorPhase,\n RuntimeErrorReporter,\n} from \"../../core/runtime-error-reporter\";\n\n/**\n * Whether a runner rejected the run because the thread is busy. Matches the\n * `code` of {@link ThreadAlreadyRunningError}, and the plain message that\n * custom runners copied from the built-in ones still throw.\n */\nfunction isThreadAlreadyRunning(error: unknown): boolean {\n return (\n error instanceof Error &&\n ((error as { code?: unknown }).code === THREAD_ALREADY_RUNNING_ERROR_CODE ||\n error.message === \"Thread already running\")\n );\n}\n\ninterface CreateSseEventResponseParams {\n request: Request;\n observableFactory: () =>\n | Promise<Observable<BaseEvent>>\n | Observable<BaseEvent>;\n debugEventBus?: DebugEventBus;\n agentId?: string;\n debug?: ResolvedDebugConfig;\n /** Pre-created logger instance to avoid creating a new pino logger per request. */\n logger?: CopilotRuntimeLogger;\n /** Runtime-bound telemetry capture. Falls back for external direct callers. */\n telemetry?: TelemetryCapture;\n /**\n * Execution facts known before the stream opens, merged under anything the\n * upstream reports as it runs. Carries `llmHostClass`, which is knowable\n * from the agent's configuration and never appears on a streamed event.\n */\n executionSeed?: AgentExecutionResponseInfo;\n /**\n * Whether to emit `oss.runtime.agent_execution_stream_*` telemetry for this\n * stream. Defaults to `true`. The stateless `/suggest` path sets this to\n * `false`: a suggestion is a side-effect-free structured completion, not a\n * tracked run, and under `available: \"always\"` it fires often enough to flood\n * run telemetry.\n */\n captureTelemetry?: boolean;\n runtimeErrorReporter?: RuntimeErrorReporter;\n startTime?: number;\n /**\n * Seconds of silence before a `: keep-alive` SSE comment is written.\n * `0` disables the keep-alive. Resolved by\n * {@link resolveSseKeepAliveIntervalSeconds}, which supplies the default\n * and enforces the timer bound for every caller.\n */\n keepAliveIntervalSeconds?: number;\n}\n\nexport function createSseEventResponse({\n request,\n observableFactory,\n debugEventBus,\n agentId,\n debug,\n logger,\n telemetry = defaultTelemetry,\n executionSeed,\n captureTelemetry = true,\n runtimeErrorReporter,\n startTime,\n keepAliveIntervalSeconds,\n}: CreateSseEventResponseParams): Response {\n const keepAliveSeconds = resolveSseKeepAliveIntervalSeconds(\n keepAliveIntervalSeconds,\n );\n const stream = new TransformStream();\n const writer = stream.writable.getWriter();\n const encoder = new EventEncoder();\n let streamClosed = false;\n // Set once the current run's RUN_FINISHED or RUN_ERROR has been queued for\n // the client. AG-UI allows nothing after either until the next RUN_STARTED,\n // so a later failure must not add a RUN_ERROR.\n let terminalEventWritten = false;\n let debugThreadId = \"\";\n let debugRunId = \"\";\n\n const debugLogger = debug?.enabled\n ? (logger ??\n createLogger({ level: \"debug\", component: \"copilotkit-debug\" }))\n : undefined;\n\n const closeStream = async () => {\n if (!streamClosed) {\n try {\n await writer.close();\n streamClosed = true;\n } catch {\n // Stream already closed.\n }\n }\n };\n\n // Report a failure to the client as a terminal RUN_ERROR. Without it the\n // client sees an empty stream that ends normally, so its run \"succeeds\"\n // with no reply and no error (e.g. \"Thread already running\" on a busy\n // thread). Only a busy thread is named, with a code clients can branch on;\n // anything else may carry internal detail, so the client gets a generic\n // message and the full error stays in the server log.\n const writeRunError = async (error: unknown) => {\n if (terminalEventWritten || streamClosed || request.signal.aborted) {\n return;\n }\n terminalEventWritten = true;\n const event = isThreadAlreadyRunning(error)\n ? {\n type: EventType.RUN_ERROR,\n message: \"Thread already running\",\n code: THREAD_ALREADY_RUNNING_ERROR_CODE,\n }\n : { type: EventType.RUN_ERROR, message: \"Agent run failed\" };\n // The inspector sees every streamed event, so it needs this one too or\n // the run it saw start never ends there. A run that never started has\n // no ids to file it under, so it is not sent.\n if (debugEventBus && debugRunId) {\n try {\n debugEventBus.broadcast(event as BaseEvent, {\n agentId: agentId ?? \"\",\n threadId: debugThreadId,\n runId: debugRunId,\n });\n } catch (broadcastError) {\n logError(broadcastError);\n }\n }\n try {\n await writer.write(encoder.encodeBinary(event as BaseEvent));\n } catch {\n // The client is already gone; closeStream() handles the rest.\n }\n };\n\n const logError = (error: unknown) => {\n console.error(\"Error running agent:\", error);\n console.error(\n \"Error stack:\",\n error instanceof Error ? error.stack : \"No stack trace\",\n );\n console.error(\"Error details:\", {\n name: error instanceof Error ? error.name : \"Unknown\",\n message: error instanceof Error ? error.message : String(error),\n cause: error instanceof Error ? error.cause : undefined,\n });\n };\n\n let subscription: Subscription | undefined;\n let agentErrorReported = false;\n\n const reportAgentError = (error: unknown, phase: RuntimeErrorPhase) => {\n if (agentErrorReported) return;\n agentErrorReported = true;\n runtimeErrorReporter?.report({\n request,\n error,\n operation: \"agent.run\",\n agentId,\n threadId: debugThreadId || undefined,\n runId: debugRunId || undefined,\n phase,\n startTime,\n });\n };\n\n (async () => {\n const observable = await observableFactory();\n\n if (captureTelemetry) {\n telemetry.capture(\"oss.runtime.agent_execution_stream_started\", {});\n }\n\n if (debug?.lifecycle) {\n debugLogger!.debug(\"SSE stream opened\");\n }\n\n let eventCount = 0;\n let loggedEventCount = 0;\n\n // Provider/model/LangGraph facts, scraped off raw upstream events as\n // they pass and reported once the stream finishes. This moved here from\n // the v1 TelemetryAgentRunner, which wrapped the runner purely to\n // collect it and emitted its own duplicate copy of every stream event\n // to carry it. v2 callers had no equivalent and reported `{}`.\n // Seeded rather than empty: `llmHostClass` comes from the agent's config,\n // not from the wire, so nothing streamed will ever fill it in. Scraped\n // fields still win, since `collectExecutionInfo` writes over this.\n const executionInfo: AgentExecutionResponseInfo = { ...executionSeed };\n\n subscription = observable.subscribe({\n next: async (event) => {\n collectExecutionInfo(event, executionInfo);\n\n // Extract threadId/runId from RUN_STARTED\n if (event.type === \"RUN_STARTED\") {\n const e = event as { threadId?: string; runId?: string };\n debugThreadId = e.threadId ?? \"\";\n debugRunId = e.runId ?? \"\";\n }\n\n if (event.type === \"RUN_ERROR\") {\n const e = event as {\n message?: unknown;\n threadId?: string;\n runId?: string;\n };\n debugThreadId = e.threadId ?? debugThreadId;\n debugRunId = e.runId ?? debugRunId;\n reportAgentError(\n new Error(\n typeof e.message === \"string\"\n ? e.message\n : \"Runner reported a run error\",\n ),\n \"sse.subscription\",\n );\n }\n\n // Broadcast to debug listeners BEFORE the stream-closed gate below.\n // Intentional: debug subscribers (e.g. the VS Code Inspector panel)\n // should still receive trailing events after the SSE client for\n // this request closed its connection — they're independent\n // consumers observing the underlying runtime, not the request's\n // response stream.\n //\n // Wrapped in try/catch so a buggy debug subscriber can't propagate\n // an exception into this observer — if the throw reached the\n // `next` callback it would get routed to `error` by RxJS, closing\n // the SSE stream for an unrelated reason. Log via `logError` and\n // move on.\n if (debugEventBus) {\n try {\n debugEventBus.broadcast(event, {\n agentId: agentId ?? \"\",\n threadId: debugThreadId,\n runId: debugRunId,\n });\n } catch (broadcastError) {\n logError(broadcastError);\n }\n }\n\n if (!request.signal.aborted && !streamClosed) {\n try {\n eventCount++;\n if (debug?.events) {\n loggedEventCount++;\n if (debug.verbose) {\n debugLogger!.debug({ event }, \"Event emitted\");\n } else {\n debugLogger!.debug(\n { type: event.type, ...summarizeEvent(event) },\n \"Event emitted\",\n );\n }\n }\n // /connect replays finished runs before the live one, so a new\n // RUN_STARTED reopens the stream for a RUN_ERROR.\n if (event.type === EventType.RUN_STARTED) {\n terminalEventWritten = false;\n } else if (\n event.type === EventType.RUN_FINISHED ||\n event.type === EventType.RUN_ERROR\n ) {\n terminalEventWritten = true;\n }\n await writer.write(encoder.encodeBinary(event));\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n streamClosed = true;\n } else {\n // Non-abort write failures (backpressure disconnects,\n // transform-stream exceptions, …) were previously swallowed\n // silently — `streamClosed` stayed `false` and the next\n // event re-attempted a broken writer. Log and mark the\n // stream closed so we stop trying.\n logError(error);\n streamClosed = true;\n }\n }\n }\n },\n error: async (error) => {\n reportAgentError(error, \"sse.subscription\");\n if (captureTelemetry) {\n // Analytics gets the outcome, not the message: provider and tool\n // errors can quote prompts, arguments or URLs. Same as Intelligence.\n telemetry.capture(\"oss.runtime.agent_execution_stream_errored\", {\n ...executionInfo,\n error: \"AGENT_EXECUTION_FAILED\",\n });\n }\n if (debug?.lifecycle) {\n debugLogger!.debug(\n { error: error instanceof Error ? error.message : String(error) },\n \"SSE stream errored\",\n );\n }\n logError(error);\n await writeRunError(error);\n await closeStream();\n },\n complete: async () => {\n if (captureTelemetry) {\n telemetry.capture(\n \"oss.runtime.agent_execution_stream_ended\",\n executionInfo,\n );\n }\n if (debug?.lifecycle) {\n debugLogger!.debug(\n { eventCount, loggedEventCount },\n \"SSE stream completed\",\n );\n }\n await closeStream();\n },\n });\n\n // If the client disconnected before the subscription was created,\n // unsubscribe immediately to avoid leaking the observable.\n if (request.signal.aborted) {\n subscription.unsubscribe();\n }\n })().catch(async (error) => {\n reportAgentError(error, \"sse.factory\");\n logError(error);\n await writeRunError(error);\n await closeStream();\n });\n\n request.signal.addEventListener(\"abort\", () => {\n subscription?.unsubscribe();\n });\n\n const body =\n keepAliveSeconds > 0\n ? keepAliveSse(stream.readable, keepAliveSeconds * 1_000)\n : stream.readable;\n\n return new Response(body, {\n status: 200,\n headers: {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n },\n });\n}\n\nfunction summarizeEvent(event: BaseEvent): Record<string, unknown> {\n const e = event as any;\n const summary: Record<string, unknown> = {};\n\n if (e.messageId) summary.messageId = e.messageId;\n if (e.toolCallId) summary.toolCallId = e.toolCallId;\n if (e.toolCallName) summary.toolCallName = e.toolCallName;\n if (e.role) summary.role = e.role;\n if (e.delta != null && typeof e.delta === \"string\")\n summary.deltaLength = e.delta.length;\n if (e.snapshot && typeof e.snapshot === \"object\")\n summary.snapshotKeys = Object.keys(e.snapshot);\n if (e.delta && Array.isArray(e.delta))\n summary.operationCount = e.delta.length;\n if (e.threadId) summary.threadId = e.threadId;\n if (e.runId) summary.runId = e.runId;\n if (e.message) summary.message = e.message;\n if (e.code) summary.code = e.code;\n if (e.stepName) summary.stepName = e.stepName;\n\n return summary;\n}\n\n/**\n * Accumulate provider, model, and LangGraph facts from one upstream event.\n *\n * Mutates rather than returns so the caller keeps one record across the whole\n * stream: these arrive on different events and the last one wins. Only fields\n * the upstream actually sent are set, so an agent that reports none leaves the\n * record empty and the stream events carry `{}` as before.\n *\n * `rawEvent` is the untransformed upstream payload, present on AG-UI events\n * that wrap one. Its shape is the provider's, not ours, hence the narrowing.\n */\nfunction collectExecutionInfo(\n event: BaseEvent,\n into: AgentExecutionResponseInfo,\n): void {\n const rawEvent = (\n event as {\n rawEvent?: {\n metadata?: Record<string, unknown>;\n data?: Record<string, unknown>;\n };\n }\n ).rawEvent;\n if (!rawEvent) return;\n\n const model = (rawEvent.data as { output?: { model?: string } } | undefined)\n ?.output?.model;\n if (model) {\n into.model = model;\n // Carried forward from the v1 implementation, which set both from the\n // same field. The upstream sends no separate provider name.\n into.provider = model;\n }\n\n const metadata = rawEvent.metadata as\n | { langgraph_host?: string; langgraph_version?: string }\n | undefined;\n if (metadata?.langgraph_host) into.langGraphHost = metadata.langgraph_host;\n if (metadata?.langgraph_version) {\n into.langGraphVersion = metadata.langgraph_version;\n }\n}\n"],"mappings":"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"}
@@ -1215,6 +1215,7 @@ var CopilotKitIntelligence = class {
1215
1215
  agentId: params.agentId,
1216
1216
  ...params.supportsBackendThreadId === void 0 ? {} : { supportsBackendThreadId: params.supportsBackendThreadId },
1217
1217
  ...params.learningContainerId !== void 0 ? { learningContainerId: params.learningContainerId } : {},
1218
+ ...params.requestId !== void 0 ? { requestId: params.requestId } : {},
1218
1219
  ...params.lockKeyPrefix !== void 0 ? { lockKeyPrefix: params.lockKeyPrefix } : {},
1219
1220
  ...params.ttlSeconds !== void 0 ? { ttlSeconds: params.ttlSeconds } : {}
1220
1221
  }, params.channelDeliveryId ? { "X-Cpki-Channel-Delivery-Id": params.channelDeliveryId } : void 0);