@copilotkit/runtime
Version:
<img src="https://github.com/user-attachments/assets/0a6b64d9-e193-4940-a3f6-60334ac34084" alt="banner" style="border-radius: 12px; border: 2px solid #d6d4fa;" />
1 lines • 7.9 kB
Source Map (JSON)
{"version":3,"file":"index.cjs","names":["getCommonConfig","getRuntimeInstanceTelemetryInfo","createCopilotEndpointSingleRoute","getFullUrl","toHeaders","isStreamConsumed","nodeStreamToReadableStream","synthesizeBodyFromParsedBody","isDisturbedOrLockedError"],"sources":["../../../../src/lib/integrations/node-http/index.ts"],"sourcesContent":["import { CreateCopilotRuntimeServerOptions, getCommonConfig } from \"../shared\";\nimport telemetry, {\n getRuntimeInstanceTelemetryInfo,\n} from \"../../telemetry-client\";\nimport { createCopilotEndpointSingleRoute } from \"../../../v2/runtime\";\nimport type { IncomingMessage, ServerResponse } from \"node:http\";\nimport {\n getFullUrl,\n IncomingWithBody,\n isDisturbedOrLockedError,\n isStreamConsumed,\n nodeStreamToReadableStream,\n readableStreamToNodeStream,\n synthesizeBodyFromParsedBody,\n toHeaders,\n} from \"./request-handler\";\n\nexport function copilotRuntimeNodeHttpEndpoint(\n options: CreateCopilotRuntimeServerOptions,\n) {\n const commonConfig = getCommonConfig(options);\n\n telemetry.setGlobalProperties({\n runtime: {\n framework: \"node-http\",\n },\n });\n\n if (options.properties?._copilotkit) {\n telemetry.setGlobalProperties({\n _copilotkit: options.properties._copilotkit,\n });\n }\n\n telemetry.capture(\n \"oss.runtime.instance_created\",\n getRuntimeInstanceTelemetryInfo(options),\n );\n\n const logger = commonConfig.logging;\n logger.debug(\"Creating Node HTTP endpoint\");\n\n const serviceAdapter = options.serviceAdapter;\n if (serviceAdapter) {\n options.runtime.handleServiceAdapter(serviceAdapter);\n }\n\n // Note: cors option requires @copilotkit/runtime with credentials support\n const honoApp = createCopilotEndpointSingleRoute({\n runtime: options.runtime.instance,\n basePath: options.baseUrl ?? options.endpoint,\n ...(options.cors && { cors: options.cors }),\n } as any);\n\n const handle = async function handler(\n req: IncomingWithBody,\n res: ServerResponse,\n ) {\n const url = getFullUrl(req);\n const hasBody = req.method !== \"GET\" && req.method !== \"HEAD\";\n\n const baseHeaders = toHeaders(req.headers);\n const parsedBody = req.body;\n\n const streamConsumed = isStreamConsumed(req) || parsedBody !== undefined;\n const canStream = hasBody && !streamConsumed;\n\n let requestBody: BodyInit | null | undefined = undefined;\n let useDuplex = false;\n\n if (hasBody && canStream) {\n requestBody = nodeStreamToReadableStream(req);\n useDuplex = true;\n }\n\n if (hasBody && streamConsumed) {\n if (parsedBody !== undefined) {\n const synthesized = synthesizeBodyFromParsedBody(\n parsedBody,\n baseHeaders,\n );\n requestBody = synthesized.body ?? undefined;\n baseHeaders.delete(\"content-length\");\n\n if (synthesized.contentType) {\n baseHeaders.set(\"content-type\", synthesized.contentType);\n }\n\n logger.debug(\n \"Request stream already consumed; using parsed req.body to rebuild request.\",\n );\n } else {\n logger.warn(\n \"Request stream consumed with no available body; sending empty payload.\",\n );\n requestBody = undefined;\n }\n }\n\n const buildRequest = (\n body: BodyInit | null | undefined,\n headers: Headers,\n duplex: boolean,\n ) =>\n new Request(url, {\n method: req.method,\n headers,\n body,\n duplex: duplex ? \"half\" : undefined,\n } as RequestInit);\n\n let response: Response;\n try {\n response = await honoApp.fetch(\n buildRequest(requestBody, baseHeaders, useDuplex),\n );\n } catch (error) {\n if (isDisturbedOrLockedError(error) && hasBody) {\n logger.warn(\n \"Encountered disturbed/locked request body; rebuilding request using parsed body or empty payload.\",\n );\n\n const fallbackHeaders = new Headers(baseHeaders);\n let fallbackBody: BodyInit | null | undefined;\n\n if (parsedBody !== undefined) {\n const synthesized = synthesizeBodyFromParsedBody(\n parsedBody,\n fallbackHeaders,\n );\n fallbackBody = synthesized.body ?? undefined;\n fallbackHeaders.delete(\"content-length\");\n\n if (synthesized.contentType) {\n fallbackHeaders.set(\"content-type\", synthesized.contentType);\n }\n } else {\n fallbackBody = undefined;\n }\n\n response = await honoApp.fetch(\n buildRequest(fallbackBody, fallbackHeaders, false),\n );\n } else {\n throw error;\n }\n }\n\n res.statusCode = response.status;\n response.headers.forEach((value, key) => {\n res.setHeader(key, value);\n });\n\n if (response.body) {\n readableStreamToNodeStream(response.body).pipe(res);\n } else {\n res.end();\n }\n };\n\n // Duck-type check for Request-like objects (handles polyfilled Request from @hono/node-server)\n function isRequestLike(obj: unknown): obj is Request {\n return (\n obj instanceof Request ||\n (typeof obj === \"object\" &&\n obj !== null &&\n \"url\" in obj &&\n \"method\" in obj &&\n \"headers\" in obj &&\n typeof (obj as any).url === \"string\" &&\n typeof (obj as any).method === \"string\")\n );\n }\n\n return function (\n reqOrRequest: IncomingMessage | Request,\n res?: ServerResponse,\n ): Promise<void> | Promise<Response> | Response {\n if (isRequestLike(reqOrRequest) && !res) {\n return honoApp.fetch(reqOrRequest as Request);\n }\n if (!res) {\n throw new TypeError(\"ServerResponse is required for Node HTTP requests\");\n }\n return handle(reqOrRequest as IncomingMessage, res);\n };\n}\n"],"mappings":";;;;;;;AAiBA,SAAgB,+BACd,SACA;CACA,MAAM,eAAeA,+BAAgB,QAAQ;AAE7C,kCAAU,oBAAoB,EAC5B,SAAS,EACP,WAAW,aACZ,EACF,CAAC;AAEF,KAAI,QAAQ,YAAY,YACtB,kCAAU,oBAAoB,EAC5B,aAAa,QAAQ,WAAW,aACjC,CAAC;AAGJ,kCAAU,QACR,gCACAC,yDAAgC,QAAQ,CACzC;CAED,MAAM,SAAS,aAAa;AAC5B,QAAO,MAAM,8BAA8B;CAE3C,MAAM,iBAAiB,QAAQ;AAC/B,KAAI,eACF,SAAQ,QAAQ,qBAAqB,eAAe;CAItD,MAAM,UAAUC,qDAAiC;EAC/C,SAAS,QAAQ,QAAQ;EACzB,UAAU,QAAQ,WAAW,QAAQ;EACrC,GAAI,QAAQ,QAAQ,EAAE,MAAM,QAAQ,MAAM;EAC3C,CAAQ;CAET,MAAM,SAAS,eAAe,QAC5B,KACA,KACA;EACA,MAAM,MAAMC,mCAAW,IAAI;EAC3B,MAAM,UAAU,IAAI,WAAW,SAAS,IAAI,WAAW;EAEvD,MAAM,cAAcC,kCAAU,IAAI,QAAQ;EAC1C,MAAM,aAAa,IAAI;EAEvB,MAAM,iBAAiBC,yCAAiB,IAAI,IAAI,eAAe;EAC/D,MAAM,YAAY,WAAW,CAAC;EAE9B,IAAI,cAA2C;EAC/C,IAAI,YAAY;AAEhB,MAAI,WAAW,WAAW;AACxB,iBAAcC,mDAA2B,IAAI;AAC7C,eAAY;;AAGd,MAAI,WAAW,eACb,KAAI,eAAe,QAAW;GAC5B,MAAM,cAAcC,qDAClB,YACA,YACD;AACD,iBAAc,YAAY,QAAQ;AAClC,eAAY,OAAO,iBAAiB;AAEpC,OAAI,YAAY,YACd,aAAY,IAAI,gBAAgB,YAAY,YAAY;AAG1D,UAAO,MACL,6EACD;SACI;AACL,UAAO,KACL,yEACD;AACD,iBAAc;;EAIlB,MAAM,gBACJ,MACA,SACA,WAEA,IAAI,QAAQ,KAAK;GACf,QAAQ,IAAI;GACZ;GACA;GACA,QAAQ,SAAS,SAAS;GAC3B,CAAgB;EAEnB,IAAI;AACJ,MAAI;AACF,cAAW,MAAM,QAAQ,MACvB,aAAa,aAAa,aAAa,UAAU,CAClD;WACM,OAAO;AACd,OAAIC,iDAAyB,MAAM,IAAI,SAAS;AAC9C,WAAO,KACL,oGACD;IAED,MAAM,kBAAkB,IAAI,QAAQ,YAAY;IAChD,IAAI;AAEJ,QAAI,eAAe,QAAW;KAC5B,MAAM,cAAcD,qDAClB,YACA,gBACD;AACD,oBAAe,YAAY,QAAQ;AACnC,qBAAgB,OAAO,iBAAiB;AAExC,SAAI,YAAY,YACd,iBAAgB,IAAI,gBAAgB,YAAY,YAAY;UAG9D,gBAAe;AAGjB,eAAW,MAAM,QAAQ,MACvB,aAAa,cAAc,iBAAiB,MAAM,CACnD;SAED,OAAM;;AAIV,MAAI,aAAa,SAAS;AAC1B,WAAS,QAAQ,SAAS,OAAO,QAAQ;AACvC,OAAI,UAAU,KAAK,MAAM;IACzB;AAEF,MAAI,SAAS,KACX,oDAA2B,SAAS,KAAK,CAAC,KAAK,IAAI;MAEnD,KAAI,KAAK;;CAKb,SAAS,cAAc,KAA8B;AACnD,SACE,eAAe,WACd,OAAO,QAAQ,YACd,QAAQ,QACR,SAAS,OACT,YAAY,OACZ,aAAa,OACb,OAAQ,IAAY,QAAQ,YAC5B,OAAQ,IAAY,WAAW;;AAIrC,QAAO,SACL,cACA,KAC8C;AAC9C,MAAI,cAAc,aAAa,IAAI,CAAC,IAClC,QAAO,QAAQ,MAAM,aAAwB;AAE/C,MAAI,CAAC,IACH,OAAM,IAAI,UAAU,oDAAoD;AAE1E,SAAO,OAAO,cAAiC,IAAI"}