{"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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"}