{"version":3,"file":"express.mjs","names":[],"sources":["../../../../src/v2/runtime/endpoints/express.ts"],"sourcesContent":["import express from \"express\";\nimport type {\n  Request as ExpressRequest,\n  Response as ExpressResponse,\n  NextFunction,\n  Router,\n} from \"express\";\nimport cors from \"cors\";\nimport type { CorsOptions } from \"cors\";\nimport type { CopilotRuntimeLike } from \"../core/runtime\";\nimport { createCopilotRuntimeHandler } from \"../core/fetch-handler\";\nimport { createExpressNodeHandler } from \"./express-fetch-bridge\";\nimport type { CopilotRuntimeHooks } from \"../core/hooks\";\n\nexport interface CopilotExpressEndpointParams {\n  runtime: CopilotRuntimeLike;\n  basePath: string;\n\n  /**\n   * Endpoint mode.\n   * - `\"multi-route\"` (default): separate routes for each operation\n   * - `\"single-route\"`: single POST endpoint with JSON envelope dispatch\n   */\n  mode?: \"multi-route\" | \"single-route\";\n\n  /**\n   * CORS configuration for the Express router.\n   * - `true` (default): permissive CORS (`origin: \"*\"`, all methods, all headers).\n   * - `false`: no CORS middleware is applied — handle it yourself.\n   * - object: passed directly to the Express `cors()` middleware.\n   */\n  cors?: boolean | CorsOptions;\n\n  /**\n   * Lifecycle hooks for request processing.\n   */\n  hooks?: CopilotRuntimeHooks;\n}\n\n/**\n * Creates an Express router that serves the CopilotKit runtime.\n *\n * In **multi-route** mode (default) the router exposes:\n * - `GET  {basePath}/info` — runtime info\n * - `POST {basePath}/agent/:agentId/run` — start an agent run\n * - `POST {basePath}/agent/:agentId/connect` — connect to an agent run\n * - `POST {basePath}/agent/:agentId/stop/:threadId` — stop an agent run\n * - `POST {basePath}/transcribe` — transcribe audio\n *\n * In **single-route** mode a single `POST {basePath}` endpoint accepts a JSON\n * envelope `{ method, params, body }` and dispatches to the appropriate handler.\n *\n * @example\n * ```typescript\n * import express from \"express\";\n * import { CopilotRuntime } from \"@copilotkit/runtime/v2\";\n * import { createCopilotExpressHandler } from \"@copilotkit/runtime/v2/express\";\n *\n * const runtime = new CopilotRuntime({\n *   agents: { default: new BuiltInAgent({ model: \"openai/gpt-4o-mini\" }) },\n * });\n *\n * const app = express();\n * app.use(createCopilotExpressHandler({\n *   runtime,\n *   basePath: \"/api/copilotkit\",\n *   cors: true,\n * }));\n * app.listen(4000);\n * ```\n *\n * @example Single-route mode with lifecycle hooks\n * ```typescript\n * app.use(createCopilotExpressHandler({\n *   runtime,\n *   basePath: \"/api/copilotkit\",\n *   mode: \"single-route\",\n *   hooks: {\n *     onRequest: ({ request }) => {\n *       if (!request.headers.get(\"authorization\")) {\n *         throw new Response(\"Unauthorized\", { status: 401 });\n *       }\n *     },\n *   },\n * }));\n * ```\n */\n/** @deprecated Use `createCopilotExpressHandler` instead. */\nexport { createCopilotExpressHandler as createCopilotEndpointExpress };\n\nexport function createCopilotExpressHandler({\n  runtime,\n  basePath,\n  mode = \"multi-route\",\n  cors: corsOption = true,\n  hooks,\n}: CopilotExpressEndpointParams): Router {\n  const normalizedBase = normalizeBasePath(basePath);\n\n  const handler = createCopilotRuntimeHandler({\n    runtime,\n    basePath: normalizedBase,\n    mode,\n    cors: false, // CORS is handled at the Express middleware layer\n    hooks,\n  });\n\n  const nodeHandler = createExpressNodeHandler(handler);\n\n  const expressHandler = async (\n    req: ExpressRequest,\n    res: ExpressResponse,\n    next: NextFunction,\n  ) => {\n    try {\n      await nodeHandler(req, res);\n    } catch (err) {\n      next(err);\n    }\n  };\n\n  const router = express.Router();\n\n  // CORS middleware\n  if (corsOption) {\n    const corsConfig: CorsOptions =\n      corsOption === true\n        ? {\n            origin: \"*\",\n            methods: [\n              \"GET\",\n              \"HEAD\",\n              \"PUT\",\n              \"POST\",\n              \"DELETE\",\n              \"PATCH\",\n              \"OPTIONS\",\n            ],\n            allowedHeaders: [\"*\"],\n          }\n        : corsOption;\n    router.use(cors(corsConfig));\n  }\n\n  // Route mounting\n  if (mode === \"single-route\") {\n    router.post(normalizedBase, expressHandler);\n    router.options(normalizedBase, expressHandler);\n  } else if (normalizedBase === \"/\") {\n    router.all(\"*\", expressHandler);\n  } else {\n    router.all(`${normalizedBase}/*`, expressHandler);\n    router.all(normalizedBase, expressHandler);\n  }\n\n  return router;\n}\n\nfunction normalizeBasePath(path: string): string {\n  if (!path) {\n    throw new Error(\"basePath must be provided for Express endpoint\");\n  }\n\n  if (!path.startsWith(\"/\")) {\n    return `/${path}`;\n  }\n\n  if (path.length > 1 && path.endsWith(\"/\")) {\n    return path.slice(0, -1);\n  }\n\n  return path;\n}\n"],"mappings":";;;;;;;AA0FA,SAAgB,4BAA4B,EAC1C,SACA,UACA,OAAO,eACP,MAAM,aAAa,MACnB,SACuC;CACvC,MAAM,iBAAiB,kBAAkB,SAAS;CAUlD,MAAM,cAAc,yBARJ,4BAA4B;EAC1C;EACA,UAAU;EACV;EACA,MAAM;EACN;EACD,CAAC,CAEmD;CAErD,MAAM,iBAAiB,OACrB,KACA,KACA,SACG;AACH,MAAI;AACF,SAAM,YAAY,KAAK,IAAI;WACpB,KAAK;AACZ,QAAK,IAAI;;;CAIb,MAAM,SAAS,QAAQ,QAAQ;AAG/B,KAAI,YAAY;EACd,MAAM,aACJ,eAAe,OACX;GACE,QAAQ;GACR,SAAS;IACP;IACA;IACA;IACA;IACA;IACA;IACA;IACD;GACD,gBAAgB,CAAC,IAAI;GACtB,GACD;AACN,SAAO,IAAI,KAAK,WAAW,CAAC;;AAI9B,KAAI,SAAS,gBAAgB;AAC3B,SAAO,KAAK,gBAAgB,eAAe;AAC3C,SAAO,QAAQ,gBAAgB,eAAe;YACrC,mBAAmB,IAC5B,QAAO,IAAI,KAAK,eAAe;MAC1B;AACL,SAAO,IAAI,GAAG,eAAe,KAAK,eAAe;AACjD,SAAO,IAAI,gBAAgB,eAAe;;AAG5C,QAAO;;AAGT,SAAS,kBAAkB,MAAsB;AAC/C,KAAI,CAAC,KACH,OAAM,IAAI,MAAM,iDAAiD;AAGnE,KAAI,CAAC,KAAK,WAAW,IAAI,CACvB,QAAO,IAAI;AAGb,KAAI,KAAK,SAAS,KAAK,KAAK,SAAS,IAAI,CACvC,QAAO,KAAK,MAAM,GAAG,GAAG;AAG1B,QAAO"}