@copilotkit/runtime 1.64.2-canary.1785346263 → 1.64.2-canary.1785375021
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/package.cjs +1 -1
- package/dist/runtime/package.mjs +1 -1
- package/dist/v2/runtime/core/channel-activation-config.cjs +3 -1
- package/dist/v2/runtime/core/channel-activation-config.cjs.map +1 -1
- package/dist/v2/runtime/core/channel-activation-config.d.cts +6 -0
- package/dist/v2/runtime/core/channel-activation-config.d.cts.map +1 -1
- package/dist/v2/runtime/core/channel-activation-config.d.mts +6 -0
- package/dist/v2/runtime/core/channel-activation-config.d.mts.map +1 -1
- package/dist/v2/runtime/core/channel-activation-config.mjs +3 -1
- package/dist/v2/runtime/core/channel-activation-config.mjs.map +1 -1
- package/dist/v2/runtime/core/channel-manager.cjs +209 -6
- package/dist/v2/runtime/core/channel-manager.cjs.map +1 -1
- package/dist/v2/runtime/core/channel-manager.d.cts +6 -1
- package/dist/v2/runtime/core/channel-manager.d.cts.map +1 -1
- package/dist/v2/runtime/core/channel-manager.d.mts +6 -1
- package/dist/v2/runtime/core/channel-manager.d.mts.map +1 -1
- package/dist/v2/runtime/core/channel-manager.mjs +209 -6
- package/dist/v2/runtime/core/channel-manager.mjs.map +1 -1
- package/dist/v2/runtime/core/fetch-handler.cjs +15 -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 +16 -1
- 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 +4 -0
- package/dist/v2/runtime/core/runtime.cjs.map +1 -1
- package/dist/v2/runtime/core/runtime.d.cts +24 -0
- package/dist/v2/runtime/core/runtime.d.cts.map +1 -1
- package/dist/v2/runtime/core/runtime.d.mts +24 -0
- package/dist/v2/runtime/core/runtime.d.mts.map +1 -1
- package/dist/v2/runtime/core/runtime.mjs +4 -0
- package/dist/v2/runtime/core/runtime.mjs.map +1 -1
- package/dist/v2/runtime/handlers/intelligence/memories.cjs +63 -1
- package/dist/v2/runtime/handlers/intelligence/memories.cjs.map +1 -1
- package/dist/v2/runtime/handlers/intelligence/memories.mjs +63 -2
- package/dist/v2/runtime/handlers/intelligence/memories.mjs.map +1 -1
- package/dist/v2/runtime/intelligence-platform/client.cjs +17 -1
- package/dist/v2/runtime/intelligence-platform/client.cjs.map +1 -1
- package/dist/v2/runtime/intelligence-platform/client.d.cts +31 -1
- package/dist/v2/runtime/intelligence-platform/client.d.cts.map +1 -1
- package/dist/v2/runtime/intelligence-platform/client.d.mts +31 -1
- package/dist/v2/runtime/intelligence-platform/client.d.mts.map +1 -1
- package/dist/v2/runtime/intelligence-platform/client.mjs +17 -1
- package/dist/v2/runtime/intelligence-platform/client.mjs.map +1 -1
- package/dist/v2/runtime/runner/agent-runner.cjs.map +1 -1
- package/dist/v2/runtime/runner/agent-runner.d.cts +2 -0
- package/dist/v2/runtime/runner/agent-runner.d.cts.map +1 -1
- package/dist/v2/runtime/runner/agent-runner.d.mts +2 -0
- package/dist/v2/runtime/runner/agent-runner.d.mts.map +1 -1
- package/dist/v2/runtime/runner/agent-runner.mjs.map +1 -1
- package/dist/v2/runtime/runner/in-memory.cjs +2 -5
- package/dist/v2/runtime/runner/in-memory.cjs.map +1 -1
- package/dist/v2/runtime/runner/in-memory.d.cts.map +1 -1
- package/dist/v2/runtime/runner/in-memory.d.mts.map +1 -1
- package/dist/v2/runtime/runner/in-memory.mjs +2 -5
- package/dist/v2/runtime/runner/in-memory.mjs.map +1 -1
- package/dist/v2/runtime/runner/intelligence.cjs +36 -31
- package/dist/v2/runtime/runner/intelligence.cjs.map +1 -1
- package/dist/v2/runtime/runner/intelligence.d.cts.map +1 -1
- package/dist/v2/runtime/runner/intelligence.d.mts.map +1 -1
- package/dist/v2/runtime/runner/intelligence.mjs +36 -31
- package/dist/v2/runtime/runner/intelligence.mjs.map +1 -1
- package/package.json +6 -6
|
@@ -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 * ## Managed Channels lifecycle (serverless-safe)\n *\n * When the runtime declares managed Channels, the returned handler carries a\n * `handler.channels` control surface — but creating the handler opens NO\n * network connection. Activation (which opens a persistent gateway WebSocket)\n * is LAZY: it is triggered by the first `await handler.channels.ready()` and\n * never before — not at handler creation, not on the first HTTP request.\n *\n * - On a LONG-RUNNING host (a Node server / container / the node/express/hono\n * endpoint wrappers), call `await handler.channels.ready()` ONCE at startup to\n * open the listener; the process owns it for its lifetime.\n * - On a SERVERLESS / EDGE host (Cloudflare Workers, Next.js App Router), do NOT\n * call `ready()` — those hosts freeze/recycle per-request isolates and cannot\n * own a persistent listener, and separate cold starts would mint conflicting\n * listeners. The generic Fetch handler stays a pure request/response function\n * there, exactly as documented above.\n *\n * @example\n * ```typescript\n * // Long-running host: open the managed-Channel listener once at startup.\n * const handler = createCopilotRuntimeHandler({ runtime });\n * await handler.channels.ready();\n * ```\n */\n\nimport type {\n CopilotRuntimeLike,\n CopilotIntelligenceRuntimeLike,\n RuntimeWithDeclaredChannels,\n} from \"./runtime\";\nimport { isIntelligenceRuntime } from \"./runtime\";\nimport { ChannelManager } from \"./channel-manager\";\nimport type { ChannelsControl, ActivateChannelEngine } from \"./channel-manager\";\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 { handleSuggestAgent } from \"../handlers/handle-suggest\";\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 handleClearThreads,\n handleListThreads,\n handleSubscribeToThreads,\n handleUpdateThread,\n handleArchiveThread,\n handleDeleteThread,\n handleGetThreadMessages,\n handleGetThreadEvents,\n handleGetThreadState,\n} from \"../handlers/handle-threads\";\nimport {\n handleListMemories,\n handleSubscribeToMemories,\n handleCreateMemory,\n handleUpdateMemory,\n handleRemoveMemory,\n} from \"../handlers/handle-memories\";\nimport { handleAnnotate } from \"../handlers/handle-user-actions\";\nimport {\n parseMethodCall,\n createJsonRequest,\n expectString,\n} from \"../endpoints/single-route-helpers\";\nimport type { MethodCall } from \"../endpoints/single-route-helpers\";\nimport { logger } from \"@copilotkit/shared\";\nimport { fireInstanceCreatedTelemetry } from \"../telemetry/instance-created\";\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 /**\n * Whether the handler builds the runtime's declared managed-Channel control\n * surface. Defaults to `true`, which constructs the {@link ChannelManager} and\n * exposes `handler.channels` — but does NOT open any connection: activation is\n * lazy and triggered by the first `handler.channels.ready()` (see the factory\n * TSDoc). Set `false` to opt out entirely: no {@link ChannelManager} is\n * constructed and the returned handler has no `.channels`. Non-intelligence or\n * channel-less runtimes never build a control surface regardless of this flag.\n */\n activateChannels?: boolean;\n\n /**\n * @internal Test seam: inject a fake Channel activation engine so channel\n * activation runs without opening a real transport. Not part of the public\n * API and may change or be removed without notice.\n */\n __channelEngine?: ActivateChannelEngine;\n}\n\n/**\n * A framework-agnostic runtime handler: a `(Request) => Promise<Response>`\n * function that is also a callable object carrying an optional {@link channels}\n * control surface. A plain function is assignable to this type, so existing\n * call sites that treat it as `(Request) => Promise<Response>` keep working.\n */\nexport type CopilotRuntimeFetchHandler = ((\n request: Request,\n) => Promise<Response>) & {\n /**\n * Present only when the handler activated managed Channels for an\n * Intelligence runtime; the lifecycle control surface for those Channels.\n */\n channels?: ChannelsControl;\n};\n\n/**\n * A {@link CopilotRuntimeFetchHandler} whose {@link ChannelsControl} surface is\n * guaranteed present. Returned when the runtime was constructed with at least\n * one declared Intelligence Channel and activation was not opted out of, so the\n * documented `handler.channels.ready(...)` call type-checks without a `!` or\n * `?.` under strict TypeScript.\n */\nexport type CopilotRuntimeFetchHandlerWithChannels = ((\n request: Request,\n) => Promise<Response>) & {\n /** Lifecycle control surface for the runtime's activated managed Channels. */\n channels: ChannelsControl;\n};\n\n/**\n * Managed Channel managers keyed by runtime instance. Guarantees a single\n * manager (and thus a single activation) per runtime: creating the handler more\n * than once for the same runtime reuses the existing manager instead of\n * constructing a second one.\n */\nconst channelManagers = new WeakMap<object, ChannelManager>();\n\n/**\n * Look up (or lazily CREATE) the {@link ChannelManager} for an Intelligence\n * runtime. First creation constructs the manager and caches it; subsequent\n * lookups reuse the cached instance so there is exactly one manager per runtime.\n *\n * Activation is NOT triggered here. Constructing the manager opens no\n * transport — the persistent gateway socket is opened lazily on the first\n * {@link ChannelManager.ready} call (see the factory TSDoc). This keeps the\n * generic Fetch handler serverless/edge-safe: creating it (e.g. at\n * Cloudflare-Worker module scope or per Next.js App Router isolate) never\n * performs network I/O and never mints a listener the host cannot own.\n *\n * Caching the un-activated manager is correct: a later `ready()` activates it\n * once (idempotently), and an up-front misconfiguration (duplicate/missing\n * channel names) surfaces as a rejected `ready()` rather than a throw at\n * creation. A manager that has been {@link ChannelManager.stop}ped stays\n * stopped on reuse — its latches short-circuit any later `activate()`/`ready()`.\n *\n * @param runtime - The Intelligence runtime whose Channels the manager drives.\n * @param engine - Optional injected activation engine (test seam); when\n * omitted the manager uses its default Realtime Gateway engine.\n * @returns The runtime's (un-activated) Channel manager.\n */\nfunction getOrCreateChannelManager(\n runtime: CopilotIntelligenceRuntimeLike,\n engine: ActivateChannelEngine | undefined,\n): ChannelManager {\n const existing = channelManagers.get(runtime);\n if (existing) {\n return existing;\n }\n const manager = new ChannelManager({\n intelligence: runtime.intelligence,\n channels: runtime.channels,\n // Bridge the manager's diagnostic sink to the shared logger. Without this\n // every `this.log?.(...)` breadcrumb in the manager (setup_required,\n // failed-to-activate, dropped-session, teardown-stop failures) is a no-op,\n // so a channel that fails to activate is permanently dead with zero output.\n // Mirror the `logger.<level>(context, message)` call shape used elsewhere in\n // this file; a failed activation is a degraded-but-recoverable condition, so\n // `warn` is the appropriate level. The manager passes an `Error` as `meta`\n // for failure breadcrumbs, but pino only serializes an Error (its\n // non-enumerable message/stack) under the `err` key — under any other key it\n // renders as `{}` and the cause is lost. Route an Error to `err` and keep the\n // `meta` key for everything else (`meta` is typed `unknown`).\n log: (msg, meta) =>\n logger.warn(meta instanceof Error ? { err: meta } : { meta }, msg),\n ...(engine ? { activateChannel: engine } : {}),\n });\n channelManagers.set(runtime, manager);\n return manager;\n}\n\n/* ------------------------------------------------------------------------------------------------\n * Handler factory\n * --------------------------------------------------------------------------------------------- */\n\n/**\n * Overload: a runtime constructed with at least one declared Intelligence\n * Channel (a {@link RuntimeWithDeclaredChannels}-branded runtime), when\n * activation is not disabled, yields a handler with a **non-optional**\n * {@link ChannelsControl}. `activateChannels` is constrained to `true | undefined`\n * here so passing `activateChannels: false` (which skips activation and leaves no\n * `.channels`) falls through to the optional-shape overload below rather than\n * dishonestly promising a control surface that will not exist.\n */\nexport function createCopilotRuntimeHandler(\n options: CopilotRuntimeHandlerOptions & {\n runtime: RuntimeWithDeclaredChannels;\n activateChannels?: true | undefined;\n },\n): CopilotRuntimeFetchHandlerWithChannels;\n/**\n * Overload: every other runtime (SSE, Intelligence without channels, or with\n * activation disabled) yields a handler whose `.channels` is optional.\n */\nexport function createCopilotRuntimeHandler(\n options: CopilotRuntimeHandlerOptions,\n): CopilotRuntimeFetchHandler;\nexport function createCopilotRuntimeHandler(\n options: CopilotRuntimeHandlerOptions,\n): CopilotRuntimeFetchHandler {\n const { runtime, basePath, mode = \"multi-route\", cors, hooks } = options;\n\n fireInstanceCreatedTelemetry({ runtime });\n\n const corsConfig = resolveCorsConfig(cors);\n\n const handler: CopilotRuntimeFetchHandler = async (\n request: Request,\n ): 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/suggest\" ||\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 threadEndpointsEnabled: false,\n });\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 threadEndpointsEnabled: true,\n });\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 // Build (but do NOT activate) the managed-Channel control surface for an\n // Intelligence runtime that declares Channels and hasn't opted out via\n // activateChannels. `handler.channels` exists immediately, but the persistent\n // gateway socket is opened lazily on the first `handler.channels.ready()` —\n // never at handler-creation time and never inside the per-request closure\n // above. This keeps the generic Fetch handler serverless/edge-safe: no\n // module-scope network I/O, and no listener a request-driven isolate cannot\n // own. See the factory TSDoc for the full lifecycle contract.\n if (\n isIntelligenceRuntime(runtime) &&\n runtime.channels &&\n runtime.channels.length > 0 &&\n options.activateChannels !== false\n ) {\n handler.channels = getOrCreateChannelManager(\n runtime,\n options.__channelEngine,\n );\n }\n\n return handler;\n}\n\n/* ------------------------------------------------------------------------------------------------\n * Route dispatch\n * --------------------------------------------------------------------------------------------- */\n\nfunction dispatchRoute(\n runtime: CopilotRuntimeLike,\n request: Request,\n route: RouteInfo,\n options: { threadEndpointsEnabled: boolean },\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/suggest\":\n return handleSuggestAgent({\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({\n runtime,\n request,\n threadEndpointsEnabled: options.threadEndpointsEnabled,\n });\n case \"transcribe\":\n return handleTranscribe({ runtime, request });\n case \"threads/clear\":\n return Promise.resolve(handleClearThreads({ runtime, request }));\n case \"threads/list\":\n return handleListThreads({ runtime, request });\n case \"memories/list\":\n return request.method.toUpperCase() === \"POST\"\n ? handleCreateMemory({ runtime, request })\n : handleListMemories({ runtime, request });\n case \"memories/subscribe\":\n return handleSubscribeToMemories({ runtime, request });\n case \"memories/mutate\":\n return request.method.toUpperCase() === \"DELETE\"\n ? handleRemoveMemory({ runtime, request, memoryId: route.memoryId })\n : handleUpdateMemory({ runtime, request, memoryId: route.memoryId });\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 \"threads/events\":\n return handleGetThreadEvents({\n runtime,\n request,\n threadId: route.threadId,\n });\n case \"threads/state\":\n return handleGetThreadState({\n runtime,\n request,\n threadId: route.threadId,\n });\n case \"annotate\":\n return handleAnnotate({ runtime, request });\n case \"cpk-debug-events\":\n return Promise.resolve(handleDebugEvents({ runtime, request }));\n default: {\n // Exhaustiveness guard: a new `RouteInfo` variant added without a case\n // above becomes a compile error here instead of silently returning\n // `undefined` at runtime.\n const _exhaustive: never = route;\n throw jsonResponse(\n { error: \"Not found\", method: (_exhaustive as RouteInfo).method },\n 404,\n );\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/suggest\":\n route = {\n method: \"agent/suggest\",\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 default: {\n // Exhaustiveness guard: a new `METHOD_NAMES`/`EndpointMethod` variant\n // added without a case above becomes a compile error here instead of\n // leaving `route` unassigned at runtime.\n const _exhaustive: never = methodCall.method;\n throw jsonResponse({ error: \"Not found\", method: _exhaustive }, 404);\n }\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 \"threads/events\":\n case \"threads/state\":\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 \"memories/list\":\n // GET lists the user's memories; POST creates one.\n if (method === \"GET\" || method === \"POST\") return null;\n return jsonResponse({ error: \"Method not allowed\" }, 405, {\n Allow: \"GET, POST\",\n });\n\n case \"memories/mutate\":\n // PATCH supersedes; DELETE retires.\n if (method === \"PATCH\" || method === \"DELETE\") return null;\n return jsonResponse({ error: \"Method not allowed\" }, 405, {\n Allow: \"PATCH, DELETE\",\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 * ## Managed Channels lifecycle (serverless-safe)\n *\n * When the runtime declares managed Channels, the returned handler carries a\n * `handler.channels` control surface — but creating the handler opens NO\n * network connection. Activation (which opens a persistent gateway WebSocket)\n * is LAZY: it is triggered by the first `await handler.channels.ready()` and\n * never before — not at handler creation, not on the first HTTP request.\n *\n * - On a LONG-RUNNING host (a Node server / container / the node/express/hono\n * endpoint wrappers), call `await handler.channels.ready()` ONCE at startup to\n * open the listener; the process owns it for its lifetime.\n * - On a SERVERLESS / EDGE host (Cloudflare Workers, Next.js App Router), do NOT\n * call `ready()` — those hosts freeze/recycle per-request isolates and cannot\n * own a persistent listener, and separate cold starts would mint conflicting\n * listeners. The generic Fetch handler stays a pure request/response function\n * there, exactly as documented above.\n *\n * @example\n * ```typescript\n * // Long-running host: open the managed-Channel listener once at startup.\n * const handler = createCopilotRuntimeHandler({ runtime });\n * await handler.channels.ready();\n * ```\n */\n\nimport type {\n CopilotRuntimeLike,\n CopilotIntelligenceRuntimeLike,\n RuntimeWithDeclaredChannels,\n} from \"./runtime\";\nimport { isIntelligenceRuntime } from \"./runtime\";\nimport { ChannelManager } from \"./channel-manager\";\nimport type { ChannelsControl, ActivateChannelEngine } from \"./channel-manager\";\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 { handleSuggestAgent } from \"../handlers/handle-suggest\";\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 handleClearThreads,\n handleListThreads,\n handleSubscribeToThreads,\n handleUpdateThread,\n handleArchiveThread,\n handleDeleteThread,\n handleGetThreadMessages,\n handleGetThreadEvents,\n handleGetThreadState,\n} from \"../handlers/handle-threads\";\nimport {\n handleListMemories,\n handleRecallMemories,\n handleSubscribeToMemories,\n handleCreateMemory,\n handleUpdateMemory,\n handleRemoveMemory,\n} from \"../handlers/handle-memories\";\nimport { handleAnnotate } from \"../handlers/handle-user-actions\";\nimport {\n parseMethodCall,\n createJsonRequest,\n expectString,\n} from \"../endpoints/single-route-helpers\";\nimport type { MethodCall } from \"../endpoints/single-route-helpers\";\nimport { logger } from \"@copilotkit/shared\";\nimport { fireInstanceCreatedTelemetry } from \"../telemetry/instance-created\";\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 /**\n * Whether the handler builds the runtime's declared managed-Channel control\n * surface. Defaults to `true`, which constructs the {@link ChannelManager} and\n * exposes `handler.channels` — but does NOT open any connection: activation is\n * lazy and triggered by the first `handler.channels.ready()` (see the factory\n * TSDoc). Set `false` to opt out entirely: no {@link ChannelManager} is\n * constructed and the returned handler has no `.channels`. Non-intelligence or\n * channel-less runtimes never build a control surface regardless of this flag.\n */\n activateChannels?: boolean;\n\n /**\n * @internal Test seam: inject a fake Channel activation engine so channel\n * activation runs without opening a real transport. Not part of the public\n * API and may change or be removed without notice.\n */\n __channelEngine?: ActivateChannelEngine;\n}\n\n/**\n * A framework-agnostic runtime handler: a `(Request) => Promise<Response>`\n * function that is also a callable object carrying an optional {@link channels}\n * control surface. A plain function is assignable to this type, so existing\n * call sites that treat it as `(Request) => Promise<Response>` keep working.\n */\nexport type CopilotRuntimeFetchHandler = ((\n request: Request,\n) => Promise<Response>) & {\n /**\n * Present only when the handler activated managed Channels for an\n * Intelligence runtime; the lifecycle control surface for those Channels.\n */\n channels?: ChannelsControl;\n};\n\n/**\n * A {@link CopilotRuntimeFetchHandler} whose {@link ChannelsControl} surface is\n * guaranteed present. Returned when the runtime was constructed with at least\n * one declared Intelligence Channel and activation was not opted out of, so the\n * documented `handler.channels.ready(...)` call type-checks without a `!` or\n * `?.` under strict TypeScript.\n */\nexport type CopilotRuntimeFetchHandlerWithChannels = ((\n request: Request,\n) => Promise<Response>) & {\n /** Lifecycle control surface for the runtime's activated managed Channels. */\n channels: ChannelsControl;\n};\n\n/**\n * Managed Channel managers keyed by runtime instance. Guarantees a single\n * manager (and thus a single activation) per runtime: creating the handler more\n * than once for the same runtime reuses the existing manager instead of\n * constructing a second one.\n */\nconst channelManagers = new WeakMap<object, ChannelManager>();\n\n/**\n * Look up (or lazily CREATE) the {@link ChannelManager} for an Intelligence\n * runtime. First creation constructs the manager and caches it; subsequent\n * lookups reuse the cached instance so there is exactly one manager per runtime.\n *\n * Activation is NOT triggered here. Constructing the manager opens no\n * transport — the persistent gateway socket is opened lazily on the first\n * {@link ChannelManager.ready} call (see the factory TSDoc). This keeps the\n * generic Fetch handler serverless/edge-safe: creating it (e.g. at\n * Cloudflare-Worker module scope or per Next.js App Router isolate) never\n * performs network I/O and never mints a listener the host cannot own.\n *\n * Caching the un-activated manager is correct: a later `ready()` activates it\n * once (idempotently), and an up-front misconfiguration (duplicate/missing\n * channel names) surfaces as a rejected `ready()` rather than a throw at\n * creation. A manager that has been {@link ChannelManager.stop}ped stays\n * stopped on reuse — its latches short-circuit any later `activate()`/`ready()`.\n *\n * @param runtime - The Intelligence runtime whose Channels the manager drives.\n * @param engine - Optional injected activation engine (test seam); when\n * omitted the manager uses its default Realtime Gateway engine.\n * @returns The runtime's (un-activated) Channel manager.\n */\nfunction getOrCreateChannelManager(\n runtime: CopilotIntelligenceRuntimeLike,\n engine: ActivateChannelEngine | undefined,\n): ChannelManager {\n const existing = channelManagers.get(runtime);\n if (existing) {\n return existing;\n }\n const manager = new ChannelManager({\n intelligence: runtime.intelligence,\n runner: runtime.runner,\n lockTtlSeconds: runtime.lockTtlSeconds,\n lockHeartbeatIntervalSeconds: runtime.lockHeartbeatIntervalSeconds,\n channels: runtime.channels,\n // Bridge the manager's diagnostic sink to the shared logger. Without this\n // every `this.log?.(...)` breadcrumb in the manager (setup_required,\n // failed-to-activate, dropped-session, teardown-stop failures) is a no-op,\n // so a channel that fails to activate is permanently dead with zero output.\n // Mirror the `logger.<level>(context, message)` call shape used elsewhere in\n // this file; a failed activation is a degraded-but-recoverable condition, so\n // `warn` is the appropriate level. The manager passes an `Error` as `meta`\n // for failure breadcrumbs, but pino only serializes an Error (its\n // non-enumerable message/stack) under the `err` key — under any other key it\n // renders as `{}` and the cause is lost. Route an Error to `err` and keep the\n // `meta` key for everything else (`meta` is typed `unknown`).\n log: (msg, meta) =>\n logger.warn(meta instanceof Error ? { err: meta } : { meta }, msg),\n ...(engine ? { activateChannel: engine } : {}),\n });\n channelManagers.set(runtime, manager);\n return manager;\n}\n\n/* ------------------------------------------------------------------------------------------------\n * Handler factory\n * --------------------------------------------------------------------------------------------- */\n\n/**\n * Overload: a runtime constructed with at least one declared Intelligence\n * Channel (a {@link RuntimeWithDeclaredChannels}-branded runtime), when\n * activation is not disabled, yields a handler with a **non-optional**\n * {@link ChannelsControl}. `activateChannels` is constrained to `true | undefined`\n * here so passing `activateChannels: false` (which skips activation and leaves no\n * `.channels`) falls through to the optional-shape overload below rather than\n * dishonestly promising a control surface that will not exist.\n */\nexport function createCopilotRuntimeHandler(\n options: CopilotRuntimeHandlerOptions & {\n runtime: RuntimeWithDeclaredChannels;\n activateChannels?: true | undefined;\n },\n): CopilotRuntimeFetchHandlerWithChannels;\n/**\n * Overload: every other runtime (SSE, Intelligence without channels, or with\n * activation disabled) yields a handler whose `.channels` is optional.\n */\nexport function createCopilotRuntimeHandler(\n options: CopilotRuntimeHandlerOptions,\n): CopilotRuntimeFetchHandler;\nexport function createCopilotRuntimeHandler(\n options: CopilotRuntimeHandlerOptions,\n): CopilotRuntimeFetchHandler {\n const { runtime, basePath, mode = \"multi-route\", cors, hooks } = options;\n\n fireInstanceCreatedTelemetry({ runtime });\n\n const corsConfig = resolveCorsConfig(cors);\n\n const handler: CopilotRuntimeFetchHandler = async (\n request: Request,\n ): 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/suggest\" ||\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 threadEndpointsEnabled: false,\n });\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 // Opt-in gate for the client-facing memory proxy routes (secure\n // default: off). Runs BEFORE method validation so a hidden route 404s\n // uniformly regardless of HTTP method — a 405 here would otherwise leak\n // that the route exists. `dispatchRoute` re-applies the same gate as\n // defense-in-depth (and to cover the single-route path).\n if (\n matched.method.startsWith(\"memories/\") &&\n runtime.exposeMemoryRoutes !== true\n ) {\n route = 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 threadEndpointsEnabled: true,\n });\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 // Build (but do NOT activate) the managed-Channel control surface for an\n // Intelligence runtime that declares Channels and hasn't opted out via\n // activateChannels. `handler.channels` exists immediately, but the persistent\n // gateway socket is opened lazily on the first `handler.channels.ready()` —\n // never at handler-creation time and never inside the per-request closure\n // above. This keeps the generic Fetch handler serverless/edge-safe: no\n // module-scope network I/O, and no listener a request-driven isolate cannot\n // own. See the factory TSDoc for the full lifecycle contract.\n if (\n isIntelligenceRuntime(runtime) &&\n runtime.channels &&\n runtime.channels.length > 0 &&\n options.activateChannels !== false\n ) {\n handler.channels = getOrCreateChannelManager(\n runtime,\n options.__channelEngine,\n );\n }\n\n return handler;\n}\n\n/* ------------------------------------------------------------------------------------------------\n * Route dispatch\n * --------------------------------------------------------------------------------------------- */\n\nfunction dispatchRoute(\n runtime: CopilotRuntimeLike,\n request: Request,\n route: RouteInfo,\n options: { threadEndpointsEnabled: boolean },\n): Promise<Response> {\n // Opt-in gate for the client-facing memory proxy routes (secure default:\n // off). When not explicitly enabled, every `/memories/*` route 404s as if it\n // did not exist — this MUST run before the per-handler `isIntelligenceRuntime`\n // check so an un-opted-in deployment reveals nothing about memory (not even\n // whether Intelligence is configured). Coalesce a missing flag (external\n // `CopilotRuntimeLike` implementor) to `false`.\n if (\n route.method.startsWith(\"memories/\") &&\n runtime.exposeMemoryRoutes !== true\n ) {\n throw jsonResponse({ error: \"Not found\" }, 404);\n }\n\n switch (route.method) {\n case \"agent/run\":\n return handleRunAgent({\n runtime,\n request,\n agentId: route.agentId,\n });\n case \"agent/suggest\":\n return handleSuggestAgent({\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({\n runtime,\n request,\n threadEndpointsEnabled: options.threadEndpointsEnabled,\n });\n case \"transcribe\":\n return handleTranscribe({ runtime, request });\n case \"threads/clear\":\n return Promise.resolve(handleClearThreads({ runtime, request }));\n case \"threads/list\":\n return handleListThreads({ runtime, request });\n case \"memories/list\":\n return request.method.toUpperCase() === \"POST\"\n ? handleCreateMemory({ runtime, request })\n : handleListMemories({ runtime, request });\n case \"memories/recall\":\n return handleRecallMemories({ runtime, request });\n case \"memories/subscribe\":\n return handleSubscribeToMemories({ runtime, request });\n case \"memories/mutate\":\n return request.method.toUpperCase() === \"DELETE\"\n ? handleRemoveMemory({ runtime, request, memoryId: route.memoryId })\n : handleUpdateMemory({ runtime, request, memoryId: route.memoryId });\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 \"threads/events\":\n return handleGetThreadEvents({\n runtime,\n request,\n threadId: route.threadId,\n });\n case \"threads/state\":\n return handleGetThreadState({\n runtime,\n request,\n threadId: route.threadId,\n });\n case \"annotate\":\n return handleAnnotate({ runtime, request });\n case \"cpk-debug-events\":\n return Promise.resolve(handleDebugEvents({ runtime, request }));\n default: {\n // Exhaustiveness guard: a new `RouteInfo` variant added without a case\n // above becomes a compile error here instead of silently returning\n // `undefined` at runtime.\n const _exhaustive: never = route;\n throw jsonResponse(\n { error: \"Not found\", method: (_exhaustive as RouteInfo).method },\n 404,\n );\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/suggest\":\n route = {\n method: \"agent/suggest\",\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 default: {\n // Exhaustiveness guard: a new `METHOD_NAMES`/`EndpointMethod` variant\n // added without a case above becomes a compile error here instead of\n // leaving `route` unassigned at runtime.\n const _exhaustive: never = methodCall.method;\n throw jsonResponse({ error: \"Not found\", method: _exhaustive }, 404);\n }\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 \"threads/events\":\n case \"threads/state\":\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 \"memories/list\":\n // GET lists the user's memories; POST creates one.\n if (method === \"GET\" || method === \"POST\") return null;\n return jsonResponse({ error: \"Method not allowed\" }, 405, {\n Allow: \"GET, POST\",\n });\n\n case \"memories/mutate\":\n // PATCH supersedes; DELETE retires.\n if (method === \"PATCH\" || method === \"DELETE\") return null;\n return jsonResponse({ error: \"Method not allowed\" }, 405, {\n Allow: \"PATCH, DELETE\",\n });\n\n case \"memories/recall\":\n // POST-only: semantic recall carries its query in the body.\n if (method === \"POST\") return null;\n return jsonResponse({ error: \"Method not allowed\" }, 405, {\n Allow: \"POST\",\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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"}
|
|
@@ -112,6 +112,7 @@ function matchSegments(path) {
|
|
|
112
112
|
};
|
|
113
113
|
}
|
|
114
114
|
if (len >= 1 && segments[len - 1] === "threads") return { method: "threads/list" };
|
|
115
|
+
if (len >= 2 && segments[len - 2] === "memories" && segments[len - 1] === "recall") return { method: "memories/recall" };
|
|
115
116
|
if (len >= 2 && segments[len - 2] === "memories" && segments[len - 1] === "subscribe") return { method: "memories/subscribe" };
|
|
116
117
|
if (len >= 2 && segments[len - 2] === "memories" && segments[len - 1] !== "subscribe") {
|
|
117
118
|
const memoryId = safeDecodeURIComponent(segments[len - 1]);
|
|
@@ -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 // /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/suggest (3 segments)\n if (\n len >= 3 &&\n segments[len - 3] === \"agent\" &&\n segments[len - 1] === \"suggest\"\n ) {\n const agentId = safeDecodeURIComponent(segments[len - 2]!);\n if (!agentId) return null;\n return { method: \"agent/suggest\", 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/events (3 segments)\n if (\n len >= 3 &&\n segments[len - 3] === \"threads\" &&\n segments[len - 1] === \"events\"\n ) {\n const threadId = safeDecodeURIComponent(segments[len - 2]!);\n if (!threadId) return null;\n return { method: \"threads/events\", threadId };\n }\n\n // /threads/:threadId/state (3 segments)\n if (\n len >= 3 &&\n segments[len - 3] === \"threads\" &&\n segments[len - 1] === \"state\"\n ) {\n const threadId = safeDecodeURIComponent(segments[len - 2]!);\n if (!threadId) return null;\n return { method: \"threads/state\", 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/clear (2 segments) — wipe in-memory thread history\n if (\n len >= 2 &&\n segments[len - 2] === \"threads\" &&\n segments[len - 1] === \"clear\"\n ) {\n return { method: \"threads/clear\" };\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 segments[len - 1] !== \"clear\"\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 // /memories/subscribe (2 segments) — mint memory-realtime join credentials.\n if (\n len >= 2 &&\n segments[len - 2] === \"memories\" &&\n segments[len - 1] === \"subscribe\"\n ) {\n return { method: \"memories/subscribe\" };\n }\n\n // /memories/:id (2 segments) — supersede (PATCH) or retire (DELETE).\n // Disambiguated by HTTP method in the handler.\n if (\n len >= 2 &&\n segments[len - 2] === \"memories\" &&\n segments[len - 1] !== \"subscribe\"\n ) {\n const memoryId = safeDecodeURIComponent(segments[len - 1]!);\n if (!memoryId) return null;\n return { method: \"memories/mutate\", memoryId };\n }\n\n // /memories (1 segment) — GET lists; POST creates.\n if (len >= 1 && segments[len - 1] === \"memories\") {\n return { method: \"memories/list\" };\n }\n\n // /annotate (1 segment) — annotate a thread event\n if (len >= 1 && segments[len - 1] === \"annotate\") {\n return { method: \"annotate\" };\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,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,UACtB;EACA,MAAM,WAAW,uBAAuB,SAAS,MAAM,GAAI;AAC3D,MAAI,CAAC,SAAU,QAAO;AACtB,SAAO;GAAE,QAAQ;GAAkB;GAAU;;AAI/C,KACE,OAAO,KACP,SAAS,MAAM,OAAO,aACtB,SAAS,MAAM,OAAO,SACtB;EACA,MAAM,WAAW,uBAAuB,SAAS,MAAM,GAAI;AAC3D,MAAI,CAAC,SAAU,QAAO;AACtB,SAAO;GAAE,QAAQ;GAAiB;GAAU;;AAI9C,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,QAEtB,QAAO,EAAE,QAAQ,iBAAiB;AAIpC,KACE,OAAO,KACP,SAAS,MAAM,OAAO,aACtB,SAAS,MAAM,OAAO,eACtB,SAAS,MAAM,OAAO,SACtB;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;AAInC,KACE,OAAO,KACP,SAAS,MAAM,OAAO,cACtB,SAAS,MAAM,OAAO,YAEtB,QAAO,EAAE,QAAQ,sBAAsB;AAKzC,KACE,OAAO,KACP,SAAS,MAAM,OAAO,cACtB,SAAS,MAAM,OAAO,aACtB;EACA,MAAM,WAAW,uBAAuB,SAAS,MAAM,GAAI;AAC3D,MAAI,CAAC,SAAU,QAAO;AACtB,SAAO;GAAE,QAAQ;GAAmB;GAAU;;AAIhD,KAAI,OAAO,KAAK,SAAS,MAAM,OAAO,WACpC,QAAO,EAAE,QAAQ,iBAAiB;AAIpC,KAAI,OAAO,KAAK,SAAS,MAAM,OAAO,WACpC,QAAO,EAAE,QAAQ,YAAY;AAG/B,QAAO"}
|
|
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/suggest (3 segments)\n if (\n len >= 3 &&\n segments[len - 3] === \"agent\" &&\n segments[len - 1] === \"suggest\"\n ) {\n const agentId = safeDecodeURIComponent(segments[len - 2]!);\n if (!agentId) return null;\n return { method: \"agent/suggest\", 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/events (3 segments)\n if (\n len >= 3 &&\n segments[len - 3] === \"threads\" &&\n segments[len - 1] === \"events\"\n ) {\n const threadId = safeDecodeURIComponent(segments[len - 2]!);\n if (!threadId) return null;\n return { method: \"threads/events\", threadId };\n }\n\n // /threads/:threadId/state (3 segments)\n if (\n len >= 3 &&\n segments[len - 3] === \"threads\" &&\n segments[len - 1] === \"state\"\n ) {\n const threadId = safeDecodeURIComponent(segments[len - 2]!);\n if (!threadId) return null;\n return { method: \"threads/state\", 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/clear (2 segments) — wipe in-memory thread history\n if (\n len >= 2 &&\n segments[len - 2] === \"threads\" &&\n segments[len - 1] === \"clear\"\n ) {\n return { method: \"threads/clear\" };\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 segments[len - 1] !== \"clear\"\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 // /memories/recall (2 segments) — semantic recall (POST). Must precede the\n // /memories/:id mutate rule below, which would otherwise capture \"recall\".\n if (\n len >= 2 &&\n segments[len - 2] === \"memories\" &&\n segments[len - 1] === \"recall\"\n ) {\n return { method: \"memories/recall\" };\n }\n\n // /memories/subscribe (2 segments) — mint memory-realtime join credentials.\n if (\n len >= 2 &&\n segments[len - 2] === \"memories\" &&\n segments[len - 1] === \"subscribe\"\n ) {\n return { method: \"memories/subscribe\" };\n }\n\n // /memories/:id (2 segments) — supersede (PATCH) or retire (DELETE).\n // Disambiguated by HTTP method in the handler.\n if (\n len >= 2 &&\n segments[len - 2] === \"memories\" &&\n segments[len - 1] !== \"subscribe\"\n ) {\n const memoryId = safeDecodeURIComponent(segments[len - 1]!);\n if (!memoryId) return null;\n return { method: \"memories/mutate\", memoryId };\n }\n\n // /memories (1 segment) — GET lists; POST creates.\n if (len >= 1 && segments[len - 1] === \"memories\") {\n return { method: \"memories/list\" };\n }\n\n // /annotate (1 segment) — annotate a thread event\n if (len >= 1 && segments[len - 1] === \"annotate\") {\n return { method: \"annotate\" };\n }\n\n return null;\n}\n"],"mappings":"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"}
|
|
@@ -111,6 +111,7 @@ function matchSegments(path) {
|
|
|
111
111
|
};
|
|
112
112
|
}
|
|
113
113
|
if (len >= 1 && segments[len - 1] === "threads") return { method: "threads/list" };
|
|
114
|
+
if (len >= 2 && segments[len - 2] === "memories" && segments[len - 1] === "recall") return { method: "memories/recall" };
|
|
114
115
|
if (len >= 2 && segments[len - 2] === "memories" && segments[len - 1] === "subscribe") return { method: "memories/subscribe" };
|
|
115
116
|
if (len >= 2 && segments[len - 2] === "memories" && segments[len - 1] !== "subscribe") {
|
|
116
117
|
const memoryId = safeDecodeURIComponent(segments[len - 1]);
|
|
@@ -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 // /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/suggest (3 segments)\n if (\n len >= 3 &&\n segments[len - 3] === \"agent\" &&\n segments[len - 1] === \"suggest\"\n ) {\n const agentId = safeDecodeURIComponent(segments[len - 2]!);\n if (!agentId) return null;\n return { method: \"agent/suggest\", 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/events (3 segments)\n if (\n len >= 3 &&\n segments[len - 3] === \"threads\" &&\n segments[len - 1] === \"events\"\n ) {\n const threadId = safeDecodeURIComponent(segments[len - 2]!);\n if (!threadId) return null;\n return { method: \"threads/events\", threadId };\n }\n\n // /threads/:threadId/state (3 segments)\n if (\n len >= 3 &&\n segments[len - 3] === \"threads\" &&\n segments[len - 1] === \"state\"\n ) {\n const threadId = safeDecodeURIComponent(segments[len - 2]!);\n if (!threadId) return null;\n return { method: \"threads/state\", 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/clear (2 segments) — wipe in-memory thread history\n if (\n len >= 2 &&\n segments[len - 2] === \"threads\" &&\n segments[len - 1] === \"clear\"\n ) {\n return { method: \"threads/clear\" };\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 segments[len - 1] !== \"clear\"\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 // /memories/subscribe (2 segments) — mint memory-realtime join credentials.\n if (\n len >= 2 &&\n segments[len - 2] === \"memories\" &&\n segments[len - 1] === \"subscribe\"\n ) {\n return { method: \"memories/subscribe\" };\n }\n\n // /memories/:id (2 segments) — supersede (PATCH) or retire (DELETE).\n // Disambiguated by HTTP method in the handler.\n if (\n len >= 2 &&\n segments[len - 2] === \"memories\" &&\n segments[len - 1] !== \"subscribe\"\n ) {\n const memoryId = safeDecodeURIComponent(segments[len - 1]!);\n if (!memoryId) return null;\n return { method: \"memories/mutate\", memoryId };\n }\n\n // /memories (1 segment) — GET lists; POST creates.\n if (len >= 1 && segments[len - 1] === \"memories\") {\n return { method: \"memories/list\" };\n }\n\n // /annotate (1 segment) — annotate a thread event\n if (len >= 1 && segments[len - 1] === \"annotate\") {\n return { method: \"annotate\" };\n }\n\n return null;\n}\n"],"mappings":"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"}
|
|
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/suggest (3 segments)\n if (\n len >= 3 &&\n segments[len - 3] === \"agent\" &&\n segments[len - 1] === \"suggest\"\n ) {\n const agentId = safeDecodeURIComponent(segments[len - 2]!);\n if (!agentId) return null;\n return { method: \"agent/suggest\", 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/events (3 segments)\n if (\n len >= 3 &&\n segments[len - 3] === \"threads\" &&\n segments[len - 1] === \"events\"\n ) {\n const threadId = safeDecodeURIComponent(segments[len - 2]!);\n if (!threadId) return null;\n return { method: \"threads/events\", threadId };\n }\n\n // /threads/:threadId/state (3 segments)\n if (\n len >= 3 &&\n segments[len - 3] === \"threads\" &&\n segments[len - 1] === \"state\"\n ) {\n const threadId = safeDecodeURIComponent(segments[len - 2]!);\n if (!threadId) return null;\n return { method: \"threads/state\", 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/clear (2 segments) — wipe in-memory thread history\n if (\n len >= 2 &&\n segments[len - 2] === \"threads\" &&\n segments[len - 1] === \"clear\"\n ) {\n return { method: \"threads/clear\" };\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 segments[len - 1] !== \"clear\"\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 // /memories/recall (2 segments) — semantic recall (POST). Must precede the\n // /memories/:id mutate rule below, which would otherwise capture \"recall\".\n if (\n len >= 2 &&\n segments[len - 2] === \"memories\" &&\n segments[len - 1] === \"recall\"\n ) {\n return { method: \"memories/recall\" };\n }\n\n // /memories/subscribe (2 segments) — mint memory-realtime join credentials.\n if (\n len >= 2 &&\n segments[len - 2] === \"memories\" &&\n segments[len - 1] === \"subscribe\"\n ) {\n return { method: \"memories/subscribe\" };\n }\n\n // /memories/:id (2 segments) — supersede (PATCH) or retire (DELETE).\n // Disambiguated by HTTP method in the handler.\n if (\n len >= 2 &&\n segments[len - 2] === \"memories\" &&\n segments[len - 1] !== \"subscribe\"\n ) {\n const memoryId = safeDecodeURIComponent(segments[len - 1]!);\n if (!memoryId) return null;\n return { method: \"memories/mutate\", memoryId };\n }\n\n // /memories (1 segment) — GET lists; POST creates.\n if (len >= 1 && segments[len - 1] === \"memories\") {\n return { method: \"memories/list\" };\n }\n\n // /annotate (1 segment) — annotate a thread event\n if (len >= 1 && segments[len - 1] === \"annotate\") {\n return { method: \"annotate\" };\n }\n\n return null;\n}\n"],"mappings":"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"}
|
|
@@ -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/suggest\"; 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: \"threads/events\"; threadId: string }\n | { method: \"threads/state\"; threadId: string }\n | { method: \"threads/clear\" }\n | { method: \"memories/list\" }\n | { method: \"memories/subscribe\" }\n | { method: \"memories/mutate\"; memoryId: string }\n | { method: \"annotate\" }\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":";;;
|
|
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/suggest\"; 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: \"threads/events\"; threadId: string }\n | { method: \"threads/state\"; threadId: string }\n | { method: \"threads/clear\" }\n | { method: \"memories/list\" }\n | { method: \"memories/recall\" }\n | { method: \"memories/subscribe\" }\n | { method: \"memories/mutate\"; memoryId: string }\n | { method: \"annotate\" }\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":";;;AAoIA,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;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;EAA0B,QAAA;AAAA;EAC1B,MAAA;EAAyB,QAAA;AAAA;EACzB,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;EAA2B,QAAA;AAAA;EAC3B,MAAA;AAAA;EACA,MAAA;AAAA;AAAA,UAMW,WAAA;
|
|
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;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;EAA0B,QAAA;AAAA;EAC1B,MAAA;EAAyB,QAAA;AAAA;EACzB,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;EAA2B,QAAA;AAAA;EAC3B,MAAA;AAAA;EACA,MAAA;AAAA;AAAA,UAMW,WAAA;EAyBf;EAvBA,OAAA,EAAS,OAAA;EAuBQ;EArBjB,IAAA;EA4Be;EA1Bf,OAAA,EAAS,kBAAA;AAAA;AAAA,UAGM,kBAAA,SAA2B,WAAA;EA+BK;EA7B/C,KAAA,EAAO,SAAA;AAAA;AAAA,UAGQ,mBAAA,SAA4B,WAAA;EAoCI;EAlC/C,QAAA,EAAU,QAAA;EA0C8C;EAxCxD,KAAA,EAAO,SAAA;AAAA;AAAA,UAGQ,gBAAA,SAAyB,WAAA;EA2CH;EAzCrC,KAAA;EAyCiD;EAvCjD,KAAA,GAAQ,SAAA;AAAA;AAAA,UAOO,mBAAA;EAQmB;;;;;;;EAAlC,SAAA,IAAa,GAAA,EAAK,WAAA,KAAgB,YAAA,CAAa,OAAA;EAkB5B;;;;;;;;EARnB,eAAA,IAAmB,GAAA,EAAK,kBAAA,KAAuB,YAAA,CAAa,OAAA;EAcF;;;;;;EAN1D,UAAA,IAAc,GAAA,EAAK,mBAAA,KAAwB,YAAA,CAAa,QAAA;;;;;EAMxD,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;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;EAA0B,QAAA;AAAA;EAC1B,MAAA;EAAyB,QAAA;AAAA;EACzB,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;EAA2B,QAAA;AAAA;EAC3B,MAAA;AAAA;EACA,MAAA;AAAA;AAAA,UAMW,WAAA;
|
|
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;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;EAA0B,QAAA;AAAA;EAC1B,MAAA;EAAyB,QAAA;AAAA;EACzB,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;AAAA;EACA,MAAA;EAA2B,QAAA;AAAA;EAC3B,MAAA;AAAA;EACA,MAAA;AAAA;AAAA,UAMW,WAAA;EAyBf;EAvBA,OAAA,EAAS,OAAA;EAuBQ;EArBjB,IAAA;EA4Be;EA1Bf,OAAA,EAAS,kBAAA;AAAA;AAAA,UAGM,kBAAA,SAA2B,WAAA;EA+BK;EA7B/C,KAAA,EAAO,SAAA;AAAA;AAAA,UAGQ,mBAAA,SAA4B,WAAA;EAoCI;EAlC/C,QAAA,EAAU,QAAA;EA0C8C;EAxCxD,KAAA,EAAO,SAAA;AAAA;AAAA,UAGQ,gBAAA,SAAyB,WAAA;EA2CH;EAzCrC,KAAA;EAyCiD;EAvCjD,KAAA,GAAQ,SAAA;AAAA;AAAA,UAOO,mBAAA;EAQmB;;;;;;;EAAlC,SAAA,IAAa,GAAA,EAAK,WAAA,KAAgB,YAAA,CAAa,OAAA;EAkB5B;;;;;;;;EARnB,eAAA,IAAmB,GAAA,EAAK,kBAAA,KAAuB,YAAA,CAAa,OAAA;EAcF;;;;;;EAN1D,UAAA,IAAc,GAAA,EAAK,mBAAA,KAAwB,YAAA,CAAa,QAAA;;;;;EAMxD,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/suggest\"; 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: \"threads/events\"; threadId: string }\n | { method: \"threads/state\"; threadId: string }\n | { method: \"threads/clear\" }\n | { method: \"memories/list\" }\n | { method: \"memories/subscribe\" }\n | { method: \"memories/mutate\"; memoryId: string }\n | { method: \"annotate\" }\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":";;
|
|
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/suggest\"; 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: \"threads/events\"; threadId: string }\n | { method: \"threads/state\"; threadId: string }\n | { method: \"threads/clear\" }\n | { method: \"memories/list\" }\n | { method: \"memories/recall\" }\n | { method: \"memories/subscribe\" }\n | { method: \"memories/mutate\"; memoryId: string }\n | { method: \"annotate\" }\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":";;AAoIA,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"}
|
|
@@ -42,6 +42,7 @@ var BaseCopilotRuntime = class {
|
|
|
42
42
|
if (this.resolvedLicenseToken) require_telemetry_client.default.setLicenseToken(this.resolvedLicenseToken);
|
|
43
43
|
if (process.env.NODE_ENV !== "production") this.debugEventBus = new require_debug_event_bus.DebugEventBus();
|
|
44
44
|
this.forwardHeadersPolicy = require_header_utils.resolveForwardHeadersPolicy(options.forwardHeaders);
|
|
45
|
+
this.exposeMemoryRoutes = options.exposeMemoryRoutes ?? false;
|
|
45
46
|
this.debug = (0, _copilotkit_shared.resolveDebugConfig)(options.debug);
|
|
46
47
|
if (this.debug.enabled) this.debugLogger = require_logger.createLogger({
|
|
47
48
|
level: "debug",
|
|
@@ -178,6 +179,9 @@ var CopilotRuntimeShim = class {
|
|
|
178
179
|
get forwardHeadersPolicy() {
|
|
179
180
|
return this.delegate.forwardHeadersPolicy;
|
|
180
181
|
}
|
|
182
|
+
get exposeMemoryRoutes() {
|
|
183
|
+
return this.delegate.exposeMemoryRoutes;
|
|
184
|
+
}
|
|
181
185
|
};
|
|
182
186
|
/**
|
|
183
187
|
* The public `CopilotRuntime` constructor. Backed by {@link CopilotRuntimeShim}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.cjs","names":["pkg","DebugEventBus","resolveForwardHeadersPolicy","createLogger","InMemoryAgentRunner","RUNTIME_MODE_SSE","IntelligenceAgentRunner","RUNTIME_MODE_INTELLIGENCE"],"sources":["../../../../src/v2/runtime/core/runtime.ts"],"sourcesContent":["import type {\n MaybePromise,\n NonEmptyRecord,\n RuntimeMode,\n} from \"@copilotkit/shared\";\nimport {\n RUNTIME_MODE_SSE,\n RUNTIME_MODE_INTELLIGENCE,\n} from \"@copilotkit/shared\";\nimport { createLicenseChecker } from \"@copilotkit/license-verifier\";\nimport type { LicenseChecker } from \"@copilotkit/license-verifier\";\nimport { resolveDebugConfig } from \"@copilotkit/shared\";\nimport type { ResolvedDebugConfig, DebugConfig } from \"@copilotkit/shared\";\nimport { resolveForwardHeadersPolicy } from \"../handlers/header-utils\";\nimport type {\n ForwardHeadersConfig,\n ResolvedForwardHeadersPolicy,\n} from \"../handlers/header-utils\";\nimport type { AbstractAgent } from \"@ag-ui/client\";\nimport type { MCPClientConfig } from \"@ag-ui/mcp-apps-middleware\";\nimport type { A2UIMiddlewareConfig } from \"@ag-ui/a2ui-middleware\";\nimport pkg from \"../../../../package.json\";\nimport type {\n BeforeRequestMiddleware,\n AfterRequestMiddleware,\n} from \"./middleware\";\nimport { createLogger } from \"../../../lib/logger\";\nimport type { CopilotRuntimeLogger } from \"../../../lib/logger\";\nimport { logRuntimeTelemetryDisclosure } from \"../../../lib/telemetry-disclosure\";\nimport type { TranscriptionService } from \"../transcription-service/transcription-service\";\nimport { DebugEventBus } from \"./debug-event-bus\";\nimport type { AgentRunner } from \"../runner/agent-runner\";\nimport { InMemoryAgentRunner } from \"../runner/in-memory\";\nimport { IntelligenceAgentRunner } from \"../runner/intelligence\";\nimport type { CopilotKitIntelligence } from \"../intelligence-platform\";\n// Type-only: @copilotkit/channels-core is the pure-ESM type source, so a value import would break this\n// package's CJS output. The channels are validated + activated (wired to delivery\n// transports) by `startChannels` from @copilotkit/channels-intelligence, called\n// by the Channel-listener bootstrap — not here.\nimport type { Channel } from \"@copilotkit/channels-core\";\nimport telemetry from \"../telemetry/telemetry-client\";\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 &\n A2UIMiddlewareConfig & {\n /**\n * Explicit on/off switch. Omit (or set `true`) to enable; set `false`\n * to disable A2UI for this runtime while keeping the rest of the config\n * (e.g. a `schema`/`catalog`) in place. A bare `a2ui: {}` stays enabled\n * for backwards compatibility.\n */\n enabled?: boolean;\n };\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 * Policy controlling which inbound HTTP headers are forwarded onto the\n * outgoing agent call. By default a built-in denylist strips known\n * infrastructure/proxy/platform headers (`x-forwarded-*`, `x-real-ip`,\n * `x-vercel-*`, `x-copilotcloud-*`, etc.) while `authorization` and custom\n * `x-*` application headers continue to forward (#5712). Set\n * `{ useDefaultDenylist: false }` to restore the previous wide-open behavior.\n */\n forwardHeaders?: ForwardHeadersConfig;\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 /** Intelligence Channels require the Intelligence runtime; not available in SSE mode. */\n channels?: 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 * Intelligence Channels declared by this runtime. Each is a\n * `createChannel({ name })` instance. Only available on the Intelligence runtime\n * path. Names are validated (required, lowercase kebab-case, unique) and wired\n * to delivery/egress transports when activated via `startChannels` from\n * `@copilotkit/channels-intelligence` — not at construction.\n */\n channels?: Channel[];\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 * Resolved inbound-header forwarding policy read by the /run and /connect call\n * sites. Optional on the published interface so an external `CopilotRuntimeLike`\n * implementor predating this field stays source-compatible (non-breaking minor\n * release). Concrete runtimes (`BaseCopilotRuntime`) always resolve and set it;\n * the call sites coalesce a missing value to the default resolved policy\n * (`resolveForwardHeadersPolicy(undefined)` — default-on denylist).\n */\n forwardHeadersPolicy?: ResolvedForwardHeadersPolicy;\n}\n\nexport interface CopilotSseRuntimeLike extends CopilotRuntimeLike {\n intelligence?: undefined;\n mode: typeof 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 channels: Channel[];\n mode: typeof 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 public readonly forwardHeadersPolicy: ResolvedForwardHeadersPolicy;\n\n /**\n * License token resolved once with the env fallback, so telemetry\n * attribution (below) and subclass feature gating\n * (CopilotIntelligenceRuntime's licenseChecker) read the exact same value\n * instead of each re-applying `?? COPILOTKIT_LICENSE_TOKEN`.\n */\n protected readonly resolvedLicenseToken?: string;\n\n abstract readonly intelligence?: CopilotKitIntelligence;\n abstract readonly mode: RuntimeMode;\n\n constructor(options: BaseCopilotRuntimeOptions, runner: AgentRunner) {\n logRuntimeTelemetryDisclosure();\n\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 // Resolve the license token once (matching the license-verifier's env\n // fallback) so telemetry attribution and subclass feature gating share\n // one value.\n this.resolvedLicenseToken =\n options.licenseToken ?? process.env.COPILOTKIT_LICENSE_TOKEN;\n\n // Attribute telemetry to the licensed customer for *every* runtime mode.\n // Done in the shared base (not the subclasses) so SSE and Intelligence\n // runtimes behave identically — previously only CopilotIntelligenceRuntime\n // set this, so self-hosted SSE users never got a telemetry_id on their\n // runtime events even with a license token configured.\n if (this.resolvedLicenseToken) {\n telemetry.setLicenseToken(this.resolvedLicenseToken);\n }\n\n if (process.env.NODE_ENV !== \"production\") {\n this.debugEventBus = new DebugEventBus();\n }\n // Resolve the inbound-header forwarding policy once (mirroring the\n // `debug` → `ResolvedDebugConfig` resolve-once above) so both the /run and\n // /connect call sites read the exact same resolved policy off the runtime\n // and can never diverge.\n this.forwardHeadersPolicy = resolveForwardHeadersPolicy(\n options.forwardHeaders,\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 // Runtime guard mirroring the discriminated-union type: the SSE runtime has\n // no Intelligence delivery path, so `channels` cannot be honored here. The\n // type forbids it, but a JS / `as any` caller passing `{ agents, channels }`\n // would otherwise land here and have `channels` silently dropped — fail\n // loud instead.\n const channels = (options as { channels?: unknown[] }).channels;\n if (Array.isArray(channels) && channels.length > 0) {\n throw new Error(\n \"`channels` requires the Intelligence runtime (pass `intelligence`); \" +\n \"Intelligence Channels are not available in SSE mode.\",\n );\n }\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 channels: Channel[];\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 // Telemetry attribution is handled by the base constructor for all modes;\n // here we only need the token for feature gating. Reuse the base-resolved\n // value so gating and attribution can never disagree.\n this.licenseChecker = createLicenseChecker(this.resolvedLicenseToken);\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 // Declared Intelligence Channels. Lowercase kebab-case name-shape validation\n // (`assertValidChannelNames`) lives in the channels-intelligence launcher —\n // it can't run here because it's a value import from the pure-ESM\n // `@copilotkit/channels-intelligence`, which this CJS package must not pull in.\n // Name UNIQUENESS across declared Channels is enforced by\n // `ChannelManager.activate()`, not the launcher: the managed path activates\n // one Channel per launcher call, so the launcher never sees the full set.\n // Fail fast on the most common misconfiguration (a missing name) right here\n // at construction, though, rather than only at activation.\n this.channels = options.channels ?? [];\n for (const c of this.channels) {\n if (!c.name) {\n throw new Error(\n \"Intelligence Channel is missing a `name` — pass createChannel({ name }) for each Channel in `channels`\",\n );\n }\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 * Single source of truth for \"is A2UI on for this runtime?\". Both the run path\n * (which applies `A2UIMiddleware`) and the `/info` response (which tells the\n * client whether to mount the A2UI renderer + catalog context) MUST go through\n * this, so they can never disagree — the divergence between them was the root\n * of CopilotKit/CopilotKit#5369.\n *\n * Backwards compatible: any config object is enabled (matching the historical\n * `!!runtime.a2ui`); only an explicit `enabled: false` turns it off.\n */\nexport function isA2UIEnabled(\n a2ui: CopilotRuntimeOptions[\"a2ui\"],\n): a2ui is NonNullable<CopilotRuntimeOptions[\"a2ui\"]> {\n return !!a2ui && a2ui.enabled !== false;\n}\n\n/**\n * Compile-time phantom brand marking a {@link CopilotRuntime} that was\n * constructed with at least one declared Intelligence Channel. It has no runtime\n * representation — the shim never sets this property; it exists purely so\n * `createCopilotRuntimeHandler` can tell, at the type level, that the resulting\n * handler will carry a non-optional `.channels` control surface.\n */\nexport interface RuntimeWithDeclaredChannels {\n /**\n * @internal Phantom brand key. Never present at runtime; do not read or set.\n */\n readonly __copilotkitChannelsDeclared: true;\n}\n\n/**\n * Instance shape of the {@link CopilotRuntime} compatibility shim. Extends\n * {@link CopilotRuntimeLike} with the Intelligence-only accessors the shim\n * surfaces (all `undefined` in SSE mode). Declared explicitly so the exported\n * `CopilotRuntime` name resolves as a type as well as a value.\n */\nexport interface CopilotRuntime extends CopilotRuntimeLike {\n /** Auto-generate short thread names; `undefined` in SSE mode. */\n generateThreadNames?: boolean;\n /** Thread lock TTL in seconds; `undefined` in SSE mode. */\n lockTtlSeconds?: number;\n /** Custom Redis key prefix for the thread lock; `undefined` in SSE mode. */\n lockKeyPrefix?: string;\n /** Thread lock heartbeat interval in seconds; `undefined` in SSE mode. */\n lockHeartbeatIntervalSeconds?: number;\n /** Declared Intelligence Channels; `undefined` in SSE mode. */\n channels?: Channel[];\n}\n\n/**\n * Constructor type for the {@link CopilotRuntime} compatibility shim.\n *\n * The first overload fires when the caller passes `intelligence` together with a\n * non-empty `channels` tuple: it returns a {@link RuntimeWithDeclaredChannels}-\n * branded runtime, which `createCopilotRuntimeHandler` maps to a handler whose\n * `.channels` is non-optional. Every other configuration (SSE, or Intelligence\n * without channels, or an empty `channels: []`) falls through to the second\n * overload and stays unbranded, so its handler keeps `.channels` optional.\n *\n * A class constructor cannot vary its return type across overloads (it is pinned\n * to the instance type), so the branding lives on this construct-signature\n * interface instead of on the class itself.\n */\nexport interface CopilotRuntimeConstructor {\n new (\n options: Omit<CopilotIntelligenceRuntimeOptions, \"channels\"> & {\n channels: readonly [Channel, ...Channel[]];\n },\n ): CopilotRuntime & RuntimeWithDeclaredChannels;\n new (options: CopilotRuntimeOptions): CopilotRuntime;\n}\n\n/**\n * Compatibility shim that preserves the legacy `CopilotRuntime` entrypoint.\n * New code should prefer `CopilotSseRuntime` or `CopilotIntelligenceRuntime`.\n *\n * Exported to consumers as the {@link CopilotRuntime} value (typed as\n * {@link CopilotRuntimeConstructor}) rather than as a class, so that the\n * channel-presence brand can flow from construction into the handler type.\n */\nclass CopilotRuntimeShim implements CopilotRuntime {\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 channels(): Channel[] | undefined {\n return isIntelligenceRuntime(this.delegate)\n ? this.delegate.channels\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 get forwardHeadersPolicy(): ResolvedForwardHeadersPolicy {\n return this.delegate.forwardHeadersPolicy;\n }\n}\n\n/**\n * The public `CopilotRuntime` constructor. Backed by {@link CopilotRuntimeShim}\n * but typed as {@link CopilotRuntimeConstructor} so that constructing with a\n * non-empty `channels` array yields a {@link RuntimeWithDeclaredChannels}-branded\n * runtime type.\n *\n * The `as unknown as` cast is required (not dishonest widening): the brand is a\n * phantom, compile-time-only marker with no runtime representation, so the shim\n * instances legitimately do not carry the brand property. Behavior is identical\n * to the former `class CopilotRuntime` — this only refines the static type.\n */\nexport const CopilotRuntime: CopilotRuntimeConstructor =\n CopilotRuntimeShim as unknown as CopilotRuntimeConstructor;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"runtime.cjs","names":["pkg","DebugEventBus","resolveForwardHeadersPolicy","createLogger","InMemoryAgentRunner","RUNTIME_MODE_SSE","IntelligenceAgentRunner","RUNTIME_MODE_INTELLIGENCE"],"sources":["../../../../src/v2/runtime/core/runtime.ts"],"sourcesContent":["import type {\n MaybePromise,\n NonEmptyRecord,\n RuntimeMode,\n} from \"@copilotkit/shared\";\nimport {\n RUNTIME_MODE_SSE,\n RUNTIME_MODE_INTELLIGENCE,\n} from \"@copilotkit/shared\";\nimport { createLicenseChecker } from \"@copilotkit/license-verifier\";\nimport type { LicenseChecker } from \"@copilotkit/license-verifier\";\nimport { resolveDebugConfig } from \"@copilotkit/shared\";\nimport type { ResolvedDebugConfig, DebugConfig } from \"@copilotkit/shared\";\nimport { resolveForwardHeadersPolicy } from \"../handlers/header-utils\";\nimport type {\n ForwardHeadersConfig,\n ResolvedForwardHeadersPolicy,\n} from \"../handlers/header-utils\";\nimport type { AbstractAgent } from \"@ag-ui/client\";\nimport type { MCPClientConfig } from \"@ag-ui/mcp-apps-middleware\";\nimport type { A2UIMiddlewareConfig } from \"@ag-ui/a2ui-middleware\";\nimport pkg from \"../../../../package.json\";\nimport type {\n BeforeRequestMiddleware,\n AfterRequestMiddleware,\n} from \"./middleware\";\nimport { createLogger } from \"../../../lib/logger\";\nimport type { CopilotRuntimeLogger } from \"../../../lib/logger\";\nimport { logRuntimeTelemetryDisclosure } from \"../../../lib/telemetry-disclosure\";\nimport type { TranscriptionService } from \"../transcription-service/transcription-service\";\nimport { DebugEventBus } from \"./debug-event-bus\";\nimport type { AgentRunner } from \"../runner/agent-runner\";\nimport { InMemoryAgentRunner } from \"../runner/in-memory\";\nimport { IntelligenceAgentRunner } from \"../runner/intelligence\";\nimport type { CopilotKitIntelligence } from \"../intelligence-platform\";\n// Type-only: @copilotkit/channels-core is the pure-ESM type source, so a value import would break this\n// package's CJS output. The channels are validated + activated (wired to delivery\n// transports) by `startChannels` from @copilotkit/channels-intelligence, called\n// by the Channel-listener bootstrap — not here.\nimport type { Channel } from \"@copilotkit/channels-core\";\nimport telemetry from \"../telemetry/telemetry-client\";\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 &\n A2UIMiddlewareConfig & {\n /**\n * Explicit on/off switch. Omit (or set `true`) to enable; set `false`\n * to disable A2UI for this runtime while keeping the rest of the config\n * (e.g. a `schema`/`catalog`) in place. A bare `a2ui: {}` stays enabled\n * for backwards compatibility.\n */\n enabled?: boolean;\n };\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 * Policy controlling which inbound HTTP headers are forwarded onto the\n * outgoing agent call. By default a built-in denylist strips known\n * infrastructure/proxy/platform headers (`x-forwarded-*`, `x-real-ip`,\n * `x-vercel-*`, `x-copilotcloud-*`, etc.) while `authorization` and custom\n * `x-*` application headers continue to forward (#5712). Set\n * `{ useDefaultDenylist: false }` to restore the previous wide-open behavior.\n */\n forwardHeaders?: ForwardHeadersConfig;\n /**\n * Opt-in flag exposing the client-facing memory proxy routes\n * (`/memories`, `/memories/recall`, `/memories/subscribe`, `/memories/:id`).\n *\n * Defaults to `false` — a **secure default**. When off, every `/memories/*`\n * request 404s as if the route did not exist, so an un-opted-in deployment\n * reveals nothing about memory even when Intelligence is configured. This does\n * NOT affect the agent's own server-side memory tooling (`recall_memory` runs\n * via the Intelligence MCP path, separate from this client REST proxy).\n *\n * Flip to `true` to power a client memory inspector (e.g. the dev console's\n * Memory tab). Existing Intelligence deployments relying on the previously\n * always-on Learning tab must set this to restore it.\n */\n exposeMemoryRoutes?: boolean;\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 /** Intelligence Channels require the Intelligence runtime; not available in SSE mode. */\n channels?: 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 * Intelligence Channels declared by this runtime. Each is a\n * `createChannel({ name })` instance. Only available on the Intelligence runtime\n * path. Names are validated (required, lowercase kebab-case, unique) and wired\n * to delivery/egress transports when activated via `startChannels` from\n * `@copilotkit/channels-intelligence` — not at construction.\n */\n channels?: Channel[];\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 * Resolved inbound-header forwarding policy read by the /run and /connect call\n * sites. Optional on the published interface so an external `CopilotRuntimeLike`\n * implementor predating this field stays source-compatible (non-breaking minor\n * release). Concrete runtimes (`BaseCopilotRuntime`) always resolve and set it;\n * the call sites coalesce a missing value to the default resolved policy\n * (`resolveForwardHeadersPolicy(undefined)` — default-on denylist).\n */\n forwardHeadersPolicy?: ResolvedForwardHeadersPolicy;\n /**\n * Resolved opt-in flag for the client-facing memory proxy routes. Optional on\n * the published interface so an external `CopilotRuntimeLike` implementor\n * predating this field stays source-compatible; the dispatcher coalesces a\n * missing value to `false` (secure default — routes hidden). Concrete runtimes\n * (`BaseCopilotRuntime`) always resolve and set it.\n */\n exposeMemoryRoutes?: boolean;\n}\n\nexport interface CopilotSseRuntimeLike extends CopilotRuntimeLike {\n intelligence?: undefined;\n mode: typeof 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 channels: Channel[];\n mode: typeof 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 public readonly forwardHeadersPolicy: ResolvedForwardHeadersPolicy;\n public readonly exposeMemoryRoutes: boolean;\n\n /**\n * License token resolved once with the env fallback, so telemetry\n * attribution (below) and subclass feature gating\n * (CopilotIntelligenceRuntime's licenseChecker) read the exact same value\n * instead of each re-applying `?? COPILOTKIT_LICENSE_TOKEN`.\n */\n protected readonly resolvedLicenseToken?: string;\n\n abstract readonly intelligence?: CopilotKitIntelligence;\n abstract readonly mode: RuntimeMode;\n\n constructor(options: BaseCopilotRuntimeOptions, runner: AgentRunner) {\n logRuntimeTelemetryDisclosure();\n\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 // Resolve the license token once (matching the license-verifier's env\n // fallback) so telemetry attribution and subclass feature gating share\n // one value.\n this.resolvedLicenseToken =\n options.licenseToken ?? process.env.COPILOTKIT_LICENSE_TOKEN;\n\n // Attribute telemetry to the licensed customer for *every* runtime mode.\n // Done in the shared base (not the subclasses) so SSE and Intelligence\n // runtimes behave identically — previously only CopilotIntelligenceRuntime\n // set this, so self-hosted SSE users never got a telemetry_id on their\n // runtime events even with a license token configured.\n if (this.resolvedLicenseToken) {\n telemetry.setLicenseToken(this.resolvedLicenseToken);\n }\n\n if (process.env.NODE_ENV !== \"production\") {\n this.debugEventBus = new DebugEventBus();\n }\n // Resolve the inbound-header forwarding policy once (mirroring the\n // `debug` → `ResolvedDebugConfig` resolve-once above) so both the /run and\n // /connect call sites read the exact same resolved policy off the runtime\n // and can never diverge.\n this.forwardHeadersPolicy = resolveForwardHeadersPolicy(\n options.forwardHeaders,\n );\n // Secure default: the client-facing memory proxy routes stay hidden (404)\n // unless a deployment explicitly opts in.\n this.exposeMemoryRoutes = options.exposeMemoryRoutes ?? false;\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 // Runtime guard mirroring the discriminated-union type: the SSE runtime has\n // no Intelligence delivery path, so `channels` cannot be honored here. The\n // type forbids it, but a JS / `as any` caller passing `{ agents, channels }`\n // would otherwise land here and have `channels` silently dropped — fail\n // loud instead.\n const channels = (options as { channels?: unknown[] }).channels;\n if (Array.isArray(channels) && channels.length > 0) {\n throw new Error(\n \"`channels` requires the Intelligence runtime (pass `intelligence`); \" +\n \"Intelligence Channels are not available in SSE mode.\",\n );\n }\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 channels: Channel[];\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 // Telemetry attribution is handled by the base constructor for all modes;\n // here we only need the token for feature gating. Reuse the base-resolved\n // value so gating and attribution can never disagree.\n this.licenseChecker = createLicenseChecker(this.resolvedLicenseToken);\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 // Declared Intelligence Channels. Lowercase kebab-case name-shape validation\n // (`assertValidChannelNames`) lives in the channels-intelligence launcher —\n // it can't run here because it's a value import from the pure-ESM\n // `@copilotkit/channels-intelligence`, which this CJS package must not pull in.\n // Name UNIQUENESS across declared Channels is enforced by\n // `ChannelManager.activate()`, not the launcher: the managed path activates\n // one Channel per launcher call, so the launcher never sees the full set.\n // Fail fast on the most common misconfiguration (a missing name) right here\n // at construction, though, rather than only at activation.\n this.channels = options.channels ?? [];\n for (const c of this.channels) {\n if (!c.name) {\n throw new Error(\n \"Intelligence Channel is missing a `name` — pass createChannel({ name }) for each Channel in `channels`\",\n );\n }\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 * Single source of truth for \"is A2UI on for this runtime?\". Both the run path\n * (which applies `A2UIMiddleware`) and the `/info` response (which tells the\n * client whether to mount the A2UI renderer + catalog context) MUST go through\n * this, so they can never disagree — the divergence between them was the root\n * of CopilotKit/CopilotKit#5369.\n *\n * Backwards compatible: any config object is enabled (matching the historical\n * `!!runtime.a2ui`); only an explicit `enabled: false` turns it off.\n */\nexport function isA2UIEnabled(\n a2ui: CopilotRuntimeOptions[\"a2ui\"],\n): a2ui is NonNullable<CopilotRuntimeOptions[\"a2ui\"]> {\n return !!a2ui && a2ui.enabled !== false;\n}\n\n/**\n * Compile-time phantom brand marking a {@link CopilotRuntime} that was\n * constructed with at least one declared Intelligence Channel. It has no runtime\n * representation — the shim never sets this property; it exists purely so\n * `createCopilotRuntimeHandler` can tell, at the type level, that the resulting\n * handler will carry a non-optional `.channels` control surface.\n */\nexport interface RuntimeWithDeclaredChannels {\n /**\n * @internal Phantom brand key. Never present at runtime; do not read or set.\n */\n readonly __copilotkitChannelsDeclared: true;\n}\n\n/**\n * Instance shape of the {@link CopilotRuntime} compatibility shim. Extends\n * {@link CopilotRuntimeLike} with the Intelligence-only accessors the shim\n * surfaces (all `undefined` in SSE mode). Declared explicitly so the exported\n * `CopilotRuntime` name resolves as a type as well as a value.\n */\nexport interface CopilotRuntime extends CopilotRuntimeLike {\n /** Auto-generate short thread names; `undefined` in SSE mode. */\n generateThreadNames?: boolean;\n /** Thread lock TTL in seconds; `undefined` in SSE mode. */\n lockTtlSeconds?: number;\n /** Custom Redis key prefix for the thread lock; `undefined` in SSE mode. */\n lockKeyPrefix?: string;\n /** Thread lock heartbeat interval in seconds; `undefined` in SSE mode. */\n lockHeartbeatIntervalSeconds?: number;\n /** Declared Intelligence Channels; `undefined` in SSE mode. */\n channels?: Channel[];\n}\n\n/**\n * Constructor type for the {@link CopilotRuntime} compatibility shim.\n *\n * The first overload fires when the caller passes `intelligence` together with a\n * non-empty `channels` tuple: it returns a {@link RuntimeWithDeclaredChannels}-\n * branded runtime, which `createCopilotRuntimeHandler` maps to a handler whose\n * `.channels` is non-optional. Every other configuration (SSE, or Intelligence\n * without channels, or an empty `channels: []`) falls through to the second\n * overload and stays unbranded, so its handler keeps `.channels` optional.\n *\n * A class constructor cannot vary its return type across overloads (it is pinned\n * to the instance type), so the branding lives on this construct-signature\n * interface instead of on the class itself.\n */\nexport interface CopilotRuntimeConstructor {\n new (\n options: Omit<CopilotIntelligenceRuntimeOptions, \"channels\"> & {\n channels: readonly [Channel, ...Channel[]];\n },\n ): CopilotRuntime & RuntimeWithDeclaredChannels;\n new (options: CopilotRuntimeOptions): CopilotRuntime;\n}\n\n/**\n * Compatibility shim that preserves the legacy `CopilotRuntime` entrypoint.\n * New code should prefer `CopilotSseRuntime` or `CopilotIntelligenceRuntime`.\n *\n * Exported to consumers as the {@link CopilotRuntime} value (typed as\n * {@link CopilotRuntimeConstructor}) rather than as a class, so that the\n * channel-presence brand can flow from construction into the handler type.\n */\nclass CopilotRuntimeShim implements CopilotRuntime {\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 channels(): Channel[] | undefined {\n return isIntelligenceRuntime(this.delegate)\n ? this.delegate.channels\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 get forwardHeadersPolicy(): ResolvedForwardHeadersPolicy {\n return this.delegate.forwardHeadersPolicy;\n }\n\n get exposeMemoryRoutes(): boolean | undefined {\n return this.delegate.exposeMemoryRoutes;\n }\n}\n\n/**\n * The public `CopilotRuntime` constructor. Backed by {@link CopilotRuntimeShim}\n * but typed as {@link CopilotRuntimeConstructor} so that constructing with a\n * non-empty `channels` array yields a {@link RuntimeWithDeclaredChannels}-branded\n * runtime type.\n *\n * The `as unknown as` cast is required (not dishonest widening): the brand is a\n * phantom, compile-time-only marker with no runtime representation, so the shim\n * instances legitimately do not carry the brand property. Behavior is identical\n * to the former `class CopilotRuntime` — this only refines the static type.\n */\nexport const CopilotRuntime: CopilotRuntimeConstructor =\n CopilotRuntimeShim as unknown as CopilotRuntimeConstructor;\n"],"mappings":"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"}
|