@copilotkit/runtime 1.56.2 → 1.56.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/graphql/resolvers/copilot.resolver.cjs +2 -1
- package/dist/graphql/resolvers/copilot.resolver.cjs.map +1 -1
- package/dist/graphql/resolvers/copilot.resolver.mjs +2 -1
- package/dist/graphql/resolvers/copilot.resolver.mjs.map +1 -1
- package/dist/graphql/resolvers/resolve-message-id.cjs +19 -0
- package/dist/graphql/resolvers/resolve-message-id.cjs.map +1 -0
- package/dist/graphql/resolvers/resolve-message-id.mjs +18 -0
- package/dist/graphql/resolvers/resolve-message-id.mjs.map +1 -0
- package/dist/lib/runtime/copilot-runtime.cjs +4 -2
- package/dist/lib/runtime/copilot-runtime.cjs.map +1 -1
- package/dist/lib/runtime/copilot-runtime.d.cts.map +1 -1
- package/dist/lib/runtime/copilot-runtime.d.mts.map +1 -1
- package/dist/lib/runtime/copilot-runtime.mjs +4 -2
- package/dist/lib/runtime/copilot-runtime.mjs.map +1 -1
- package/dist/package.cjs +2 -2
- package/dist/package.mjs +2 -2
- package/dist/v2/runtime/core/debug-event-bus.cjs +36 -0
- package/dist/v2/runtime/core/debug-event-bus.cjs.map +1 -0
- package/dist/v2/runtime/core/debug-event-bus.d.cts +19 -0
- package/dist/v2/runtime/core/debug-event-bus.d.cts.map +1 -0
- package/dist/v2/runtime/core/debug-event-bus.d.mts +19 -0
- package/dist/v2/runtime/core/debug-event-bus.d.mts.map +1 -0
- package/dist/v2/runtime/core/debug-event-bus.mjs +35 -0
- package/dist/v2/runtime/core/debug-event-bus.mjs.map +1 -0
- package/dist/v2/runtime/core/fetch-handler.cjs +6 -0
- package/dist/v2/runtime/core/fetch-handler.cjs.map +1 -1
- package/dist/v2/runtime/core/fetch-handler.d.cts.map +1 -1
- package/dist/v2/runtime/core/fetch-handler.d.mts.map +1 -1
- package/dist/v2/runtime/core/fetch-handler.mjs +6 -0
- package/dist/v2/runtime/core/fetch-handler.mjs.map +1 -1
- package/dist/v2/runtime/core/fetch-router.cjs +1 -0
- package/dist/v2/runtime/core/fetch-router.cjs.map +1 -1
- package/dist/v2/runtime/core/fetch-router.mjs +1 -0
- package/dist/v2/runtime/core/fetch-router.mjs.map +1 -1
- package/dist/v2/runtime/core/hooks.cjs.map +1 -1
- package/dist/v2/runtime/core/hooks.d.cts +2 -0
- package/dist/v2/runtime/core/hooks.d.cts.map +1 -1
- package/dist/v2/runtime/core/hooks.d.mts +2 -0
- package/dist/v2/runtime/core/hooks.d.mts.map +1 -1
- package/dist/v2/runtime/core/hooks.mjs.map +1 -1
- package/dist/v2/runtime/core/runtime.cjs +5 -0
- package/dist/v2/runtime/core/runtime.cjs.map +1 -1
- package/dist/v2/runtime/core/runtime.d.cts +5 -0
- package/dist/v2/runtime/core/runtime.d.cts.map +1 -1
- package/dist/v2/runtime/core/runtime.d.mts +5 -0
- package/dist/v2/runtime/core/runtime.d.mts.map +1 -1
- package/dist/v2/runtime/core/runtime.mjs +5 -0
- package/dist/v2/runtime/core/runtime.mjs.map +1 -1
- package/dist/v2/runtime/handlers/handle-connect.cjs +2 -0
- package/dist/v2/runtime/handlers/handle-connect.cjs.map +1 -1
- package/dist/v2/runtime/handlers/handle-connect.mjs +2 -0
- package/dist/v2/runtime/handlers/handle-connect.mjs.map +1 -1
- package/dist/v2/runtime/handlers/handle-debug-events.cjs +33 -0
- package/dist/v2/runtime/handlers/handle-debug-events.cjs.map +1 -0
- package/dist/v2/runtime/handlers/handle-debug-events.mjs +32 -0
- package/dist/v2/runtime/handlers/handle-debug-events.mjs.map +1 -0
- package/dist/v2/runtime/handlers/handle-run.cjs +1 -0
- package/dist/v2/runtime/handlers/handle-run.cjs.map +1 -1
- package/dist/v2/runtime/handlers/handle-run.mjs +1 -0
- package/dist/v2/runtime/handlers/handle-run.mjs.map +1 -1
- package/dist/v2/runtime/handlers/intelligence/connect.cjs +32 -2
- package/dist/v2/runtime/handlers/intelligence/connect.cjs.map +1 -1
- package/dist/v2/runtime/handlers/intelligence/connect.mjs +31 -2
- package/dist/v2/runtime/handlers/intelligence/connect.mjs.map +1 -1
- package/dist/v2/runtime/handlers/shared/resolve-intelligence-user.cjs +5 -1
- package/dist/v2/runtime/handlers/shared/resolve-intelligence-user.cjs.map +1 -1
- package/dist/v2/runtime/handlers/shared/resolve-intelligence-user.mjs +5 -1
- package/dist/v2/runtime/handlers/shared/resolve-intelligence-user.mjs.map +1 -1
- package/dist/v2/runtime/handlers/shared/sse-response.cjs +21 -1
- package/dist/v2/runtime/handlers/shared/sse-response.cjs.map +1 -1
- package/dist/v2/runtime/handlers/shared/sse-response.mjs +21 -1
- package/dist/v2/runtime/handlers/shared/sse-response.mjs.map +1 -1
- package/dist/v2/runtime/handlers/sse/connect.cjs +3 -1
- package/dist/v2/runtime/handlers/sse/connect.cjs.map +1 -1
- package/dist/v2/runtime/handlers/sse/connect.mjs +3 -1
- package/dist/v2/runtime/handlers/sse/connect.mjs.map +1 -1
- package/dist/v2/runtime/handlers/sse/run.cjs +3 -1
- package/dist/v2/runtime/handlers/sse/run.cjs.map +1 -1
- package/dist/v2/runtime/handlers/sse/run.mjs +3 -1
- package/dist/v2/runtime/handlers/sse/run.mjs.map +1 -1
- package/dist/v2/runtime/intelligence-platform/client.cjs +2 -7
- package/dist/v2/runtime/intelligence-platform/client.cjs.map +1 -1
- package/dist/v2/runtime/intelligence-platform/client.d.cts +1 -4
- package/dist/v2/runtime/intelligence-platform/client.d.cts.map +1 -1
- package/dist/v2/runtime/intelligence-platform/client.d.mts +1 -4
- package/dist/v2/runtime/intelligence-platform/client.d.mts.map +1 -1
- package/dist/v2/runtime/intelligence-platform/client.mjs +2 -7
- package/dist/v2/runtime/intelligence-platform/client.mjs.map +1 -1
- package/dist/v2/runtime/runner/intelligence.cjs +17 -5
- package/dist/v2/runtime/runner/intelligence.cjs.map +1 -1
- package/dist/v2/runtime/runner/intelligence.d.cts +1 -0
- package/dist/v2/runtime/runner/intelligence.d.cts.map +1 -1
- package/dist/v2/runtime/runner/intelligence.d.mts +1 -0
- package/dist/v2/runtime/runner/intelligence.d.mts.map +1 -1
- package/dist/v2/runtime/runner/intelligence.mjs +17 -5
- package/dist/v2/runtime/runner/intelligence.mjs.map +1 -1
- package/package.json +3 -3
- package/src/agents/langgraph/__tests__/event-source.test.ts +256 -0
- package/src/graphql/resolvers/__tests__/resolve-message-id.test.ts +25 -0
- package/src/graphql/resolvers/copilot.resolver.ts +2 -1
- package/src/graphql/resolvers/resolve-message-id.ts +14 -0
- package/src/lib/runtime/__tests__/handle-service-adapter.test.ts +108 -0
- package/src/lib/runtime/__tests__/retry-utils.test.ts +137 -0
- package/src/lib/runtime/agent-integrations/langgraph/__tests__/dispatch-event-filtering.test.ts +190 -0
- package/src/lib/runtime/copilot-runtime.ts +20 -4
- package/src/lib/runtime/retry-utils.ts +41 -1
- package/src/v2/runtime/__tests__/fetch-router.test.ts +22 -0
- package/src/v2/runtime/__tests__/handle-connect.test.ts +58 -5
- package/src/v2/runtime/__tests__/handle-run.test.ts +31 -4
- package/src/v2/runtime/__tests__/handle-threads.test.ts +66 -4
- package/src/v2/runtime/__tests__/integration/node-servers.integration.test.ts +19 -0
- package/src/v2/runtime/__tests__/integration/suites/debug-events.suite.ts +253 -0
- package/src/v2/runtime/__tests__/runtime.test.ts +3 -1
- package/src/v2/runtime/core/__tests__/debug-event-bus.test.ts +156 -0
- package/src/v2/runtime/core/debug-event-bus.ts +45 -0
- package/src/v2/runtime/core/fetch-handler.ts +4 -0
- package/src/v2/runtime/core/fetch-router.ts +11 -0
- package/src/v2/runtime/core/hooks.ts +2 -1
- package/src/v2/runtime/core/runtime.ts +12 -0
- package/src/v2/runtime/handlers/__tests__/handle-debug-events.test.ts +176 -0
- package/src/v2/runtime/handlers/handle-connect.ts +2 -0
- package/src/v2/runtime/handlers/handle-debug-events.ts +52 -0
- package/src/v2/runtime/handlers/handle-run.ts +1 -0
- package/src/v2/runtime/handlers/intelligence/connect.ts +58 -1
- package/src/v2/runtime/handlers/shared/resolve-intelligence-user.ts +4 -1
- package/src/v2/runtime/handlers/shared/sse-response.ts +46 -0
- package/src/v2/runtime/handlers/sse/__tests__/sse-connect-agent-id.test.ts +71 -0
- package/src/v2/runtime/handlers/sse/connect.ts +6 -0
- package/src/v2/runtime/handlers/sse/run.ts +4 -0
- package/src/v2/runtime/intelligence-platform/__tests__/client.test.ts +13 -11
- package/src/v2/runtime/intelligence-platform/client.ts +3 -11
- package/src/v2/runtime/runner/__tests__/intelligence-runner.test.ts +51 -1
- package/src/v2/runtime/runner/intelligence.ts +27 -9
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-handler.cjs","names":["handleCors","runOnRequest","callBeforeRequestMiddleware","runOnBeforeHandler","createJsonRequest","matchRoute","runOnResponse","runOnError","handleRunAgent","handleConnectAgent","handleStopAgent","handleGetRuntimeInfo","handleTranscribe","handleListThreads","handleSubscribeToThreads","handleDeleteThread","handleUpdateThread","handleArchiveThread","handleGetThreadMessages","parseMethodCall","expectString","addCorsHeaders"],"sources":["../../../../src/v2/runtime/core/fetch-handler.ts"],"sourcesContent":["/**\n * Framework-agnostic CopilotKit runtime handler.\n *\n * Returns a pure `(Request) => Promise<Response>` function that can be used\n * directly with Bun, Deno, Cloudflare Workers, Next.js App Router, or any\n * Fetch-native runtime — no framework dependency required.\n *\n * @example\n * ```typescript\n * import { CopilotRuntime, createCopilotRuntimeHandler } from \"@copilotkit/runtime/v2\";\n *\n * const handler = createCopilotRuntimeHandler({\n * runtime: new CopilotRuntime({ agents: { ... } }),\n * basePath: \"/api/copilotkit\",\n * cors: true,\n * });\n *\n * // Bun\n * Bun.serve({ fetch: handler });\n *\n * // Deno\n * Deno.serve(handler);\n *\n * // Cloudflare Workers\n * export default { fetch: handler };\n * ```\n */\n\nimport type { CopilotRuntimeLike } from \"./runtime\";\nimport type { CopilotRuntimeHooks, RouteInfo, HookContext } from \"./hooks\";\nimport {\n runOnRequest,\n runOnBeforeHandler,\n runOnResponse,\n runOnError,\n} from \"./hooks\";\nimport type { CopilotCorsConfig } from \"./fetch-cors\";\nimport { handleCors, addCorsHeaders } from \"./fetch-cors\";\nimport { matchRoute } from \"./fetch-router\";\nimport {\n callBeforeRequestMiddleware,\n callAfterRequestMiddleware,\n} from \"./middleware\";\nimport { handleRunAgent } from \"../handlers/handle-run\";\nimport { handleConnectAgent } from \"../handlers/handle-connect\";\nimport { handleStopAgent } from \"../handlers/handle-stop\";\nimport { handleGetRuntimeInfo } from \"../handlers/get-runtime-info\";\nimport { handleTranscribe } from \"../handlers/handle-transcribe\";\nimport {\n handleListThreads,\n handleSubscribeToThreads,\n handleUpdateThread,\n handleArchiveThread,\n handleDeleteThread,\n handleGetThreadMessages,\n} from \"../handlers/handle-threads\";\nimport {\n parseMethodCall,\n createJsonRequest,\n expectString,\n type MethodCall,\n} from \"../endpoints/single-route-helpers\";\nimport { logger } from \"@copilotkit/shared\";\n\n/* ------------------------------------------------------------------------------------------------\n * Public types\n * --------------------------------------------------------------------------------------------- */\n\nexport interface CopilotRuntimeHandlerOptions {\n runtime: CopilotRuntimeLike;\n\n /**\n * Optional base path for routing.\n *\n * When provided: strict prefix stripping. The handler strips this prefix from the\n * URL pathname and matches the remainder against known routes.\n *\n * When omitted: suffix matching. The handler matches known route patterns as\n * suffixes of the URL pathname.\n */\n basePath?: string;\n\n /**\n * Endpoint mode:\n * - \"multi-route\" (default): Routes like POST /agent/:agentId/run, GET /info, etc.\n * - \"single-route\": Single POST endpoint with JSON envelope { method, params, body }\n */\n mode?: \"multi-route\" | \"single-route\";\n\n /**\n * Optional CORS configuration.\n * When not provided, no CORS headers are added (let the framework handle it).\n * Set to true for permissive defaults, or provide an object.\n */\n cors?: boolean | CopilotCorsConfig;\n\n /**\n * Lifecycle hooks for request processing.\n */\n hooks?: CopilotRuntimeHooks;\n}\n\nexport type CopilotRuntimeFetchHandler = (\n request: Request,\n) => Promise<Response>;\n\n/* ------------------------------------------------------------------------------------------------\n * Handler factory\n * --------------------------------------------------------------------------------------------- */\n\nexport function createCopilotRuntimeHandler(\n options: CopilotRuntimeHandlerOptions,\n): CopilotRuntimeFetchHandler {\n const { runtime, basePath, mode = \"multi-route\", cors, hooks } = options;\n\n const corsConfig = resolveCorsConfig(cors);\n\n return async (request: Request): Promise<Response> => {\n const url = new URL(request.url, \"http://localhost\");\n const path = url.pathname;\n const requestOrigin = request.headers.get(\"origin\");\n\n // Base hook context (route not yet known)\n const baseCtx: HookContext = { request, path, runtime };\n\n let route: RouteInfo | undefined;\n\n try {\n // 1. CORS preflight\n if (corsConfig) {\n const preflight = handleCors(request, corsConfig);\n if (preflight) return preflight;\n }\n\n // 2. onRequest hook\n request = await runOnRequest(hooks, { ...baseCtx, request });\n\n // 3. Legacy beforeRequestMiddleware\n try {\n const maybeModified = await callBeforeRequestMiddleware({\n runtime,\n request,\n path,\n });\n if (maybeModified) {\n request = maybeModified;\n }\n } catch (mwError: unknown) {\n logger.error(\n { err: mwError, url: request.url, path },\n \"Error running before request middleware\",\n );\n if (mwError instanceof Response) {\n return maybeAddCors(mwError, corsConfig, requestOrigin);\n }\n throw mwError;\n }\n\n // 4. Route matching\n let response: Response;\n\n if (mode === \"single-route\") {\n const resolved = await resolveSingleRoute(request, basePath, path);\n route = resolved.route;\n const { methodCall } = resolved;\n // 5. onBeforeHandler hook\n request = await runOnBeforeHandler(hooks, {\n request,\n path,\n runtime,\n route,\n });\n // 6. Wrap body for methods that need it, then dispatch\n if (\n route.method === \"agent/run\" ||\n route.method === \"agent/connect\" ||\n route.method === \"transcribe\"\n ) {\n request = createJsonRequest(request, methodCall.body);\n }\n response = await dispatchRoute(runtime, request, route);\n } else {\n // Multi-route: match URL pattern\n const matched = matchRoute(path, basePath);\n if (!matched) {\n throw jsonResponse({ error: \"Not found\" }, 404);\n }\n\n // Validate HTTP method\n const methodError = validateHttpMethod(request.method, matched);\n if (methodError) {\n route = matched;\n throw methodError;\n }\n\n route = matched;\n\n // 5. onBeforeHandler hook\n request = await runOnBeforeHandler(hooks, {\n request,\n path,\n runtime,\n route,\n });\n\n // 6. Handler dispatch\n response = await dispatchRoute(runtime, request, route);\n }\n\n // 7. onResponse hook\n response = await runOnResponse(hooks, {\n request,\n response,\n path,\n runtime,\n route,\n });\n\n // 8. CORS headers on response\n response = maybeAddCors(response, corsConfig, requestOrigin);\n\n // 9. Legacy afterRequestMiddleware (non-blocking)\n // Clone the response so middleware can read the body without consuming\n // the original stream that will be sent to the client.\n callAfterRequestMiddleware({\n runtime,\n response: response.clone(),\n path,\n }).catch((error: unknown) => {\n logger.error(\n { err: error, url: request.url, path },\n \"Error running after request middleware\",\n );\n });\n\n return response;\n } catch (error) {\n // Short-circuit with thrown Response\n if (error instanceof Response) {\n const finalResponse = await runOnResponse(hooks, {\n request,\n response: error,\n path,\n runtime,\n route: route ?? { method: \"info\" },\n });\n return maybeAddCors(finalResponse, corsConfig, requestOrigin);\n }\n\n // Run onError hook — wrapped so a throwing hook doesn't escape\n try {\n const errorResponse = await runOnError(hooks, {\n request,\n error,\n path,\n runtime,\n route,\n });\n\n if (errorResponse) {\n return maybeAddCors(errorResponse, corsConfig, requestOrigin);\n }\n } catch (hookError: unknown) {\n logger.error(\n { err: hookError, originalErr: error, url: request.url, path },\n \"onError hook threw\",\n );\n }\n\n logger.error(\n { err: error, url: request.url, path },\n \"Unhandled error in CopilotKit runtime handler\",\n );\n\n return maybeAddCors(\n jsonResponse({ error: \"internal_error\" }, 500),\n corsConfig,\n requestOrigin,\n );\n }\n };\n}\n\n/* ------------------------------------------------------------------------------------------------\n * Route dispatch\n * --------------------------------------------------------------------------------------------- */\n\nfunction dispatchRoute(\n runtime: CopilotRuntimeLike,\n request: Request,\n route: RouteInfo,\n): Promise<Response> {\n switch (route.method) {\n case \"agent/run\":\n return handleRunAgent({\n runtime,\n request,\n agentId: route.agentId,\n });\n case \"agent/connect\":\n return handleConnectAgent({\n runtime,\n request,\n agentId: route.agentId,\n });\n case \"agent/stop\":\n return handleStopAgent({\n runtime,\n request,\n agentId: route.agentId,\n threadId: route.threadId,\n });\n case \"info\":\n return handleGetRuntimeInfo({ runtime, request });\n case \"transcribe\":\n return handleTranscribe({ runtime, request });\n case \"threads/list\":\n return handleListThreads({ runtime, request });\n case \"threads/subscribe\":\n return handleSubscribeToThreads({ runtime, request });\n case \"threads/update\":\n if (request.method.toUpperCase() === \"DELETE\") {\n return handleDeleteThread({\n runtime,\n request,\n threadId: route.threadId,\n });\n }\n return handleUpdateThread({ runtime, request, threadId: route.threadId });\n case \"threads/archive\":\n return handleArchiveThread({\n runtime,\n request,\n threadId: route.threadId,\n });\n case \"threads/messages\":\n return handleGetThreadMessages({\n runtime,\n request,\n threadId: route.threadId,\n });\n }\n}\n\ninterface SingleRouteResolution {\n route: RouteInfo;\n methodCall: MethodCall;\n}\n\nasync function resolveSingleRoute(\n request: Request,\n basePath: string | undefined,\n pathname: string,\n): Promise<SingleRouteResolution> {\n if (basePath) {\n const normalizedBase =\n basePath.length > 1 && basePath.endsWith(\"/\")\n ? basePath.slice(0, -1)\n : basePath;\n if (!pathname.startsWith(normalizedBase)) {\n throw jsonResponse({ error: \"Not found\" }, 404);\n }\n }\n\n if (request.method !== \"POST\") {\n throw jsonResponse({ error: \"Method not allowed\" }, 405, { Allow: \"POST\" });\n }\n\n const methodCall = await parseMethodCall(request);\n\n let route: RouteInfo;\n switch (methodCall.method) {\n case \"agent/run\":\n route = {\n method: \"agent/run\",\n agentId: expectString(methodCall.params, \"agentId\"),\n };\n break;\n case \"agent/connect\":\n route = {\n method: \"agent/connect\",\n agentId: expectString(methodCall.params, \"agentId\"),\n };\n break;\n case \"agent/stop\":\n route = {\n method: \"agent/stop\",\n agentId: expectString(methodCall.params, \"agentId\"),\n threadId: expectString(methodCall.params, \"threadId\"),\n };\n break;\n case \"info\":\n route = { method: \"info\" };\n break;\n case \"transcribe\":\n route = { method: \"transcribe\" };\n break;\n }\n\n return { route, methodCall };\n}\n\n/* ------------------------------------------------------------------------------------------------\n * HTTP method validation\n * --------------------------------------------------------------------------------------------- */\n\nfunction validateHttpMethod(\n httpMethod: string,\n route: RouteInfo,\n): Response | null {\n const method = httpMethod.toUpperCase();\n\n switch (route.method) {\n case \"info\":\n case \"threads/list\":\n case \"threads/messages\":\n if (method === \"GET\") return null;\n return jsonResponse({ error: \"Method not allowed\" }, 405, {\n Allow: \"GET\",\n });\n\n case \"threads/update\":\n if (method === \"PATCH\" || method === \"DELETE\") return null;\n return jsonResponse({ error: \"Method not allowed\" }, 405, {\n Allow: \"PATCH, DELETE\",\n });\n\n default:\n if (method === \"POST\") return null;\n return jsonResponse({ error: \"Method not allowed\" }, 405, {\n Allow: \"POST\",\n });\n }\n}\n\n/* ------------------------------------------------------------------------------------------------\n * Helpers\n * --------------------------------------------------------------------------------------------- */\n\nfunction resolveCorsConfig(\n cors: boolean | CopilotCorsConfig | undefined,\n): CopilotCorsConfig | null {\n if (!cors) return null;\n if (cors === true) return {};\n return cors;\n}\n\nfunction maybeAddCors(\n response: Response,\n config: CopilotCorsConfig | null,\n requestOrigin: string | null,\n): Response {\n if (!config) return response;\n return addCorsHeaders(response, config, requestOrigin);\n}\n\nfunction jsonResponse(\n body: unknown,\n status: number,\n extraHeaders?: Record<string, string>,\n): Response {\n return new Response(JSON.stringify(body), {\n status,\n headers: { \"Content-Type\": \"application/json\", ...extraHeaders },\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"fetch-handler.cjs","names":["handleCors","runOnRequest","callBeforeRequestMiddleware","runOnBeforeHandler","createJsonRequest","matchRoute","runOnResponse","runOnError","handleRunAgent","handleConnectAgent","handleStopAgent","handleGetRuntimeInfo","handleTranscribe","handleListThreads","handleSubscribeToThreads","handleDeleteThread","handleUpdateThread","handleArchiveThread","handleGetThreadMessages","handleDebugEvents","parseMethodCall","expectString","addCorsHeaders"],"sources":["../../../../src/v2/runtime/core/fetch-handler.ts"],"sourcesContent":["/**\n * Framework-agnostic CopilotKit runtime handler.\n *\n * Returns a pure `(Request) => Promise<Response>` function that can be used\n * directly with Bun, Deno, Cloudflare Workers, Next.js App Router, or any\n * Fetch-native runtime — no framework dependency required.\n *\n * @example\n * ```typescript\n * import { CopilotRuntime, createCopilotRuntimeHandler } from \"@copilotkit/runtime/v2\";\n *\n * const handler = createCopilotRuntimeHandler({\n * runtime: new CopilotRuntime({ agents: { ... } }),\n * basePath: \"/api/copilotkit\",\n * cors: true,\n * });\n *\n * // Bun\n * Bun.serve({ fetch: handler });\n *\n * // Deno\n * Deno.serve(handler);\n *\n * // Cloudflare Workers\n * export default { fetch: handler };\n * ```\n */\n\nimport type { CopilotRuntimeLike } from \"./runtime\";\nimport type { CopilotRuntimeHooks, RouteInfo, HookContext } from \"./hooks\";\nimport {\n runOnRequest,\n runOnBeforeHandler,\n runOnResponse,\n runOnError,\n} from \"./hooks\";\nimport type { CopilotCorsConfig } from \"./fetch-cors\";\nimport { handleCors, addCorsHeaders } from \"./fetch-cors\";\nimport { matchRoute } from \"./fetch-router\";\nimport {\n callBeforeRequestMiddleware,\n callAfterRequestMiddleware,\n} from \"./middleware\";\nimport { handleRunAgent } from \"../handlers/handle-run\";\nimport { handleConnectAgent } from \"../handlers/handle-connect\";\nimport { handleStopAgent } from \"../handlers/handle-stop\";\nimport { handleGetRuntimeInfo } from \"../handlers/get-runtime-info\";\nimport { handleTranscribe } from \"../handlers/handle-transcribe\";\nimport { handleDebugEvents } from \"../handlers/handle-debug-events\";\nimport {\n handleListThreads,\n handleSubscribeToThreads,\n handleUpdateThread,\n handleArchiveThread,\n handleDeleteThread,\n handleGetThreadMessages,\n} from \"../handlers/handle-threads\";\nimport {\n parseMethodCall,\n createJsonRequest,\n expectString,\n type MethodCall,\n} from \"../endpoints/single-route-helpers\";\nimport { logger } from \"@copilotkit/shared\";\n\n/* ------------------------------------------------------------------------------------------------\n * Public types\n * --------------------------------------------------------------------------------------------- */\n\nexport interface CopilotRuntimeHandlerOptions {\n runtime: CopilotRuntimeLike;\n\n /**\n * Optional base path for routing.\n *\n * When provided: strict prefix stripping. The handler strips this prefix from the\n * URL pathname and matches the remainder against known routes.\n *\n * When omitted: suffix matching. The handler matches known route patterns as\n * suffixes of the URL pathname.\n */\n basePath?: string;\n\n /**\n * Endpoint mode:\n * - \"multi-route\" (default): Routes like POST /agent/:agentId/run, GET /info, etc.\n * - \"single-route\": Single POST endpoint with JSON envelope { method, params, body }\n */\n mode?: \"multi-route\" | \"single-route\";\n\n /**\n * Optional CORS configuration.\n * When not provided, no CORS headers are added (let the framework handle it).\n * Set to true for permissive defaults, or provide an object.\n */\n cors?: boolean | CopilotCorsConfig;\n\n /**\n * Lifecycle hooks for request processing.\n */\n hooks?: CopilotRuntimeHooks;\n}\n\nexport type CopilotRuntimeFetchHandler = (\n request: Request,\n) => Promise<Response>;\n\n/* ------------------------------------------------------------------------------------------------\n * Handler factory\n * --------------------------------------------------------------------------------------------- */\n\nexport function createCopilotRuntimeHandler(\n options: CopilotRuntimeHandlerOptions,\n): CopilotRuntimeFetchHandler {\n const { runtime, basePath, mode = \"multi-route\", cors, hooks } = options;\n\n const corsConfig = resolveCorsConfig(cors);\n\n return async (request: Request): Promise<Response> => {\n const url = new URL(request.url, \"http://localhost\");\n const path = url.pathname;\n const requestOrigin = request.headers.get(\"origin\");\n\n // Base hook context (route not yet known)\n const baseCtx: HookContext = { request, path, runtime };\n\n let route: RouteInfo | undefined;\n\n try {\n // 1. CORS preflight\n if (corsConfig) {\n const preflight = handleCors(request, corsConfig);\n if (preflight) return preflight;\n }\n\n // 2. onRequest hook\n request = await runOnRequest(hooks, { ...baseCtx, request });\n\n // 3. Legacy beforeRequestMiddleware\n try {\n const maybeModified = await callBeforeRequestMiddleware({\n runtime,\n request,\n path,\n });\n if (maybeModified) {\n request = maybeModified;\n }\n } catch (mwError: unknown) {\n logger.error(\n { err: mwError, url: request.url, path },\n \"Error running before request middleware\",\n );\n if (mwError instanceof Response) {\n return maybeAddCors(mwError, corsConfig, requestOrigin);\n }\n throw mwError;\n }\n\n // 4. Route matching\n let response: Response;\n\n if (mode === \"single-route\") {\n const resolved = await resolveSingleRoute(request, basePath, path);\n route = resolved.route;\n const { methodCall } = resolved;\n // 5. onBeforeHandler hook\n request = await runOnBeforeHandler(hooks, {\n request,\n path,\n runtime,\n route,\n });\n // 6. Wrap body for methods that need it, then dispatch\n if (\n route.method === \"agent/run\" ||\n route.method === \"agent/connect\" ||\n route.method === \"transcribe\"\n ) {\n request = createJsonRequest(request, methodCall.body);\n }\n response = await dispatchRoute(runtime, request, route);\n } else {\n // Multi-route: match URL pattern\n const matched = matchRoute(path, basePath);\n if (!matched) {\n throw jsonResponse({ error: \"Not found\" }, 404);\n }\n\n // Validate HTTP method\n const methodError = validateHttpMethod(request.method, matched);\n if (methodError) {\n route = matched;\n throw methodError;\n }\n\n route = matched;\n\n // 5. onBeforeHandler hook\n request = await runOnBeforeHandler(hooks, {\n request,\n path,\n runtime,\n route,\n });\n\n // 6. Handler dispatch\n response = await dispatchRoute(runtime, request, route);\n }\n\n // 7. onResponse hook\n response = await runOnResponse(hooks, {\n request,\n response,\n path,\n runtime,\n route,\n });\n\n // 8. CORS headers on response\n response = maybeAddCors(response, corsConfig, requestOrigin);\n\n // 9. Legacy afterRequestMiddleware (non-blocking)\n // Clone the response so middleware can read the body without consuming\n // the original stream that will be sent to the client.\n callAfterRequestMiddleware({\n runtime,\n response: response.clone(),\n path,\n }).catch((error: unknown) => {\n logger.error(\n { err: error, url: request.url, path },\n \"Error running after request middleware\",\n );\n });\n\n return response;\n } catch (error) {\n // Short-circuit with thrown Response\n if (error instanceof Response) {\n const finalResponse = await runOnResponse(hooks, {\n request,\n response: error,\n path,\n runtime,\n route: route ?? { method: \"info\" },\n });\n return maybeAddCors(finalResponse, corsConfig, requestOrigin);\n }\n\n // Run onError hook — wrapped so a throwing hook doesn't escape\n try {\n const errorResponse = await runOnError(hooks, {\n request,\n error,\n path,\n runtime,\n route,\n });\n\n if (errorResponse) {\n return maybeAddCors(errorResponse, corsConfig, requestOrigin);\n }\n } catch (hookError: unknown) {\n logger.error(\n { err: hookError, originalErr: error, url: request.url, path },\n \"onError hook threw\",\n );\n }\n\n logger.error(\n { err: error, url: request.url, path },\n \"Unhandled error in CopilotKit runtime handler\",\n );\n\n return maybeAddCors(\n jsonResponse({ error: \"internal_error\" }, 500),\n corsConfig,\n requestOrigin,\n );\n }\n };\n}\n\n/* ------------------------------------------------------------------------------------------------\n * Route dispatch\n * --------------------------------------------------------------------------------------------- */\n\nfunction dispatchRoute(\n runtime: CopilotRuntimeLike,\n request: Request,\n route: RouteInfo,\n): Promise<Response> {\n switch (route.method) {\n case \"agent/run\":\n return handleRunAgent({\n runtime,\n request,\n agentId: route.agentId,\n });\n case \"agent/connect\":\n return handleConnectAgent({\n runtime,\n request,\n agentId: route.agentId,\n });\n case \"agent/stop\":\n return handleStopAgent({\n runtime,\n request,\n agentId: route.agentId,\n threadId: route.threadId,\n });\n case \"info\":\n return handleGetRuntimeInfo({ runtime, request });\n case \"transcribe\":\n return handleTranscribe({ runtime, request });\n case \"threads/list\":\n return handleListThreads({ runtime, request });\n case \"threads/subscribe\":\n return handleSubscribeToThreads({ runtime, request });\n case \"threads/update\":\n if (request.method.toUpperCase() === \"DELETE\") {\n return handleDeleteThread({\n runtime,\n request,\n threadId: route.threadId,\n });\n }\n return handleUpdateThread({ runtime, request, threadId: route.threadId });\n case \"threads/archive\":\n return handleArchiveThread({\n runtime,\n request,\n threadId: route.threadId,\n });\n case \"threads/messages\":\n return handleGetThreadMessages({\n runtime,\n request,\n threadId: route.threadId,\n });\n case \"cpk-debug-events\":\n return Promise.resolve(handleDebugEvents({ runtime, request }));\n }\n}\n\ninterface SingleRouteResolution {\n route: RouteInfo;\n methodCall: MethodCall;\n}\n\nasync function resolveSingleRoute(\n request: Request,\n basePath: string | undefined,\n pathname: string,\n): Promise<SingleRouteResolution> {\n if (basePath) {\n const normalizedBase =\n basePath.length > 1 && basePath.endsWith(\"/\")\n ? basePath.slice(0, -1)\n : basePath;\n if (!pathname.startsWith(normalizedBase)) {\n throw jsonResponse({ error: \"Not found\" }, 404);\n }\n }\n\n if (request.method !== \"POST\") {\n throw jsonResponse({ error: \"Method not allowed\" }, 405, { Allow: \"POST\" });\n }\n\n const methodCall = await parseMethodCall(request);\n\n let route: RouteInfo;\n switch (methodCall.method) {\n case \"agent/run\":\n route = {\n method: \"agent/run\",\n agentId: expectString(methodCall.params, \"agentId\"),\n };\n break;\n case \"agent/connect\":\n route = {\n method: \"agent/connect\",\n agentId: expectString(methodCall.params, \"agentId\"),\n };\n break;\n case \"agent/stop\":\n route = {\n method: \"agent/stop\",\n agentId: expectString(methodCall.params, \"agentId\"),\n threadId: expectString(methodCall.params, \"threadId\"),\n };\n break;\n case \"info\":\n route = { method: \"info\" };\n break;\n case \"transcribe\":\n route = { method: \"transcribe\" };\n break;\n }\n\n return { route, methodCall };\n}\n\n/* ------------------------------------------------------------------------------------------------\n * HTTP method validation\n * --------------------------------------------------------------------------------------------- */\n\nfunction validateHttpMethod(\n httpMethod: string,\n route: RouteInfo,\n): Response | null {\n const method = httpMethod.toUpperCase();\n\n switch (route.method) {\n case \"info\":\n case \"threads/list\":\n case \"threads/messages\":\n case \"cpk-debug-events\":\n if (method === \"GET\") return null;\n return jsonResponse({ error: \"Method not allowed\" }, 405, {\n Allow: \"GET\",\n });\n\n case \"threads/update\":\n if (method === \"PATCH\" || method === \"DELETE\") return null;\n return jsonResponse({ error: \"Method not allowed\" }, 405, {\n Allow: \"PATCH, DELETE\",\n });\n\n default:\n if (method === \"POST\") return null;\n return jsonResponse({ error: \"Method not allowed\" }, 405, {\n Allow: \"POST\",\n });\n }\n}\n\n/* ------------------------------------------------------------------------------------------------\n * Helpers\n * --------------------------------------------------------------------------------------------- */\n\nfunction resolveCorsConfig(\n cors: boolean | CopilotCorsConfig | undefined,\n): CopilotCorsConfig | null {\n if (!cors) return null;\n if (cors === true) return {};\n return cors;\n}\n\nfunction maybeAddCors(\n response: Response,\n config: CopilotCorsConfig | null,\n requestOrigin: string | null,\n): Response {\n if (!config) return response;\n return addCorsHeaders(response, config, requestOrigin);\n}\n\nfunction jsonResponse(\n body: unknown,\n status: number,\n extraHeaders?: Record<string, string>,\n): Response {\n return new Response(JSON.stringify(body), {\n status,\n headers: { \"Content-Type\": \"application/json\", ...extraHeaders },\n });\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-handler.d.cts","names":[],"sources":["../../../../src/v2/runtime/core/fetch-handler.ts"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"fetch-handler.d.cts","names":[],"sources":["../../../../src/v2/runtime/core/fetch-handler.ts"],"mappings":";;;;;;UAqEiB,4BAAA;EACf,OAAA,EAAS,kBAAA;EAkCT;;;;;AAOF;;;;EA9BE,QAAA;EA+BA;;;;;EAxBA,IAAA;;;;;;EAOA,IAAA,aAAiB,iBAAA;;;;EAKjB,KAAA,GAAQ,mBAAA;AAAA;AAAA,KAGE,0BAAA,IACV,OAAA,EAAS,OAAA,KACN,OAAA,CAAQ,QAAA;AAAA,iBAMG,2BAAA,CACd,OAAA,EAAS,4BAAA,GACR,0BAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-handler.d.mts","names":[],"sources":["../../../../src/v2/runtime/core/fetch-handler.ts"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"fetch-handler.d.mts","names":[],"sources":["../../../../src/v2/runtime/core/fetch-handler.ts"],"mappings":";;;;;;UAqEiB,4BAAA;EACf,OAAA,EAAS,kBAAA;EAkCT;;;;;AAOF;;;;EA9BE,QAAA;EA+BA;;;;;EAxBA,IAAA;;;;;;EAOA,IAAA,aAAiB,iBAAA;;;;EAKjB,KAAA,GAAQ,mBAAA;AAAA;AAAA,KAGE,0BAAA,IACV,OAAA,EAAS,OAAA,KACN,OAAA,CAAQ,QAAA;AAAA,iBAMG,2BAAA,CACd,OAAA,EAAS,4BAAA,GACR,0BAAA"}
|
|
@@ -8,6 +8,7 @@ import { handleConnectAgent } from "../handlers/handle-connect.mjs";
|
|
|
8
8
|
import { handleStopAgent } from "../handlers/handle-stop.mjs";
|
|
9
9
|
import { handleGetRuntimeInfo } from "../handlers/get-runtime-info.mjs";
|
|
10
10
|
import { handleTranscribe } from "../handlers/handle-transcribe.mjs";
|
|
11
|
+
import { handleDebugEvents } from "../handlers/handle-debug-events.mjs";
|
|
11
12
|
import { handleArchiveThread, handleDeleteThread, handleGetThreadMessages, handleListThreads, handleSubscribeToThreads, handleUpdateThread } from "../handlers/intelligence/threads.mjs";
|
|
12
13
|
import { createJsonRequest, expectString, parseMethodCall } from "../endpoints/single-route-helpers.mjs";
|
|
13
14
|
import { logger } from "@copilotkit/shared";
|
|
@@ -189,6 +190,10 @@ function dispatchRoute(runtime, request, route) {
|
|
|
189
190
|
request,
|
|
190
191
|
threadId: route.threadId
|
|
191
192
|
});
|
|
193
|
+
case "cpk-debug-events": return Promise.resolve(handleDebugEvents({
|
|
194
|
+
runtime,
|
|
195
|
+
request
|
|
196
|
+
}));
|
|
192
197
|
}
|
|
193
198
|
}
|
|
194
199
|
async function resolveSingleRoute(request, basePath, pathname) {
|
|
@@ -237,6 +242,7 @@ function validateHttpMethod(httpMethod, route) {
|
|
|
237
242
|
case "info":
|
|
238
243
|
case "threads/list":
|
|
239
244
|
case "threads/messages":
|
|
245
|
+
case "cpk-debug-events":
|
|
240
246
|
if (method === "GET") return null;
|
|
241
247
|
return jsonResponse({ error: "Method not allowed" }, 405, { Allow: "GET" });
|
|
242
248
|
case "threads/update":
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-handler.mjs","names":[],"sources":["../../../../src/v2/runtime/core/fetch-handler.ts"],"sourcesContent":["/**\n * Framework-agnostic CopilotKit runtime handler.\n *\n * Returns a pure `(Request) => Promise<Response>` function that can be used\n * directly with Bun, Deno, Cloudflare Workers, Next.js App Router, or any\n * Fetch-native runtime — no framework dependency required.\n *\n * @example\n * ```typescript\n * import { CopilotRuntime, createCopilotRuntimeHandler } from \"@copilotkit/runtime/v2\";\n *\n * const handler = createCopilotRuntimeHandler({\n * runtime: new CopilotRuntime({ agents: { ... } }),\n * basePath: \"/api/copilotkit\",\n * cors: true,\n * });\n *\n * // Bun\n * Bun.serve({ fetch: handler });\n *\n * // Deno\n * Deno.serve(handler);\n *\n * // Cloudflare Workers\n * export default { fetch: handler };\n * ```\n */\n\nimport type { CopilotRuntimeLike } from \"./runtime\";\nimport type { CopilotRuntimeHooks, RouteInfo, HookContext } from \"./hooks\";\nimport {\n runOnRequest,\n runOnBeforeHandler,\n runOnResponse,\n runOnError,\n} from \"./hooks\";\nimport type { CopilotCorsConfig } from \"./fetch-cors\";\nimport { handleCors, addCorsHeaders } from \"./fetch-cors\";\nimport { matchRoute } from \"./fetch-router\";\nimport {\n callBeforeRequestMiddleware,\n callAfterRequestMiddleware,\n} from \"./middleware\";\nimport { handleRunAgent } from \"../handlers/handle-run\";\nimport { handleConnectAgent } from \"../handlers/handle-connect\";\nimport { handleStopAgent } from \"../handlers/handle-stop\";\nimport { handleGetRuntimeInfo } from \"../handlers/get-runtime-info\";\nimport { handleTranscribe } from \"../handlers/handle-transcribe\";\nimport {\n handleListThreads,\n handleSubscribeToThreads,\n handleUpdateThread,\n handleArchiveThread,\n handleDeleteThread,\n handleGetThreadMessages,\n} from \"../handlers/handle-threads\";\nimport {\n parseMethodCall,\n createJsonRequest,\n expectString,\n type MethodCall,\n} from \"../endpoints/single-route-helpers\";\nimport { logger } from \"@copilotkit/shared\";\n\n/* ------------------------------------------------------------------------------------------------\n * Public types\n * --------------------------------------------------------------------------------------------- */\n\nexport interface CopilotRuntimeHandlerOptions {\n runtime: CopilotRuntimeLike;\n\n /**\n * Optional base path for routing.\n *\n * When provided: strict prefix stripping. The handler strips this prefix from the\n * URL pathname and matches the remainder against known routes.\n *\n * When omitted: suffix matching. The handler matches known route patterns as\n * suffixes of the URL pathname.\n */\n basePath?: string;\n\n /**\n * Endpoint mode:\n * - \"multi-route\" (default): Routes like POST /agent/:agentId/run, GET /info, etc.\n * - \"single-route\": Single POST endpoint with JSON envelope { method, params, body }\n */\n mode?: \"multi-route\" | \"single-route\";\n\n /**\n * Optional CORS configuration.\n * When not provided, no CORS headers are added (let the framework handle it).\n * Set to true for permissive defaults, or provide an object.\n */\n cors?: boolean | CopilotCorsConfig;\n\n /**\n * Lifecycle hooks for request processing.\n */\n hooks?: CopilotRuntimeHooks;\n}\n\nexport type CopilotRuntimeFetchHandler = (\n request: Request,\n) => Promise<Response>;\n\n/* ------------------------------------------------------------------------------------------------\n * Handler factory\n * --------------------------------------------------------------------------------------------- */\n\nexport function createCopilotRuntimeHandler(\n options: CopilotRuntimeHandlerOptions,\n): CopilotRuntimeFetchHandler {\n const { runtime, basePath, mode = \"multi-route\", cors, hooks } = options;\n\n const corsConfig = resolveCorsConfig(cors);\n\n return async (request: Request): Promise<Response> => {\n const url = new URL(request.url, \"http://localhost\");\n const path = url.pathname;\n const requestOrigin = request.headers.get(\"origin\");\n\n // Base hook context (route not yet known)\n const baseCtx: HookContext = { request, path, runtime };\n\n let route: RouteInfo | undefined;\n\n try {\n // 1. CORS preflight\n if (corsConfig) {\n const preflight = handleCors(request, corsConfig);\n if (preflight) return preflight;\n }\n\n // 2. onRequest hook\n request = await runOnRequest(hooks, { ...baseCtx, request });\n\n // 3. Legacy beforeRequestMiddleware\n try {\n const maybeModified = await callBeforeRequestMiddleware({\n runtime,\n request,\n path,\n });\n if (maybeModified) {\n request = maybeModified;\n }\n } catch (mwError: unknown) {\n logger.error(\n { err: mwError, url: request.url, path },\n \"Error running before request middleware\",\n );\n if (mwError instanceof Response) {\n return maybeAddCors(mwError, corsConfig, requestOrigin);\n }\n throw mwError;\n }\n\n // 4. Route matching\n let response: Response;\n\n if (mode === \"single-route\") {\n const resolved = await resolveSingleRoute(request, basePath, path);\n route = resolved.route;\n const { methodCall } = resolved;\n // 5. onBeforeHandler hook\n request = await runOnBeforeHandler(hooks, {\n request,\n path,\n runtime,\n route,\n });\n // 6. Wrap body for methods that need it, then dispatch\n if (\n route.method === \"agent/run\" ||\n route.method === \"agent/connect\" ||\n route.method === \"transcribe\"\n ) {\n request = createJsonRequest(request, methodCall.body);\n }\n response = await dispatchRoute(runtime, request, route);\n } else {\n // Multi-route: match URL pattern\n const matched = matchRoute(path, basePath);\n if (!matched) {\n throw jsonResponse({ error: \"Not found\" }, 404);\n }\n\n // Validate HTTP method\n const methodError = validateHttpMethod(request.method, matched);\n if (methodError) {\n route = matched;\n throw methodError;\n }\n\n route = matched;\n\n // 5. onBeforeHandler hook\n request = await runOnBeforeHandler(hooks, {\n request,\n path,\n runtime,\n route,\n });\n\n // 6. Handler dispatch\n response = await dispatchRoute(runtime, request, route);\n }\n\n // 7. onResponse hook\n response = await runOnResponse(hooks, {\n request,\n response,\n path,\n runtime,\n route,\n });\n\n // 8. CORS headers on response\n response = maybeAddCors(response, corsConfig, requestOrigin);\n\n // 9. Legacy afterRequestMiddleware (non-blocking)\n // Clone the response so middleware can read the body without consuming\n // the original stream that will be sent to the client.\n callAfterRequestMiddleware({\n runtime,\n response: response.clone(),\n path,\n }).catch((error: unknown) => {\n logger.error(\n { err: error, url: request.url, path },\n \"Error running after request middleware\",\n );\n });\n\n return response;\n } catch (error) {\n // Short-circuit with thrown Response\n if (error instanceof Response) {\n const finalResponse = await runOnResponse(hooks, {\n request,\n response: error,\n path,\n runtime,\n route: route ?? { method: \"info\" },\n });\n return maybeAddCors(finalResponse, corsConfig, requestOrigin);\n }\n\n // Run onError hook — wrapped so a throwing hook doesn't escape\n try {\n const errorResponse = await runOnError(hooks, {\n request,\n error,\n path,\n runtime,\n route,\n });\n\n if (errorResponse) {\n return maybeAddCors(errorResponse, corsConfig, requestOrigin);\n }\n } catch (hookError: unknown) {\n logger.error(\n { err: hookError, originalErr: error, url: request.url, path },\n \"onError hook threw\",\n );\n }\n\n logger.error(\n { err: error, url: request.url, path },\n \"Unhandled error in CopilotKit runtime handler\",\n );\n\n return maybeAddCors(\n jsonResponse({ error: \"internal_error\" }, 500),\n corsConfig,\n requestOrigin,\n );\n }\n };\n}\n\n/* ------------------------------------------------------------------------------------------------\n * Route dispatch\n * --------------------------------------------------------------------------------------------- */\n\nfunction dispatchRoute(\n runtime: CopilotRuntimeLike,\n request: Request,\n route: RouteInfo,\n): Promise<Response> {\n switch (route.method) {\n case \"agent/run\":\n return handleRunAgent({\n runtime,\n request,\n agentId: route.agentId,\n });\n case \"agent/connect\":\n return handleConnectAgent({\n runtime,\n request,\n agentId: route.agentId,\n });\n case \"agent/stop\":\n return handleStopAgent({\n runtime,\n request,\n agentId: route.agentId,\n threadId: route.threadId,\n });\n case \"info\":\n return handleGetRuntimeInfo({ runtime, request });\n case \"transcribe\":\n return handleTranscribe({ runtime, request });\n case \"threads/list\":\n return handleListThreads({ runtime, request });\n case \"threads/subscribe\":\n return handleSubscribeToThreads({ runtime, request });\n case \"threads/update\":\n if (request.method.toUpperCase() === \"DELETE\") {\n return handleDeleteThread({\n runtime,\n request,\n threadId: route.threadId,\n });\n }\n return handleUpdateThread({ runtime, request, threadId: route.threadId });\n case \"threads/archive\":\n return handleArchiveThread({\n runtime,\n request,\n threadId: route.threadId,\n });\n case \"threads/messages\":\n return handleGetThreadMessages({\n runtime,\n request,\n threadId: route.threadId,\n });\n }\n}\n\ninterface SingleRouteResolution {\n route: RouteInfo;\n methodCall: MethodCall;\n}\n\nasync function resolveSingleRoute(\n request: Request,\n basePath: string | undefined,\n pathname: string,\n): Promise<SingleRouteResolution> {\n if (basePath) {\n const normalizedBase =\n basePath.length > 1 && basePath.endsWith(\"/\")\n ? basePath.slice(0, -1)\n : basePath;\n if (!pathname.startsWith(normalizedBase)) {\n throw jsonResponse({ error: \"Not found\" }, 404);\n }\n }\n\n if (request.method !== \"POST\") {\n throw jsonResponse({ error: \"Method not allowed\" }, 405, { Allow: \"POST\" });\n }\n\n const methodCall = await parseMethodCall(request);\n\n let route: RouteInfo;\n switch (methodCall.method) {\n case \"agent/run\":\n route = {\n method: \"agent/run\",\n agentId: expectString(methodCall.params, \"agentId\"),\n };\n break;\n case \"agent/connect\":\n route = {\n method: \"agent/connect\",\n agentId: expectString(methodCall.params, \"agentId\"),\n };\n break;\n case \"agent/stop\":\n route = {\n method: \"agent/stop\",\n agentId: expectString(methodCall.params, \"agentId\"),\n threadId: expectString(methodCall.params, \"threadId\"),\n };\n break;\n case \"info\":\n route = { method: \"info\" };\n break;\n case \"transcribe\":\n route = { method: \"transcribe\" };\n break;\n }\n\n return { route, methodCall };\n}\n\n/* ------------------------------------------------------------------------------------------------\n * HTTP method validation\n * --------------------------------------------------------------------------------------------- */\n\nfunction validateHttpMethod(\n httpMethod: string,\n route: RouteInfo,\n): Response | null {\n const method = httpMethod.toUpperCase();\n\n switch (route.method) {\n case \"info\":\n case \"threads/list\":\n case \"threads/messages\":\n if (method === \"GET\") return null;\n return jsonResponse({ error: \"Method not allowed\" }, 405, {\n Allow: \"GET\",\n });\n\n case \"threads/update\":\n if (method === \"PATCH\" || method === \"DELETE\") return null;\n return jsonResponse({ error: \"Method not allowed\" }, 405, {\n Allow: \"PATCH, DELETE\",\n });\n\n default:\n if (method === \"POST\") return null;\n return jsonResponse({ error: \"Method not allowed\" }, 405, {\n Allow: \"POST\",\n });\n }\n}\n\n/* ------------------------------------------------------------------------------------------------\n * Helpers\n * --------------------------------------------------------------------------------------------- */\n\nfunction resolveCorsConfig(\n cors: boolean | CopilotCorsConfig | undefined,\n): CopilotCorsConfig | null {\n if (!cors) return null;\n if (cors === true) return {};\n return cors;\n}\n\nfunction maybeAddCors(\n response: Response,\n config: CopilotCorsConfig | null,\n requestOrigin: string | null,\n): Response {\n if (!config) return response;\n return addCorsHeaders(response, config, requestOrigin);\n}\n\nfunction jsonResponse(\n body: unknown,\n status: number,\n extraHeaders?: Record<string, string>,\n): Response {\n return new Response(JSON.stringify(body), {\n status,\n headers: { \"Content-Type\": \"application/json\", ...extraHeaders },\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"fetch-handler.mjs","names":[],"sources":["../../../../src/v2/runtime/core/fetch-handler.ts"],"sourcesContent":["/**\n * Framework-agnostic CopilotKit runtime handler.\n *\n * Returns a pure `(Request) => Promise<Response>` function that can be used\n * directly with Bun, Deno, Cloudflare Workers, Next.js App Router, or any\n * Fetch-native runtime — no framework dependency required.\n *\n * @example\n * ```typescript\n * import { CopilotRuntime, createCopilotRuntimeHandler } from \"@copilotkit/runtime/v2\";\n *\n * const handler = createCopilotRuntimeHandler({\n * runtime: new CopilotRuntime({ agents: { ... } }),\n * basePath: \"/api/copilotkit\",\n * cors: true,\n * });\n *\n * // Bun\n * Bun.serve({ fetch: handler });\n *\n * // Deno\n * Deno.serve(handler);\n *\n * // Cloudflare Workers\n * export default { fetch: handler };\n * ```\n */\n\nimport type { CopilotRuntimeLike } from \"./runtime\";\nimport type { CopilotRuntimeHooks, RouteInfo, HookContext } from \"./hooks\";\nimport {\n runOnRequest,\n runOnBeforeHandler,\n runOnResponse,\n runOnError,\n} from \"./hooks\";\nimport type { CopilotCorsConfig } from \"./fetch-cors\";\nimport { handleCors, addCorsHeaders } from \"./fetch-cors\";\nimport { matchRoute } from \"./fetch-router\";\nimport {\n callBeforeRequestMiddleware,\n callAfterRequestMiddleware,\n} from \"./middleware\";\nimport { handleRunAgent } from \"../handlers/handle-run\";\nimport { handleConnectAgent } from \"../handlers/handle-connect\";\nimport { handleStopAgent } from \"../handlers/handle-stop\";\nimport { handleGetRuntimeInfo } from \"../handlers/get-runtime-info\";\nimport { handleTranscribe } from \"../handlers/handle-transcribe\";\nimport { handleDebugEvents } from \"../handlers/handle-debug-events\";\nimport {\n handleListThreads,\n handleSubscribeToThreads,\n handleUpdateThread,\n handleArchiveThread,\n handleDeleteThread,\n handleGetThreadMessages,\n} from \"../handlers/handle-threads\";\nimport {\n parseMethodCall,\n createJsonRequest,\n expectString,\n type MethodCall,\n} from \"../endpoints/single-route-helpers\";\nimport { logger } from \"@copilotkit/shared\";\n\n/* ------------------------------------------------------------------------------------------------\n * Public types\n * --------------------------------------------------------------------------------------------- */\n\nexport interface CopilotRuntimeHandlerOptions {\n runtime: CopilotRuntimeLike;\n\n /**\n * Optional base path for routing.\n *\n * When provided: strict prefix stripping. The handler strips this prefix from the\n * URL pathname and matches the remainder against known routes.\n *\n * When omitted: suffix matching. The handler matches known route patterns as\n * suffixes of the URL pathname.\n */\n basePath?: string;\n\n /**\n * Endpoint mode:\n * - \"multi-route\" (default): Routes like POST /agent/:agentId/run, GET /info, etc.\n * - \"single-route\": Single POST endpoint with JSON envelope { method, params, body }\n */\n mode?: \"multi-route\" | \"single-route\";\n\n /**\n * Optional CORS configuration.\n * When not provided, no CORS headers are added (let the framework handle it).\n * Set to true for permissive defaults, or provide an object.\n */\n cors?: boolean | CopilotCorsConfig;\n\n /**\n * Lifecycle hooks for request processing.\n */\n hooks?: CopilotRuntimeHooks;\n}\n\nexport type CopilotRuntimeFetchHandler = (\n request: Request,\n) => Promise<Response>;\n\n/* ------------------------------------------------------------------------------------------------\n * Handler factory\n * --------------------------------------------------------------------------------------------- */\n\nexport function createCopilotRuntimeHandler(\n options: CopilotRuntimeHandlerOptions,\n): CopilotRuntimeFetchHandler {\n const { runtime, basePath, mode = \"multi-route\", cors, hooks } = options;\n\n const corsConfig = resolveCorsConfig(cors);\n\n return async (request: Request): Promise<Response> => {\n const url = new URL(request.url, \"http://localhost\");\n const path = url.pathname;\n const requestOrigin = request.headers.get(\"origin\");\n\n // Base hook context (route not yet known)\n const baseCtx: HookContext = { request, path, runtime };\n\n let route: RouteInfo | undefined;\n\n try {\n // 1. CORS preflight\n if (corsConfig) {\n const preflight = handleCors(request, corsConfig);\n if (preflight) return preflight;\n }\n\n // 2. onRequest hook\n request = await runOnRequest(hooks, { ...baseCtx, request });\n\n // 3. Legacy beforeRequestMiddleware\n try {\n const maybeModified = await callBeforeRequestMiddleware({\n runtime,\n request,\n path,\n });\n if (maybeModified) {\n request = maybeModified;\n }\n } catch (mwError: unknown) {\n logger.error(\n { err: mwError, url: request.url, path },\n \"Error running before request middleware\",\n );\n if (mwError instanceof Response) {\n return maybeAddCors(mwError, corsConfig, requestOrigin);\n }\n throw mwError;\n }\n\n // 4. Route matching\n let response: Response;\n\n if (mode === \"single-route\") {\n const resolved = await resolveSingleRoute(request, basePath, path);\n route = resolved.route;\n const { methodCall } = resolved;\n // 5. onBeforeHandler hook\n request = await runOnBeforeHandler(hooks, {\n request,\n path,\n runtime,\n route,\n });\n // 6. Wrap body for methods that need it, then dispatch\n if (\n route.method === \"agent/run\" ||\n route.method === \"agent/connect\" ||\n route.method === \"transcribe\"\n ) {\n request = createJsonRequest(request, methodCall.body);\n }\n response = await dispatchRoute(runtime, request, route);\n } else {\n // Multi-route: match URL pattern\n const matched = matchRoute(path, basePath);\n if (!matched) {\n throw jsonResponse({ error: \"Not found\" }, 404);\n }\n\n // Validate HTTP method\n const methodError = validateHttpMethod(request.method, matched);\n if (methodError) {\n route = matched;\n throw methodError;\n }\n\n route = matched;\n\n // 5. onBeforeHandler hook\n request = await runOnBeforeHandler(hooks, {\n request,\n path,\n runtime,\n route,\n });\n\n // 6. Handler dispatch\n response = await dispatchRoute(runtime, request, route);\n }\n\n // 7. onResponse hook\n response = await runOnResponse(hooks, {\n request,\n response,\n path,\n runtime,\n route,\n });\n\n // 8. CORS headers on response\n response = maybeAddCors(response, corsConfig, requestOrigin);\n\n // 9. Legacy afterRequestMiddleware (non-blocking)\n // Clone the response so middleware can read the body without consuming\n // the original stream that will be sent to the client.\n callAfterRequestMiddleware({\n runtime,\n response: response.clone(),\n path,\n }).catch((error: unknown) => {\n logger.error(\n { err: error, url: request.url, path },\n \"Error running after request middleware\",\n );\n });\n\n return response;\n } catch (error) {\n // Short-circuit with thrown Response\n if (error instanceof Response) {\n const finalResponse = await runOnResponse(hooks, {\n request,\n response: error,\n path,\n runtime,\n route: route ?? { method: \"info\" },\n });\n return maybeAddCors(finalResponse, corsConfig, requestOrigin);\n }\n\n // Run onError hook — wrapped so a throwing hook doesn't escape\n try {\n const errorResponse = await runOnError(hooks, {\n request,\n error,\n path,\n runtime,\n route,\n });\n\n if (errorResponse) {\n return maybeAddCors(errorResponse, corsConfig, requestOrigin);\n }\n } catch (hookError: unknown) {\n logger.error(\n { err: hookError, originalErr: error, url: request.url, path },\n \"onError hook threw\",\n );\n }\n\n logger.error(\n { err: error, url: request.url, path },\n \"Unhandled error in CopilotKit runtime handler\",\n );\n\n return maybeAddCors(\n jsonResponse({ error: \"internal_error\" }, 500),\n corsConfig,\n requestOrigin,\n );\n }\n };\n}\n\n/* ------------------------------------------------------------------------------------------------\n * Route dispatch\n * --------------------------------------------------------------------------------------------- */\n\nfunction dispatchRoute(\n runtime: CopilotRuntimeLike,\n request: Request,\n route: RouteInfo,\n): Promise<Response> {\n switch (route.method) {\n case \"agent/run\":\n return handleRunAgent({\n runtime,\n request,\n agentId: route.agentId,\n });\n case \"agent/connect\":\n return handleConnectAgent({\n runtime,\n request,\n agentId: route.agentId,\n });\n case \"agent/stop\":\n return handleStopAgent({\n runtime,\n request,\n agentId: route.agentId,\n threadId: route.threadId,\n });\n case \"info\":\n return handleGetRuntimeInfo({ runtime, request });\n case \"transcribe\":\n return handleTranscribe({ runtime, request });\n case \"threads/list\":\n return handleListThreads({ runtime, request });\n case \"threads/subscribe\":\n return handleSubscribeToThreads({ runtime, request });\n case \"threads/update\":\n if (request.method.toUpperCase() === \"DELETE\") {\n return handleDeleteThread({\n runtime,\n request,\n threadId: route.threadId,\n });\n }\n return handleUpdateThread({ runtime, request, threadId: route.threadId });\n case \"threads/archive\":\n return handleArchiveThread({\n runtime,\n request,\n threadId: route.threadId,\n });\n case \"threads/messages\":\n return handleGetThreadMessages({\n runtime,\n request,\n threadId: route.threadId,\n });\n case \"cpk-debug-events\":\n return Promise.resolve(handleDebugEvents({ runtime, request }));\n }\n}\n\ninterface SingleRouteResolution {\n route: RouteInfo;\n methodCall: MethodCall;\n}\n\nasync function resolveSingleRoute(\n request: Request,\n basePath: string | undefined,\n pathname: string,\n): Promise<SingleRouteResolution> {\n if (basePath) {\n const normalizedBase =\n basePath.length > 1 && basePath.endsWith(\"/\")\n ? basePath.slice(0, -1)\n : basePath;\n if (!pathname.startsWith(normalizedBase)) {\n throw jsonResponse({ error: \"Not found\" }, 404);\n }\n }\n\n if (request.method !== \"POST\") {\n throw jsonResponse({ error: \"Method not allowed\" }, 405, { Allow: \"POST\" });\n }\n\n const methodCall = await parseMethodCall(request);\n\n let route: RouteInfo;\n switch (methodCall.method) {\n case \"agent/run\":\n route = {\n method: \"agent/run\",\n agentId: expectString(methodCall.params, \"agentId\"),\n };\n break;\n case \"agent/connect\":\n route = {\n method: \"agent/connect\",\n agentId: expectString(methodCall.params, \"agentId\"),\n };\n break;\n case \"agent/stop\":\n route = {\n method: \"agent/stop\",\n agentId: expectString(methodCall.params, \"agentId\"),\n threadId: expectString(methodCall.params, \"threadId\"),\n };\n break;\n case \"info\":\n route = { method: \"info\" };\n break;\n case \"transcribe\":\n route = { method: \"transcribe\" };\n break;\n }\n\n return { route, methodCall };\n}\n\n/* ------------------------------------------------------------------------------------------------\n * HTTP method validation\n * --------------------------------------------------------------------------------------------- */\n\nfunction validateHttpMethod(\n httpMethod: string,\n route: RouteInfo,\n): Response | null {\n const method = httpMethod.toUpperCase();\n\n switch (route.method) {\n case \"info\":\n case \"threads/list\":\n case \"threads/messages\":\n case \"cpk-debug-events\":\n if (method === \"GET\") return null;\n return jsonResponse({ error: \"Method not allowed\" }, 405, {\n Allow: \"GET\",\n });\n\n case \"threads/update\":\n if (method === \"PATCH\" || method === \"DELETE\") return null;\n return jsonResponse({ error: \"Method not allowed\" }, 405, {\n Allow: \"PATCH, DELETE\",\n });\n\n default:\n if (method === \"POST\") return null;\n return jsonResponse({ error: \"Method not allowed\" }, 405, {\n Allow: \"POST\",\n });\n }\n}\n\n/* ------------------------------------------------------------------------------------------------\n * Helpers\n * --------------------------------------------------------------------------------------------- */\n\nfunction resolveCorsConfig(\n cors: boolean | CopilotCorsConfig | undefined,\n): CopilotCorsConfig | null {\n if (!cors) return null;\n if (cors === true) return {};\n return cors;\n}\n\nfunction maybeAddCors(\n response: Response,\n config: CopilotCorsConfig | null,\n requestOrigin: string | null,\n): Response {\n if (!config) return response;\n return addCorsHeaders(response, config, requestOrigin);\n}\n\nfunction jsonResponse(\n body: unknown,\n status: number,\n extraHeaders?: Record<string, string>,\n): Response {\n return new Response(JSON.stringify(body), {\n status,\n headers: { \"Content-Type\": \"application/json\", ...extraHeaders },\n });\n}\n"],"mappings":"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"}
|
|
@@ -34,6 +34,7 @@ function matchSegments(path) {
|
|
|
34
34
|
const len = segments.length;
|
|
35
35
|
if (len >= 1 && segments[len - 1] === "info") return { method: "info" };
|
|
36
36
|
if (len >= 1 && segments[len - 1] === "transcribe") return { method: "transcribe" };
|
|
37
|
+
if (len >= 1 && segments[len - 1] === "cpk-debug-events") return { method: "cpk-debug-events" };
|
|
37
38
|
if (len >= 3 && segments[len - 3] === "agent" && segments[len - 1] === "run") {
|
|
38
39
|
const agentId = safeDecodeURIComponent(segments[len - 2]);
|
|
39
40
|
if (!agentId) return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-router.cjs","names":[],"sources":["../../../../src/v2/runtime/core/fetch-router.ts"],"sourcesContent":["/**\n * Lightweight URL router for framework-agnostic CopilotKit runtime handler.\n *\n * Two strategies:\n * - With `basePath`: strict prefix strip → match remainder\n * - Without `basePath`: suffix matching on known patterns\n *\n * Single-route mode: delegates to `parseMethodCall` for JSON envelope dispatch.\n */\n\nimport type { RouteInfo } from \"./hooks\";\n\n/**\n * Match a request URL against known CopilotKit route patterns.\n *\n * @param pathname - The URL pathname to match\n * @param basePath - Optional base path prefix to strip first\n * @returns RouteInfo if matched, null otherwise\n */\nexport function matchRoute(\n pathname: string,\n basePath?: string,\n): RouteInfo | null {\n let remainder: string;\n\n if (basePath) {\n // Normalize: ensure basePath doesn't end with /\n const normalizedBase =\n basePath.length > 1 && basePath.endsWith(\"/\")\n ? basePath.slice(0, -1)\n : basePath;\n\n // Special case: basePath === \"/\" matches everything\n if (normalizedBase === \"/\") {\n remainder = pathname;\n } else {\n if (!pathname.startsWith(normalizedBase)) return null;\n\n // The character after basePath must be \"/\" or end of string\n const afterBase = pathname.slice(normalizedBase.length);\n if (afterBase.length > 0 && !afterBase.startsWith(\"/\")) return null;\n\n remainder = afterBase || \"/\";\n }\n } else {\n // Suffix matching: find known patterns at the end of the pathname\n remainder = pathname;\n }\n\n return matchSegments(remainder);\n}\n\nfunction safeDecodeURIComponent(value: string): string | null {\n try {\n return decodeURIComponent(value);\n } catch {\n return null;\n }\n}\n\nfunction matchSegments(path: string): RouteInfo | null {\n const segments = path.split(\"/\").filter(Boolean);\n const len = segments.length;\n\n // Try suffix matching — scan from the end for known patterns\n\n // /info (1 segment)\n if (len >= 1 && segments[len - 1] === \"info\") {\n return { method: \"info\" };\n }\n\n // /transcribe (1 segment)\n if (len >= 1 && segments[len - 1] === \"transcribe\") {\n return { method: \"transcribe\" };\n }\n\n // /agent/:agentId/run (3 segments)\n if (\n len >= 3 &&\n segments[len - 3] === \"agent\" &&\n segments[len - 1] === \"run\"\n ) {\n const agentId = safeDecodeURIComponent(segments[len - 2]!);\n if (!agentId) return null;\n return { method: \"agent/run\", agentId };\n }\n\n // /agent/:agentId/connect (3 segments)\n if (\n len >= 3 &&\n segments[len - 3] === \"agent\" &&\n segments[len - 1] === \"connect\"\n ) {\n const agentId = safeDecodeURIComponent(segments[len - 2]!);\n if (!agentId) return null;\n return { method: \"agent/connect\", agentId };\n }\n\n // /agent/:agentId/stop/:threadId (4 segments)\n if (\n len >= 4 &&\n segments[len - 4] === \"agent\" &&\n segments[len - 2] === \"stop\"\n ) {\n const agentId = safeDecodeURIComponent(segments[len - 3]!);\n const threadId = safeDecodeURIComponent(segments[len - 1]!);\n if (!agentId || !threadId) return null;\n return { method: \"agent/stop\", agentId, threadId };\n }\n\n // /threads/subscribe (2 segments)\n if (\n len >= 2 &&\n segments[len - 2] === \"threads\" &&\n segments[len - 1] === \"subscribe\"\n ) {\n return { method: \"threads/subscribe\" };\n }\n\n // /threads/:threadId/messages (3 segments)\n if (\n len >= 3 &&\n segments[len - 3] === \"threads\" &&\n segments[len - 1] === \"messages\"\n ) {\n const threadId = safeDecodeURIComponent(segments[len - 2]!);\n if (!threadId) return null;\n return { method: \"threads/messages\", threadId };\n }\n\n // /threads/:threadId/archive (3 segments)\n if (\n len >= 3 &&\n segments[len - 3] === \"threads\" &&\n segments[len - 1] === \"archive\"\n ) {\n const threadId = safeDecodeURIComponent(segments[len - 2]!);\n if (!threadId) return null;\n return { method: \"threads/archive\", threadId };\n }\n\n // /threads/:threadId (2 segments) — update or delete\n if (\n len >= 2 &&\n segments[len - 2] === \"threads\" &&\n segments[len - 1] !== \"subscribe\"\n ) {\n const threadId = safeDecodeURIComponent(segments[len - 1]!);\n if (!threadId) return null;\n // Disambiguated by HTTP method in the handler\n return { method: \"threads/update\", threadId };\n }\n\n // /threads (1 segment) — list\n if (len >= 1 && segments[len - 1] === \"threads\") {\n return { method: \"threads/list\" };\n }\n\n return null;\n}\n"],"mappings":";;;;;;;;;;AAmBA,SAAgB,WACd,UACA,UACkB;CAClB,IAAI;AAEJ,KAAI,UAAU;EAEZ,MAAM,iBACJ,SAAS,SAAS,KAAK,SAAS,SAAS,IAAI,GACzC,SAAS,MAAM,GAAG,GAAG,GACrB;AAGN,MAAI,mBAAmB,IACrB,aAAY;OACP;AACL,OAAI,CAAC,SAAS,WAAW,eAAe,CAAE,QAAO;GAGjD,MAAM,YAAY,SAAS,MAAM,eAAe,OAAO;AACvD,OAAI,UAAU,SAAS,KAAK,CAAC,UAAU,WAAW,IAAI,CAAE,QAAO;AAE/D,eAAY,aAAa;;OAI3B,aAAY;AAGd,QAAO,cAAc,UAAU;;AAGjC,SAAS,uBAAuB,OAA8B;AAC5D,KAAI;AACF,SAAO,mBAAmB,MAAM;SAC1B;AACN,SAAO;;;AAIX,SAAS,cAAc,MAAgC;CACrD,MAAM,WAAW,KAAK,MAAM,IAAI,CAAC,OAAO,QAAQ;CAChD,MAAM,MAAM,SAAS;AAKrB,KAAI,OAAO,KAAK,SAAS,MAAM,OAAO,OACpC,QAAO,EAAE,QAAQ,QAAQ;AAI3B,KAAI,OAAO,KAAK,SAAS,MAAM,OAAO,aACpC,QAAO,EAAE,QAAQ,cAAc;
|
|
1
|
+
{"version":3,"file":"fetch-router.cjs","names":[],"sources":["../../../../src/v2/runtime/core/fetch-router.ts"],"sourcesContent":["/**\n * Lightweight URL router for framework-agnostic CopilotKit runtime handler.\n *\n * Two strategies:\n * - With `basePath`: strict prefix strip → match remainder\n * - Without `basePath`: suffix matching on known patterns\n *\n * Single-route mode: delegates to `parseMethodCall` for JSON envelope dispatch.\n */\n\nimport type { RouteInfo } from \"./hooks\";\n\n/**\n * Match a request URL against known CopilotKit route patterns.\n *\n * @param pathname - The URL pathname to match\n * @param basePath - Optional base path prefix to strip first\n * @returns RouteInfo if matched, null otherwise\n */\nexport function matchRoute(\n pathname: string,\n basePath?: string,\n): RouteInfo | null {\n let remainder: string;\n\n if (basePath) {\n // Normalize: ensure basePath doesn't end with /\n const normalizedBase =\n basePath.length > 1 && basePath.endsWith(\"/\")\n ? basePath.slice(0, -1)\n : basePath;\n\n // Special case: basePath === \"/\" matches everything\n if (normalizedBase === \"/\") {\n remainder = pathname;\n } else {\n if (!pathname.startsWith(normalizedBase)) return null;\n\n // The character after basePath must be \"/\" or end of string\n const afterBase = pathname.slice(normalizedBase.length);\n if (afterBase.length > 0 && !afterBase.startsWith(\"/\")) return null;\n\n remainder = afterBase || \"/\";\n }\n } else {\n // Suffix matching: find known patterns at the end of the pathname\n remainder = pathname;\n }\n\n return matchSegments(remainder);\n}\n\nfunction safeDecodeURIComponent(value: string): string | null {\n try {\n return decodeURIComponent(value);\n } catch {\n return null;\n }\n}\n\nfunction matchSegments(path: string): RouteInfo | null {\n const segments = path.split(\"/\").filter(Boolean);\n const len = segments.length;\n\n // Try suffix matching — scan from the end for known patterns\n\n // /info (1 segment)\n if (len >= 1 && segments[len - 1] === \"info\") {\n return { method: \"info\" };\n }\n\n // /transcribe (1 segment)\n if (len >= 1 && segments[len - 1] === \"transcribe\") {\n return { method: \"transcribe\" };\n }\n\n // /cpk-debug-events (1 segment)\n // Reserved route name: the `cpk-` prefix makes collision with a\n // user-named agent essentially impossible (the router only treats\n // `agent/:agentId/...` patterns as agent lookups, so a bare\n // `cpk-debug-events` segment would never fall through to one —\n // the prefix is the real guard, not this branch's position).\n // Handler returns 404 in production.\n if (len >= 1 && segments[len - 1] === \"cpk-debug-events\") {\n return { method: \"cpk-debug-events\" };\n }\n\n // /agent/:agentId/run (3 segments)\n if (\n len >= 3 &&\n segments[len - 3] === \"agent\" &&\n segments[len - 1] === \"run\"\n ) {\n const agentId = safeDecodeURIComponent(segments[len - 2]!);\n if (!agentId) return null;\n return { method: \"agent/run\", agentId };\n }\n\n // /agent/:agentId/connect (3 segments)\n if (\n len >= 3 &&\n segments[len - 3] === \"agent\" &&\n segments[len - 1] === \"connect\"\n ) {\n const agentId = safeDecodeURIComponent(segments[len - 2]!);\n if (!agentId) return null;\n return { method: \"agent/connect\", agentId };\n }\n\n // /agent/:agentId/stop/:threadId (4 segments)\n if (\n len >= 4 &&\n segments[len - 4] === \"agent\" &&\n segments[len - 2] === \"stop\"\n ) {\n const agentId = safeDecodeURIComponent(segments[len - 3]!);\n const threadId = safeDecodeURIComponent(segments[len - 1]!);\n if (!agentId || !threadId) return null;\n return { method: \"agent/stop\", agentId, threadId };\n }\n\n // /threads/subscribe (2 segments)\n if (\n len >= 2 &&\n segments[len - 2] === \"threads\" &&\n segments[len - 1] === \"subscribe\"\n ) {\n return { method: \"threads/subscribe\" };\n }\n\n // /threads/:threadId/messages (3 segments)\n if (\n len >= 3 &&\n segments[len - 3] === \"threads\" &&\n segments[len - 1] === \"messages\"\n ) {\n const threadId = safeDecodeURIComponent(segments[len - 2]!);\n if (!threadId) return null;\n return { method: \"threads/messages\", threadId };\n }\n\n // /threads/:threadId/archive (3 segments)\n if (\n len >= 3 &&\n segments[len - 3] === \"threads\" &&\n segments[len - 1] === \"archive\"\n ) {\n const threadId = safeDecodeURIComponent(segments[len - 2]!);\n if (!threadId) return null;\n return { method: \"threads/archive\", threadId };\n }\n\n // /threads/:threadId (2 segments) — update or delete\n if (\n len >= 2 &&\n segments[len - 2] === \"threads\" &&\n segments[len - 1] !== \"subscribe\"\n ) {\n const threadId = safeDecodeURIComponent(segments[len - 1]!);\n if (!threadId) return null;\n // Disambiguated by HTTP method in the handler\n return { method: \"threads/update\", threadId };\n }\n\n // /threads (1 segment) — list\n if (len >= 1 && segments[len - 1] === \"threads\") {\n return { method: \"threads/list\" };\n }\n\n return null;\n}\n"],"mappings":";;;;;;;;;;AAmBA,SAAgB,WACd,UACA,UACkB;CAClB,IAAI;AAEJ,KAAI,UAAU;EAEZ,MAAM,iBACJ,SAAS,SAAS,KAAK,SAAS,SAAS,IAAI,GACzC,SAAS,MAAM,GAAG,GAAG,GACrB;AAGN,MAAI,mBAAmB,IACrB,aAAY;OACP;AACL,OAAI,CAAC,SAAS,WAAW,eAAe,CAAE,QAAO;GAGjD,MAAM,YAAY,SAAS,MAAM,eAAe,OAAO;AACvD,OAAI,UAAU,SAAS,KAAK,CAAC,UAAU,WAAW,IAAI,CAAE,QAAO;AAE/D,eAAY,aAAa;;OAI3B,aAAY;AAGd,QAAO,cAAc,UAAU;;AAGjC,SAAS,uBAAuB,OAA8B;AAC5D,KAAI;AACF,SAAO,mBAAmB,MAAM;SAC1B;AACN,SAAO;;;AAIX,SAAS,cAAc,MAAgC;CACrD,MAAM,WAAW,KAAK,MAAM,IAAI,CAAC,OAAO,QAAQ;CAChD,MAAM,MAAM,SAAS;AAKrB,KAAI,OAAO,KAAK,SAAS,MAAM,OAAO,OACpC,QAAO,EAAE,QAAQ,QAAQ;AAI3B,KAAI,OAAO,KAAK,SAAS,MAAM,OAAO,aACpC,QAAO,EAAE,QAAQ,cAAc;AAUjC,KAAI,OAAO,KAAK,SAAS,MAAM,OAAO,mBACpC,QAAO,EAAE,QAAQ,oBAAoB;AAIvC,KACE,OAAO,KACP,SAAS,MAAM,OAAO,WACtB,SAAS,MAAM,OAAO,OACtB;EACA,MAAM,UAAU,uBAAuB,SAAS,MAAM,GAAI;AAC1D,MAAI,CAAC,QAAS,QAAO;AACrB,SAAO;GAAE,QAAQ;GAAa;GAAS;;AAIzC,KACE,OAAO,KACP,SAAS,MAAM,OAAO,WACtB,SAAS,MAAM,OAAO,WACtB;EACA,MAAM,UAAU,uBAAuB,SAAS,MAAM,GAAI;AAC1D,MAAI,CAAC,QAAS,QAAO;AACrB,SAAO;GAAE,QAAQ;GAAiB;GAAS;;AAI7C,KACE,OAAO,KACP,SAAS,MAAM,OAAO,WACtB,SAAS,MAAM,OAAO,QACtB;EACA,MAAM,UAAU,uBAAuB,SAAS,MAAM,GAAI;EAC1D,MAAM,WAAW,uBAAuB,SAAS,MAAM,GAAI;AAC3D,MAAI,CAAC,WAAW,CAAC,SAAU,QAAO;AAClC,SAAO;GAAE,QAAQ;GAAc;GAAS;GAAU;;AAIpD,KACE,OAAO,KACP,SAAS,MAAM,OAAO,aACtB,SAAS,MAAM,OAAO,YAEtB,QAAO,EAAE,QAAQ,qBAAqB;AAIxC,KACE,OAAO,KACP,SAAS,MAAM,OAAO,aACtB,SAAS,MAAM,OAAO,YACtB;EACA,MAAM,WAAW,uBAAuB,SAAS,MAAM,GAAI;AAC3D,MAAI,CAAC,SAAU,QAAO;AACtB,SAAO;GAAE,QAAQ;GAAoB;GAAU;;AAIjD,KACE,OAAO,KACP,SAAS,MAAM,OAAO,aACtB,SAAS,MAAM,OAAO,WACtB;EACA,MAAM,WAAW,uBAAuB,SAAS,MAAM,GAAI;AAC3D,MAAI,CAAC,SAAU,QAAO;AACtB,SAAO;GAAE,QAAQ;GAAmB;GAAU;;AAIhD,KACE,OAAO,KACP,SAAS,MAAM,OAAO,aACtB,SAAS,MAAM,OAAO,aACtB;EACA,MAAM,WAAW,uBAAuB,SAAS,MAAM,GAAI;AAC3D,MAAI,CAAC,SAAU,QAAO;AAEtB,SAAO;GAAE,QAAQ;GAAkB;GAAU;;AAI/C,KAAI,OAAO,KAAK,SAAS,MAAM,OAAO,UACpC,QAAO,EAAE,QAAQ,gBAAgB;AAGnC,QAAO"}
|
|
@@ -33,6 +33,7 @@ function matchSegments(path) {
|
|
|
33
33
|
const len = segments.length;
|
|
34
34
|
if (len >= 1 && segments[len - 1] === "info") return { method: "info" };
|
|
35
35
|
if (len >= 1 && segments[len - 1] === "transcribe") return { method: "transcribe" };
|
|
36
|
+
if (len >= 1 && segments[len - 1] === "cpk-debug-events") return { method: "cpk-debug-events" };
|
|
36
37
|
if (len >= 3 && segments[len - 3] === "agent" && segments[len - 1] === "run") {
|
|
37
38
|
const agentId = safeDecodeURIComponent(segments[len - 2]);
|
|
38
39
|
if (!agentId) return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-router.mjs","names":[],"sources":["../../../../src/v2/runtime/core/fetch-router.ts"],"sourcesContent":["/**\n * Lightweight URL router for framework-agnostic CopilotKit runtime handler.\n *\n * Two strategies:\n * - With `basePath`: strict prefix strip → match remainder\n * - Without `basePath`: suffix matching on known patterns\n *\n * Single-route mode: delegates to `parseMethodCall` for JSON envelope dispatch.\n */\n\nimport type { RouteInfo } from \"./hooks\";\n\n/**\n * Match a request URL against known CopilotKit route patterns.\n *\n * @param pathname - The URL pathname to match\n * @param basePath - Optional base path prefix to strip first\n * @returns RouteInfo if matched, null otherwise\n */\nexport function matchRoute(\n pathname: string,\n basePath?: string,\n): RouteInfo | null {\n let remainder: string;\n\n if (basePath) {\n // Normalize: ensure basePath doesn't end with /\n const normalizedBase =\n basePath.length > 1 && basePath.endsWith(\"/\")\n ? basePath.slice(0, -1)\n : basePath;\n\n // Special case: basePath === \"/\" matches everything\n if (normalizedBase === \"/\") {\n remainder = pathname;\n } else {\n if (!pathname.startsWith(normalizedBase)) return null;\n\n // The character after basePath must be \"/\" or end of string\n const afterBase = pathname.slice(normalizedBase.length);\n if (afterBase.length > 0 && !afterBase.startsWith(\"/\")) return null;\n\n remainder = afterBase || \"/\";\n }\n } else {\n // Suffix matching: find known patterns at the end of the pathname\n remainder = pathname;\n }\n\n return matchSegments(remainder);\n}\n\nfunction safeDecodeURIComponent(value: string): string | null {\n try {\n return decodeURIComponent(value);\n } catch {\n return null;\n }\n}\n\nfunction matchSegments(path: string): RouteInfo | null {\n const segments = path.split(\"/\").filter(Boolean);\n const len = segments.length;\n\n // Try suffix matching — scan from the end for known patterns\n\n // /info (1 segment)\n if (len >= 1 && segments[len - 1] === \"info\") {\n return { method: \"info\" };\n }\n\n // /transcribe (1 segment)\n if (len >= 1 && segments[len - 1] === \"transcribe\") {\n return { method: \"transcribe\" };\n }\n\n // /agent/:agentId/run (3 segments)\n if (\n len >= 3 &&\n segments[len - 3] === \"agent\" &&\n segments[len - 1] === \"run\"\n ) {\n const agentId = safeDecodeURIComponent(segments[len - 2]!);\n if (!agentId) return null;\n return { method: \"agent/run\", agentId };\n }\n\n // /agent/:agentId/connect (3 segments)\n if (\n len >= 3 &&\n segments[len - 3] === \"agent\" &&\n segments[len - 1] === \"connect\"\n ) {\n const agentId = safeDecodeURIComponent(segments[len - 2]!);\n if (!agentId) return null;\n return { method: \"agent/connect\", agentId };\n }\n\n // /agent/:agentId/stop/:threadId (4 segments)\n if (\n len >= 4 &&\n segments[len - 4] === \"agent\" &&\n segments[len - 2] === \"stop\"\n ) {\n const agentId = safeDecodeURIComponent(segments[len - 3]!);\n const threadId = safeDecodeURIComponent(segments[len - 1]!);\n if (!agentId || !threadId) return null;\n return { method: \"agent/stop\", agentId, threadId };\n }\n\n // /threads/subscribe (2 segments)\n if (\n len >= 2 &&\n segments[len - 2] === \"threads\" &&\n segments[len - 1] === \"subscribe\"\n ) {\n return { method: \"threads/subscribe\" };\n }\n\n // /threads/:threadId/messages (3 segments)\n if (\n len >= 3 &&\n segments[len - 3] === \"threads\" &&\n segments[len - 1] === \"messages\"\n ) {\n const threadId = safeDecodeURIComponent(segments[len - 2]!);\n if (!threadId) return null;\n return { method: \"threads/messages\", threadId };\n }\n\n // /threads/:threadId/archive (3 segments)\n if (\n len >= 3 &&\n segments[len - 3] === \"threads\" &&\n segments[len - 1] === \"archive\"\n ) {\n const threadId = safeDecodeURIComponent(segments[len - 2]!);\n if (!threadId) return null;\n return { method: \"threads/archive\", threadId };\n }\n\n // /threads/:threadId (2 segments) — update or delete\n if (\n len >= 2 &&\n segments[len - 2] === \"threads\" &&\n segments[len - 1] !== \"subscribe\"\n ) {\n const threadId = safeDecodeURIComponent(segments[len - 1]!);\n if (!threadId) return null;\n // Disambiguated by HTTP method in the handler\n return { method: \"threads/update\", threadId };\n }\n\n // /threads (1 segment) — list\n if (len >= 1 && segments[len - 1] === \"threads\") {\n return { method: \"threads/list\" };\n }\n\n return null;\n}\n"],"mappings":";;;;;;;;;AAmBA,SAAgB,WACd,UACA,UACkB;CAClB,IAAI;AAEJ,KAAI,UAAU;EAEZ,MAAM,iBACJ,SAAS,SAAS,KAAK,SAAS,SAAS,IAAI,GACzC,SAAS,MAAM,GAAG,GAAG,GACrB;AAGN,MAAI,mBAAmB,IACrB,aAAY;OACP;AACL,OAAI,CAAC,SAAS,WAAW,eAAe,CAAE,QAAO;GAGjD,MAAM,YAAY,SAAS,MAAM,eAAe,OAAO;AACvD,OAAI,UAAU,SAAS,KAAK,CAAC,UAAU,WAAW,IAAI,CAAE,QAAO;AAE/D,eAAY,aAAa;;OAI3B,aAAY;AAGd,QAAO,cAAc,UAAU;;AAGjC,SAAS,uBAAuB,OAA8B;AAC5D,KAAI;AACF,SAAO,mBAAmB,MAAM;SAC1B;AACN,SAAO;;;AAIX,SAAS,cAAc,MAAgC;CACrD,MAAM,WAAW,KAAK,MAAM,IAAI,CAAC,OAAO,QAAQ;CAChD,MAAM,MAAM,SAAS;AAKrB,KAAI,OAAO,KAAK,SAAS,MAAM,OAAO,OACpC,QAAO,EAAE,QAAQ,QAAQ;AAI3B,KAAI,OAAO,KAAK,SAAS,MAAM,OAAO,aACpC,QAAO,EAAE,QAAQ,cAAc;
|
|
1
|
+
{"version":3,"file":"fetch-router.mjs","names":[],"sources":["../../../../src/v2/runtime/core/fetch-router.ts"],"sourcesContent":["/**\n * Lightweight URL router for framework-agnostic CopilotKit runtime handler.\n *\n * Two strategies:\n * - With `basePath`: strict prefix strip → match remainder\n * - Without `basePath`: suffix matching on known patterns\n *\n * Single-route mode: delegates to `parseMethodCall` for JSON envelope dispatch.\n */\n\nimport type { RouteInfo } from \"./hooks\";\n\n/**\n * Match a request URL against known CopilotKit route patterns.\n *\n * @param pathname - The URL pathname to match\n * @param basePath - Optional base path prefix to strip first\n * @returns RouteInfo if matched, null otherwise\n */\nexport function matchRoute(\n pathname: string,\n basePath?: string,\n): RouteInfo | null {\n let remainder: string;\n\n if (basePath) {\n // Normalize: ensure basePath doesn't end with /\n const normalizedBase =\n basePath.length > 1 && basePath.endsWith(\"/\")\n ? basePath.slice(0, -1)\n : basePath;\n\n // Special case: basePath === \"/\" matches everything\n if (normalizedBase === \"/\") {\n remainder = pathname;\n } else {\n if (!pathname.startsWith(normalizedBase)) return null;\n\n // The character after basePath must be \"/\" or end of string\n const afterBase = pathname.slice(normalizedBase.length);\n if (afterBase.length > 0 && !afterBase.startsWith(\"/\")) return null;\n\n remainder = afterBase || \"/\";\n }\n } else {\n // Suffix matching: find known patterns at the end of the pathname\n remainder = pathname;\n }\n\n return matchSegments(remainder);\n}\n\nfunction safeDecodeURIComponent(value: string): string | null {\n try {\n return decodeURIComponent(value);\n } catch {\n return null;\n }\n}\n\nfunction matchSegments(path: string): RouteInfo | null {\n const segments = path.split(\"/\").filter(Boolean);\n const len = segments.length;\n\n // Try suffix matching — scan from the end for known patterns\n\n // /info (1 segment)\n if (len >= 1 && segments[len - 1] === \"info\") {\n return { method: \"info\" };\n }\n\n // /transcribe (1 segment)\n if (len >= 1 && segments[len - 1] === \"transcribe\") {\n return { method: \"transcribe\" };\n }\n\n // /cpk-debug-events (1 segment)\n // Reserved route name: the `cpk-` prefix makes collision with a\n // user-named agent essentially impossible (the router only treats\n // `agent/:agentId/...` patterns as agent lookups, so a bare\n // `cpk-debug-events` segment would never fall through to one —\n // the prefix is the real guard, not this branch's position).\n // Handler returns 404 in production.\n if (len >= 1 && segments[len - 1] === \"cpk-debug-events\") {\n return { method: \"cpk-debug-events\" };\n }\n\n // /agent/:agentId/run (3 segments)\n if (\n len >= 3 &&\n segments[len - 3] === \"agent\" &&\n segments[len - 1] === \"run\"\n ) {\n const agentId = safeDecodeURIComponent(segments[len - 2]!);\n if (!agentId) return null;\n return { method: \"agent/run\", agentId };\n }\n\n // /agent/:agentId/connect (3 segments)\n if (\n len >= 3 &&\n segments[len - 3] === \"agent\" &&\n segments[len - 1] === \"connect\"\n ) {\n const agentId = safeDecodeURIComponent(segments[len - 2]!);\n if (!agentId) return null;\n return { method: \"agent/connect\", agentId };\n }\n\n // /agent/:agentId/stop/:threadId (4 segments)\n if (\n len >= 4 &&\n segments[len - 4] === \"agent\" &&\n segments[len - 2] === \"stop\"\n ) {\n const agentId = safeDecodeURIComponent(segments[len - 3]!);\n const threadId = safeDecodeURIComponent(segments[len - 1]!);\n if (!agentId || !threadId) return null;\n return { method: \"agent/stop\", agentId, threadId };\n }\n\n // /threads/subscribe (2 segments)\n if (\n len >= 2 &&\n segments[len - 2] === \"threads\" &&\n segments[len - 1] === \"subscribe\"\n ) {\n return { method: \"threads/subscribe\" };\n }\n\n // /threads/:threadId/messages (3 segments)\n if (\n len >= 3 &&\n segments[len - 3] === \"threads\" &&\n segments[len - 1] === \"messages\"\n ) {\n const threadId = safeDecodeURIComponent(segments[len - 2]!);\n if (!threadId) return null;\n return { method: \"threads/messages\", threadId };\n }\n\n // /threads/:threadId/archive (3 segments)\n if (\n len >= 3 &&\n segments[len - 3] === \"threads\" &&\n segments[len - 1] === \"archive\"\n ) {\n const threadId = safeDecodeURIComponent(segments[len - 2]!);\n if (!threadId) return null;\n return { method: \"threads/archive\", threadId };\n }\n\n // /threads/:threadId (2 segments) — update or delete\n if (\n len >= 2 &&\n segments[len - 2] === \"threads\" &&\n segments[len - 1] !== \"subscribe\"\n ) {\n const threadId = safeDecodeURIComponent(segments[len - 1]!);\n if (!threadId) return null;\n // Disambiguated by HTTP method in the handler\n return { method: \"threads/update\", threadId };\n }\n\n // /threads (1 segment) — list\n if (len >= 1 && segments[len - 1] === \"threads\") {\n return { method: \"threads/list\" };\n }\n\n return null;\n}\n"],"mappings":";;;;;;;;;AAmBA,SAAgB,WACd,UACA,UACkB;CAClB,IAAI;AAEJ,KAAI,UAAU;EAEZ,MAAM,iBACJ,SAAS,SAAS,KAAK,SAAS,SAAS,IAAI,GACzC,SAAS,MAAM,GAAG,GAAG,GACrB;AAGN,MAAI,mBAAmB,IACrB,aAAY;OACP;AACL,OAAI,CAAC,SAAS,WAAW,eAAe,CAAE,QAAO;GAGjD,MAAM,YAAY,SAAS,MAAM,eAAe,OAAO;AACvD,OAAI,UAAU,SAAS,KAAK,CAAC,UAAU,WAAW,IAAI,CAAE,QAAO;AAE/D,eAAY,aAAa;;OAI3B,aAAY;AAGd,QAAO,cAAc,UAAU;;AAGjC,SAAS,uBAAuB,OAA8B;AAC5D,KAAI;AACF,SAAO,mBAAmB,MAAM;SAC1B;AACN,SAAO;;;AAIX,SAAS,cAAc,MAAgC;CACrD,MAAM,WAAW,KAAK,MAAM,IAAI,CAAC,OAAO,QAAQ;CAChD,MAAM,MAAM,SAAS;AAKrB,KAAI,OAAO,KAAK,SAAS,MAAM,OAAO,OACpC,QAAO,EAAE,QAAQ,QAAQ;AAI3B,KAAI,OAAO,KAAK,SAAS,MAAM,OAAO,aACpC,QAAO,EAAE,QAAQ,cAAc;AAUjC,KAAI,OAAO,KAAK,SAAS,MAAM,OAAO,mBACpC,QAAO,EAAE,QAAQ,oBAAoB;AAIvC,KACE,OAAO,KACP,SAAS,MAAM,OAAO,WACtB,SAAS,MAAM,OAAO,OACtB;EACA,MAAM,UAAU,uBAAuB,SAAS,MAAM,GAAI;AAC1D,MAAI,CAAC,QAAS,QAAO;AACrB,SAAO;GAAE,QAAQ;GAAa;GAAS;;AAIzC,KACE,OAAO,KACP,SAAS,MAAM,OAAO,WACtB,SAAS,MAAM,OAAO,WACtB;EACA,MAAM,UAAU,uBAAuB,SAAS,MAAM,GAAI;AAC1D,MAAI,CAAC,QAAS,QAAO;AACrB,SAAO;GAAE,QAAQ;GAAiB;GAAS;;AAI7C,KACE,OAAO,KACP,SAAS,MAAM,OAAO,WACtB,SAAS,MAAM,OAAO,QACtB;EACA,MAAM,UAAU,uBAAuB,SAAS,MAAM,GAAI;EAC1D,MAAM,WAAW,uBAAuB,SAAS,MAAM,GAAI;AAC3D,MAAI,CAAC,WAAW,CAAC,SAAU,QAAO;AAClC,SAAO;GAAE,QAAQ;GAAc;GAAS;GAAU;;AAIpD,KACE,OAAO,KACP,SAAS,MAAM,OAAO,aACtB,SAAS,MAAM,OAAO,YAEtB,QAAO,EAAE,QAAQ,qBAAqB;AAIxC,KACE,OAAO,KACP,SAAS,MAAM,OAAO,aACtB,SAAS,MAAM,OAAO,YACtB;EACA,MAAM,WAAW,uBAAuB,SAAS,MAAM,GAAI;AAC3D,MAAI,CAAC,SAAU,QAAO;AACtB,SAAO;GAAE,QAAQ;GAAoB;GAAU;;AAIjD,KACE,OAAO,KACP,SAAS,MAAM,OAAO,aACtB,SAAS,MAAM,OAAO,WACtB;EACA,MAAM,WAAW,uBAAuB,SAAS,MAAM,GAAI;AAC3D,MAAI,CAAC,SAAU,QAAO;AACtB,SAAO;GAAE,QAAQ;GAAmB;GAAU;;AAIhD,KACE,OAAO,KACP,SAAS,MAAM,OAAO,aACtB,SAAS,MAAM,OAAO,aACtB;EACA,MAAM,WAAW,uBAAuB,SAAS,MAAM,GAAI;AAC3D,MAAI,CAAC,SAAU,QAAO;AAEtB,SAAO;GAAE,QAAQ;GAAkB;GAAU;;AAI/C,KAAI,OAAO,KAAK,SAAS,MAAM,OAAO,UACpC,QAAO,EAAE,QAAQ,gBAAgB;AAGnC,QAAO"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.cjs","names":[],"sources":["../../../../src/v2/runtime/core/hooks.ts"],"sourcesContent":["/**\n * Lifecycle hooks for CopilotKit runtime request processing.\n *\n * Hooks let you intercept requests at various stages of the pipeline:\n * - `onRequest`: Before routing — auth, correlation IDs, header injection\n * - `onBeforeHandler`: After routing — route-specific authorization\n * - `onResponse`: After handler — add headers, log, set cookies\n * - `onError`: On error — custom error responses\n *\n * @example\n * ```typescript\n * const handler = createCopilotRuntimeHandler({\n * runtime,\n * hooks: {\n * onRequest: async ({ request }) => {\n * const token = request.headers.get(\"authorization\");\n * if (!token) throw new Response(\"Unauthorized\", { status: 401 });\n * },\n * onResponse: async ({ response }) => {\n * const headers = new Headers(response.headers);\n * headers.set(\"x-copilot-version\", \"2.0\");\n * return new Response(response.body, { ...response, headers });\n * },\n * },\n * });\n * ```\n */\n\nimport type { MaybePromise } from \"@copilotkit/shared\";\nimport type { CopilotRuntimeLike } from \"./runtime\";\n\n/* ------------------------------------------------------------------------------------------------\n * Route info\n * --------------------------------------------------------------------------------------------- */\n\nexport type RouteInfo =\n | { method: \"agent/run\"; agentId: string }\n | { method: \"agent/connect\"; agentId: string }\n | { method: \"agent/stop\"; agentId: string; threadId: string }\n | { method: \"info\" }\n | { method: \"transcribe\" }\n | { method: \"threads/list\" }\n | { method: \"threads/subscribe\" }\n | { method: \"threads/update\"; threadId: string }\n | { method: \"threads/archive\"; threadId: string }\n | { method: \"threads/messages\"; threadId: string };\n\n/* ------------------------------------------------------------------------------------------------\n * Hook contexts\n * --------------------------------------------------------------------------------------------- */\n\nexport interface HookContext {\n /** The incoming Fetch Request (possibly modified by prior hooks). */\n request: Request;\n /** The resolved URL pathname. */\n path: string;\n /** The CopilotRuntimeLike instance. */\n runtime: CopilotRuntimeLike;\n}\n\nexport interface HandlerHookContext extends HookContext {\n /** The resolved route information. */\n route: RouteInfo;\n}\n\nexport interface ResponseHookContext extends HookContext {\n /** The Response produced by the handler. */\n response: Response;\n /** The resolved route information. */\n route: RouteInfo;\n}\n\nexport interface ErrorHookContext extends HookContext {\n /** The error that occurred. */\n error: unknown;\n /** The route info, if routing had already succeeded. */\n route?: RouteInfo;\n}\n\n/* ------------------------------------------------------------------------------------------------\n * Hooks interface\n * --------------------------------------------------------------------------------------------- */\n\nexport interface CopilotRuntimeHooks {\n /**\n * Called at the start of every request, before routing.\n * Use to validate auth, attach headers, initialize correlation IDs, etc.\n *\n * Return a modified Request to replace the original, or void to continue.\n * Throw a Response to short-circuit with an early response.\n */\n onRequest?: (ctx: HookContext) => MaybePromise<Request | void>;\n\n /**\n * Called after routing is resolved but before the handler executes.\n * Receives the resolved route info (method, agentId, threadId).\n *\n * Use to do route-specific authorization, attach headers for agent calls, etc.\n * Return a modified Request or void.\n * Throw a Response to short-circuit.\n */\n onBeforeHandler?: (ctx: HandlerHookContext) => MaybePromise<Request | void>;\n\n /**\n * Called after the handler produces a Response, before it's sent to the client.\n * Use to set cookies, add debugging headers, log, etc.\n *\n * Return a modified Response to replace the original, or void.\n */\n onResponse?: (ctx: ResponseHookContext) => MaybePromise<Response | void>;\n\n /**\n * Called when an error occurs during request processing.\n * Return a Response to override the default error response, or void to use the default.\n */\n onError?: (ctx: ErrorHookContext) => MaybePromise<Response | void>;\n}\n\n/* ------------------------------------------------------------------------------------------------\n * Internal hook runners\n * --------------------------------------------------------------------------------------------- */\n\nexport async function runOnRequest(\n hooks: CopilotRuntimeHooks | undefined,\n ctx: HookContext,\n): Promise<Request> {\n if (!hooks?.onRequest) return ctx.request;\n const result = await hooks.onRequest(ctx);\n return result instanceof Request ? result : ctx.request;\n}\n\nexport async function runOnBeforeHandler(\n hooks: CopilotRuntimeHooks | undefined,\n ctx: HandlerHookContext,\n): Promise<Request> {\n if (!hooks?.onBeforeHandler) return ctx.request;\n const result = await hooks.onBeforeHandler(ctx);\n return result instanceof Request ? result : ctx.request;\n}\n\nexport async function runOnResponse(\n hooks: CopilotRuntimeHooks | undefined,\n ctx: ResponseHookContext,\n): Promise<Response> {\n if (!hooks?.onResponse) return ctx.response;\n const result = await hooks.onResponse(ctx);\n return result instanceof Response ? result : ctx.response;\n}\n\nexport async function runOnError(\n hooks: CopilotRuntimeHooks | undefined,\n ctx: ErrorHookContext,\n): Promise<Response | void> {\n if (!hooks?.onError) return;\n return hooks.onError(ctx);\n}\n"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"hooks.cjs","names":[],"sources":["../../../../src/v2/runtime/core/hooks.ts"],"sourcesContent":["/**\n * Lifecycle hooks for CopilotKit runtime request processing.\n *\n * Hooks let you intercept requests at various stages of the pipeline:\n * - `onRequest`: Before routing — auth, correlation IDs, header injection\n * - `onBeforeHandler`: After routing — route-specific authorization\n * - `onResponse`: After handler — add headers, log, set cookies\n * - `onError`: On error — custom error responses\n *\n * @example\n * ```typescript\n * const handler = createCopilotRuntimeHandler({\n * runtime,\n * hooks: {\n * onRequest: async ({ request }) => {\n * const token = request.headers.get(\"authorization\");\n * if (!token) throw new Response(\"Unauthorized\", { status: 401 });\n * },\n * onResponse: async ({ response }) => {\n * const headers = new Headers(response.headers);\n * headers.set(\"x-copilot-version\", \"2.0\");\n * return new Response(response.body, { ...response, headers });\n * },\n * },\n * });\n * ```\n */\n\nimport type { MaybePromise } from \"@copilotkit/shared\";\nimport type { CopilotRuntimeLike } from \"./runtime\";\n\n/* ------------------------------------------------------------------------------------------------\n * Route info\n * --------------------------------------------------------------------------------------------- */\n\nexport type RouteInfo =\n | { method: \"agent/run\"; agentId: string }\n | { method: \"agent/connect\"; agentId: string }\n | { method: \"agent/stop\"; agentId: string; threadId: string }\n | { method: \"info\" }\n | { method: \"transcribe\" }\n | { method: \"threads/list\" }\n | { method: \"threads/subscribe\" }\n | { method: \"threads/update\"; threadId: string }\n | { method: \"threads/archive\"; threadId: string }\n | { method: \"threads/messages\"; threadId: string }\n | { method: \"cpk-debug-events\" };\n\n/* ------------------------------------------------------------------------------------------------\n * Hook contexts\n * --------------------------------------------------------------------------------------------- */\n\nexport interface HookContext {\n /** The incoming Fetch Request (possibly modified by prior hooks). */\n request: Request;\n /** The resolved URL pathname. */\n path: string;\n /** The CopilotRuntimeLike instance. */\n runtime: CopilotRuntimeLike;\n}\n\nexport interface HandlerHookContext extends HookContext {\n /** The resolved route information. */\n route: RouteInfo;\n}\n\nexport interface ResponseHookContext extends HookContext {\n /** The Response produced by the handler. */\n response: Response;\n /** The resolved route information. */\n route: RouteInfo;\n}\n\nexport interface ErrorHookContext extends HookContext {\n /** The error that occurred. */\n error: unknown;\n /** The route info, if routing had already succeeded. */\n route?: RouteInfo;\n}\n\n/* ------------------------------------------------------------------------------------------------\n * Hooks interface\n * --------------------------------------------------------------------------------------------- */\n\nexport interface CopilotRuntimeHooks {\n /**\n * Called at the start of every request, before routing.\n * Use to validate auth, attach headers, initialize correlation IDs, etc.\n *\n * Return a modified Request to replace the original, or void to continue.\n * Throw a Response to short-circuit with an early response.\n */\n onRequest?: (ctx: HookContext) => MaybePromise<Request | void>;\n\n /**\n * Called after routing is resolved but before the handler executes.\n * Receives the resolved route info (method, agentId, threadId).\n *\n * Use to do route-specific authorization, attach headers for agent calls, etc.\n * Return a modified Request or void.\n * Throw a Response to short-circuit.\n */\n onBeforeHandler?: (ctx: HandlerHookContext) => MaybePromise<Request | void>;\n\n /**\n * Called after the handler produces a Response, before it's sent to the client.\n * Use to set cookies, add debugging headers, log, etc.\n *\n * Return a modified Response to replace the original, or void.\n */\n onResponse?: (ctx: ResponseHookContext) => MaybePromise<Response | void>;\n\n /**\n * Called when an error occurs during request processing.\n * Return a Response to override the default error response, or void to use the default.\n */\n onError?: (ctx: ErrorHookContext) => MaybePromise<Response | void>;\n}\n\n/* ------------------------------------------------------------------------------------------------\n * Internal hook runners\n * --------------------------------------------------------------------------------------------- */\n\nexport async function runOnRequest(\n hooks: CopilotRuntimeHooks | undefined,\n ctx: HookContext,\n): Promise<Request> {\n if (!hooks?.onRequest) return ctx.request;\n const result = await hooks.onRequest(ctx);\n return result instanceof Request ? result : ctx.request;\n}\n\nexport async function runOnBeforeHandler(\n hooks: CopilotRuntimeHooks | undefined,\n ctx: HandlerHookContext,\n): Promise<Request> {\n if (!hooks?.onBeforeHandler) return ctx.request;\n const result = await hooks.onBeforeHandler(ctx);\n return result instanceof Request ? result : ctx.request;\n}\n\nexport async function runOnResponse(\n hooks: CopilotRuntimeHooks | undefined,\n ctx: ResponseHookContext,\n): Promise<Response> {\n if (!hooks?.onResponse) return ctx.response;\n const result = await hooks.onResponse(ctx);\n return result instanceof Response ? result : ctx.response;\n}\n\nexport async function runOnError(\n hooks: CopilotRuntimeHooks | undefined,\n ctx: ErrorHookContext,\n): Promise<Response | void> {\n if (!hooks?.onError) return;\n return hooks.onError(ctx);\n}\n"],"mappings":";;;AA2HA,eAAsB,aACpB,OACA,KACkB;AAClB,KAAI,CAAC,OAAO,UAAW,QAAO,IAAI;CAClC,MAAM,SAAS,MAAM,MAAM,UAAU,IAAI;AACzC,QAAO,kBAAkB,UAAU,SAAS,IAAI;;AAGlD,eAAsB,mBACpB,OACA,KACkB;AAClB,KAAI,CAAC,OAAO,gBAAiB,QAAO,IAAI;CACxC,MAAM,SAAS,MAAM,MAAM,gBAAgB,IAAI;AAC/C,QAAO,kBAAkB,UAAU,SAAS,IAAI;;AAGlD,eAAsB,cACpB,OACA,KACmB;AACnB,KAAI,CAAC,OAAO,WAAY,QAAO,IAAI;CACnC,MAAM,SAAS,MAAM,MAAM,WAAW,IAAI;AAC1C,QAAO,kBAAkB,WAAW,SAAS,IAAI;;AAGnD,eAAsB,WACpB,OACA,KAC0B;AAC1B,KAAI,CAAC,OAAO,QAAS;AACrB,QAAO,MAAM,QAAQ,IAAI"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.d.cts","names":[],"sources":["../../../../src/v2/runtime/core/hooks.ts"],"mappings":";;;;;KAmCY,SAAA;EACN,MAAA;EAAqB,OAAA;AAAA;EACrB,MAAA;EAAyB,OAAA;AAAA;EACzB,MAAA;EAAsB,OAAA;EAAiB,QAAA;AAAA;EACvC,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;EAA0B,QAAA;AAAA;EAC1B,MAAA;EAA2B,QAAA;AAAA;EAC3B,MAAA;EAA4B,QAAA;AAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"hooks.d.cts","names":[],"sources":["../../../../src/v2/runtime/core/hooks.ts"],"mappings":";;;;;KAmCY,SAAA;EACN,MAAA;EAAqB,OAAA;AAAA;EACrB,MAAA;EAAyB,OAAA;AAAA;EACzB,MAAA;EAAsB,OAAA;EAAiB,QAAA;AAAA;EACvC,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;EAA0B,QAAA;AAAA;EAC1B,MAAA;EAA2B,QAAA;AAAA;EAC3B,MAAA;EAA4B,QAAA;AAAA;EAC5B,MAAA;AAAA;AAAA,UAMW,WAAA;EAkBR;EAhBP,OAAA,EAAS,OAAA;EAgBO;EAdhB,IAAA;EAiBgC;EAfhC,OAAA,EAAS,kBAAA;AAAA;AAAA,UAGM,kBAAA,SAA2B,WAAA;EAc1C;EAZA,KAAA,EAAO,SAAA;AAAA;AAAA,UAGQ,mBAAA,SAA4B,WAAA;EAW1B;EATjB,QAAA,EAAU,QAAA;EAgBwB;EAdlC,KAAA,EAAO,SAAA;AAAA;AAAA,UAGQ,gBAAA,SAAyB,WAAA;EAmBN;EAjBlC,KAAA;EA2B4D;EAzB5D,KAAA,GAAQ,SAAA;AAAA;AAAA,UAOO,mBAAA;EA0B4B;;;;;;;EAlB3C,SAAA,IAAa,GAAA,EAAK,WAAA,KAAgB,YAAA,CAAa,OAAA;EAAlC;;;;;;;;EAUb,eAAA,IAAmB,GAAA,EAAK,kBAAA,KAAuB,YAAA,CAAa,OAAA;EAQzC;;;;;;EAAnB,UAAA,IAAc,GAAA,EAAK,mBAAA,KAAwB,YAAA,CAAa,QAAA;EAMnB;;;;EAArC,OAAA,IAAW,GAAA,EAAK,gBAAA,KAAqB,YAAA,CAAa,QAAA;AAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.d.mts","names":[],"sources":["../../../../src/v2/runtime/core/hooks.ts"],"mappings":";;;;;KAmCY,SAAA;EACN,MAAA;EAAqB,OAAA;AAAA;EACrB,MAAA;EAAyB,OAAA;AAAA;EACzB,MAAA;EAAsB,OAAA;EAAiB,QAAA;AAAA;EACvC,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;EAA0B,QAAA;AAAA;EAC1B,MAAA;EAA2B,QAAA;AAAA;EAC3B,MAAA;EAA4B,QAAA;AAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"hooks.d.mts","names":[],"sources":["../../../../src/v2/runtime/core/hooks.ts"],"mappings":";;;;;KAmCY,SAAA;EACN,MAAA;EAAqB,OAAA;AAAA;EACrB,MAAA;EAAyB,OAAA;AAAA;EACzB,MAAA;EAAsB,OAAA;EAAiB,QAAA;AAAA;EACvC,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;EAA0B,QAAA;AAAA;EAC1B,MAAA;EAA2B,QAAA;AAAA;EAC3B,MAAA;EAA4B,QAAA;AAAA;EAC5B,MAAA;AAAA;AAAA,UAMW,WAAA;EAkBR;EAhBP,OAAA,EAAS,OAAA;EAgBO;EAdhB,IAAA;EAiBgC;EAfhC,OAAA,EAAS,kBAAA;AAAA;AAAA,UAGM,kBAAA,SAA2B,WAAA;EAc1C;EAZA,KAAA,EAAO,SAAA;AAAA;AAAA,UAGQ,mBAAA,SAA4B,WAAA;EAW1B;EATjB,QAAA,EAAU,QAAA;EAgBwB;EAdlC,KAAA,EAAO,SAAA;AAAA;AAAA,UAGQ,gBAAA,SAAyB,WAAA;EAmBN;EAjBlC,KAAA;EA2B4D;EAzB5D,KAAA,GAAQ,SAAA;AAAA;AAAA,UAOO,mBAAA;EA0B4B;;;;;;;EAlB3C,SAAA,IAAa,GAAA,EAAK,WAAA,KAAgB,YAAA,CAAa,OAAA;EAAlC;;;;;;;;EAUb,eAAA,IAAmB,GAAA,EAAK,kBAAA,KAAuB,YAAA,CAAa,OAAA;EAQzC;;;;;;EAAnB,UAAA,IAAc,GAAA,EAAK,mBAAA,KAAwB,YAAA,CAAa,QAAA;EAMnB;;;;EAArC,OAAA,IAAW,GAAA,EAAK,gBAAA,KAAqB,YAAA,CAAa,QAAA;AAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.mjs","names":[],"sources":["../../../../src/v2/runtime/core/hooks.ts"],"sourcesContent":["/**\n * Lifecycle hooks for CopilotKit runtime request processing.\n *\n * Hooks let you intercept requests at various stages of the pipeline:\n * - `onRequest`: Before routing — auth, correlation IDs, header injection\n * - `onBeforeHandler`: After routing — route-specific authorization\n * - `onResponse`: After handler — add headers, log, set cookies\n * - `onError`: On error — custom error responses\n *\n * @example\n * ```typescript\n * const handler = createCopilotRuntimeHandler({\n * runtime,\n * hooks: {\n * onRequest: async ({ request }) => {\n * const token = request.headers.get(\"authorization\");\n * if (!token) throw new Response(\"Unauthorized\", { status: 401 });\n * },\n * onResponse: async ({ response }) => {\n * const headers = new Headers(response.headers);\n * headers.set(\"x-copilot-version\", \"2.0\");\n * return new Response(response.body, { ...response, headers });\n * },\n * },\n * });\n * ```\n */\n\nimport type { MaybePromise } from \"@copilotkit/shared\";\nimport type { CopilotRuntimeLike } from \"./runtime\";\n\n/* ------------------------------------------------------------------------------------------------\n * Route info\n * --------------------------------------------------------------------------------------------- */\n\nexport type RouteInfo =\n | { method: \"agent/run\"; agentId: string }\n | { method: \"agent/connect\"; agentId: string }\n | { method: \"agent/stop\"; agentId: string; threadId: string }\n | { method: \"info\" }\n | { method: \"transcribe\" }\n | { method: \"threads/list\" }\n | { method: \"threads/subscribe\" }\n | { method: \"threads/update\"; threadId: string }\n | { method: \"threads/archive\"; threadId: string }\n | { method: \"threads/messages\"; threadId: string };\n\n/* ------------------------------------------------------------------------------------------------\n * Hook contexts\n * --------------------------------------------------------------------------------------------- */\n\nexport interface HookContext {\n /** The incoming Fetch Request (possibly modified by prior hooks). */\n request: Request;\n /** The resolved URL pathname. */\n path: string;\n /** The CopilotRuntimeLike instance. */\n runtime: CopilotRuntimeLike;\n}\n\nexport interface HandlerHookContext extends HookContext {\n /** The resolved route information. */\n route: RouteInfo;\n}\n\nexport interface ResponseHookContext extends HookContext {\n /** The Response produced by the handler. */\n response: Response;\n /** The resolved route information. */\n route: RouteInfo;\n}\n\nexport interface ErrorHookContext extends HookContext {\n /** The error that occurred. */\n error: unknown;\n /** The route info, if routing had already succeeded. */\n route?: RouteInfo;\n}\n\n/* ------------------------------------------------------------------------------------------------\n * Hooks interface\n * --------------------------------------------------------------------------------------------- */\n\nexport interface CopilotRuntimeHooks {\n /**\n * Called at the start of every request, before routing.\n * Use to validate auth, attach headers, initialize correlation IDs, etc.\n *\n * Return a modified Request to replace the original, or void to continue.\n * Throw a Response to short-circuit with an early response.\n */\n onRequest?: (ctx: HookContext) => MaybePromise<Request | void>;\n\n /**\n * Called after routing is resolved but before the handler executes.\n * Receives the resolved route info (method, agentId, threadId).\n *\n * Use to do route-specific authorization, attach headers for agent calls, etc.\n * Return a modified Request or void.\n * Throw a Response to short-circuit.\n */\n onBeforeHandler?: (ctx: HandlerHookContext) => MaybePromise<Request | void>;\n\n /**\n * Called after the handler produces a Response, before it's sent to the client.\n * Use to set cookies, add debugging headers, log, etc.\n *\n * Return a modified Response to replace the original, or void.\n */\n onResponse?: (ctx: ResponseHookContext) => MaybePromise<Response | void>;\n\n /**\n * Called when an error occurs during request processing.\n * Return a Response to override the default error response, or void to use the default.\n */\n onError?: (ctx: ErrorHookContext) => MaybePromise<Response | void>;\n}\n\n/* ------------------------------------------------------------------------------------------------\n * Internal hook runners\n * --------------------------------------------------------------------------------------------- */\n\nexport async function runOnRequest(\n hooks: CopilotRuntimeHooks | undefined,\n ctx: HookContext,\n): Promise<Request> {\n if (!hooks?.onRequest) return ctx.request;\n const result = await hooks.onRequest(ctx);\n return result instanceof Request ? result : ctx.request;\n}\n\nexport async function runOnBeforeHandler(\n hooks: CopilotRuntimeHooks | undefined,\n ctx: HandlerHookContext,\n): Promise<Request> {\n if (!hooks?.onBeforeHandler) return ctx.request;\n const result = await hooks.onBeforeHandler(ctx);\n return result instanceof Request ? result : ctx.request;\n}\n\nexport async function runOnResponse(\n hooks: CopilotRuntimeHooks | undefined,\n ctx: ResponseHookContext,\n): Promise<Response> {\n if (!hooks?.onResponse) return ctx.response;\n const result = await hooks.onResponse(ctx);\n return result instanceof Response ? result : ctx.response;\n}\n\nexport async function runOnError(\n hooks: CopilotRuntimeHooks | undefined,\n ctx: ErrorHookContext,\n): Promise<Response | void> {\n if (!hooks?.onError) return;\n return hooks.onError(ctx);\n}\n"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"hooks.mjs","names":[],"sources":["../../../../src/v2/runtime/core/hooks.ts"],"sourcesContent":["/**\n * Lifecycle hooks for CopilotKit runtime request processing.\n *\n * Hooks let you intercept requests at various stages of the pipeline:\n * - `onRequest`: Before routing — auth, correlation IDs, header injection\n * - `onBeforeHandler`: After routing — route-specific authorization\n * - `onResponse`: After handler — add headers, log, set cookies\n * - `onError`: On error — custom error responses\n *\n * @example\n * ```typescript\n * const handler = createCopilotRuntimeHandler({\n * runtime,\n * hooks: {\n * onRequest: async ({ request }) => {\n * const token = request.headers.get(\"authorization\");\n * if (!token) throw new Response(\"Unauthorized\", { status: 401 });\n * },\n * onResponse: async ({ response }) => {\n * const headers = new Headers(response.headers);\n * headers.set(\"x-copilot-version\", \"2.0\");\n * return new Response(response.body, { ...response, headers });\n * },\n * },\n * });\n * ```\n */\n\nimport type { MaybePromise } from \"@copilotkit/shared\";\nimport type { CopilotRuntimeLike } from \"./runtime\";\n\n/* ------------------------------------------------------------------------------------------------\n * Route info\n * --------------------------------------------------------------------------------------------- */\n\nexport type RouteInfo =\n | { method: \"agent/run\"; agentId: string }\n | { method: \"agent/connect\"; agentId: string }\n | { method: \"agent/stop\"; agentId: string; threadId: string }\n | { method: \"info\" }\n | { method: \"transcribe\" }\n | { method: \"threads/list\" }\n | { method: \"threads/subscribe\" }\n | { method: \"threads/update\"; threadId: string }\n | { method: \"threads/archive\"; threadId: string }\n | { method: \"threads/messages\"; threadId: string }\n | { method: \"cpk-debug-events\" };\n\n/* ------------------------------------------------------------------------------------------------\n * Hook contexts\n * --------------------------------------------------------------------------------------------- */\n\nexport interface HookContext {\n /** The incoming Fetch Request (possibly modified by prior hooks). */\n request: Request;\n /** The resolved URL pathname. */\n path: string;\n /** The CopilotRuntimeLike instance. */\n runtime: CopilotRuntimeLike;\n}\n\nexport interface HandlerHookContext extends HookContext {\n /** The resolved route information. */\n route: RouteInfo;\n}\n\nexport interface ResponseHookContext extends HookContext {\n /** The Response produced by the handler. */\n response: Response;\n /** The resolved route information. */\n route: RouteInfo;\n}\n\nexport interface ErrorHookContext extends HookContext {\n /** The error that occurred. */\n error: unknown;\n /** The route info, if routing had already succeeded. */\n route?: RouteInfo;\n}\n\n/* ------------------------------------------------------------------------------------------------\n * Hooks interface\n * --------------------------------------------------------------------------------------------- */\n\nexport interface CopilotRuntimeHooks {\n /**\n * Called at the start of every request, before routing.\n * Use to validate auth, attach headers, initialize correlation IDs, etc.\n *\n * Return a modified Request to replace the original, or void to continue.\n * Throw a Response to short-circuit with an early response.\n */\n onRequest?: (ctx: HookContext) => MaybePromise<Request | void>;\n\n /**\n * Called after routing is resolved but before the handler executes.\n * Receives the resolved route info (method, agentId, threadId).\n *\n * Use to do route-specific authorization, attach headers for agent calls, etc.\n * Return a modified Request or void.\n * Throw a Response to short-circuit.\n */\n onBeforeHandler?: (ctx: HandlerHookContext) => MaybePromise<Request | void>;\n\n /**\n * Called after the handler produces a Response, before it's sent to the client.\n * Use to set cookies, add debugging headers, log, etc.\n *\n * Return a modified Response to replace the original, or void.\n */\n onResponse?: (ctx: ResponseHookContext) => MaybePromise<Response | void>;\n\n /**\n * Called when an error occurs during request processing.\n * Return a Response to override the default error response, or void to use the default.\n */\n onError?: (ctx: ErrorHookContext) => MaybePromise<Response | void>;\n}\n\n/* ------------------------------------------------------------------------------------------------\n * Internal hook runners\n * --------------------------------------------------------------------------------------------- */\n\nexport async function runOnRequest(\n hooks: CopilotRuntimeHooks | undefined,\n ctx: HookContext,\n): Promise<Request> {\n if (!hooks?.onRequest) return ctx.request;\n const result = await hooks.onRequest(ctx);\n return result instanceof Request ? result : ctx.request;\n}\n\nexport async function runOnBeforeHandler(\n hooks: CopilotRuntimeHooks | undefined,\n ctx: HandlerHookContext,\n): Promise<Request> {\n if (!hooks?.onBeforeHandler) return ctx.request;\n const result = await hooks.onBeforeHandler(ctx);\n return result instanceof Request ? result : ctx.request;\n}\n\nexport async function runOnResponse(\n hooks: CopilotRuntimeHooks | undefined,\n ctx: ResponseHookContext,\n): Promise<Response> {\n if (!hooks?.onResponse) return ctx.response;\n const result = await hooks.onResponse(ctx);\n return result instanceof Response ? result : ctx.response;\n}\n\nexport async function runOnError(\n hooks: CopilotRuntimeHooks | undefined,\n ctx: ErrorHookContext,\n): Promise<Response | void> {\n if (!hooks?.onError) return;\n return hooks.onError(ctx);\n}\n"],"mappings":";;AA2HA,eAAsB,aACpB,OACA,KACkB;AAClB,KAAI,CAAC,OAAO,UAAW,QAAO,IAAI;CAClC,MAAM,SAAS,MAAM,MAAM,UAAU,IAAI;AACzC,QAAO,kBAAkB,UAAU,SAAS,IAAI;;AAGlD,eAAsB,mBACpB,OACA,KACkB;AAClB,KAAI,CAAC,OAAO,gBAAiB,QAAO,IAAI;CACxC,MAAM,SAAS,MAAM,MAAM,gBAAgB,IAAI;AAC/C,QAAO,kBAAkB,UAAU,SAAS,IAAI;;AAGlD,eAAsB,cACpB,OACA,KACmB;AACnB,KAAI,CAAC,OAAO,WAAY,QAAO,IAAI;CACnC,MAAM,SAAS,MAAM,MAAM,WAAW,IAAI;AAC1C,QAAO,kBAAkB,WAAW,SAAS,IAAI;;AAGnD,eAAsB,WACpB,OACA,KAC0B;AAC1B,KAAI,CAAC,OAAO,QAAS;AACrB,QAAO,MAAM,QAAQ,IAAI"}
|
|
@@ -2,6 +2,7 @@ require("reflect-metadata");
|
|
|
2
2
|
const require_runtime = require('../../../_virtual/_rolldown/runtime.cjs');
|
|
3
3
|
const require_package$1 = require('../../../package.cjs');
|
|
4
4
|
const require_logger = require('../../../lib/logger.cjs');
|
|
5
|
+
const require_debug_event_bus = require('./debug-event-bus.cjs');
|
|
5
6
|
const require_in_memory = require('../runner/in-memory.cjs');
|
|
6
7
|
const require_intelligence = require('../runner/intelligence.cjs');
|
|
7
8
|
let _copilotkit_shared = require("@copilotkit/shared");
|
|
@@ -33,6 +34,7 @@ var BaseCopilotRuntime = class {
|
|
|
33
34
|
this.mcpApps = mcpApps;
|
|
34
35
|
this.openGenerativeUI = openGenerativeUI;
|
|
35
36
|
this.runner = runner;
|
|
37
|
+
if (process.env.NODE_ENV !== "production") this.debugEventBus = new require_debug_event_bus.DebugEventBus();
|
|
36
38
|
this.debug = (0, _copilotkit_shared.resolveDebugConfig)(options.debug);
|
|
37
39
|
if (this.debug.enabled) this.debugLogger = require_logger.createLogger({
|
|
38
40
|
level: "debug",
|
|
@@ -133,6 +135,9 @@ var CopilotRuntime = class {
|
|
|
133
135
|
get licenseChecker() {
|
|
134
136
|
return this.delegate.licenseChecker;
|
|
135
137
|
}
|
|
138
|
+
get debugEventBus() {
|
|
139
|
+
return this.delegate.debugEventBus;
|
|
140
|
+
}
|
|
136
141
|
get debug() {
|
|
137
142
|
return this.delegate.debug;
|
|
138
143
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.cjs","names":["pkg","createLogger","InMemoryAgentRunner","RUNTIME_MODE_SSE","IntelligenceAgentRunner","RUNTIME_MODE_INTELLIGENCE"],"sources":["../../../../src/v2/runtime/core/runtime.ts"],"sourcesContent":["import {\n MaybePromise,\n NonEmptyRecord,\n RuntimeMode,\n RUNTIME_MODE_SSE,\n RUNTIME_MODE_INTELLIGENCE,\n} from \"@copilotkit/shared\";\nimport {\n createLicenseChecker,\n type LicenseChecker,\n} from \"@copilotkit/license-verifier\";\nimport {\n type ResolvedDebugConfig,\n resolveDebugConfig,\n type DebugConfig,\n} from \"@copilotkit/shared\";\nimport { AbstractAgent } from \"@ag-ui/client\";\nimport type { MCPClientConfig } from \"@ag-ui/mcp-apps-middleware\";\nimport { A2UIMiddlewareConfig } from \"@ag-ui/a2ui-middleware\";\nimport pkg from \"../../../../package.json\";\nimport type {\n BeforeRequestMiddleware,\n AfterRequestMiddleware,\n} from \"./middleware\";\nimport { createLogger, type CopilotRuntimeLogger } from \"../../../lib/logger\";\nimport { TranscriptionService } from \"../transcription-service/transcription-service\";\nimport { AgentRunner } from \"../runner/agent-runner\";\nimport { InMemoryAgentRunner } from \"../runner/in-memory\";\nimport { IntelligenceAgentRunner } from \"../runner/intelligence\";\nimport { CopilotKitIntelligence } from \"../intelligence-platform\";\n\nexport const VERSION = pkg.version;\n\ninterface BaseCopilotRuntimeMiddlewareOptions {\n /** If set, middleware only applies to these named agents. Applies to all agents if omitted. */\n agents?: string[];\n}\n\nexport type McpAppsServerConfig = MCPClientConfig & {\n /** Agent to bind this server to. If omitted, the server is available to all agents. */\n agentId?: string;\n};\n\nexport interface McpAppsConfig {\n /** List of MCP server configurations. */\n servers: McpAppsServerConfig[];\n}\n\nexport interface OpenGenerativeUIOptions extends BaseCopilotRuntimeMiddlewareOptions {}\n\nexport type OpenGenerativeUIConfig = boolean | OpenGenerativeUIOptions;\n\ninterface CopilotRuntimeMiddlewares {\n /**\n * Auto-apply A2UIMiddleware to agents at run time.\n * Pass an object to enable and customise behaviour, or omit to disable.\n */\n a2ui?: BaseCopilotRuntimeMiddlewareOptions & A2UIMiddlewareConfig;\n /** Auto-apply MCPAppsMiddleware to agents at run time. */\n mcpApps?: McpAppsConfig;\n /** Auto-apply OpenGenerativeUIMiddleware to agents at run time. */\n openGenerativeUI?: OpenGenerativeUIConfig;\n}\n\n/**\n * Context passed to agent factory functions for per-request agent resolution.\n */\nexport interface AgentFactoryContext {\n /** The incoming HTTP request. */\n request: Request;\n}\n\n/**\n * A function that dynamically creates agents on a per-request basis.\n * Useful for multi-tenant scenarios or request-scoped agent configuration.\n */\nexport type AgentsFactory = (\n ctx: AgentFactoryContext,\n) => MaybePromise<NonEmptyRecord<Record<string, AbstractAgent>>>;\n\n/**\n * Agents can be provided as:\n * - A static record of agents\n * - A Promise that resolves to a record of agents\n * - A factory function that receives request context and returns agents (or a Promise of agents)\n */\nexport type AgentsConfig =\n | MaybePromise<NonEmptyRecord<Record<string, AbstractAgent>>>\n | AgentsFactory;\n\n/**\n * Resolve an AgentsConfig value to a concrete record of agents.\n * If the config is a factory function, it is called with the given request context.\n * Otherwise it is awaited directly (static record or Promise).\n */\nexport async function resolveAgents(\n agents: AgentsConfig,\n request?: Request,\n): Promise<Record<string, AbstractAgent>> {\n if (typeof agents === \"function\") {\n if (!request) {\n throw new Error(\n \"Agent factory function requires a request context, but none was provided.\",\n );\n }\n return agents({ request });\n }\n return agents;\n}\n\ninterface BaseCopilotRuntimeOptions extends CopilotRuntimeMiddlewares {\n /**\n * Map of available agents, or a factory function for per-request agent resolution.\n *\n * Static record:\n * ```ts\n * agents: { support: new SupportAgent(), technical: new TechnicalAgent() }\n * ```\n *\n * Factory function (called per-request):\n * ```ts\n * agents: ({ request }) => {\n * const tenantId = request.headers.get(\"x-tenant-id\");\n * return { default: createAgentForTenant(tenantId) };\n * }\n * ```\n */\n agents: AgentsConfig;\n /** Optional transcription service for audio processing. */\n transcriptionService?: TranscriptionService;\n /** Optional *before* middleware – callback function or webhook URL. */\n beforeRequestMiddleware?: BeforeRequestMiddleware;\n /** Optional *after* middleware – callback function or webhook URL. */\n afterRequestMiddleware?: AfterRequestMiddleware;\n /** Signed license token for server-side feature verification. Falls back to COPILOTKIT_LICENSE_TOKEN env var. */\n licenseToken?: string;\n /** Enable debug logging for the event pipeline. */\n debug?: DebugConfig;\n}\n\nexport interface CopilotRuntimeUser {\n id: string;\n}\n\nexport type IdentifyUserCallback = (\n request: Request,\n) => MaybePromise<CopilotRuntimeUser>;\n\nexport interface CopilotSseRuntimeOptions extends BaseCopilotRuntimeOptions {\n /** The runner to use for running agents in SSE mode. */\n runner?: AgentRunner;\n intelligence?: undefined;\n generateThreadNames?: undefined;\n}\n\nexport interface CopilotIntelligenceRuntimeOptions extends BaseCopilotRuntimeOptions {\n /** Configures Intelligence mode for durable threads and realtime events. */\n intelligence: CopilotKitIntelligence;\n /** Resolves the authenticated user for intelligence requests. */\n identifyUser: IdentifyUserCallback;\n /** Auto-generate short names for newly created threads. */\n generateThreadNames?: boolean;\n /** Max delay (ms) for WebSocket reconnect backoff. @default 10_000 */\n maxReconnectMs?: number;\n /** Max delay (ms) for channel rejoin backoff. @default 30_000 */\n maxRejoinMs?: number;\n /** Lock TTL in seconds. Clamped to a maximum of 3600 (1 hour). @default 20 */\n lockTtlSeconds?: number;\n /** Custom Redis key prefix for the thread lock. */\n lockKeyPrefix?: string;\n /** Interval in seconds at which the runtime renews the thread lock. Clamped to a maximum of 3000 (50 minutes). @default 15 */\n lockHeartbeatIntervalSeconds?: number;\n}\n\nexport type CopilotRuntimeOptions =\n | CopilotSseRuntimeOptions\n | CopilotIntelligenceRuntimeOptions;\n\nexport interface CopilotRuntimeLike {\n agents: CopilotRuntimeOptions[\"agents\"];\n transcriptionService: CopilotRuntimeOptions[\"transcriptionService\"];\n beforeRequestMiddleware: CopilotRuntimeOptions[\"beforeRequestMiddleware\"];\n afterRequestMiddleware: CopilotRuntimeOptions[\"afterRequestMiddleware\"];\n runner: AgentRunner;\n a2ui: CopilotRuntimeOptions[\"a2ui\"];\n mcpApps: CopilotRuntimeOptions[\"mcpApps\"];\n openGenerativeUI: CopilotRuntimeOptions[\"openGenerativeUI\"];\n intelligence?: CopilotKitIntelligence;\n identifyUser?: IdentifyUserCallback;\n mode: RuntimeMode;\n licenseChecker?: LicenseChecker;\n debug: ResolvedDebugConfig;\n debugLogger?: CopilotRuntimeLogger;\n}\n\nexport interface CopilotSseRuntimeLike extends CopilotRuntimeLike {\n intelligence?: undefined;\n mode: RUNTIME_MODE_SSE;\n}\n\nexport interface CopilotIntelligenceRuntimeLike extends CopilotRuntimeLike {\n intelligence: CopilotKitIntelligence;\n identifyUser: IdentifyUserCallback;\n generateThreadNames: boolean;\n lockTtlSeconds: number;\n lockKeyPrefix?: string;\n lockHeartbeatIntervalSeconds: number;\n mode: RUNTIME_MODE_INTELLIGENCE;\n}\n\nabstract class BaseCopilotRuntime implements CopilotRuntimeLike {\n public agents: CopilotRuntimeOptions[\"agents\"];\n public transcriptionService: CopilotRuntimeOptions[\"transcriptionService\"];\n public beforeRequestMiddleware: CopilotRuntimeOptions[\"beforeRequestMiddleware\"];\n public afterRequestMiddleware: CopilotRuntimeOptions[\"afterRequestMiddleware\"];\n public runner: AgentRunner;\n public a2ui: CopilotRuntimeOptions[\"a2ui\"];\n public mcpApps: CopilotRuntimeOptions[\"mcpApps\"];\n public openGenerativeUI: CopilotRuntimeOptions[\"openGenerativeUI\"];\n public licenseChecker?: LicenseChecker;\n public debug: ResolvedDebugConfig;\n public debugLogger?: CopilotRuntimeLogger;\n\n abstract readonly intelligence?: CopilotKitIntelligence;\n abstract readonly mode: RuntimeMode;\n\n constructor(options: BaseCopilotRuntimeOptions, runner: AgentRunner) {\n const {\n agents,\n transcriptionService,\n beforeRequestMiddleware,\n afterRequestMiddleware,\n a2ui,\n mcpApps,\n openGenerativeUI,\n } = options;\n\n this.agents = agents;\n this.transcriptionService = transcriptionService;\n this.beforeRequestMiddleware = beforeRequestMiddleware;\n this.afterRequestMiddleware = afterRequestMiddleware;\n this.a2ui = a2ui || undefined;\n this.mcpApps = mcpApps;\n this.openGenerativeUI = openGenerativeUI;\n this.runner = runner;\n this.debug = resolveDebugConfig(options.debug);\n if (this.debug.enabled) {\n this.debugLogger = createLogger({\n level: \"debug\",\n component: \"copilotkit-debug\",\n });\n }\n }\n}\n\nexport class CopilotSseRuntime\n extends BaseCopilotRuntime\n implements CopilotSseRuntimeLike\n{\n readonly intelligence = undefined;\n readonly mode = RUNTIME_MODE_SSE;\n\n constructor(options: CopilotSseRuntimeOptions) {\n super(options, options.runner ?? new InMemoryAgentRunner());\n }\n}\n\nexport class CopilotIntelligenceRuntime\n extends BaseCopilotRuntime\n implements CopilotIntelligenceRuntimeLike\n{\n readonly intelligence: CopilotKitIntelligence;\n readonly identifyUser: IdentifyUserCallback;\n readonly generateThreadNames: boolean;\n readonly lockTtlSeconds: number;\n readonly lockKeyPrefix?: string;\n readonly lockHeartbeatIntervalSeconds: number;\n readonly mode = RUNTIME_MODE_INTELLIGENCE;\n\n /** Maximum allowed lock TTL in seconds (1 hour). */\n static readonly MAX_LOCK_TTL_SECONDS = 3_600;\n /** Maximum allowed heartbeat interval in seconds (50 minutes). */\n static readonly MAX_HEARTBEAT_INTERVAL_SECONDS = 3_000;\n\n constructor(options: CopilotIntelligenceRuntimeOptions) {\n super(\n options,\n new IntelligenceAgentRunner({\n url: options.intelligence.ɵgetRunnerWsUrl(),\n authToken: options.intelligence.ɵgetRunnerAuthToken(),\n maxReconnectMs: options.maxReconnectMs,\n maxRejoinMs: options.maxRejoinMs,\n }),\n );\n this.intelligence = options.intelligence;\n this.identifyUser = options.identifyUser;\n this.generateThreadNames = options.generateThreadNames ?? true;\n this.licenseChecker = createLicenseChecker(options.licenseToken);\n this.lockTtlSeconds = Math.min(\n options.lockTtlSeconds ?? 20,\n CopilotIntelligenceRuntime.MAX_LOCK_TTL_SECONDS,\n );\n this.lockKeyPrefix = options.lockKeyPrefix;\n this.lockHeartbeatIntervalSeconds = Math.min(\n options.lockHeartbeatIntervalSeconds ?? 15,\n CopilotIntelligenceRuntime.MAX_HEARTBEAT_INTERVAL_SECONDS,\n );\n }\n}\n\nfunction hasIntelligenceOptions(\n options: CopilotRuntimeOptions,\n): options is CopilotIntelligenceRuntimeOptions {\n return \"intelligence\" in options && !!options.intelligence;\n}\n\nexport function isIntelligenceRuntime(\n runtime: CopilotRuntimeLike,\n): runtime is CopilotIntelligenceRuntimeLike {\n return runtime.mode === RUNTIME_MODE_INTELLIGENCE && !!runtime.intelligence;\n}\n\n/**\n * Compatibility shim that preserves the legacy `CopilotRuntime` entrypoint.\n * New code should prefer `CopilotSseRuntime` or `CopilotIntelligenceRuntime`.\n */\nexport class CopilotRuntime implements CopilotRuntimeLike {\n private delegate: CopilotRuntimeLike;\n\n constructor(options: CopilotRuntimeOptions) {\n this.delegate = hasIntelligenceOptions(options)\n ? new CopilotIntelligenceRuntime(options)\n : new CopilotSseRuntime(options);\n }\n\n get agents(): CopilotRuntimeOptions[\"agents\"] {\n return this.delegate.agents;\n }\n\n get transcriptionService(): CopilotRuntimeOptions[\"transcriptionService\"] {\n return this.delegate.transcriptionService;\n }\n\n get beforeRequestMiddleware(): CopilotRuntimeOptions[\"beforeRequestMiddleware\"] {\n return this.delegate.beforeRequestMiddleware;\n }\n\n get afterRequestMiddleware(): CopilotRuntimeOptions[\"afterRequestMiddleware\"] {\n return this.delegate.afterRequestMiddleware;\n }\n\n get runner(): AgentRunner {\n return this.delegate.runner;\n }\n\n get a2ui(): CopilotRuntimeOptions[\"a2ui\"] {\n return this.delegate.a2ui;\n }\n\n get mcpApps(): CopilotRuntimeOptions[\"mcpApps\"] {\n return this.delegate.mcpApps;\n }\n\n get openGenerativeUI(): CopilotRuntimeOptions[\"openGenerativeUI\"] {\n return this.delegate.openGenerativeUI;\n }\n\n get intelligence(): CopilotKitIntelligence | undefined {\n return this.delegate.intelligence;\n }\n\n get generateThreadNames(): boolean | undefined {\n return isIntelligenceRuntime(this.delegate)\n ? this.delegate.generateThreadNames\n : undefined;\n }\n\n get identifyUser(): IdentifyUserCallback | undefined {\n return isIntelligenceRuntime(this.delegate)\n ? this.delegate.identifyUser\n : undefined;\n }\n\n get lockTtlSeconds(): number | undefined {\n return isIntelligenceRuntime(this.delegate)\n ? this.delegate.lockTtlSeconds\n : undefined;\n }\n\n get lockKeyPrefix(): string | undefined {\n return isIntelligenceRuntime(this.delegate)\n ? this.delegate.lockKeyPrefix\n : undefined;\n }\n\n get lockHeartbeatIntervalSeconds(): number | undefined {\n return isIntelligenceRuntime(this.delegate)\n ? this.delegate.lockHeartbeatIntervalSeconds\n : undefined;\n }\n\n get mode(): RuntimeMode {\n return this.delegate.mode;\n }\n\n get licenseChecker() {\n return this.delegate.licenseChecker;\n }\n\n get debug(): ResolvedDebugConfig {\n return this.delegate.debug;\n }\n\n get debugLogger(): CopilotRuntimeLogger | undefined {\n return this.delegate.debugLogger;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"runtime.cjs","names":["pkg","DebugEventBus","createLogger","InMemoryAgentRunner","RUNTIME_MODE_SSE","IntelligenceAgentRunner","RUNTIME_MODE_INTELLIGENCE"],"sources":["../../../../src/v2/runtime/core/runtime.ts"],"sourcesContent":["import {\n MaybePromise,\n NonEmptyRecord,\n RuntimeMode,\n RUNTIME_MODE_SSE,\n RUNTIME_MODE_INTELLIGENCE,\n} from \"@copilotkit/shared\";\nimport {\n createLicenseChecker,\n type LicenseChecker,\n} from \"@copilotkit/license-verifier\";\nimport {\n type ResolvedDebugConfig,\n resolveDebugConfig,\n type DebugConfig,\n} from \"@copilotkit/shared\";\nimport { AbstractAgent } from \"@ag-ui/client\";\nimport type { MCPClientConfig } from \"@ag-ui/mcp-apps-middleware\";\nimport { A2UIMiddlewareConfig } from \"@ag-ui/a2ui-middleware\";\nimport pkg from \"../../../../package.json\";\nimport type {\n BeforeRequestMiddleware,\n AfterRequestMiddleware,\n} from \"./middleware\";\nimport { createLogger, type CopilotRuntimeLogger } from \"../../../lib/logger\";\nimport { TranscriptionService } from \"../transcription-service/transcription-service\";\nimport { DebugEventBus } from \"./debug-event-bus\";\nimport { AgentRunner } from \"../runner/agent-runner\";\nimport { InMemoryAgentRunner } from \"../runner/in-memory\";\nimport { IntelligenceAgentRunner } from \"../runner/intelligence\";\nimport { CopilotKitIntelligence } from \"../intelligence-platform\";\n\nexport const VERSION = pkg.version;\n\ninterface BaseCopilotRuntimeMiddlewareOptions {\n /** If set, middleware only applies to these named agents. Applies to all agents if omitted. */\n agents?: string[];\n}\n\nexport type McpAppsServerConfig = MCPClientConfig & {\n /** Agent to bind this server to. If omitted, the server is available to all agents. */\n agentId?: string;\n};\n\nexport interface McpAppsConfig {\n /** List of MCP server configurations. */\n servers: McpAppsServerConfig[];\n}\n\nexport interface OpenGenerativeUIOptions extends BaseCopilotRuntimeMiddlewareOptions {}\n\nexport type OpenGenerativeUIConfig = boolean | OpenGenerativeUIOptions;\n\ninterface CopilotRuntimeMiddlewares {\n /**\n * Auto-apply A2UIMiddleware to agents at run time.\n * Pass an object to enable and customise behaviour, or omit to disable.\n */\n a2ui?: BaseCopilotRuntimeMiddlewareOptions & A2UIMiddlewareConfig;\n /** Auto-apply MCPAppsMiddleware to agents at run time. */\n mcpApps?: McpAppsConfig;\n /** Auto-apply OpenGenerativeUIMiddleware to agents at run time. */\n openGenerativeUI?: OpenGenerativeUIConfig;\n}\n\n/**\n * Context passed to agent factory functions for per-request agent resolution.\n */\nexport interface AgentFactoryContext {\n /** The incoming HTTP request. */\n request: Request;\n}\n\n/**\n * A function that dynamically creates agents on a per-request basis.\n * Useful for multi-tenant scenarios or request-scoped agent configuration.\n */\nexport type AgentsFactory = (\n ctx: AgentFactoryContext,\n) => MaybePromise<NonEmptyRecord<Record<string, AbstractAgent>>>;\n\n/**\n * Agents can be provided as:\n * - A static record of agents\n * - A Promise that resolves to a record of agents\n * - A factory function that receives request context and returns agents (or a Promise of agents)\n */\nexport type AgentsConfig =\n | MaybePromise<NonEmptyRecord<Record<string, AbstractAgent>>>\n | AgentsFactory;\n\n/**\n * Resolve an AgentsConfig value to a concrete record of agents.\n * If the config is a factory function, it is called with the given request context.\n * Otherwise it is awaited directly (static record or Promise).\n */\nexport async function resolveAgents(\n agents: AgentsConfig,\n request?: Request,\n): Promise<Record<string, AbstractAgent>> {\n if (typeof agents === \"function\") {\n if (!request) {\n throw new Error(\n \"Agent factory function requires a request context, but none was provided.\",\n );\n }\n return agents({ request });\n }\n return agents;\n}\n\ninterface BaseCopilotRuntimeOptions extends CopilotRuntimeMiddlewares {\n /**\n * Map of available agents, or a factory function for per-request agent resolution.\n *\n * Static record:\n * ```ts\n * agents: { support: new SupportAgent(), technical: new TechnicalAgent() }\n * ```\n *\n * Factory function (called per-request):\n * ```ts\n * agents: ({ request }) => {\n * const tenantId = request.headers.get(\"x-tenant-id\");\n * return { default: createAgentForTenant(tenantId) };\n * }\n * ```\n */\n agents: AgentsConfig;\n /** Optional transcription service for audio processing. */\n transcriptionService?: TranscriptionService;\n /** Optional *before* middleware – callback function or webhook URL. */\n beforeRequestMiddleware?: BeforeRequestMiddleware;\n /** Optional *after* middleware – callback function or webhook URL. */\n afterRequestMiddleware?: AfterRequestMiddleware;\n /** Signed license token for server-side feature verification. Falls back to COPILOTKIT_LICENSE_TOKEN env var. */\n licenseToken?: string;\n /** Enable debug logging for the event pipeline. */\n debug?: DebugConfig;\n}\n\nexport interface CopilotRuntimeUser {\n id: string;\n name: string;\n}\n\nexport type IdentifyUserCallback = (\n request: Request,\n) => MaybePromise<CopilotRuntimeUser>;\n\nexport interface CopilotSseRuntimeOptions extends BaseCopilotRuntimeOptions {\n /** The runner to use for running agents in SSE mode. */\n runner?: AgentRunner;\n intelligence?: undefined;\n generateThreadNames?: undefined;\n}\n\nexport interface CopilotIntelligenceRuntimeOptions extends BaseCopilotRuntimeOptions {\n /** Configures Intelligence mode for durable threads and realtime events. */\n intelligence: CopilotKitIntelligence;\n /** Resolves the authenticated user for intelligence requests. */\n identifyUser: IdentifyUserCallback;\n /** Auto-generate short names for newly created threads. */\n generateThreadNames?: boolean;\n /** Max delay (ms) for WebSocket reconnect backoff. @default 10_000 */\n maxReconnectMs?: number;\n /** Max delay (ms) for channel rejoin backoff. @default 30_000 */\n maxRejoinMs?: number;\n /** Lock TTL in seconds. Clamped to a maximum of 3600 (1 hour). @default 20 */\n lockTtlSeconds?: number;\n /** Custom Redis key prefix for the thread lock. */\n lockKeyPrefix?: string;\n /** Interval in seconds at which the runtime renews the thread lock. Clamped to a maximum of 3000 (50 minutes). @default 15 */\n lockHeartbeatIntervalSeconds?: number;\n}\n\nexport type CopilotRuntimeOptions =\n | CopilotSseRuntimeOptions\n | CopilotIntelligenceRuntimeOptions;\n\nexport interface CopilotRuntimeLike {\n agents: CopilotRuntimeOptions[\"agents\"];\n transcriptionService: CopilotRuntimeOptions[\"transcriptionService\"];\n beforeRequestMiddleware: CopilotRuntimeOptions[\"beforeRequestMiddleware\"];\n afterRequestMiddleware: CopilotRuntimeOptions[\"afterRequestMiddleware\"];\n runner: AgentRunner;\n a2ui: CopilotRuntimeOptions[\"a2ui\"];\n mcpApps: CopilotRuntimeOptions[\"mcpApps\"];\n openGenerativeUI: CopilotRuntimeOptions[\"openGenerativeUI\"];\n intelligence?: CopilotKitIntelligence;\n identifyUser?: IdentifyUserCallback;\n mode: RuntimeMode;\n licenseChecker?: LicenseChecker;\n debugEventBus?: DebugEventBus;\n debug: ResolvedDebugConfig;\n debugLogger?: CopilotRuntimeLogger;\n}\n\nexport interface CopilotSseRuntimeLike extends CopilotRuntimeLike {\n intelligence?: undefined;\n mode: RUNTIME_MODE_SSE;\n}\n\nexport interface CopilotIntelligenceRuntimeLike extends CopilotRuntimeLike {\n intelligence: CopilotKitIntelligence;\n identifyUser: IdentifyUserCallback;\n generateThreadNames: boolean;\n lockTtlSeconds: number;\n lockKeyPrefix?: string;\n lockHeartbeatIntervalSeconds: number;\n mode: RUNTIME_MODE_INTELLIGENCE;\n}\n\nabstract class BaseCopilotRuntime implements CopilotRuntimeLike {\n public agents: CopilotRuntimeOptions[\"agents\"];\n public transcriptionService: CopilotRuntimeOptions[\"transcriptionService\"];\n public beforeRequestMiddleware: CopilotRuntimeOptions[\"beforeRequestMiddleware\"];\n public afterRequestMiddleware: CopilotRuntimeOptions[\"afterRequestMiddleware\"];\n public runner: AgentRunner;\n public a2ui: CopilotRuntimeOptions[\"a2ui\"];\n public mcpApps: CopilotRuntimeOptions[\"mcpApps\"];\n public openGenerativeUI: CopilotRuntimeOptions[\"openGenerativeUI\"];\n public licenseChecker?: LicenseChecker;\n public readonly debugEventBus?: DebugEventBus;\n public debug: ResolvedDebugConfig;\n public debugLogger?: CopilotRuntimeLogger;\n\n abstract readonly intelligence?: CopilotKitIntelligence;\n abstract readonly mode: RuntimeMode;\n\n constructor(options: BaseCopilotRuntimeOptions, runner: AgentRunner) {\n const {\n agents,\n transcriptionService,\n beforeRequestMiddleware,\n afterRequestMiddleware,\n a2ui,\n mcpApps,\n openGenerativeUI,\n } = options;\n\n this.agents = agents;\n this.transcriptionService = transcriptionService;\n this.beforeRequestMiddleware = beforeRequestMiddleware;\n this.afterRequestMiddleware = afterRequestMiddleware;\n this.a2ui = a2ui || undefined;\n this.mcpApps = mcpApps;\n this.openGenerativeUI = openGenerativeUI;\n this.runner = runner;\n\n if (process.env.NODE_ENV !== \"production\") {\n this.debugEventBus = new DebugEventBus();\n }\n this.debug = resolveDebugConfig(options.debug);\n if (this.debug.enabled) {\n this.debugLogger = createLogger({\n level: \"debug\",\n component: \"copilotkit-debug\",\n });\n }\n }\n}\n\nexport class CopilotSseRuntime\n extends BaseCopilotRuntime\n implements CopilotSseRuntimeLike\n{\n readonly intelligence = undefined;\n readonly mode = RUNTIME_MODE_SSE;\n\n constructor(options: CopilotSseRuntimeOptions) {\n super(options, options.runner ?? new InMemoryAgentRunner());\n }\n}\n\nexport class CopilotIntelligenceRuntime\n extends BaseCopilotRuntime\n implements CopilotIntelligenceRuntimeLike\n{\n readonly intelligence: CopilotKitIntelligence;\n readonly identifyUser: IdentifyUserCallback;\n readonly generateThreadNames: boolean;\n readonly lockTtlSeconds: number;\n readonly lockKeyPrefix?: string;\n readonly lockHeartbeatIntervalSeconds: number;\n readonly mode = RUNTIME_MODE_INTELLIGENCE;\n\n /** Maximum allowed lock TTL in seconds (1 hour). */\n static readonly MAX_LOCK_TTL_SECONDS = 3_600;\n /** Maximum allowed heartbeat interval in seconds (50 minutes). */\n static readonly MAX_HEARTBEAT_INTERVAL_SECONDS = 3_000;\n\n constructor(options: CopilotIntelligenceRuntimeOptions) {\n super(\n options,\n new IntelligenceAgentRunner({\n url: options.intelligence.ɵgetRunnerWsUrl(),\n authToken: options.intelligence.ɵgetRunnerAuthToken(),\n maxReconnectMs: options.maxReconnectMs,\n maxRejoinMs: options.maxRejoinMs,\n }),\n );\n this.intelligence = options.intelligence;\n this.identifyUser = options.identifyUser;\n this.generateThreadNames = options.generateThreadNames ?? true;\n this.licenseChecker = createLicenseChecker(options.licenseToken);\n this.lockTtlSeconds = Math.min(\n options.lockTtlSeconds ?? 20,\n CopilotIntelligenceRuntime.MAX_LOCK_TTL_SECONDS,\n );\n this.lockKeyPrefix = options.lockKeyPrefix;\n this.lockHeartbeatIntervalSeconds = Math.min(\n options.lockHeartbeatIntervalSeconds ?? 15,\n CopilotIntelligenceRuntime.MAX_HEARTBEAT_INTERVAL_SECONDS,\n );\n }\n}\n\nfunction hasIntelligenceOptions(\n options: CopilotRuntimeOptions,\n): options is CopilotIntelligenceRuntimeOptions {\n return \"intelligence\" in options && !!options.intelligence;\n}\n\nexport function isIntelligenceRuntime(\n runtime: CopilotRuntimeLike,\n): runtime is CopilotIntelligenceRuntimeLike {\n return runtime.mode === RUNTIME_MODE_INTELLIGENCE && !!runtime.intelligence;\n}\n\n/**\n * Compatibility shim that preserves the legacy `CopilotRuntime` entrypoint.\n * New code should prefer `CopilotSseRuntime` or `CopilotIntelligenceRuntime`.\n */\nexport class CopilotRuntime implements CopilotRuntimeLike {\n private delegate: CopilotRuntimeLike;\n\n constructor(options: CopilotRuntimeOptions) {\n this.delegate = hasIntelligenceOptions(options)\n ? new CopilotIntelligenceRuntime(options)\n : new CopilotSseRuntime(options);\n }\n\n get agents(): CopilotRuntimeOptions[\"agents\"] {\n return this.delegate.agents;\n }\n\n get transcriptionService(): CopilotRuntimeOptions[\"transcriptionService\"] {\n return this.delegate.transcriptionService;\n }\n\n get beforeRequestMiddleware(): CopilotRuntimeOptions[\"beforeRequestMiddleware\"] {\n return this.delegate.beforeRequestMiddleware;\n }\n\n get afterRequestMiddleware(): CopilotRuntimeOptions[\"afterRequestMiddleware\"] {\n return this.delegate.afterRequestMiddleware;\n }\n\n get runner(): AgentRunner {\n return this.delegate.runner;\n }\n\n get a2ui(): CopilotRuntimeOptions[\"a2ui\"] {\n return this.delegate.a2ui;\n }\n\n get mcpApps(): CopilotRuntimeOptions[\"mcpApps\"] {\n return this.delegate.mcpApps;\n }\n\n get openGenerativeUI(): CopilotRuntimeOptions[\"openGenerativeUI\"] {\n return this.delegate.openGenerativeUI;\n }\n\n get intelligence(): CopilotKitIntelligence | undefined {\n return this.delegate.intelligence;\n }\n\n get generateThreadNames(): boolean | undefined {\n return isIntelligenceRuntime(this.delegate)\n ? this.delegate.generateThreadNames\n : undefined;\n }\n\n get identifyUser(): IdentifyUserCallback | undefined {\n return isIntelligenceRuntime(this.delegate)\n ? this.delegate.identifyUser\n : undefined;\n }\n\n get lockTtlSeconds(): number | undefined {\n return isIntelligenceRuntime(this.delegate)\n ? this.delegate.lockTtlSeconds\n : undefined;\n }\n\n get lockKeyPrefix(): string | undefined {\n return isIntelligenceRuntime(this.delegate)\n ? this.delegate.lockKeyPrefix\n : undefined;\n }\n\n get lockHeartbeatIntervalSeconds(): number | undefined {\n return isIntelligenceRuntime(this.delegate)\n ? this.delegate.lockHeartbeatIntervalSeconds\n : undefined;\n }\n\n get mode(): RuntimeMode {\n return this.delegate.mode;\n }\n\n get licenseChecker() {\n return this.delegate.licenseChecker;\n }\n\n get debugEventBus() {\n return this.delegate.debugEventBus;\n }\n\n get debug(): ResolvedDebugConfig {\n return this.delegate.debug;\n }\n\n get debugLogger(): CopilotRuntimeLogger | undefined {\n return this.delegate.debugLogger;\n }\n}\n"],"mappings":"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"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { AfterRequestMiddleware, BeforeRequestMiddleware } from "./middleware.cjs";
|
|
3
3
|
import { CopilotRuntimeLogger } from "../../../lib/logger.cjs";
|
|
4
4
|
import { TranscriptionService } from "../transcription-service/transcription-service.cjs";
|
|
5
|
+
import { DebugEventBus } from "./debug-event-bus.cjs";
|
|
5
6
|
import { AgentRunner } from "../runner/agent-runner.cjs";
|
|
6
7
|
import { CopilotKitIntelligence } from "../intelligence-platform/client.cjs";
|
|
7
8
|
import { DebugConfig, MaybePromise, NonEmptyRecord, ResolvedDebugConfig, RuntimeMode } from "@copilotkit/shared";
|
|
@@ -92,6 +93,7 @@ interface BaseCopilotRuntimeOptions extends CopilotRuntimeMiddlewares {
|
|
|
92
93
|
}
|
|
93
94
|
interface CopilotRuntimeUser {
|
|
94
95
|
id: string;
|
|
96
|
+
name: string;
|
|
95
97
|
}
|
|
96
98
|
type IdentifyUserCallback = (request: Request) => MaybePromise<CopilotRuntimeUser>;
|
|
97
99
|
interface CopilotSseRuntimeOptions extends BaseCopilotRuntimeOptions {
|
|
@@ -132,6 +134,7 @@ interface CopilotRuntimeLike {
|
|
|
132
134
|
identifyUser?: IdentifyUserCallback;
|
|
133
135
|
mode: RuntimeMode;
|
|
134
136
|
licenseChecker?: LicenseChecker;
|
|
137
|
+
debugEventBus?: DebugEventBus;
|
|
135
138
|
debug: ResolvedDebugConfig;
|
|
136
139
|
debugLogger?: CopilotRuntimeLogger;
|
|
137
140
|
}
|
|
@@ -158,6 +161,7 @@ declare abstract class BaseCopilotRuntime implements CopilotRuntimeLike {
|
|
|
158
161
|
mcpApps: CopilotRuntimeOptions["mcpApps"];
|
|
159
162
|
openGenerativeUI: CopilotRuntimeOptions["openGenerativeUI"];
|
|
160
163
|
licenseChecker?: LicenseChecker;
|
|
164
|
+
readonly debugEventBus?: DebugEventBus;
|
|
161
165
|
debug: ResolvedDebugConfig;
|
|
162
166
|
debugLogger?: CopilotRuntimeLogger;
|
|
163
167
|
abstract readonly intelligence?: CopilotKitIntelligence;
|
|
@@ -207,6 +211,7 @@ declare class CopilotRuntime implements CopilotRuntimeLike {
|
|
|
207
211
|
get lockHeartbeatIntervalSeconds(): number | undefined;
|
|
208
212
|
get mode(): RuntimeMode;
|
|
209
213
|
get licenseChecker(): LicenseChecker;
|
|
214
|
+
get debugEventBus(): DebugEventBus;
|
|
210
215
|
get debug(): ResolvedDebugConfig;
|
|
211
216
|
get debugLogger(): CopilotRuntimeLogger | undefined;
|
|
212
217
|
}
|