@copilotkit/runtime 1.55.0-next.8 → 1.55.0

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 (345) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/agent/index.cjs +101 -12
  3. package/dist/agent/index.cjs.map +1 -1
  4. package/dist/agent/index.d.cts.map +1 -1
  5. package/dist/agent/index.d.mts.map +1 -1
  6. package/dist/agent/index.mjs +102 -13
  7. package/dist/agent/index.mjs.map +1 -1
  8. package/dist/lib/runtime/agent-integrations/langgraph/agent.cjs.map +1 -1
  9. package/dist/lib/runtime/agent-integrations/langgraph/agent.d.cts +4 -841
  10. package/dist/lib/runtime/agent-integrations/langgraph/agent.d.cts.map +1 -1
  11. package/dist/lib/runtime/agent-integrations/langgraph/agent.d.mts +4 -841
  12. package/dist/lib/runtime/agent-integrations/langgraph/agent.d.mts.map +1 -1
  13. package/dist/lib/runtime/agent-integrations/langgraph/agent.mjs.map +1 -1
  14. package/dist/lib/runtime/copilot-runtime.cjs +3 -2
  15. package/dist/lib/runtime/copilot-runtime.cjs.map +1 -1
  16. package/dist/lib/runtime/copilot-runtime.d.cts +1 -1
  17. package/dist/lib/runtime/copilot-runtime.d.cts.map +1 -1
  18. package/dist/lib/runtime/copilot-runtime.d.mts +3 -3
  19. package/dist/lib/runtime/copilot-runtime.d.mts.map +1 -1
  20. package/dist/lib/runtime/copilot-runtime.mjs +3 -2
  21. package/dist/lib/runtime/copilot-runtime.mjs.map +1 -1
  22. package/dist/package.cjs +70 -47
  23. package/dist/package.mjs +70 -47
  24. package/dist/v2/express.cjs +8 -0
  25. package/dist/v2/express.d.cts +5 -0
  26. package/dist/v2/express.d.mts +5 -0
  27. package/dist/v2/express.mjs +5 -0
  28. package/dist/v2/hono.cjs +9 -0
  29. package/dist/v2/hono.d.cts +5 -0
  30. package/dist/v2/hono.d.mts +5 -0
  31. package/dist/v2/hono.mjs +5 -0
  32. package/dist/v2/index.cjs +8 -3
  33. package/dist/v2/index.d.cts +8 -5
  34. package/dist/v2/index.d.mts +8 -5
  35. package/dist/v2/index.mjs +5 -4
  36. package/dist/v2/node.cjs +8 -0
  37. package/dist/v2/node.d.cts +5 -0
  38. package/dist/v2/node.d.mts +5 -0
  39. package/dist/v2/node.mjs +5 -0
  40. package/dist/v2/runtime/core/fetch-cors.cjs +72 -0
  41. package/dist/v2/runtime/core/fetch-cors.cjs.map +1 -0
  42. package/dist/v2/runtime/core/fetch-cors.d.cts +20 -0
  43. package/dist/v2/runtime/core/fetch-cors.d.cts.map +1 -0
  44. package/dist/v2/runtime/core/fetch-cors.d.mts +20 -0
  45. package/dist/v2/runtime/core/fetch-cors.d.mts.map +1 -0
  46. package/dist/v2/runtime/core/fetch-cors.mjs +70 -0
  47. package/dist/v2/runtime/core/fetch-cors.mjs.map +1 -0
  48. package/dist/v2/runtime/core/fetch-handler.cjs +232 -0
  49. package/dist/v2/runtime/core/fetch-handler.cjs.map +1 -0
  50. package/dist/v2/runtime/core/fetch-handler.d.cts +40 -0
  51. package/dist/v2/runtime/core/fetch-handler.d.cts.map +1 -0
  52. package/dist/v2/runtime/core/fetch-handler.d.mts +40 -0
  53. package/dist/v2/runtime/core/fetch-handler.d.mts.map +1 -0
  54. package/dist/v2/runtime/core/fetch-handler.mjs +231 -0
  55. package/dist/v2/runtime/core/fetch-handler.mjs.map +1 -0
  56. package/dist/v2/runtime/core/fetch-router.cjs +68 -0
  57. package/dist/v2/runtime/core/fetch-router.cjs.map +1 -0
  58. package/dist/v2/runtime/core/fetch-router.mjs +67 -0
  59. package/dist/v2/runtime/core/fetch-router.mjs.map +1 -0
  60. package/dist/v2/runtime/core/hooks.cjs +29 -0
  61. package/dist/v2/runtime/core/hooks.cjs.map +1 -0
  62. package/dist/v2/runtime/core/hooks.d.cts +78 -0
  63. package/dist/v2/runtime/core/hooks.d.cts.map +1 -0
  64. package/dist/v2/runtime/core/hooks.d.mts +78 -0
  65. package/dist/v2/runtime/core/hooks.d.mts.map +1 -0
  66. package/dist/v2/runtime/core/hooks.mjs +25 -0
  67. package/dist/v2/runtime/core/hooks.mjs.map +1 -0
  68. package/dist/v2/runtime/{middleware-sse-parser.cjs → core/middleware-sse-parser.cjs} +2 -2
  69. package/dist/v2/runtime/core/middleware-sse-parser.cjs.map +1 -0
  70. package/dist/v2/runtime/{middleware-sse-parser.d.cts → core/middleware-sse-parser.d.cts} +1 -1
  71. package/dist/v2/runtime/core/middleware-sse-parser.d.cts.map +1 -0
  72. package/dist/v2/runtime/{middleware-sse-parser.d.mts → core/middleware-sse-parser.d.mts} +1 -1
  73. package/dist/v2/runtime/core/middleware-sse-parser.d.mts.map +1 -0
  74. package/dist/v2/runtime/{middleware-sse-parser.mjs → core/middleware-sse-parser.mjs} +1 -1
  75. package/dist/v2/runtime/core/middleware-sse-parser.mjs.map +1 -0
  76. package/dist/v2/runtime/{middleware.cjs → core/middleware.cjs} +2 -2
  77. package/dist/v2/runtime/core/middleware.cjs.map +1 -0
  78. package/dist/v2/runtime/{middleware.d.cts → core/middleware.d.cts} +1 -1
  79. package/dist/v2/runtime/core/middleware.d.cts.map +1 -0
  80. package/dist/v2/runtime/{middleware.d.mts → core/middleware.d.mts} +1 -1
  81. package/dist/v2/runtime/core/middleware.d.mts.map +1 -0
  82. package/dist/v2/runtime/{middleware.mjs → core/middleware.mjs} +1 -1
  83. package/dist/v2/runtime/core/middleware.mjs.map +1 -0
  84. package/dist/v2/runtime/{runtime.cjs → core/runtime.cjs} +35 -10
  85. package/dist/v2/runtime/core/runtime.cjs.map +1 -0
  86. package/dist/v2/runtime/{runtime.d.cts → core/runtime.d.cts} +41 -7
  87. package/dist/v2/runtime/core/runtime.d.cts.map +1 -0
  88. package/dist/v2/runtime/{runtime.d.mts → core/runtime.d.mts} +42 -8
  89. package/dist/v2/runtime/core/runtime.d.mts.map +1 -0
  90. package/dist/v2/runtime/{runtime.mjs → core/runtime.mjs} +36 -11
  91. package/dist/v2/runtime/core/runtime.mjs.map +1 -0
  92. package/dist/v2/runtime/endpoints/express-fetch-bridge.cjs +83 -0
  93. package/dist/v2/runtime/endpoints/express-fetch-bridge.cjs.map +1 -0
  94. package/dist/v2/runtime/endpoints/express-fetch-bridge.mjs +82 -0
  95. package/dist/v2/runtime/endpoints/express-fetch-bridge.mjs.map +1 -0
  96. package/dist/v2/runtime/endpoints/express-single.cjs +35 -181
  97. package/dist/v2/runtime/endpoints/express-single.cjs.map +1 -1
  98. package/dist/v2/runtime/endpoints/express-single.d.cts +35 -2
  99. package/dist/v2/runtime/endpoints/express-single.d.cts.map +1 -1
  100. package/dist/v2/runtime/endpoints/express-single.d.mts +35 -2
  101. package/dist/v2/runtime/endpoints/express-single.d.mts.map +1 -1
  102. package/dist/v2/runtime/endpoints/express-single.mjs +35 -178
  103. package/dist/v2/runtime/endpoints/express-single.mjs.map +1 -1
  104. package/dist/v2/runtime/endpoints/express.cjs +41 -195
  105. package/dist/v2/runtime/endpoints/express.cjs.map +1 -1
  106. package/dist/v2/runtime/endpoints/express.d.cts +26 -4
  107. package/dist/v2/runtime/endpoints/express.d.cts.map +1 -1
  108. package/dist/v2/runtime/endpoints/express.d.mts +26 -4
  109. package/dist/v2/runtime/endpoints/express.d.mts.map +1 -1
  110. package/dist/v2/runtime/endpoints/express.mjs +41 -195
  111. package/dist/v2/runtime/endpoints/express.mjs.map +1 -1
  112. package/dist/v2/runtime/endpoints/hono-single.cjs +11 -123
  113. package/dist/v2/runtime/endpoints/hono-single.cjs.map +1 -1
  114. package/dist/v2/runtime/endpoints/hono-single.d.cts +14 -11
  115. package/dist/v2/runtime/endpoints/hono-single.d.cts.map +1 -1
  116. package/dist/v2/runtime/endpoints/hono-single.d.mts +14 -11
  117. package/dist/v2/runtime/endpoints/hono-single.d.mts.map +1 -1
  118. package/dist/v2/runtime/endpoints/hono-single.mjs +11 -123
  119. package/dist/v2/runtime/endpoints/hono-single.mjs.map +1 -1
  120. package/dist/v2/runtime/endpoints/hono.cjs +23 -237
  121. package/dist/v2/runtime/endpoints/hono.cjs.map +1 -1
  122. package/dist/v2/runtime/endpoints/hono.d.cts +29 -120
  123. package/dist/v2/runtime/endpoints/hono.d.cts.map +1 -1
  124. package/dist/v2/runtime/endpoints/hono.d.mts +29 -120
  125. package/dist/v2/runtime/endpoints/hono.d.mts.map +1 -1
  126. package/dist/v2/runtime/endpoints/hono.mjs +22 -238
  127. package/dist/v2/runtime/endpoints/hono.mjs.map +1 -1
  128. package/dist/v2/runtime/endpoints/index.d.cts +2 -2
  129. package/dist/v2/runtime/endpoints/index.d.mts +2 -2
  130. package/dist/v2/runtime/endpoints/node-fetch-handler.cjs +26 -0
  131. package/dist/v2/runtime/endpoints/node-fetch-handler.cjs.map +1 -0
  132. package/dist/v2/runtime/endpoints/node-fetch-handler.d.cts +12 -0
  133. package/dist/v2/runtime/endpoints/node-fetch-handler.d.cts.map +1 -0
  134. package/dist/v2/runtime/endpoints/node-fetch-handler.d.mts +12 -0
  135. package/dist/v2/runtime/endpoints/node-fetch-handler.d.mts.map +1 -0
  136. package/dist/v2/runtime/endpoints/node-fetch-handler.mjs +24 -0
  137. package/dist/v2/runtime/endpoints/node-fetch-handler.mjs.map +1 -0
  138. package/dist/v2/runtime/endpoints/node.cjs +30 -0
  139. package/dist/v2/runtime/endpoints/node.cjs.map +1 -0
  140. package/dist/v2/runtime/endpoints/node.d.cts +27 -0
  141. package/dist/v2/runtime/endpoints/node.d.cts.map +1 -0
  142. package/dist/v2/runtime/endpoints/node.d.mts +27 -0
  143. package/dist/v2/runtime/endpoints/node.d.mts.map +1 -0
  144. package/dist/v2/runtime/endpoints/node.mjs +30 -0
  145. package/dist/v2/runtime/endpoints/node.mjs.map +1 -0
  146. package/dist/v2/runtime/express.d.cts +3 -0
  147. package/dist/v2/runtime/express.d.mts +3 -0
  148. package/dist/v2/runtime/handlers/get-runtime-info.cjs +2 -1
  149. package/dist/v2/runtime/handlers/get-runtime-info.cjs.map +1 -1
  150. package/dist/v2/runtime/handlers/get-runtime-info.mjs +2 -1
  151. package/dist/v2/runtime/handlers/get-runtime-info.mjs.map +1 -1
  152. package/dist/v2/runtime/handlers/handle-connect.cjs +6 -3
  153. package/dist/v2/runtime/handlers/handle-connect.cjs.map +1 -1
  154. package/dist/v2/runtime/handlers/handle-connect.mjs +6 -3
  155. package/dist/v2/runtime/handlers/handle-connect.mjs.map +1 -1
  156. package/dist/v2/runtime/handlers/handle-run.cjs +6 -3
  157. package/dist/v2/runtime/handlers/handle-run.cjs.map +1 -1
  158. package/dist/v2/runtime/handlers/handle-run.mjs +6 -3
  159. package/dist/v2/runtime/handlers/handle-run.mjs.map +1 -1
  160. package/dist/v2/runtime/handlers/handle-stop.cjs.map +1 -1
  161. package/dist/v2/runtime/handlers/handle-stop.mjs.map +1 -1
  162. package/dist/v2/runtime/handlers/handle-transcribe.cjs.map +1 -1
  163. package/dist/v2/runtime/handlers/handle-transcribe.mjs.map +1 -1
  164. package/dist/v2/runtime/handlers/intelligence/connect.cjs.map +1 -1
  165. package/dist/v2/runtime/handlers/intelligence/connect.mjs.map +1 -1
  166. package/dist/v2/runtime/handlers/intelligence/run.cjs +22 -1
  167. package/dist/v2/runtime/handlers/intelligence/run.cjs.map +1 -1
  168. package/dist/v2/runtime/handlers/intelligence/run.mjs +22 -1
  169. package/dist/v2/runtime/handlers/intelligence/run.mjs.map +1 -1
  170. package/dist/v2/runtime/handlers/intelligence/thread-names.cjs +1 -1
  171. package/dist/v2/runtime/handlers/intelligence/thread-names.cjs.map +1 -1
  172. package/dist/v2/runtime/handlers/intelligence/thread-names.mjs +1 -1
  173. package/dist/v2/runtime/handlers/intelligence/thread-names.mjs.map +1 -1
  174. package/dist/v2/runtime/handlers/shared/agent-utils.cjs +21 -6
  175. package/dist/v2/runtime/handlers/shared/agent-utils.cjs.map +1 -1
  176. package/dist/v2/runtime/handlers/shared/agent-utils.mjs +21 -6
  177. package/dist/v2/runtime/handlers/shared/agent-utils.mjs.map +1 -1
  178. package/dist/v2/runtime/handlers/shared/json-response.cjs +4 -1
  179. package/dist/v2/runtime/handlers/shared/json-response.cjs.map +1 -1
  180. package/dist/v2/runtime/handlers/shared/json-response.mjs +4 -1
  181. package/dist/v2/runtime/handlers/shared/json-response.mjs.map +1 -1
  182. package/dist/v2/runtime/handlers/shared/resolve-intelligence-user.cjs.map +1 -1
  183. package/dist/v2/runtime/handlers/shared/resolve-intelligence-user.mjs.map +1 -1
  184. package/dist/v2/runtime/handlers/sse/connect.cjs.map +1 -1
  185. package/dist/v2/runtime/handlers/sse/connect.mjs.map +1 -1
  186. package/dist/v2/runtime/handlers/sse/run.cjs.map +1 -1
  187. package/dist/v2/runtime/handlers/sse/run.mjs.map +1 -1
  188. package/dist/v2/runtime/hono.d.cts +3 -0
  189. package/dist/v2/runtime/hono.d.mts +3 -0
  190. package/dist/v2/runtime/index.d.cts +16 -4
  191. package/dist/v2/runtime/index.d.cts.map +1 -0
  192. package/dist/v2/runtime/index.d.mts +16 -4
  193. package/dist/v2/runtime/index.d.mts.map +1 -0
  194. package/dist/v2/runtime/intelligence-platform/client.cjs +10 -1
  195. package/dist/v2/runtime/intelligence-platform/client.cjs.map +1 -1
  196. package/dist/v2/runtime/intelligence-platform/client.d.cts +22 -0
  197. package/dist/v2/runtime/intelligence-platform/client.d.cts.map +1 -1
  198. package/dist/v2/runtime/intelligence-platform/client.d.mts +22 -0
  199. package/dist/v2/runtime/intelligence-platform/client.d.mts.map +1 -1
  200. package/dist/v2/runtime/intelligence-platform/client.mjs +10 -1
  201. package/dist/v2/runtime/intelligence-platform/client.mjs.map +1 -1
  202. package/dist/v2/runtime/node.d.cts +3 -0
  203. package/dist/v2/runtime/node.d.mts +3 -0
  204. package/dist/v2/runtime/open-generative-ui-middleware.cjs +282 -0
  205. package/dist/v2/runtime/open-generative-ui-middleware.cjs.map +1 -0
  206. package/dist/v2/runtime/open-generative-ui-middleware.mjs +280 -0
  207. package/dist/v2/runtime/open-generative-ui-middleware.mjs.map +1 -0
  208. package/dist/v2/runtime/runner/intelligence.cjs +4 -4
  209. package/dist/v2/runtime/runner/intelligence.cjs.map +1 -1
  210. package/dist/v2/runtime/runner/intelligence.d.cts +6 -2
  211. package/dist/v2/runtime/runner/intelligence.d.cts.map +1 -1
  212. package/dist/v2/runtime/runner/intelligence.d.mts +6 -2
  213. package/dist/v2/runtime/runner/intelligence.d.mts.map +1 -1
  214. package/dist/v2/runtime/runner/intelligence.mjs +4 -4
  215. package/dist/v2/runtime/runner/intelligence.mjs.map +1 -1
  216. package/dist/v2/runtime/telemetry/telemetry-client.cjs +37 -0
  217. package/dist/v2/runtime/telemetry/telemetry-client.cjs.map +1 -1
  218. package/dist/v2/runtime/telemetry/telemetry-client.mjs +36 -0
  219. package/dist/v2/runtime/telemetry/telemetry-client.mjs.map +1 -1
  220. package/dist/v2/runtime/telemetry/utils.cjs +15 -0
  221. package/dist/v2/runtime/telemetry/utils.cjs.map +1 -0
  222. package/dist/v2/runtime/telemetry/utils.mjs +14 -0
  223. package/dist/v2/runtime/telemetry/utils.mjs.map +1 -0
  224. package/package.json +81 -48
  225. package/src/agent/__tests__/multimodal.test.ts +176 -0
  226. package/src/agent/index.ts +130 -19
  227. package/src/lib/runtime/agent-integrations/langgraph/agent.ts +3 -3
  228. package/src/lib/runtime/copilot-runtime.ts +1 -0
  229. package/src/v2/express.ts +1 -0
  230. package/src/v2/hono.ts +1 -0
  231. package/src/v2/node.ts +1 -0
  232. package/src/v2/runtime/__tests__/backward-compat.test.ts +261 -0
  233. package/src/v2/runtime/__tests__/code-review-fixes.test.ts +500 -0
  234. package/src/v2/runtime/__tests__/cors-credentials.test.ts +2 -2
  235. package/src/v2/runtime/__tests__/express-adapter.test.ts +188 -0
  236. package/src/v2/runtime/__tests__/express-body-order.test.ts +1 -1
  237. package/src/v2/runtime/__tests__/express-fetch-bridge.test.ts +344 -0
  238. package/src/v2/runtime/__tests__/express-single-sse.test.ts +1 -1
  239. package/src/v2/runtime/__tests__/fetch-cors.test.ts +205 -0
  240. package/src/v2/runtime/__tests__/fetch-handler-validation.test.ts +372 -0
  241. package/src/v2/runtime/__tests__/fetch-handler.test.ts +456 -0
  242. package/src/v2/runtime/__tests__/fetch-router.test.ts +132 -0
  243. package/src/v2/runtime/__tests__/get-runtime-info.test.ts +4 -1
  244. package/src/v2/runtime/__tests__/handle-connect.test.ts +15 -13
  245. package/src/v2/runtime/__tests__/handle-run.test.ts +21 -17
  246. package/src/v2/runtime/__tests__/handle-threads.test.ts +1 -1
  247. package/src/v2/runtime/__tests__/handle-transcribe.test.ts +1 -1
  248. package/src/v2/runtime/__tests__/hono-adapter.test.ts +150 -0
  249. package/src/v2/runtime/__tests__/hooks-edge-cases.test.ts +457 -0
  250. package/src/v2/runtime/__tests__/hooks.test.ts +557 -0
  251. package/src/v2/runtime/__tests__/integration/bun/bun-servers.integration.test.ts +27 -0
  252. package/src/v2/runtime/__tests__/integration/bun/elysia-multi.ts +32 -0
  253. package/src/v2/runtime/__tests__/integration/bun/elysia-single.ts +33 -0
  254. package/src/v2/runtime/__tests__/integration/bun/hono-bun-multi.ts +25 -0
  255. package/src/v2/runtime/__tests__/integration/bun/hono-bun-single.ts +32 -0
  256. package/src/v2/runtime/__tests__/integration/helpers/create-test-runtime.ts +15 -0
  257. package/src/v2/runtime/__tests__/integration/helpers/sse-reader.ts +45 -0
  258. package/src/v2/runtime/__tests__/integration/helpers/test-agent.ts +58 -0
  259. package/src/v2/runtime/__tests__/integration/node-servers.integration.test.ts +39 -0
  260. package/src/v2/runtime/__tests__/integration/servers/express-multi.ts +35 -0
  261. package/src/v2/runtime/__tests__/integration/servers/express-single.ts +36 -0
  262. package/src/v2/runtime/__tests__/integration/servers/fetch-direct.ts +39 -0
  263. package/src/v2/runtime/__tests__/integration/servers/hono-multi.ts +30 -0
  264. package/src/v2/runtime/__tests__/integration/servers/hono-single.ts +37 -0
  265. package/src/v2/runtime/__tests__/integration/servers/node-multi.ts +45 -0
  266. package/src/v2/runtime/__tests__/integration/servers/node-single.ts +46 -0
  267. package/src/v2/runtime/__tests__/integration/servers/types.ts +18 -0
  268. package/src/v2/runtime/__tests__/integration/suites/multi-endpoint.suite.ts +358 -0
  269. package/src/v2/runtime/__tests__/integration/suites/single-endpoint.suite.ts +363 -0
  270. package/src/v2/runtime/__tests__/middleware-express.test.ts +25 -23
  271. package/src/v2/runtime/__tests__/middleware-single-express.test.ts +25 -23
  272. package/src/v2/runtime/__tests__/middleware-single.test.ts +1 -1
  273. package/src/v2/runtime/__tests__/middleware-sse-parser.test.ts +1 -1
  274. package/src/v2/runtime/__tests__/middleware.test.ts +1 -2
  275. package/src/v2/runtime/__tests__/node-fetch-handler.test.ts +157 -0
  276. package/src/v2/runtime/__tests__/open-generative-ui-middleware.e2e.test.ts +728 -0
  277. package/src/v2/runtime/__tests__/router-edge-cases.test.ts +217 -0
  278. package/src/v2/runtime/__tests__/routing-express.test.ts +1 -1
  279. package/src/v2/runtime/__tests__/routing-single-express.test.ts +1 -1
  280. package/src/v2/runtime/__tests__/routing-single.test.ts +1 -1
  281. package/src/v2/runtime/__tests__/routing.test.ts +1 -1
  282. package/src/v2/runtime/__tests__/runtime.test.ts +110 -1
  283. package/src/v2/runtime/__tests__/telemetry.test.ts +62 -1
  284. package/src/v2/runtime/core/fetch-cors.ts +136 -0
  285. package/src/v2/runtime/core/fetch-handler.ts +415 -0
  286. package/src/v2/runtime/core/fetch-router.ts +112 -0
  287. package/src/v2/runtime/core/hooks.ts +151 -0
  288. package/src/v2/runtime/{runtime.ts → core/runtime.ts} +79 -10
  289. package/src/v2/runtime/endpoints/express-fetch-bridge.ts +137 -0
  290. package/src/v2/runtime/endpoints/express-single.ts +42 -219
  291. package/src/v2/runtime/endpoints/express.ts +128 -230
  292. package/src/v2/runtime/endpoints/hono-single.ts +19 -171
  293. package/src/v2/runtime/endpoints/hono.ts +45 -270
  294. package/src/v2/runtime/endpoints/node-fetch-handler.ts +48 -0
  295. package/src/v2/runtime/endpoints/node.ts +28 -0
  296. package/src/v2/runtime/handlers/get-runtime-info.ts +3 -2
  297. package/src/v2/runtime/handlers/handle-connect.ts +7 -4
  298. package/src/v2/runtime/handlers/handle-run.ts +7 -4
  299. package/src/v2/runtime/handlers/handle-stop.ts +1 -1
  300. package/src/v2/runtime/handlers/handle-transcribe.ts +1 -1
  301. package/src/v2/runtime/handlers/intelligence/connect.ts +1 -1
  302. package/src/v2/runtime/handlers/intelligence/run.ts +31 -1
  303. package/src/v2/runtime/handlers/intelligence/thread-names.ts +2 -2
  304. package/src/v2/runtime/handlers/intelligence/threads.ts +1 -1
  305. package/src/v2/runtime/handlers/shared/agent-utils.ts +29 -10
  306. package/src/v2/runtime/handlers/shared/json-response.ts +4 -1
  307. package/src/v2/runtime/handlers/shared/resolve-intelligence-user.ts +1 -1
  308. package/src/v2/runtime/handlers/sse/connect.ts +1 -1
  309. package/src/v2/runtime/handlers/sse/run.ts +1 -1
  310. package/src/v2/runtime/hono.ts +2 -0
  311. package/src/v2/runtime/index.ts +27 -1
  312. package/src/v2/runtime/intelligence-platform/client.ts +50 -1
  313. package/src/v2/runtime/node.ts +6 -0
  314. package/src/v2/runtime/open-generative-ui-middleware.ts +373 -0
  315. package/src/v2/runtime/runner/intelligence.ts +14 -4
  316. package/src/v2/runtime/telemetry/telemetry-client.ts +56 -0
  317. package/src/v2/runtime/telemetry/utils.ts +15 -0
  318. package/tsdown.config.ts +8 -1
  319. package/vitest.config.mjs +2 -5
  320. package/.eslintrc.js +0 -7
  321. package/dist/v2/runtime/endpoints/express-utils.cjs +0 -119
  322. package/dist/v2/runtime/endpoints/express-utils.cjs.map +0 -1
  323. package/dist/v2/runtime/endpoints/express-utils.mjs +0 -117
  324. package/dist/v2/runtime/endpoints/express-utils.mjs.map +0 -1
  325. package/dist/v2/runtime/handlers/intelligence/threads.cjs +0 -159
  326. package/dist/v2/runtime/handlers/intelligence/threads.cjs.map +0 -1
  327. package/dist/v2/runtime/handlers/intelligence/threads.mjs +0 -154
  328. package/dist/v2/runtime/handlers/intelligence/threads.mjs.map +0 -1
  329. package/dist/v2/runtime/middleware-sse-parser.cjs.map +0 -1
  330. package/dist/v2/runtime/middleware-sse-parser.d.cts.map +0 -1
  331. package/dist/v2/runtime/middleware-sse-parser.d.mts.map +0 -1
  332. package/dist/v2/runtime/middleware-sse-parser.mjs.map +0 -1
  333. package/dist/v2/runtime/middleware.cjs.map +0 -1
  334. package/dist/v2/runtime/middleware.d.cts.map +0 -1
  335. package/dist/v2/runtime/middleware.d.mts.map +0 -1
  336. package/dist/v2/runtime/middleware.mjs.map +0 -1
  337. package/dist/v2/runtime/runtime.cjs.map +0 -1
  338. package/dist/v2/runtime/runtime.d.cts.map +0 -1
  339. package/dist/v2/runtime/runtime.d.mts.map +0 -1
  340. package/dist/v2/runtime/runtime.mjs.map +0 -1
  341. package/src/v2/runtime/__tests__/express-abort-signal.test.ts +0 -25
  342. package/src/v2/runtime/endpoints/express-utils.ts +0 -182
  343. package/src/v2/runtime/handler.ts +0 -3
  344. /package/src/v2/runtime/{middleware-sse-parser.ts → core/middleware-sse-parser.ts} +0 -0
  345. /package/src/v2/runtime/{middleware.ts → core/middleware.ts} +0 -0
@@ -4,7 +4,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
4
4
  import type { AbstractAgent } from "@ag-ui/client";
5
5
 
6
6
  import { createCopilotEndpointExpress } from "../express";
7
- import { CopilotRuntime } from "../runtime";
7
+ import { CopilotRuntime } from "../core/runtime";
8
8
 
9
9
  const handleRunAgentMock = vi.fn();
10
10
 
@@ -0,0 +1,344 @@
1
+ import express from "express";
2
+ import request from "supertest";
3
+ import { describe, it, expect, vi } from "vitest";
4
+ import { createExpressNodeHandler } from "../endpoints/express-fetch-bridge";
5
+ import type { CopilotRuntimeFetchHandler } from "../core/fetch-handler";
6
+
7
+ /* ------------------------------------------------------------------------------------------------
8
+ * Helpers
9
+ * --------------------------------------------------------------------------------------------- */
10
+
11
+ /**
12
+ * Creates an Express app that optionally runs express.json() before our handler,
13
+ * simulating the "pre-parsed body" scenario.
14
+ */
15
+ function createApp(
16
+ fetchHandler: CopilotRuntimeFetchHandler,
17
+ opts: { bodyParserFirst?: boolean } = {},
18
+ ) {
19
+ const app = express();
20
+ const nodeHandler = createExpressNodeHandler(fetchHandler);
21
+
22
+ if (opts.bodyParserFirst) {
23
+ app.use(express.json());
24
+ }
25
+
26
+ app.all("*", (req, res) => nodeHandler(req, res));
27
+ return app;
28
+ }
29
+
30
+ /* ------------------------------------------------------------------------------------------------
31
+ * Pre-parsed body (express.json() before handler)
32
+ * --------------------------------------------------------------------------------------------- */
33
+
34
+ describe("express-fetch-bridge — pre-parsed body", () => {
35
+ it("receives JSON body when express.json() runs first", async () => {
36
+ const fetchHandler: CopilotRuntimeFetchHandler = async (req) => {
37
+ const body = await req.json();
38
+ return new Response(JSON.stringify({ received: body }), {
39
+ status: 200,
40
+ headers: { "Content-Type": "application/json" },
41
+ });
42
+ };
43
+
44
+ const app = createApp(fetchHandler, { bodyParserFirst: true });
45
+
46
+ const res = await request(app)
47
+ .post("/test")
48
+ .set("Content-Type", "application/json")
49
+ .send({ hello: "world" });
50
+
51
+ expect(res.status).toBe(200);
52
+ expect(res.body.received).toEqual({ hello: "world" });
53
+ });
54
+
55
+ it("receives JSON body when express.json() does NOT run first", async () => {
56
+ const fetchHandler: CopilotRuntimeFetchHandler = async (req) => {
57
+ const body = await req.json();
58
+ return new Response(JSON.stringify({ received: body }), {
59
+ status: 200,
60
+ headers: { "Content-Type": "application/json" },
61
+ });
62
+ };
63
+
64
+ const app = createApp(fetchHandler, { bodyParserFirst: false });
65
+
66
+ const res = await request(app)
67
+ .post("/test")
68
+ .set("Content-Type", "application/json")
69
+ .send({ hello: "world" });
70
+
71
+ expect(res.status).toBe(200);
72
+ expect(res.body.received).toEqual({ hello: "world" });
73
+ });
74
+
75
+ it("preserves nested objects in pre-parsed body", async () => {
76
+ const fetchHandler: CopilotRuntimeFetchHandler = async (req) => {
77
+ const body = await req.json();
78
+ return new Response(JSON.stringify(body), {
79
+ status: 200,
80
+ headers: { "Content-Type": "application/json" },
81
+ });
82
+ };
83
+
84
+ const app = createApp(fetchHandler, { bodyParserFirst: true });
85
+
86
+ const payload = {
87
+ messages: [{ role: "user", content: "hi" }],
88
+ state: { count: 42, nested: { deep: true } },
89
+ threadId: "t-123",
90
+ };
91
+
92
+ const res = await request(app)
93
+ .post("/agent/default/run")
94
+ .set("Content-Type", "application/json")
95
+ .send(payload);
96
+
97
+ expect(res.status).toBe(200);
98
+ expect(res.body).toEqual(payload);
99
+ });
100
+
101
+ it("preserves arrays in pre-parsed body", async () => {
102
+ const fetchHandler: CopilotRuntimeFetchHandler = async (req) => {
103
+ const body = await req.json();
104
+ return new Response(JSON.stringify(body), {
105
+ status: 200,
106
+ headers: { "Content-Type": "application/json" },
107
+ });
108
+ };
109
+
110
+ const app = createApp(fetchHandler, { bodyParserFirst: true });
111
+
112
+ const res = await request(app)
113
+ .post("/test")
114
+ .set("Content-Type", "application/json")
115
+ .send([1, 2, 3]);
116
+
117
+ expect(res.status).toBe(200);
118
+ expect(res.body).toEqual([1, 2, 3]);
119
+ });
120
+
121
+ it("empty object body is preserved", async () => {
122
+ const fetchHandler: CopilotRuntimeFetchHandler = async (req) => {
123
+ const body = await req.json();
124
+ return new Response(JSON.stringify({ received: body }), {
125
+ status: 200,
126
+ headers: { "Content-Type": "application/json" },
127
+ });
128
+ };
129
+
130
+ const app = createApp(fetchHandler, { bodyParserFirst: true });
131
+
132
+ const res = await request(app)
133
+ .post("/test")
134
+ .set("Content-Type", "application/json")
135
+ .send({});
136
+
137
+ expect(res.status).toBe(200);
138
+ expect(res.body.received).toEqual({});
139
+ });
140
+ });
141
+
142
+ /* ------------------------------------------------------------------------------------------------
143
+ * URL reconstruction
144
+ * --------------------------------------------------------------------------------------------- */
145
+
146
+ describe("express-fetch-bridge — URL reconstruction", () => {
147
+ it("preserves pathname in reconstructed URL", async () => {
148
+ const fetchHandler: CopilotRuntimeFetchHandler = async (req) => {
149
+ const url = new URL(req.url);
150
+ return new Response(JSON.stringify({ path: url.pathname }), {
151
+ status: 200,
152
+ headers: { "Content-Type": "application/json" },
153
+ });
154
+ };
155
+
156
+ const app = createApp(fetchHandler, { bodyParserFirst: true });
157
+
158
+ const res = await request(app)
159
+ .post("/api/copilotkit/agent/default/run")
160
+ .set("Content-Type", "application/json")
161
+ .send({ threadId: "t1" });
162
+
163
+ expect(res.status).toBe(200);
164
+ expect(res.body.path).toBe("/api/copilotkit/agent/default/run");
165
+ });
166
+
167
+ it("preserves query string in reconstructed URL", async () => {
168
+ const fetchHandler: CopilotRuntimeFetchHandler = async (req) => {
169
+ const url = new URL(req.url);
170
+ return new Response(
171
+ JSON.stringify({
172
+ search: url.search,
173
+ param: url.searchParams.get("foo"),
174
+ }),
175
+ { status: 200, headers: { "Content-Type": "application/json" } },
176
+ );
177
+ };
178
+
179
+ const app = createApp(fetchHandler, { bodyParserFirst: true });
180
+
181
+ const res = await request(app)
182
+ .post("/test?foo=bar")
183
+ .set("Content-Type", "application/json")
184
+ .send({ data: true });
185
+
186
+ expect(res.status).toBe(200);
187
+ expect(res.body.param).toBe("bar");
188
+ });
189
+ });
190
+
191
+ /* ------------------------------------------------------------------------------------------------
192
+ * Header preservation
193
+ * --------------------------------------------------------------------------------------------- */
194
+
195
+ describe("express-fetch-bridge — header preservation", () => {
196
+ it("preserves custom headers from original request", async () => {
197
+ const fetchHandler: CopilotRuntimeFetchHandler = async (req) => {
198
+ return new Response(
199
+ JSON.stringify({
200
+ auth: req.headers.get("authorization"),
201
+ custom: req.headers.get("x-custom-header"),
202
+ }),
203
+ { status: 200, headers: { "Content-Type": "application/json" } },
204
+ );
205
+ };
206
+
207
+ const app = createApp(fetchHandler, { bodyParserFirst: true });
208
+
209
+ const res = await request(app)
210
+ .post("/test")
211
+ .set("Content-Type", "application/json")
212
+ .set("Authorization", "Bearer tok123")
213
+ .set("X-Custom-Header", "my-value")
214
+ .send({ data: true });
215
+
216
+ expect(res.status).toBe(200);
217
+ expect(res.body.auth).toBe("Bearer tok123");
218
+ expect(res.body.custom).toBe("my-value");
219
+ });
220
+
221
+ it("sets content-type to application/json for object bodies", async () => {
222
+ const fetchHandler: CopilotRuntimeFetchHandler = async (req) => {
223
+ return new Response(
224
+ JSON.stringify({ contentType: req.headers.get("content-type") }),
225
+ { status: 200, headers: { "Content-Type": "application/json" } },
226
+ );
227
+ };
228
+
229
+ const app = createApp(fetchHandler, { bodyParserFirst: true });
230
+
231
+ const res = await request(app)
232
+ .post("/test")
233
+ .set("Content-Type", "application/json")
234
+ .send({ data: true });
235
+
236
+ expect(res.status).toBe(200);
237
+ expect(res.body.contentType).toBe("application/json");
238
+ });
239
+ });
240
+
241
+ /* ------------------------------------------------------------------------------------------------
242
+ * HTTP method handling
243
+ * --------------------------------------------------------------------------------------------- */
244
+
245
+ describe("express-fetch-bridge — HTTP methods", () => {
246
+ it("GET requests bypass pre-parsed body logic", async () => {
247
+ const fetchHandler: CopilotRuntimeFetchHandler = async (req) => {
248
+ return new Response(JSON.stringify({ method: req.method }), {
249
+ status: 200,
250
+ headers: { "Content-Type": "application/json" },
251
+ });
252
+ };
253
+
254
+ const app = createApp(fetchHandler, { bodyParserFirst: true });
255
+
256
+ const res = await request(app).get("/info");
257
+
258
+ expect(res.status).toBe(200);
259
+ expect(res.body.method).toBe("GET");
260
+ });
261
+
262
+ it("OPTIONS requests bypass pre-parsed body logic", async () => {
263
+ const fetchHandler: CopilotRuntimeFetchHandler = async (req) => {
264
+ return new Response(null, { status: 204 });
265
+ };
266
+
267
+ const app = createApp(fetchHandler, { bodyParserFirst: true });
268
+
269
+ const res = await request(app).options("/test");
270
+
271
+ expect(res.status).toBe(204);
272
+ });
273
+ });
274
+
275
+ /* ------------------------------------------------------------------------------------------------
276
+ * Error handling
277
+ * --------------------------------------------------------------------------------------------- */
278
+
279
+ describe("express-fetch-bridge — error handling", () => {
280
+ it("returns 500 when fetch handler throws", async () => {
281
+ const fetchHandler: CopilotRuntimeFetchHandler = async () => {
282
+ throw new Error("handler exploded");
283
+ };
284
+
285
+ const app = createApp(fetchHandler, { bodyParserFirst: true });
286
+
287
+ const res = await request(app)
288
+ .post("/test")
289
+ .set("Content-Type", "application/json")
290
+ .send({ data: true });
291
+
292
+ expect(res.status).toBe(500);
293
+ expect(res.text).toBe("Internal Server Error");
294
+ });
295
+
296
+ it("returns 500 when fetch handler throws (no body parser)", async () => {
297
+ const fetchHandler: CopilotRuntimeFetchHandler = async () => {
298
+ throw new Error("handler exploded");
299
+ };
300
+
301
+ const app = createApp(fetchHandler, { bodyParserFirst: false });
302
+
303
+ const res = await request(app)
304
+ .post("/test")
305
+ .set("Content-Type", "application/json")
306
+ .send({ data: true });
307
+
308
+ expect(res.status).toBe(500);
309
+ expect(res.text).toBe("Internal Server Error");
310
+ });
311
+ });
312
+
313
+ /* ------------------------------------------------------------------------------------------------
314
+ * Streaming responses
315
+ * --------------------------------------------------------------------------------------------- */
316
+
317
+ describe("express-fetch-bridge — streaming responses", () => {
318
+ it("streams SSE response through pre-parsed body path", async () => {
319
+ const fetchHandler: CopilotRuntimeFetchHandler = async () => {
320
+ const stream = new ReadableStream({
321
+ start(controller) {
322
+ controller.enqueue(new TextEncoder().encode("data: event1\n\n"));
323
+ controller.enqueue(new TextEncoder().encode("data: event2\n\n"));
324
+ controller.close();
325
+ },
326
+ });
327
+ return new Response(stream, {
328
+ status: 200,
329
+ headers: { "Content-Type": "text/event-stream" },
330
+ });
331
+ };
332
+
333
+ const app = createApp(fetchHandler, { bodyParserFirst: true });
334
+
335
+ const res = await request(app)
336
+ .post("/test")
337
+ .set("Content-Type", "application/json")
338
+ .send({ data: true });
339
+
340
+ expect(res.status).toBe(200);
341
+ expect(res.text).toContain("data: event1");
342
+ expect(res.text).toContain("data: event2");
343
+ });
344
+ });
@@ -3,7 +3,7 @@ import type { AddressInfo } from "node:net";
3
3
  import { afterEach, describe, expect, it } from "vitest";
4
4
 
5
5
  import { createCopilotEndpointSingleRouteExpress } from "../express";
6
- import { CopilotRuntime } from "../runtime";
6
+ import { CopilotRuntime } from "../core/runtime";
7
7
  import { InMemoryAgentRunner } from "../runner/in-memory";
8
8
 
9
9
  const buildRuntime = () => {
@@ -0,0 +1,205 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { handleCors, addCorsHeaders } from "../core/fetch-cors";
3
+ import type { CopilotCorsConfig } from "../core/fetch-cors";
4
+
5
+ describe("fetch-cors", () => {
6
+ describe("handleCors (preflight)", () => {
7
+ it("returns null for non-OPTIONS requests", () => {
8
+ const request = new Request("http://localhost/api", { method: "GET" });
9
+ expect(handleCors(request, {})).toBeNull();
10
+ });
11
+
12
+ it("returns null for POST requests", () => {
13
+ const request = new Request("http://localhost/api", { method: "POST" });
14
+ expect(handleCors(request, {})).toBeNull();
15
+ });
16
+
17
+ it("returns 204 for OPTIONS requests", () => {
18
+ const request = new Request("http://localhost/api", {
19
+ method: "OPTIONS",
20
+ });
21
+ const response = handleCors(request, {});
22
+ expect(response).not.toBeNull();
23
+ expect(response!.status).toBe(204);
24
+ });
25
+
26
+ it("adds permissive CORS headers with empty config (cors: true equivalent)", () => {
27
+ const request = new Request("http://localhost/api", {
28
+ method: "OPTIONS",
29
+ });
30
+ const response = handleCors(request, {})!;
31
+ expect(response.headers.get("Access-Control-Allow-Origin")).toBe("*");
32
+ expect(response.headers.get("Access-Control-Allow-Methods")).toContain(
33
+ "GET",
34
+ );
35
+ expect(response.headers.get("Access-Control-Allow-Methods")).toContain(
36
+ "POST",
37
+ );
38
+ expect(response.headers.get("Access-Control-Allow-Headers")).toBe("*");
39
+ });
40
+
41
+ it("reflects custom origin string", () => {
42
+ const request = new Request("http://localhost/api", {
43
+ method: "OPTIONS",
44
+ headers: { Origin: "https://myapp.com" },
45
+ });
46
+ const config: CopilotCorsConfig = { origin: "https://myapp.com" };
47
+ const response = handleCors(request, config)!;
48
+ expect(response.headers.get("Access-Control-Allow-Origin")).toBe(
49
+ "https://myapp.com",
50
+ );
51
+ });
52
+
53
+ it("reflects request origin when in allowed array", () => {
54
+ const request = new Request("http://localhost/api", {
55
+ method: "OPTIONS",
56
+ headers: { Origin: "https://b.com" },
57
+ });
58
+ const config: CopilotCorsConfig = {
59
+ origin: ["https://a.com", "https://b.com"],
60
+ };
61
+ const response = handleCors(request, config)!;
62
+ expect(response.headers.get("Access-Control-Allow-Origin")).toBe(
63
+ "https://b.com",
64
+ );
65
+ });
66
+
67
+ it("does not set origin when request origin is not in allowed array", () => {
68
+ const request = new Request("http://localhost/api", {
69
+ method: "OPTIONS",
70
+ headers: { Origin: "https://c.com" },
71
+ });
72
+ const config: CopilotCorsConfig = {
73
+ origin: ["https://a.com", "https://b.com"],
74
+ };
75
+ const response = handleCors(request, config)!;
76
+ expect(response.headers.get("Access-Control-Allow-Origin")).toBeNull();
77
+ });
78
+
79
+ it("uses origin function to resolve", () => {
80
+ const request = new Request("http://localhost/api", {
81
+ method: "OPTIONS",
82
+ headers: { Origin: "https://dynamic.com" },
83
+ });
84
+ const config: CopilotCorsConfig = {
85
+ origin: (origin: string) => (origin.endsWith(".com") ? origin : null),
86
+ };
87
+ const response = handleCors(request, config)!;
88
+ expect(response.headers.get("Access-Control-Allow-Origin")).toBe(
89
+ "https://dynamic.com",
90
+ );
91
+ });
92
+
93
+ it("sets credentials header when configured", () => {
94
+ const request = new Request("http://localhost/api", {
95
+ method: "OPTIONS",
96
+ headers: { Origin: "https://myapp.com" },
97
+ });
98
+ const config: CopilotCorsConfig = {
99
+ origin: "https://myapp.com",
100
+ credentials: true,
101
+ };
102
+ const response = handleCors(request, config)!;
103
+ expect(response.headers.get("Access-Control-Allow-Credentials")).toBe(
104
+ "true",
105
+ );
106
+ });
107
+
108
+ it("sets custom allowMethods", () => {
109
+ const request = new Request("http://localhost/api", {
110
+ method: "OPTIONS",
111
+ });
112
+ const config: CopilotCorsConfig = { allowMethods: ["GET", "POST"] };
113
+ const response = handleCors(request, config)!;
114
+ expect(response.headers.get("Access-Control-Allow-Methods")).toBe(
115
+ "GET, POST",
116
+ );
117
+ });
118
+
119
+ it("sets custom allowHeaders", () => {
120
+ const request = new Request("http://localhost/api", {
121
+ method: "OPTIONS",
122
+ });
123
+ const config: CopilotCorsConfig = {
124
+ allowHeaders: ["Content-Type", "Authorization"],
125
+ };
126
+ const response = handleCors(request, config)!;
127
+ expect(response.headers.get("Access-Control-Allow-Headers")).toBe(
128
+ "Content-Type, Authorization",
129
+ );
130
+ });
131
+
132
+ it("sets maxAge header", () => {
133
+ const request = new Request("http://localhost/api", {
134
+ method: "OPTIONS",
135
+ });
136
+ const config: CopilotCorsConfig = { maxAge: 86400 };
137
+ const response = handleCors(request, config)!;
138
+ expect(response.headers.get("Access-Control-Max-Age")).toBe("86400");
139
+ });
140
+
141
+ it("auto-resolves wildcard to request origin when credentials enabled", () => {
142
+ const request = new Request("http://localhost/api", {
143
+ method: "OPTIONS",
144
+ headers: { Origin: "https://example.com" },
145
+ });
146
+ const config: CopilotCorsConfig = { origin: "*", credentials: true };
147
+ const response = handleCors(request, config)!;
148
+ // Per Fetch spec, wildcard + credentials is invalid. We auto-resolve
149
+ // the wildcard to the actual request origin when credentials are enabled.
150
+ expect(response.headers.get("Access-Control-Allow-Origin")).toBe(
151
+ "https://example.com",
152
+ );
153
+ expect(response.headers.get("Access-Control-Allow-Credentials")).toBe(
154
+ "true",
155
+ );
156
+ });
157
+ });
158
+
159
+ describe("addCorsHeaders (response decoration)", () => {
160
+ it("adds CORS headers to an existing response", () => {
161
+ const response = new Response(JSON.stringify({ ok: true }), {
162
+ status: 200,
163
+ headers: { "Content-Type": "application/json" },
164
+ });
165
+ const config: CopilotCorsConfig = {};
166
+ const result = addCorsHeaders(response, config, null);
167
+ expect(result.headers.get("Access-Control-Allow-Origin")).toBe("*");
168
+ expect(result.headers.get("Content-Type")).toBe("application/json");
169
+ expect(result.status).toBe(200);
170
+ });
171
+
172
+ it("adds CORS headers to error responses", () => {
173
+ const response = new Response("Not found", { status: 404 });
174
+ const config: CopilotCorsConfig = {};
175
+ const result = addCorsHeaders(response, config, null);
176
+ expect(result.headers.get("Access-Control-Allow-Origin")).toBe("*");
177
+ expect(result.status).toBe(404);
178
+ });
179
+
180
+ it("sets exposeHeaders", () => {
181
+ const response = new Response(null, { status: 200 });
182
+ const config: CopilotCorsConfig = {
183
+ exposeHeaders: ["X-Request-Id", "X-Custom"],
184
+ };
185
+ const result = addCorsHeaders(response, config, null);
186
+ expect(result.headers.get("Access-Control-Expose-Headers")).toBe(
187
+ "X-Request-Id, X-Custom",
188
+ );
189
+ });
190
+
191
+ it("adds Vary: Origin when origin is not wildcard", () => {
192
+ const response = new Response(null, { status: 200 });
193
+ const config: CopilotCorsConfig = { origin: "https://myapp.com" };
194
+ const result = addCorsHeaders(response, config, "https://myapp.com");
195
+ expect(result.headers.get("Vary")).toContain("Origin");
196
+ });
197
+
198
+ it("does not add Vary when origin is wildcard", () => {
199
+ const response = new Response(null, { status: 200 });
200
+ const config: CopilotCorsConfig = {};
201
+ const result = addCorsHeaders(response, config, null);
202
+ expect(result.headers.get("Vary")).toBeNull();
203
+ });
204
+ });
205
+ });