@copilotkit/runtime 1.56.0 → 1.56.2-canary.pin-to-send

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.
Files changed (194) hide show
  1. package/dist/agent/index.cjs +2 -2
  2. package/dist/agent/index.cjs.map +1 -1
  3. package/dist/agent/index.d.cts.map +1 -1
  4. package/dist/agent/index.d.mts.map +1 -1
  5. package/dist/agent/index.mjs +2 -2
  6. package/dist/agent/index.mjs.map +1 -1
  7. package/dist/graphql/resolvers/copilot.resolver.cjs +2 -1
  8. package/dist/graphql/resolvers/copilot.resolver.cjs.map +1 -1
  9. package/dist/graphql/resolvers/copilot.resolver.mjs +2 -1
  10. package/dist/graphql/resolvers/copilot.resolver.mjs.map +1 -1
  11. package/dist/graphql/resolvers/resolve-message-id.cjs +19 -0
  12. package/dist/graphql/resolvers/resolve-message-id.cjs.map +1 -0
  13. package/dist/graphql/resolvers/resolve-message-id.mjs +18 -0
  14. package/dist/graphql/resolvers/resolve-message-id.mjs.map +1 -0
  15. package/dist/lib/integrations/node-http/index.cjs +4 -1
  16. package/dist/lib/integrations/node-http/index.cjs.map +1 -1
  17. package/dist/lib/integrations/node-http/index.d.cts.map +1 -1
  18. package/dist/lib/integrations/node-http/index.d.mts.map +1 -1
  19. package/dist/lib/integrations/node-http/index.mjs +4 -1
  20. package/dist/lib/integrations/node-http/index.mjs.map +1 -1
  21. package/dist/lib/runtime/copilot-runtime.cjs +15 -3
  22. package/dist/lib/runtime/copilot-runtime.cjs.map +1 -1
  23. package/dist/lib/runtime/copilot-runtime.d.cts.map +1 -1
  24. package/dist/lib/runtime/copilot-runtime.d.mts.map +1 -1
  25. package/dist/lib/runtime/copilot-runtime.mjs +15 -3
  26. package/dist/lib/runtime/copilot-runtime.mjs.map +1 -1
  27. package/dist/lib/runtime/mcp-tools-utils.cjs +21 -4
  28. package/dist/lib/runtime/mcp-tools-utils.cjs.map +1 -1
  29. package/dist/lib/runtime/mcp-tools-utils.d.cts.map +1 -1
  30. package/dist/lib/runtime/mcp-tools-utils.d.mts.map +1 -1
  31. package/dist/lib/runtime/mcp-tools-utils.mjs +21 -4
  32. package/dist/lib/runtime/mcp-tools-utils.mjs.map +1 -1
  33. package/dist/package.cjs +2 -2
  34. package/dist/package.mjs +2 -2
  35. package/dist/service-adapters/anthropic/anthropic-adapter.cjs +11 -3
  36. package/dist/service-adapters/anthropic/anthropic-adapter.cjs.map +1 -1
  37. package/dist/service-adapters/anthropic/anthropic-adapter.d.cts +6 -0
  38. package/dist/service-adapters/anthropic/anthropic-adapter.d.cts.map +1 -1
  39. package/dist/service-adapters/anthropic/anthropic-adapter.d.mts +6 -0
  40. package/dist/service-adapters/anthropic/anthropic-adapter.d.mts.map +1 -1
  41. package/dist/service-adapters/anthropic/anthropic-adapter.mjs +11 -3
  42. package/dist/service-adapters/anthropic/anthropic-adapter.mjs.map +1 -1
  43. package/dist/service-adapters/anthropic/utils.cjs +27 -1
  44. package/dist/service-adapters/anthropic/utils.cjs.map +1 -1
  45. package/dist/service-adapters/anthropic/utils.mjs +27 -1
  46. package/dist/service-adapters/anthropic/utils.mjs.map +1 -1
  47. package/dist/service-adapters/langchain/utils.cjs +1 -1
  48. package/dist/service-adapters/langchain/utils.cjs.map +1 -1
  49. package/dist/service-adapters/langchain/utils.mjs +1 -1
  50. package/dist/service-adapters/langchain/utils.mjs.map +1 -1
  51. package/dist/service-adapters/openai/openai-adapter.cjs +2 -1
  52. package/dist/service-adapters/openai/openai-adapter.cjs.map +1 -1
  53. package/dist/service-adapters/openai/openai-adapter.d.cts +6 -0
  54. package/dist/service-adapters/openai/openai-adapter.d.cts.map +1 -1
  55. package/dist/service-adapters/openai/openai-adapter.d.mts +6 -0
  56. package/dist/service-adapters/openai/openai-adapter.d.mts.map +1 -1
  57. package/dist/service-adapters/openai/openai-adapter.mjs +2 -1
  58. package/dist/service-adapters/openai/openai-adapter.mjs.map +1 -1
  59. package/dist/v2/runtime/core/debug-event-bus.cjs +36 -0
  60. package/dist/v2/runtime/core/debug-event-bus.cjs.map +1 -0
  61. package/dist/v2/runtime/core/debug-event-bus.d.cts +19 -0
  62. package/dist/v2/runtime/core/debug-event-bus.d.cts.map +1 -0
  63. package/dist/v2/runtime/core/debug-event-bus.d.mts +19 -0
  64. package/dist/v2/runtime/core/debug-event-bus.d.mts.map +1 -0
  65. package/dist/v2/runtime/core/debug-event-bus.mjs +35 -0
  66. package/dist/v2/runtime/core/debug-event-bus.mjs.map +1 -0
  67. package/dist/v2/runtime/core/fetch-handler.cjs +6 -0
  68. package/dist/v2/runtime/core/fetch-handler.cjs.map +1 -1
  69. package/dist/v2/runtime/core/fetch-handler.d.cts.map +1 -1
  70. package/dist/v2/runtime/core/fetch-handler.d.mts.map +1 -1
  71. package/dist/v2/runtime/core/fetch-handler.mjs +6 -0
  72. package/dist/v2/runtime/core/fetch-handler.mjs.map +1 -1
  73. package/dist/v2/runtime/core/fetch-router.cjs +1 -0
  74. package/dist/v2/runtime/core/fetch-router.cjs.map +1 -1
  75. package/dist/v2/runtime/core/fetch-router.mjs +1 -0
  76. package/dist/v2/runtime/core/fetch-router.mjs.map +1 -1
  77. package/dist/v2/runtime/core/hooks.cjs.map +1 -1
  78. package/dist/v2/runtime/core/hooks.d.cts +2 -0
  79. package/dist/v2/runtime/core/hooks.d.cts.map +1 -1
  80. package/dist/v2/runtime/core/hooks.d.mts +2 -0
  81. package/dist/v2/runtime/core/hooks.d.mts.map +1 -1
  82. package/dist/v2/runtime/core/hooks.mjs.map +1 -1
  83. package/dist/v2/runtime/core/middleware-sse-parser.cjs +5 -2
  84. package/dist/v2/runtime/core/middleware-sse-parser.cjs.map +1 -1
  85. package/dist/v2/runtime/core/middleware-sse-parser.mjs +5 -2
  86. package/dist/v2/runtime/core/middleware-sse-parser.mjs.map +1 -1
  87. package/dist/v2/runtime/core/runtime.cjs +5 -0
  88. package/dist/v2/runtime/core/runtime.cjs.map +1 -1
  89. package/dist/v2/runtime/core/runtime.d.cts +5 -0
  90. package/dist/v2/runtime/core/runtime.d.cts.map +1 -1
  91. package/dist/v2/runtime/core/runtime.d.mts +5 -0
  92. package/dist/v2/runtime/core/runtime.d.mts.map +1 -1
  93. package/dist/v2/runtime/core/runtime.mjs +5 -0
  94. package/dist/v2/runtime/core/runtime.mjs.map +1 -1
  95. package/dist/v2/runtime/handlers/handle-connect.cjs +2 -0
  96. package/dist/v2/runtime/handlers/handle-connect.cjs.map +1 -1
  97. package/dist/v2/runtime/handlers/handle-connect.mjs +2 -0
  98. package/dist/v2/runtime/handlers/handle-connect.mjs.map +1 -1
  99. package/dist/v2/runtime/handlers/handle-debug-events.cjs +33 -0
  100. package/dist/v2/runtime/handlers/handle-debug-events.cjs.map +1 -0
  101. package/dist/v2/runtime/handlers/handle-debug-events.mjs +32 -0
  102. package/dist/v2/runtime/handlers/handle-debug-events.mjs.map +1 -0
  103. package/dist/v2/runtime/handlers/handle-run.cjs +1 -0
  104. package/dist/v2/runtime/handlers/handle-run.cjs.map +1 -1
  105. package/dist/v2/runtime/handlers/handle-run.mjs +1 -0
  106. package/dist/v2/runtime/handlers/handle-run.mjs.map +1 -1
  107. package/dist/v2/runtime/handlers/intelligence/connect.cjs +32 -2
  108. package/dist/v2/runtime/handlers/intelligence/connect.cjs.map +1 -1
  109. package/dist/v2/runtime/handlers/intelligence/connect.mjs +31 -2
  110. package/dist/v2/runtime/handlers/intelligence/connect.mjs.map +1 -1
  111. package/dist/v2/runtime/handlers/shared/resolve-intelligence-user.cjs +5 -1
  112. package/dist/v2/runtime/handlers/shared/resolve-intelligence-user.cjs.map +1 -1
  113. package/dist/v2/runtime/handlers/shared/resolve-intelligence-user.mjs +5 -1
  114. package/dist/v2/runtime/handlers/shared/resolve-intelligence-user.mjs.map +1 -1
  115. package/dist/v2/runtime/handlers/shared/sse-response.cjs +21 -1
  116. package/dist/v2/runtime/handlers/shared/sse-response.cjs.map +1 -1
  117. package/dist/v2/runtime/handlers/shared/sse-response.mjs +21 -1
  118. package/dist/v2/runtime/handlers/shared/sse-response.mjs.map +1 -1
  119. package/dist/v2/runtime/handlers/sse/connect.cjs +3 -1
  120. package/dist/v2/runtime/handlers/sse/connect.cjs.map +1 -1
  121. package/dist/v2/runtime/handlers/sse/connect.mjs +3 -1
  122. package/dist/v2/runtime/handlers/sse/connect.mjs.map +1 -1
  123. package/dist/v2/runtime/handlers/sse/run.cjs +3 -1
  124. package/dist/v2/runtime/handlers/sse/run.cjs.map +1 -1
  125. package/dist/v2/runtime/handlers/sse/run.mjs +3 -1
  126. package/dist/v2/runtime/handlers/sse/run.mjs.map +1 -1
  127. package/dist/v2/runtime/intelligence-platform/client.cjs +2 -7
  128. package/dist/v2/runtime/intelligence-platform/client.cjs.map +1 -1
  129. package/dist/v2/runtime/intelligence-platform/client.d.cts +1 -4
  130. package/dist/v2/runtime/intelligence-platform/client.d.cts.map +1 -1
  131. package/dist/v2/runtime/intelligence-platform/client.d.mts +1 -4
  132. package/dist/v2/runtime/intelligence-platform/client.d.mts.map +1 -1
  133. package/dist/v2/runtime/intelligence-platform/client.mjs +2 -7
  134. package/dist/v2/runtime/intelligence-platform/client.mjs.map +1 -1
  135. package/dist/v2/runtime/runner/intelligence.cjs +17 -5
  136. package/dist/v2/runtime/runner/intelligence.cjs.map +1 -1
  137. package/dist/v2/runtime/runner/intelligence.d.cts +1 -0
  138. package/dist/v2/runtime/runner/intelligence.d.cts.map +1 -1
  139. package/dist/v2/runtime/runner/intelligence.d.mts +1 -0
  140. package/dist/v2/runtime/runner/intelligence.d.mts.map +1 -1
  141. package/dist/v2/runtime/runner/intelligence.mjs +17 -5
  142. package/dist/v2/runtime/runner/intelligence.mjs.map +1 -1
  143. package/package.json +3 -3
  144. package/src/agent/__tests__/provider-id-collision.test.ts +195 -0
  145. package/src/agent/index.ts +19 -11
  146. package/src/agents/langgraph/__tests__/event-source.test.ts +256 -0
  147. package/src/graphql/resolvers/__tests__/resolve-message-id.test.ts +25 -0
  148. package/src/graphql/resolvers/copilot.resolver.ts +2 -1
  149. package/src/graphql/resolvers/resolve-message-id.ts +14 -0
  150. package/src/lib/integrations/node-http/__tests__/request-duck-type.test.ts +66 -0
  151. package/src/lib/integrations/node-http/index.ts +15 -1
  152. package/src/lib/runtime/__tests__/handle-service-adapter.test.ts +108 -0
  153. package/src/lib/runtime/__tests__/mcp-tools-utils.test.ts +30 -1
  154. package/src/lib/runtime/__tests__/on-after-request.test.ts +122 -0
  155. package/src/lib/runtime/__tests__/retry-utils.test.ts +137 -0
  156. package/src/lib/runtime/agent-integrations/langgraph/__tests__/dispatch-event-filtering.test.ts +190 -0
  157. package/src/lib/runtime/copilot-runtime.ts +36 -7
  158. package/src/lib/runtime/mcp-tools-utils.ts +41 -6
  159. package/src/lib/runtime/retry-utils.ts +41 -1
  160. package/src/service-adapters/anthropic/anthropic-adapter.ts +22 -2
  161. package/src/service-adapters/anthropic/utils.ts +60 -1
  162. package/src/service-adapters/langchain/utils.ts +1 -1
  163. package/src/service-adapters/openai/openai-adapter.ts +14 -1
  164. package/src/v2/runtime/__tests__/fetch-router.test.ts +22 -0
  165. package/src/v2/runtime/__tests__/handle-connect.test.ts +58 -5
  166. package/src/v2/runtime/__tests__/handle-run.test.ts +31 -4
  167. package/src/v2/runtime/__tests__/handle-threads.test.ts +66 -4
  168. package/src/v2/runtime/__tests__/integration/node-servers.integration.test.ts +19 -0
  169. package/src/v2/runtime/__tests__/integration/suites/debug-events.suite.ts +253 -0
  170. package/src/v2/runtime/__tests__/middleware-sse-parser.test.ts +50 -0
  171. package/src/v2/runtime/__tests__/runtime.test.ts +3 -1
  172. package/src/v2/runtime/core/__tests__/debug-event-bus.test.ts +156 -0
  173. package/src/v2/runtime/core/debug-event-bus.ts +45 -0
  174. package/src/v2/runtime/core/fetch-handler.ts +4 -0
  175. package/src/v2/runtime/core/fetch-router.ts +11 -0
  176. package/src/v2/runtime/core/hooks.ts +2 -1
  177. package/src/v2/runtime/core/middleware-sse-parser.ts +12 -2
  178. package/src/v2/runtime/core/runtime.ts +12 -0
  179. package/src/v2/runtime/handlers/__tests__/handle-debug-events.test.ts +176 -0
  180. package/src/v2/runtime/handlers/handle-connect.ts +2 -0
  181. package/src/v2/runtime/handlers/handle-debug-events.ts +52 -0
  182. package/src/v2/runtime/handlers/handle-run.ts +1 -0
  183. package/src/v2/runtime/handlers/intelligence/connect.ts +58 -1
  184. package/src/v2/runtime/handlers/shared/resolve-intelligence-user.ts +4 -1
  185. package/src/v2/runtime/handlers/shared/sse-response.ts +46 -0
  186. package/src/v2/runtime/handlers/sse/__tests__/sse-connect-agent-id.test.ts +71 -0
  187. package/src/v2/runtime/handlers/sse/connect.ts +6 -0
  188. package/src/v2/runtime/handlers/sse/run.ts +4 -0
  189. package/src/v2/runtime/intelligence-platform/__tests__/client.test.ts +13 -11
  190. package/src/v2/runtime/intelligence-platform/client.ts +3 -11
  191. package/src/v2/runtime/runner/__tests__/intelligence-runner.test.ts +51 -1
  192. package/src/v2/runtime/runner/intelligence.ts +27 -9
  193. package/tests/service-adapters/anthropic/anthropic-adapter.test.ts +268 -0
  194. package/tests/service-adapters/anthropic/utils-token-trimming.test.ts +301 -0
@@ -1 +1 @@
1
- {"version":3,"file":"utils.mjs","names":[],"sources":["../../../src/service-adapters/langchain/utils.ts"],"sourcesContent":["import {\n ActionExecutionMessage,\n Message,\n ResultMessage,\n TextMessage,\n} from \"../../graphql/types/converted\";\nimport {\n AIMessage,\n AIMessageChunk,\n BaseMessage,\n BaseMessageChunk,\n HumanMessage,\n SystemMessage,\n ToolMessage,\n} from \"@langchain/core/messages\";\nimport { DynamicStructuredTool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { ActionInput } from \"../../graphql/inputs/action.input\";\nimport { LangChainReturnType } from \"./types\";\nimport { RuntimeEventSubject } from \"../events\";\nimport { randomId, convertJsonSchemaToZodSchema } from \"@copilotkit/shared\";\n\nexport function convertMessageToLangChainMessage(\n message: Message,\n): BaseMessage {\n if (message.isTextMessage()) {\n if (message.role == \"user\") {\n return new HumanMessage(message.content);\n } else if (message.role == \"assistant\") {\n return new AIMessage(message.content);\n } else if (message.role === \"system\") {\n return new SystemMessage(message.content);\n }\n } else if (message.isActionExecutionMessage()) {\n return new AIMessage({\n content: \"\",\n tool_calls: [\n {\n id: message.id,\n args: message.arguments,\n name: message.name,\n },\n ],\n });\n } else if (message.isResultMessage()) {\n return new ToolMessage({\n content: message.result,\n tool_call_id: message.actionExecutionId,\n });\n }\n}\n\nexport function convertActionInputToLangChainTool(\n actionInput: ActionInput,\n): any {\n return new DynamicStructuredTool({\n ...actionInput,\n name: actionInput.name,\n description: actionInput.description,\n schema: convertJsonSchemaToZodSchema(\n JSON.parse(actionInput.jsonSchema),\n true,\n ) as z.ZodObject<any>,\n func: async () => {\n return \"\";\n },\n });\n}\n\ninterface StreamLangChainResponseParams {\n result: LangChainReturnType;\n eventStream$: RuntimeEventSubject;\n actionExecution?: {\n id: string;\n name: string;\n returnDirect?: boolean;\n };\n}\n\nfunction getConstructorName(object: any): string {\n if (\n object &&\n typeof object === \"object\" &&\n object.constructor &&\n object.constructor.name\n ) {\n return object.constructor.name;\n }\n return \"\";\n}\n\nfunction isAIMessage(message: any): message is AIMessage {\n return Object.prototype.toString.call(message) === \"[object AIMessage]\";\n}\n\nfunction isAIMessageChunk(message: any): message is AIMessageChunk {\n return Object.prototype.toString.call(message) === \"[object AIMessageChunk]\";\n}\n\nfunction isBaseMessageChunk(message: any): message is BaseMessageChunk {\n return (\n Object.prototype.toString.call(message) === \"[object BaseMessageChunk]\"\n );\n}\n\nfunction maybeSendActionExecutionResultIsMessage(\n eventStream$: RuntimeEventSubject,\n actionExecution?: { id: string; name: string },\n) {\n // language models need a result after the function call\n // we simply let them know that we are sending a message\n if (actionExecution) {\n eventStream$.sendActionExecutionResult({\n actionExecutionId: actionExecution.id,\n actionName: actionExecution.name,\n result: \"Sending a message\",\n });\n }\n}\n\nexport async function streamLangChainResponse({\n result,\n eventStream$,\n actionExecution,\n}: StreamLangChainResponseParams) {\n // We support several types of return values from LangChain functions:\n\n // 1. string\n\n if (typeof result === \"string\") {\n if (!actionExecution || actionExecution?.returnDirect) {\n // Just send one chunk with the string as the content.\n eventStream$.sendActionExecutionResult({\n actionExecutionId: actionExecution.id,\n actionName: actionExecution.name,\n result: result,\n });\n eventStream$.sendTextMessage(randomId(), result);\n } else {\n // Send as a result\n eventStream$.sendActionExecutionResult({\n actionExecutionId: actionExecution.id,\n actionName: actionExecution.name,\n result: result,\n });\n }\n }\n\n // 2. AIMessage\n // Send the content and function call of the AIMessage as the content of the chunk.\n else if (isAIMessage(result)) {\n maybeSendActionExecutionResultIsMessage(eventStream$, actionExecution);\n\n if (result.content) {\n eventStream$.sendTextMessage(randomId(), result.content as string);\n }\n for (const toolCall of result.tool_calls) {\n eventStream$.sendActionExecution({\n actionExecutionId: toolCall.id || randomId(),\n actionName: toolCall.name,\n args: JSON.stringify(toolCall.args),\n });\n }\n }\n\n // 3. BaseMessageChunk\n // Send the content and function call of the AIMessage as the content of the chunk.\n else if (isBaseMessageChunk(result)) {\n maybeSendActionExecutionResultIsMessage(eventStream$, actionExecution);\n\n if (result.lc_kwargs?.content) {\n eventStream$.sendTextMessage(randomId(), result.content as string);\n }\n if (result.lc_kwargs?.tool_calls) {\n for (const toolCall of result.lc_kwargs?.tool_calls) {\n eventStream$.sendActionExecution({\n actionExecutionId: toolCall.id || randomId(),\n actionName: toolCall.name,\n args: JSON.stringify(toolCall.args),\n });\n }\n }\n }\n\n // 4. IterableReadableStream\n // Stream the result of the LangChain function.\n else if (result && \"getReader\" in result) {\n maybeSendActionExecutionResultIsMessage(eventStream$, actionExecution);\n\n let reader = result.getReader();\n\n let mode: \"function\" | \"message\" | null = null;\n let currentMessageId: string;\n\n const toolCallDetails = {\n name: null,\n id: null,\n index: null,\n prevIndex: null,\n };\n\n while (true) {\n try {\n const { done, value } = await reader.read();\n\n let toolCallName: string | undefined = undefined;\n let toolCallId: string | undefined = undefined;\n let toolCallArgs: string | undefined = undefined;\n let hasToolCall: boolean = false;\n let content = \"\";\n if (value && value.content) {\n content = Array.isArray(value.content)\n ? (((value.content[0] as any)?.text ?? \"\") as string)\n : value.content;\n }\n\n if (isAIMessageChunk(value)) {\n let chunk = value.tool_call_chunks?.[0];\n toolCallArgs = chunk?.args;\n hasToolCall = chunk != undefined;\n if (chunk?.name) toolCallDetails.name = chunk.name;\n // track different index on the same tool cool\n if (chunk?.index != null) {\n toolCallDetails.index = chunk.index; // 1\n if (toolCallDetails.prevIndex == null)\n toolCallDetails.prevIndex = chunk.index;\n }\n // Differentiate when calling the same tool but with different index\n if (chunk?.id)\n toolCallDetails.id =\n chunk.index != null ? `${chunk.id}-idx-${chunk.index}` : chunk.id;\n\n // Assign to internal variables that the entire script here knows how to work with\n toolCallName = toolCallDetails.name;\n toolCallId = toolCallDetails.id;\n } else if (isBaseMessageChunk(value)) {\n let chunk = value.additional_kwargs?.tool_calls?.[0];\n toolCallName = chunk?.function?.name;\n toolCallId = chunk?.id;\n toolCallArgs = chunk?.function?.arguments;\n hasToolCall = chunk?.function != undefined;\n }\n\n // When switching from message to function or vice versa,\n // send the respective end event.\n // If toolCallName is defined, it means a new tool call starts.\n if (mode === \"message\" && (toolCallId || done)) {\n mode = null;\n eventStream$.sendTextMessageEnd({ messageId: currentMessageId });\n } else if (mode === \"function\" && (!hasToolCall || done)) {\n mode = null;\n eventStream$.sendActionExecutionEnd({\n actionExecutionId: toolCallId,\n });\n }\n\n if (done) {\n break;\n }\n\n // If we send a new message type, send the appropriate start event.\n if (mode === null) {\n if (hasToolCall && toolCallId && toolCallName) {\n mode = \"function\";\n eventStream$.sendActionExecutionStart({\n actionExecutionId: toolCallId,\n actionName: toolCallName,\n parentMessageId: value.lc_kwargs?.id,\n });\n } else if (content) {\n mode = \"message\";\n currentMessageId = value.lc_kwargs?.id || randomId();\n eventStream$.sendTextMessageStart({ messageId: currentMessageId });\n }\n }\n\n // send the content events\n if (mode === \"message\" && content) {\n eventStream$.sendTextMessageContent({\n messageId: currentMessageId,\n content,\n });\n } else if (mode === \"function\" && toolCallArgs) {\n // For calls of the same tool with different index, we seal last tool call and register a new one\n if (toolCallDetails.index !== toolCallDetails.prevIndex) {\n eventStream$.sendActionExecutionEnd({\n actionExecutionId: toolCallId,\n });\n eventStream$.sendActionExecutionStart({\n actionExecutionId: toolCallId,\n actionName: toolCallName,\n parentMessageId: value.lc_kwargs?.id,\n });\n toolCallDetails.prevIndex = toolCallDetails.index;\n }\n eventStream$.sendActionExecutionArgs({\n actionExecutionId: toolCallId,\n args: toolCallArgs,\n });\n }\n } catch (error) {\n console.error(\"Error reading from stream\", error);\n break;\n }\n }\n } else if (actionExecution) {\n eventStream$.sendActionExecutionResult({\n actionExecutionId: actionExecution.id,\n actionName: actionExecution.name,\n result: encodeResult(result),\n });\n }\n\n // unsupported type\n else {\n throw new Error(\"Invalid return type from LangChain function.\");\n }\n\n eventStream$.complete();\n}\n\nfunction encodeResult(result: any): string {\n if (result === undefined) {\n return \"\";\n } else if (typeof result === \"string\") {\n return result;\n } else {\n return JSON.stringify(result);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"utils.mjs","names":[],"sources":["../../../src/service-adapters/langchain/utils.ts"],"sourcesContent":["import {\n ActionExecutionMessage,\n Message,\n ResultMessage,\n TextMessage,\n} from \"../../graphql/types/converted\";\nimport {\n AIMessage,\n AIMessageChunk,\n BaseMessage,\n BaseMessageChunk,\n HumanMessage,\n SystemMessage,\n ToolMessage,\n} from \"@langchain/core/messages\";\nimport { DynamicStructuredTool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { ActionInput } from \"../../graphql/inputs/action.input\";\nimport { LangChainReturnType } from \"./types\";\nimport { RuntimeEventSubject } from \"../events\";\nimport { randomId, convertJsonSchemaToZodSchema } from \"@copilotkit/shared\";\n\nexport function convertMessageToLangChainMessage(\n message: Message,\n): BaseMessage {\n if (message.isTextMessage()) {\n if (message.role == \"user\") {\n return new HumanMessage(message.content);\n } else if (message.role == \"assistant\") {\n return new AIMessage(message.content);\n } else if (message.role === \"system\") {\n return new SystemMessage(message.content);\n }\n } else if (message.isActionExecutionMessage()) {\n return new AIMessage({\n content: \"\",\n tool_calls: [\n {\n id: message.id,\n args: message.arguments,\n name: message.name,\n },\n ],\n });\n } else if (message.isResultMessage()) {\n return new ToolMessage({\n content: message.result,\n tool_call_id: message.actionExecutionId,\n });\n }\n}\n\nexport function convertActionInputToLangChainTool(\n actionInput: ActionInput,\n): any {\n return new DynamicStructuredTool({\n ...actionInput,\n name: actionInput.name,\n description: actionInput.description,\n schema: convertJsonSchemaToZodSchema(\n JSON.parse(actionInput.jsonSchema),\n true,\n ) as z.ZodObject<any>,\n func: async () => {\n return \"\";\n },\n });\n}\n\ninterface StreamLangChainResponseParams {\n result: LangChainReturnType;\n eventStream$: RuntimeEventSubject;\n actionExecution?: {\n id: string;\n name: string;\n returnDirect?: boolean;\n };\n}\n\nfunction getConstructorName(object: any): string {\n if (\n object &&\n typeof object === \"object\" &&\n object.constructor &&\n object.constructor.name\n ) {\n return object.constructor.name;\n }\n return \"\";\n}\n\nfunction isAIMessage(message: any): message is AIMessage {\n return Object.prototype.toString.call(message) === \"[object AIMessage]\";\n}\n\nfunction isAIMessageChunk(message: any): message is AIMessageChunk {\n return Object.prototype.toString.call(message) === \"[object AIMessageChunk]\";\n}\n\nfunction isBaseMessageChunk(message: any): message is BaseMessageChunk {\n return (\n Object.prototype.toString.call(message) === \"[object BaseMessageChunk]\"\n );\n}\n\nfunction maybeSendActionExecutionResultIsMessage(\n eventStream$: RuntimeEventSubject,\n actionExecution?: { id: string; name: string },\n) {\n // language models need a result after the function call\n // we simply let them know that we are sending a message\n if (actionExecution) {\n eventStream$.sendActionExecutionResult({\n actionExecutionId: actionExecution.id,\n actionName: actionExecution.name,\n result: \"Sending a message\",\n });\n }\n}\n\nexport async function streamLangChainResponse({\n result,\n eventStream$,\n actionExecution,\n}: StreamLangChainResponseParams) {\n // We support several types of return values from LangChain functions:\n\n // 1. string\n\n if (typeof result === \"string\") {\n if (!actionExecution || actionExecution?.returnDirect) {\n // Just send one chunk with the string as the content.\n eventStream$.sendActionExecutionResult({\n actionExecutionId: actionExecution.id,\n actionName: actionExecution.name,\n result: result,\n });\n eventStream$.sendTextMessage(randomId(), result);\n } else {\n // Send as a result\n eventStream$.sendActionExecutionResult({\n actionExecutionId: actionExecution.id,\n actionName: actionExecution.name,\n result: result,\n });\n }\n }\n\n // 2. AIMessage\n // Send the content and function call of the AIMessage as the content of the chunk.\n else if (isAIMessage(result)) {\n maybeSendActionExecutionResultIsMessage(eventStream$, actionExecution);\n\n if (result.content) {\n eventStream$.sendTextMessage(randomId(), result.content as string);\n }\n for (const toolCall of result.tool_calls) {\n eventStream$.sendActionExecution({\n actionExecutionId: toolCall.id || randomId(),\n actionName: toolCall.name,\n args: JSON.stringify(toolCall.args),\n });\n }\n }\n\n // 3. BaseMessageChunk\n // Send the content and function call of the AIMessage as the content of the chunk.\n else if (isBaseMessageChunk(result)) {\n maybeSendActionExecutionResultIsMessage(eventStream$, actionExecution);\n\n if (result.lc_kwargs?.content) {\n eventStream$.sendTextMessage(randomId(), result.content as string);\n }\n if (result.lc_kwargs?.tool_calls) {\n for (const toolCall of result.lc_kwargs?.tool_calls) {\n eventStream$.sendActionExecution({\n actionExecutionId: toolCall.id || randomId(),\n actionName: toolCall.name,\n args: JSON.stringify(toolCall.args),\n });\n }\n }\n }\n\n // 4. IterableReadableStream\n // Stream the result of the LangChain function.\n else if (result && \"getReader\" in result) {\n maybeSendActionExecutionResultIsMessage(eventStream$, actionExecution);\n\n let reader = result.getReader();\n\n let mode: \"function\" | \"message\" | null = null;\n let currentMessageId: string;\n\n const toolCallDetails = {\n name: null,\n id: null,\n index: null,\n prevIndex: null,\n };\n\n while (true) {\n try {\n const { done, value } = await reader.read();\n\n let toolCallName: string | undefined = undefined;\n let toolCallId: string | undefined = undefined;\n let toolCallArgs: string | undefined = undefined;\n let hasToolCall: boolean = false;\n let content = \"\";\n if (value && value.content) {\n content = Array.isArray(value.content)\n ? (((value.content[0] as any)?.text ?? \"\") as string)\n : value.content;\n }\n\n if (isAIMessageChunk(value)) {\n let chunk = value.tool_call_chunks?.[0];\n toolCallArgs = chunk?.args;\n hasToolCall = chunk != undefined;\n if (chunk?.name) toolCallDetails.name = chunk.name;\n // track different index on the same tool cool\n if (chunk?.index != null) {\n toolCallDetails.index = chunk.index; // 1\n if (toolCallDetails.prevIndex == null)\n toolCallDetails.prevIndex = chunk.index;\n }\n // Differentiate when calling the same tool but with different index\n if (chunk?.id)\n toolCallDetails.id =\n chunk.index != null ? `${chunk.id}-idx-${chunk.index}` : chunk.id;\n\n // Assign to internal variables that the entire script here knows how to work with\n toolCallName = toolCallDetails.name;\n toolCallId = toolCallDetails.id;\n } else if (isBaseMessageChunk(value)) {\n let chunk = value.additional_kwargs?.tool_calls?.[0];\n toolCallName = chunk?.function?.name;\n toolCallId = chunk?.id;\n toolCallArgs = chunk?.function?.arguments;\n hasToolCall = chunk?.function != undefined;\n }\n\n // When switching from message to function or vice versa,\n // send the respective end event.\n // If toolCallName is defined, it means a new tool call starts.\n if (mode === \"message\" && (toolCallId || done)) {\n mode = null;\n eventStream$.sendTextMessageEnd({ messageId: currentMessageId });\n } else if (mode === \"function\" && (!hasToolCall || done)) {\n mode = null;\n eventStream$.sendActionExecutionEnd({\n actionExecutionId: toolCallId,\n });\n }\n\n if (done) {\n break;\n }\n\n // If we send a new message type, send the appropriate start event.\n if (mode === null) {\n if (hasToolCall && toolCallId && toolCallName) {\n mode = \"function\";\n eventStream$.sendActionExecutionStart({\n actionExecutionId: toolCallId,\n actionName: toolCallName,\n parentMessageId: value.lc_kwargs?.id,\n });\n } else if (content) {\n mode = \"message\";\n currentMessageId = randomId();\n eventStream$.sendTextMessageStart({ messageId: currentMessageId });\n }\n }\n\n // send the content events\n if (mode === \"message\" && content) {\n eventStream$.sendTextMessageContent({\n messageId: currentMessageId,\n content,\n });\n } else if (mode === \"function\" && toolCallArgs) {\n // For calls of the same tool with different index, we seal last tool call and register a new one\n if (toolCallDetails.index !== toolCallDetails.prevIndex) {\n eventStream$.sendActionExecutionEnd({\n actionExecutionId: toolCallId,\n });\n eventStream$.sendActionExecutionStart({\n actionExecutionId: toolCallId,\n actionName: toolCallName,\n parentMessageId: value.lc_kwargs?.id,\n });\n toolCallDetails.prevIndex = toolCallDetails.index;\n }\n eventStream$.sendActionExecutionArgs({\n actionExecutionId: toolCallId,\n args: toolCallArgs,\n });\n }\n } catch (error) {\n console.error(\"Error reading from stream\", error);\n break;\n }\n }\n } else if (actionExecution) {\n eventStream$.sendActionExecutionResult({\n actionExecutionId: actionExecution.id,\n actionName: actionExecution.name,\n result: encodeResult(result),\n });\n }\n\n // unsupported type\n else {\n throw new Error(\"Invalid return type from LangChain function.\");\n }\n\n eventStream$.complete();\n}\n\nfunction encodeResult(result: any): string {\n if (result === undefined) {\n return \"\";\n } else if (typeof result === \"string\") {\n return result;\n } else {\n return JSON.stringify(result);\n }\n}\n"],"mappings":"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"}
@@ -26,6 +26,7 @@ var OpenAIAdapter = class {
26
26
  if (params?.model) this.model = params.model;
27
27
  this.disableParallelToolCalls = params?.disableParallelToolCalls || false;
28
28
  this.keepSystemRole = params?.keepSystemRole ?? false;
29
+ this.maxInputTokens = params?.maxInputTokens;
29
30
  }
30
31
  getLanguageModel() {
31
32
  const openai$1 = this.ensureOpenAI();
@@ -57,7 +58,7 @@ var OpenAIAdapter = class {
57
58
  }
58
59
  return true;
59
60
  }).map((m) => require_utils.convertMessageToOpenAIMessage(m, { keepSystemRole: this.keepSystemRole }));
60
- openaiMessages = require_utils.limitMessagesToTokenCount(openaiMessages, tools, model);
61
+ openaiMessages = require_utils.limitMessagesToTokenCount(openaiMessages, tools, model, this.maxInputTokens);
61
62
  let toolChoice = forwardedParameters?.toolChoice;
62
63
  if (forwardedParameters?.toolChoice === "function") toolChoice = {
63
64
  type: "function",
@@ -1 +1 @@
1
- {"version":3,"file":"openai-adapter.cjs","names":["openai","getSdkClientOptions","Openai","convertActionInputToOpenAITool","convertMessageToOpenAIMessage","limitMessagesToTokenCount","getChatCompletionsForStreaming","convertServiceAdapterError"],"sources":["../../../src/service-adapters/openai/openai-adapter.ts"],"sourcesContent":["/**\n * Copilot Runtime adapter for OpenAI.\n *\n * ## Example\n *\n * ```ts\n * import { CopilotRuntime, OpenAIAdapter } from \"@copilotkit/runtime\";\n * import OpenAI from \"openai\";\n *\n * const copilotKit = new CopilotRuntime();\n *\n * const openai = new OpenAI({\n * organization: \"<your-organization-id>\", // optional\n * apiKey: \"<your-api-key>\",\n * });\n *\n * return new OpenAIAdapter({ openai });\n * ```\n *\n * ## Example with Azure OpenAI\n *\n * ```ts\n * import { CopilotRuntime, OpenAIAdapter } from \"@copilotkit/runtime\";\n * import OpenAI from \"openai\";\n *\n * // The name of your Azure OpenAI Instance.\n * // https://learn.microsoft.com/en-us/azure/cognitive-services/openai/how-to/create-resource?pivots=web-portal#create-a-resource\n * const instance = \"<your instance name>\";\n *\n * // Corresponds to your Model deployment within your OpenAI resource, e.g. my-gpt35-16k-deployment\n * // Navigate to the Azure OpenAI Studio to deploy a model.\n * const model = \"<your model>\";\n *\n * const apiKey = process.env[\"AZURE_OPENAI_API_KEY\"];\n * if (!apiKey) {\n * throw new Error(\"The AZURE_OPENAI_API_KEY environment variable is missing or empty.\");\n * }\n *\n * const copilotKit = new CopilotRuntime();\n *\n * const openai = new OpenAI({\n * apiKey,\n * baseURL: `https://${instance}.openai.azure.com/openai/deployments/${model}`,\n * defaultQuery: { \"api-version\": \"2024-04-01-preview\" },\n * defaultHeaders: { \"api-key\": apiKey },\n * });\n *\n * return new OpenAIAdapter({ openai });\n * ```\n */\nimport type { LanguageModel } from \"ai\";\nimport { createOpenAI } from \"@ai-sdk/openai\";\nimport type OpenAI from \"openai\";\nimport Openai from \"openai\";\nimport {\n CopilotServiceAdapter,\n CopilotRuntimeChatCompletionRequest,\n CopilotRuntimeChatCompletionResponse,\n} from \"../service-adapter\";\nimport {\n convertActionInputToOpenAITool,\n convertMessageToOpenAIMessage,\n limitMessagesToTokenCount,\n getChatCompletionsForStreaming,\n} from \"./utils\";\nimport { randomUUID } from \"@copilotkit/shared\";\nimport { convertServiceAdapterError, getSdkClientOptions } from \"../shared\";\n\nconst DEFAULT_MODEL = \"gpt-4o\";\n\nexport interface OpenAIAdapterParams {\n /**\n * An optional OpenAI instance to use. If not provided, a new instance will be\n * created.\n */\n openai?: OpenAI;\n\n /**\n * The model to use.\n */\n model?: string;\n\n /**\n * Whether to disable parallel tool calls.\n * You can disable parallel tool calls to force the model to execute tool calls sequentially.\n * This is useful if you want to execute tool calls in a specific order so that the state changes\n * introduced by one tool call are visible to the next tool call. (i.e. new actions or readables)\n *\n * @default false\n */\n disableParallelToolCalls?: boolean;\n\n /**\n * Whether to keep the role in system messages as \"System\".\n * By default, it is converted to \"developer\", which is used by newer OpenAI models\n *\n * @default false\n */\n keepSystemRole?: boolean;\n}\n\nexport class OpenAIAdapter implements CopilotServiceAdapter {\n public model: string = DEFAULT_MODEL;\n public provider = \"openai\";\n\n private disableParallelToolCalls: boolean = false;\n private _openai: OpenAI;\n private keepSystemRole: boolean = false;\n\n public get openai(): OpenAI {\n return this._openai;\n }\n public get name() {\n return \"OpenAIAdapter\";\n }\n\n constructor(params?: OpenAIAdapterParams) {\n if (params?.openai) {\n this._openai = params.openai;\n }\n // If no instance provided, we'll lazy-load in ensureOpenAI()\n\n if (params?.model) {\n this.model = params.model;\n }\n this.disableParallelToolCalls = params?.disableParallelToolCalls || false;\n this.keepSystemRole = params?.keepSystemRole ?? false;\n }\n\n getLanguageModel(): LanguageModel {\n const openai = this.ensureOpenAI();\n const options = getSdkClientOptions(openai);\n const provider = createOpenAI({\n baseURL: openai.baseURL,\n apiKey: openai.apiKey,\n organization: openai.organization ?? undefined,\n project: openai.project ?? undefined,\n headers: options.defaultHeaders,\n fetch: options.fetch,\n });\n return provider(this.model);\n }\n\n private ensureOpenAI(): OpenAI {\n if (!this._openai) {\n this._openai = new Openai();\n }\n return this._openai;\n }\n\n async process(\n request: CopilotRuntimeChatCompletionRequest,\n ): Promise<CopilotRuntimeChatCompletionResponse> {\n const {\n threadId: threadIdFromRequest,\n model = this.model,\n messages,\n actions,\n eventSource,\n forwardedParameters,\n } = request;\n const tools = actions.map(convertActionInputToOpenAITool);\n const threadId = threadIdFromRequest ?? randomUUID();\n\n // ALLOWLIST APPROACH: Only include tool_result messages that correspond to valid tool_calls\n // Step 1: Extract valid tool_call IDs\n const validToolUseIds = new Set<string>();\n\n for (const message of messages) {\n if (message.isActionExecutionMessage()) {\n validToolUseIds.add(message.id);\n }\n }\n\n // Step 2: Filter messages, keeping only those with valid tool_call IDs\n const filteredMessages = messages.filter((message) => {\n if (message.isResultMessage()) {\n // Skip if there's no corresponding tool_call\n if (!validToolUseIds.has(message.actionExecutionId)) {\n return false;\n }\n\n // Remove this ID from valid IDs so we don't process duplicates\n validToolUseIds.delete(message.actionExecutionId);\n return true;\n }\n\n // Keep all non-tool-result messages\n return true;\n });\n\n let openaiMessages = filteredMessages.map((m) =>\n convertMessageToOpenAIMessage(m, { keepSystemRole: this.keepSystemRole }),\n );\n openaiMessages = limitMessagesToTokenCount(openaiMessages, tools, model);\n\n let toolChoice: any = forwardedParameters?.toolChoice;\n if (forwardedParameters?.toolChoice === \"function\") {\n toolChoice = {\n type: \"function\",\n function: { name: forwardedParameters.toolChoiceFunctionName },\n };\n }\n\n try {\n const openai = this.ensureOpenAI();\n const completions = getChatCompletionsForStreaming(openai);\n const stream = completions.stream({\n model: model,\n stream: true,\n messages: openaiMessages,\n ...(tools.length > 0 && { tools }),\n ...(forwardedParameters?.maxTokens && {\n max_completion_tokens: forwardedParameters.maxTokens,\n }),\n ...(forwardedParameters?.stop && { stop: forwardedParameters.stop }),\n ...(toolChoice && { tool_choice: toolChoice }),\n ...(this.disableParallelToolCalls && { parallel_tool_calls: false }),\n ...(forwardedParameters?.temperature && {\n temperature: forwardedParameters.temperature,\n }),\n });\n\n eventSource.stream(async (eventStream$) => {\n let mode: \"function\" | \"message\" | null = null;\n let currentMessageId: string;\n let currentToolCallId: string;\n\n try {\n for await (const chunk of stream) {\n if (chunk.choices.length === 0) {\n continue;\n }\n\n const toolCall = chunk.choices[0].delta.tool_calls?.[0];\n const content = chunk.choices[0].delta.content;\n\n // When switching from message to function or vice versa,\n // send the respective end event.\n // If toolCall?.id is defined, it means a new tool call starts.\n if (mode === \"message\" && toolCall?.id) {\n mode = null;\n eventStream$.sendTextMessageEnd({ messageId: currentMessageId });\n } else if (\n mode === \"function\" &&\n (toolCall === undefined || toolCall?.id)\n ) {\n mode = null;\n eventStream$.sendActionExecutionEnd({\n actionExecutionId: currentToolCallId,\n });\n }\n\n // If we send a new message type, send the appropriate start event.\n if (mode === null) {\n if (toolCall?.id) {\n mode = \"function\";\n currentToolCallId = toolCall!.id;\n eventStream$.sendActionExecutionStart({\n actionExecutionId: currentToolCallId,\n parentMessageId: chunk.id,\n actionName: toolCall!.function!.name,\n });\n } else if (content) {\n mode = \"message\";\n currentMessageId = chunk.id;\n eventStream$.sendTextMessageStart({\n messageId: currentMessageId,\n });\n }\n }\n\n // send the content events\n if (mode === \"message\" && content) {\n eventStream$.sendTextMessageContent({\n messageId: currentMessageId,\n content: content,\n });\n } else if (mode === \"function\" && toolCall?.function?.arguments) {\n eventStream$.sendActionExecutionArgs({\n actionExecutionId: currentToolCallId,\n args: toolCall.function.arguments,\n });\n }\n }\n\n // send the end events\n if (mode === \"message\") {\n eventStream$.sendTextMessageEnd({ messageId: currentMessageId });\n } else if (mode === \"function\") {\n eventStream$.sendActionExecutionEnd({\n actionExecutionId: currentToolCallId,\n });\n }\n } catch (error) {\n console.error(\"[OpenAI] Error during API call:\", error);\n throw convertServiceAdapterError(error, \"OpenAI\");\n }\n\n eventStream$.complete();\n });\n } catch (error) {\n console.error(\"[OpenAI] Error during API call:\", error);\n throw convertServiceAdapterError(error, \"OpenAI\");\n }\n\n return {\n threadId,\n };\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"openai-adapter.cjs","names":["openai","getSdkClientOptions","Openai","convertActionInputToOpenAITool","convertMessageToOpenAIMessage","limitMessagesToTokenCount","getChatCompletionsForStreaming","convertServiceAdapterError"],"sources":["../../../src/service-adapters/openai/openai-adapter.ts"],"sourcesContent":["/**\n * Copilot Runtime adapter for OpenAI.\n *\n * ## Example\n *\n * ```ts\n * import { CopilotRuntime, OpenAIAdapter } from \"@copilotkit/runtime\";\n * import OpenAI from \"openai\";\n *\n * const copilotKit = new CopilotRuntime();\n *\n * const openai = new OpenAI({\n * organization: \"<your-organization-id>\", // optional\n * apiKey: \"<your-api-key>\",\n * });\n *\n * return new OpenAIAdapter({ openai });\n * ```\n *\n * ## Example with Azure OpenAI\n *\n * ```ts\n * import { CopilotRuntime, OpenAIAdapter } from \"@copilotkit/runtime\";\n * import OpenAI from \"openai\";\n *\n * // The name of your Azure OpenAI Instance.\n * // https://learn.microsoft.com/en-us/azure/cognitive-services/openai/how-to/create-resource?pivots=web-portal#create-a-resource\n * const instance = \"<your instance name>\";\n *\n * // Corresponds to your Model deployment within your OpenAI resource, e.g. my-gpt35-16k-deployment\n * // Navigate to the Azure OpenAI Studio to deploy a model.\n * const model = \"<your model>\";\n *\n * const apiKey = process.env[\"AZURE_OPENAI_API_KEY\"];\n * if (!apiKey) {\n * throw new Error(\"The AZURE_OPENAI_API_KEY environment variable is missing or empty.\");\n * }\n *\n * const copilotKit = new CopilotRuntime();\n *\n * const openai = new OpenAI({\n * apiKey,\n * baseURL: `https://${instance}.openai.azure.com/openai/deployments/${model}`,\n * defaultQuery: { \"api-version\": \"2024-04-01-preview\" },\n * defaultHeaders: { \"api-key\": apiKey },\n * });\n *\n * return new OpenAIAdapter({ openai });\n * ```\n */\nimport type { LanguageModel } from \"ai\";\nimport { createOpenAI } from \"@ai-sdk/openai\";\nimport type OpenAI from \"openai\";\nimport Openai from \"openai\";\nimport {\n CopilotServiceAdapter,\n CopilotRuntimeChatCompletionRequest,\n CopilotRuntimeChatCompletionResponse,\n} from \"../service-adapter\";\nimport {\n convertActionInputToOpenAITool,\n convertMessageToOpenAIMessage,\n limitMessagesToTokenCount,\n getChatCompletionsForStreaming,\n} from \"./utils\";\nimport { randomUUID } from \"@copilotkit/shared\";\nimport { convertServiceAdapterError, getSdkClientOptions } from \"../shared\";\n\nconst DEFAULT_MODEL = \"gpt-4o\";\n\nexport interface OpenAIAdapterParams {\n /**\n * An optional OpenAI instance to use. If not provided, a new instance will be\n * created.\n */\n openai?: OpenAI;\n\n /**\n * The model to use.\n */\n model?: string;\n\n /**\n * Whether to disable parallel tool calls.\n * You can disable parallel tool calls to force the model to execute tool calls sequentially.\n * This is useful if you want to execute tool calls in a specific order so that the state changes\n * introduced by one tool call are visible to the next tool call. (i.e. new actions or readables)\n *\n * @default false\n */\n disableParallelToolCalls?: boolean;\n\n /**\n * Whether to keep the role in system messages as \"System\".\n * By default, it is converted to \"developer\", which is used by newer OpenAI models\n *\n * @default false\n */\n keepSystemRole?: boolean;\n\n /**\n * Optional maximum input token limit. Overrides the default model-based limit\n * used when trimming messages to fit the context window.\n */\n maxInputTokens?: number;\n}\n\nexport class OpenAIAdapter implements CopilotServiceAdapter {\n public model: string = DEFAULT_MODEL;\n public provider = \"openai\";\n\n private disableParallelToolCalls: boolean = false;\n private _openai: OpenAI;\n private keepSystemRole: boolean = false;\n private maxInputTokens?: number;\n\n public get openai(): OpenAI {\n return this._openai;\n }\n public get name() {\n return \"OpenAIAdapter\";\n }\n\n constructor(params?: OpenAIAdapterParams) {\n if (params?.openai) {\n this._openai = params.openai;\n }\n // If no instance provided, we'll lazy-load in ensureOpenAI()\n\n if (params?.model) {\n this.model = params.model;\n }\n this.disableParallelToolCalls = params?.disableParallelToolCalls || false;\n this.keepSystemRole = params?.keepSystemRole ?? false;\n this.maxInputTokens = params?.maxInputTokens;\n }\n\n getLanguageModel(): LanguageModel {\n const openai = this.ensureOpenAI();\n const options = getSdkClientOptions(openai);\n const provider = createOpenAI({\n baseURL: openai.baseURL,\n apiKey: openai.apiKey,\n organization: openai.organization ?? undefined,\n project: openai.project ?? undefined,\n headers: options.defaultHeaders,\n fetch: options.fetch,\n });\n return provider(this.model);\n }\n\n private ensureOpenAI(): OpenAI {\n if (!this._openai) {\n this._openai = new Openai();\n }\n return this._openai;\n }\n\n async process(\n request: CopilotRuntimeChatCompletionRequest,\n ): Promise<CopilotRuntimeChatCompletionResponse> {\n const {\n threadId: threadIdFromRequest,\n model = this.model,\n messages,\n actions,\n eventSource,\n forwardedParameters,\n } = request;\n const tools = actions.map(convertActionInputToOpenAITool);\n const threadId = threadIdFromRequest ?? randomUUID();\n\n // ALLOWLIST APPROACH: Only include tool_result messages that correspond to valid tool_calls\n // Step 1: Extract valid tool_call IDs\n const validToolUseIds = new Set<string>();\n\n for (const message of messages) {\n if (message.isActionExecutionMessage()) {\n validToolUseIds.add(message.id);\n }\n }\n\n // Step 2: Filter messages, keeping only those with valid tool_call IDs\n const filteredMessages = messages.filter((message) => {\n if (message.isResultMessage()) {\n // Skip if there's no corresponding tool_call\n if (!validToolUseIds.has(message.actionExecutionId)) {\n return false;\n }\n\n // Remove this ID from valid IDs so we don't process duplicates\n validToolUseIds.delete(message.actionExecutionId);\n return true;\n }\n\n // Keep all non-tool-result messages\n return true;\n });\n\n let openaiMessages = filteredMessages.map((m) =>\n convertMessageToOpenAIMessage(m, { keepSystemRole: this.keepSystemRole }),\n );\n openaiMessages = limitMessagesToTokenCount(\n openaiMessages,\n tools,\n model,\n this.maxInputTokens,\n );\n\n let toolChoice: any = forwardedParameters?.toolChoice;\n if (forwardedParameters?.toolChoice === \"function\") {\n toolChoice = {\n type: \"function\",\n function: { name: forwardedParameters.toolChoiceFunctionName },\n };\n }\n\n try {\n const openai = this.ensureOpenAI();\n const completions = getChatCompletionsForStreaming(openai);\n const stream = completions.stream({\n model: model,\n stream: true,\n messages: openaiMessages,\n ...(tools.length > 0 && { tools }),\n ...(forwardedParameters?.maxTokens && {\n max_completion_tokens: forwardedParameters.maxTokens,\n }),\n ...(forwardedParameters?.stop && { stop: forwardedParameters.stop }),\n ...(toolChoice && { tool_choice: toolChoice }),\n ...(this.disableParallelToolCalls && { parallel_tool_calls: false }),\n ...(forwardedParameters?.temperature && {\n temperature: forwardedParameters.temperature,\n }),\n });\n\n eventSource.stream(async (eventStream$) => {\n let mode: \"function\" | \"message\" | null = null;\n let currentMessageId: string;\n let currentToolCallId: string;\n\n try {\n for await (const chunk of stream) {\n if (chunk.choices.length === 0) {\n continue;\n }\n\n const toolCall = chunk.choices[0].delta.tool_calls?.[0];\n const content = chunk.choices[0].delta.content;\n\n // When switching from message to function or vice versa,\n // send the respective end event.\n // If toolCall?.id is defined, it means a new tool call starts.\n if (mode === \"message\" && toolCall?.id) {\n mode = null;\n eventStream$.sendTextMessageEnd({ messageId: currentMessageId });\n } else if (\n mode === \"function\" &&\n (toolCall === undefined || toolCall?.id)\n ) {\n mode = null;\n eventStream$.sendActionExecutionEnd({\n actionExecutionId: currentToolCallId,\n });\n }\n\n // If we send a new message type, send the appropriate start event.\n if (mode === null) {\n if (toolCall?.id) {\n mode = \"function\";\n currentToolCallId = toolCall!.id;\n eventStream$.sendActionExecutionStart({\n actionExecutionId: currentToolCallId,\n parentMessageId: chunk.id,\n actionName: toolCall!.function!.name,\n });\n } else if (content) {\n mode = \"message\";\n currentMessageId = chunk.id;\n eventStream$.sendTextMessageStart({\n messageId: currentMessageId,\n });\n }\n }\n\n // send the content events\n if (mode === \"message\" && content) {\n eventStream$.sendTextMessageContent({\n messageId: currentMessageId,\n content: content,\n });\n } else if (mode === \"function\" && toolCall?.function?.arguments) {\n eventStream$.sendActionExecutionArgs({\n actionExecutionId: currentToolCallId,\n args: toolCall.function.arguments,\n });\n }\n }\n\n // send the end events\n if (mode === \"message\") {\n eventStream$.sendTextMessageEnd({ messageId: currentMessageId });\n } else if (mode === \"function\") {\n eventStream$.sendActionExecutionEnd({\n actionExecutionId: currentToolCallId,\n });\n }\n } catch (error) {\n console.error(\"[OpenAI] Error during API call:\", error);\n throw convertServiceAdapterError(error, \"OpenAI\");\n }\n\n eventStream$.complete();\n });\n } catch (error) {\n console.error(\"[OpenAI] Error during API call:\", error);\n throw convertServiceAdapterError(error, \"OpenAI\");\n }\n\n return {\n threadId,\n };\n }\n}\n"],"mappings":"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"}
@@ -30,6 +30,11 @@ interface OpenAIAdapterParams {
30
30
  * @default false
31
31
  */
32
32
  keepSystemRole?: boolean;
33
+ /**
34
+ * Optional maximum input token limit. Overrides the default model-based limit
35
+ * used when trimming messages to fit the context window.
36
+ */
37
+ maxInputTokens?: number;
33
38
  }
34
39
  declare class OpenAIAdapter implements CopilotServiceAdapter {
35
40
  model: string;
@@ -37,6 +42,7 @@ declare class OpenAIAdapter implements CopilotServiceAdapter {
37
42
  private disableParallelToolCalls;
38
43
  private _openai;
39
44
  private keepSystemRole;
45
+ private maxInputTokens?;
40
46
  get openai(): OpenAI;
41
47
  get name(): string;
42
48
  constructor(params?: OpenAIAdapterParams);
@@ -1 +1 @@
1
- {"version":3,"file":"openai-adapter.d.cts","names":[],"sources":["../../../src/service-adapters/openai/openai-adapter.ts"],"mappings":";;;;;;UAsEiB,mBAAA;;;;;EAKf,MAAA,GAAS,MAAA;;;;EAKT,KAAA;;;;;;;;;EAUA,wBAAA;;;;;;;EAQA,cAAA;AAAA;AAAA,cAGW,aAAA,YAAyB,qBAAA;EAC7B,KAAA;EACA,QAAA;EAAA,QAEC,wBAAA;EAAA,QACA,OAAA;EAAA,QACA,cAAA;EAAA,IAEG,MAAA,CAAA,GAAU,MAAA;EAAA,IAGV,IAAA,CAAA;cAIC,MAAA,GAAS,mBAAA;EAarB,gBAAA,CAAA,GAAoB,aAAA;EAAA,QAcZ,YAAA;EAOF,OAAA,CACJ,OAAA,EAAS,mCAAA,GACR,OAAA,CAAQ,oCAAA;AAAA"}
1
+ {"version":3,"file":"openai-adapter.d.cts","names":[],"sources":["../../../src/service-adapters/openai/openai-adapter.ts"],"mappings":";;;;;;UAsEiB,mBAAA;;;;;EAKf,MAAA,GAAS,MAAA;;;;EAKT,KAAA;;;;;;;;;EAUA,wBAAA;;;;;;;EAQA,cAAA;;;;;EAMA,cAAA;AAAA;AAAA,cAGW,aAAA,YAAyB,qBAAA;EAC7B,KAAA;EACA,QAAA;EAAA,QAEC,wBAAA;EAAA,QACA,OAAA;EAAA,QACA,cAAA;EAAA,QACA,cAAA;EAAA,IAEG,MAAA,CAAA,GAAU,MAAA;EAAA,IAGV,IAAA,CAAA;cAIC,MAAA,GAAS,mBAAA;EAcrB,gBAAA,CAAA,GAAoB,aAAA;EAAA,QAcZ,YAAA;EAOF,OAAA,CACJ,OAAA,EAAS,mCAAA,GACR,OAAA,CAAQ,oCAAA;AAAA"}
@@ -30,6 +30,11 @@ interface OpenAIAdapterParams {
30
30
  * @default false
31
31
  */
32
32
  keepSystemRole?: boolean;
33
+ /**
34
+ * Optional maximum input token limit. Overrides the default model-based limit
35
+ * used when trimming messages to fit the context window.
36
+ */
37
+ maxInputTokens?: number;
33
38
  }
34
39
  declare class OpenAIAdapter implements CopilotServiceAdapter {
35
40
  model: string;
@@ -37,6 +42,7 @@ declare class OpenAIAdapter implements CopilotServiceAdapter {
37
42
  private disableParallelToolCalls;
38
43
  private _openai;
39
44
  private keepSystemRole;
45
+ private maxInputTokens?;
40
46
  get openai(): Openai;
41
47
  get name(): string;
42
48
  constructor(params?: OpenAIAdapterParams);
@@ -1 +1 @@
1
- {"version":3,"file":"openai-adapter.d.mts","names":[],"sources":["../../../src/service-adapters/openai/openai-adapter.ts"],"mappings":";;;;;;UAsEiB,mBAAA;;;;;EAKf,MAAA,GAAS,MAAA;;;;EAKT,KAAA;;;;;;;;;EAUA,wBAAA;;;;;;;EAQA,cAAA;AAAA;AAAA,cAGW,aAAA,YAAyB,qBAAA;EAC7B,KAAA;EACA,QAAA;EAAA,QAEC,wBAAA;EAAA,QACA,OAAA;EAAA,QACA,cAAA;EAAA,IAEG,MAAA,CAAA,GAAU,MAAA;EAAA,IAGV,IAAA,CAAA;cAIC,MAAA,GAAS,mBAAA;EAarB,gBAAA,CAAA,GAAoB,aAAA;EAAA,QAcZ,YAAA;EAOF,OAAA,CACJ,OAAA,EAAS,mCAAA,GACR,OAAA,CAAQ,oCAAA;AAAA"}
1
+ {"version":3,"file":"openai-adapter.d.mts","names":[],"sources":["../../../src/service-adapters/openai/openai-adapter.ts"],"mappings":";;;;;;UAsEiB,mBAAA;;;;;EAKf,MAAA,GAAS,MAAA;;;;EAKT,KAAA;;;;;;;;;EAUA,wBAAA;;;;;;;EAQA,cAAA;;;;;EAMA,cAAA;AAAA;AAAA,cAGW,aAAA,YAAyB,qBAAA;EAC7B,KAAA;EACA,QAAA;EAAA,QAEC,wBAAA;EAAA,QACA,OAAA;EAAA,QACA,cAAA;EAAA,QACA,cAAA;EAAA,IAEG,MAAA,CAAA,GAAU,MAAA;EAAA,IAGV,IAAA,CAAA;cAIC,MAAA,GAAS,mBAAA;EAcrB,gBAAA,CAAA,GAAoB,aAAA;EAAA,QAcZ,YAAA;EAOF,OAAA,CACJ,OAAA,EAAS,mCAAA,GACR,OAAA,CAAQ,oCAAA;AAAA"}
@@ -24,6 +24,7 @@ var OpenAIAdapter = class {
24
24
  if (params?.model) this.model = params.model;
25
25
  this.disableParallelToolCalls = params?.disableParallelToolCalls || false;
26
26
  this.keepSystemRole = params?.keepSystemRole ?? false;
27
+ this.maxInputTokens = params?.maxInputTokens;
27
28
  }
28
29
  getLanguageModel() {
29
30
  const openai = this.ensureOpenAI();
@@ -55,7 +56,7 @@ var OpenAIAdapter = class {
55
56
  }
56
57
  return true;
57
58
  }).map((m) => convertMessageToOpenAIMessage(m, { keepSystemRole: this.keepSystemRole }));
58
- openaiMessages = limitMessagesToTokenCount(openaiMessages, tools, model);
59
+ openaiMessages = limitMessagesToTokenCount(openaiMessages, tools, model, this.maxInputTokens);
59
60
  let toolChoice = forwardedParameters?.toolChoice;
60
61
  if (forwardedParameters?.toolChoice === "function") toolChoice = {
61
62
  type: "function",
@@ -1 +1 @@
1
- {"version":3,"file":"openai-adapter.mjs","names":[],"sources":["../../../src/service-adapters/openai/openai-adapter.ts"],"sourcesContent":["/**\n * Copilot Runtime adapter for OpenAI.\n *\n * ## Example\n *\n * ```ts\n * import { CopilotRuntime, OpenAIAdapter } from \"@copilotkit/runtime\";\n * import OpenAI from \"openai\";\n *\n * const copilotKit = new CopilotRuntime();\n *\n * const openai = new OpenAI({\n * organization: \"<your-organization-id>\", // optional\n * apiKey: \"<your-api-key>\",\n * });\n *\n * return new OpenAIAdapter({ openai });\n * ```\n *\n * ## Example with Azure OpenAI\n *\n * ```ts\n * import { CopilotRuntime, OpenAIAdapter } from \"@copilotkit/runtime\";\n * import OpenAI from \"openai\";\n *\n * // The name of your Azure OpenAI Instance.\n * // https://learn.microsoft.com/en-us/azure/cognitive-services/openai/how-to/create-resource?pivots=web-portal#create-a-resource\n * const instance = \"<your instance name>\";\n *\n * // Corresponds to your Model deployment within your OpenAI resource, e.g. my-gpt35-16k-deployment\n * // Navigate to the Azure OpenAI Studio to deploy a model.\n * const model = \"<your model>\";\n *\n * const apiKey = process.env[\"AZURE_OPENAI_API_KEY\"];\n * if (!apiKey) {\n * throw new Error(\"The AZURE_OPENAI_API_KEY environment variable is missing or empty.\");\n * }\n *\n * const copilotKit = new CopilotRuntime();\n *\n * const openai = new OpenAI({\n * apiKey,\n * baseURL: `https://${instance}.openai.azure.com/openai/deployments/${model}`,\n * defaultQuery: { \"api-version\": \"2024-04-01-preview\" },\n * defaultHeaders: { \"api-key\": apiKey },\n * });\n *\n * return new OpenAIAdapter({ openai });\n * ```\n */\nimport type { LanguageModel } from \"ai\";\nimport { createOpenAI } from \"@ai-sdk/openai\";\nimport type OpenAI from \"openai\";\nimport Openai from \"openai\";\nimport {\n CopilotServiceAdapter,\n CopilotRuntimeChatCompletionRequest,\n CopilotRuntimeChatCompletionResponse,\n} from \"../service-adapter\";\nimport {\n convertActionInputToOpenAITool,\n convertMessageToOpenAIMessage,\n limitMessagesToTokenCount,\n getChatCompletionsForStreaming,\n} from \"./utils\";\nimport { randomUUID } from \"@copilotkit/shared\";\nimport { convertServiceAdapterError, getSdkClientOptions } from \"../shared\";\n\nconst DEFAULT_MODEL = \"gpt-4o\";\n\nexport interface OpenAIAdapterParams {\n /**\n * An optional OpenAI instance to use. If not provided, a new instance will be\n * created.\n */\n openai?: OpenAI;\n\n /**\n * The model to use.\n */\n model?: string;\n\n /**\n * Whether to disable parallel tool calls.\n * You can disable parallel tool calls to force the model to execute tool calls sequentially.\n * This is useful if you want to execute tool calls in a specific order so that the state changes\n * introduced by one tool call are visible to the next tool call. (i.e. new actions or readables)\n *\n * @default false\n */\n disableParallelToolCalls?: boolean;\n\n /**\n * Whether to keep the role in system messages as \"System\".\n * By default, it is converted to \"developer\", which is used by newer OpenAI models\n *\n * @default false\n */\n keepSystemRole?: boolean;\n}\n\nexport class OpenAIAdapter implements CopilotServiceAdapter {\n public model: string = DEFAULT_MODEL;\n public provider = \"openai\";\n\n private disableParallelToolCalls: boolean = false;\n private _openai: OpenAI;\n private keepSystemRole: boolean = false;\n\n public get openai(): OpenAI {\n return this._openai;\n }\n public get name() {\n return \"OpenAIAdapter\";\n }\n\n constructor(params?: OpenAIAdapterParams) {\n if (params?.openai) {\n this._openai = params.openai;\n }\n // If no instance provided, we'll lazy-load in ensureOpenAI()\n\n if (params?.model) {\n this.model = params.model;\n }\n this.disableParallelToolCalls = params?.disableParallelToolCalls || false;\n this.keepSystemRole = params?.keepSystemRole ?? false;\n }\n\n getLanguageModel(): LanguageModel {\n const openai = this.ensureOpenAI();\n const options = getSdkClientOptions(openai);\n const provider = createOpenAI({\n baseURL: openai.baseURL,\n apiKey: openai.apiKey,\n organization: openai.organization ?? undefined,\n project: openai.project ?? undefined,\n headers: options.defaultHeaders,\n fetch: options.fetch,\n });\n return provider(this.model);\n }\n\n private ensureOpenAI(): OpenAI {\n if (!this._openai) {\n this._openai = new Openai();\n }\n return this._openai;\n }\n\n async process(\n request: CopilotRuntimeChatCompletionRequest,\n ): Promise<CopilotRuntimeChatCompletionResponse> {\n const {\n threadId: threadIdFromRequest,\n model = this.model,\n messages,\n actions,\n eventSource,\n forwardedParameters,\n } = request;\n const tools = actions.map(convertActionInputToOpenAITool);\n const threadId = threadIdFromRequest ?? randomUUID();\n\n // ALLOWLIST APPROACH: Only include tool_result messages that correspond to valid tool_calls\n // Step 1: Extract valid tool_call IDs\n const validToolUseIds = new Set<string>();\n\n for (const message of messages) {\n if (message.isActionExecutionMessage()) {\n validToolUseIds.add(message.id);\n }\n }\n\n // Step 2: Filter messages, keeping only those with valid tool_call IDs\n const filteredMessages = messages.filter((message) => {\n if (message.isResultMessage()) {\n // Skip if there's no corresponding tool_call\n if (!validToolUseIds.has(message.actionExecutionId)) {\n return false;\n }\n\n // Remove this ID from valid IDs so we don't process duplicates\n validToolUseIds.delete(message.actionExecutionId);\n return true;\n }\n\n // Keep all non-tool-result messages\n return true;\n });\n\n let openaiMessages = filteredMessages.map((m) =>\n convertMessageToOpenAIMessage(m, { keepSystemRole: this.keepSystemRole }),\n );\n openaiMessages = limitMessagesToTokenCount(openaiMessages, tools, model);\n\n let toolChoice: any = forwardedParameters?.toolChoice;\n if (forwardedParameters?.toolChoice === \"function\") {\n toolChoice = {\n type: \"function\",\n function: { name: forwardedParameters.toolChoiceFunctionName },\n };\n }\n\n try {\n const openai = this.ensureOpenAI();\n const completions = getChatCompletionsForStreaming(openai);\n const stream = completions.stream({\n model: model,\n stream: true,\n messages: openaiMessages,\n ...(tools.length > 0 && { tools }),\n ...(forwardedParameters?.maxTokens && {\n max_completion_tokens: forwardedParameters.maxTokens,\n }),\n ...(forwardedParameters?.stop && { stop: forwardedParameters.stop }),\n ...(toolChoice && { tool_choice: toolChoice }),\n ...(this.disableParallelToolCalls && { parallel_tool_calls: false }),\n ...(forwardedParameters?.temperature && {\n temperature: forwardedParameters.temperature,\n }),\n });\n\n eventSource.stream(async (eventStream$) => {\n let mode: \"function\" | \"message\" | null = null;\n let currentMessageId: string;\n let currentToolCallId: string;\n\n try {\n for await (const chunk of stream) {\n if (chunk.choices.length === 0) {\n continue;\n }\n\n const toolCall = chunk.choices[0].delta.tool_calls?.[0];\n const content = chunk.choices[0].delta.content;\n\n // When switching from message to function or vice versa,\n // send the respective end event.\n // If toolCall?.id is defined, it means a new tool call starts.\n if (mode === \"message\" && toolCall?.id) {\n mode = null;\n eventStream$.sendTextMessageEnd({ messageId: currentMessageId });\n } else if (\n mode === \"function\" &&\n (toolCall === undefined || toolCall?.id)\n ) {\n mode = null;\n eventStream$.sendActionExecutionEnd({\n actionExecutionId: currentToolCallId,\n });\n }\n\n // If we send a new message type, send the appropriate start event.\n if (mode === null) {\n if (toolCall?.id) {\n mode = \"function\";\n currentToolCallId = toolCall!.id;\n eventStream$.sendActionExecutionStart({\n actionExecutionId: currentToolCallId,\n parentMessageId: chunk.id,\n actionName: toolCall!.function!.name,\n });\n } else if (content) {\n mode = \"message\";\n currentMessageId = chunk.id;\n eventStream$.sendTextMessageStart({\n messageId: currentMessageId,\n });\n }\n }\n\n // send the content events\n if (mode === \"message\" && content) {\n eventStream$.sendTextMessageContent({\n messageId: currentMessageId,\n content: content,\n });\n } else if (mode === \"function\" && toolCall?.function?.arguments) {\n eventStream$.sendActionExecutionArgs({\n actionExecutionId: currentToolCallId,\n args: toolCall.function.arguments,\n });\n }\n }\n\n // send the end events\n if (mode === \"message\") {\n eventStream$.sendTextMessageEnd({ messageId: currentMessageId });\n } else if (mode === \"function\") {\n eventStream$.sendActionExecutionEnd({\n actionExecutionId: currentToolCallId,\n });\n }\n } catch (error) {\n console.error(\"[OpenAI] Error during API call:\", error);\n throw convertServiceAdapterError(error, \"OpenAI\");\n }\n\n eventStream$.complete();\n });\n } catch (error) {\n console.error(\"[OpenAI] Error during API call:\", error);\n throw convertServiceAdapterError(error, \"OpenAI\");\n }\n\n return {\n threadId,\n };\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"openai-adapter.mjs","names":[],"sources":["../../../src/service-adapters/openai/openai-adapter.ts"],"sourcesContent":["/**\n * Copilot Runtime adapter for OpenAI.\n *\n * ## Example\n *\n * ```ts\n * import { CopilotRuntime, OpenAIAdapter } from \"@copilotkit/runtime\";\n * import OpenAI from \"openai\";\n *\n * const copilotKit = new CopilotRuntime();\n *\n * const openai = new OpenAI({\n * organization: \"<your-organization-id>\", // optional\n * apiKey: \"<your-api-key>\",\n * });\n *\n * return new OpenAIAdapter({ openai });\n * ```\n *\n * ## Example with Azure OpenAI\n *\n * ```ts\n * import { CopilotRuntime, OpenAIAdapter } from \"@copilotkit/runtime\";\n * import OpenAI from \"openai\";\n *\n * // The name of your Azure OpenAI Instance.\n * // https://learn.microsoft.com/en-us/azure/cognitive-services/openai/how-to/create-resource?pivots=web-portal#create-a-resource\n * const instance = \"<your instance name>\";\n *\n * // Corresponds to your Model deployment within your OpenAI resource, e.g. my-gpt35-16k-deployment\n * // Navigate to the Azure OpenAI Studio to deploy a model.\n * const model = \"<your model>\";\n *\n * const apiKey = process.env[\"AZURE_OPENAI_API_KEY\"];\n * if (!apiKey) {\n * throw new Error(\"The AZURE_OPENAI_API_KEY environment variable is missing or empty.\");\n * }\n *\n * const copilotKit = new CopilotRuntime();\n *\n * const openai = new OpenAI({\n * apiKey,\n * baseURL: `https://${instance}.openai.azure.com/openai/deployments/${model}`,\n * defaultQuery: { \"api-version\": \"2024-04-01-preview\" },\n * defaultHeaders: { \"api-key\": apiKey },\n * });\n *\n * return new OpenAIAdapter({ openai });\n * ```\n */\nimport type { LanguageModel } from \"ai\";\nimport { createOpenAI } from \"@ai-sdk/openai\";\nimport type OpenAI from \"openai\";\nimport Openai from \"openai\";\nimport {\n CopilotServiceAdapter,\n CopilotRuntimeChatCompletionRequest,\n CopilotRuntimeChatCompletionResponse,\n} from \"../service-adapter\";\nimport {\n convertActionInputToOpenAITool,\n convertMessageToOpenAIMessage,\n limitMessagesToTokenCount,\n getChatCompletionsForStreaming,\n} from \"./utils\";\nimport { randomUUID } from \"@copilotkit/shared\";\nimport { convertServiceAdapterError, getSdkClientOptions } from \"../shared\";\n\nconst DEFAULT_MODEL = \"gpt-4o\";\n\nexport interface OpenAIAdapterParams {\n /**\n * An optional OpenAI instance to use. If not provided, a new instance will be\n * created.\n */\n openai?: OpenAI;\n\n /**\n * The model to use.\n */\n model?: string;\n\n /**\n * Whether to disable parallel tool calls.\n * You can disable parallel tool calls to force the model to execute tool calls sequentially.\n * This is useful if you want to execute tool calls in a specific order so that the state changes\n * introduced by one tool call are visible to the next tool call. (i.e. new actions or readables)\n *\n * @default false\n */\n disableParallelToolCalls?: boolean;\n\n /**\n * Whether to keep the role in system messages as \"System\".\n * By default, it is converted to \"developer\", which is used by newer OpenAI models\n *\n * @default false\n */\n keepSystemRole?: boolean;\n\n /**\n * Optional maximum input token limit. Overrides the default model-based limit\n * used when trimming messages to fit the context window.\n */\n maxInputTokens?: number;\n}\n\nexport class OpenAIAdapter implements CopilotServiceAdapter {\n public model: string = DEFAULT_MODEL;\n public provider = \"openai\";\n\n private disableParallelToolCalls: boolean = false;\n private _openai: OpenAI;\n private keepSystemRole: boolean = false;\n private maxInputTokens?: number;\n\n public get openai(): OpenAI {\n return this._openai;\n }\n public get name() {\n return \"OpenAIAdapter\";\n }\n\n constructor(params?: OpenAIAdapterParams) {\n if (params?.openai) {\n this._openai = params.openai;\n }\n // If no instance provided, we'll lazy-load in ensureOpenAI()\n\n if (params?.model) {\n this.model = params.model;\n }\n this.disableParallelToolCalls = params?.disableParallelToolCalls || false;\n this.keepSystemRole = params?.keepSystemRole ?? false;\n this.maxInputTokens = params?.maxInputTokens;\n }\n\n getLanguageModel(): LanguageModel {\n const openai = this.ensureOpenAI();\n const options = getSdkClientOptions(openai);\n const provider = createOpenAI({\n baseURL: openai.baseURL,\n apiKey: openai.apiKey,\n organization: openai.organization ?? undefined,\n project: openai.project ?? undefined,\n headers: options.defaultHeaders,\n fetch: options.fetch,\n });\n return provider(this.model);\n }\n\n private ensureOpenAI(): OpenAI {\n if (!this._openai) {\n this._openai = new Openai();\n }\n return this._openai;\n }\n\n async process(\n request: CopilotRuntimeChatCompletionRequest,\n ): Promise<CopilotRuntimeChatCompletionResponse> {\n const {\n threadId: threadIdFromRequest,\n model = this.model,\n messages,\n actions,\n eventSource,\n forwardedParameters,\n } = request;\n const tools = actions.map(convertActionInputToOpenAITool);\n const threadId = threadIdFromRequest ?? randomUUID();\n\n // ALLOWLIST APPROACH: Only include tool_result messages that correspond to valid tool_calls\n // Step 1: Extract valid tool_call IDs\n const validToolUseIds = new Set<string>();\n\n for (const message of messages) {\n if (message.isActionExecutionMessage()) {\n validToolUseIds.add(message.id);\n }\n }\n\n // Step 2: Filter messages, keeping only those with valid tool_call IDs\n const filteredMessages = messages.filter((message) => {\n if (message.isResultMessage()) {\n // Skip if there's no corresponding tool_call\n if (!validToolUseIds.has(message.actionExecutionId)) {\n return false;\n }\n\n // Remove this ID from valid IDs so we don't process duplicates\n validToolUseIds.delete(message.actionExecutionId);\n return true;\n }\n\n // Keep all non-tool-result messages\n return true;\n });\n\n let openaiMessages = filteredMessages.map((m) =>\n convertMessageToOpenAIMessage(m, { keepSystemRole: this.keepSystemRole }),\n );\n openaiMessages = limitMessagesToTokenCount(\n openaiMessages,\n tools,\n model,\n this.maxInputTokens,\n );\n\n let toolChoice: any = forwardedParameters?.toolChoice;\n if (forwardedParameters?.toolChoice === \"function\") {\n toolChoice = {\n type: \"function\",\n function: { name: forwardedParameters.toolChoiceFunctionName },\n };\n }\n\n try {\n const openai = this.ensureOpenAI();\n const completions = getChatCompletionsForStreaming(openai);\n const stream = completions.stream({\n model: model,\n stream: true,\n messages: openaiMessages,\n ...(tools.length > 0 && { tools }),\n ...(forwardedParameters?.maxTokens && {\n max_completion_tokens: forwardedParameters.maxTokens,\n }),\n ...(forwardedParameters?.stop && { stop: forwardedParameters.stop }),\n ...(toolChoice && { tool_choice: toolChoice }),\n ...(this.disableParallelToolCalls && { parallel_tool_calls: false }),\n ...(forwardedParameters?.temperature && {\n temperature: forwardedParameters.temperature,\n }),\n });\n\n eventSource.stream(async (eventStream$) => {\n let mode: \"function\" | \"message\" | null = null;\n let currentMessageId: string;\n let currentToolCallId: string;\n\n try {\n for await (const chunk of stream) {\n if (chunk.choices.length === 0) {\n continue;\n }\n\n const toolCall = chunk.choices[0].delta.tool_calls?.[0];\n const content = chunk.choices[0].delta.content;\n\n // When switching from message to function or vice versa,\n // send the respective end event.\n // If toolCall?.id is defined, it means a new tool call starts.\n if (mode === \"message\" && toolCall?.id) {\n mode = null;\n eventStream$.sendTextMessageEnd({ messageId: currentMessageId });\n } else if (\n mode === \"function\" &&\n (toolCall === undefined || toolCall?.id)\n ) {\n mode = null;\n eventStream$.sendActionExecutionEnd({\n actionExecutionId: currentToolCallId,\n });\n }\n\n // If we send a new message type, send the appropriate start event.\n if (mode === null) {\n if (toolCall?.id) {\n mode = \"function\";\n currentToolCallId = toolCall!.id;\n eventStream$.sendActionExecutionStart({\n actionExecutionId: currentToolCallId,\n parentMessageId: chunk.id,\n actionName: toolCall!.function!.name,\n });\n } else if (content) {\n mode = \"message\";\n currentMessageId = chunk.id;\n eventStream$.sendTextMessageStart({\n messageId: currentMessageId,\n });\n }\n }\n\n // send the content events\n if (mode === \"message\" && content) {\n eventStream$.sendTextMessageContent({\n messageId: currentMessageId,\n content: content,\n });\n } else if (mode === \"function\" && toolCall?.function?.arguments) {\n eventStream$.sendActionExecutionArgs({\n actionExecutionId: currentToolCallId,\n args: toolCall.function.arguments,\n });\n }\n }\n\n // send the end events\n if (mode === \"message\") {\n eventStream$.sendTextMessageEnd({ messageId: currentMessageId });\n } else if (mode === \"function\") {\n eventStream$.sendActionExecutionEnd({\n actionExecutionId: currentToolCallId,\n });\n }\n } catch (error) {\n console.error(\"[OpenAI] Error during API call:\", error);\n throw convertServiceAdapterError(error, \"OpenAI\");\n }\n\n eventStream$.complete();\n });\n } catch (error) {\n console.error(\"[OpenAI] Error during API call:\", error);\n throw convertServiceAdapterError(error, \"OpenAI\");\n }\n\n return {\n threadId,\n };\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ require("reflect-metadata");
2
+
3
+ //#region src/v2/runtime/core/debug-event-bus.ts
4
+ var DebugEventBus = class {
5
+ constructor() {
6
+ this.listeners = /* @__PURE__ */ new Set();
7
+ }
8
+ subscribe(listener) {
9
+ this.listeners.add(listener);
10
+ return () => {
11
+ this.listeners.delete(listener);
12
+ };
13
+ }
14
+ broadcast(event, metadata) {
15
+ if (this.listeners.size === 0) return;
16
+ const envelope = {
17
+ timestamp: Date.now(),
18
+ agentId: metadata.agentId,
19
+ threadId: metadata.threadId,
20
+ runId: metadata.runId,
21
+ event
22
+ };
23
+ for (const listener of this.listeners) try {
24
+ listener(envelope);
25
+ } catch (err) {
26
+ console.warn("[DebugEventBus] Listener error suppressed:", err instanceof Error ? err.message : err);
27
+ }
28
+ }
29
+ get listenerCount() {
30
+ return this.listeners.size;
31
+ }
32
+ };
33
+
34
+ //#endregion
35
+ exports.DebugEventBus = DebugEventBus;
36
+ //# sourceMappingURL=debug-event-bus.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debug-event-bus.cjs","names":[],"sources":["../../../../src/v2/runtime/core/debug-event-bus.ts"],"sourcesContent":["import { BaseEvent } from \"@ag-ui/client\";\nimport { DebugEventEnvelope } from \"@copilotkit/shared\";\n\nexport type DebugEventListener = (envelope: DebugEventEnvelope) => void;\n\nexport class DebugEventBus {\n private listeners = new Set<DebugEventListener>();\n\n subscribe(listener: DebugEventListener): () => void {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n broadcast(\n event: BaseEvent,\n metadata: { agentId: string; threadId: string; runId: string },\n ): void {\n if (this.listeners.size === 0) return;\n\n const envelope: DebugEventEnvelope = {\n timestamp: Date.now(),\n agentId: metadata.agentId,\n threadId: metadata.threadId,\n runId: metadata.runId,\n event,\n };\n\n for (const listener of this.listeners) {\n try {\n listener(envelope);\n } catch (err) {\n console.warn(\n \"[DebugEventBus] Listener error suppressed:\",\n err instanceof Error ? err.message : err,\n );\n }\n }\n }\n\n get listenerCount(): number {\n return this.listeners.size;\n }\n}\n"],"mappings":";;;AAKA,IAAa,gBAAb,MAA2B;;mCACL,IAAI,KAAyB;;CAEjD,UAAU,UAA0C;AAClD,OAAK,UAAU,IAAI,SAAS;AAC5B,eAAa;AACX,QAAK,UAAU,OAAO,SAAS;;;CAInC,UACE,OACA,UACM;AACN,MAAI,KAAK,UAAU,SAAS,EAAG;EAE/B,MAAM,WAA+B;GACnC,WAAW,KAAK,KAAK;GACrB,SAAS,SAAS;GAClB,UAAU,SAAS;GACnB,OAAO,SAAS;GAChB;GACD;AAED,OAAK,MAAM,YAAY,KAAK,UAC1B,KAAI;AACF,YAAS,SAAS;WACX,KAAK;AACZ,WAAQ,KACN,8CACA,eAAe,QAAQ,IAAI,UAAU,IACtC;;;CAKP,IAAI,gBAAwB;AAC1B,SAAO,KAAK,UAAU"}
@@ -0,0 +1,19 @@
1
+
2
+ import { DebugEventEnvelope } from "@copilotkit/shared";
3
+ import { BaseEvent } from "@ag-ui/client";
4
+
5
+ //#region src/v2/runtime/core/debug-event-bus.d.ts
6
+ type DebugEventListener = (envelope: DebugEventEnvelope) => void;
7
+ declare class DebugEventBus {
8
+ private listeners;
9
+ subscribe(listener: DebugEventListener): () => void;
10
+ broadcast(event: BaseEvent, metadata: {
11
+ agentId: string;
12
+ threadId: string;
13
+ runId: string;
14
+ }): void;
15
+ get listenerCount(): number;
16
+ }
17
+ //#endregion
18
+ export { DebugEventBus };
19
+ //# sourceMappingURL=debug-event-bus.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debug-event-bus.d.cts","names":[],"sources":["../../../../src/v2/runtime/core/debug-event-bus.ts"],"mappings":";;;;;KAGY,kBAAA,IAAsB,QAAA,EAAU,kBAAA;AAAA,cAE/B,aAAA;EAAA,QACH,SAAA;EAER,SAAA,CAAU,QAAA,EAAU,kBAAA;EAOpB,SAAA,CACE,KAAA,EAAO,SAAA,EACP,QAAA;IAAY,OAAA;IAAiB,QAAA;IAAkB,KAAA;EAAA;EAAA,IAwB7C,aAAA,CAAA;AAAA"}
@@ -0,0 +1,19 @@
1
+ import "reflect-metadata";
2
+ import { DebugEventEnvelope } from "@copilotkit/shared";
3
+ import { BaseEvent } from "@ag-ui/client";
4
+
5
+ //#region src/v2/runtime/core/debug-event-bus.d.ts
6
+ type DebugEventListener = (envelope: DebugEventEnvelope) => void;
7
+ declare class DebugEventBus {
8
+ private listeners;
9
+ subscribe(listener: DebugEventListener): () => void;
10
+ broadcast(event: BaseEvent, metadata: {
11
+ agentId: string;
12
+ threadId: string;
13
+ runId: string;
14
+ }): void;
15
+ get listenerCount(): number;
16
+ }
17
+ //#endregion
18
+ export { DebugEventBus };
19
+ //# sourceMappingURL=debug-event-bus.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debug-event-bus.d.mts","names":[],"sources":["../../../../src/v2/runtime/core/debug-event-bus.ts"],"mappings":";;;;;KAGY,kBAAA,IAAsB,QAAA,EAAU,kBAAA;AAAA,cAE/B,aAAA;EAAA,QACH,SAAA;EAER,SAAA,CAAU,QAAA,EAAU,kBAAA;EAOpB,SAAA,CACE,KAAA,EAAO,SAAA,EACP,QAAA;IAAY,OAAA;IAAiB,QAAA;IAAkB,KAAA;EAAA;EAAA,IAwB7C,aAAA,CAAA;AAAA"}
@@ -0,0 +1,35 @@
1
+ import "reflect-metadata";
2
+ //#region src/v2/runtime/core/debug-event-bus.ts
3
+ var DebugEventBus = class {
4
+ constructor() {
5
+ this.listeners = /* @__PURE__ */ new Set();
6
+ }
7
+ subscribe(listener) {
8
+ this.listeners.add(listener);
9
+ return () => {
10
+ this.listeners.delete(listener);
11
+ };
12
+ }
13
+ broadcast(event, metadata) {
14
+ if (this.listeners.size === 0) return;
15
+ const envelope = {
16
+ timestamp: Date.now(),
17
+ agentId: metadata.agentId,
18
+ threadId: metadata.threadId,
19
+ runId: metadata.runId,
20
+ event
21
+ };
22
+ for (const listener of this.listeners) try {
23
+ listener(envelope);
24
+ } catch (err) {
25
+ console.warn("[DebugEventBus] Listener error suppressed:", err instanceof Error ? err.message : err);
26
+ }
27
+ }
28
+ get listenerCount() {
29
+ return this.listeners.size;
30
+ }
31
+ };
32
+
33
+ //#endregion
34
+ export { DebugEventBus };
35
+ //# sourceMappingURL=debug-event-bus.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debug-event-bus.mjs","names":[],"sources":["../../../../src/v2/runtime/core/debug-event-bus.ts"],"sourcesContent":["import { BaseEvent } from \"@ag-ui/client\";\nimport { DebugEventEnvelope } from \"@copilotkit/shared\";\n\nexport type DebugEventListener = (envelope: DebugEventEnvelope) => void;\n\nexport class DebugEventBus {\n private listeners = new Set<DebugEventListener>();\n\n subscribe(listener: DebugEventListener): () => void {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n broadcast(\n event: BaseEvent,\n metadata: { agentId: string; threadId: string; runId: string },\n ): void {\n if (this.listeners.size === 0) return;\n\n const envelope: DebugEventEnvelope = {\n timestamp: Date.now(),\n agentId: metadata.agentId,\n threadId: metadata.threadId,\n runId: metadata.runId,\n event,\n };\n\n for (const listener of this.listeners) {\n try {\n listener(envelope);\n } catch (err) {\n console.warn(\n \"[DebugEventBus] Listener error suppressed:\",\n err instanceof Error ? err.message : err,\n );\n }\n }\n }\n\n get listenerCount(): number {\n return this.listeners.size;\n }\n}\n"],"mappings":";;AAKA,IAAa,gBAAb,MAA2B;;mCACL,IAAI,KAAyB;;CAEjD,UAAU,UAA0C;AAClD,OAAK,UAAU,IAAI,SAAS;AAC5B,eAAa;AACX,QAAK,UAAU,OAAO,SAAS;;;CAInC,UACE,OACA,UACM;AACN,MAAI,KAAK,UAAU,SAAS,EAAG;EAE/B,MAAM,WAA+B;GACnC,WAAW,KAAK,KAAK;GACrB,SAAS,SAAS;GAClB,UAAU,SAAS;GACnB,OAAO,SAAS;GAChB;GACD;AAED,OAAK,MAAM,YAAY,KAAK,UAC1B,KAAI;AACF,YAAS,SAAS;WACX,KAAK;AACZ,WAAQ,KACN,8CACA,eAAe,QAAQ,IAAI,UAAU,IACtC;;;CAKP,IAAI,gBAAwB;AAC1B,SAAO,KAAK,UAAU"}
@@ -9,6 +9,7 @@ const require_handle_connect = require('../handlers/handle-connect.cjs');
9
9
  const require_handle_stop = require('../handlers/handle-stop.cjs');
10
10
  const require_get_runtime_info = require('../handlers/get-runtime-info.cjs');
11
11
  const require_handle_transcribe = require('../handlers/handle-transcribe.cjs');
12
+ const require_handle_debug_events = require('../handlers/handle-debug-events.cjs');
12
13
  const require_threads = require('../handlers/intelligence/threads.cjs');
13
14
  const require_single_route_helpers = require('../endpoints/single-route-helpers.cjs');
14
15
  let _copilotkit_shared = require("@copilotkit/shared");
@@ -190,6 +191,10 @@ function dispatchRoute(runtime, request, route) {
190
191
  request,
191
192
  threadId: route.threadId
192
193
  });
194
+ case "cpk-debug-events": return Promise.resolve(require_handle_debug_events.handleDebugEvents({
195
+ runtime,
196
+ request
197
+ }));
193
198
  }
194
199
  }
195
200
  async function resolveSingleRoute(request, basePath, pathname) {
@@ -238,6 +243,7 @@ function validateHttpMethod(httpMethod, route) {
238
243
  case "info":
239
244
  case "threads/list":
240
245
  case "threads/messages":
246
+ case "cpk-debug-events":
241
247
  if (method === "GET") return null;
242
248
  return jsonResponse({ error: "Method not allowed" }, 405, { Allow: "GET" });
243
249
  case "threads/update":
@@ -1 +1 @@
1
- {"version":3,"file":"fetch-handler.cjs","names":["handleCors","runOnRequest","callBeforeRequestMiddleware","runOnBeforeHandler","createJsonRequest","matchRoute","runOnResponse","runOnError","handleRunAgent","handleConnectAgent","handleStopAgent","handleGetRuntimeInfo","handleTranscribe","handleListThreads","handleSubscribeToThreads","handleDeleteThread","handleUpdateThread","handleArchiveThread","handleGetThreadMessages","parseMethodCall","expectString","addCorsHeaders"],"sources":["../../../../src/v2/runtime/core/fetch-handler.ts"],"sourcesContent":["/**\n * Framework-agnostic CopilotKit runtime handler.\n *\n * Returns a pure `(Request) => Promise<Response>` function that can be used\n * directly with Bun, Deno, Cloudflare Workers, Next.js App Router, or any\n * Fetch-native runtime — no framework dependency required.\n *\n * @example\n * ```typescript\n * import { CopilotRuntime, createCopilotRuntimeHandler } from \"@copilotkit/runtime/v2\";\n *\n * const handler = createCopilotRuntimeHandler({\n * runtime: new CopilotRuntime({ agents: { ... } }),\n * basePath: \"/api/copilotkit\",\n * cors: true,\n * });\n *\n * // Bun\n * Bun.serve({ fetch: handler });\n *\n * // Deno\n * Deno.serve(handler);\n *\n * // Cloudflare Workers\n * export default { fetch: handler };\n * ```\n */\n\nimport type { CopilotRuntimeLike } from \"./runtime\";\nimport type { CopilotRuntimeHooks, RouteInfo, HookContext } from \"./hooks\";\nimport {\n runOnRequest,\n runOnBeforeHandler,\n runOnResponse,\n runOnError,\n} from \"./hooks\";\nimport type { CopilotCorsConfig } from \"./fetch-cors\";\nimport { handleCors, addCorsHeaders } from \"./fetch-cors\";\nimport { matchRoute } from \"./fetch-router\";\nimport {\n callBeforeRequestMiddleware,\n callAfterRequestMiddleware,\n} from \"./middleware\";\nimport { handleRunAgent } from \"../handlers/handle-run\";\nimport { handleConnectAgent } from \"../handlers/handle-connect\";\nimport { handleStopAgent } from \"../handlers/handle-stop\";\nimport { handleGetRuntimeInfo } from \"../handlers/get-runtime-info\";\nimport { handleTranscribe } from \"../handlers/handle-transcribe\";\nimport {\n handleListThreads,\n handleSubscribeToThreads,\n handleUpdateThread,\n handleArchiveThread,\n handleDeleteThread,\n handleGetThreadMessages,\n} from \"../handlers/handle-threads\";\nimport {\n parseMethodCall,\n createJsonRequest,\n expectString,\n type MethodCall,\n} from \"../endpoints/single-route-helpers\";\nimport { logger } from \"@copilotkit/shared\";\n\n/* ------------------------------------------------------------------------------------------------\n * Public types\n * --------------------------------------------------------------------------------------------- */\n\nexport interface CopilotRuntimeHandlerOptions {\n runtime: CopilotRuntimeLike;\n\n /**\n * Optional base path for routing.\n *\n * When provided: strict prefix stripping. The handler strips this prefix from the\n * URL pathname and matches the remainder against known routes.\n *\n * When omitted: suffix matching. The handler matches known route patterns as\n * suffixes of the URL pathname.\n */\n basePath?: string;\n\n /**\n * Endpoint mode:\n * - \"multi-route\" (default): Routes like POST /agent/:agentId/run, GET /info, etc.\n * - \"single-route\": Single POST endpoint with JSON envelope { method, params, body }\n */\n mode?: \"multi-route\" | \"single-route\";\n\n /**\n * Optional CORS configuration.\n * When not provided, no CORS headers are added (let the framework handle it).\n * Set to true for permissive defaults, or provide an object.\n */\n cors?: boolean | CopilotCorsConfig;\n\n /**\n * Lifecycle hooks for request processing.\n */\n hooks?: CopilotRuntimeHooks;\n}\n\nexport type CopilotRuntimeFetchHandler = (\n request: Request,\n) => Promise<Response>;\n\n/* ------------------------------------------------------------------------------------------------\n * Handler factory\n * --------------------------------------------------------------------------------------------- */\n\nexport function createCopilotRuntimeHandler(\n options: CopilotRuntimeHandlerOptions,\n): CopilotRuntimeFetchHandler {\n const { runtime, basePath, mode = \"multi-route\", cors, hooks } = options;\n\n const corsConfig = resolveCorsConfig(cors);\n\n return async (request: Request): Promise<Response> => {\n const url = new URL(request.url, \"http://localhost\");\n const path = url.pathname;\n const requestOrigin = request.headers.get(\"origin\");\n\n // Base hook context (route not yet known)\n const baseCtx: HookContext = { request, path, runtime };\n\n let route: RouteInfo | undefined;\n\n try {\n // 1. CORS preflight\n if (corsConfig) {\n const preflight = handleCors(request, corsConfig);\n if (preflight) return preflight;\n }\n\n // 2. onRequest hook\n request = await runOnRequest(hooks, { ...baseCtx, request });\n\n // 3. Legacy beforeRequestMiddleware\n try {\n const maybeModified = await callBeforeRequestMiddleware({\n runtime,\n request,\n path,\n });\n if (maybeModified) {\n request = maybeModified;\n }\n } catch (mwError: unknown) {\n logger.error(\n { err: mwError, url: request.url, path },\n \"Error running before request middleware\",\n );\n if (mwError instanceof Response) {\n return maybeAddCors(mwError, corsConfig, requestOrigin);\n }\n throw mwError;\n }\n\n // 4. Route matching\n let response: Response;\n\n if (mode === \"single-route\") {\n const resolved = await resolveSingleRoute(request, basePath, path);\n route = resolved.route;\n const { methodCall } = resolved;\n // 5. onBeforeHandler hook\n request = await runOnBeforeHandler(hooks, {\n request,\n path,\n runtime,\n route,\n });\n // 6. Wrap body for methods that need it, then dispatch\n if (\n route.method === \"agent/run\" ||\n route.method === \"agent/connect\" ||\n route.method === \"transcribe\"\n ) {\n request = createJsonRequest(request, methodCall.body);\n }\n response = await dispatchRoute(runtime, request, route);\n } else {\n // Multi-route: match URL pattern\n const matched = matchRoute(path, basePath);\n if (!matched) {\n throw jsonResponse({ error: \"Not found\" }, 404);\n }\n\n // Validate HTTP method\n const methodError = validateHttpMethod(request.method, matched);\n if (methodError) {\n route = matched;\n throw methodError;\n }\n\n route = matched;\n\n // 5. onBeforeHandler hook\n request = await runOnBeforeHandler(hooks, {\n request,\n path,\n runtime,\n route,\n });\n\n // 6. Handler dispatch\n response = await dispatchRoute(runtime, request, route);\n }\n\n // 7. onResponse hook\n response = await runOnResponse(hooks, {\n request,\n response,\n path,\n runtime,\n route,\n });\n\n // 8. CORS headers on response\n response = maybeAddCors(response, corsConfig, requestOrigin);\n\n // 9. Legacy afterRequestMiddleware (non-blocking)\n // Clone the response so middleware can read the body without consuming\n // the original stream that will be sent to the client.\n callAfterRequestMiddleware({\n runtime,\n response: response.clone(),\n path,\n }).catch((error: unknown) => {\n logger.error(\n { err: error, url: request.url, path },\n \"Error running after request middleware\",\n );\n });\n\n return response;\n } catch (error) {\n // Short-circuit with thrown Response\n if (error instanceof Response) {\n const finalResponse = await runOnResponse(hooks, {\n request,\n response: error,\n path,\n runtime,\n route: route ?? { method: \"info\" },\n });\n return maybeAddCors(finalResponse, corsConfig, requestOrigin);\n }\n\n // Run onError hook — wrapped so a throwing hook doesn't escape\n try {\n const errorResponse = await runOnError(hooks, {\n request,\n error,\n path,\n runtime,\n route,\n });\n\n if (errorResponse) {\n return maybeAddCors(errorResponse, corsConfig, requestOrigin);\n }\n } catch (hookError: unknown) {\n logger.error(\n { err: hookError, originalErr: error, url: request.url, path },\n \"onError hook threw\",\n );\n }\n\n logger.error(\n { err: error, url: request.url, path },\n \"Unhandled error in CopilotKit runtime handler\",\n );\n\n return maybeAddCors(\n jsonResponse({ error: \"internal_error\" }, 500),\n corsConfig,\n requestOrigin,\n );\n }\n };\n}\n\n/* ------------------------------------------------------------------------------------------------\n * Route dispatch\n * --------------------------------------------------------------------------------------------- */\n\nfunction dispatchRoute(\n runtime: CopilotRuntimeLike,\n request: Request,\n route: RouteInfo,\n): Promise<Response> {\n switch (route.method) {\n case \"agent/run\":\n return handleRunAgent({\n runtime,\n request,\n agentId: route.agentId,\n });\n case \"agent/connect\":\n return handleConnectAgent({\n runtime,\n request,\n agentId: route.agentId,\n });\n case \"agent/stop\":\n return handleStopAgent({\n runtime,\n request,\n agentId: route.agentId,\n threadId: route.threadId,\n });\n case \"info\":\n return handleGetRuntimeInfo({ runtime, request });\n case \"transcribe\":\n return handleTranscribe({ runtime, request });\n case \"threads/list\":\n return handleListThreads({ runtime, request });\n case \"threads/subscribe\":\n return handleSubscribeToThreads({ runtime, request });\n case \"threads/update\":\n if (request.method.toUpperCase() === \"DELETE\") {\n return handleDeleteThread({\n runtime,\n request,\n threadId: route.threadId,\n });\n }\n return handleUpdateThread({ runtime, request, threadId: route.threadId });\n case \"threads/archive\":\n return handleArchiveThread({\n runtime,\n request,\n threadId: route.threadId,\n });\n case \"threads/messages\":\n return handleGetThreadMessages({\n runtime,\n request,\n threadId: route.threadId,\n });\n }\n}\n\ninterface SingleRouteResolution {\n route: RouteInfo;\n methodCall: MethodCall;\n}\n\nasync function resolveSingleRoute(\n request: Request,\n basePath: string | undefined,\n pathname: string,\n): Promise<SingleRouteResolution> {\n if (basePath) {\n const normalizedBase =\n basePath.length > 1 && basePath.endsWith(\"/\")\n ? basePath.slice(0, -1)\n : basePath;\n if (!pathname.startsWith(normalizedBase)) {\n throw jsonResponse({ error: \"Not found\" }, 404);\n }\n }\n\n if (request.method !== \"POST\") {\n throw jsonResponse({ error: \"Method not allowed\" }, 405, { Allow: \"POST\" });\n }\n\n const methodCall = await parseMethodCall(request);\n\n let route: RouteInfo;\n switch (methodCall.method) {\n case \"agent/run\":\n route = {\n method: \"agent/run\",\n agentId: expectString(methodCall.params, \"agentId\"),\n };\n break;\n case \"agent/connect\":\n route = {\n method: \"agent/connect\",\n agentId: expectString(methodCall.params, \"agentId\"),\n };\n break;\n case \"agent/stop\":\n route = {\n method: \"agent/stop\",\n agentId: expectString(methodCall.params, \"agentId\"),\n threadId: expectString(methodCall.params, \"threadId\"),\n };\n break;\n case \"info\":\n route = { method: \"info\" };\n break;\n case \"transcribe\":\n route = { method: \"transcribe\" };\n break;\n }\n\n return { route, methodCall };\n}\n\n/* ------------------------------------------------------------------------------------------------\n * HTTP method validation\n * --------------------------------------------------------------------------------------------- */\n\nfunction validateHttpMethod(\n httpMethod: string,\n route: RouteInfo,\n): Response | null {\n const method = httpMethod.toUpperCase();\n\n switch (route.method) {\n case \"info\":\n case \"threads/list\":\n case \"threads/messages\":\n if (method === \"GET\") return null;\n return jsonResponse({ error: \"Method not allowed\" }, 405, {\n Allow: \"GET\",\n });\n\n case \"threads/update\":\n if (method === \"PATCH\" || method === \"DELETE\") return null;\n return jsonResponse({ error: \"Method not allowed\" }, 405, {\n Allow: \"PATCH, DELETE\",\n });\n\n default:\n if (method === \"POST\") return null;\n return jsonResponse({ error: \"Method not allowed\" }, 405, {\n Allow: \"POST\",\n });\n }\n}\n\n/* ------------------------------------------------------------------------------------------------\n * Helpers\n * --------------------------------------------------------------------------------------------- */\n\nfunction resolveCorsConfig(\n cors: boolean | CopilotCorsConfig | undefined,\n): CopilotCorsConfig | null {\n if (!cors) return null;\n if (cors === true) return {};\n return cors;\n}\n\nfunction maybeAddCors(\n response: Response,\n config: CopilotCorsConfig | null,\n requestOrigin: string | null,\n): Response {\n if (!config) return response;\n return addCorsHeaders(response, config, requestOrigin);\n}\n\nfunction jsonResponse(\n body: unknown,\n status: number,\n extraHeaders?: Record<string, string>,\n): Response {\n return new Response(JSON.stringify(body), {\n status,\n headers: { \"Content-Type\": \"application/json\", ...extraHeaders },\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;AA8GA,SAAgB,4BACd,SAC4B;CAC5B,MAAM,EAAE,SAAS,UAAU,OAAO,eAAe,MAAM,UAAU;CAEjE,MAAM,aAAa,kBAAkB,KAAK;AAE1C,QAAO,OAAO,YAAwC;EAEpD,MAAM,OADM,IAAI,IAAI,QAAQ,KAAK,mBAAmB,CACnC;EACjB,MAAM,gBAAgB,QAAQ,QAAQ,IAAI,SAAS;EAGnD,MAAM,UAAuB;GAAE;GAAS;GAAM;GAAS;EAEvD,IAAI;AAEJ,MAAI;AAEF,OAAI,YAAY;IACd,MAAM,YAAYA,8BAAW,SAAS,WAAW;AACjD,QAAI,UAAW,QAAO;;AAIxB,aAAU,MAAMC,2BAAa,OAAO;IAAE,GAAG;IAAS;IAAS,CAAC;AAG5D,OAAI;IACF,MAAM,gBAAgB,MAAMC,+CAA4B;KACtD;KACA;KACA;KACD,CAAC;AACF,QAAI,cACF,WAAU;YAEL,SAAkB;AACzB,8BAAO,MACL;KAAE,KAAK;KAAS,KAAK,QAAQ;KAAK;KAAM,EACxC,0CACD;AACD,QAAI,mBAAmB,SACrB,QAAO,aAAa,SAAS,YAAY,cAAc;AAEzD,UAAM;;GAIR,IAAI;AAEJ,OAAI,SAAS,gBAAgB;IAC3B,MAAM,WAAW,MAAM,mBAAmB,SAAS,UAAU,KAAK;AAClE,YAAQ,SAAS;IACjB,MAAM,EAAE,eAAe;AAEvB,cAAU,MAAMC,iCAAmB,OAAO;KACxC;KACA;KACA;KACA;KACD,CAAC;AAEF,QACE,MAAM,WAAW,eACjB,MAAM,WAAW,mBACjB,MAAM,WAAW,aAEjB,WAAUC,+CAAkB,SAAS,WAAW,KAAK;AAEvD,eAAW,MAAM,cAAc,SAAS,SAAS,MAAM;UAClD;IAEL,MAAM,UAAUC,gCAAW,MAAM,SAAS;AAC1C,QAAI,CAAC,QACH,OAAM,aAAa,EAAE,OAAO,aAAa,EAAE,IAAI;IAIjD,MAAM,cAAc,mBAAmB,QAAQ,QAAQ,QAAQ;AAC/D,QAAI,aAAa;AACf,aAAQ;AACR,WAAM;;AAGR,YAAQ;AAGR,cAAU,MAAMF,iCAAmB,OAAO;KACxC;KACA;KACA;KACA;KACD,CAAC;AAGF,eAAW,MAAM,cAAc,SAAS,SAAS,MAAM;;AAIzD,cAAW,MAAMG,4BAAc,OAAO;IACpC;IACA;IACA;IACA;IACA;IACD,CAAC;AAGF,cAAW,aAAa,UAAU,YAAY,cAAc;AAK5D,iDAA2B;IACzB;IACA,UAAU,SAAS,OAAO;IAC1B;IACD,CAAC,CAAC,OAAO,UAAmB;AAC3B,8BAAO,MACL;KAAE,KAAK;KAAO,KAAK,QAAQ;KAAK;KAAM,EACtC,yCACD;KACD;AAEF,UAAO;WACA,OAAO;AAEd,OAAI,iBAAiB,SAQnB,QAAO,aAPe,MAAMA,4BAAc,OAAO;IAC/C;IACA,UAAU;IACV;IACA;IACA,OAAO,SAAS,EAAE,QAAQ,QAAQ;IACnC,CAAC,EACiC,YAAY,cAAc;AAI/D,OAAI;IACF,MAAM,gBAAgB,MAAMC,yBAAW,OAAO;KAC5C;KACA;KACA;KACA;KACA;KACD,CAAC;AAEF,QAAI,cACF,QAAO,aAAa,eAAe,YAAY,cAAc;YAExD,WAAoB;AAC3B,8BAAO,MACL;KAAE,KAAK;KAAW,aAAa;KAAO,KAAK,QAAQ;KAAK;KAAM,EAC9D,qBACD;;AAGH,6BAAO,MACL;IAAE,KAAK;IAAO,KAAK,QAAQ;IAAK;IAAM,EACtC,gDACD;AAED,UAAO,aACL,aAAa,EAAE,OAAO,kBAAkB,EAAE,IAAI,EAC9C,YACA,cACD;;;;AASP,SAAS,cACP,SACA,SACA,OACmB;AACnB,SAAQ,MAAM,QAAd;EACE,KAAK,YACH,QAAOC,kCAAe;GACpB;GACA;GACA,SAAS,MAAM;GAChB,CAAC;EACJ,KAAK,gBACH,QAAOC,0CAAmB;GACxB;GACA;GACA,SAAS,MAAM;GAChB,CAAC;EACJ,KAAK,aACH,QAAOC,oCAAgB;GACrB;GACA;GACA,SAAS,MAAM;GACf,UAAU,MAAM;GACjB,CAAC;EACJ,KAAK,OACH,QAAOC,8CAAqB;GAAE;GAAS;GAAS,CAAC;EACnD,KAAK,aACH,QAAOC,2CAAiB;GAAE;GAAS;GAAS,CAAC;EAC/C,KAAK,eACH,QAAOC,kCAAkB;GAAE;GAAS;GAAS,CAAC;EAChD,KAAK,oBACH,QAAOC,yCAAyB;GAAE;GAAS;GAAS,CAAC;EACvD,KAAK;AACH,OAAI,QAAQ,OAAO,aAAa,KAAK,SACnC,QAAOC,mCAAmB;IACxB;IACA;IACA,UAAU,MAAM;IACjB,CAAC;AAEJ,UAAOC,mCAAmB;IAAE;IAAS;IAAS,UAAU,MAAM;IAAU,CAAC;EAC3E,KAAK,kBACH,QAAOC,oCAAoB;GACzB;GACA;GACA,UAAU,MAAM;GACjB,CAAC;EACJ,KAAK,mBACH,QAAOC,wCAAwB;GAC7B;GACA;GACA,UAAU,MAAM;GACjB,CAAC;;;AASR,eAAe,mBACb,SACA,UACA,UACgC;AAChC,KAAI,UAAU;EACZ,MAAM,iBACJ,SAAS,SAAS,KAAK,SAAS,SAAS,IAAI,GACzC,SAAS,MAAM,GAAG,GAAG,GACrB;AACN,MAAI,CAAC,SAAS,WAAW,eAAe,CACtC,OAAM,aAAa,EAAE,OAAO,aAAa,EAAE,IAAI;;AAInD,KAAI,QAAQ,WAAW,OACrB,OAAM,aAAa,EAAE,OAAO,sBAAsB,EAAE,KAAK,EAAE,OAAO,QAAQ,CAAC;CAG7E,MAAM,aAAa,MAAMC,6CAAgB,QAAQ;CAEjD,IAAI;AACJ,SAAQ,WAAW,QAAnB;EACE,KAAK;AACH,WAAQ;IACN,QAAQ;IACR,SAASC,0CAAa,WAAW,QAAQ,UAAU;IACpD;AACD;EACF,KAAK;AACH,WAAQ;IACN,QAAQ;IACR,SAASA,0CAAa,WAAW,QAAQ,UAAU;IACpD;AACD;EACF,KAAK;AACH,WAAQ;IACN,QAAQ;IACR,SAASA,0CAAa,WAAW,QAAQ,UAAU;IACnD,UAAUA,0CAAa,WAAW,QAAQ,WAAW;IACtD;AACD;EACF,KAAK;AACH,WAAQ,EAAE,QAAQ,QAAQ;AAC1B;EACF,KAAK;AACH,WAAQ,EAAE,QAAQ,cAAc;AAChC;;AAGJ,QAAO;EAAE;EAAO;EAAY;;AAO9B,SAAS,mBACP,YACA,OACiB;CACjB,MAAM,SAAS,WAAW,aAAa;AAEvC,SAAQ,MAAM,QAAd;EACE,KAAK;EACL,KAAK;EACL,KAAK;AACH,OAAI,WAAW,MAAO,QAAO;AAC7B,UAAO,aAAa,EAAE,OAAO,sBAAsB,EAAE,KAAK,EACxD,OAAO,OACR,CAAC;EAEJ,KAAK;AACH,OAAI,WAAW,WAAW,WAAW,SAAU,QAAO;AACtD,UAAO,aAAa,EAAE,OAAO,sBAAsB,EAAE,KAAK,EACxD,OAAO,iBACR,CAAC;EAEJ;AACE,OAAI,WAAW,OAAQ,QAAO;AAC9B,UAAO,aAAa,EAAE,OAAO,sBAAsB,EAAE,KAAK,EACxD,OAAO,QACR,CAAC;;;AAQR,SAAS,kBACP,MAC0B;AAC1B,KAAI,CAAC,KAAM,QAAO;AAClB,KAAI,SAAS,KAAM,QAAO,EAAE;AAC5B,QAAO;;AAGT,SAAS,aACP,UACA,QACA,eACU;AACV,KAAI,CAAC,OAAQ,QAAO;AACpB,QAAOC,kCAAe,UAAU,QAAQ,cAAc;;AAGxD,SAAS,aACP,MACA,QACA,cACU;AACV,QAAO,IAAI,SAAS,KAAK,UAAU,KAAK,EAAE;EACxC;EACA,SAAS;GAAE,gBAAgB;GAAoB,GAAG;GAAc;EACjE,CAAC"}
1
+ {"version":3,"file":"fetch-handler.cjs","names":["handleCors","runOnRequest","callBeforeRequestMiddleware","runOnBeforeHandler","createJsonRequest","matchRoute","runOnResponse","runOnError","handleRunAgent","handleConnectAgent","handleStopAgent","handleGetRuntimeInfo","handleTranscribe","handleListThreads","handleSubscribeToThreads","handleDeleteThread","handleUpdateThread","handleArchiveThread","handleGetThreadMessages","handleDebugEvents","parseMethodCall","expectString","addCorsHeaders"],"sources":["../../../../src/v2/runtime/core/fetch-handler.ts"],"sourcesContent":["/**\n * Framework-agnostic CopilotKit runtime handler.\n *\n * Returns a pure `(Request) => Promise<Response>` function that can be used\n * directly with Bun, Deno, Cloudflare Workers, Next.js App Router, or any\n * Fetch-native runtime — no framework dependency required.\n *\n * @example\n * ```typescript\n * import { CopilotRuntime, createCopilotRuntimeHandler } from \"@copilotkit/runtime/v2\";\n *\n * const handler = createCopilotRuntimeHandler({\n * runtime: new CopilotRuntime({ agents: { ... } }),\n * basePath: \"/api/copilotkit\",\n * cors: true,\n * });\n *\n * // Bun\n * Bun.serve({ fetch: handler });\n *\n * // Deno\n * Deno.serve(handler);\n *\n * // Cloudflare Workers\n * export default { fetch: handler };\n * ```\n */\n\nimport type { CopilotRuntimeLike } from \"./runtime\";\nimport type { CopilotRuntimeHooks, RouteInfo, HookContext } from \"./hooks\";\nimport {\n runOnRequest,\n runOnBeforeHandler,\n runOnResponse,\n runOnError,\n} from \"./hooks\";\nimport type { CopilotCorsConfig } from \"./fetch-cors\";\nimport { handleCors, addCorsHeaders } from \"./fetch-cors\";\nimport { matchRoute } from \"./fetch-router\";\nimport {\n callBeforeRequestMiddleware,\n callAfterRequestMiddleware,\n} from \"./middleware\";\nimport { handleRunAgent } from \"../handlers/handle-run\";\nimport { handleConnectAgent } from \"../handlers/handle-connect\";\nimport { handleStopAgent } from \"../handlers/handle-stop\";\nimport { handleGetRuntimeInfo } from \"../handlers/get-runtime-info\";\nimport { handleTranscribe } from \"../handlers/handle-transcribe\";\nimport { handleDebugEvents } from \"../handlers/handle-debug-events\";\nimport {\n handleListThreads,\n handleSubscribeToThreads,\n handleUpdateThread,\n handleArchiveThread,\n handleDeleteThread,\n handleGetThreadMessages,\n} from \"../handlers/handle-threads\";\nimport {\n parseMethodCall,\n createJsonRequest,\n expectString,\n type MethodCall,\n} from \"../endpoints/single-route-helpers\";\nimport { logger } from \"@copilotkit/shared\";\n\n/* ------------------------------------------------------------------------------------------------\n * Public types\n * --------------------------------------------------------------------------------------------- */\n\nexport interface CopilotRuntimeHandlerOptions {\n runtime: CopilotRuntimeLike;\n\n /**\n * Optional base path for routing.\n *\n * When provided: strict prefix stripping. The handler strips this prefix from the\n * URL pathname and matches the remainder against known routes.\n *\n * When omitted: suffix matching. The handler matches known route patterns as\n * suffixes of the URL pathname.\n */\n basePath?: string;\n\n /**\n * Endpoint mode:\n * - \"multi-route\" (default): Routes like POST /agent/:agentId/run, GET /info, etc.\n * - \"single-route\": Single POST endpoint with JSON envelope { method, params, body }\n */\n mode?: \"multi-route\" | \"single-route\";\n\n /**\n * Optional CORS configuration.\n * When not provided, no CORS headers are added (let the framework handle it).\n * Set to true for permissive defaults, or provide an object.\n */\n cors?: boolean | CopilotCorsConfig;\n\n /**\n * Lifecycle hooks for request processing.\n */\n hooks?: CopilotRuntimeHooks;\n}\n\nexport type CopilotRuntimeFetchHandler = (\n request: Request,\n) => Promise<Response>;\n\n/* ------------------------------------------------------------------------------------------------\n * Handler factory\n * --------------------------------------------------------------------------------------------- */\n\nexport function createCopilotRuntimeHandler(\n options: CopilotRuntimeHandlerOptions,\n): CopilotRuntimeFetchHandler {\n const { runtime, basePath, mode = \"multi-route\", cors, hooks } = options;\n\n const corsConfig = resolveCorsConfig(cors);\n\n return async (request: Request): Promise<Response> => {\n const url = new URL(request.url, \"http://localhost\");\n const path = url.pathname;\n const requestOrigin = request.headers.get(\"origin\");\n\n // Base hook context (route not yet known)\n const baseCtx: HookContext = { request, path, runtime };\n\n let route: RouteInfo | undefined;\n\n try {\n // 1. CORS preflight\n if (corsConfig) {\n const preflight = handleCors(request, corsConfig);\n if (preflight) return preflight;\n }\n\n // 2. onRequest hook\n request = await runOnRequest(hooks, { ...baseCtx, request });\n\n // 3. Legacy beforeRequestMiddleware\n try {\n const maybeModified = await callBeforeRequestMiddleware({\n runtime,\n request,\n path,\n });\n if (maybeModified) {\n request = maybeModified;\n }\n } catch (mwError: unknown) {\n logger.error(\n { err: mwError, url: request.url, path },\n \"Error running before request middleware\",\n );\n if (mwError instanceof Response) {\n return maybeAddCors(mwError, corsConfig, requestOrigin);\n }\n throw mwError;\n }\n\n // 4. Route matching\n let response: Response;\n\n if (mode === \"single-route\") {\n const resolved = await resolveSingleRoute(request, basePath, path);\n route = resolved.route;\n const { methodCall } = resolved;\n // 5. onBeforeHandler hook\n request = await runOnBeforeHandler(hooks, {\n request,\n path,\n runtime,\n route,\n });\n // 6. Wrap body for methods that need it, then dispatch\n if (\n route.method === \"agent/run\" ||\n route.method === \"agent/connect\" ||\n route.method === \"transcribe\"\n ) {\n request = createJsonRequest(request, methodCall.body);\n }\n response = await dispatchRoute(runtime, request, route);\n } else {\n // Multi-route: match URL pattern\n const matched = matchRoute(path, basePath);\n if (!matched) {\n throw jsonResponse({ error: \"Not found\" }, 404);\n }\n\n // Validate HTTP method\n const methodError = validateHttpMethod(request.method, matched);\n if (methodError) {\n route = matched;\n throw methodError;\n }\n\n route = matched;\n\n // 5. onBeforeHandler hook\n request = await runOnBeforeHandler(hooks, {\n request,\n path,\n runtime,\n route,\n });\n\n // 6. Handler dispatch\n response = await dispatchRoute(runtime, request, route);\n }\n\n // 7. onResponse hook\n response = await runOnResponse(hooks, {\n request,\n response,\n path,\n runtime,\n route,\n });\n\n // 8. CORS headers on response\n response = maybeAddCors(response, corsConfig, requestOrigin);\n\n // 9. Legacy afterRequestMiddleware (non-blocking)\n // Clone the response so middleware can read the body without consuming\n // the original stream that will be sent to the client.\n callAfterRequestMiddleware({\n runtime,\n response: response.clone(),\n path,\n }).catch((error: unknown) => {\n logger.error(\n { err: error, url: request.url, path },\n \"Error running after request middleware\",\n );\n });\n\n return response;\n } catch (error) {\n // Short-circuit with thrown Response\n if (error instanceof Response) {\n const finalResponse = await runOnResponse(hooks, {\n request,\n response: error,\n path,\n runtime,\n route: route ?? { method: \"info\" },\n });\n return maybeAddCors(finalResponse, corsConfig, requestOrigin);\n }\n\n // Run onError hook — wrapped so a throwing hook doesn't escape\n try {\n const errorResponse = await runOnError(hooks, {\n request,\n error,\n path,\n runtime,\n route,\n });\n\n if (errorResponse) {\n return maybeAddCors(errorResponse, corsConfig, requestOrigin);\n }\n } catch (hookError: unknown) {\n logger.error(\n { err: hookError, originalErr: error, url: request.url, path },\n \"onError hook threw\",\n );\n }\n\n logger.error(\n { err: error, url: request.url, path },\n \"Unhandled error in CopilotKit runtime handler\",\n );\n\n return maybeAddCors(\n jsonResponse({ error: \"internal_error\" }, 500),\n corsConfig,\n requestOrigin,\n );\n }\n };\n}\n\n/* ------------------------------------------------------------------------------------------------\n * Route dispatch\n * --------------------------------------------------------------------------------------------- */\n\nfunction dispatchRoute(\n runtime: CopilotRuntimeLike,\n request: Request,\n route: RouteInfo,\n): Promise<Response> {\n switch (route.method) {\n case \"agent/run\":\n return handleRunAgent({\n runtime,\n request,\n agentId: route.agentId,\n });\n case \"agent/connect\":\n return handleConnectAgent({\n runtime,\n request,\n agentId: route.agentId,\n });\n case \"agent/stop\":\n return handleStopAgent({\n runtime,\n request,\n agentId: route.agentId,\n threadId: route.threadId,\n });\n case \"info\":\n return handleGetRuntimeInfo({ runtime, request });\n case \"transcribe\":\n return handleTranscribe({ runtime, request });\n case \"threads/list\":\n return handleListThreads({ runtime, request });\n case \"threads/subscribe\":\n return handleSubscribeToThreads({ runtime, request });\n case \"threads/update\":\n if (request.method.toUpperCase() === \"DELETE\") {\n return handleDeleteThread({\n runtime,\n request,\n threadId: route.threadId,\n });\n }\n return handleUpdateThread({ runtime, request, threadId: route.threadId });\n case \"threads/archive\":\n return handleArchiveThread({\n runtime,\n request,\n threadId: route.threadId,\n });\n case \"threads/messages\":\n return handleGetThreadMessages({\n runtime,\n request,\n threadId: route.threadId,\n });\n case \"cpk-debug-events\":\n return Promise.resolve(handleDebugEvents({ runtime, request }));\n }\n}\n\ninterface SingleRouteResolution {\n route: RouteInfo;\n methodCall: MethodCall;\n}\n\nasync function resolveSingleRoute(\n request: Request,\n basePath: string | undefined,\n pathname: string,\n): Promise<SingleRouteResolution> {\n if (basePath) {\n const normalizedBase =\n basePath.length > 1 && basePath.endsWith(\"/\")\n ? basePath.slice(0, -1)\n : basePath;\n if (!pathname.startsWith(normalizedBase)) {\n throw jsonResponse({ error: \"Not found\" }, 404);\n }\n }\n\n if (request.method !== \"POST\") {\n throw jsonResponse({ error: \"Method not allowed\" }, 405, { Allow: \"POST\" });\n }\n\n const methodCall = await parseMethodCall(request);\n\n let route: RouteInfo;\n switch (methodCall.method) {\n case \"agent/run\":\n route = {\n method: \"agent/run\",\n agentId: expectString(methodCall.params, \"agentId\"),\n };\n break;\n case \"agent/connect\":\n route = {\n method: \"agent/connect\",\n agentId: expectString(methodCall.params, \"agentId\"),\n };\n break;\n case \"agent/stop\":\n route = {\n method: \"agent/stop\",\n agentId: expectString(methodCall.params, \"agentId\"),\n threadId: expectString(methodCall.params, \"threadId\"),\n };\n break;\n case \"info\":\n route = { method: \"info\" };\n break;\n case \"transcribe\":\n route = { method: \"transcribe\" };\n break;\n }\n\n return { route, methodCall };\n}\n\n/* ------------------------------------------------------------------------------------------------\n * HTTP method validation\n * --------------------------------------------------------------------------------------------- */\n\nfunction validateHttpMethod(\n httpMethod: string,\n route: RouteInfo,\n): Response | null {\n const method = httpMethod.toUpperCase();\n\n switch (route.method) {\n case \"info\":\n case \"threads/list\":\n case \"threads/messages\":\n case \"cpk-debug-events\":\n if (method === \"GET\") return null;\n return jsonResponse({ error: \"Method not allowed\" }, 405, {\n Allow: \"GET\",\n });\n\n case \"threads/update\":\n if (method === \"PATCH\" || method === \"DELETE\") return null;\n return jsonResponse({ error: \"Method not allowed\" }, 405, {\n Allow: \"PATCH, DELETE\",\n });\n\n default:\n if (method === \"POST\") return null;\n return jsonResponse({ error: \"Method not allowed\" }, 405, {\n Allow: \"POST\",\n });\n }\n}\n\n/* ------------------------------------------------------------------------------------------------\n * Helpers\n * --------------------------------------------------------------------------------------------- */\n\nfunction resolveCorsConfig(\n cors: boolean | CopilotCorsConfig | undefined,\n): CopilotCorsConfig | null {\n if (!cors) return null;\n if (cors === true) return {};\n return cors;\n}\n\nfunction maybeAddCors(\n response: Response,\n config: CopilotCorsConfig | null,\n requestOrigin: string | null,\n): Response {\n if (!config) return response;\n return addCorsHeaders(response, config, requestOrigin);\n}\n\nfunction jsonResponse(\n body: unknown,\n status: number,\n extraHeaders?: Record<string, string>,\n): Response {\n return new Response(JSON.stringify(body), {\n status,\n headers: { \"Content-Type\": \"application/json\", ...extraHeaders },\n });\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"fetch-handler.d.cts","names":[],"sources":["../../../../src/v2/runtime/core/fetch-handler.ts"],"mappings":";;;;;;UAoEiB,4BAAA;EACf,OAAA,EAAS,kBAAA;EAkCT;;;;;AAOF;;;;EA9BE,QAAA;EA+BA;;;;;EAxBA,IAAA;;;;;;EAOA,IAAA,aAAiB,iBAAA;;;;EAKjB,KAAA,GAAQ,mBAAA;AAAA;AAAA,KAGE,0BAAA,IACV,OAAA,EAAS,OAAA,KACN,OAAA,CAAQ,QAAA;AAAA,iBAMG,2BAAA,CACd,OAAA,EAAS,4BAAA,GACR,0BAAA"}
1
+ {"version":3,"file":"fetch-handler.d.cts","names":[],"sources":["../../../../src/v2/runtime/core/fetch-handler.ts"],"mappings":";;;;;;UAqEiB,4BAAA;EACf,OAAA,EAAS,kBAAA;EAkCT;;;;;AAOF;;;;EA9BE,QAAA;EA+BA;;;;;EAxBA,IAAA;;;;;;EAOA,IAAA,aAAiB,iBAAA;;;;EAKjB,KAAA,GAAQ,mBAAA;AAAA;AAAA,KAGE,0BAAA,IACV,OAAA,EAAS,OAAA,KACN,OAAA,CAAQ,QAAA;AAAA,iBAMG,2BAAA,CACd,OAAA,EAAS,4BAAA,GACR,0BAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"fetch-handler.d.mts","names":[],"sources":["../../../../src/v2/runtime/core/fetch-handler.ts"],"mappings":";;;;;;UAoEiB,4BAAA;EACf,OAAA,EAAS,kBAAA;EAkCT;;;;;AAOF;;;;EA9BE,QAAA;EA+BA;;;;;EAxBA,IAAA;;;;;;EAOA,IAAA,aAAiB,iBAAA;;;;EAKjB,KAAA,GAAQ,mBAAA;AAAA;AAAA,KAGE,0BAAA,IACV,OAAA,EAAS,OAAA,KACN,OAAA,CAAQ,QAAA;AAAA,iBAMG,2BAAA,CACd,OAAA,EAAS,4BAAA,GACR,0BAAA"}
1
+ {"version":3,"file":"fetch-handler.d.mts","names":[],"sources":["../../../../src/v2/runtime/core/fetch-handler.ts"],"mappings":";;;;;;UAqEiB,4BAAA;EACf,OAAA,EAAS,kBAAA;EAkCT;;;;;AAOF;;;;EA9BE,QAAA;EA+BA;;;;;EAxBA,IAAA;;;;;;EAOA,IAAA,aAAiB,iBAAA;;;;EAKjB,KAAA,GAAQ,mBAAA;AAAA;AAAA,KAGE,0BAAA,IACV,OAAA,EAAS,OAAA,KACN,OAAA,CAAQ,QAAA;AAAA,iBAMG,2BAAA,CACd,OAAA,EAAS,4BAAA,GACR,0BAAA"}
@@ -8,6 +8,7 @@ import { handleConnectAgent } from "../handlers/handle-connect.mjs";
8
8
  import { handleStopAgent } from "../handlers/handle-stop.mjs";
9
9
  import { handleGetRuntimeInfo } from "../handlers/get-runtime-info.mjs";
10
10
  import { handleTranscribe } from "../handlers/handle-transcribe.mjs";
11
+ import { handleDebugEvents } from "../handlers/handle-debug-events.mjs";
11
12
  import { handleArchiveThread, handleDeleteThread, handleGetThreadMessages, handleListThreads, handleSubscribeToThreads, handleUpdateThread } from "../handlers/intelligence/threads.mjs";
12
13
  import { createJsonRequest, expectString, parseMethodCall } from "../endpoints/single-route-helpers.mjs";
13
14
  import { logger } from "@copilotkit/shared";
@@ -189,6 +190,10 @@ function dispatchRoute(runtime, request, route) {
189
190
  request,
190
191
  threadId: route.threadId
191
192
  });
193
+ case "cpk-debug-events": return Promise.resolve(handleDebugEvents({
194
+ runtime,
195
+ request
196
+ }));
192
197
  }
193
198
  }
194
199
  async function resolveSingleRoute(request, basePath, pathname) {
@@ -237,6 +242,7 @@ function validateHttpMethod(httpMethod, route) {
237
242
  case "info":
238
243
  case "threads/list":
239
244
  case "threads/messages":
245
+ case "cpk-debug-events":
240
246
  if (method === "GET") return null;
241
247
  return jsonResponse({ error: "Method not allowed" }, 405, { Allow: "GET" });
242
248
  case "threads/update":