@copilotkit/runtime 1.54.1 → 1.55.0-next.8

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 (337) hide show
  1. package/.eslintrc.js +4 -4
  2. package/CHANGELOG.md +125 -113
  3. package/dist/_virtual/_rolldown/runtime.mjs +25 -1
  4. package/dist/agent/index.cjs +654 -0
  5. package/dist/agent/index.cjs.map +1 -0
  6. package/dist/agent/index.d.cts +263 -0
  7. package/dist/agent/index.d.cts.map +1 -0
  8. package/dist/agent/index.d.mts +263 -0
  9. package/dist/agent/index.d.mts.map +1 -0
  10. package/dist/agent/index.mjs +646 -0
  11. package/dist/agent/index.mjs.map +1 -0
  12. package/dist/graphql/message-conversion/agui-to-gql.cjs.map +1 -1
  13. package/dist/graphql/message-conversion/agui-to-gql.mjs.map +1 -1
  14. package/dist/lib/integrations/nextjs/app-router.cjs +2 -2
  15. package/dist/lib/integrations/nextjs/app-router.cjs.map +1 -1
  16. package/dist/lib/integrations/nextjs/app-router.mjs +1 -1
  17. package/dist/lib/integrations/nextjs/app-router.mjs.map +1 -1
  18. package/dist/lib/integrations/node-http/index.cjs +2 -3
  19. package/dist/lib/integrations/node-http/index.cjs.map +1 -1
  20. package/dist/lib/integrations/node-http/index.mjs +1 -1
  21. package/dist/lib/integrations/node-http/index.mjs.map +1 -1
  22. package/dist/lib/runtime/agent-integrations/langgraph/agent.cjs +1 -1
  23. package/dist/lib/runtime/agent-integrations/langgraph/agent.d.cts +2 -2
  24. package/dist/lib/runtime/agent-integrations/langgraph/agent.d.cts.map +1 -1
  25. package/dist/lib/runtime/agent-integrations/langgraph/agent.d.mts +3 -3
  26. package/dist/lib/runtime/agent-integrations/langgraph/agent.d.mts.map +1 -1
  27. package/dist/lib/runtime/agent-integrations/langgraph/agent.mjs +1 -1
  28. package/dist/lib/runtime/copilot-runtime.cjs +7 -5
  29. package/dist/lib/runtime/copilot-runtime.cjs.map +1 -1
  30. package/dist/lib/runtime/copilot-runtime.d.cts +10 -8
  31. package/dist/lib/runtime/copilot-runtime.d.cts.map +1 -1
  32. package/dist/lib/runtime/copilot-runtime.d.mts +10 -8
  33. package/dist/lib/runtime/copilot-runtime.d.mts.map +1 -1
  34. package/dist/lib/runtime/copilot-runtime.mjs +7 -5
  35. package/dist/lib/runtime/copilot-runtime.mjs.map +1 -1
  36. package/dist/lib/runtime/telemetry-agent-runner.cjs +2 -2
  37. package/dist/lib/runtime/telemetry-agent-runner.cjs.map +1 -1
  38. package/dist/lib/runtime/telemetry-agent-runner.d.cts +2 -1
  39. package/dist/lib/runtime/telemetry-agent-runner.d.cts.map +1 -1
  40. package/dist/lib/runtime/telemetry-agent-runner.d.mts +2 -1
  41. package/dist/lib/runtime/telemetry-agent-runner.d.mts.map +1 -1
  42. package/dist/lib/runtime/telemetry-agent-runner.mjs +1 -1
  43. package/dist/lib/runtime/telemetry-agent-runner.mjs.map +1 -1
  44. package/dist/lib/telemetry-client.cjs +1 -1
  45. package/dist/lib/telemetry-client.mjs +1 -1
  46. package/dist/package.cjs +21 -4
  47. package/dist/package.mjs +21 -4
  48. package/dist/service-adapters/anthropic/anthropic-adapter.d.mts +1 -1
  49. package/dist/v2/index.cjs +41 -15
  50. package/dist/v2/index.d.cts +14 -2
  51. package/dist/v2/index.d.mts +14 -2
  52. package/dist/v2/index.mjs +13 -4
  53. package/dist/v2/runtime/endpoints/express-single.cjs +190 -0
  54. package/dist/v2/runtime/endpoints/express-single.cjs.map +1 -0
  55. package/dist/v2/runtime/endpoints/express-single.d.cts +16 -0
  56. package/dist/v2/runtime/endpoints/express-single.d.cts.map +1 -0
  57. package/dist/v2/runtime/endpoints/express-single.d.mts +16 -0
  58. package/dist/v2/runtime/endpoints/express-single.d.mts.map +1 -0
  59. package/dist/v2/runtime/endpoints/express-single.mjs +187 -0
  60. package/dist/v2/runtime/endpoints/express-single.mjs.map +1 -0
  61. package/dist/v2/runtime/endpoints/express-utils.cjs +119 -0
  62. package/dist/v2/runtime/endpoints/express-utils.cjs.map +1 -0
  63. package/dist/v2/runtime/endpoints/express-utils.mjs +117 -0
  64. package/dist/v2/runtime/endpoints/express-utils.mjs.map +1 -0
  65. package/dist/v2/runtime/endpoints/express.cjs +217 -0
  66. package/dist/v2/runtime/endpoints/express.cjs.map +1 -0
  67. package/dist/v2/runtime/endpoints/express.d.cts +16 -0
  68. package/dist/v2/runtime/endpoints/express.d.cts.map +1 -0
  69. package/dist/v2/runtime/endpoints/express.d.mts +16 -0
  70. package/dist/v2/runtime/endpoints/express.d.mts.map +1 -0
  71. package/dist/v2/runtime/endpoints/express.mjs +214 -0
  72. package/dist/v2/runtime/endpoints/express.mjs.map +1 -0
  73. package/dist/v2/runtime/endpoints/hono-single.cjs +141 -0
  74. package/dist/v2/runtime/endpoints/hono-single.cjs.map +1 -0
  75. package/dist/v2/runtime/endpoints/hono-single.d.cts +41 -0
  76. package/dist/v2/runtime/endpoints/hono-single.d.cts.map +1 -0
  77. package/dist/v2/runtime/endpoints/hono-single.d.mts +41 -0
  78. package/dist/v2/runtime/endpoints/hono-single.d.mts.map +1 -0
  79. package/dist/v2/runtime/endpoints/hono-single.mjs +140 -0
  80. package/dist/v2/runtime/endpoints/hono-single.mjs.map +1 -0
  81. package/dist/v2/runtime/endpoints/hono.cjs +248 -0
  82. package/dist/v2/runtime/endpoints/hono.cjs.map +1 -0
  83. package/dist/v2/runtime/endpoints/hono.d.cts +164 -0
  84. package/dist/v2/runtime/endpoints/hono.d.cts.map +1 -0
  85. package/dist/v2/runtime/endpoints/hono.d.mts +164 -0
  86. package/dist/v2/runtime/endpoints/hono.d.mts.map +1 -0
  87. package/dist/v2/runtime/endpoints/hono.mjs +247 -0
  88. package/dist/v2/runtime/endpoints/hono.mjs.map +1 -0
  89. package/dist/v2/runtime/endpoints/index.d.cts +5 -0
  90. package/dist/v2/runtime/endpoints/index.d.mts +5 -0
  91. package/dist/v2/runtime/endpoints/single-route-helpers.cjs +68 -0
  92. package/dist/v2/runtime/endpoints/single-route-helpers.cjs.map +1 -0
  93. package/dist/v2/runtime/endpoints/single-route-helpers.mjs +65 -0
  94. package/dist/v2/runtime/endpoints/single-route-helpers.mjs.map +1 -0
  95. package/dist/v2/runtime/handlers/get-runtime-info.cjs +51 -0
  96. package/dist/v2/runtime/handlers/get-runtime-info.cjs.map +1 -0
  97. package/dist/v2/runtime/handlers/get-runtime-info.mjs +51 -0
  98. package/dist/v2/runtime/handlers/get-runtime-info.mjs.map +1 -0
  99. package/dist/v2/runtime/handlers/handle-connect.cjs +49 -0
  100. package/dist/v2/runtime/handlers/handle-connect.cjs.map +1 -0
  101. package/dist/v2/runtime/handlers/handle-connect.mjs +49 -0
  102. package/dist/v2/runtime/handlers/handle-connect.mjs.map +1 -0
  103. package/dist/v2/runtime/handlers/handle-run.cjs +61 -0
  104. package/dist/v2/runtime/handlers/handle-run.cjs.map +1 -0
  105. package/dist/v2/runtime/handlers/handle-run.mjs +61 -0
  106. package/dist/v2/runtime/handlers/handle-run.mjs.map +1 -0
  107. package/dist/v2/runtime/handlers/handle-stop.cjs +47 -0
  108. package/dist/v2/runtime/handlers/handle-stop.cjs.map +1 -0
  109. package/dist/v2/runtime/handlers/handle-stop.mjs +46 -0
  110. package/dist/v2/runtime/handlers/handle-stop.mjs.map +1 -0
  111. package/dist/v2/runtime/handlers/handle-transcribe.cjs +112 -0
  112. package/dist/v2/runtime/handlers/handle-transcribe.cjs.map +1 -0
  113. package/dist/v2/runtime/handlers/handle-transcribe.mjs +111 -0
  114. package/dist/v2/runtime/handlers/handle-transcribe.mjs.map +1 -0
  115. package/dist/v2/runtime/handlers/header-utils.cjs +26 -0
  116. package/dist/v2/runtime/handlers/header-utils.cjs.map +1 -0
  117. package/dist/v2/runtime/handlers/header-utils.mjs +25 -0
  118. package/dist/v2/runtime/handlers/header-utils.mjs.map +1 -0
  119. package/dist/v2/runtime/handlers/intelligence/connect.cjs +37 -0
  120. package/dist/v2/runtime/handlers/intelligence/connect.cjs.map +1 -0
  121. package/dist/v2/runtime/handlers/intelligence/connect.mjs +37 -0
  122. package/dist/v2/runtime/handlers/intelligence/connect.mjs.map +1 -0
  123. package/dist/v2/runtime/handlers/intelligence/run.cjs +89 -0
  124. package/dist/v2/runtime/handlers/intelligence/run.cjs.map +1 -0
  125. package/dist/v2/runtime/handlers/intelligence/run.mjs +88 -0
  126. package/dist/v2/runtime/handlers/intelligence/run.mjs.map +1 -0
  127. package/dist/v2/runtime/handlers/intelligence/thread-names.cjs +146 -0
  128. package/dist/v2/runtime/handlers/intelligence/thread-names.cjs.map +1 -0
  129. package/dist/v2/runtime/handlers/intelligence/thread-names.mjs +145 -0
  130. package/dist/v2/runtime/handlers/intelligence/thread-names.mjs.map +1 -0
  131. package/dist/v2/runtime/handlers/intelligence/threads.cjs +159 -0
  132. package/dist/v2/runtime/handlers/intelligence/threads.cjs.map +1 -0
  133. package/dist/v2/runtime/handlers/intelligence/threads.mjs +154 -0
  134. package/dist/v2/runtime/handlers/intelligence/threads.mjs.map +1 -0
  135. package/dist/v2/runtime/handlers/shared/agent-utils.cjs +74 -0
  136. package/dist/v2/runtime/handlers/shared/agent-utils.cjs.map +1 -0
  137. package/dist/v2/runtime/handlers/shared/agent-utils.mjs +70 -0
  138. package/dist/v2/runtime/handlers/shared/agent-utils.mjs.map +1 -0
  139. package/dist/v2/runtime/handlers/shared/intelligence-utils.cjs +21 -0
  140. package/dist/v2/runtime/handlers/shared/intelligence-utils.cjs.map +1 -0
  141. package/dist/v2/runtime/handlers/shared/intelligence-utils.mjs +20 -0
  142. package/dist/v2/runtime/handlers/shared/intelligence-utils.mjs.map +1 -0
  143. package/dist/v2/runtime/handlers/shared/json-response.cjs +12 -0
  144. package/dist/v2/runtime/handlers/shared/json-response.cjs.map +1 -0
  145. package/dist/v2/runtime/handlers/shared/json-response.mjs +10 -0
  146. package/dist/v2/runtime/handlers/shared/json-response.mjs.map +1 -0
  147. package/dist/v2/runtime/handlers/shared/resolve-intelligence-user.cjs +20 -0
  148. package/dist/v2/runtime/handlers/shared/resolve-intelligence-user.cjs.map +1 -0
  149. package/dist/v2/runtime/handlers/shared/resolve-intelligence-user.mjs +20 -0
  150. package/dist/v2/runtime/handlers/shared/resolve-intelligence-user.mjs.map +1 -0
  151. package/dist/v2/runtime/handlers/shared/sse-response.cjs +69 -0
  152. package/dist/v2/runtime/handlers/shared/sse-response.cjs.map +1 -0
  153. package/dist/v2/runtime/handlers/shared/sse-response.mjs +68 -0
  154. package/dist/v2/runtime/handlers/shared/sse-response.mjs.map +1 -0
  155. package/dist/v2/runtime/handlers/sse/connect.cjs +18 -0
  156. package/dist/v2/runtime/handlers/sse/connect.cjs.map +1 -0
  157. package/dist/v2/runtime/handlers/sse/connect.mjs +18 -0
  158. package/dist/v2/runtime/handlers/sse/connect.mjs.map +1 -0
  159. package/dist/v2/runtime/handlers/sse/run.cjs +18 -0
  160. package/dist/v2/runtime/handlers/sse/run.cjs.map +1 -0
  161. package/dist/v2/runtime/handlers/sse/run.mjs +18 -0
  162. package/dist/v2/runtime/handlers/sse/run.mjs.map +1 -0
  163. package/dist/v2/runtime/index.d.cts +13 -0
  164. package/dist/v2/runtime/index.d.mts +14 -0
  165. package/dist/v2/runtime/intelligence-platform/client.cjs +333 -0
  166. package/dist/v2/runtime/intelligence-platform/client.cjs.map +1 -0
  167. package/dist/v2/runtime/intelligence-platform/client.d.cts +336 -0
  168. package/dist/v2/runtime/intelligence-platform/client.d.cts.map +1 -0
  169. package/dist/v2/runtime/intelligence-platform/client.d.mts +336 -0
  170. package/dist/v2/runtime/intelligence-platform/client.d.mts.map +1 -0
  171. package/dist/v2/runtime/intelligence-platform/client.mjs +331 -0
  172. package/dist/v2/runtime/intelligence-platform/client.mjs.map +1 -0
  173. package/dist/v2/runtime/intelligence-platform/index.d.mts +2 -0
  174. package/dist/v2/runtime/middleware-sse-parser.cjs +138 -0
  175. package/dist/v2/runtime/middleware-sse-parser.cjs.map +1 -0
  176. package/dist/v2/runtime/middleware-sse-parser.d.cts +22 -0
  177. package/dist/v2/runtime/middleware-sse-parser.d.cts.map +1 -0
  178. package/dist/v2/runtime/middleware-sse-parser.d.mts +22 -0
  179. package/dist/v2/runtime/middleware-sse-parser.d.mts.map +1 -0
  180. package/dist/v2/runtime/middleware-sse-parser.mjs +137 -0
  181. package/dist/v2/runtime/middleware-sse-parser.mjs.map +1 -0
  182. package/dist/v2/runtime/middleware.cjs +35 -0
  183. package/dist/v2/runtime/middleware.cjs.map +1 -0
  184. package/dist/v2/runtime/middleware.d.cts +32 -0
  185. package/dist/v2/runtime/middleware.d.cts.map +1 -0
  186. package/dist/v2/runtime/middleware.d.mts +32 -0
  187. package/dist/v2/runtime/middleware.d.mts.map +1 -0
  188. package/dist/v2/runtime/middleware.mjs +33 -0
  189. package/dist/v2/runtime/middleware.mjs.map +1 -0
  190. package/dist/v2/runtime/runner/agent-runner.cjs +8 -0
  191. package/dist/v2/runtime/runner/agent-runner.cjs.map +1 -0
  192. package/dist/v2/runtime/runner/agent-runner.d.cts +32 -0
  193. package/dist/v2/runtime/runner/agent-runner.d.cts.map +1 -0
  194. package/dist/v2/runtime/runner/agent-runner.d.mts +32 -0
  195. package/dist/v2/runtime/runner/agent-runner.d.mts.map +1 -0
  196. package/dist/v2/runtime/runner/agent-runner.mjs +7 -0
  197. package/dist/v2/runtime/runner/agent-runner.mjs.map +1 -0
  198. package/dist/v2/runtime/runner/in-memory.cjs +223 -0
  199. package/dist/v2/runtime/runner/in-memory.cjs.map +1 -0
  200. package/dist/v2/runtime/runner/in-memory.d.cts +15 -0
  201. package/dist/v2/runtime/runner/in-memory.d.cts.map +1 -0
  202. package/dist/v2/runtime/runner/in-memory.d.mts +15 -0
  203. package/dist/v2/runtime/runner/in-memory.d.mts.map +1 -0
  204. package/dist/v2/runtime/runner/in-memory.mjs +222 -0
  205. package/dist/v2/runtime/runner/in-memory.mjs.map +1 -0
  206. package/dist/v2/runtime/runner/index.d.cts +6 -0
  207. package/dist/v2/runtime/runner/index.d.mts +6 -0
  208. package/dist/v2/runtime/runner/index.mjs +7 -0
  209. package/dist/v2/runtime/runner/intelligence.cjs +246 -0
  210. package/dist/v2/runtime/runner/intelligence.cjs.map +1 -0
  211. package/dist/v2/runtime/runner/intelligence.d.cts +57 -0
  212. package/dist/v2/runtime/runner/intelligence.d.cts.map +1 -0
  213. package/dist/v2/runtime/runner/intelligence.d.mts +57 -0
  214. package/dist/v2/runtime/runner/intelligence.d.mts.map +1 -0
  215. package/dist/v2/runtime/runner/intelligence.mjs +245 -0
  216. package/dist/v2/runtime/runner/intelligence.mjs.map +1 -0
  217. package/dist/v2/runtime/runtime.cjs +101 -0
  218. package/dist/v2/runtime/runtime.cjs.map +1 -0
  219. package/dist/v2/runtime/runtime.d.cts +132 -0
  220. package/dist/v2/runtime/runtime.d.cts.map +1 -0
  221. package/dist/v2/runtime/runtime.d.mts +133 -0
  222. package/dist/v2/runtime/runtime.d.mts.map +1 -0
  223. package/dist/v2/runtime/runtime.mjs +97 -0
  224. package/dist/v2/runtime/runtime.mjs.map +1 -0
  225. package/dist/v2/runtime/telemetry/scarf-client.cjs +32 -0
  226. package/dist/v2/runtime/telemetry/scarf-client.cjs.map +1 -0
  227. package/dist/v2/runtime/telemetry/scarf-client.mjs +32 -0
  228. package/dist/v2/runtime/telemetry/scarf-client.mjs.map +1 -0
  229. package/dist/v2/runtime/telemetry/telemetry-client.cjs +35 -0
  230. package/dist/v2/runtime/telemetry/telemetry-client.cjs.map +1 -0
  231. package/dist/v2/runtime/telemetry/telemetry-client.mjs +35 -0
  232. package/dist/v2/runtime/telemetry/telemetry-client.mjs.map +1 -0
  233. package/dist/v2/runtime/transcription-service/transcription-service.cjs +8 -0
  234. package/dist/v2/runtime/transcription-service/transcription-service.cjs.map +1 -0
  235. package/dist/v2/runtime/transcription-service/transcription-service.d.cts +15 -0
  236. package/dist/v2/runtime/transcription-service/transcription-service.d.cts.map +1 -0
  237. package/dist/v2/runtime/transcription-service/transcription-service.d.mts +15 -0
  238. package/dist/v2/runtime/transcription-service/transcription-service.d.mts.map +1 -0
  239. package/dist/v2/runtime/transcription-service/transcription-service.mjs +7 -0
  240. package/dist/v2/runtime/transcription-service/transcription-service.mjs.map +1 -0
  241. package/package.json +24 -7
  242. package/src/agent/__tests__/ai-sdk-v6-compat.test.ts +116 -0
  243. package/src/agent/__tests__/basic-agent.test.ts +1698 -0
  244. package/src/agent/__tests__/config-tools-execution.test.ts +516 -0
  245. package/src/agent/__tests__/mcp-clients.test.ts +260 -0
  246. package/src/agent/__tests__/property-overrides.test.ts +598 -0
  247. package/src/agent/__tests__/standard-schema-tools.test.ts +313 -0
  248. package/src/agent/__tests__/standard-schema-types.test.ts +158 -0
  249. package/src/agent/__tests__/state-tools.test.ts +436 -0
  250. package/src/agent/__tests__/test-helpers.ts +193 -0
  251. package/src/agent/__tests__/utils.test.ts +536 -0
  252. package/src/agent/__tests__/zod-regression.test.ts +350 -0
  253. package/src/agent/index.ts +1329 -0
  254. package/src/graphql/message-conversion/agui-to-gql.test.ts +1 -1
  255. package/src/graphql/message-conversion/agui-to-gql.ts +1 -1
  256. package/src/graphql/message-conversion/gql-to-agui.ts +1 -1
  257. package/src/graphql/message-conversion/roundtrip-conversion.test.ts +1 -1
  258. package/src/lib/integrations/nextjs/app-router.ts +2 -2
  259. package/src/lib/integrations/node-http/index.ts +2 -2
  260. package/src/lib/runtime/copilot-runtime.ts +3 -5
  261. package/src/lib/runtime/telemetry-agent-runner.ts +1 -1
  262. package/src/service-adapters/conversion.test.ts +1 -1
  263. package/src/service-adapters/conversion.ts +1 -28
  264. package/src/v2/index.ts +5 -2
  265. package/src/v2/runtime/__tests__/cors-credentials.test.ts +320 -0
  266. package/src/v2/runtime/__tests__/express-abort-signal.test.ts +25 -0
  267. package/src/v2/runtime/__tests__/express-body-order.test.ts +76 -0
  268. package/src/v2/runtime/__tests__/express-single-sse.test.ts +122 -0
  269. package/src/v2/runtime/__tests__/get-runtime-info.test.ts +141 -0
  270. package/src/v2/runtime/__tests__/handle-connect.test.ts +423 -0
  271. package/src/v2/runtime/__tests__/handle-run.test.ts +910 -0
  272. package/src/v2/runtime/__tests__/handle-threads.test.ts +388 -0
  273. package/src/v2/runtime/__tests__/handle-transcribe.test.ts +301 -0
  274. package/src/v2/runtime/__tests__/header-utils.test.ts +88 -0
  275. package/src/v2/runtime/__tests__/in-process-agent-runner-messages.test.ts +230 -0
  276. package/src/v2/runtime/__tests__/in-process-agent-runner.test.ts +1030 -0
  277. package/src/v2/runtime/__tests__/middleware-express.test.ts +206 -0
  278. package/src/v2/runtime/__tests__/middleware-single-express.test.ts +211 -0
  279. package/src/v2/runtime/__tests__/middleware-single.test.ts +225 -0
  280. package/src/v2/runtime/__tests__/middleware-sse-parser.test.ts +187 -0
  281. package/src/v2/runtime/__tests__/middleware.test.ts +251 -0
  282. package/src/v2/runtime/__tests__/routing-express.test.ts +174 -0
  283. package/src/v2/runtime/__tests__/routing-single-express.test.ts +168 -0
  284. package/src/v2/runtime/__tests__/routing-single.test.ts +193 -0
  285. package/src/v2/runtime/__tests__/routing.test.ts +257 -0
  286. package/src/v2/runtime/__tests__/runtime.test.ts +123 -0
  287. package/src/v2/runtime/__tests__/telemetry.test.ts +167 -0
  288. package/src/v2/runtime/__tests__/thread-names.test.ts +188 -0
  289. package/src/v2/runtime/endpoints/express-single.ts +231 -0
  290. package/src/v2/runtime/endpoints/express-utils.ts +182 -0
  291. package/src/v2/runtime/endpoints/express.ts +275 -0
  292. package/src/v2/runtime/endpoints/hono-single.ts +212 -0
  293. package/src/v2/runtime/endpoints/hono.ts +314 -0
  294. package/src/v2/runtime/endpoints/index.ts +4 -0
  295. package/src/v2/runtime/endpoints/single-route-helpers.ts +125 -0
  296. package/src/v2/runtime/express.ts +2 -0
  297. package/src/v2/runtime/handler.ts +3 -0
  298. package/src/v2/runtime/handlers/get-runtime-info.ts +79 -0
  299. package/src/v2/runtime/handlers/handle-connect.ts +76 -0
  300. package/src/v2/runtime/handlers/handle-run.ts +89 -0
  301. package/src/v2/runtime/handlers/handle-stop.ts +76 -0
  302. package/src/v2/runtime/handlers/handle-threads.ts +7 -0
  303. package/src/v2/runtime/handlers/handle-transcribe.ts +256 -0
  304. package/src/v2/runtime/handlers/header-utils.ts +24 -0
  305. package/src/v2/runtime/handlers/intelligence/connect.ts +65 -0
  306. package/src/v2/runtime/handlers/intelligence/run.ts +152 -0
  307. package/src/v2/runtime/handlers/intelligence/thread-names.ts +246 -0
  308. package/src/v2/runtime/handlers/intelligence/threads.ts +233 -0
  309. package/src/v2/runtime/handlers/shared/agent-utils.ts +136 -0
  310. package/src/v2/runtime/handlers/shared/intelligence-utils.ts +21 -0
  311. package/src/v2/runtime/handlers/shared/json-response.ts +6 -0
  312. package/src/v2/runtime/handlers/shared/resolve-intelligence-user.ts +25 -0
  313. package/src/v2/runtime/handlers/shared/sse-response.ts +100 -0
  314. package/src/v2/runtime/handlers/sse/connect.ts +24 -0
  315. package/src/v2/runtime/handlers/sse/run.ts +27 -0
  316. package/src/v2/runtime/index.ts +20 -0
  317. package/src/v2/runtime/intelligence-platform/__tests__/client.test.ts +605 -0
  318. package/src/v2/runtime/intelligence-platform/client.ts +659 -0
  319. package/src/v2/runtime/intelligence-platform/index.ts +10 -0
  320. package/src/v2/runtime/middleware-sse-parser.ts +200 -0
  321. package/src/v2/runtime/middleware.ts +115 -0
  322. package/src/v2/runtime/runner/__tests__/finalize-events.test.ts +109 -0
  323. package/src/v2/runtime/runner/__tests__/in-memory-runner.e2e.test.ts +775 -0
  324. package/src/v2/runtime/runner/__tests__/in-memory-runner.test.ts +363 -0
  325. package/src/v2/runtime/runner/__tests__/intelligence-runner.test.ts +981 -0
  326. package/src/v2/runtime/runner/agent-runner.ts +36 -0
  327. package/src/v2/runtime/runner/in-memory.ts +381 -0
  328. package/src/v2/runtime/runner/index.ts +4 -0
  329. package/src/v2/runtime/runner/intelligence.ts +429 -0
  330. package/src/v2/runtime/runtime.ts +260 -0
  331. package/src/v2/runtime/telemetry/events.ts +35 -0
  332. package/src/v2/runtime/telemetry/index.ts +7 -0
  333. package/src/v2/runtime/telemetry/scarf-client.ts +39 -0
  334. package/src/v2/runtime/telemetry/telemetry-client.ts +70 -0
  335. package/src/v2/runtime/transcription-service/transcription-service.ts +11 -0
  336. package/tsconfig.json +9 -2
  337. package/tsdown.config.ts +1 -0
@@ -0,0 +1,122 @@
1
+ import express from "express";
2
+ import type { AddressInfo } from "node:net";
3
+ import { afterEach, describe, expect, it } from "vitest";
4
+
5
+ import { createCopilotEndpointSingleRouteExpress } from "../express";
6
+ import { CopilotRuntime } from "../runtime";
7
+ import { InMemoryAgentRunner } from "../runner/in-memory";
8
+
9
+ const buildRuntime = () => {
10
+ const fakeAgent = {
11
+ clone: () => ({
12
+ setMessages: () => undefined,
13
+ setState: () => undefined,
14
+ threadId: "thread",
15
+ runAgent: async (
16
+ input: { runId: string },
17
+ { onEvent }: { onEvent: (payload: { event: unknown }) => void },
18
+ ) => {
19
+ onEvent({
20
+ event: {
21
+ type: "RUN_STARTED",
22
+ runId: input.runId,
23
+ input: { runId: input.runId },
24
+ },
25
+ });
26
+ onEvent({ event: { type: "TEXT_MESSAGE_START", messageId: "m1" } });
27
+ onEvent({
28
+ event: {
29
+ type: "TEXT_MESSAGE_CONTENT",
30
+ messageId: "m1",
31
+ delta: "hello",
32
+ },
33
+ });
34
+ onEvent({ event: { type: "TEXT_MESSAGE_END", messageId: "m1" } });
35
+ onEvent({ event: { type: "RUN_FINISHED", runId: input.runId } });
36
+ },
37
+ }),
38
+ };
39
+
40
+ return new CopilotRuntime({
41
+ agents: { default: fakeAgent },
42
+ runner: new InMemoryAgentRunner(),
43
+ });
44
+ };
45
+
46
+ async function readStreamText(
47
+ stream: ReadableStream<Uint8Array>,
48
+ ): Promise<string> {
49
+ const reader = stream.getReader();
50
+ const decoder = new TextDecoder();
51
+ let output = "";
52
+
53
+ for (let i = 0; i < 20; i += 1) {
54
+ const { done, value } = await reader.read();
55
+ if (done) {
56
+ break;
57
+ }
58
+ if (value) {
59
+ output += decoder.decode(value, { stream: true });
60
+ if (output.includes("RUN_FINISHED")) {
61
+ break;
62
+ }
63
+ }
64
+ }
65
+
66
+ await reader.cancel();
67
+ output += decoder.decode();
68
+ return output;
69
+ }
70
+
71
+ describe("Express single-route SSE streaming", () => {
72
+ let server: ReturnType<express.Express["listen"]> | undefined;
73
+
74
+ afterEach(() => {
75
+ if (server) {
76
+ server.close();
77
+ server = undefined;
78
+ }
79
+ });
80
+
81
+ it("streams SSE events for single-route run requests", async () => {
82
+ const runtime = buildRuntime();
83
+ const app = express();
84
+ app.use(
85
+ createCopilotEndpointSingleRouteExpress({ runtime, basePath: "/" }),
86
+ );
87
+
88
+ server = app.listen(0);
89
+ const { port } = server.address() as AddressInfo;
90
+
91
+ const response = await fetch(`http://localhost:${port}/`, {
92
+ method: "POST",
93
+ headers: {
94
+ "Content-Type": "application/json",
95
+ Accept: "text/event-stream",
96
+ },
97
+ body: JSON.stringify({
98
+ method: "agent/run",
99
+ params: { agentId: "default" },
100
+ body: {
101
+ threadId: "thread",
102
+ runId: "run-1",
103
+ messages: [],
104
+ state: {},
105
+ tools: [],
106
+ context: [],
107
+ forwardedProps: {},
108
+ },
109
+ }),
110
+ });
111
+
112
+ expect(response.status).toBe(200);
113
+ expect(response.headers.get("content-type")).toContain("text/event-stream");
114
+ expect(response.body).toBeTruthy();
115
+
116
+ const payload = await readStreamText(response.body!);
117
+ expect(payload).toContain("data:");
118
+ expect(payload).toContain("RUN_STARTED");
119
+ expect(payload).toContain("TEXT_MESSAGE_CONTENT");
120
+ expect(payload).toContain("RUN_FINISHED");
121
+ });
122
+ });
@@ -0,0 +1,141 @@
1
+ import { handleGetRuntimeInfo } from "../handlers/get-runtime-info";
2
+ import { CopilotRuntime } from "../runtime";
3
+ import { TranscriptionService } from "../transcription-service/transcription-service";
4
+ import { describe, it, expect } from "vitest";
5
+ import type { AbstractAgent } from "@ag-ui/client";
6
+
7
+ // Mock transcription service
8
+ class MockTranscriptionService extends TranscriptionService {
9
+ async transcribeFile(): Promise<string> {
10
+ return "Mock transcription result";
11
+ }
12
+ }
13
+
14
+ describe("handleGetRuntimeInfo", () => {
15
+ const mockRequest = new Request("https://example.com/info");
16
+
17
+ it("should return runtime info with audioFileTranscriptionEnabled=false when no transcription service", async () => {
18
+ const runtime = new CopilotRuntime({
19
+ agents: {},
20
+ // No transcriptionService provided
21
+ });
22
+
23
+ const response = await handleGetRuntimeInfo({
24
+ runtime,
25
+ request: mockRequest,
26
+ });
27
+
28
+ expect(response.status).toBe(200);
29
+
30
+ const data = await response.json();
31
+ expect(data).toEqual({
32
+ version: expect.any(String),
33
+ agents: {},
34
+ audioFileTranscriptionEnabled: false,
35
+ mode: "sse",
36
+ a2uiEnabled: false,
37
+ });
38
+ });
39
+
40
+ it("should return runtime info with audioFileTranscriptionEnabled=true when transcription service is configured", async () => {
41
+ const mockTranscriptionService = new MockTranscriptionService();
42
+ const runtime = new CopilotRuntime({
43
+ agents: {},
44
+ transcriptionService: mockTranscriptionService,
45
+ });
46
+
47
+ const response = await handleGetRuntimeInfo({
48
+ runtime,
49
+ request: mockRequest,
50
+ });
51
+
52
+ expect(response.status).toBe(200);
53
+
54
+ const data = await response.json();
55
+ expect(data).toEqual({
56
+ version: expect.any(String),
57
+ agents: {},
58
+ audioFileTranscriptionEnabled: true,
59
+ mode: "sse",
60
+ a2uiEnabled: false,
61
+ });
62
+ });
63
+
64
+ it("should include agents information along with audioFileTranscriptionEnabled", async () => {
65
+ const mockAgent = {
66
+ description: "Test agent description",
67
+ constructor: { name: "TestAgent" },
68
+ };
69
+
70
+ const runtime = new CopilotRuntime({
71
+ agents: {
72
+ testAgent: mockAgent as AbstractAgent,
73
+ },
74
+ transcriptionService: new MockTranscriptionService(),
75
+ });
76
+
77
+ const response = await handleGetRuntimeInfo({
78
+ runtime,
79
+ request: mockRequest,
80
+ });
81
+
82
+ expect(response.status).toBe(200);
83
+
84
+ const data = await response.json();
85
+ expect(data).toEqual({
86
+ version: expect.any(String),
87
+ agents: {
88
+ testAgent: {
89
+ name: "testAgent",
90
+ description: "Test agent description",
91
+ className: "TestAgent",
92
+ },
93
+ },
94
+ audioFileTranscriptionEnabled: true,
95
+ mode: "sse",
96
+ a2uiEnabled: false,
97
+ });
98
+ });
99
+
100
+ it("should return a2uiEnabled: true when runtime has a2ui configured", async () => {
101
+ const runtime = new CopilotRuntime({
102
+ agents: {},
103
+ a2ui: {},
104
+ });
105
+
106
+ const response = await handleGetRuntimeInfo({
107
+ runtime,
108
+ request: mockRequest,
109
+ });
110
+
111
+ expect(response.status).toBe(200);
112
+
113
+ const data = await response.json();
114
+ expect(data.a2uiEnabled).toBe(true);
115
+ });
116
+
117
+ it("should return 500 error when runtime.agents throws an error", async () => {
118
+ const runtime = {
119
+ get agents(): Record<string, AbstractAgent> {
120
+ throw new Error("Failed to get agents");
121
+ },
122
+ transcriptionService: undefined,
123
+ beforeRequestMiddleware: undefined,
124
+ afterRequestMiddleware: undefined,
125
+ mode: "sse",
126
+ } as CopilotRuntime;
127
+
128
+ const response = await handleGetRuntimeInfo({
129
+ runtime,
130
+ request: mockRequest,
131
+ });
132
+
133
+ expect(response.status).toBe(500);
134
+
135
+ const data = await response.json();
136
+ expect(data).toEqual({
137
+ error: "Failed to retrieve runtime information",
138
+ message: "Failed to get agents",
139
+ });
140
+ });
141
+ });
@@ -0,0 +1,423 @@
1
+ import { Observable } from "rxjs";
2
+ import { describe, it, expect, vi } from "vitest";
3
+ import { BaseEvent } from "@ag-ui/client";
4
+ import { handleConnectAgent } from "../handlers/handle-connect";
5
+ import { CopilotRuntime } from "../runtime";
6
+ import { AgentRunnerConnectRequest } from "../runner/agent-runner";
7
+ import { IntelligenceAgentRunner } from "../runner/intelligence";
8
+ import { CopilotKitIntelligence } from "../intelligence-platform/client";
9
+
10
+ describe("handleConnectAgent", () => {
11
+ const createMockRuntime = (
12
+ agents: Record<string, unknown> = {},
13
+ connectHandler?: (
14
+ request: AgentRunnerConnectRequest,
15
+ ) => Observable<BaseEvent>,
16
+ ): CopilotRuntime => {
17
+ return {
18
+ agents: Promise.resolve(agents),
19
+ transcriptionService: undefined,
20
+ beforeRequestMiddleware: undefined,
21
+ afterRequestMiddleware: undefined,
22
+ runner: {
23
+ run: () =>
24
+ new Observable<BaseEvent>((subscriber) => {
25
+ subscriber.complete();
26
+ }),
27
+ connect:
28
+ connectHandler ??
29
+ (() =>
30
+ new Observable<BaseEvent>((subscriber) => {
31
+ subscriber.complete();
32
+ })),
33
+ isRunning: async () => false,
34
+ stop: async () => false,
35
+ },
36
+ } as CopilotRuntime;
37
+ };
38
+
39
+ it("should return 404 when agent does not exist", async () => {
40
+ const runtime = createMockRuntime({});
41
+ const request = new Request(
42
+ "https://example.com/agent/nonexistent/connect",
43
+ {
44
+ method: "POST",
45
+ headers: { "Content-Type": "application/json" },
46
+ body: JSON.stringify({
47
+ threadId: "thread-1",
48
+ runId: "run-1",
49
+ state: {},
50
+ messages: [],
51
+ tools: [],
52
+ context: [],
53
+ forwardedProps: {},
54
+ }),
55
+ },
56
+ );
57
+
58
+ const response = await handleConnectAgent({
59
+ runtime,
60
+ request,
61
+ agentId: "nonexistent-agent",
62
+ });
63
+
64
+ expect(response.status).toBe(404);
65
+ expect(response.headers.get("Content-Type")).toBe("application/json");
66
+
67
+ const body = await response.json();
68
+ expect(body).toEqual({
69
+ error: "Agent not found",
70
+ message: "Agent 'nonexistent-agent' does not exist",
71
+ });
72
+ });
73
+
74
+ it("forwards only authorization and custom x- headers to runner.connect()", async () => {
75
+ const recordedRequests: AgentRunnerConnectRequest[] = [];
76
+ let resolveConnect: (() => void) | undefined;
77
+ const connectInvoked = new Promise<void>((resolve) => {
78
+ resolveConnect = resolve;
79
+ });
80
+
81
+ const runtime = createMockRuntime(
82
+ { "test-agent": { clone: () => ({}) } },
83
+ (request: AgentRunnerConnectRequest) =>
84
+ new Observable<BaseEvent>((subscriber) => {
85
+ recordedRequests.push(request);
86
+ resolveConnect?.();
87
+ subscriber.complete();
88
+ }),
89
+ );
90
+
91
+ const requestBody = {
92
+ threadId: "thread-1",
93
+ runId: "run-1",
94
+ state: {},
95
+ messages: [],
96
+ tools: [],
97
+ context: [],
98
+ forwardedProps: {},
99
+ };
100
+
101
+ const request = new Request(
102
+ "https://example.com/agent/test-agent/connect",
103
+ {
104
+ method: "POST",
105
+ headers: {
106
+ "Content-Type": "application/json",
107
+ "X-Custom": "custom-value",
108
+ "X-Another-Header": "another-value",
109
+ Authorization: "Bearer forwarded-token",
110
+ Origin: "http://localhost:4200",
111
+ "User-Agent": "test-agent",
112
+ },
113
+ body: JSON.stringify(requestBody),
114
+ },
115
+ );
116
+
117
+ const response = await handleConnectAgent({
118
+ runtime,
119
+ request,
120
+ agentId: "test-agent",
121
+ });
122
+
123
+ expect(response.status).toBe(200);
124
+ await connectInvoked;
125
+
126
+ expect(recordedRequests).toHaveLength(1);
127
+ expect(recordedRequests[0].threadId).toBe("thread-1");
128
+ expect(recordedRequests[0].headers).toMatchObject({
129
+ authorization: "Bearer forwarded-token",
130
+ "x-custom": "custom-value",
131
+ "x-another-header": "another-value",
132
+ });
133
+ expect(recordedRequests[0].headers).not.toHaveProperty("origin");
134
+ expect(recordedRequests[0].headers).not.toHaveProperty("content-type");
135
+ expect(recordedRequests[0].headers).not.toHaveProperty("user-agent");
136
+ });
137
+
138
+ it("passes empty headers object when no forwardable headers present", async () => {
139
+ const recordedRequests: AgentRunnerConnectRequest[] = [];
140
+ let resolveConnect: (() => void) | undefined;
141
+ const connectInvoked = new Promise<void>((resolve) => {
142
+ resolveConnect = resolve;
143
+ });
144
+
145
+ const runtime = createMockRuntime(
146
+ { "test-agent": { clone: () => ({}) } },
147
+ (request: AgentRunnerConnectRequest) =>
148
+ new Observable<BaseEvent>((subscriber) => {
149
+ recordedRequests.push(request);
150
+ resolveConnect?.();
151
+ subscriber.complete();
152
+ }),
153
+ );
154
+
155
+ const requestBody = {
156
+ threadId: "thread-1",
157
+ runId: "run-1",
158
+ state: {},
159
+ messages: [],
160
+ tools: [],
161
+ context: [],
162
+ forwardedProps: {},
163
+ };
164
+
165
+ const request = new Request(
166
+ "https://example.com/agent/test-agent/connect",
167
+ {
168
+ method: "POST",
169
+ headers: {
170
+ "Content-Type": "application/json",
171
+ Origin: "http://localhost:4200",
172
+ },
173
+ body: JSON.stringify(requestBody),
174
+ },
175
+ );
176
+
177
+ const response = await handleConnectAgent({
178
+ runtime,
179
+ request,
180
+ agentId: "test-agent",
181
+ });
182
+
183
+ expect(response.status).toBe(200);
184
+ await connectInvoked;
185
+
186
+ expect(recordedRequests).toHaveLength(1);
187
+ expect(recordedRequests[0].headers).toEqual({});
188
+ });
189
+
190
+ describe("IntelligenceAgentRunner connect planning path", () => {
191
+ const createConnectRequest = (
192
+ headers?: Record<string, string>,
193
+ lastSeenEventId?: string | null,
194
+ ) =>
195
+ new Request("https://example.com/agent/my-agent/connect", {
196
+ method: "POST",
197
+ headers: { "Content-Type": "application/json", ...headers },
198
+ body: JSON.stringify({
199
+ threadId: "thread-1",
200
+ runId: "run-1",
201
+ state: {},
202
+ messages: [],
203
+ tools: [],
204
+ context: [],
205
+ forwardedProps: {},
206
+ ...(lastSeenEventId !== undefined ? { lastSeenEventId } : {}),
207
+ }),
208
+ });
209
+
210
+ const createIntelligenceRuntime = (
211
+ platform?: Partial<CopilotKitIntelligence>,
212
+ ) => {
213
+ const runner = Object.create(IntelligenceAgentRunner.prototype);
214
+ runner.connect = vi.fn(
215
+ () =>
216
+ new Observable<BaseEvent>((subscriber) => {
217
+ subscriber.complete();
218
+ }),
219
+ );
220
+ return {
221
+ agents: Promise.resolve({
222
+ "my-agent": { clone: () => ({}) },
223
+ }),
224
+ transcriptionService: undefined,
225
+ beforeRequestMiddleware: undefined,
226
+ afterRequestMiddleware: undefined,
227
+ runner,
228
+ mode: "intelligence",
229
+ identifyUser: vi.fn().mockResolvedValue({ id: "user-1" }),
230
+ intelligence: platform,
231
+ } as unknown as CopilotRuntime;
232
+ };
233
+
234
+ it("returns a live connect plan when join credentials are available", async () => {
235
+ const platform = {
236
+ ɵconnectThread: vi.fn().mockResolvedValue({
237
+ mode: "live",
238
+ joinToken: "jt-connect-1",
239
+ joinFromEventId: "event-1",
240
+ events: [],
241
+ }),
242
+ };
243
+ const runtime = createIntelligenceRuntime(platform as any);
244
+
245
+ const response = await handleConnectAgent({
246
+ runtime,
247
+ request: createConnectRequest(),
248
+ agentId: "my-agent",
249
+ });
250
+
251
+ expect(response.status).toBe(200);
252
+ expect(response.headers.get("Content-Type")).toBe("application/json");
253
+ const body = await response.json();
254
+ expect(body).toEqual({
255
+ mode: "live",
256
+ joinToken: "jt-connect-1",
257
+ joinFromEventId: "event-1",
258
+ events: [],
259
+ });
260
+ expect(platform.ɵconnectThread).toHaveBeenCalledWith({
261
+ threadId: "thread-1",
262
+ userId: "user-1",
263
+ lastSeenEventId: null,
264
+ });
265
+ });
266
+
267
+ it("returns a bootstrap connect plan when no socket is needed", async () => {
268
+ const platform = {
269
+ ɵconnectThread: vi.fn().mockResolvedValue({
270
+ mode: "bootstrap",
271
+ latestEventId: "event-2",
272
+ events: [{ type: "MESSAGES_SNAPSHOT", messages: [] }],
273
+ }),
274
+ };
275
+ const runtime = createIntelligenceRuntime(platform as any);
276
+
277
+ const response = await handleConnectAgent({
278
+ runtime,
279
+ request: createConnectRequest(),
280
+ agentId: "my-agent",
281
+ });
282
+
283
+ expect(response.status).toBe(200);
284
+ const body = await response.json();
285
+ expect(body).toEqual({
286
+ mode: "bootstrap",
287
+ latestEventId: "event-2",
288
+ events: [{ type: "MESSAGES_SNAPSHOT", messages: [] }],
289
+ });
290
+ });
291
+
292
+ it("returns 204 when connect targets a fresh thread", async () => {
293
+ const platform = {
294
+ ɵconnectThread: vi.fn().mockResolvedValue(null),
295
+ createThread: vi.fn(),
296
+ };
297
+ const runtime = createIntelligenceRuntime(platform as any);
298
+
299
+ const response = await handleConnectAgent({
300
+ runtime,
301
+ request: createConnectRequest(),
302
+ agentId: "my-agent",
303
+ });
304
+
305
+ expect(response.status).toBe(204);
306
+ expect(platform.createThread).not.toHaveBeenCalled();
307
+ expect(platform.ɵconnectThread).toHaveBeenCalledTimes(1);
308
+ expect(platform.ɵconnectThread).toHaveBeenCalledWith({
309
+ threadId: "thread-1",
310
+ userId: "user-1",
311
+ lastSeenEventId: null,
312
+ });
313
+ });
314
+
315
+ it("returns 404 when connect planning is not available", async () => {
316
+ const platform = {
317
+ ɵconnectThread: vi
318
+ .fn()
319
+ .mockRejectedValue(new Error("No active connect plan")),
320
+ };
321
+ const runtime = createIntelligenceRuntime(platform as any);
322
+
323
+ const response = await handleConnectAgent({
324
+ runtime,
325
+ request: createConnectRequest(),
326
+ agentId: "my-agent",
327
+ });
328
+
329
+ expect(response.status).toBe(404);
330
+ const body = await response.json();
331
+ expect(body.error).toBe("Connect plan not available");
332
+ });
333
+
334
+ it("forwards lastSeenEventId to the intelligence platform", async () => {
335
+ const platform = {
336
+ ɵconnectThread: vi.fn().mockResolvedValue(null),
337
+ };
338
+ const runtime = createIntelligenceRuntime(platform as any);
339
+
340
+ const response = await handleConnectAgent({
341
+ runtime,
342
+ request: createConnectRequest(undefined, "event-9"),
343
+ agentId: "my-agent",
344
+ });
345
+
346
+ expect(response.status).toBe(204);
347
+ expect(platform.ɵconnectThread).toHaveBeenCalledWith({
348
+ threadId: "thread-1",
349
+ userId: "user-1",
350
+ lastSeenEventId: "event-9",
351
+ });
352
+ });
353
+
354
+ it("uses identifyUser instead of a conflicting X-User-Id header", async () => {
355
+ const platform = {
356
+ ɵconnectThread: vi.fn().mockResolvedValue(null),
357
+ };
358
+ const identifyUser = vi.fn().mockResolvedValue({ id: "resolved-user" });
359
+ const runtime = createIntelligenceRuntime(platform as any);
360
+ runtime.identifyUser = identifyUser;
361
+ const request = createConnectRequest(
362
+ { "X-User-Id": "legacy-user" },
363
+ "event-9",
364
+ );
365
+
366
+ const response = await handleConnectAgent({
367
+ runtime,
368
+ request,
369
+ agentId: "my-agent",
370
+ });
371
+
372
+ expect(response.status).toBe(204);
373
+ expect(identifyUser).toHaveBeenCalledTimes(1);
374
+ expect(identifyUser).toHaveBeenCalledWith(request);
375
+ expect(platform.ɵconnectThread).toHaveBeenCalledWith({
376
+ threadId: "thread-1",
377
+ userId: "resolved-user",
378
+ lastSeenEventId: "event-9",
379
+ });
380
+ });
381
+
382
+ it("returns 400 when identifyUser returns an invalid id", async () => {
383
+ const platform = {
384
+ ɵconnectThread: vi.fn(),
385
+ };
386
+ const runtime = createIntelligenceRuntime(platform as any);
387
+ runtime.identifyUser = vi.fn().mockResolvedValue({ id: "" });
388
+
389
+ const response = await handleConnectAgent({
390
+ runtime,
391
+ request: createConnectRequest(),
392
+ agentId: "my-agent",
393
+ });
394
+
395
+ expect(response.status).toBe(400);
396
+ expect(platform.ɵconnectThread).not.toHaveBeenCalled();
397
+ });
398
+
399
+ it("returns 500 when identifyUser throws", async () => {
400
+ const platform = {
401
+ ɵconnectThread: vi.fn(),
402
+ };
403
+ const runtime = createIntelligenceRuntime(platform as any);
404
+ runtime.identifyUser = vi
405
+ .fn()
406
+ .mockRejectedValue(new Error("auth failed"));
407
+ const errorSpy = vi.spyOn(console, "error").mockImplementation(() => {});
408
+
409
+ try {
410
+ const response = await handleConnectAgent({
411
+ runtime,
412
+ request: createConnectRequest(),
413
+ agentId: "my-agent",
414
+ });
415
+
416
+ expect(response.status).toBe(500);
417
+ expect(platform.ɵconnectThread).not.toHaveBeenCalled();
418
+ } finally {
419
+ errorSpy.mockRestore();
420
+ }
421
+ });
422
+ });
423
+ });