@copilotkit/runtime 1.57.3 → 1.58.0-canary.thread-id-propagation

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 (346) hide show
  1. package/dist/lib/observability.d.cts +1 -1
  2. package/dist/lib/observability.d.cts.map +1 -1
  3. package/dist/lib/observability.d.mts +1 -1
  4. package/dist/lib/observability.d.mts.map +1 -1
  5. package/dist/lib/runtime/copilot-runtime.cjs +2 -0
  6. package/dist/lib/runtime/copilot-runtime.cjs.map +1 -1
  7. package/dist/lib/runtime/copilot-runtime.d.cts.map +1 -1
  8. package/dist/lib/runtime/copilot-runtime.d.mts.map +1 -1
  9. package/dist/lib/runtime/copilot-runtime.mjs +2 -0
  10. package/dist/lib/runtime/copilot-runtime.mjs.map +1 -1
  11. package/dist/package.cjs +5 -8
  12. package/dist/package.mjs +5 -8
  13. package/dist/v2/runtime/core/runtime.cjs +4 -1
  14. package/dist/v2/runtime/core/runtime.cjs.map +1 -1
  15. package/dist/v2/runtime/core/runtime.d.cts.map +1 -1
  16. package/dist/v2/runtime/core/runtime.d.mts.map +1 -1
  17. package/dist/v2/runtime/core/runtime.mjs +4 -1
  18. package/dist/v2/runtime/core/runtime.mjs.map +1 -1
  19. package/dist/v2/runtime/handlers/get-runtime-info.cjs +1 -1
  20. package/dist/v2/runtime/handlers/get-runtime-info.mjs +1 -1
  21. package/dist/v2/runtime/handlers/handle-connect.cjs +1 -1
  22. package/dist/v2/runtime/handlers/handle-connect.mjs +1 -1
  23. package/dist/v2/runtime/handlers/handle-run.cjs +1 -1
  24. package/dist/v2/runtime/handlers/handle-run.mjs +1 -1
  25. package/dist/v2/runtime/handlers/shared/agent-utils.cjs +1 -1
  26. package/dist/v2/runtime/handlers/shared/agent-utils.cjs.map +1 -1
  27. package/dist/v2/runtime/handlers/shared/agent-utils.mjs +1 -1
  28. package/dist/v2/runtime/handlers/shared/agent-utils.mjs.map +1 -1
  29. package/dist/v2/runtime/telemetry/telemetry-client.cjs +22 -6
  30. package/dist/v2/runtime/telemetry/telemetry-client.cjs.map +1 -1
  31. package/dist/v2/runtime/telemetry/telemetry-client.mjs +27 -11
  32. package/dist/v2/runtime/telemetry/telemetry-client.mjs.map +1 -1
  33. package/package.json +9 -19
  34. package/skills/runtime/SKILL.md +98 -0
  35. package/skills/runtime/references/agent-runners-custom.md +161 -0
  36. package/skills/runtime/references/agent-runners-in-memory.md +64 -0
  37. package/skills/runtime/references/agent-runners-sqlite.md +90 -0
  38. package/skills/runtime/references/agent-runners.md +304 -0
  39. package/skills/runtime/references/built-in-agent-factory-modes.md +232 -0
  40. package/skills/runtime/references/built-in-agent-helper-utilities.md +123 -0
  41. package/skills/runtime/references/built-in-agent-model-identifiers.md +59 -0
  42. package/skills/runtime/references/built-in-agent.md +523 -0
  43. package/skills/runtime/references/intelligence-mode.md +336 -0
  44. package/skills/runtime/references/middleware.md +376 -0
  45. package/skills/runtime/references/server-side-tools.md +414 -0
  46. package/skills/runtime/references/setup-endpoint.md +503 -0
  47. package/skills/runtime/references/transcription.md +287 -0
  48. package/skills/runtime/references/wiring-a2a.md +40 -0
  49. package/skills/runtime/references/wiring-adk.md +45 -0
  50. package/skills/runtime/references/wiring-ag2.md +41 -0
  51. package/skills/runtime/references/wiring-agno.md +39 -0
  52. package/skills/runtime/references/wiring-aws-strands.md +59 -0
  53. package/skills/runtime/references/wiring-crewai-crews.md +51 -0
  54. package/skills/runtime/references/wiring-crewai-flows.md +45 -0
  55. package/skills/runtime/references/wiring-external-agents.md +348 -0
  56. package/skills/runtime/references/wiring-langgraph.md +50 -0
  57. package/skills/runtime/references/wiring-llamaindex.md +39 -0
  58. package/skills/runtime/references/wiring-mastra.md +70 -0
  59. package/skills/runtime/references/wiring-mcp-apps-middleware.md +68 -0
  60. package/skills/runtime/references/wiring-ms-agent-framework.md +41 -0
  61. package/skills/runtime/references/wiring-pydantic-ai.md +45 -0
  62. package/CHANGELOG.md +0 -3624
  63. package/__snapshots__/schema/schema.graphql +0 -371
  64. package/dist/v2/runtime/telemetry/scarf-client.cjs +0 -32
  65. package/dist/v2/runtime/telemetry/scarf-client.cjs.map +0 -1
  66. package/dist/v2/runtime/telemetry/scarf-client.mjs +0 -32
  67. package/dist/v2/runtime/telemetry/scarf-client.mjs.map +0 -1
  68. package/scripts/generate-gql-schema.ts +0 -16
  69. package/src/agent/__tests__/agent-test-helpers.ts +0 -476
  70. package/src/agent/__tests__/agent.test.ts +0 -593
  71. package/src/agent/__tests__/ai-sdk-v6-compat.test.ts +0 -116
  72. package/src/agent/__tests__/basic-agent.test.ts +0 -1698
  73. package/src/agent/__tests__/capabilities.test.ts +0 -81
  74. package/src/agent/__tests__/config-tools-execution.test.ts +0 -516
  75. package/src/agent/__tests__/converter-aisdk.test.ts +0 -692
  76. package/src/agent/__tests__/converter-custom.test.ts +0 -319
  77. package/src/agent/__tests__/converter-tanstack-input.test.ts +0 -211
  78. package/src/agent/__tests__/converter-tanstack.test.ts +0 -594
  79. package/src/agent/__tests__/mcp-clients.test.ts +0 -246
  80. package/src/agent/__tests__/mcp-servers-integration.test.ts +0 -373
  81. package/src/agent/__tests__/multimodal-tanstack.test.ts +0 -284
  82. package/src/agent/__tests__/multimodal.test.ts +0 -176
  83. package/src/agent/__tests__/property-overrides.test.ts +0 -598
  84. package/src/agent/__tests__/provider-id-collision.test.ts +0 -195
  85. package/src/agent/__tests__/standard-schema-tools.test.ts +0 -313
  86. package/src/agent/__tests__/standard-schema-types.test.ts +0 -158
  87. package/src/agent/__tests__/state-tools.test.ts +0 -436
  88. package/src/agent/__tests__/test-helpers.ts +0 -197
  89. package/src/agent/__tests__/utils.test.ts +0 -536
  90. package/src/agent/__tests__/zod-regression.test.ts +0 -350
  91. package/src/agent/converters/aisdk.ts +0 -326
  92. package/src/agent/converters/index.ts +0 -7
  93. package/src/agent/converters/tanstack.ts +0 -451
  94. package/src/agent/index.ts +0 -1743
  95. package/src/agents/langgraph/__tests__/event-source.test.ts +0 -256
  96. package/src/agents/langgraph/event-source.ts +0 -365
  97. package/src/agents/langgraph/events.ts +0 -394
  98. package/src/graphql/inputs/action.input.ts +0 -16
  99. package/src/graphql/inputs/agent-session.input.ts +0 -13
  100. package/src/graphql/inputs/agent-state.input.ts +0 -13
  101. package/src/graphql/inputs/cloud-guardrails.input.ts +0 -16
  102. package/src/graphql/inputs/cloud.input.ts +0 -8
  103. package/src/graphql/inputs/context-property.input.ts +0 -10
  104. package/src/graphql/inputs/copilot-context.input.ts +0 -10
  105. package/src/graphql/inputs/custom-property.input.ts +0 -15
  106. package/src/graphql/inputs/extensions.input.ts +0 -21
  107. package/src/graphql/inputs/forwarded-parameters.input.ts +0 -22
  108. package/src/graphql/inputs/frontend.input.ts +0 -14
  109. package/src/graphql/inputs/generate-copilot-response.input.ts +0 -59
  110. package/src/graphql/inputs/load-agent-state.input.ts +0 -10
  111. package/src/graphql/inputs/message.input.ts +0 -110
  112. package/src/graphql/inputs/meta-event.input.ts +0 -18
  113. package/src/graphql/message-conversion/agui-to-gql.test.ts +0 -1384
  114. package/src/graphql/message-conversion/agui-to-gql.ts +0 -384
  115. package/src/graphql/message-conversion/gql-to-agui.test.ts +0 -1653
  116. package/src/graphql/message-conversion/gql-to-agui.ts +0 -297
  117. package/src/graphql/message-conversion/index.ts +0 -2
  118. package/src/graphql/message-conversion/roundtrip-conversion.test.ts +0 -561
  119. package/src/graphql/resolvers/__tests__/resolve-message-id.test.ts +0 -25
  120. package/src/graphql/resolvers/copilot.resolver.ts +0 -785
  121. package/src/graphql/resolvers/resolve-message-id.ts +0 -14
  122. package/src/graphql/resolvers/state.resolver.ts +0 -30
  123. package/src/graphql/types/agents-response.type.ts +0 -19
  124. package/src/graphql/types/base/index.ts +0 -10
  125. package/src/graphql/types/converted/index.ts +0 -183
  126. package/src/graphql/types/copilot-response.type.ts +0 -141
  127. package/src/graphql/types/enums.ts +0 -38
  128. package/src/graphql/types/extensions-response.type.ts +0 -23
  129. package/src/graphql/types/guardrails-result.type.ts +0 -20
  130. package/src/graphql/types/load-agent-state-response.type.ts +0 -17
  131. package/src/graphql/types/message-status.type.ts +0 -48
  132. package/src/graphql/types/meta-events.type.ts +0 -78
  133. package/src/graphql/types/response-status.type.ts +0 -77
  134. package/src/index.ts +0 -3
  135. package/src/langgraph.ts +0 -1
  136. package/src/lib/__tests__/telemetry-disclosure.test.ts +0 -55
  137. package/src/lib/cloud/index.ts +0 -4
  138. package/src/lib/error-messages.ts +0 -211
  139. package/src/lib/index.ts +0 -52
  140. package/src/lib/integrations/index.ts +0 -6
  141. package/src/lib/integrations/nest/index.ts +0 -21
  142. package/src/lib/integrations/nextjs/app-router.ts +0 -47
  143. package/src/lib/integrations/nextjs/pages-router.ts +0 -45
  144. package/src/lib/integrations/node-express/index.ts +0 -21
  145. package/src/lib/integrations/node-http/__tests__/request-duck-type.test.ts +0 -66
  146. package/src/lib/integrations/node-http/index.ts +0 -187
  147. package/src/lib/integrations/node-http/request-handler.ts +0 -128
  148. package/src/lib/integrations/shared.ts +0 -112
  149. package/src/lib/logger.ts +0 -31
  150. package/src/lib/observability.ts +0 -167
  151. package/src/lib/runtime/__tests__/copilot-runtime-error.test.ts +0 -183
  152. package/src/lib/runtime/__tests__/handle-service-adapter.test.ts +0 -108
  153. package/src/lib/runtime/__tests__/mcp-tools-utils.test.ts +0 -499
  154. package/src/lib/runtime/__tests__/on-after-request.test.ts +0 -122
  155. package/src/lib/runtime/__tests__/retry-utils.test.ts +0 -137
  156. package/src/lib/runtime/__tests__/v1-agent-factory.test.ts +0 -109
  157. package/src/lib/runtime/agent-integrations/langgraph/__tests__/dispatch-event-filtering.test.ts +0 -345
  158. package/src/lib/runtime/agent-integrations/langgraph/__tests__/run-message-filtering.test.ts +0 -156
  159. package/src/lib/runtime/agent-integrations/langgraph/agent.ts +0 -263
  160. package/src/lib/runtime/agent-integrations/langgraph/consts.ts +0 -37
  161. package/src/lib/runtime/agent-integrations/langgraph/index.ts +0 -2
  162. package/src/lib/runtime/copilot-runtime.ts +0 -863
  163. package/src/lib/runtime/mcp-tools-utils.ts +0 -313
  164. package/src/lib/runtime/retry-utils.ts +0 -141
  165. package/src/lib/runtime/telemetry-agent-runner.ts +0 -151
  166. package/src/lib/runtime/types.ts +0 -48
  167. package/src/lib/runtime/utils.ts +0 -93
  168. package/src/lib/streaming.ts +0 -220
  169. package/src/lib/telemetry-client.ts +0 -66
  170. package/src/lib/telemetry-disclosure.ts +0 -53
  171. package/src/service-adapters/anthropic/anthropic-adapter.ts +0 -532
  172. package/src/service-adapters/anthropic/utils.ts +0 -219
  173. package/src/service-adapters/bedrock/bedrock-adapter.ts +0 -73
  174. package/src/service-adapters/conversion.test.ts +0 -56
  175. package/src/service-adapters/conversion.ts +0 -69
  176. package/src/service-adapters/empty/empty-adapter.ts +0 -38
  177. package/src/service-adapters/events.ts +0 -337
  178. package/src/service-adapters/experimental/ollama/ollama-adapter.ts +0 -84
  179. package/src/service-adapters/google/google-genai-adapter.test.ts +0 -151
  180. package/src/service-adapters/google/google-genai-adapter.ts +0 -95
  181. package/src/service-adapters/groq/groq-adapter.ts +0 -229
  182. package/src/service-adapters/index.ts +0 -18
  183. package/src/service-adapters/langchain/langchain-adapter.ts +0 -113
  184. package/src/service-adapters/langchain/langserve.ts +0 -88
  185. package/src/service-adapters/langchain/types.ts +0 -20
  186. package/src/service-adapters/langchain/utils.ts +0 -330
  187. package/src/service-adapters/openai/__tests__/openai-v5-compat.test.ts +0 -177
  188. package/src/service-adapters/openai/openai-adapter.ts +0 -324
  189. package/src/service-adapters/openai/openai-assistant-adapter.ts +0 -385
  190. package/src/service-adapters/openai/utils.ts +0 -305
  191. package/src/service-adapters/service-adapter.ts +0 -50
  192. package/src/service-adapters/shared/error-utils.ts +0 -64
  193. package/src/service-adapters/shared/index.ts +0 -2
  194. package/src/service-adapters/shared/sdk-client-utils.ts +0 -19
  195. package/src/service-adapters/unify/unify-adapter.ts +0 -165
  196. package/src/utils/failed-response-status-reasons.ts +0 -70
  197. package/src/utils/index.ts +0 -1
  198. package/src/v2/express.ts +0 -1
  199. package/src/v2/hono.ts +0 -1
  200. package/src/v2/index.ts +0 -5
  201. package/src/v2/node.ts +0 -1
  202. package/src/v2/runtime/__tests__/agents-factory.test.ts +0 -136
  203. package/src/v2/runtime/__tests__/backward-compat.test.ts +0 -261
  204. package/src/v2/runtime/__tests__/code-review-fixes.test.ts +0 -500
  205. package/src/v2/runtime/__tests__/cors-credentials.test.ts +0 -320
  206. package/src/v2/runtime/__tests__/debug-sse-response.test.ts +0 -302
  207. package/src/v2/runtime/__tests__/express-adapter.test.ts +0 -188
  208. package/src/v2/runtime/__tests__/express-body-order.test.ts +0 -76
  209. package/src/v2/runtime/__tests__/express-fetch-bridge.test.ts +0 -344
  210. package/src/v2/runtime/__tests__/express-single-sse.test.ts +0 -122
  211. package/src/v2/runtime/__tests__/express-single-telemetry.integration.test.ts +0 -65
  212. package/src/v2/runtime/__tests__/express-telemetry.integration.test.ts +0 -101
  213. package/src/v2/runtime/__tests__/fetch-cors.test.ts +0 -205
  214. package/src/v2/runtime/__tests__/fetch-handler-validation.test.ts +0 -440
  215. package/src/v2/runtime/__tests__/fetch-handler.test.ts +0 -456
  216. package/src/v2/runtime/__tests__/fetch-router.test.ts +0 -276
  217. package/src/v2/runtime/__tests__/get-runtime-info.test.ts +0 -335
  218. package/src/v2/runtime/__tests__/handle-connect.test.ts +0 -585
  219. package/src/v2/runtime/__tests__/handle-run.test.ts +0 -1388
  220. package/src/v2/runtime/__tests__/handle-threads.test.ts +0 -930
  221. package/src/v2/runtime/__tests__/handle-transcribe.test.ts +0 -301
  222. package/src/v2/runtime/__tests__/header-utils.test.ts +0 -88
  223. package/src/v2/runtime/__tests__/hono-adapter.test.ts +0 -150
  224. package/src/v2/runtime/__tests__/hono-single-telemetry.integration.test.ts +0 -46
  225. package/src/v2/runtime/__tests__/hono-telemetry.integration.test.ts +0 -99
  226. package/src/v2/runtime/__tests__/hooks-edge-cases.test.ts +0 -457
  227. package/src/v2/runtime/__tests__/hooks.test.ts +0 -557
  228. package/src/v2/runtime/__tests__/in-process-agent-runner-messages.test.ts +0 -230
  229. package/src/v2/runtime/__tests__/in-process-agent-runner.test.ts +0 -1030
  230. package/src/v2/runtime/__tests__/integration/bun/bun-servers.integration.test.ts +0 -27
  231. package/src/v2/runtime/__tests__/integration/bun/elysia-multi.ts +0 -32
  232. package/src/v2/runtime/__tests__/integration/bun/elysia-single.ts +0 -33
  233. package/src/v2/runtime/__tests__/integration/bun/hono-bun-multi.ts +0 -25
  234. package/src/v2/runtime/__tests__/integration/bun/hono-bun-single.ts +0 -32
  235. package/src/v2/runtime/__tests__/integration/helpers/create-test-runtime.ts +0 -15
  236. package/src/v2/runtime/__tests__/integration/helpers/sse-reader.ts +0 -45
  237. package/src/v2/runtime/__tests__/integration/helpers/test-agent.ts +0 -58
  238. package/src/v2/runtime/__tests__/integration/node-servers.integration.test.ts +0 -58
  239. package/src/v2/runtime/__tests__/integration/servers/express-multi.ts +0 -35
  240. package/src/v2/runtime/__tests__/integration/servers/express-single.ts +0 -36
  241. package/src/v2/runtime/__tests__/integration/servers/fetch-direct.ts +0 -39
  242. package/src/v2/runtime/__tests__/integration/servers/hono-multi.ts +0 -30
  243. package/src/v2/runtime/__tests__/integration/servers/hono-single.ts +0 -37
  244. package/src/v2/runtime/__tests__/integration/servers/node-multi.ts +0 -45
  245. package/src/v2/runtime/__tests__/integration/servers/node-single.ts +0 -46
  246. package/src/v2/runtime/__tests__/integration/servers/types.ts +0 -18
  247. package/src/v2/runtime/__tests__/integration/suites/debug-events.suite.ts +0 -253
  248. package/src/v2/runtime/__tests__/integration/suites/multi-endpoint.suite.ts +0 -358
  249. package/src/v2/runtime/__tests__/integration/suites/single-endpoint.suite.ts +0 -363
  250. package/src/v2/runtime/__tests__/intelligence-run-telemetry.test.ts +0 -194
  251. package/src/v2/runtime/__tests__/mcp-apps-middleware-integration.test.ts +0 -275
  252. package/src/v2/runtime/__tests__/middleware-express.test.ts +0 -208
  253. package/src/v2/runtime/__tests__/middleware-single-express.test.ts +0 -213
  254. package/src/v2/runtime/__tests__/middleware-single.test.ts +0 -225
  255. package/src/v2/runtime/__tests__/middleware-sse-parser.test.ts +0 -237
  256. package/src/v2/runtime/__tests__/middleware.test.ts +0 -250
  257. package/src/v2/runtime/__tests__/node-fetch-handler.test.ts +0 -157
  258. package/src/v2/runtime/__tests__/open-generative-ui-middleware.e2e.test.ts +0 -728
  259. package/src/v2/runtime/__tests__/router-edge-cases.test.ts +0 -217
  260. package/src/v2/runtime/__tests__/routing-express.test.ts +0 -174
  261. package/src/v2/runtime/__tests__/routing-single-express.test.ts +0 -168
  262. package/src/v2/runtime/__tests__/routing-single.test.ts +0 -193
  263. package/src/v2/runtime/__tests__/routing.test.ts +0 -257
  264. package/src/v2/runtime/__tests__/runtime.test.ts +0 -234
  265. package/src/v2/runtime/__tests__/sse-response-telemetry.test.ts +0 -108
  266. package/src/v2/runtime/__tests__/telemetry.test.ts +0 -167
  267. package/src/v2/runtime/__tests__/thread-names.test.ts +0 -188
  268. package/src/v2/runtime/core/__tests__/debug-event-bus.test.ts +0 -156
  269. package/src/v2/runtime/core/debug-event-bus.ts +0 -45
  270. package/src/v2/runtime/core/fetch-cors.ts +0 -136
  271. package/src/v2/runtime/core/fetch-handler.ts +0 -492
  272. package/src/v2/runtime/core/fetch-router.ts +0 -203
  273. package/src/v2/runtime/core/hooks.ts +0 -160
  274. package/src/v2/runtime/core/middleware-sse-parser.ts +0 -210
  275. package/src/v2/runtime/core/middleware.ts +0 -115
  276. package/src/v2/runtime/core/runtime.ts +0 -432
  277. package/src/v2/runtime/endpoints/express-fetch-bridge.ts +0 -137
  278. package/src/v2/runtime/endpoints/express-single.ts +0 -54
  279. package/src/v2/runtime/endpoints/express.ts +0 -179
  280. package/src/v2/runtime/endpoints/hono-single.ts +0 -60
  281. package/src/v2/runtime/endpoints/hono.ts +0 -89
  282. package/src/v2/runtime/endpoints/index.ts +0 -4
  283. package/src/v2/runtime/endpoints/node-fetch-handler.ts +0 -48
  284. package/src/v2/runtime/endpoints/node.ts +0 -28
  285. package/src/v2/runtime/endpoints/single-route-helpers.ts +0 -125
  286. package/src/v2/runtime/express.ts +0 -2
  287. package/src/v2/runtime/handlers/__tests__/handle-debug-events.test.ts +0 -176
  288. package/src/v2/runtime/handlers/get-runtime-info.ts +0 -101
  289. package/src/v2/runtime/handlers/handle-connect.ts +0 -80
  290. package/src/v2/runtime/handlers/handle-debug-events.ts +0 -52
  291. package/src/v2/runtime/handlers/handle-run.ts +0 -111
  292. package/src/v2/runtime/handlers/handle-stop.ts +0 -77
  293. package/src/v2/runtime/handlers/handle-threads.ts +0 -11
  294. package/src/v2/runtime/handlers/handle-transcribe.ts +0 -269
  295. package/src/v2/runtime/handlers/header-utils.ts +0 -24
  296. package/src/v2/runtime/handlers/intelligence/connect.ts +0 -102
  297. package/src/v2/runtime/handlers/intelligence/run.ts +0 -351
  298. package/src/v2/runtime/handlers/intelligence/thread-names.ts +0 -246
  299. package/src/v2/runtime/handlers/intelligence/threads.ts +0 -420
  300. package/src/v2/runtime/handlers/shared/agent-utils.ts +0 -154
  301. package/src/v2/runtime/handlers/shared/intelligence-utils.ts +0 -41
  302. package/src/v2/runtime/handlers/shared/json-response.ts +0 -9
  303. package/src/v2/runtime/handlers/shared/resolve-intelligence-user.ts +0 -28
  304. package/src/v2/runtime/handlers/shared/sse-response.ts +0 -215
  305. package/src/v2/runtime/handlers/sse/__tests__/sse-connect-agent-id.test.ts +0 -71
  306. package/src/v2/runtime/handlers/sse/connect.ts +0 -30
  307. package/src/v2/runtime/handlers/sse/run.ts +0 -40
  308. package/src/v2/runtime/hono.ts +0 -2
  309. package/src/v2/runtime/index.ts +0 -51
  310. package/src/v2/runtime/intelligence-platform/__tests__/client.test.ts +0 -601
  311. package/src/v2/runtime/intelligence-platform/__tests__/intelligence-mcp-helper.test.ts +0 -246
  312. package/src/v2/runtime/intelligence-platform/client.ts +0 -818
  313. package/src/v2/runtime/intelligence-platform/index.ts +0 -10
  314. package/src/v2/runtime/node.ts +0 -6
  315. package/src/v2/runtime/open-generative-ui-middleware.ts +0 -373
  316. package/src/v2/runtime/runner/__tests__/finalize-events.test.ts +0 -109
  317. package/src/v2/runtime/runner/__tests__/in-memory-runner.e2e.test.ts +0 -775
  318. package/src/v2/runtime/runner/__tests__/in-memory-runner.test.ts +0 -777
  319. package/src/v2/runtime/runner/__tests__/intelligence-runner.test.ts +0 -1039
  320. package/src/v2/runtime/runner/agent-runner.ts +0 -35
  321. package/src/v2/runtime/runner/in-memory.ts +0 -467
  322. package/src/v2/runtime/runner/index.ts +0 -4
  323. package/src/v2/runtime/runner/intelligence.ts +0 -498
  324. package/src/v2/runtime/telemetry/__tests__/instance-created.test.ts +0 -96
  325. package/src/v2/runtime/telemetry/events.ts +0 -35
  326. package/src/v2/runtime/telemetry/index.ts +0 -7
  327. package/src/v2/runtime/telemetry/instance-created.ts +0 -44
  328. package/src/v2/runtime/telemetry/scarf-client.ts +0 -39
  329. package/src/v2/runtime/telemetry/telemetry-client.ts +0 -70
  330. package/src/v2/runtime/transcription-service/transcription-service.ts +0 -11
  331. package/tests/global.d.ts +0 -1
  332. package/tests/service-adapters/anthropic/allowlist-approach.test.ts +0 -259
  333. package/tests/service-adapters/anthropic/anthropic-adapter-language-model.test.ts +0 -101
  334. package/tests/service-adapters/anthropic/anthropic-adapter.test.ts +0 -645
  335. package/tests/service-adapters/anthropic/utils-token-trimming.test.ts +0 -301
  336. package/tests/service-adapters/groq/groq-adapter-language-model.test.ts +0 -102
  337. package/tests/service-adapters/openai/allowlist-approach.test.ts +0 -294
  338. package/tests/service-adapters/openai/openai-adapter-language-model.test.ts +0 -122
  339. package/tests/service-adapters/openai/openai-adapter.test.ts +0 -291
  340. package/tests/service-adapters/shared/sdk-client-utils.test.ts +0 -36
  341. package/tests/setup.vitest.ts +0 -8
  342. package/tests/tsconfig.json +0 -10
  343. package/tsconfig.json +0 -20
  344. package/tsdown.config.ts +0 -45
  345. package/typedoc.json +0 -4
  346. package/vitest.config.mjs +0 -13
@@ -1,301 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import { limitMessagesToTokenCount } from "../../../src/service-adapters/anthropic/utils";
3
-
4
- // Helper to build messages for testing. The token counter is length/3,
5
- // so we can control token counts via string length.
6
-
7
- function textUser(text: string) {
8
- return { role: "user", content: [{ type: "text", text }] };
9
- }
10
-
11
- function textAssistant(text: string) {
12
- return { role: "assistant", content: [{ type: "text", text }] };
13
- }
14
-
15
- function toolUseAssistant(id: string, name = "my_tool", input = {}) {
16
- return {
17
- role: "assistant",
18
- content: [{ type: "tool_use", id, name, input }],
19
- };
20
- }
21
-
22
- function toolResultUser(toolUseId: string, content = "result") {
23
- return {
24
- role: "user",
25
- content: [{ type: "tool_result", tool_use_id: toolUseId, content }],
26
- };
27
- }
28
-
29
- function mixedAssistant(blocks: any[]) {
30
- return { role: "assistant", content: blocks };
31
- }
32
-
33
- function mixedUser(blocks: any[]) {
34
- return { role: "user", content: blocks };
35
- }
36
-
37
- describe("limitMessagesToTokenCount - orphan handling", () => {
38
- // Use a high token limit so trimming doesn't kick in for these tests
39
- const HIGH_LIMIT = 999999;
40
-
41
- it("preserves matched tool_use / tool_result pairs", () => {
42
- const messages = [
43
- textUser("hello"),
44
- toolUseAssistant("t1", "tool_a"),
45
- toolResultUser("t1", "done"),
46
- textAssistant("ok"),
47
- ];
48
-
49
- const result = limitMessagesToTokenCount(
50
- messages,
51
- [],
52
- "claude-3",
53
- HIGH_LIMIT,
54
- );
55
-
56
- // All four messages should survive
57
- expect(result).toHaveLength(4);
58
- // The tool_use and tool_result should still be present
59
- const toolUse = result.find(
60
- (m: any) =>
61
- m.role === "assistant" &&
62
- Array.isArray(m.content) &&
63
- m.content.some((b: any) => b.type === "tool_use"),
64
- );
65
- const toolResult = result.find(
66
- (m: any) =>
67
- m.role === "user" &&
68
- Array.isArray(m.content) &&
69
- m.content.some((b: any) => b.type === "tool_result"),
70
- );
71
- expect(toolUse).toBeDefined();
72
- expect(toolResult).toBeDefined();
73
- });
74
-
75
- it("removes orphaned tool_result when tool_use was trimmed", () => {
76
- // Simulate: tool_use message was removed by token trimming, leaving
77
- // a tool_result without a matching tool_use.
78
- const messages = [
79
- textUser("hello"),
80
- // no toolUseAssistant for "t1"
81
- toolResultUser("t1", "orphaned result"),
82
- textAssistant("ok"),
83
- ];
84
-
85
- const result = limitMessagesToTokenCount(
86
- messages,
87
- [],
88
- "claude-3",
89
- HIGH_LIMIT,
90
- );
91
-
92
- // The orphaned tool_result message should be gone
93
- const hasToolResult = result.some(
94
- (m: any) =>
95
- m.role === "user" &&
96
- Array.isArray(m.content) &&
97
- m.content.some((b: any) => b.type === "tool_result"),
98
- );
99
- expect(hasToolResult).toBe(false);
100
- expect(result).toHaveLength(2); // textUser + textAssistant
101
- });
102
-
103
- it("removes orphaned tool_use when tool_result was trimmed", () => {
104
- // Simulate: tool_result message was removed by token trimming, leaving
105
- // a tool_use without a matching tool_result.
106
- const messages = [
107
- textUser("hello"),
108
- toolUseAssistant("t1", "tool_a"),
109
- // no toolResultUser for "t1"
110
- textAssistant("ok"),
111
- ];
112
-
113
- const result = limitMessagesToTokenCount(
114
- messages,
115
- [],
116
- "claude-3",
117
- HIGH_LIMIT,
118
- );
119
-
120
- // The orphaned tool_use message should be gone
121
- const hasToolUse = result.some(
122
- (m: any) =>
123
- m.role === "assistant" &&
124
- Array.isArray(m.content) &&
125
- m.content.some((b: any) => b.type === "tool_use"),
126
- );
127
- expect(hasToolUse).toBe(false);
128
- expect(result).toHaveLength(2); // textUser + textAssistant
129
- });
130
-
131
- it("retains non-orphaned blocks in mixed-content messages", () => {
132
- // Assistant message has both a text block and an orphaned tool_use
133
- const messages = [
134
- textUser("hello"),
135
- mixedAssistant([
136
- { type: "text", text: "thinking..." },
137
- { type: "tool_use", id: "t1", name: "tool_a", input: {} },
138
- ]),
139
- // no tool_result for t1
140
- textAssistant("done"),
141
- ];
142
-
143
- const result = limitMessagesToTokenCount(
144
- messages,
145
- [],
146
- "claude-3",
147
- HIGH_LIMIT,
148
- );
149
-
150
- // The assistant message should survive with only the text block
151
- const assistantMixed = result.find(
152
- (m: any) =>
153
- m.role === "assistant" &&
154
- Array.isArray(m.content) &&
155
- m.content.some(
156
- (b: any) => b.type === "text" && b.text === "thinking...",
157
- ),
158
- );
159
- expect(assistantMixed).toBeDefined();
160
- expect(assistantMixed.content).toHaveLength(1);
161
- expect(assistantMixed.content[0].type).toBe("text");
162
- });
163
-
164
- it("retains non-orphaned blocks in mixed user messages", () => {
165
- // User message has both a text block and an orphaned tool_result
166
- const messages = [
167
- textUser("hello"),
168
- mixedUser([
169
- { type: "text", text: "here is context" },
170
- { type: "tool_result", tool_use_id: "t_missing", content: "orphan" },
171
- ]),
172
- textAssistant("ok"),
173
- ];
174
-
175
- const result = limitMessagesToTokenCount(
176
- messages,
177
- [],
178
- "claude-3",
179
- HIGH_LIMIT,
180
- );
181
-
182
- const userMixed = result.find(
183
- (m: any) =>
184
- m.role === "user" &&
185
- Array.isArray(m.content) &&
186
- m.content.some(
187
- (b: any) => b.type === "text" && b.text === "here is context",
188
- ),
189
- );
190
- expect(userMixed).toBeDefined();
191
- expect(userMixed.content).toHaveLength(1);
192
- expect(userMixed.content[0].type).toBe("text");
193
- });
194
-
195
- it("drops message entirely when all blocks are orphaned", () => {
196
- const messages = [
197
- textUser("hello"),
198
- mixedUser([
199
- { type: "tool_result", tool_use_id: "t_a", content: "orphan a" },
200
- { type: "tool_result", tool_use_id: "t_b", content: "orphan b" },
201
- ]),
202
- textAssistant("ok"),
203
- ];
204
-
205
- const result = limitMessagesToTokenCount(
206
- messages,
207
- [],
208
- "claude-3",
209
- HIGH_LIMIT,
210
- );
211
-
212
- expect(result).toHaveLength(2);
213
- expect(result[0].role).toBe("user");
214
- expect(result[1].role).toBe("assistant");
215
- });
216
-
217
- it("drops assistant message entirely when all tool_use blocks are orphaned", () => {
218
- const messages = [
219
- textUser("hello"),
220
- mixedAssistant([
221
- { type: "tool_use", id: "t_x", name: "tool_x", input: {} },
222
- { type: "tool_use", id: "t_y", name: "tool_y", input: {} },
223
- ]),
224
- // no tool_results for either
225
- textAssistant("done"),
226
- ];
227
-
228
- const result = limitMessagesToTokenCount(
229
- messages,
230
- [],
231
- "claude-3",
232
- HIGH_LIMIT,
233
- );
234
-
235
- expect(result).toHaveLength(2);
236
- });
237
-
238
- it("does not mutate the original messages array or message objects", () => {
239
- const originalContent = [
240
- { type: "text", text: "context" },
241
- { type: "tool_result", tool_use_id: "t_orphan", content: "orphan" },
242
- ];
243
- const userMsg = { role: "user", content: [...originalContent] };
244
- const messages = [textUser("hello"), userMsg, textAssistant("ok")];
245
-
246
- const result = limitMessagesToTokenCount(
247
- messages,
248
- [],
249
- "claude-3",
250
- HIGH_LIMIT,
251
- );
252
-
253
- // Original message should still have both blocks
254
- expect(userMsg.content).toHaveLength(2);
255
- expect(userMsg.content[1].type).toBe("tool_result");
256
-
257
- // Original messages array should still have 3 entries
258
- expect(messages).toHaveLength(3);
259
-
260
- // Result should have the filtered version
261
- const filtered = result.find(
262
- (m: any) =>
263
- m.role === "user" &&
264
- Array.isArray(m.content) &&
265
- m.content.some((b: any) => b.text === "context"),
266
- );
267
- expect(filtered).toBeDefined();
268
- expect(filtered.content).toHaveLength(1);
269
- });
270
-
271
- it("handles token trimming that creates orphans via cutoff", () => {
272
- // Build messages where token trimming will cut off early messages,
273
- // leaving orphaned tool_result for a tool_use that got trimmed.
274
- // Each char ~0.33 tokens, so 300 chars ~ 100 tokens
275
- const longText = "x".repeat(300);
276
-
277
- const messages = [
278
- toolUseAssistant("t_old"),
279
- toolResultUser("t_old", "old result"),
280
- textUser(longText),
281
- textAssistant(longText),
282
- toolUseAssistant("t_new"),
283
- toolResultUser("t_new", "new result"),
284
- ];
285
-
286
- // Set a limit that keeps only the last few messages, trimming t_old's tool_use
287
- const result = limitMessagesToTokenCount(messages, [], "claude-3", 300);
288
-
289
- // t_old's tool_use should have been trimmed by the token limit,
290
- // and then t_old's tool_result should be cleaned up as orphaned
291
- const hasOldResult = result.some(
292
- (m: any) =>
293
- m.role === "user" &&
294
- Array.isArray(m.content) &&
295
- m.content.some(
296
- (b: any) => b.type === "tool_result" && b.tool_use_id === "t_old",
297
- ),
298
- );
299
- expect(hasOldResult).toBe(false);
300
- });
301
- });
@@ -1,102 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach } from "vitest";
2
- import type { OpenAIProviderSettings } from "@ai-sdk/openai";
3
- import { GroqAdapter } from "../../../src/service-adapters/groq/groq-adapter";
4
- import { Groq } from "groq-sdk";
5
-
6
- // Groq uses createOpenAI (OpenAI-compatible API), so we check against
7
- // OpenAIProviderSettings. Same exhaustiveness guard as the OpenAI test.
8
- type ForwardedGroqKeys = "baseURL" | "apiKey" | "headers" | "fetch";
9
-
10
- // Keys we set ourselves or that don't apply to Groq.
11
- type ControlledGroqKeys = "name" | "organization" | "project";
12
-
13
- type _exhaustive =
14
- Exclude<
15
- keyof OpenAIProviderSettings,
16
- ForwardedGroqKeys | ControlledGroqKeys
17
- > extends never
18
- ? true
19
- : {
20
- error: "OpenAIProviderSettings has unhandled keys";
21
- unhandled: Exclude<
22
- keyof OpenAIProviderSettings,
23
- ForwardedGroqKeys | ControlledGroqKeys
24
- >;
25
- };
26
- const _check: _exhaustive = true;
27
-
28
- const { mockProviderFn, mockCreateOpenAI } = vi.hoisted(() => {
29
- const mockProviderFn = vi.fn().mockReturnValue({ modelId: "test-model" });
30
- const mockCreateOpenAI = vi.fn().mockReturnValue(mockProviderFn);
31
- return { mockProviderFn, mockCreateOpenAI };
32
- });
33
-
34
- vi.mock("@ai-sdk/openai", async (importOriginal) => {
35
- const actual = await importOriginal<typeof import("@ai-sdk/openai")>();
36
- return { ...actual, createOpenAI: mockCreateOpenAI };
37
- });
38
-
39
- vi.mock("groq-sdk", () => {
40
- return {
41
- Groq: class MockGroq {
42
- baseURL: string;
43
- apiKey: string;
44
- _options: Record<string, any>;
45
- chat = { completions: { create: vi.fn() } };
46
-
47
- constructor(opts: any = {}) {
48
- this.baseURL = opts.baseURL ?? "https://api.groq.com";
49
- this.apiKey = opts.apiKey ?? "default-key";
50
- this._options = {
51
- defaultHeaders: opts.defaultHeaders,
52
- fetch: opts.fetch,
53
- ...opts,
54
- };
55
- }
56
- },
57
- };
58
- });
59
-
60
- describe("GroqAdapter.getLanguageModel()", () => {
61
- beforeEach(() => {
62
- vi.clearAllMocks();
63
- });
64
-
65
- it("forwards all provider-relevant options from the Groq SDK client", () => {
66
- const customFetch = vi.fn();
67
- const groq = new Groq({
68
- apiKey: "gsk-test",
69
- baseURL: "https://custom-groq.example.com",
70
- defaultHeaders: { "x-groq": "value" },
71
- fetch: customFetch,
72
- });
73
-
74
- const adapter = new GroqAdapter({
75
- groq,
76
- model: "llama-3.3-70b-versatile",
77
- });
78
- adapter.getLanguageModel();
79
-
80
- expect(mockCreateOpenAI).toHaveBeenCalledOnce();
81
- const settings = mockCreateOpenAI.mock.calls[0][0];
82
-
83
- expect(settings.baseURL).toBe("https://custom-groq.example.com");
84
- expect(settings.apiKey).toBe("gsk-test");
85
- expect(settings.headers).toEqual({ "x-groq": "value" });
86
- expect(settings.fetch).toBe(customFetch);
87
- expect(settings.name).toBe("groq");
88
-
89
- expect(mockProviderFn).toHaveBeenCalledWith("llama-3.3-70b-versatile");
90
- });
91
-
92
- it("works with default Groq config (no custom options)", () => {
93
- const groq = new Groq({ apiKey: "gsk-default" });
94
- const adapter = new GroqAdapter({ groq });
95
- adapter.getLanguageModel();
96
-
97
- const settings = mockCreateOpenAI.mock.calls[0][0];
98
- expect(settings.baseURL).toBe("https://api.groq.com");
99
- expect(settings.apiKey).toBe("gsk-default");
100
- expect(settings.name).toBe("groq");
101
- });
102
- });
@@ -1,294 +0,0 @@
1
- describe("OpenAI Adapter - Allowlist Approach", () => {
2
- it("should filter out tool_result messages with no corresponding tool_call ID", () => {
3
- // Setup test data
4
- const validToolCallIds = new Set<string>(["valid-id-1", "valid-id-2"]);
5
-
6
- // Messages to filter - valid and invalid ones
7
- const messages = [
8
- { type: "text", role: "user", content: "Hello" },
9
- {
10
- type: "tool_result",
11
- actionExecutionId: "valid-id-1",
12
- result: "result1",
13
- },
14
- {
15
- type: "tool_result",
16
- actionExecutionId: "invalid-id",
17
- result: "invalid",
18
- },
19
- {
20
- type: "tool_result",
21
- actionExecutionId: "valid-id-2",
22
- result: "result2",
23
- },
24
- {
25
- type: "tool_result",
26
- actionExecutionId: "valid-id-1",
27
- result: "duplicate",
28
- }, // Duplicate ID
29
- ];
30
-
31
- // Implement the filtering logic, similar to the adapter
32
- const filteredMessages = messages.filter((message) => {
33
- if (message.type === "tool_result") {
34
- // Skip if there's no corresponding tool_call
35
- if (!validToolCallIds.has(message.actionExecutionId)) {
36
- return false;
37
- }
38
-
39
- // Remove this ID from valid IDs so we don't process duplicates
40
- validToolCallIds.delete(message.actionExecutionId);
41
- }
42
-
43
- // Keep all non-tool-result messages
44
- return true;
45
- });
46
-
47
- // Verify results
48
- expect(filteredMessages.length).toBe(3); // text + 2 valid tool results (no duplicates or invalid)
49
-
50
- // Valid results should be included
51
- expect(
52
- filteredMessages.some(
53
- (m) => m.type === "tool_result" && m.actionExecutionId === "valid-id-1",
54
- ),
55
- ).toBe(true);
56
-
57
- expect(
58
- filteredMessages.some(
59
- (m) => m.type === "tool_result" && m.actionExecutionId === "valid-id-2",
60
- ),
61
- ).toBe(true);
62
-
63
- // Invalid result should be excluded
64
- expect(
65
- filteredMessages.some(
66
- (m) => m.type === "tool_result" && m.actionExecutionId === "invalid-id",
67
- ),
68
- ).toBe(false);
69
-
70
- // Duplicate should be excluded - we used a different approach than Anthropic
71
- const validId1Count = filteredMessages.filter(
72
- (m) => m.type === "tool_result" && m.actionExecutionId === "valid-id-1",
73
- ).length;
74
-
75
- expect(validId1Count).toBe(1);
76
- });
77
-
78
- it("should maintain correct order of messages when filtering", () => {
79
- // Setup test data
80
- const validToolCallIds = new Set<string>(["tool-1", "tool-2", "tool-3"]);
81
-
82
- // Test with a complex conversation pattern
83
- const messages = [
84
- { type: "text", role: "user", content: "Initial message" },
85
- { type: "text", role: "assistant", content: "I'll help with that" },
86
- { type: "tool_call", id: "tool-1", name: "firstTool" },
87
- { type: "tool_result", actionExecutionId: "tool-1", result: "result1" },
88
- { type: "text", role: "assistant", content: "Got the first result" },
89
- { type: "tool_call", id: "tool-2", name: "secondTool" },
90
- { type: "tool_result", actionExecutionId: "tool-2", result: "result2" },
91
- {
92
- type: "tool_result",
93
- actionExecutionId: "invalid-id",
94
- result: "invalid-result",
95
- },
96
- { type: "tool_call", id: "tool-3", name: "thirdTool" },
97
- {
98
- type: "tool_result",
99
- actionExecutionId: "tool-1",
100
- result: "duplicate-result",
101
- }, // Duplicate
102
- { type: "tool_result", actionExecutionId: "tool-3", result: "result3" },
103
- { type: "text", role: "user", content: "Final message" },
104
- ];
105
-
106
- // Apply OpenAI's filter approach (using filter instead of loop)
107
- const filteredMessages = messages.filter((message) => {
108
- if (message.type === "tool_result") {
109
- // Skip if there's no corresponding tool_call
110
- if (!validToolCallIds.has(message.actionExecutionId)) {
111
- return false;
112
- }
113
-
114
- // Remove this ID from valid IDs so we don't process duplicates
115
- validToolCallIds.delete(message.actionExecutionId);
116
- }
117
-
118
- // Keep all non-tool-result messages
119
- return true;
120
- });
121
-
122
- // Verify results
123
- expect(filteredMessages.length).toBe(10); // 12 original - 2 filtered out
124
-
125
- // Check that the message order is preserved
126
- expect(filteredMessages[0].type).toBe("text"); // Initial user message
127
- expect(filteredMessages[0].content).toBe("Initial message");
128
- expect(filteredMessages[1].type).toBe("text"); // Assistant response
129
- expect(filteredMessages[2].type).toBe("tool_call"); // First tool
130
- expect(filteredMessages[3].type).toBe("tool_result"); // First result
131
- expect(filteredMessages[3].actionExecutionId).toBe("tool-1");
132
- expect(filteredMessages[4].type).toBe("text"); // Assistant comment
133
- expect(filteredMessages[5].type).toBe("tool_call"); // Second tool
134
- expect(filteredMessages[6].type).toBe("tool_result"); // Second result
135
- expect(filteredMessages[6].actionExecutionId).toBe("tool-2");
136
- expect(filteredMessages[7].type).toBe("tool_call"); // Third tool
137
- expect(filteredMessages[8].type).toBe("tool_result"); // Third result
138
- expect(filteredMessages[8].actionExecutionId).toBe("tool-3");
139
- expect(filteredMessages[9].type).toBe("text"); // Final user message
140
-
141
- // Each valid tool result should appear exactly once
142
- const toolResultCounts = new Map();
143
- filteredMessages.forEach((message) => {
144
- if (message.type === "tool_result") {
145
- const id = message.actionExecutionId;
146
- toolResultCounts.set(id, (toolResultCounts.get(id) || 0) + 1);
147
- }
148
- });
149
-
150
- expect(toolResultCounts.size).toBe(3); // Should have 3 different tool results
151
- expect(toolResultCounts.get("tool-1")).toBe(1);
152
- expect(toolResultCounts.get("tool-2")).toBe(1);
153
- expect(toolResultCounts.get("tool-3")).toBe(1);
154
- expect(toolResultCounts.has("invalid-id")).toBe(false);
155
- });
156
-
157
- it("should handle empty message array", () => {
158
- const validToolCallIds = new Set<string>(["valid-id-1", "valid-id-2"]);
159
- const messages = [];
160
-
161
- // Apply OpenAI's filter approach
162
- const filteredMessages = messages.filter((message) => {
163
- if (message.type === "tool_result") {
164
- if (!validToolCallIds.has(message.actionExecutionId)) {
165
- return false;
166
- }
167
- validToolCallIds.delete(message.actionExecutionId);
168
- }
169
- return true;
170
- });
171
-
172
- expect(filteredMessages.length).toBe(0);
173
- });
174
-
175
- it("should handle edge cases with mixed message types", () => {
176
- // Setup test data with various message types
177
- const validToolCallIds = new Set<string>(["valid-id-1"]);
178
-
179
- const messages = [
180
- { type: "text", role: "user", content: "Hello" },
181
- { type: "image", url: "https://example.com/image.jpg" }, // Non-tool message type
182
- {
183
- type: "tool_result",
184
- actionExecutionId: "valid-id-1",
185
- result: "result1",
186
- },
187
- { type: "custom", data: { key: "value" } }, // Another custom type
188
- {
189
- type: "tool_result",
190
- actionExecutionId: "valid-id-1",
191
- result: "duplicate",
192
- }, // Duplicate
193
- { type: "null", value: null }, // Edge case
194
- { type: "undefined" }, // Edge case
195
- ];
196
-
197
- // Apply OpenAI's filter approach
198
- const filteredMessages = messages.filter((message) => {
199
- if (message.type === "tool_result") {
200
- if (!validToolCallIds.has(message.actionExecutionId)) {
201
- return false;
202
- }
203
- validToolCallIds.delete(message.actionExecutionId);
204
- }
205
- return true;
206
- });
207
-
208
- // Should have all non-tool_result messages + 1 valid tool_result
209
- expect(filteredMessages.length).toBe(6); // 7 original - 1 duplicate
210
-
211
- // Valid tool_result should be included exactly once
212
- const toolResults = filteredMessages.filter(
213
- (m) => m.type === "tool_result",
214
- );
215
- expect(toolResults.length).toBe(1);
216
- expect(toolResults[0].actionExecutionId).toBe("valid-id-1");
217
-
218
- // All non-tool_result messages should be preserved
219
- expect(filteredMessages.filter((m) => m.type === "text").length).toBe(1);
220
- expect(filteredMessages.filter((m) => m.type === "image").length).toBe(1);
221
- expect(filteredMessages.filter((m) => m.type === "custom").length).toBe(1);
222
- expect(filteredMessages.filter((m) => m.type === "null").length).toBe(1);
223
- expect(filteredMessages.filter((m) => m.type === "undefined").length).toBe(
224
- 1,
225
- );
226
- });
227
-
228
- it("should properly handle multiple duplicate tool results", () => {
229
- // Setup test data with multiple duplicates
230
- const validToolCallIds = new Set<string>(["tool-1", "tool-2"]);
231
-
232
- const messages = [
233
- { type: "text", role: "user", content: "Initial prompt" },
234
- { type: "tool_call", id: "tool-1", name: "firstTool" },
235
- {
236
- type: "tool_result",
237
- actionExecutionId: "tool-1",
238
- result: "first-result",
239
- },
240
- {
241
- type: "tool_result",
242
- actionExecutionId: "tool-1",
243
- result: "duplicate-1",
244
- }, // Duplicate 1
245
- { type: "tool_call", id: "tool-2", name: "secondTool" },
246
- {
247
- type: "tool_result",
248
- actionExecutionId: "tool-1",
249
- result: "duplicate-2",
250
- }, // Duplicate 2
251
- {
252
- type: "tool_result",
253
- actionExecutionId: "tool-2",
254
- result: "second-result",
255
- },
256
- {
257
- type: "tool_result",
258
- actionExecutionId: "tool-2",
259
- result: "duplicate-3",
260
- }, // Duplicate 3
261
- {
262
- type: "tool_result",
263
- actionExecutionId: "tool-1",
264
- result: "duplicate-4",
265
- }, // Duplicate 4
266
- ];
267
-
268
- // Apply OpenAI's filter approach
269
- const filteredMessages = messages.filter((message) => {
270
- if (message.type === "tool_result") {
271
- if (!validToolCallIds.has(message.actionExecutionId)) {
272
- return false;
273
- }
274
- validToolCallIds.delete(message.actionExecutionId);
275
- }
276
- return true;
277
- });
278
-
279
- // Should have text + tool calls + only the first occurrence of each tool result
280
- expect(filteredMessages.length).toBe(5);
281
-
282
- // Check that only the first occurrence of each tool result is kept
283
- const toolResults = filteredMessages.filter(
284
- (m) => m.type === "tool_result",
285
- );
286
- expect(toolResults.length).toBe(2);
287
-
288
- expect(toolResults[0].actionExecutionId).toBe("tool-1");
289
- expect(toolResults[0].result).toBe("first-result"); // First occurrence should be kept
290
-
291
- expect(toolResults[1].actionExecutionId).toBe("tool-2");
292
- expect(toolResults[1].result).toBe("second-result"); // First occurrence should be kept
293
- });
294
- });