@copilotkit/runtime 1.69.0 → 1.69.1

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 (506) hide show
  1. package/dist/_virtual/_rolldown/runtime.mjs +1 -15
  2. package/dist/agents/langgraph/events.cjs +1 -1
  3. package/dist/agents/langgraph/events.cjs.map +1 -1
  4. package/dist/agents/langgraph/events.mjs +1 -1
  5. package/dist/agents/langgraph/events.mjs.map +1 -1
  6. package/dist/graphql/inputs/action.input.cjs +1 -1
  7. package/dist/graphql/inputs/action.input.cjs.map +1 -1
  8. package/dist/graphql/inputs/action.input.d.cts +1 -1
  9. package/dist/graphql/inputs/action.input.d.cts.map +1 -1
  10. package/dist/graphql/inputs/action.input.d.mts +1 -1
  11. package/dist/graphql/inputs/action.input.d.mts.map +1 -1
  12. package/dist/graphql/inputs/action.input.mjs +1 -1
  13. package/dist/graphql/inputs/action.input.mjs.map +1 -1
  14. package/dist/graphql/inputs/agent-session.input.cjs +1 -1
  15. package/dist/graphql/inputs/agent-session.input.cjs.map +1 -1
  16. package/dist/graphql/inputs/agent-session.input.d.cts +1 -1
  17. package/dist/graphql/inputs/agent-session.input.d.cts.map +1 -1
  18. package/dist/graphql/inputs/agent-session.input.d.mts +1 -1
  19. package/dist/graphql/inputs/agent-session.input.d.mts.map +1 -1
  20. package/dist/graphql/inputs/agent-session.input.mjs +1 -1
  21. package/dist/graphql/inputs/agent-session.input.mjs.map +1 -1
  22. package/dist/graphql/inputs/agent-state.input.cjs +1 -1
  23. package/dist/graphql/inputs/agent-state.input.cjs.map +1 -1
  24. package/dist/graphql/inputs/agent-state.input.d.cts +1 -1
  25. package/dist/graphql/inputs/agent-state.input.d.cts.map +1 -1
  26. package/dist/graphql/inputs/agent-state.input.d.mts +1 -1
  27. package/dist/graphql/inputs/agent-state.input.d.mts.map +1 -1
  28. package/dist/graphql/inputs/agent-state.input.mjs +1 -1
  29. package/dist/graphql/inputs/agent-state.input.mjs.map +1 -1
  30. package/dist/graphql/inputs/cloud-guardrails.input.cjs +1 -1
  31. package/dist/graphql/inputs/cloud-guardrails.input.cjs.map +1 -1
  32. package/dist/graphql/inputs/cloud-guardrails.input.mjs +1 -1
  33. package/dist/graphql/inputs/cloud-guardrails.input.mjs.map +1 -1
  34. package/dist/graphql/inputs/cloud.input.cjs +1 -1
  35. package/dist/graphql/inputs/cloud.input.cjs.map +1 -1
  36. package/dist/graphql/inputs/cloud.input.mjs +1 -1
  37. package/dist/graphql/inputs/cloud.input.mjs.map +1 -1
  38. package/dist/graphql/inputs/copilot-context.input.cjs +1 -1
  39. package/dist/graphql/inputs/copilot-context.input.cjs.map +1 -1
  40. package/dist/graphql/inputs/copilot-context.input.mjs +1 -1
  41. package/dist/graphql/inputs/copilot-context.input.mjs.map +1 -1
  42. package/dist/graphql/inputs/extensions.input.cjs +1 -1
  43. package/dist/graphql/inputs/extensions.input.cjs.map +1 -1
  44. package/dist/graphql/inputs/extensions.input.d.cts +1 -1
  45. package/dist/graphql/inputs/extensions.input.d.cts.map +1 -1
  46. package/dist/graphql/inputs/extensions.input.d.mts +1 -1
  47. package/dist/graphql/inputs/extensions.input.d.mts.map +1 -1
  48. package/dist/graphql/inputs/extensions.input.mjs +1 -1
  49. package/dist/graphql/inputs/extensions.input.mjs.map +1 -1
  50. package/dist/graphql/inputs/forwarded-parameters.input.cjs +2 -3
  51. package/dist/graphql/inputs/forwarded-parameters.input.cjs.map +1 -1
  52. package/dist/graphql/inputs/forwarded-parameters.input.d.cts +2 -2
  53. package/dist/graphql/inputs/forwarded-parameters.input.d.cts.map +1 -1
  54. package/dist/graphql/inputs/forwarded-parameters.input.d.mts +2 -2
  55. package/dist/graphql/inputs/forwarded-parameters.input.d.mts.map +1 -1
  56. package/dist/graphql/inputs/forwarded-parameters.input.mjs +2 -3
  57. package/dist/graphql/inputs/forwarded-parameters.input.mjs.map +1 -1
  58. package/dist/graphql/inputs/frontend.input.cjs +1 -1
  59. package/dist/graphql/inputs/frontend.input.cjs.map +1 -1
  60. package/dist/graphql/inputs/frontend.input.mjs +1 -1
  61. package/dist/graphql/inputs/frontend.input.mjs.map +1 -1
  62. package/dist/graphql/inputs/generate-copilot-response.input.cjs +1 -1
  63. package/dist/graphql/inputs/generate-copilot-response.input.cjs.map +1 -1
  64. package/dist/graphql/inputs/generate-copilot-response.input.mjs +1 -1
  65. package/dist/graphql/inputs/generate-copilot-response.input.mjs.map +1 -1
  66. package/dist/graphql/inputs/load-agent-state.input.cjs +1 -1
  67. package/dist/graphql/inputs/load-agent-state.input.cjs.map +1 -1
  68. package/dist/graphql/inputs/load-agent-state.input.mjs +1 -1
  69. package/dist/graphql/inputs/load-agent-state.input.mjs.map +1 -1
  70. package/dist/graphql/inputs/message.input.cjs +10 -10
  71. package/dist/graphql/inputs/message.input.cjs.map +1 -1
  72. package/dist/graphql/inputs/message.input.d.cts +2 -2
  73. package/dist/graphql/inputs/message.input.d.cts.map +1 -1
  74. package/dist/graphql/inputs/message.input.d.mts +2 -2
  75. package/dist/graphql/inputs/message.input.d.mts.map +1 -1
  76. package/dist/graphql/inputs/message.input.mjs +10 -10
  77. package/dist/graphql/inputs/message.input.mjs.map +1 -1
  78. package/dist/graphql/inputs/meta-event.input.cjs +1 -1
  79. package/dist/graphql/inputs/meta-event.input.cjs.map +1 -1
  80. package/dist/graphql/inputs/meta-event.input.mjs +1 -1
  81. package/dist/graphql/inputs/meta-event.input.mjs.map +1 -1
  82. package/dist/graphql/message-conversion/agui-to-gql.cjs +1 -1
  83. package/dist/graphql/message-conversion/agui-to-gql.cjs.map +1 -1
  84. package/dist/graphql/message-conversion/agui-to-gql.mjs +1 -1
  85. package/dist/graphql/message-conversion/agui-to-gql.mjs.map +1 -1
  86. package/dist/graphql/resolvers/copilot.resolver.cjs +1 -1
  87. package/dist/graphql/resolvers/copilot.resolver.cjs.map +1 -1
  88. package/dist/graphql/resolvers/copilot.resolver.mjs +1 -1
  89. package/dist/graphql/resolvers/copilot.resolver.mjs.map +1 -1
  90. package/dist/graphql/resolvers/resolve-message-id.cjs +1 -1
  91. package/dist/graphql/resolvers/resolve-message-id.cjs.map +1 -1
  92. package/dist/graphql/resolvers/resolve-message-id.mjs +1 -1
  93. package/dist/graphql/resolvers/resolve-message-id.mjs.map +1 -1
  94. package/dist/graphql/resolvers/state.resolver.cjs +1 -1
  95. package/dist/graphql/resolvers/state.resolver.cjs.map +1 -1
  96. package/dist/graphql/resolvers/state.resolver.mjs +1 -1
  97. package/dist/graphql/resolvers/state.resolver.mjs.map +1 -1
  98. package/dist/graphql/types/agents-response.type.cjs +1 -1
  99. package/dist/graphql/types/agents-response.type.cjs.map +1 -1
  100. package/dist/graphql/types/agents-response.type.mjs +1 -1
  101. package/dist/graphql/types/agents-response.type.mjs.map +1 -1
  102. package/dist/graphql/types/base/index.cjs +1 -1
  103. package/dist/graphql/types/base/index.cjs.map +1 -1
  104. package/dist/graphql/types/base/index.d.cts +1 -1
  105. package/dist/graphql/types/base/index.d.cts.map +1 -1
  106. package/dist/graphql/types/base/index.d.mts +1 -1
  107. package/dist/graphql/types/base/index.d.mts.map +1 -1
  108. package/dist/graphql/types/base/index.mjs +1 -1
  109. package/dist/graphql/types/base/index.mjs.map +1 -1
  110. package/dist/graphql/types/converted/index.cjs +2 -2
  111. package/dist/graphql/types/converted/index.cjs.map +1 -1
  112. package/dist/graphql/types/converted/index.d.cts +1 -1
  113. package/dist/graphql/types/converted/index.d.cts.map +1 -1
  114. package/dist/graphql/types/converted/index.d.mts +1 -1
  115. package/dist/graphql/types/converted/index.d.mts.map +1 -1
  116. package/dist/graphql/types/converted/index.mjs +2 -2
  117. package/dist/graphql/types/converted/index.mjs.map +1 -1
  118. package/dist/graphql/types/copilot-response.type.cjs +1 -1
  119. package/dist/graphql/types/copilot-response.type.cjs.map +1 -1
  120. package/dist/graphql/types/copilot-response.type.d.cts +1 -1
  121. package/dist/graphql/types/copilot-response.type.d.cts.map +1 -1
  122. package/dist/graphql/types/copilot-response.type.d.mts +1 -1
  123. package/dist/graphql/types/copilot-response.type.d.mts.map +1 -1
  124. package/dist/graphql/types/copilot-response.type.mjs +1 -1
  125. package/dist/graphql/types/copilot-response.type.mjs.map +1 -1
  126. package/dist/graphql/types/enums.cjs +1 -1
  127. package/dist/graphql/types/enums.cjs.map +1 -1
  128. package/dist/graphql/types/enums.d.cts +1 -1
  129. package/dist/graphql/types/enums.d.cts.map +1 -1
  130. package/dist/graphql/types/enums.d.mts +1 -1
  131. package/dist/graphql/types/enums.d.mts.map +1 -1
  132. package/dist/graphql/types/enums.mjs +1 -1
  133. package/dist/graphql/types/enums.mjs.map +1 -1
  134. package/dist/graphql/types/extensions-response.type.cjs +1 -1
  135. package/dist/graphql/types/extensions-response.type.cjs.map +1 -1
  136. package/dist/graphql/types/extensions-response.type.d.cts +1 -1
  137. package/dist/graphql/types/extensions-response.type.d.cts.map +1 -1
  138. package/dist/graphql/types/extensions-response.type.d.mts +1 -1
  139. package/dist/graphql/types/extensions-response.type.d.mts.map +1 -1
  140. package/dist/graphql/types/extensions-response.type.mjs +1 -1
  141. package/dist/graphql/types/extensions-response.type.mjs.map +1 -1
  142. package/dist/graphql/types/load-agent-state-response.type.cjs +1 -1
  143. package/dist/graphql/types/load-agent-state-response.type.cjs.map +1 -1
  144. package/dist/graphql/types/load-agent-state-response.type.mjs +1 -1
  145. package/dist/graphql/types/load-agent-state-response.type.mjs.map +1 -1
  146. package/dist/graphql/types/message-status.type.cjs +1 -1
  147. package/dist/graphql/types/message-status.type.cjs.map +1 -1
  148. package/dist/graphql/types/message-status.type.d.cts +1 -1
  149. package/dist/graphql/types/message-status.type.d.cts.map +1 -1
  150. package/dist/graphql/types/message-status.type.d.mts +1 -1
  151. package/dist/graphql/types/message-status.type.d.mts.map +1 -1
  152. package/dist/graphql/types/message-status.type.mjs +1 -1
  153. package/dist/graphql/types/message-status.type.mjs.map +1 -1
  154. package/dist/graphql/types/meta-events.type.cjs +2 -2
  155. package/dist/graphql/types/meta-events.type.cjs.map +1 -1
  156. package/dist/graphql/types/meta-events.type.mjs +2 -2
  157. package/dist/graphql/types/meta-events.type.mjs.map +1 -1
  158. package/dist/graphql/types/response-status.type.cjs +1 -1
  159. package/dist/graphql/types/response-status.type.cjs.map +1 -1
  160. package/dist/graphql/types/response-status.type.d.cts +1 -1
  161. package/dist/graphql/types/response-status.type.d.cts.map +1 -1
  162. package/dist/graphql/types/response-status.type.d.mts +1 -1
  163. package/dist/graphql/types/response-status.type.d.mts.map +1 -1
  164. package/dist/graphql/types/response-status.type.mjs +1 -1
  165. package/dist/graphql/types/response-status.type.mjs.map +1 -1
  166. package/dist/index.d.cts +618 -4
  167. package/dist/index.d.mts +618 -4
  168. package/dist/langgraph.d.cts +54 -1
  169. package/dist/langgraph.d.mts +54 -1
  170. package/dist/lib/cloud/index.d.cts +1 -1
  171. package/dist/lib/cloud/index.d.cts.map +1 -1
  172. package/dist/lib/cloud/index.d.mts +1 -1
  173. package/dist/lib/cloud/index.d.mts.map +1 -1
  174. package/dist/lib/index.cjs +1 -1
  175. package/dist/lib/index.cjs.map +1 -1
  176. package/dist/lib/index.d.cts +2 -2
  177. package/dist/lib/index.d.cts.map +1 -1
  178. package/dist/lib/index.d.mts +2 -2
  179. package/dist/lib/index.d.mts.map +1 -1
  180. package/dist/lib/index.mjs +1 -1
  181. package/dist/lib/index.mjs.map +1 -1
  182. package/dist/lib/integrations/index.d.cts +1 -1
  183. package/dist/lib/integrations/index.d.mts +1 -1
  184. package/dist/lib/integrations/nest/index.cjs +1 -1
  185. package/dist/lib/integrations/nest/index.cjs.map +1 -1
  186. package/dist/lib/integrations/nest/index.d.cts +1 -1
  187. package/dist/lib/integrations/nest/index.d.cts.map +1 -1
  188. package/dist/lib/integrations/nest/index.d.mts +1 -1
  189. package/dist/lib/integrations/nest/index.d.mts.map +1 -1
  190. package/dist/lib/integrations/nest/index.mjs +1 -1
  191. package/dist/lib/integrations/nest/index.mjs.map +1 -1
  192. package/dist/lib/integrations/nextjs/app-router.cjs +1 -1
  193. package/dist/lib/integrations/nextjs/app-router.cjs.map +1 -1
  194. package/dist/lib/integrations/nextjs/app-router.d.cts +1 -1
  195. package/dist/lib/integrations/nextjs/app-router.d.cts.map +1 -1
  196. package/dist/lib/integrations/nextjs/app-router.d.mts +1 -1
  197. package/dist/lib/integrations/nextjs/app-router.d.mts.map +1 -1
  198. package/dist/lib/integrations/nextjs/app-router.mjs +1 -1
  199. package/dist/lib/integrations/nextjs/app-router.mjs.map +1 -1
  200. package/dist/lib/integrations/nextjs/pages-router.cjs +1 -1
  201. package/dist/lib/integrations/nextjs/pages-router.cjs.map +1 -1
  202. package/dist/lib/integrations/nextjs/pages-router.d.cts +1 -2
  203. package/dist/lib/integrations/nextjs/pages-router.d.cts.map +1 -1
  204. package/dist/lib/integrations/nextjs/pages-router.d.mts +1 -2
  205. package/dist/lib/integrations/nextjs/pages-router.d.mts.map +1 -1
  206. package/dist/lib/integrations/nextjs/pages-router.mjs +1 -1
  207. package/dist/lib/integrations/nextjs/pages-router.mjs.map +1 -1
  208. package/dist/lib/integrations/node-express/index.cjs +1 -1
  209. package/dist/lib/integrations/node-express/index.cjs.map +1 -1
  210. package/dist/lib/integrations/node-express/index.d.cts +1 -1
  211. package/dist/lib/integrations/node-express/index.d.cts.map +1 -1
  212. package/dist/lib/integrations/node-express/index.d.mts +1 -1
  213. package/dist/lib/integrations/node-express/index.d.mts.map +1 -1
  214. package/dist/lib/integrations/node-express/index.mjs +1 -1
  215. package/dist/lib/integrations/node-express/index.mjs.map +1 -1
  216. package/dist/lib/integrations/node-http/index.cjs +1 -1
  217. package/dist/lib/integrations/node-http/index.cjs.map +1 -1
  218. package/dist/lib/integrations/node-http/index.d.cts +1 -1
  219. package/dist/lib/integrations/node-http/index.d.cts.map +1 -1
  220. package/dist/lib/integrations/node-http/index.d.mts +1 -1
  221. package/dist/lib/integrations/node-http/index.d.mts.map +1 -1
  222. package/dist/lib/integrations/node-http/index.mjs +1 -1
  223. package/dist/lib/integrations/node-http/index.mjs.map +1 -1
  224. package/dist/lib/integrations/node-http/request-handler.cjs +1 -1
  225. package/dist/lib/integrations/node-http/request-handler.cjs.map +1 -1
  226. package/dist/lib/integrations/node-http/request-handler.mjs +1 -1
  227. package/dist/lib/integrations/node-http/request-handler.mjs.map +1 -1
  228. package/dist/lib/integrations/shared.cjs +1 -1
  229. package/dist/lib/integrations/shared.cjs.map +1 -1
  230. package/dist/lib/integrations/shared.d.cts +30 -4
  231. package/dist/lib/integrations/shared.d.cts.map +1 -1
  232. package/dist/lib/integrations/shared.d.mts +30 -4
  233. package/dist/lib/integrations/shared.d.mts.map +1 -1
  234. package/dist/lib/integrations/shared.mjs +1 -1
  235. package/dist/lib/integrations/shared.mjs.map +1 -1
  236. package/dist/lib/logger.cjs +1 -1
  237. package/dist/lib/logger.cjs.map +1 -1
  238. package/dist/lib/logger.d.cts +1 -1
  239. package/dist/lib/logger.d.cts.map +1 -1
  240. package/dist/lib/logger.d.mts +1 -1
  241. package/dist/lib/logger.d.mts.map +1 -1
  242. package/dist/lib/logger.mjs +1 -1
  243. package/dist/lib/logger.mjs.map +1 -1
  244. package/dist/lib/observability.d.cts +1 -1
  245. package/dist/lib/observability.d.cts.map +1 -1
  246. package/dist/lib/observability.d.mts +1 -1
  247. package/dist/lib/observability.d.mts.map +1 -1
  248. package/dist/lib/runtime/agent-integrations/langgraph/agent.cjs +1 -1
  249. package/dist/lib/runtime/agent-integrations/langgraph/agent.cjs.map +1 -1
  250. package/dist/lib/runtime/agent-integrations/langgraph/agent.d.cts +13 -3
  251. package/dist/lib/runtime/agent-integrations/langgraph/agent.d.cts.map +1 -1
  252. package/dist/lib/runtime/agent-integrations/langgraph/agent.d.mts +13 -3
  253. package/dist/lib/runtime/agent-integrations/langgraph/agent.d.mts.map +1 -1
  254. package/dist/lib/runtime/agent-integrations/langgraph/agent.mjs +1 -1
  255. package/dist/lib/runtime/agent-integrations/langgraph/agent.mjs.map +1 -1
  256. package/dist/lib/runtime/agent-integrations/langgraph/consts.cjs +1 -1
  257. package/dist/lib/runtime/agent-integrations/langgraph/consts.cjs.map +1 -1
  258. package/dist/lib/runtime/agent-integrations/langgraph/consts.d.cts +1 -1
  259. package/dist/lib/runtime/agent-integrations/langgraph/consts.d.cts.map +1 -1
  260. package/dist/lib/runtime/agent-integrations/langgraph/consts.d.mts +1 -1
  261. package/dist/lib/runtime/agent-integrations/langgraph/consts.d.mts.map +1 -1
  262. package/dist/lib/runtime/agent-integrations/langgraph/consts.mjs +1 -1
  263. package/dist/lib/runtime/agent-integrations/langgraph/consts.mjs.map +1 -1
  264. package/dist/lib/runtime/copilot-runtime.cjs +9 -1
  265. package/dist/lib/runtime/copilot-runtime.cjs.map +1 -1
  266. package/dist/lib/runtime/copilot-runtime.d.cts +9 -1
  267. package/dist/lib/runtime/copilot-runtime.d.cts.map +1 -1
  268. package/dist/lib/runtime/copilot-runtime.d.mts +9 -1
  269. package/dist/lib/runtime/copilot-runtime.d.mts.map +1 -1
  270. package/dist/lib/runtime/copilot-runtime.mjs +9 -1
  271. package/dist/lib/runtime/copilot-runtime.mjs.map +1 -1
  272. package/dist/lib/runtime/mcp-tools-utils.cjs +1 -1
  273. package/dist/lib/runtime/mcp-tools-utils.cjs.map +1 -1
  274. package/dist/lib/runtime/mcp-tools-utils.d.cts +1 -1
  275. package/dist/lib/runtime/mcp-tools-utils.d.cts.map +1 -1
  276. package/dist/lib/runtime/mcp-tools-utils.d.mts +1 -1
  277. package/dist/lib/runtime/mcp-tools-utils.d.mts.map +1 -1
  278. package/dist/lib/runtime/mcp-tools-utils.mjs +1 -1
  279. package/dist/lib/runtime/mcp-tools-utils.mjs.map +1 -1
  280. package/dist/lib/runtime/telemetry-agent-runner.cjs +1 -1
  281. package/dist/lib/runtime/telemetry-agent-runner.cjs.map +1 -1
  282. package/dist/lib/runtime/telemetry-agent-runner.d.cts +1 -1
  283. package/dist/lib/runtime/telemetry-agent-runner.d.cts.map +1 -1
  284. package/dist/lib/runtime/telemetry-agent-runner.d.mts +1 -1
  285. package/dist/lib/runtime/telemetry-agent-runner.d.mts.map +1 -1
  286. package/dist/lib/runtime/telemetry-agent-runner.mjs +1 -1
  287. package/dist/lib/runtime/telemetry-agent-runner.mjs.map +1 -1
  288. package/dist/lib/runtime/types.cjs +1 -1
  289. package/dist/lib/runtime/types.cjs.map +1 -1
  290. package/dist/lib/runtime/types.d.cts +1 -1
  291. package/dist/lib/runtime/types.d.cts.map +1 -1
  292. package/dist/lib/runtime/types.d.mts +1 -1
  293. package/dist/lib/runtime/types.d.mts.map +1 -1
  294. package/dist/lib/runtime/types.mjs +1 -1
  295. package/dist/lib/runtime/types.mjs.map +1 -1
  296. package/dist/lib/telemetry-client.cjs +1 -1
  297. package/dist/lib/telemetry-client.cjs.map +1 -1
  298. package/dist/lib/telemetry-client.mjs +2 -2
  299. package/dist/lib/telemetry-client.mjs.map +1 -1
  300. package/dist/lib/telemetry-disclosure.cjs +1 -1
  301. package/dist/lib/telemetry-disclosure.cjs.map +1 -1
  302. package/dist/lib/telemetry-disclosure.mjs +1 -1
  303. package/dist/lib/telemetry-disclosure.mjs.map +1 -1
  304. package/dist/package.cjs +5 -5
  305. package/dist/{runtime/package.mjs → package.mjs} +6 -6
  306. package/dist/package.mjs.map +1 -0
  307. package/dist/service-adapters/anthropic/anthropic-adapter.cjs +1 -1
  308. package/dist/service-adapters/anthropic/anthropic-adapter.cjs.map +1 -1
  309. package/dist/service-adapters/anthropic/anthropic-adapter.d.cts +4 -4
  310. package/dist/service-adapters/anthropic/anthropic-adapter.d.cts.map +1 -1
  311. package/dist/service-adapters/anthropic/anthropic-adapter.d.mts +5 -4
  312. package/dist/service-adapters/anthropic/anthropic-adapter.d.mts.map +1 -1
  313. package/dist/service-adapters/anthropic/anthropic-adapter.mjs +1 -1
  314. package/dist/service-adapters/anthropic/anthropic-adapter.mjs.map +1 -1
  315. package/dist/service-adapters/anthropic/utils.cjs +1 -1
  316. package/dist/service-adapters/anthropic/utils.cjs.map +1 -1
  317. package/dist/service-adapters/anthropic/utils.mjs +1 -1
  318. package/dist/service-adapters/anthropic/utils.mjs.map +1 -1
  319. package/dist/service-adapters/bedrock/bedrock-adapter.cjs +1 -1
  320. package/dist/service-adapters/bedrock/bedrock-adapter.cjs.map +1 -1
  321. package/dist/service-adapters/bedrock/bedrock-adapter.d.cts +1 -1
  322. package/dist/service-adapters/bedrock/bedrock-adapter.d.cts.map +1 -1
  323. package/dist/service-adapters/bedrock/bedrock-adapter.d.mts +1 -1
  324. package/dist/service-adapters/bedrock/bedrock-adapter.d.mts.map +1 -1
  325. package/dist/service-adapters/bedrock/bedrock-adapter.mjs +1 -1
  326. package/dist/service-adapters/bedrock/bedrock-adapter.mjs.map +1 -1
  327. package/dist/service-adapters/empty/empty-adapter.cjs +1 -1
  328. package/dist/service-adapters/empty/empty-adapter.cjs.map +1 -1
  329. package/dist/service-adapters/empty/empty-adapter.d.cts +1 -1
  330. package/dist/service-adapters/empty/empty-adapter.d.cts.map +1 -1
  331. package/dist/service-adapters/empty/empty-adapter.d.mts +1 -1
  332. package/dist/service-adapters/empty/empty-adapter.d.mts.map +1 -1
  333. package/dist/service-adapters/empty/empty-adapter.mjs +1 -1
  334. package/dist/service-adapters/empty/empty-adapter.mjs.map +1 -1
  335. package/dist/service-adapters/events.cjs +1 -1
  336. package/dist/service-adapters/events.cjs.map +1 -1
  337. package/dist/service-adapters/events.d.cts +1 -1
  338. package/dist/service-adapters/events.d.cts.map +1 -1
  339. package/dist/service-adapters/events.d.mts +1 -1
  340. package/dist/service-adapters/events.d.mts.map +1 -1
  341. package/dist/service-adapters/events.mjs +1 -1
  342. package/dist/service-adapters/events.mjs.map +1 -1
  343. package/dist/service-adapters/experimental/ollama/ollama-adapter.cjs +1 -1
  344. package/dist/service-adapters/experimental/ollama/ollama-adapter.cjs.map +1 -1
  345. package/dist/service-adapters/experimental/ollama/ollama-adapter.d.cts +1 -1
  346. package/dist/service-adapters/experimental/ollama/ollama-adapter.d.cts.map +1 -1
  347. package/dist/service-adapters/experimental/ollama/ollama-adapter.d.mts +1 -1
  348. package/dist/service-adapters/experimental/ollama/ollama-adapter.d.mts.map +1 -1
  349. package/dist/service-adapters/experimental/ollama/ollama-adapter.mjs +1 -1
  350. package/dist/service-adapters/experimental/ollama/ollama-adapter.mjs.map +1 -1
  351. package/dist/service-adapters/google/google-genai-adapter.cjs +1 -1
  352. package/dist/service-adapters/google/google-genai-adapter.cjs.map +1 -1
  353. package/dist/service-adapters/google/google-genai-adapter.d.cts +1 -1
  354. package/dist/service-adapters/google/google-genai-adapter.d.cts.map +1 -1
  355. package/dist/service-adapters/google/google-genai-adapter.d.mts +1 -1
  356. package/dist/service-adapters/google/google-genai-adapter.d.mts.map +1 -1
  357. package/dist/service-adapters/google/google-genai-adapter.mjs +1 -1
  358. package/dist/service-adapters/google/google-genai-adapter.mjs.map +1 -1
  359. package/dist/service-adapters/groq/groq-adapter.cjs +1 -1
  360. package/dist/service-adapters/groq/groq-adapter.cjs.map +1 -1
  361. package/dist/service-adapters/groq/groq-adapter.d.cts +4 -4
  362. package/dist/service-adapters/groq/groq-adapter.d.cts.map +1 -1
  363. package/dist/service-adapters/groq/groq-adapter.d.mts +5 -4
  364. package/dist/service-adapters/groq/groq-adapter.d.mts.map +1 -1
  365. package/dist/service-adapters/groq/groq-adapter.mjs +1 -1
  366. package/dist/service-adapters/groq/groq-adapter.mjs.map +1 -1
  367. package/dist/service-adapters/index.d.cts +2 -2
  368. package/dist/service-adapters/index.d.mts +3 -3
  369. package/dist/service-adapters/langchain/langchain-adapter.cjs +1 -1
  370. package/dist/service-adapters/langchain/langchain-adapter.cjs.map +1 -1
  371. package/dist/service-adapters/langchain/langchain-adapter.d.cts +1 -1
  372. package/dist/service-adapters/langchain/langchain-adapter.d.cts.map +1 -1
  373. package/dist/service-adapters/langchain/langchain-adapter.d.mts +1 -1
  374. package/dist/service-adapters/langchain/langchain-adapter.d.mts.map +1 -1
  375. package/dist/service-adapters/langchain/langchain-adapter.mjs +1 -1
  376. package/dist/service-adapters/langchain/langchain-adapter.mjs.map +1 -1
  377. package/dist/service-adapters/langchain/langserve.cjs +1 -1
  378. package/dist/service-adapters/langchain/langserve.cjs.map +1 -1
  379. package/dist/service-adapters/langchain/langserve.d.cts +1 -1
  380. package/dist/service-adapters/langchain/langserve.d.cts.map +1 -1
  381. package/dist/service-adapters/langchain/langserve.d.mts +1 -1
  382. package/dist/service-adapters/langchain/langserve.d.mts.map +1 -1
  383. package/dist/service-adapters/langchain/langserve.mjs +1 -1
  384. package/dist/service-adapters/langchain/langserve.mjs.map +1 -1
  385. package/dist/service-adapters/langchain/types.d.cts +1 -1
  386. package/dist/service-adapters/langchain/types.d.cts.map +1 -1
  387. package/dist/service-adapters/langchain/types.d.mts +1 -1
  388. package/dist/service-adapters/langchain/types.d.mts.map +1 -1
  389. package/dist/service-adapters/langchain/utils.cjs +1 -1
  390. package/dist/service-adapters/langchain/utils.cjs.map +1 -1
  391. package/dist/service-adapters/langchain/utils.mjs +1 -1
  392. package/dist/service-adapters/langchain/utils.mjs.map +1 -1
  393. package/dist/service-adapters/openai/openai-adapter.cjs +1 -1
  394. package/dist/service-adapters/openai/openai-adapter.cjs.map +1 -1
  395. package/dist/service-adapters/openai/openai-adapter.d.cts +1 -1
  396. package/dist/service-adapters/openai/openai-adapter.d.cts.map +1 -1
  397. package/dist/service-adapters/openai/openai-adapter.d.mts +1 -1
  398. package/dist/service-adapters/openai/openai-adapter.d.mts.map +1 -1
  399. package/dist/service-adapters/openai/openai-adapter.mjs +1 -1
  400. package/dist/service-adapters/openai/openai-adapter.mjs.map +1 -1
  401. package/dist/service-adapters/openai/openai-assistant-adapter.cjs +1 -1
  402. package/dist/service-adapters/openai/openai-assistant-adapter.cjs.map +1 -1
  403. package/dist/service-adapters/openai/openai-assistant-adapter.d.cts +1 -1
  404. package/dist/service-adapters/openai/openai-assistant-adapter.d.cts.map +1 -1
  405. package/dist/service-adapters/openai/openai-assistant-adapter.d.mts +1 -1
  406. package/dist/service-adapters/openai/openai-assistant-adapter.d.mts.map +1 -1
  407. package/dist/service-adapters/openai/openai-assistant-adapter.mjs +1 -1
  408. package/dist/service-adapters/openai/openai-assistant-adapter.mjs.map +1 -1
  409. package/dist/service-adapters/openai/utils.cjs +1 -1
  410. package/dist/service-adapters/openai/utils.cjs.map +1 -1
  411. package/dist/service-adapters/openai/utils.mjs +1 -1
  412. package/dist/service-adapters/openai/utils.mjs.map +1 -1
  413. package/dist/service-adapters/service-adapter.d.cts +1 -1
  414. package/dist/service-adapters/service-adapter.d.cts.map +1 -1
  415. package/dist/service-adapters/service-adapter.d.mts +1 -1
  416. package/dist/service-adapters/service-adapter.d.mts.map +1 -1
  417. package/dist/service-adapters/shared/error-utils.cjs +1 -1
  418. package/dist/service-adapters/shared/error-utils.cjs.map +1 -1
  419. package/dist/service-adapters/shared/error-utils.d.cts +1 -1
  420. package/dist/service-adapters/shared/error-utils.d.cts.map +1 -1
  421. package/dist/service-adapters/shared/error-utils.d.mts +1 -1
  422. package/dist/service-adapters/shared/error-utils.d.mts.map +1 -1
  423. package/dist/service-adapters/shared/error-utils.mjs +1 -1
  424. package/dist/service-adapters/shared/error-utils.mjs.map +1 -1
  425. package/dist/service-adapters/shared/index.d.mts +1 -1
  426. package/dist/service-adapters/shared/sdk-client-utils.cjs +1 -1
  427. package/dist/service-adapters/shared/sdk-client-utils.cjs.map +1 -1
  428. package/dist/service-adapters/shared/sdk-client-utils.d.cts +21 -2
  429. package/dist/service-adapters/shared/sdk-client-utils.d.cts.map +1 -1
  430. package/dist/service-adapters/shared/sdk-client-utils.d.mts +21 -2
  431. package/dist/service-adapters/shared/sdk-client-utils.d.mts.map +1 -1
  432. package/dist/service-adapters/shared/sdk-client-utils.mjs +1 -1
  433. package/dist/service-adapters/shared/sdk-client-utils.mjs.map +1 -1
  434. package/dist/service-adapters/unify/unify-adapter.cjs +1 -1
  435. package/dist/service-adapters/unify/unify-adapter.cjs.map +1 -1
  436. package/dist/service-adapters/unify/unify-adapter.d.cts +1 -1
  437. package/dist/service-adapters/unify/unify-adapter.d.cts.map +1 -1
  438. package/dist/service-adapters/unify/unify-adapter.d.mts +1 -1
  439. package/dist/service-adapters/unify/unify-adapter.d.mts.map +1 -1
  440. package/dist/service-adapters/unify/unify-adapter.mjs +1 -1
  441. package/dist/service-adapters/unify/unify-adapter.mjs.map +1 -1
  442. package/dist/utils/failed-response-status-reasons.cjs +1 -1
  443. package/dist/utils/failed-response-status-reasons.cjs.map +1 -1
  444. package/dist/utils/failed-response-status-reasons.d.cts +1 -1
  445. package/dist/utils/failed-response-status-reasons.d.cts.map +1 -1
  446. package/dist/utils/failed-response-status-reasons.d.mts +1 -1
  447. package/dist/utils/failed-response-status-reasons.d.mts.map +1 -1
  448. package/dist/utils/failed-response-status-reasons.mjs +1 -1
  449. package/dist/utils/failed-response-status-reasons.mjs.map +1 -1
  450. package/dist/v2/runtime/core/channel-activation-config.cjs.map +1 -1
  451. package/dist/v2/runtime/core/channel-activation-config.d.cts +2 -2
  452. package/dist/v2/runtime/core/channel-activation-config.d.cts.map +1 -1
  453. package/dist/v2/runtime/core/channel-activation-config.d.mts +2 -2
  454. package/dist/v2/runtime/core/channel-activation-config.d.mts.map +1 -1
  455. package/dist/v2/runtime/core/channel-activation-config.mjs.map +1 -1
  456. package/dist/v2/runtime/core/channel-manager.cjs.map +1 -1
  457. package/dist/v2/runtime/core/channel-manager.d.cts +2 -2
  458. package/dist/v2/runtime/core/channel-manager.d.cts.map +1 -1
  459. package/dist/v2/runtime/core/channel-manager.d.mts +2 -2
  460. package/dist/v2/runtime/core/channel-manager.d.mts.map +1 -1
  461. package/dist/v2/runtime/core/channel-manager.mjs.map +1 -1
  462. package/dist/v2/runtime/core/runtime.cjs +1 -0
  463. package/dist/v2/runtime/core/runtime.cjs.map +1 -1
  464. package/dist/v2/runtime/core/runtime.d.cts.map +1 -1
  465. package/dist/v2/runtime/core/runtime.d.mts.map +1 -1
  466. package/dist/v2/runtime/core/runtime.mjs +2 -1
  467. package/dist/v2/runtime/core/runtime.mjs.map +1 -1
  468. package/dist/v2/runtime/handlers/intelligence/memories.cjs +1 -1
  469. package/dist/v2/runtime/handlers/intelligence/memories.cjs.map +1 -1
  470. package/dist/v2/runtime/handlers/intelligence/memories.mjs +1 -1
  471. package/dist/v2/runtime/handlers/intelligence/memories.mjs.map +1 -1
  472. package/dist/v2/runtime/handlers/intelligence/threads.cjs +1 -1
  473. package/dist/v2/runtime/handlers/intelligence/threads.cjs.map +1 -1
  474. package/dist/v2/runtime/handlers/intelligence/threads.mjs +1 -1
  475. package/dist/v2/runtime/handlers/intelligence/threads.mjs.map +1 -1
  476. package/dist/v2/runtime/handlers/shared/agent-utils.cjs +1 -1
  477. package/dist/v2/runtime/handlers/shared/agent-utils.cjs.map +1 -1
  478. package/dist/v2/runtime/handlers/shared/agent-utils.mjs +1 -1
  479. package/dist/v2/runtime/handlers/shared/agent-utils.mjs.map +1 -1
  480. package/dist/v2/runtime/handlers/shared/sse-response.cjs.map +1 -1
  481. package/dist/v2/runtime/handlers/shared/sse-response.mjs.map +1 -1
  482. package/dist/v2/runtime/handlers/sse/run.cjs.map +1 -1
  483. package/dist/v2/runtime/handlers/sse/run.mjs.map +1 -1
  484. package/dist/v2/runtime/intelligence-platform/client.cjs +6 -6
  485. package/dist/v2/runtime/intelligence-platform/client.cjs.map +1 -1
  486. package/dist/v2/runtime/intelligence-platform/client.d.cts +8 -8
  487. package/dist/v2/runtime/intelligence-platform/client.d.mts +8 -8
  488. package/dist/v2/runtime/intelligence-platform/client.mjs +6 -6
  489. package/dist/v2/runtime/intelligence-platform/client.mjs.map +1 -1
  490. package/dist/v2/runtime/runner/in-memory.cjs +3 -3
  491. package/dist/v2/runtime/runner/in-memory.cjs.map +1 -1
  492. package/dist/v2/runtime/runner/in-memory.d.cts +4 -4
  493. package/dist/v2/runtime/runner/in-memory.d.mts +4 -4
  494. package/dist/v2/runtime/runner/in-memory.mjs +3 -3
  495. package/dist/v2/runtime/runner/in-memory.mjs.map +1 -1
  496. package/dist/v2/runtime/telemetry/telemetry-client.mjs +1 -1
  497. package/package.json +6 -6
  498. package/skills/runtime/SKILL.md +1 -1
  499. package/skills/runtime/references/agent-runners-custom.md +1 -1
  500. package/skills/runtime/references/agent-runners.md +11 -5
  501. package/skills/runtime/references/intelligence-mode.md +1 -1
  502. package/dist/channels/dist/index.d.cts +0 -10
  503. package/dist/channels/dist/index.d.cts.map +0 -1
  504. package/dist/channels/dist/index.d.mts +0 -10
  505. package/dist/channels/dist/index.d.mts.map +0 -1
  506. package/dist/runtime/package.mjs.map +0 -1
@@ -106,7 +106,7 @@ interface HistoricRun {
106
106
  }
107
107
  /**
108
108
  * Lightweight thread summary returned by {@link InMemoryAgentRunner.listThreads}.
109
- * Shape matches the Intelligence platform's ThreadRecord so the same HTTP
109
+ * Shape matches CopilotKit Intelligence's ThreadRecord so the same HTTP
110
110
  * response envelope can be used for both backends.
111
111
  */
112
112
  interface InMemoryThread {
@@ -290,16 +290,16 @@ declare class InMemoryAgentRunner extends AgentRunner {
290
290
  * of the most recent run.
291
291
  *
292
292
  * This powers the local-dev fallback for `GET /threads/:threadId/messages`
293
- * when the Intelligence platform is not configured. The returned `Message[]`
293
+ * when CopilotKit Intelligence is not configured. The returned `Message[]`
294
294
  * objects come directly from the ag-ui agent, so their shape is compatible
295
- * with the Intelligence platform's `ThreadMessage` type.
295
+ * with CopilotKit Intelligence's `ThreadMessage` type.
296
296
  */
297
297
  getThreadMessages(threadId: string): Message[];
298
298
  /**
299
299
  * Returns all AG-UI events for a thread, compacted across historic runs.
300
300
  *
301
301
  * Powers the local-dev fallback for `GET /threads/:threadId/events` when the
302
- * Intelligence platform is not configured. The compaction logic matches
302
+ * CopilotKit Intelligence is not configured. The compaction logic matches
303
303
  * the connection-replay path in {@link connect}, so the stream a
304
304
  * late-joining inspector sees matches what this method returns.
305
305
  */
@@ -106,7 +106,7 @@ interface HistoricRun {
106
106
  }
107
107
  /**
108
108
  * Lightweight thread summary returned by {@link InMemoryAgentRunner.listThreads}.
109
- * Shape matches the Intelligence platform's ThreadRecord so the same HTTP
109
+ * Shape matches CopilotKit Intelligence's ThreadRecord so the same HTTP
110
110
  * response envelope can be used for both backends.
111
111
  */
112
112
  interface InMemoryThread {
@@ -290,16 +290,16 @@ declare class InMemoryAgentRunner extends AgentRunner {
290
290
  * of the most recent run.
291
291
  *
292
292
  * This powers the local-dev fallback for `GET /threads/:threadId/messages`
293
- * when the Intelligence platform is not configured. The returned `Message[]`
293
+ * when CopilotKit Intelligence is not configured. The returned `Message[]`
294
294
  * objects come directly from the ag-ui agent, so their shape is compatible
295
- * with the Intelligence platform's `ThreadMessage` type.
295
+ * with CopilotKit Intelligence's `ThreadMessage` type.
296
296
  */
297
297
  getThreadMessages(threadId: string): Message[];
298
298
  /**
299
299
  * Returns all AG-UI events for a thread, compacted across historic runs.
300
300
  *
301
301
  * Powers the local-dev fallback for `GET /threads/:threadId/events` when the
302
- * Intelligence platform is not configured. The compaction logic matches
302
+ * CopilotKit Intelligence is not configured. The compaction logic matches
303
303
  * the connection-replay path in {@link connect}, so the stream a
304
304
  * late-joining inspector sees matches what this method returns.
305
305
  */
@@ -476,9 +476,9 @@ var InMemoryAgentRunner = class extends AgentRunner {
476
476
  * of the most recent run.
477
477
  *
478
478
  * This powers the local-dev fallback for `GET /threads/:threadId/messages`
479
- * when the Intelligence platform is not configured. The returned `Message[]`
479
+ * when CopilotKit Intelligence is not configured. The returned `Message[]`
480
480
  * objects come directly from the ag-ui agent, so their shape is compatible
481
- * with the Intelligence platform's `ThreadMessage` type.
481
+ * with CopilotKit Intelligence's `ThreadMessage` type.
482
482
  */
483
483
  getThreadMessages(threadId) {
484
484
  const store = sharedStore.peek(threadId);
@@ -489,7 +489,7 @@ var InMemoryAgentRunner = class extends AgentRunner {
489
489
  * Returns all AG-UI events for a thread, compacted across historic runs.
490
490
  *
491
491
  * Powers the local-dev fallback for `GET /threads/:threadId/events` when the
492
- * Intelligence platform is not configured. The compaction logic matches
492
+ * CopilotKit Intelligence is not configured. The compaction logic matches
493
493
  * the connection-replay path in {@link connect}, so the stream a
494
494
  * late-joining inspector sees matches what this method returns.
495
495
  */
@@ -1 +1 @@
1
- {"version":3,"file":"in-memory.mjs","names":[],"sources":["../../../../src/v2/runtime/runner/in-memory.ts"],"sourcesContent":["import type {\n AgentRunnerConnectRequest,\n AgentRunnerIsRunningRequest,\n AgentRunnerRunRequest,\n} from \"./agent-runner\";\nimport { AgentRunner } from \"./agent-runner\";\nimport type { AgentRunnerStopRequest } from \"./agent-runner\";\nimport type { Observable } from \"rxjs\";\nimport { ReplaySubject } from \"rxjs\";\nimport type {\n AbstractAgent,\n BaseEvent,\n Message,\n RunStartedEvent,\n StateSnapshotEvent,\n} from \"@ag-ui/client\";\nimport { EventType, compactEvents } from \"@ag-ui/client\";\nimport { finalizeRunEvents } from \"@copilotkit/shared\";\n\nexport interface InMemoryLimits {\n /** LRU cap on distinct threads. */\n maxThreads?: number;\n /** FIFO cap on runs kept per thread. `Infinity` or `0` disables the cap. */\n maxRunsPerThread?: number;\n /**\n * Approximate byte ceiling on RETAINED thread/run history. Enforced at run\n * completion (in `appendRun`), where LRU non-running threads are evicted to\n * keep the total under this limit.\n *\n * Limitation: this bounds only history that has already been committed. A\n * single in-flight run's buffered events (`currentRunEvents` and the two\n * `ReplaySubject<BaseEvent>(Infinity)` buffers in `run()`) are NOT counted\n * until that run completes, so `maxBytes` does not bound a single runaway\n * run mid-stream.\n *\n * Limitation: byte eviction drops only other LRU non-running threads and\n * never self-evicts the active/just-appended thread, so a single dominant\n * thread's own retained history is not byte-trimmed (bounded only by\n * `maxRunsPerThread`). `maxBytes` is thus a cross-thread ceiling enforced by\n * evicting OTHER threads, not a per-thread cap.\n */\n maxBytes?: number;\n}\n\n/**\n * Constructor options for {@link InMemoryAgentRunner}.\n *\n * Extends {@link InMemoryLimits} so bounds can be passed inline alongside the\n * per-runner behavior flags. Be aware of the scope difference: the limits\n * reconfigure the process-global store shared by every runner, whereas\n * `onConcurrentRun` applies only to the runner instance it is passed to.\n */\nexport interface InMemoryAgentRunnerOptions extends InMemoryLimits {\n /**\n * How to handle a `run()` for a thread that already has an in-flight run.\n * `\"throw\"` (default) rejects with \"Thread already running\". `\"supersede\"`\n * aborts the prior run and starts the new one.\n */\n onConcurrentRun?: \"throw\" | \"supersede\";\n}\n\nexport const ɵINMEMORY_DEFAULTS: Required<InMemoryLimits> = {\n maxThreads: 1000,\n maxRunsPerThread: 100,\n maxBytes: 512 * 1024 ** 2,\n};\n\n/**\n * A limit value is well-formed iff it is a non-negative integer OR `+Infinity`.\n * `+Infinity` is the documented \"disabled/unbounded\" sentinel and `0` is the\n * documented run-cap disable sentinel; both are non-negative and pass. Every\n * enforcement site (`evictThreadsIfNeeded`, `enforceRunCap`,\n * `evictByBytesIfNeeded`) compares its counter against the limit with `>` in a\n * `while`/`if` guard, so only these shapes keep those loops finite and correct.\n * Rejected: negatives (drive `count > -1` true on an empty collection, so\n * `enforceRunCap` `shift()!`s `undefined` and throws), `-Infinity` (loops never\n * terminate their intent — always \"over\"), `NaN` (every `>` is false, silently\n * disabling the bound), and non-integer finites (fractional caps are nonsense).\n */\nfunction ɵisValidLimit(value: number): boolean {\n return value === Infinity || (Number.isInteger(value) && value >= 0);\n}\n\n/**\n * Normalize a fully-resolved limits bag so every field is well-formed before it\n * can reach an enforcement loop. Each field is validated independently against\n * {@link ɵisValidLimit}; an invalid value is CLAMPED to its\n * {@link ɵINMEMORY_DEFAULTS} floor and a single `console.warn` naming the field\n * and the received value is emitted.\n *\n * Clamp-and-warn (rather than throw) is deliberate and matches this file's\n * established posture toward bad input: `ɵestimateBytes` swallows serialization\n * failures and returns 0, the limits-clobber path warns rather than throwing,\n * and both the eviction and clobber logs are wrapped so \"logging must never\n * break construction/a run\". Constructing a bounded in-memory runner is a\n * best-effort, non-durable convenience; a typo'd bound must degrade to a safe\n * default, never abort construction or (worse) surface later as an unhandled\n * rejection from the fire-and-forget finalize path.\n */\nexport function ɵnormalizeLimits(\n limits: Required<InMemoryLimits>,\n): Required<InMemoryLimits> {\n const normalized = { ...limits };\n for (const field of Object.keys(\n ɵINMEMORY_DEFAULTS,\n ) as (keyof InMemoryLimits)[]) {\n const value = limits[field];\n if (!ɵisValidLimit(value)) {\n const fallback = ɵINMEMORY_DEFAULTS[field];\n normalized[field] = fallback;\n try {\n console.warn(\n `[CopilotKit] InMemoryAgentRunner: invalid ${field} value ` +\n `${String(value)} (expected a non-negative integer or Infinity); ` +\n `falling back to ${String(fallback)}.`,\n );\n } catch {\n // best-effort: logging must never break construction\n }\n }\n }\n return normalized;\n}\n\nconst EVICTION_GUIDANCE =\n \"[CopilotKit] InMemoryAgentRunner evicted in-memory thread history to stay \" +\n \"under memory limits. This runner is bounded and non-durable by design. For \" +\n \"durable or production threads, configure an Intelligence backend.\";\n\nconst LIMITS_CLOBBER_GUIDANCE =\n \"[CopilotKit] InMemoryAgentRunner was constructed with in-memory limits that \" +\n \"differ from the already-configured process-global store; the last-constructed \" +\n \"runner's limits apply to ALL in-memory threads (the store is shared per-process). \" +\n \"Configure a single consistent set of limits, or use an Intelligence backend for \" +\n \"isolated bounds.\";\n\n/**\n * Best-effort approximate byte size of a value, via serialized length.\n * Never throws — returns 0 when the value cannot be serialized. This is an\n * approximation (UTF-16 length, not exact heap bytes), used only for relative\n * accounting against `maxBytes`.\n */\nexport function ɵestimateBytes(value: unknown): number {\n try {\n return JSON.stringify(value)?.length ?? 0;\n } catch {\n return 0;\n }\n}\n\n/**\n * Per-run finalize intent, captured once when a run starts and mutated (only)\n * by whoever aborts THAT run — `stop()` or a superseding `run()`. The run's own\n * teardown reads this captured holder instead of the shared, mutable\n * `store.stopRequested`, so a later run that resets store state can never cause\n * an intentionally-stopped run to be finalized as an error (or vice versa).\n */\ninterface RunFinalizeControl {\n /** True once THIS run has been asked to stop (clean stop, not an error). */\n stopRequested: boolean;\n}\n\ninterface HistoricRun {\n threadId: string;\n runId: string;\n /** ID of the agent that executed this run. */\n agentId: string;\n parentRunId: string | null;\n events: BaseEvent[];\n /**\n * Snapshot of all messages (input + generated) at the end of this run, as\n * passed in by the caller. NOTE: `BoundedThreadStore.appendRun` moves this\n * snapshot to the THREAD level (`InMemoryEventStore.messagesSnapshot`) and\n * clears this field to `[]`, so a stored HistoricRun never carries messages.\n * The thread-messages fallback reads the thread-level snapshot, not this.\n */\n messages: Message[];\n createdAt: number;\n /** Approximate retained byte size of `events`; set by BoundedThreadStore at append. */\n approxEventBytes?: number;\n /**\n * Legacy field retained for shape compatibility. `appendRun` always zeroes it\n * because message bytes are accounted at the thread level, not per run.\n */\n approxMessageBytes?: number;\n}\n\n/**\n * Lightweight thread summary returned by {@link InMemoryAgentRunner.listThreads}.\n * Shape matches the Intelligence platform's ThreadRecord so the same HTTP\n * response envelope can be used for both backends.\n */\nexport interface InMemoryThread {\n id: string;\n name: string | null;\n agentId: string;\n organizationId: \"\"; // always empty in in-memory mode\n createdById: \"\"; // always empty in in-memory mode\n archived: false; // always false in in-memory mode\n createdAt: string;\n updatedAt: string;\n}\n\nclass InMemoryEventStore {\n constructor(public threadId: string) {}\n\n /** The subject that current consumers subscribe to. */\n subject: ReplaySubject<BaseEvent> | null = null;\n\n /** True while a run is actively producing events. */\n isRunning = false;\n\n /** Current run ID */\n currentRunId: string | null = null;\n\n /** Historic completed runs */\n historicRuns: HistoricRun[] = [];\n\n /** Currently running agent instance (if any). */\n agent: AbstractAgent | null = null;\n\n /** Subject returned from run() while the run is active. */\n runSubject: ReplaySubject<BaseEvent> | null = null;\n\n /**\n * Thread-level lifecycle flag: true once a stop/supersede has been requested\n * for the currently-owning run but that run has not yet finalized. Drives\n * eviction protection, the connect() bridge, and stop() de-dup. This is NOT\n * the finalize intent read by a run's teardown — that lives per-run on\n * {@link activeFinalize}, so a superseding run resetting this field cannot\n * mislabel the run it replaced. A new run resets this to false when it takes\n * ownership.\n */\n stopRequested = false;\n\n /**\n * Finalize control of the currently-owning run. `stop()` and a superseding\n * `run()` flip the owning run's flag through this reference; each run also\n * captures the SAME object in its closure, so its teardown finalizes against\n * its own intent regardless of what a later run does to the store.\n */\n activeFinalize: RunFinalizeControl | null = null;\n\n /** Reference to the events emitted in the current run. */\n currentEvents: BaseEvent[] | null = null;\n\n /**\n * The thread's single latest NON-EMPTY message snapshot, held at the THREAD\n * level (independent of `historicRuns` lifecycle). Decoupling the snapshot\n * from per-run storage means run-cap FIFO eviction and interleaved\n * empty-snapshot runs can never drop or pin the thread's message history.\n */\n messagesSnapshot: Message[] = [];\n\n /** Approximate retained byte size of `messagesSnapshot`. */\n approxMessagesSnapshotBytes = 0;\n\n /**\n * The thread's true creation timestamp (epoch ms), captured from the FIRST\n * run ever appended and held at the THREAD level (independent of\n * `historicRuns` lifecycle). Decoupling it from per-run storage means run-cap\n * FIFO eviction — which shifts the oldest entries off `historicRuns` — can\n * never move the reported creation time forward. `null` until the first run\n * lands. Mirrors the `messagesSnapshot` thread-level decoupling.\n */\n createdAt: number | null = null;\n}\n\nexport class ɵBoundedThreadStore {\n private readonly map = new Map<string, InMemoryEventStore>();\n private totalBytes = 0;\n private warned = false;\n /** True once limits have been EXPLICITLY set (via setLimits), not just the constructor default. */\n private limitsExplicitlySet = false;\n /** Warn-once latch for the clobber warning, kept distinct from the eviction `warned` latch. */\n private clobberWarned = false;\n\n private limits: Required<InMemoryLimits>;\n\n constructor(limits: Required<InMemoryLimits>) {\n // Normalize once at construction so `this.limits` is ALWAYS well-formed,\n // regardless of entry point (direct construction or a later `setLimits`).\n this.limits = ɵnormalizeLimits(limits);\n }\n\n get byteTotal(): number {\n return this.totalBytes;\n }\n\n /**\n * The store's CURRENT effective bounds. Exposed (with the `ɵ` internal-API\n * prefix) so a partial `setLimits` can coalesce unspecified fields against the\n * live config rather than the hardcoded {@link ɵINMEMORY_DEFAULTS} — a partial\n * update must be a partial update, never a silent reset of the fields the\n * caller did not mention. Returns a copy so callers cannot mutate the store's\n * bounds through it.\n */\n get ɵlimits(): Required<InMemoryLimits> {\n return { ...this.limits };\n }\n\n /**\n * Reconfigure the process-global store's bounds. Called by the\n * {@link InMemoryAgentRunner} constructor when limits are passed. Because the\n * store is a per-process singleton, this replaces the bounds for ALL in-memory\n * threads. Emits {@link LIMITS_CLOBBER_GUIDANCE} at most ONCE per store when a\n * SECOND (or later) explicit set arrives whose resolved values differ from the\n * prior explicit set — i.e. a genuine clobber of an already-customized config.\n * The first explicit customization (defaults → custom) is the intended\n * override and never warns; identical re-sets never warn.\n */\n setLimits(limits: Required<InMemoryLimits>): void {\n // Normalize FIRST so invalid fields can never reach an enforcement loop and\n // so the clobber comparison below is against the EFFECTIVE (clamped) values,\n // not the raw ones — a typo'd bound that clamps to the current default is not\n // a genuine clobber and must not warn.\n const normalized = ɵnormalizeLimits(limits);\n if (\n this.limitsExplicitlySet &&\n !this.clobberWarned &&\n (normalized.maxThreads !== this.limits.maxThreads ||\n normalized.maxRunsPerThread !== this.limits.maxRunsPerThread ||\n normalized.maxBytes !== this.limits.maxBytes)\n ) {\n this.clobberWarned = true;\n try {\n console.warn(LIMITS_CLOBBER_GUIDANCE);\n } catch {\n // best-effort: logging must never break construction\n }\n }\n this.limitsExplicitlySet = true;\n this.limits = normalized;\n }\n\n get size(): number {\n return this.map.size;\n }\n\n /** Re-insert at the tail so Map iteration order stays LRU-first. */\n private touchOrder(threadId: string, store: InMemoryEventStore): void {\n this.map.delete(threadId);\n this.map.set(threadId, store);\n }\n\n getOrCreate(threadId: string): InMemoryEventStore {\n const existing = this.map.get(threadId);\n if (existing) {\n this.touchOrder(threadId, existing);\n return existing;\n }\n const store = new InMemoryEventStore(threadId);\n this.map.set(threadId, store);\n this.evictThreadsIfNeeded(threadId);\n return store;\n }\n\n get(\n threadId: string,\n opts: { touch: boolean },\n ): InMemoryEventStore | undefined {\n const store = this.map.get(threadId);\n if (store && opts.touch) this.touchOrder(threadId, store);\n return store;\n }\n\n peek(threadId: string): InMemoryEventStore | undefined {\n return this.map.get(threadId);\n }\n\n /**\n * Evict the least-recently-used thread that is neither running NOR\n * mid-finalization. Returns false if none evictable. The `protect` thread\n * (typically the one just created) is never evicted, so a fresh thread is not\n * immediately dropped when it is the only non-running candidate.\n *\n * A thread is skipped while `isRunning` OR `stopRequested` is set.\n * `stop()` flips `isRunning` to false the moment it aborts the agent, but the\n * run keeps finalizing asynchronously (the abort trips the `catch` in\n * `runAgent`, which later calls `appendRun`). During that window\n * `stopRequested` stays true; evicting the thread then would make the pending\n * `appendRun` hit `if (!store) return` and silently drop the aborted run's\n * history. Guarding on `stopRequested` keeps the thread alive until\n * finalization completes.\n */\n private evictOneLru(protect?: string): boolean {\n for (const [threadId, store] of this.map) {\n if (threadId === protect) continue; // never evict the just-created thread\n // never evict a running or still-finalizing (stop-requested) thread\n if (store.isRunning || store.stopRequested) continue;\n this.removeThread(threadId, store);\n this.noteEviction();\n return true;\n }\n return false;\n }\n\n appendRun(threadId: string, run: HistoricRun): void {\n const store = this.map.get(threadId);\n if (!store) return; // best-effort: nothing to append to\n\n // Thread-level creation timestamp: capture the FIRST run's createdAt once\n // and never overwrite it. Held on the store (not derived from\n // `historicRuns[0]`) so run-cap FIFO eviction of the oldest runs cannot\n // drift the thread's reported creation time forward. Mirrors the\n // thread-level `messagesSnapshot` decoupling below.\n if (store.createdAt === null) {\n store.createdAt = run.createdAt;\n }\n\n // Thread-level message snapshot: keep the single latest NON-EMPTY snapshot\n // on the store, decoupled from `historicRuns`. When the incoming run\n // carries a non-empty snapshot, replace the thread's snapshot (adjusting\n // byte accounting). When it's empty (non-array `agent.messages` or an\n // error-path run), leave the existing thread snapshot untouched so history\n // is never lost. The snapshot never lives on a HistoricRun, so run-cap FIFO\n // eviction can never drop it and an interleaved empty run can never pin it.\n if (run.messages.length > 0) {\n this.totalBytes -= store.approxMessagesSnapshotBytes;\n // Store the incoming array directly (SHALLOW, array-level copy). `run.messages`\n // is already a fresh `[...agent.messages]` array created in run(), so we own the\n // array and it is decoupled from `agent.messages` at the array level (push/splice\n // on the agent's array cannot mutate our snapshot). We deliberately do NOT deep-copy\n // here: `structuredClone` throws DataCloneError on a non-cloneable message field,\n // which would wedge the thread and hang SSE — inconsistent with `ɵestimateBytes`,\n // which tolerates the same bad-payload class. The tradeoff is that the inner\n // `Message` objects remain shared by reference with `agent.messages`, so an agent\n // that mutates its own message objects IN PLACE after the run can still be observed\n // through this snapshot. That inner-object isolation is a known limitation tracked as\n // follow-up; callers must treat returned messages as read-only. Estimate bytes on the\n // same value so accounting matches exactly what is retained.\n store.messagesSnapshot = run.messages;\n store.approxMessagesSnapshotBytes = ɵestimateBytes(run.messages);\n this.totalBytes += store.approxMessagesSnapshotBytes;\n }\n\n // Do not carry message bytes on the HistoricRun: the snapshot is now tracked\n // at the thread level, so historicRuns must never account message bytes.\n run.messages = [];\n run.approxMessageBytes = 0;\n\n // Compute this run's approximate event size once, at append time.\n run.approxEventBytes = ɵestimateBytes(run.events);\n store.historicRuns.push(run);\n this.totalBytes += run.approxEventBytes;\n this.touchOrder(threadId, store);\n\n this.enforceRunCap(store);\n this.evictByBytesIfNeeded(threadId);\n }\n\n private enforceRunCap(store: InMemoryEventStore): void {\n const cap = this.limits.maxRunsPerThread;\n if (!cap || cap === Infinity) return; // 0 or Infinity → disabled\n while (store.historicRuns.length > cap) {\n const dropped = store.historicRuns.shift()!;\n // Only event bytes live on a HistoricRun; the message snapshot is tracked\n // at the thread level and survives run-cap eviction.\n this.totalBytes -= dropped.approxEventBytes ?? 0;\n // Per-thread run-cap trimming is also eviction — history is being dropped.\n // Route it through the SAME warn-once latch as whole-thread LRU eviction so\n // this shows up in logs rather than as silent data loss. `noteEviction` is\n // latched (one warning per store, reset by `clear()`), so a hot thread that\n // trims on every subsequent append warns once, never per dropped run. The\n // loop only runs when a run is ACTUALLY over the cap, so a disabled or\n // under-cap `enforceRunCap` stays silent (it returned / never entered here).\n this.noteEviction();\n }\n }\n\n /**\n * Trim the store back under the byte ceiling by evicting LRU non-running\n * threads. `protect` (the just-appended thread) is never self-evicted, so a\n * fresh run pushes OTHER threads out rather than dropping itself.\n */\n private evictByBytesIfNeeded(protect?: string): void {\n while (this.totalBytes > this.limits.maxBytes) {\n if (!this.evictOneLru(protect)) break; // only protected/running threads left → accept overage\n }\n }\n\n private removeThread(threadId: string, store: InMemoryEventStore): void {\n for (const run of store.historicRuns) {\n this.totalBytes -= run.approxEventBytes ?? 0;\n }\n // The thread's message snapshot is tracked at the store level, so it must\n // be reclaimed here in addition to the per-run event bytes.\n this.totalBytes -= store.approxMessagesSnapshotBytes;\n this.map.delete(threadId);\n }\n\n private evictThreadsIfNeeded(protect?: string): void {\n while (this.map.size > this.limits.maxThreads) {\n if (!this.evictOneLru(protect)) break; // everything evictable is running → accept overage\n }\n }\n\n private noteEviction(): void {\n if (this.warned) return;\n this.warned = true;\n try {\n console.warn(EVICTION_GUIDANCE);\n } catch {\n // best-effort: logging must never break a run\n }\n }\n\n listThreads(): InMemoryThread[] {\n const threads: InMemoryThread[] = [];\n for (const [threadId, store] of this.map) {\n if (store.historicRuns.length === 0) continue;\n const lastRun = store.historicRuns[store.historicRuns.length - 1]!;\n // Creation time comes from the thread-level `store.createdAt` (the first\n // run ever appended), NOT `historicRuns[0]` (the oldest RETAINED run):\n // run-cap FIFO eviction drops the oldest retained runs, so deriving it\n // from `historicRuns[0]` would silently drift the timestamp forward over\n // a thread's lifetime. `updatedAt` stays on `lastRun` because FIFO\n // eviction removes from the FRONT, so the newest run is never evicted.\n // The `?? lastRun.createdAt` fallback is defensive only: any thread with\n // runs has had `store.createdAt` set by `appendRun`.\n threads.push({\n id: threadId,\n name: null,\n agentId: lastRun.agentId,\n organizationId: \"\",\n createdById: \"\",\n archived: false,\n createdAt: new Date(store.createdAt ?? lastRun.createdAt).toISOString(),\n updatedAt: new Date(lastRun.createdAt).toISOString(),\n });\n }\n return threads.sort(\n (a, b) =>\n new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime(),\n );\n }\n\n clear(): void {\n this.map.clear();\n this.totalBytes = 0;\n this.warned = false;\n }\n}\n\n/**\n * Process-wide singleton backing every {@link InMemoryAgentRunner}. Exported\n * (with the `ɵ` internal-API prefix) so tests can inspect the exact store the\n * runner writes to; not part of the public API.\n */\nexport const ɵGLOBAL_STORE = new ɵBoundedThreadStore(ɵINMEMORY_DEFAULTS);\nconst sharedStore = ɵGLOBAL_STORE;\n\nexport class InMemoryAgentRunner extends AgentRunner {\n readonly ɵsupportsLocalThreadEndpoints = true;\n\n /**\n * How to handle a `run()` for a thread that already has an in-flight run.\n * `\"throw\"` (default) preserves the historic behavior. `\"supersede\"` aborts\n * the prior run (mirroring `stop()`) and starts the new one — opted into by\n * the hosted-bot listener so a fast follow-up turn on the same thread cleanly\n * replaces a still-running (or wedged) prior turn instead of erroring with\n * \"Thread already running\".\n */\n private readonly onConcurrentRun: \"throw\" | \"supersede\";\n\n /**\n * @param options Per-runner behavior (`onConcurrentRun`) plus optional bounds\n * for the in-memory store ({@link InMemoryLimits}).\n *\n * Note the differing scopes: `onConcurrentRun` is per-runner instance, while\n * the limits reconfigure the PROCESS-GLOBAL store shared by every\n * `InMemoryAgentRunner`. Omit the limits for safe defaults\n * ({@link ɵINMEMORY_DEFAULTS}); passing none leaves the store untouched. When\n * multiple runners are constructed with differing limits, the last-constructed\n * wins — in practice the OSS/SSE default construction passes nothing. If a\n * second (or later) runner is constructed with limits that DIFFER from an\n * already-customized store, a one-time `console.warn` is emitted to signal that\n * the shared store's bounds are being clobbered for ALL in-memory threads.\n */\n constructor(options?: InMemoryAgentRunnerOptions) {\n super();\n const { onConcurrentRun, ...limits } = options ?? {};\n this.onConcurrentRun = onConcurrentRun ?? \"throw\";\n\n // Only reconfigure the shared store when a bound was actually supplied.\n // `new InMemoryAgentRunner({ onConcurrentRun: \"supersede\" })` must stay\n // inert with respect to limits.\n if (\n limits.maxThreads !== undefined ||\n limits.maxRunsPerThread !== undefined ||\n limits.maxBytes !== undefined\n ) {\n // Coalesce each unspecified field against the store's CURRENT effective\n // limits, NOT ɵINMEMORY_DEFAULTS. The store is process-global, so tuning\n // one bound must leave every previously-customized sibling bound intact —\n // a partial update stays a partial update instead of silently resetting the\n // fields the caller never mentioned. Passing all three (e.g.\n // ɵINMEMORY_DEFAULTS) still fully replaces the config, so the defaults-\n // restore path is unaffected.\n const current = sharedStore.ɵlimits;\n sharedStore.setLimits({\n maxThreads: limits.maxThreads ?? current.maxThreads,\n maxRunsPerThread: limits.maxRunsPerThread ?? current.maxRunsPerThread,\n maxBytes: limits.maxBytes ?? current.maxBytes,\n });\n }\n }\n\n run(request: AgentRunnerRunRequest): Observable<BaseEvent> {\n const store = sharedStore.getOrCreate(request.threadId);\n\n // Enter the concurrency branch whenever a prior run still owns the thread —\n // either actively running OR still finalizing after a stop()/supersede.\n // `stop()` flips `isRunning` to false the instant it aborts the agent, but\n // the run keeps finalizing asynchronously (`stopRequested` stays true).\n // Gating on `isRunning` alone let a `run()` slip through that window\n // unhandled: no supersede/throw, no per-run intent capture, and a leaked\n // bridge from the dying run's subject.\n if (store.isRunning || store.stopRequested) {\n if (this.onConcurrentRun !== \"supersede\") {\n throw new Error(\"Thread already running\");\n }\n // Supersede: abort the prior (possibly wedged) run so this one can start.\n // Mirrors stop(). Record the prior run's OWN finalize intent on its\n // captured control BEFORE resetting the shared store flags for the new\n // run: a supersede is a clean stop of the prior run, so its async teardown\n // must finalize as RUN_FINISHED, never a synthetic RUN_ERROR. The prior\n // run's async finalization is prevented from clobbering this run's state\n // by the run-id guard below.\n const priorAgent = store.agent;\n const priorFinalize = store.activeFinalize;\n if (priorFinalize) {\n priorFinalize.stopRequested = true;\n }\n store.isRunning = false;\n if (priorAgent) {\n try {\n priorAgent.abortRun();\n } catch (error) {\n console.error(\"Failed to abort superseded run\", error);\n }\n }\n }\n store.isRunning = true;\n store.currentRunId = request.input.runId;\n store.agent = request.agent;\n store.stopRequested = false;\n\n // Per-run finalize control. This run's teardown reads THIS captured holder\n // (never the shared `store.stopRequested`, which a later run resets), so an\n // aborted run is always finalized against its own stop-intent.\n const finalizeControl: RunFinalizeControl = { stopRequested: false };\n store.activeFinalize = finalizeControl;\n\n // Track seen message IDs and current run events for this run\n const seenMessageIds = new Set<string>();\n const currentRunEvents: BaseEvent[] = [];\n store.currentEvents = currentRunEvents;\n\n // Get all previously seen message IDs from historic runs\n const historicMessageIds = new Set<string>();\n for (const run of store.historicRuns) {\n for (const event of run.events) {\n if (\"messageId\" in event && typeof event.messageId === \"string\") {\n historicMessageIds.add(event.messageId);\n }\n if (event.type === EventType.RUN_STARTED) {\n const runStarted = event as RunStartedEvent;\n const messages = runStarted.input?.messages ?? [];\n for (const message of messages) {\n historicMessageIds.add(message.id);\n }\n }\n }\n }\n\n const nextSubject = new ReplaySubject<BaseEvent>(Infinity);\n\n // Update the store's subject immediately. We intentionally do NOT capture\n // and bridge the previous subject: see the note before `runAgent()` below.\n store.subject = nextSubject;\n\n // Create a subject for run() return value\n const runSubject = new ReplaySubject<BaseEvent>(Infinity);\n store.runSubject = runSubject;\n\n // Helper function to run the agent and handle errors\n const runAgent = async () => {\n // Get parent run ID for chaining\n const lastRun = store.historicRuns[store.historicRuns.length - 1];\n const parentRunId = lastRun?.runId ?? null;\n\n // Shared teardown for both the success and error paths. Keeping this one\n // helper means the two paths cannot drift apart (they were near-identical\n // and must stay symmetric). `interruptionMessage` is set only on the error\n // path; its presence is what distinguishes the two.\n const finalizeRun = (opts: { interruptionMessage?: string }) => {\n const isError = opts.interruptionMessage !== undefined;\n\n // Capture the count of REAL (agent-emitted) events BEFORE finalizing.\n // `finalizeRunEvents` mutates `currentRunEvents` IN PLACE — it always\n // pushes a synthetic terminal (and any closers) when the stream ended\n // without one — so after the call `currentRunEvents.length` is never 0.\n // The persistence guard below must gate on this pre-finalize count, or\n // the \"skip an immediate throw that emitted nothing\" check is dead.\n const preFinalizeEventCount = currentRunEvents.length;\n\n // Finalize against THIS run's own captured stop-intent — never the\n // shared `store.stopRequested`, which a superseding run resets. An\n // aborted run is thus finalized as a clean RUN_FINISHED, not a synthetic\n // RUN_ERROR.\n const appendedEvents = finalizeRunEvents(currentRunEvents, {\n stopRequested: finalizeControl.stopRequested,\n ...(isError ? { interruptionMessage: opts.interruptionMessage } : {}),\n });\n for (const event of appendedEvents) {\n runSubject.next(event);\n nextSubject.next(event);\n }\n\n // Does this run still own the thread? A superseding run has changed\n // `currentRunId`, so the run it replaced no longer owns the store.\n const ownsThread = store.currentRunId === request.input.runId;\n\n // Store this run's events. Guard on the per-run id (not the shared\n // `store.currentRunId`): a superseded run no longer owns the store, so\n // it must not push history — and never under a newer run's id, which\n // would corrupt the thread's history. On the error path also require at\n // least one real (pre-finalize) event, so an immediate throw with\n // nothing emitted does not create a phantom historic run holding only\n // the synthetic terminal.\n if (ownsThread && (!isError || preFinalizeEventCount > 0)) {\n // Compact the events before storing (like SQLite does)\n const compactedEvents = compactEvents(currentRunEvents);\n sharedStore.appendRun(request.threadId, {\n threadId: request.threadId,\n runId: request.input.runId,\n agentId: request.agent.agentId ?? \"default\",\n parentRunId,\n events: compactedEvents,\n // Snapshot all messages (input + generated) for the thread-messages endpoint\n messages: Array.isArray(request.agent.messages)\n ? [...request.agent.messages]\n : [],\n createdAt: Date.now(),\n });\n }\n\n // Complete the run. Guard the shared-store reset: if a newer run has\n // superseded this one (`currentRunId` changed), that run now owns the\n // store — don't clobber its state. Always complete THIS run's subjects.\n if (ownsThread) {\n store.currentEvents = null;\n store.currentRunId = null;\n store.agent = null;\n store.runSubject = null;\n store.stopRequested = false;\n store.isRunning = false;\n store.activeFinalize = null;\n }\n runSubject.complete();\n nextSubject.complete();\n // Time-scoped release: this run's events are now in historicRuns, so its\n // infinite ReplaySubject buffer is pure duplication — drop the store's\n // reference so it becomes collectable. The identity guard is what makes\n // this correct, and it does so differently on each path:\n //\n // - Owning path: no newer run superseded this one, so store.subject is\n // still nextSubject and the guard passes. The `if (ownsThread)` block\n // above just cleared isRunning and stopRequested, so connect() — which\n // bridges store.subject only while isRunning || stopRequested — will\n // not re-subscribe; it rebuilds this run's events from historicRuns\n // instead. Nulling the reference is therefore safe.\n //\n // - Superseded path (`onConcurrentRun: \"supersede\"`): a newer run has\n // already installed ITS subject and run id on the store, so the guard\n // fails and we leave store.subject untouched. Here isRunning/\n // stopRequested describe that live run (isRunning is typically true),\n // so it is precisely the identity guard — not those flags — that\n // prevents us from nulling the live run's subject and cutting\n // connect() off from the in-flight stream. This run's own buffer is no\n // longer referenced by the store and becomes collectable regardless.\n if (store.subject === nextSubject) {\n store.subject = null;\n }\n };\n\n try {\n await request.agent.runAgent(request.input, {\n onEvent: ({ event }) => {\n let processedEvent: BaseEvent = event;\n if (event.type === EventType.RUN_STARTED) {\n const runStartedEvent = event as RunStartedEvent;\n if (!runStartedEvent.input) {\n const sanitizedMessages = request.input.messages\n ? request.input.messages.filter(\n (message) => !historicMessageIds.has(message.id),\n )\n : undefined;\n const updatedInput = {\n ...request.input,\n ...(sanitizedMessages !== undefined\n ? { messages: sanitizedMessages }\n : {}),\n };\n runStartedEvent.input = updatedInput;\n processedEvent = runStartedEvent;\n }\n }\n\n runSubject.next(processedEvent); // For run() return - only agent events\n nextSubject.next(processedEvent); // For connect() / store - all events\n currentRunEvents.push(processedEvent); // Accumulate for storage\n },\n onNewMessage: ({ message }) => {\n // Called for each new message\n if (!seenMessageIds.has(message.id)) {\n seenMessageIds.add(message.id);\n }\n },\n onRunStartedEvent: () => {\n // Mark any messages from the input as seen so they aren't emitted twice\n if (request.input.messages) {\n for (const message of request.input.messages) {\n if (!seenMessageIds.has(message.id)) {\n seenMessageIds.add(message.id);\n }\n }\n }\n },\n });\n\n finalizeRun({});\n } catch (error) {\n const interruptionMessage =\n error instanceof Error ? error.message : String(error);\n finalizeRun({ interruptionMessage });\n }\n };\n\n // NOTE: we deliberately do NOT bridge the previous store subject into\n // `nextSubject`. `store.subject` is nulled the moment a run fully tears down\n // (identity guard in `finalizeRun`), so the previous subject is non-null\n // ONLY when this run is superseding a prior run that is still in flight or\n // finalizing. Forwarding that dying run's subject would replay its buffered\n // RUN_STARTED and push its terminal event (RUN_FINISHED/RUN_ERROR) into THIS\n // live run's stream — an invalid AG-UI sequence on a healthy run. A\n // superseded run's stream must stay isolated: it reaches only its own\n // connect() subscribers via its own (now-detached) subject, never the\n // superseding run's.\n\n // Start the agent execution immediately (not lazily)\n runAgent();\n\n // Return the run subject (only agent events, no injected messages)\n return runSubject.asObservable();\n }\n\n connect(request: AgentRunnerConnectRequest): Observable<BaseEvent> {\n const store = sharedStore.get(request.threadId, { touch: true });\n const connectionSubject = new ReplaySubject<BaseEvent>(Infinity);\n\n if (!store) {\n // No store means no events\n connectionSubject.complete();\n return connectionSubject.asObservable();\n }\n\n // Collect all historic events from memory\n const allHistoricEvents: BaseEvent[] = [];\n for (const run of store.historicRuns) {\n allHistoricEvents.push(...run.events);\n }\n\n // Apply compaction to all historic events together (like SQLite)\n const compactedEvents = compactEvents(allHistoricEvents);\n\n // Emit compacted events and track message IDs\n const emittedMessageIds = new Set<string>();\n for (const event of compactedEvents) {\n connectionSubject.next(event);\n if (\"messageId\" in event && typeof event.messageId === \"string\") {\n emittedMessageIds.add(event.messageId);\n }\n }\n\n // Bridge active run to connection if exists\n if (store.subject && (store.isRunning || store.stopRequested)) {\n store.subject.subscribe({\n next: (event) => {\n // Skip message events that we've already emitted from historic\n if (\n \"messageId\" in event &&\n typeof event.messageId === \"string\" &&\n emittedMessageIds.has(event.messageId)\n ) {\n return;\n }\n connectionSubject.next(event);\n },\n complete: () => connectionSubject.complete(),\n error: (err) => connectionSubject.error(err),\n });\n } else {\n // No active run, complete after historic events\n connectionSubject.complete();\n }\n\n return connectionSubject.asObservable();\n }\n\n isRunning(request: AgentRunnerIsRunningRequest): Promise<boolean> {\n const store = sharedStore.peek(request.threadId);\n return Promise.resolve(store?.isRunning ?? false);\n }\n\n stop(request: AgentRunnerStopRequest): Promise<boolean | undefined> {\n const store = sharedStore.peek(request.threadId);\n if (!store || !store.isRunning) {\n return Promise.resolve(false);\n }\n if (request.runId !== undefined && store.currentRunId !== request.runId) {\n return Promise.resolve(false);\n }\n if (store.stopRequested) {\n return Promise.resolve(false);\n }\n\n store.stopRequested = true;\n store.isRunning = false;\n // Record the stop on the running run's OWN finalize control so its async\n // teardown finalizes as a clean RUN_FINISHED. This is the same object that\n // run's closure reads, so a later run cannot mislabel this stop.\n const finalizeControl = store.activeFinalize;\n if (finalizeControl) {\n finalizeControl.stopRequested = true;\n }\n\n const agent = store.agent;\n if (!agent) {\n store.stopRequested = false;\n store.isRunning = false;\n if (finalizeControl) {\n finalizeControl.stopRequested = false;\n }\n return Promise.resolve(false);\n }\n\n try {\n agent.abortRun();\n return Promise.resolve(true);\n } catch (error) {\n console.error(\"Failed to abort agent run\", error);\n store.stopRequested = false;\n store.isRunning = true;\n if (finalizeControl) {\n finalizeControl.stopRequested = false;\n }\n return Promise.resolve(false);\n }\n }\n\n /**\n * Returns a summary of every thread that has been run through this runner.\n *\n * This powers the local-dev fallback for `GET /threads` when the Intelligence\n * platform is not configured. Each entry mirrors the shape of a platform\n * `ThreadRecord` so the HTTP handler can use the same response envelope.\n */\n listThreads(): InMemoryThread[] {\n return sharedStore.listThreads();\n }\n\n /**\n * Returns all messages for a thread, using the snapshot captured at the end\n * of the most recent run.\n *\n * This powers the local-dev fallback for `GET /threads/:threadId/messages`\n * when the Intelligence platform is not configured. The returned `Message[]`\n * objects come directly from the ag-ui agent, so their shape is compatible\n * with the Intelligence platform's `ThreadMessage` type.\n */\n getThreadMessages(threadId: string): Message[] {\n const store = sharedStore.peek(threadId);\n if (!store) return [];\n // The thread's latest non-empty snapshot is held at the store level,\n // independent of `historicRuns` lifecycle, so run-cap eviction and\n // interleaved empty-snapshot runs can never lose it. Return a SHALLOW\n // (array-level) copy: a fresh array so a caller mutating array STRUCTURE\n // (push/splice/reassign elements) cannot affect the stored snapshot. We\n // deliberately do NOT deep-copy: `structuredClone` throws DataCloneError on a\n // non-cloneable message field, which would wedge the thread and hang SSE —\n // inconsistent with `ɵestimateBytes`, which tolerates the same bad-payload class.\n // The tradeoff is that the inner `Message` objects remain shared by reference with\n // the stored snapshot, so mutating a returned message's FIELD\n // (e.g. `getThreadMessages(t)[0].content = \"x\"`) is NOT isolated and would corrupt\n // the stored snapshot. That inner-object isolation is a known limitation tracked as\n // follow-up; callers must treat returned messages as read-only.\n return [...store.messagesSnapshot];\n }\n\n /**\n * Returns all AG-UI events for a thread, compacted across historic runs.\n *\n * Powers the local-dev fallback for `GET /threads/:threadId/events` when the\n * Intelligence platform is not configured. The compaction logic matches\n * the connection-replay path in {@link connect}, so the stream a\n * late-joining inspector sees matches what this method returns.\n */\n getThreadEvents(threadId: string): BaseEvent[] {\n const store = sharedStore.peek(threadId);\n if (!store || store.historicRuns.length === 0) return [];\n const all: BaseEvent[] = [];\n for (const run of store.historicRuns) all.push(...run.events);\n return compactEvents(all);\n }\n\n /**\n * Returns the agent state snapshot for a thread.\n *\n * Derived from the last `STATE_SNAPSHOT` in the compacted event stream. The\n * AG-UI `compactEvents` helper consolidates STATE_DELTA events and produces\n * a single trailing STATE_SNAPSHOT when state changes exist, so this is a\n * faithful view of state at the end of the most recent run.\n *\n * Returns `null` when the thread has never emitted a STATE_SNAPSHOT.\n */\n getThreadState(threadId: string): Record<string, unknown> | null {\n const events = this.getThreadEvents(threadId);\n // Walk backwards — the last snapshot wins.\n for (let i = events.length - 1; i >= 0; i--) {\n const event = events[i]!;\n if (event.type === EventType.STATE_SNAPSHOT) {\n const snapshot = (event as StateSnapshotEvent).snapshot;\n // Only plain objects satisfy the Record<string, unknown> contract.\n // `typeof [] === \"object\"` is true, so arrays must be rejected\n // explicitly to avoid returning an array typed as a Record.\n if (\n snapshot &&\n typeof snapshot === \"object\" &&\n !Array.isArray(snapshot)\n ) {\n // Return a defensive shallow copy so callers can't mutate the\n // snapshot object held inside the stored event (matches the\n // getThreadMessages defensive-copy approach).\n return { ...(snapshot as Record<string, unknown>) };\n }\n return null;\n }\n }\n return null;\n }\n\n /**\n * Clears all in-memory thread history.\n *\n * Powers the local-dev fallback for `POST /threads/clear`, letting consumers\n * (e.g. the demo's Clear button) reset to an empty thread list without\n * restarting the runtime. Intentionally not exposed on the Intelligence\n * platform path: there, thread history lives in a real database and must\n * not be wiped this way.\n */\n clearThreads(): void {\n sharedStore.clear();\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"in-memory.mjs","names":[],"sources":["../../../../src/v2/runtime/runner/in-memory.ts"],"sourcesContent":["import type {\n AgentRunnerConnectRequest,\n AgentRunnerIsRunningRequest,\n AgentRunnerRunRequest,\n} from \"./agent-runner\";\nimport { AgentRunner } from \"./agent-runner\";\nimport type { AgentRunnerStopRequest } from \"./agent-runner\";\nimport type { Observable } from \"rxjs\";\nimport { ReplaySubject } from \"rxjs\";\nimport type {\n AbstractAgent,\n BaseEvent,\n Message,\n RunStartedEvent,\n StateSnapshotEvent,\n} from \"@ag-ui/client\";\nimport { EventType, compactEvents } from \"@ag-ui/client\";\nimport { finalizeRunEvents } from \"@copilotkit/shared\";\n\nexport interface InMemoryLimits {\n /** LRU cap on distinct threads. */\n maxThreads?: number;\n /** FIFO cap on runs kept per thread. `Infinity` or `0` disables the cap. */\n maxRunsPerThread?: number;\n /**\n * Approximate byte ceiling on RETAINED thread/run history. Enforced at run\n * completion (in `appendRun`), where LRU non-running threads are evicted to\n * keep the total under this limit.\n *\n * Limitation: this bounds only history that has already been committed. A\n * single in-flight run's buffered events (`currentRunEvents` and the two\n * `ReplaySubject<BaseEvent>(Infinity)` buffers in `run()`) are NOT counted\n * until that run completes, so `maxBytes` does not bound a single runaway\n * run mid-stream.\n *\n * Limitation: byte eviction drops only other LRU non-running threads and\n * never self-evicts the active/just-appended thread, so a single dominant\n * thread's own retained history is not byte-trimmed (bounded only by\n * `maxRunsPerThread`). `maxBytes` is thus a cross-thread ceiling enforced by\n * evicting OTHER threads, not a per-thread cap.\n */\n maxBytes?: number;\n}\n\n/**\n * Constructor options for {@link InMemoryAgentRunner}.\n *\n * Extends {@link InMemoryLimits} so bounds can be passed inline alongside the\n * per-runner behavior flags. Be aware of the scope difference: the limits\n * reconfigure the process-global store shared by every runner, whereas\n * `onConcurrentRun` applies only to the runner instance it is passed to.\n */\nexport interface InMemoryAgentRunnerOptions extends InMemoryLimits {\n /**\n * How to handle a `run()` for a thread that already has an in-flight run.\n * `\"throw\"` (default) rejects with \"Thread already running\". `\"supersede\"`\n * aborts the prior run and starts the new one.\n */\n onConcurrentRun?: \"throw\" | \"supersede\";\n}\n\nexport const ɵINMEMORY_DEFAULTS: Required<InMemoryLimits> = {\n maxThreads: 1000,\n maxRunsPerThread: 100,\n maxBytes: 512 * 1024 ** 2,\n};\n\n/**\n * A limit value is well-formed iff it is a non-negative integer OR `+Infinity`.\n * `+Infinity` is the documented \"disabled/unbounded\" sentinel and `0` is the\n * documented run-cap disable sentinel; both are non-negative and pass. Every\n * enforcement site (`evictThreadsIfNeeded`, `enforceRunCap`,\n * `evictByBytesIfNeeded`) compares its counter against the limit with `>` in a\n * `while`/`if` guard, so only these shapes keep those loops finite and correct.\n * Rejected: negatives (drive `count > -1` true on an empty collection, so\n * `enforceRunCap` `shift()!`s `undefined` and throws), `-Infinity` (loops never\n * terminate their intent — always \"over\"), `NaN` (every `>` is false, silently\n * disabling the bound), and non-integer finites (fractional caps are nonsense).\n */\nfunction ɵisValidLimit(value: number): boolean {\n return value === Infinity || (Number.isInteger(value) && value >= 0);\n}\n\n/**\n * Normalize a fully-resolved limits bag so every field is well-formed before it\n * can reach an enforcement loop. Each field is validated independently against\n * {@link ɵisValidLimit}; an invalid value is CLAMPED to its\n * {@link ɵINMEMORY_DEFAULTS} floor and a single `console.warn` naming the field\n * and the received value is emitted.\n *\n * Clamp-and-warn (rather than throw) is deliberate and matches this file's\n * established posture toward bad input: `ɵestimateBytes` swallows serialization\n * failures and returns 0, the limits-clobber path warns rather than throwing,\n * and both the eviction and clobber logs are wrapped so \"logging must never\n * break construction/a run\". Constructing a bounded in-memory runner is a\n * best-effort, non-durable convenience; a typo'd bound must degrade to a safe\n * default, never abort construction or (worse) surface later as an unhandled\n * rejection from the fire-and-forget finalize path.\n */\nexport function ɵnormalizeLimits(\n limits: Required<InMemoryLimits>,\n): Required<InMemoryLimits> {\n const normalized = { ...limits };\n for (const field of Object.keys(\n ɵINMEMORY_DEFAULTS,\n ) as (keyof InMemoryLimits)[]) {\n const value = limits[field];\n if (!ɵisValidLimit(value)) {\n const fallback = ɵINMEMORY_DEFAULTS[field];\n normalized[field] = fallback;\n try {\n console.warn(\n `[CopilotKit] InMemoryAgentRunner: invalid ${field} value ` +\n `${String(value)} (expected a non-negative integer or Infinity); ` +\n `falling back to ${String(fallback)}.`,\n );\n } catch {\n // best-effort: logging must never break construction\n }\n }\n }\n return normalized;\n}\n\nconst EVICTION_GUIDANCE =\n \"[CopilotKit] InMemoryAgentRunner evicted in-memory thread history to stay \" +\n \"under memory limits. This runner is bounded and non-durable by design. For \" +\n \"durable or production threads, configure an Intelligence backend.\";\n\nconst LIMITS_CLOBBER_GUIDANCE =\n \"[CopilotKit] InMemoryAgentRunner was constructed with in-memory limits that \" +\n \"differ from the already-configured process-global store; the last-constructed \" +\n \"runner's limits apply to ALL in-memory threads (the store is shared per-process). \" +\n \"Configure a single consistent set of limits, or use an Intelligence backend for \" +\n \"isolated bounds.\";\n\n/**\n * Best-effort approximate byte size of a value, via serialized length.\n * Never throws — returns 0 when the value cannot be serialized. This is an\n * approximation (UTF-16 length, not exact heap bytes), used only for relative\n * accounting against `maxBytes`.\n */\nexport function ɵestimateBytes(value: unknown): number {\n try {\n return JSON.stringify(value)?.length ?? 0;\n } catch {\n return 0;\n }\n}\n\n/**\n * Per-run finalize intent, captured once when a run starts and mutated (only)\n * by whoever aborts THAT run — `stop()` or a superseding `run()`. The run's own\n * teardown reads this captured holder instead of the shared, mutable\n * `store.stopRequested`, so a later run that resets store state can never cause\n * an intentionally-stopped run to be finalized as an error (or vice versa).\n */\ninterface RunFinalizeControl {\n /** True once THIS run has been asked to stop (clean stop, not an error). */\n stopRequested: boolean;\n}\n\ninterface HistoricRun {\n threadId: string;\n runId: string;\n /** ID of the agent that executed this run. */\n agentId: string;\n parentRunId: string | null;\n events: BaseEvent[];\n /**\n * Snapshot of all messages (input + generated) at the end of this run, as\n * passed in by the caller. NOTE: `BoundedThreadStore.appendRun` moves this\n * snapshot to the THREAD level (`InMemoryEventStore.messagesSnapshot`) and\n * clears this field to `[]`, so a stored HistoricRun never carries messages.\n * The thread-messages fallback reads the thread-level snapshot, not this.\n */\n messages: Message[];\n createdAt: number;\n /** Approximate retained byte size of `events`; set by BoundedThreadStore at append. */\n approxEventBytes?: number;\n /**\n * Legacy field retained for shape compatibility. `appendRun` always zeroes it\n * because message bytes are accounted at the thread level, not per run.\n */\n approxMessageBytes?: number;\n}\n\n/**\n * Lightweight thread summary returned by {@link InMemoryAgentRunner.listThreads}.\n * Shape matches CopilotKit Intelligence's ThreadRecord so the same HTTP\n * response envelope can be used for both backends.\n */\nexport interface InMemoryThread {\n id: string;\n name: string | null;\n agentId: string;\n organizationId: \"\"; // always empty in in-memory mode\n createdById: \"\"; // always empty in in-memory mode\n archived: false; // always false in in-memory mode\n createdAt: string;\n updatedAt: string;\n}\n\nclass InMemoryEventStore {\n constructor(public threadId: string) {}\n\n /** The subject that current consumers subscribe to. */\n subject: ReplaySubject<BaseEvent> | null = null;\n\n /** True while a run is actively producing events. */\n isRunning = false;\n\n /** Current run ID */\n currentRunId: string | null = null;\n\n /** Historic completed runs */\n historicRuns: HistoricRun[] = [];\n\n /** Currently running agent instance (if any). */\n agent: AbstractAgent | null = null;\n\n /** Subject returned from run() while the run is active. */\n runSubject: ReplaySubject<BaseEvent> | null = null;\n\n /**\n * Thread-level lifecycle flag: true once a stop/supersede has been requested\n * for the currently-owning run but that run has not yet finalized. Drives\n * eviction protection, the connect() bridge, and stop() de-dup. This is NOT\n * the finalize intent read by a run's teardown — that lives per-run on\n * {@link activeFinalize}, so a superseding run resetting this field cannot\n * mislabel the run it replaced. A new run resets this to false when it takes\n * ownership.\n */\n stopRequested = false;\n\n /**\n * Finalize control of the currently-owning run. `stop()` and a superseding\n * `run()` flip the owning run's flag through this reference; each run also\n * captures the SAME object in its closure, so its teardown finalizes against\n * its own intent regardless of what a later run does to the store.\n */\n activeFinalize: RunFinalizeControl | null = null;\n\n /** Reference to the events emitted in the current run. */\n currentEvents: BaseEvent[] | null = null;\n\n /**\n * The thread's single latest NON-EMPTY message snapshot, held at the THREAD\n * level (independent of `historicRuns` lifecycle). Decoupling the snapshot\n * from per-run storage means run-cap FIFO eviction and interleaved\n * empty-snapshot runs can never drop or pin the thread's message history.\n */\n messagesSnapshot: Message[] = [];\n\n /** Approximate retained byte size of `messagesSnapshot`. */\n approxMessagesSnapshotBytes = 0;\n\n /**\n * The thread's true creation timestamp (epoch ms), captured from the FIRST\n * run ever appended and held at the THREAD level (independent of\n * `historicRuns` lifecycle). Decoupling it from per-run storage means run-cap\n * FIFO eviction — which shifts the oldest entries off `historicRuns` — can\n * never move the reported creation time forward. `null` until the first run\n * lands. Mirrors the `messagesSnapshot` thread-level decoupling.\n */\n createdAt: number | null = null;\n}\n\nexport class ɵBoundedThreadStore {\n private readonly map = new Map<string, InMemoryEventStore>();\n private totalBytes = 0;\n private warned = false;\n /** True once limits have been EXPLICITLY set (via setLimits), not just the constructor default. */\n private limitsExplicitlySet = false;\n /** Warn-once latch for the clobber warning, kept distinct from the eviction `warned` latch. */\n private clobberWarned = false;\n\n private limits: Required<InMemoryLimits>;\n\n constructor(limits: Required<InMemoryLimits>) {\n // Normalize once at construction so `this.limits` is ALWAYS well-formed,\n // regardless of entry point (direct construction or a later `setLimits`).\n this.limits = ɵnormalizeLimits(limits);\n }\n\n get byteTotal(): number {\n return this.totalBytes;\n }\n\n /**\n * The store's CURRENT effective bounds. Exposed (with the `ɵ` internal-API\n * prefix) so a partial `setLimits` can coalesce unspecified fields against the\n * live config rather than the hardcoded {@link ɵINMEMORY_DEFAULTS} — a partial\n * update must be a partial update, never a silent reset of the fields the\n * caller did not mention. Returns a copy so callers cannot mutate the store's\n * bounds through it.\n */\n get ɵlimits(): Required<InMemoryLimits> {\n return { ...this.limits };\n }\n\n /**\n * Reconfigure the process-global store's bounds. Called by the\n * {@link InMemoryAgentRunner} constructor when limits are passed. Because the\n * store is a per-process singleton, this replaces the bounds for ALL in-memory\n * threads. Emits {@link LIMITS_CLOBBER_GUIDANCE} at most ONCE per store when a\n * SECOND (or later) explicit set arrives whose resolved values differ from the\n * prior explicit set — i.e. a genuine clobber of an already-customized config.\n * The first explicit customization (defaults → custom) is the intended\n * override and never warns; identical re-sets never warn.\n */\n setLimits(limits: Required<InMemoryLimits>): void {\n // Normalize FIRST so invalid fields can never reach an enforcement loop and\n // so the clobber comparison below is against the EFFECTIVE (clamped) values,\n // not the raw ones — a typo'd bound that clamps to the current default is not\n // a genuine clobber and must not warn.\n const normalized = ɵnormalizeLimits(limits);\n if (\n this.limitsExplicitlySet &&\n !this.clobberWarned &&\n (normalized.maxThreads !== this.limits.maxThreads ||\n normalized.maxRunsPerThread !== this.limits.maxRunsPerThread ||\n normalized.maxBytes !== this.limits.maxBytes)\n ) {\n this.clobberWarned = true;\n try {\n console.warn(LIMITS_CLOBBER_GUIDANCE);\n } catch {\n // best-effort: logging must never break construction\n }\n }\n this.limitsExplicitlySet = true;\n this.limits = normalized;\n }\n\n get size(): number {\n return this.map.size;\n }\n\n /** Re-insert at the tail so Map iteration order stays LRU-first. */\n private touchOrder(threadId: string, store: InMemoryEventStore): void {\n this.map.delete(threadId);\n this.map.set(threadId, store);\n }\n\n getOrCreate(threadId: string): InMemoryEventStore {\n const existing = this.map.get(threadId);\n if (existing) {\n this.touchOrder(threadId, existing);\n return existing;\n }\n const store = new InMemoryEventStore(threadId);\n this.map.set(threadId, store);\n this.evictThreadsIfNeeded(threadId);\n return store;\n }\n\n get(\n threadId: string,\n opts: { touch: boolean },\n ): InMemoryEventStore | undefined {\n const store = this.map.get(threadId);\n if (store && opts.touch) this.touchOrder(threadId, store);\n return store;\n }\n\n peek(threadId: string): InMemoryEventStore | undefined {\n return this.map.get(threadId);\n }\n\n /**\n * Evict the least-recently-used thread that is neither running NOR\n * mid-finalization. Returns false if none evictable. The `protect` thread\n * (typically the one just created) is never evicted, so a fresh thread is not\n * immediately dropped when it is the only non-running candidate.\n *\n * A thread is skipped while `isRunning` OR `stopRequested` is set.\n * `stop()` flips `isRunning` to false the moment it aborts the agent, but the\n * run keeps finalizing asynchronously (the abort trips the `catch` in\n * `runAgent`, which later calls `appendRun`). During that window\n * `stopRequested` stays true; evicting the thread then would make the pending\n * `appendRun` hit `if (!store) return` and silently drop the aborted run's\n * history. Guarding on `stopRequested` keeps the thread alive until\n * finalization completes.\n */\n private evictOneLru(protect?: string): boolean {\n for (const [threadId, store] of this.map) {\n if (threadId === protect) continue; // never evict the just-created thread\n // never evict a running or still-finalizing (stop-requested) thread\n if (store.isRunning || store.stopRequested) continue;\n this.removeThread(threadId, store);\n this.noteEviction();\n return true;\n }\n return false;\n }\n\n appendRun(threadId: string, run: HistoricRun): void {\n const store = this.map.get(threadId);\n if (!store) return; // best-effort: nothing to append to\n\n // Thread-level creation timestamp: capture the FIRST run's createdAt once\n // and never overwrite it. Held on the store (not derived from\n // `historicRuns[0]`) so run-cap FIFO eviction of the oldest runs cannot\n // drift the thread's reported creation time forward. Mirrors the\n // thread-level `messagesSnapshot` decoupling below.\n if (store.createdAt === null) {\n store.createdAt = run.createdAt;\n }\n\n // Thread-level message snapshot: keep the single latest NON-EMPTY snapshot\n // on the store, decoupled from `historicRuns`. When the incoming run\n // carries a non-empty snapshot, replace the thread's snapshot (adjusting\n // byte accounting). When it's empty (non-array `agent.messages` or an\n // error-path run), leave the existing thread snapshot untouched so history\n // is never lost. The snapshot never lives on a HistoricRun, so run-cap FIFO\n // eviction can never drop it and an interleaved empty run can never pin it.\n if (run.messages.length > 0) {\n this.totalBytes -= store.approxMessagesSnapshotBytes;\n // Store the incoming array directly (SHALLOW, array-level copy). `run.messages`\n // is already a fresh `[...agent.messages]` array created in run(), so we own the\n // array and it is decoupled from `agent.messages` at the array level (push/splice\n // on the agent's array cannot mutate our snapshot). We deliberately do NOT deep-copy\n // here: `structuredClone` throws DataCloneError on a non-cloneable message field,\n // which would wedge the thread and hang SSE — inconsistent with `ɵestimateBytes`,\n // which tolerates the same bad-payload class. The tradeoff is that the inner\n // `Message` objects remain shared by reference with `agent.messages`, so an agent\n // that mutates its own message objects IN PLACE after the run can still be observed\n // through this snapshot. That inner-object isolation is a known limitation tracked as\n // follow-up; callers must treat returned messages as read-only. Estimate bytes on the\n // same value so accounting matches exactly what is retained.\n store.messagesSnapshot = run.messages;\n store.approxMessagesSnapshotBytes = ɵestimateBytes(run.messages);\n this.totalBytes += store.approxMessagesSnapshotBytes;\n }\n\n // Do not carry message bytes on the HistoricRun: the snapshot is now tracked\n // at the thread level, so historicRuns must never account message bytes.\n run.messages = [];\n run.approxMessageBytes = 0;\n\n // Compute this run's approximate event size once, at append time.\n run.approxEventBytes = ɵestimateBytes(run.events);\n store.historicRuns.push(run);\n this.totalBytes += run.approxEventBytes;\n this.touchOrder(threadId, store);\n\n this.enforceRunCap(store);\n this.evictByBytesIfNeeded(threadId);\n }\n\n private enforceRunCap(store: InMemoryEventStore): void {\n const cap = this.limits.maxRunsPerThread;\n if (!cap || cap === Infinity) return; // 0 or Infinity → disabled\n while (store.historicRuns.length > cap) {\n const dropped = store.historicRuns.shift()!;\n // Only event bytes live on a HistoricRun; the message snapshot is tracked\n // at the thread level and survives run-cap eviction.\n this.totalBytes -= dropped.approxEventBytes ?? 0;\n // Per-thread run-cap trimming is also eviction — history is being dropped.\n // Route it through the SAME warn-once latch as whole-thread LRU eviction so\n // this shows up in logs rather than as silent data loss. `noteEviction` is\n // latched (one warning per store, reset by `clear()`), so a hot thread that\n // trims on every subsequent append warns once, never per dropped run. The\n // loop only runs when a run is ACTUALLY over the cap, so a disabled or\n // under-cap `enforceRunCap` stays silent (it returned / never entered here).\n this.noteEviction();\n }\n }\n\n /**\n * Trim the store back under the byte ceiling by evicting LRU non-running\n * threads. `protect` (the just-appended thread) is never self-evicted, so a\n * fresh run pushes OTHER threads out rather than dropping itself.\n */\n private evictByBytesIfNeeded(protect?: string): void {\n while (this.totalBytes > this.limits.maxBytes) {\n if (!this.evictOneLru(protect)) break; // only protected/running threads left → accept overage\n }\n }\n\n private removeThread(threadId: string, store: InMemoryEventStore): void {\n for (const run of store.historicRuns) {\n this.totalBytes -= run.approxEventBytes ?? 0;\n }\n // The thread's message snapshot is tracked at the store level, so it must\n // be reclaimed here in addition to the per-run event bytes.\n this.totalBytes -= store.approxMessagesSnapshotBytes;\n this.map.delete(threadId);\n }\n\n private evictThreadsIfNeeded(protect?: string): void {\n while (this.map.size > this.limits.maxThreads) {\n if (!this.evictOneLru(protect)) break; // everything evictable is running → accept overage\n }\n }\n\n private noteEviction(): void {\n if (this.warned) return;\n this.warned = true;\n try {\n console.warn(EVICTION_GUIDANCE);\n } catch {\n // best-effort: logging must never break a run\n }\n }\n\n listThreads(): InMemoryThread[] {\n const threads: InMemoryThread[] = [];\n for (const [threadId, store] of this.map) {\n if (store.historicRuns.length === 0) continue;\n const lastRun = store.historicRuns[store.historicRuns.length - 1]!;\n // Creation time comes from the thread-level `store.createdAt` (the first\n // run ever appended), NOT `historicRuns[0]` (the oldest RETAINED run):\n // run-cap FIFO eviction drops the oldest retained runs, so deriving it\n // from `historicRuns[0]` would silently drift the timestamp forward over\n // a thread's lifetime. `updatedAt` stays on `lastRun` because FIFO\n // eviction removes from the FRONT, so the newest run is never evicted.\n // The `?? lastRun.createdAt` fallback is defensive only: any thread with\n // runs has had `store.createdAt` set by `appendRun`.\n threads.push({\n id: threadId,\n name: null,\n agentId: lastRun.agentId,\n organizationId: \"\",\n createdById: \"\",\n archived: false,\n createdAt: new Date(store.createdAt ?? lastRun.createdAt).toISOString(),\n updatedAt: new Date(lastRun.createdAt).toISOString(),\n });\n }\n return threads.sort(\n (a, b) =>\n new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime(),\n );\n }\n\n clear(): void {\n this.map.clear();\n this.totalBytes = 0;\n this.warned = false;\n }\n}\n\n/**\n * Process-wide singleton backing every {@link InMemoryAgentRunner}. Exported\n * (with the `ɵ` internal-API prefix) so tests can inspect the exact store the\n * runner writes to; not part of the public API.\n */\nexport const ɵGLOBAL_STORE = new ɵBoundedThreadStore(ɵINMEMORY_DEFAULTS);\nconst sharedStore = ɵGLOBAL_STORE;\n\nexport class InMemoryAgentRunner extends AgentRunner {\n readonly ɵsupportsLocalThreadEndpoints = true;\n\n /**\n * How to handle a `run()` for a thread that already has an in-flight run.\n * `\"throw\"` (default) preserves the historic behavior. `\"supersede\"` aborts\n * the prior run (mirroring `stop()`) and starts the new one — opted into by\n * the hosted-bot listener so a fast follow-up turn on the same thread cleanly\n * replaces a still-running (or wedged) prior turn instead of erroring with\n * \"Thread already running\".\n */\n private readonly onConcurrentRun: \"throw\" | \"supersede\";\n\n /**\n * @param options Per-runner behavior (`onConcurrentRun`) plus optional bounds\n * for the in-memory store ({@link InMemoryLimits}).\n *\n * Note the differing scopes: `onConcurrentRun` is per-runner instance, while\n * the limits reconfigure the PROCESS-GLOBAL store shared by every\n * `InMemoryAgentRunner`. Omit the limits for safe defaults\n * ({@link ɵINMEMORY_DEFAULTS}); passing none leaves the store untouched. When\n * multiple runners are constructed with differing limits, the last-constructed\n * wins — in practice the OSS/SSE default construction passes nothing. If a\n * second (or later) runner is constructed with limits that DIFFER from an\n * already-customized store, a one-time `console.warn` is emitted to signal that\n * the shared store's bounds are being clobbered for ALL in-memory threads.\n */\n constructor(options?: InMemoryAgentRunnerOptions) {\n super();\n const { onConcurrentRun, ...limits } = options ?? {};\n this.onConcurrentRun = onConcurrentRun ?? \"throw\";\n\n // Only reconfigure the shared store when a bound was actually supplied.\n // `new InMemoryAgentRunner({ onConcurrentRun: \"supersede\" })` must stay\n // inert with respect to limits.\n if (\n limits.maxThreads !== undefined ||\n limits.maxRunsPerThread !== undefined ||\n limits.maxBytes !== undefined\n ) {\n // Coalesce each unspecified field against the store's CURRENT effective\n // limits, NOT ɵINMEMORY_DEFAULTS. The store is process-global, so tuning\n // one bound must leave every previously-customized sibling bound intact —\n // a partial update stays a partial update instead of silently resetting the\n // fields the caller never mentioned. Passing all three (e.g.\n // ɵINMEMORY_DEFAULTS) still fully replaces the config, so the defaults-\n // restore path is unaffected.\n const current = sharedStore.ɵlimits;\n sharedStore.setLimits({\n maxThreads: limits.maxThreads ?? current.maxThreads,\n maxRunsPerThread: limits.maxRunsPerThread ?? current.maxRunsPerThread,\n maxBytes: limits.maxBytes ?? current.maxBytes,\n });\n }\n }\n\n run(request: AgentRunnerRunRequest): Observable<BaseEvent> {\n const store = sharedStore.getOrCreate(request.threadId);\n\n // Enter the concurrency branch whenever a prior run still owns the thread —\n // either actively running OR still finalizing after a stop()/supersede.\n // `stop()` flips `isRunning` to false the instant it aborts the agent, but\n // the run keeps finalizing asynchronously (`stopRequested` stays true).\n // Gating on `isRunning` alone let a `run()` slip through that window\n // unhandled: no supersede/throw, no per-run intent capture, and a leaked\n // bridge from the dying run's subject.\n if (store.isRunning || store.stopRequested) {\n if (this.onConcurrentRun !== \"supersede\") {\n throw new Error(\"Thread already running\");\n }\n // Supersede: abort the prior (possibly wedged) run so this one can start.\n // Mirrors stop(). Record the prior run's OWN finalize intent on its\n // captured control BEFORE resetting the shared store flags for the new\n // run: a supersede is a clean stop of the prior run, so its async teardown\n // must finalize as RUN_FINISHED, never a synthetic RUN_ERROR. The prior\n // run's async finalization is prevented from clobbering this run's state\n // by the run-id guard below.\n const priorAgent = store.agent;\n const priorFinalize = store.activeFinalize;\n if (priorFinalize) {\n priorFinalize.stopRequested = true;\n }\n store.isRunning = false;\n if (priorAgent) {\n try {\n priorAgent.abortRun();\n } catch (error) {\n console.error(\"Failed to abort superseded run\", error);\n }\n }\n }\n store.isRunning = true;\n store.currentRunId = request.input.runId;\n store.agent = request.agent;\n store.stopRequested = false;\n\n // Per-run finalize control. This run's teardown reads THIS captured holder\n // (never the shared `store.stopRequested`, which a later run resets), so an\n // aborted run is always finalized against its own stop-intent.\n const finalizeControl: RunFinalizeControl = { stopRequested: false };\n store.activeFinalize = finalizeControl;\n\n // Track seen message IDs and current run events for this run\n const seenMessageIds = new Set<string>();\n const currentRunEvents: BaseEvent[] = [];\n store.currentEvents = currentRunEvents;\n\n // Get all previously seen message IDs from historic runs\n const historicMessageIds = new Set<string>();\n for (const run of store.historicRuns) {\n for (const event of run.events) {\n if (\"messageId\" in event && typeof event.messageId === \"string\") {\n historicMessageIds.add(event.messageId);\n }\n if (event.type === EventType.RUN_STARTED) {\n const runStarted = event as RunStartedEvent;\n const messages = runStarted.input?.messages ?? [];\n for (const message of messages) {\n historicMessageIds.add(message.id);\n }\n }\n }\n }\n\n const nextSubject = new ReplaySubject<BaseEvent>(Infinity);\n\n // Update the store's subject immediately. We intentionally do NOT capture\n // and bridge the previous subject: see the note before `runAgent()` below.\n store.subject = nextSubject;\n\n // Create a subject for run() return value\n const runSubject = new ReplaySubject<BaseEvent>(Infinity);\n store.runSubject = runSubject;\n\n // Helper function to run the agent and handle errors\n const runAgent = async () => {\n // Get parent run ID for chaining\n const lastRun = store.historicRuns[store.historicRuns.length - 1];\n const parentRunId = lastRun?.runId ?? null;\n\n // Shared teardown for both the success and error paths. Keeping this one\n // helper means the two paths cannot drift apart (they were near-identical\n // and must stay symmetric). `interruptionMessage` is set only on the error\n // path; its presence is what distinguishes the two.\n const finalizeRun = (opts: { interruptionMessage?: string }) => {\n const isError = opts.interruptionMessage !== undefined;\n\n // Capture the count of REAL (agent-emitted) events BEFORE finalizing.\n // `finalizeRunEvents` mutates `currentRunEvents` IN PLACE — it always\n // pushes a synthetic terminal (and any closers) when the stream ended\n // without one — so after the call `currentRunEvents.length` is never 0.\n // The persistence guard below must gate on this pre-finalize count, or\n // the \"skip an immediate throw that emitted nothing\" check is dead.\n const preFinalizeEventCount = currentRunEvents.length;\n\n // Finalize against THIS run's own captured stop-intent — never the\n // shared `store.stopRequested`, which a superseding run resets. An\n // aborted run is thus finalized as a clean RUN_FINISHED, not a synthetic\n // RUN_ERROR.\n const appendedEvents = finalizeRunEvents(currentRunEvents, {\n stopRequested: finalizeControl.stopRequested,\n ...(isError ? { interruptionMessage: opts.interruptionMessage } : {}),\n });\n for (const event of appendedEvents) {\n runSubject.next(event);\n nextSubject.next(event);\n }\n\n // Does this run still own the thread? A superseding run has changed\n // `currentRunId`, so the run it replaced no longer owns the store.\n const ownsThread = store.currentRunId === request.input.runId;\n\n // Store this run's events. Guard on the per-run id (not the shared\n // `store.currentRunId`): a superseded run no longer owns the store, so\n // it must not push history — and never under a newer run's id, which\n // would corrupt the thread's history. On the error path also require at\n // least one real (pre-finalize) event, so an immediate throw with\n // nothing emitted does not create a phantom historic run holding only\n // the synthetic terminal.\n if (ownsThread && (!isError || preFinalizeEventCount > 0)) {\n // Compact the events before storing (like SQLite does)\n const compactedEvents = compactEvents(currentRunEvents);\n sharedStore.appendRun(request.threadId, {\n threadId: request.threadId,\n runId: request.input.runId,\n agentId: request.agent.agentId ?? \"default\",\n parentRunId,\n events: compactedEvents,\n // Snapshot all messages (input + generated) for the thread-messages endpoint\n messages: Array.isArray(request.agent.messages)\n ? [...request.agent.messages]\n : [],\n createdAt: Date.now(),\n });\n }\n\n // Complete the run. Guard the shared-store reset: if a newer run has\n // superseded this one (`currentRunId` changed), that run now owns the\n // store — don't clobber its state. Always complete THIS run's subjects.\n if (ownsThread) {\n store.currentEvents = null;\n store.currentRunId = null;\n store.agent = null;\n store.runSubject = null;\n store.stopRequested = false;\n store.isRunning = false;\n store.activeFinalize = null;\n }\n runSubject.complete();\n nextSubject.complete();\n // Time-scoped release: this run's events are now in historicRuns, so its\n // infinite ReplaySubject buffer is pure duplication — drop the store's\n // reference so it becomes collectable. The identity guard is what makes\n // this correct, and it does so differently on each path:\n //\n // - Owning path: no newer run superseded this one, so store.subject is\n // still nextSubject and the guard passes. The `if (ownsThread)` block\n // above just cleared isRunning and stopRequested, so connect() — which\n // bridges store.subject only while isRunning || stopRequested — will\n // not re-subscribe; it rebuilds this run's events from historicRuns\n // instead. Nulling the reference is therefore safe.\n //\n // - Superseded path (`onConcurrentRun: \"supersede\"`): a newer run has\n // already installed ITS subject and run id on the store, so the guard\n // fails and we leave store.subject untouched. Here isRunning/\n // stopRequested describe that live run (isRunning is typically true),\n // so it is precisely the identity guard — not those flags — that\n // prevents us from nulling the live run's subject and cutting\n // connect() off from the in-flight stream. This run's own buffer is no\n // longer referenced by the store and becomes collectable regardless.\n if (store.subject === nextSubject) {\n store.subject = null;\n }\n };\n\n try {\n await request.agent.runAgent(request.input, {\n onEvent: ({ event }) => {\n let processedEvent: BaseEvent = event;\n if (event.type === EventType.RUN_STARTED) {\n const runStartedEvent = event as RunStartedEvent;\n if (!runStartedEvent.input) {\n const sanitizedMessages = request.input.messages\n ? request.input.messages.filter(\n (message) => !historicMessageIds.has(message.id),\n )\n : undefined;\n const updatedInput = {\n ...request.input,\n ...(sanitizedMessages !== undefined\n ? { messages: sanitizedMessages }\n : {}),\n };\n runStartedEvent.input = updatedInput;\n processedEvent = runStartedEvent;\n }\n }\n\n runSubject.next(processedEvent); // For run() return - only agent events\n nextSubject.next(processedEvent); // For connect() / store - all events\n currentRunEvents.push(processedEvent); // Accumulate for storage\n },\n onNewMessage: ({ message }) => {\n // Called for each new message\n if (!seenMessageIds.has(message.id)) {\n seenMessageIds.add(message.id);\n }\n },\n onRunStartedEvent: () => {\n // Mark any messages from the input as seen so they aren't emitted twice\n if (request.input.messages) {\n for (const message of request.input.messages) {\n if (!seenMessageIds.has(message.id)) {\n seenMessageIds.add(message.id);\n }\n }\n }\n },\n });\n\n finalizeRun({});\n } catch (error) {\n const interruptionMessage =\n error instanceof Error ? error.message : String(error);\n finalizeRun({ interruptionMessage });\n }\n };\n\n // NOTE: we deliberately do NOT bridge the previous store subject into\n // `nextSubject`. `store.subject` is nulled the moment a run fully tears down\n // (identity guard in `finalizeRun`), so the previous subject is non-null\n // ONLY when this run is superseding a prior run that is still in flight or\n // finalizing. Forwarding that dying run's subject would replay its buffered\n // RUN_STARTED and push its terminal event (RUN_FINISHED/RUN_ERROR) into THIS\n // live run's stream — an invalid AG-UI sequence on a healthy run. A\n // superseded run's stream must stay isolated: it reaches only its own\n // connect() subscribers via its own (now-detached) subject, never the\n // superseding run's.\n\n // Start the agent execution immediately (not lazily)\n runAgent();\n\n // Return the run subject (only agent events, no injected messages)\n return runSubject.asObservable();\n }\n\n connect(request: AgentRunnerConnectRequest): Observable<BaseEvent> {\n const store = sharedStore.get(request.threadId, { touch: true });\n const connectionSubject = new ReplaySubject<BaseEvent>(Infinity);\n\n if (!store) {\n // No store means no events\n connectionSubject.complete();\n return connectionSubject.asObservable();\n }\n\n // Collect all historic events from memory\n const allHistoricEvents: BaseEvent[] = [];\n for (const run of store.historicRuns) {\n allHistoricEvents.push(...run.events);\n }\n\n // Apply compaction to all historic events together (like SQLite)\n const compactedEvents = compactEvents(allHistoricEvents);\n\n // Emit compacted events and track message IDs\n const emittedMessageIds = new Set<string>();\n for (const event of compactedEvents) {\n connectionSubject.next(event);\n if (\"messageId\" in event && typeof event.messageId === \"string\") {\n emittedMessageIds.add(event.messageId);\n }\n }\n\n // Bridge active run to connection if exists\n if (store.subject && (store.isRunning || store.stopRequested)) {\n store.subject.subscribe({\n next: (event) => {\n // Skip message events that we've already emitted from historic\n if (\n \"messageId\" in event &&\n typeof event.messageId === \"string\" &&\n emittedMessageIds.has(event.messageId)\n ) {\n return;\n }\n connectionSubject.next(event);\n },\n complete: () => connectionSubject.complete(),\n error: (err) => connectionSubject.error(err),\n });\n } else {\n // No active run, complete after historic events\n connectionSubject.complete();\n }\n\n return connectionSubject.asObservable();\n }\n\n isRunning(request: AgentRunnerIsRunningRequest): Promise<boolean> {\n const store = sharedStore.peek(request.threadId);\n return Promise.resolve(store?.isRunning ?? false);\n }\n\n stop(request: AgentRunnerStopRequest): Promise<boolean | undefined> {\n const store = sharedStore.peek(request.threadId);\n if (!store || !store.isRunning) {\n return Promise.resolve(false);\n }\n if (request.runId !== undefined && store.currentRunId !== request.runId) {\n return Promise.resolve(false);\n }\n if (store.stopRequested) {\n return Promise.resolve(false);\n }\n\n store.stopRequested = true;\n store.isRunning = false;\n // Record the stop on the running run's OWN finalize control so its async\n // teardown finalizes as a clean RUN_FINISHED. This is the same object that\n // run's closure reads, so a later run cannot mislabel this stop.\n const finalizeControl = store.activeFinalize;\n if (finalizeControl) {\n finalizeControl.stopRequested = true;\n }\n\n const agent = store.agent;\n if (!agent) {\n store.stopRequested = false;\n store.isRunning = false;\n if (finalizeControl) {\n finalizeControl.stopRequested = false;\n }\n return Promise.resolve(false);\n }\n\n try {\n agent.abortRun();\n return Promise.resolve(true);\n } catch (error) {\n console.error(\"Failed to abort agent run\", error);\n store.stopRequested = false;\n store.isRunning = true;\n if (finalizeControl) {\n finalizeControl.stopRequested = false;\n }\n return Promise.resolve(false);\n }\n }\n\n /**\n * Returns a summary of every thread that has been run through this runner.\n *\n * This powers the local-dev fallback for `GET /threads` when the Intelligence\n * platform is not configured. Each entry mirrors the shape of a platform\n * `ThreadRecord` so the HTTP handler can use the same response envelope.\n */\n listThreads(): InMemoryThread[] {\n return sharedStore.listThreads();\n }\n\n /**\n * Returns all messages for a thread, using the snapshot captured at the end\n * of the most recent run.\n *\n * This powers the local-dev fallback for `GET /threads/:threadId/messages`\n * when CopilotKit Intelligence is not configured. The returned `Message[]`\n * objects come directly from the ag-ui agent, so their shape is compatible\n * with CopilotKit Intelligence's `ThreadMessage` type.\n */\n getThreadMessages(threadId: string): Message[] {\n const store = sharedStore.peek(threadId);\n if (!store) return [];\n // The thread's latest non-empty snapshot is held at the store level,\n // independent of `historicRuns` lifecycle, so run-cap eviction and\n // interleaved empty-snapshot runs can never lose it. Return a SHALLOW\n // (array-level) copy: a fresh array so a caller mutating array STRUCTURE\n // (push/splice/reassign elements) cannot affect the stored snapshot. We\n // deliberately do NOT deep-copy: `structuredClone` throws DataCloneError on a\n // non-cloneable message field, which would wedge the thread and hang SSE —\n // inconsistent with `ɵestimateBytes`, which tolerates the same bad-payload class.\n // The tradeoff is that the inner `Message` objects remain shared by reference with\n // the stored snapshot, so mutating a returned message's FIELD\n // (e.g. `getThreadMessages(t)[0].content = \"x\"`) is NOT isolated and would corrupt\n // the stored snapshot. That inner-object isolation is a known limitation tracked as\n // follow-up; callers must treat returned messages as read-only.\n return [...store.messagesSnapshot];\n }\n\n /**\n * Returns all AG-UI events for a thread, compacted across historic runs.\n *\n * Powers the local-dev fallback for `GET /threads/:threadId/events` when the\n * CopilotKit Intelligence is not configured. The compaction logic matches\n * the connection-replay path in {@link connect}, so the stream a\n * late-joining inspector sees matches what this method returns.\n */\n getThreadEvents(threadId: string): BaseEvent[] {\n const store = sharedStore.peek(threadId);\n if (!store || store.historicRuns.length === 0) return [];\n const all: BaseEvent[] = [];\n for (const run of store.historicRuns) all.push(...run.events);\n return compactEvents(all);\n }\n\n /**\n * Returns the agent state snapshot for a thread.\n *\n * Derived from the last `STATE_SNAPSHOT` in the compacted event stream. The\n * AG-UI `compactEvents` helper consolidates STATE_DELTA events and produces\n * a single trailing STATE_SNAPSHOT when state changes exist, so this is a\n * faithful view of state at the end of the most recent run.\n *\n * Returns `null` when the thread has never emitted a STATE_SNAPSHOT.\n */\n getThreadState(threadId: string): Record<string, unknown> | null {\n const events = this.getThreadEvents(threadId);\n // Walk backwards — the last snapshot wins.\n for (let i = events.length - 1; i >= 0; i--) {\n const event = events[i]!;\n if (event.type === EventType.STATE_SNAPSHOT) {\n const snapshot = (event as StateSnapshotEvent).snapshot;\n // Only plain objects satisfy the Record<string, unknown> contract.\n // `typeof [] === \"object\"` is true, so arrays must be rejected\n // explicitly to avoid returning an array typed as a Record.\n if (\n snapshot &&\n typeof snapshot === \"object\" &&\n !Array.isArray(snapshot)\n ) {\n // Return a defensive shallow copy so callers can't mutate the\n // snapshot object held inside the stored event (matches the\n // getThreadMessages defensive-copy approach).\n return { ...(snapshot as Record<string, unknown>) };\n }\n return null;\n }\n }\n return null;\n }\n\n /**\n * Clears all in-memory thread history.\n *\n * Powers the local-dev fallback for `POST /threads/clear`, letting consumers\n * (e.g. the demo's Clear button) reset to an empty thread list without\n * restarting the runtime. Intentionally not exposed on the Intelligence\n * platform path: there, thread history lives in a real database and must\n * not be wiped this way.\n */\n clearThreads(): void {\n sharedStore.clear();\n }\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import "reflect-metadata";
2
2
  import { __toESM } from "../../../_virtual/_rolldown/runtime.mjs";
3
- import { require_package } from "../../../runtime/package.mjs";
3
+ import { require_package } from "../../../package.mjs";
4
4
  import { lambdaClient, parseAndWarnTelemetryId } from "@copilotkit/shared";
5
5
 
6
6
  //#region src/v2/runtime/telemetry/telemetry-client.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@copilotkit/runtime",
3
- "version": "1.69.0",
3
+ "version": "1.69.1",
4
4
  "private": false,
5
5
  "keywords": [
6
6
  "ai",
@@ -84,6 +84,8 @@
84
84
  "@remix-run/node-fetch-server": "^0.13.0",
85
85
  "@scarf/scarf": "^1.3.0",
86
86
  "@segment/analytics-node": "^2.1.2",
87
+ "@types/cors": "^2.8.17",
88
+ "@types/express": "^4.17.21",
87
89
  "ai": "^6.0.104",
88
90
  "clarinet": "^0.12.4",
89
91
  "class-transformer": "^0.5.1",
@@ -107,14 +109,12 @@
107
109
  "zod": "^3.23.3",
108
110
  "@copilotkit/channels-intelligence": "0.9.0",
109
111
  "@copilotkit/channels-core": "^0.9.0",
110
- "@copilotkit/shared": "1.69.0"
112
+ "@copilotkit/shared": "1.69.1"
111
113
  },
112
114
  "devDependencies": {
113
115
  "@copilotkit/aimock": "latest",
114
116
  "@swc/core": "1.5.28",
115
117
  "@tanstack/intent": "^0.0.29",
116
- "@types/cors": "^2.8.17",
117
- "@types/express": "^4.17.21",
118
118
  "@types/node": "^18.11.17",
119
119
  "@types/phoenix": "^1.6.6",
120
120
  "@valibot/to-json-schema": "^1.5.0",
@@ -185,7 +185,7 @@
185
185
  }
186
186
  },
187
187
  "scripts": {
188
- "build": "tsdown",
188
+ "build": "tsdown && node ../../scripts/deprecations/v1-dist-notices.mjs --entrypoint runtime,runtime-langgraph",
189
189
  "dev": "tsdown --watch",
190
190
  "test": "vitest run",
191
191
  "test:watch": "vitest",
@@ -193,7 +193,7 @@
193
193
  "generate-graphql-schema": "node -e \"const fs=require('fs');fs.rmSync('__snapshots__',{recursive:true,force:true})\" && ts-node --transpile-only ./scripts/generate-gql-schema.ts",
194
194
  "link:global": "pnpm link --global",
195
195
  "unlink:global": "pnpm unlink --global",
196
- "check-dts": "tsx ../../scripts/validate-dts-ambient.ts dist",
196
+ "check-dts": "tsx ../../scripts/validate-dts-ambient.ts dist && tsx ../../scripts/validate-dts-imports.ts dist",
197
197
  "publint": "publint .",
198
198
  "attw": "attw --pack . --profile node16"
199
199
  }
@@ -11,7 +11,7 @@ description: >
11
11
  discouraged. Load the reference under references/ that matches your task.
12
12
  type: core
13
13
  library: copilotkit
14
- library_version: "1.69.0"
14
+ library_version: "1.69.1"
15
15
  requires: []
16
16
  sources:
17
17
  - "CopilotKit/CopilotKit:packages/runtime/src/v2/runtime/core/fetch-handler.ts"
@@ -152,7 +152,7 @@ export class RedisAgentRunner extends AgentRunner {
152
152
  - `connect()` must replay historic events so late clients can catch up on an active run.
153
153
  - `stop()` is optional to implement in the sense that returning `undefined` is allowed, but
154
154
  surface cancellations through `abortController.abort()` to the underlying agent if you can.
155
- - The runner does not persist user messages on its own — that is the Intelligence platform's
155
+ - The runner does not persist user messages on its own — that is CopilotKit Intelligence's
156
156
  job. A custom runner that persists only its own event stream is still a drop-in replacement
157
157
  for `InMemoryAgentRunner` / `SqliteAgentRunner`.
158
158
 
@@ -89,7 +89,7 @@ throwing — the superseded run's partial output is discarded rather than persis
89
89
  to history. `SqliteAgentRunner` has no such option and always throws. When the
90
90
  throw does happen, how it surfaces to the client depends on the runtime mode:
91
91
 
92
- - **Intelligence mode** — the Intelligence platform returns HTTP `409` when a lock is
92
+ - **Intelligence mode** — CopilotKit Intelligence returns HTTP `409` when a lock is
93
93
  held. The client core maps this to `CopilotKitCoreErrorCode.AGENT_THREAD_LOCKED`
94
94
  and fires `onError({ code: "agent_thread_locked", ... })`. Handle this in
95
95
  `<CopilotKit onError>` (the `CopilotKit` provider from `@copilotkit/react-core/v2`).
@@ -183,16 +183,22 @@ Correct:
183
183
  new CopilotRuntime({
184
184
  agents,
185
185
  intelligence,
186
- identifyUser: (req) => ({ id: req.headers.get("x-user-id")! }),
186
+ identifyUser: (req) => ({
187
+ id: req.headers.get("x-user-id")!,
188
+ name: req.headers.get("x-user-name") ?? "Anonymous",
189
+ }),
187
190
  });
188
191
  ```
189
192
 
190
193
  `CopilotIntelligenceRuntimeOptions` does not declare a `runner` field — Intelligence mode
191
194
  auto-wires `IntelligenceAgentRunner` pointed at the Intelligence service socket. Excess-property checks will
192
- flag a `runner:` key on an Intelligence-shaped options object as a type error, and at runtime
193
- the auto-wired Intelligence runner wins regardless of what you pass.
195
+ flag a `runner:` key on an Intelligence-shaped options object as a type error, and a caller who
196
+ evades that check (JS, `as any`, or a non-literal options object) gets a `throw` at construction
197
+ rather than a silently ignored runner.
194
198
 
195
- Source: `packages/runtime/src/v2/runtime/core/runtime.ts:149-173,285-294`.
199
+ Source: `packages/runtime/src/v2/runtime/core/runtime.ts` — `runner?` is declared only on
200
+ `CopilotSseRuntimeOptions` (:239); the Intelligence constructor guard is at :512 and the
201
+ auto-wired runner at :582.
196
202
 
197
203
  ### HIGH Forgetting the better-sqlite3 peer
198
204
 
@@ -57,7 +57,7 @@ import {
57
57
  } from "@copilotkit/runtime/v2";
58
58
 
59
59
  const intelligence = new CopilotKitIntelligence({
60
- // apiUrl / wsUrl default to the managed Intelligence platform — leave them unset.
60
+ // apiUrl / wsUrl default to cloud-hosted CopilotKit Intelligence — leave them unset.
61
61
  apiKey: process.env.INTELLIGENCE_API_KEY!,
62
62
  });
63
63
 
@@ -1,10 +0,0 @@
1
-
2
- import { __exportAll, __reExport } from "../../_virtual/_rolldown/runtime.cjs";
3
- export * from "@copilotkit/channels-core";
4
-
5
- //#region ../channels/dist/index.d.ts
6
-
7
- import * as import__copilotkit_channels_core from "@copilotkit/channels-core";
8
- //#endregion
9
- export { import__copilotkit_channels_core as index_d_exports };
10
- //# sourceMappingURL=index.d.cts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../../../../channels/dist/index.d.ts"],"mappings":""}
@@ -1,10 +0,0 @@
1
-
2
- import { __exportAll, __reExport } from "../../_virtual/_rolldown/runtime.mjs";
3
- export * from "@copilotkit/channels-core";
4
-
5
- //#region ../channels/dist/index.d.ts
6
-
7
- import * as import__copilotkit_channels_core from "@copilotkit/channels-core";
8
- //#endregion
9
- export { import__copilotkit_channels_core as index_d_exports };
10
- //# sourceMappingURL=index.d.mts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../../../channels/dist/index.d.ts"],"mappings":""}
@@ -1 +0,0 @@
1
- {"version":3,"file":"package.mjs","names":[],"sources":["../../package.json"],"sourcesContent":[""],"mappings":""}