@agent-native/core 0.95.0 → 0.96.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (316) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +35 -0
  3. package/corpus/core/docs/content/locales/ar-SA/template-design.mdx +13 -0
  4. package/corpus/core/docs/content/locales/de-DE/template-design.mdx +18 -0
  5. package/corpus/core/docs/content/locales/es-ES/template-design.mdx +16 -0
  6. package/corpus/core/docs/content/locales/fr-FR/template-design.mdx +17 -0
  7. package/corpus/core/docs/content/locales/hi-IN/template-design.mdx +16 -0
  8. package/corpus/core/docs/content/locales/ja-JP/template-design.mdx +17 -0
  9. package/corpus/core/docs/content/locales/ko-KR/template-design.mdx +15 -0
  10. package/corpus/core/docs/content/locales/pt-BR/template-design.mdx +16 -0
  11. package/corpus/core/docs/content/locales/zh-CN/template-design.mdx +11 -0
  12. package/corpus/core/docs/content/locales/zh-TW/template-design.mdx +12 -0
  13. package/corpus/core/docs/content/template-design.mdx +16 -0
  14. package/corpus/core/package.json +4 -2
  15. package/corpus/core/src/a2a/client.ts +11 -1
  16. package/corpus/core/src/agent/production-agent.ts +107 -27
  17. package/corpus/core/src/agent/thread-data-builder.ts +48 -22
  18. package/corpus/core/src/chat-threads/store.ts +20 -1
  19. package/corpus/core/src/cli/code-agent-executor.ts +1 -0
  20. package/corpus/core/src/cli/code-agent-runs.ts +14 -0
  21. package/corpus/core/src/client/AgentPanel.tsx +32 -25
  22. package/corpus/core/src/client/AssistantChat.tsx +286 -45
  23. package/corpus/core/src/client/MultiTabAssistantChat.tsx +141 -90
  24. package/corpus/core/src/client/chat/ChatHistoryList.tsx +404 -0
  25. package/corpus/core/src/client/chat/index.ts +6 -0
  26. package/corpus/core/src/client/chat/tool-call-display.tsx +38 -4
  27. package/corpus/core/src/client/chat/use-reconnect-reader-owner.ts +28 -0
  28. package/corpus/core/src/client/code-agent-chat-adapter.ts +72 -4
  29. package/corpus/core/src/client/composer/RealtimeVoiceMode.tsx +52 -11
  30. package/corpus/core/src/client/composer/TiptapComposer.tsx +157 -20
  31. package/corpus/core/src/client/composer/VoiceButton.tsx +28 -0
  32. package/corpus/core/src/client/composer/useRealtimeVoiceMode.tsx +5 -0
  33. package/corpus/core/src/client/conversation/code-agent-transcript.ts +4 -5
  34. package/corpus/core/src/client/guided-questions.tsx +11 -2
  35. package/corpus/core/src/client/index.ts +11 -0
  36. package/corpus/core/src/client/integrations/IntegrationsPanel.tsx +6 -7
  37. package/corpus/core/src/client/sse-event-processor.ts +90 -21
  38. package/corpus/core/src/client/use-chat-threads.ts +10 -1
  39. package/corpus/core/src/client/voice-provider-status.ts +44 -0
  40. package/corpus/core/src/code-agents/transcript-normalizer.ts +76 -0
  41. package/corpus/core/src/connections/catalog.ts +2 -2
  42. package/corpus/core/src/deploy/build.ts +12 -8
  43. package/corpus/core/src/integrations/a2a-continuation-processor.ts +35 -5
  44. package/corpus/core/src/integrations/adapters/slack.ts +74 -21
  45. package/corpus/core/src/integrations/catalog.ts +2 -2
  46. package/corpus/core/src/integrations/webhook-handler.ts +14 -0
  47. package/corpus/core/src/localization/default-messages.ts +6 -0
  48. package/corpus/core/src/observability/hosted-model-experiment.ts +118 -0
  49. package/corpus/core/src/observability/routes.ts +17 -0
  50. package/corpus/core/src/observability/store.ts +4 -1
  51. package/corpus/core/src/observability/traces.ts +41 -2
  52. package/corpus/core/src/scripts/agent-engines/list-agent-engines.ts +19 -1
  53. package/corpus/core/src/scripts/call-agent.ts +53 -3
  54. package/corpus/core/src/scripts/chat/search-chats.ts +11 -8
  55. package/corpus/core/src/secrets/register-framework-secrets.ts +1 -1
  56. package/corpus/core/src/server/agent-chat-plugin.ts +41 -6
  57. package/corpus/core/src/server/auth.ts +1 -1
  58. package/corpus/core/src/server/core-routes-plugin.ts +15 -0
  59. package/corpus/core/src/server/credential-provider.ts +7 -3
  60. package/corpus/core/src/server/realtime-voice.ts +71 -24
  61. package/corpus/core/src/server/voice-providers-status.ts +4 -3
  62. package/corpus/core/src/shared/cache-control.ts +4 -4
  63. package/corpus/core/src/styles/agent-native.css +1 -0
  64. package/corpus/core/src/styles/chat-history-list.css +313 -0
  65. package/corpus/core/src/templates/workspace-core/.agents/skills/observability/SKILL.md +20 -0
  66. package/corpus/core/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +8 -4
  67. package/corpus/core/src/vite/client.ts +1 -0
  68. package/corpus/templates/analytics/AGENTS.md +7 -0
  69. package/corpus/templates/analytics/actions/bigquery.ts +26 -2
  70. package/corpus/templates/analytics/actions/data-source-status.ts +18 -0
  71. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +5 -4
  72. package/corpus/templates/analytics/app/global.css +10 -0
  73. package/corpus/templates/analytics/app/lib/data-sources.ts +5 -4
  74. package/corpus/templates/analytics/app/pages/Ask.tsx +25 -2
  75. package/corpus/templates/analytics/changelog/2026-07-10-analytics-answers-simple-time-bounded-metrics-without-unnece.md +6 -0
  76. package/corpus/templates/analytics/changelog/2026-07-10-analytics-chat-reliably-uses-connected-data-sources-across-s.md +6 -0
  77. package/corpus/templates/analytics/changelog/2026-07-10-chat-threads-now-stay-clear-of-top-actions-and-fade-smoothly.md +6 -0
  78. package/corpus/templates/analytics/changelog/2026-07-10-context-chips-can-now-be-selected-and-removed-one-at-a-time-.md +6 -0
  79. package/corpus/templates/analytics/changelog/2026-07-10-slack-token-setup-marked-legacy.md +6 -0
  80. package/corpus/templates/analytics/changelog/2026-07-10-the-ask-composer-no-longer-carries-dashboard-or-panel-contex.md +6 -0
  81. package/corpus/templates/analytics/changelog/2026-07-10-the-ask-section-stays-highlighted-while-its-chat-history-is-.md +6 -0
  82. package/corpus/templates/analytics/server/lib/bigquery.ts +90 -14
  83. package/corpus/templates/analytics/server/lib/credential-keys.ts +6 -2
  84. package/corpus/templates/analytics/server/plugins/agent-chat.ts +82 -7
  85. package/corpus/templates/brain/changelog/2026-07-10-slack-backfill-token-marked-legacy.md +6 -0
  86. package/corpus/templates/brain/server/register-secrets.ts +2 -2
  87. package/corpus/templates/clips/app/components/library/library-layout.tsx +7 -1
  88. package/corpus/templates/clips/app/components/library/page-header.tsx +19 -3
  89. package/corpus/templates/clips/app/routes/_app.library._index.tsx +16 -12
  90. package/corpus/templates/clips/changelog/2026-07-10-new-recording-appears-once-when-the-library-sidebar-is-open.md +6 -0
  91. package/corpus/templates/clips/changelog/2026-07-10-slack-token-fallback-guidance.md +6 -0
  92. package/corpus/templates/clips/server/register-secrets.ts +1 -1
  93. package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +0 -66
  94. package/corpus/templates/content/app/routes/_app.local-files.tsx +7 -47
  95. package/corpus/templates/content/changelog/2026-07-10-local-folders-now-wait-for-an-explicit-pull-before-content-r.md +6 -0
  96. package/corpus/templates/content/package.json +1 -1
  97. package/corpus/templates/design/actions/generate-design.ts +128 -31
  98. package/corpus/templates/design/actions/present-design-variants.ts +37 -9
  99. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +9 -3
  100. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +32 -10
  101. package/corpus/templates/design/app/components/design/QuestionFlow.tsx +2 -2
  102. package/corpus/templates/design/app/components/design/TweaksPanel.tsx +9 -1
  103. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +7 -5
  104. package/corpus/templates/design/app/components/design/multi-screen/types.ts +3 -0
  105. package/corpus/templates/design/app/global.css +10 -0
  106. package/corpus/templates/design/app/hooks/use-question-flow.ts +9 -2
  107. package/corpus/templates/design/app/i18n/zh-TW.ts +1 -0
  108. package/corpus/templates/design/app/i18n-data.ts +21 -11
  109. package/corpus/templates/design/changelog/2026-07-10-editor-panels-are-easier-to-distinguish-and-design-intake-qu.md +6 -0
  110. package/corpus/templates/design/changelog/2026-07-10-interact-mode-now-stays-on-the-full-canvas-matches-edit-visu.md +6 -0
  111. package/corpus/templates/design/changelog/2026-07-10-new-web-designs-open-at-desktop-size-and-adapt-across-mobile.md +6 -0
  112. package/corpus/templates/design/changelog/2026-07-10-tweaks-now-link-to-full-documentation.md +6 -0
  113. package/corpus/templates/design/server/plugins/agent-chat.ts +2 -0
  114. package/corpus/templates/mail/app/i18n/ar-SA.ts +3 -3
  115. package/corpus/templates/mail/app/i18n/de-DE.ts +3 -3
  116. package/corpus/templates/mail/app/i18n/en-US.ts +4 -3
  117. package/corpus/templates/mail/app/i18n/es-ES.ts +3 -3
  118. package/corpus/templates/mail/app/i18n/fr-FR.ts +3 -3
  119. package/corpus/templates/mail/app/i18n/hi-IN.ts +3 -3
  120. package/corpus/templates/mail/app/i18n/ja-JP.ts +3 -3
  121. package/corpus/templates/mail/app/i18n/ko-KR.ts +3 -3
  122. package/corpus/templates/mail/app/i18n/pt-BR.ts +3 -3
  123. package/corpus/templates/mail/app/i18n/zh-CN.ts +3 -3
  124. package/corpus/templates/mail/app/i18n/zh-TW.ts +3 -3
  125. package/corpus/templates/mail/changelog/2026-07-10-slack-intake-marked-legacy.md +6 -0
  126. package/corpus/templates/mail/server/lib/env-config.ts +5 -4
  127. package/corpus/templates/plan/package.json +1 -1
  128. package/dist/a2a/client.d.ts +7 -0
  129. package/dist/a2a/client.d.ts.map +1 -1
  130. package/dist/a2a/client.js +2 -1
  131. package/dist/a2a/client.js.map +1 -1
  132. package/dist/agent/production-agent.d.ts +6 -0
  133. package/dist/agent/production-agent.d.ts.map +1 -1
  134. package/dist/agent/production-agent.js +83 -26
  135. package/dist/agent/production-agent.js.map +1 -1
  136. package/dist/agent/thread-data-builder.d.ts +1 -0
  137. package/dist/agent/thread-data-builder.d.ts.map +1 -1
  138. package/dist/agent/thread-data-builder.js +42 -23
  139. package/dist/agent/thread-data-builder.js.map +1 -1
  140. package/dist/chat-threads/store.d.ts +10 -0
  141. package/dist/chat-threads/store.d.ts.map +1 -1
  142. package/dist/chat-threads/store.js +6 -0
  143. package/dist/chat-threads/store.js.map +1 -1
  144. package/dist/cli/code-agent-executor.d.ts.map +1 -1
  145. package/dist/cli/code-agent-executor.js +1 -0
  146. package/dist/cli/code-agent-executor.js.map +1 -1
  147. package/dist/cli/code-agent-runs.d.ts +12 -0
  148. package/dist/cli/code-agent-runs.d.ts.map +1 -1
  149. package/dist/cli/code-agent-runs.js +1 -0
  150. package/dist/cli/code-agent-runs.js.map +1 -1
  151. package/dist/client/AgentPanel.d.ts.map +1 -1
  152. package/dist/client/AgentPanel.js +3 -3
  153. package/dist/client/AgentPanel.js.map +1 -1
  154. package/dist/client/AssistantChat.d.ts +14 -1
  155. package/dist/client/AssistantChat.d.ts.map +1 -1
  156. package/dist/client/AssistantChat.js +207 -32
  157. package/dist/client/AssistantChat.js.map +1 -1
  158. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  159. package/dist/client/MultiTabAssistantChat.js +83 -10
  160. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  161. package/dist/client/chat/ChatHistoryList.d.ts +88 -0
  162. package/dist/client/chat/ChatHistoryList.d.ts.map +1 -0
  163. package/dist/client/chat/ChatHistoryList.js +83 -0
  164. package/dist/client/chat/ChatHistoryList.js.map +1 -0
  165. package/dist/client/chat/index.d.ts +1 -0
  166. package/dist/client/chat/index.d.ts.map +1 -1
  167. package/dist/client/chat/index.js +1 -0
  168. package/dist/client/chat/index.js.map +1 -1
  169. package/dist/client/chat/tool-call-display.d.ts +13 -1
  170. package/dist/client/chat/tool-call-display.d.ts.map +1 -1
  171. package/dist/client/chat/tool-call-display.js +11 -3
  172. package/dist/client/chat/tool-call-display.js.map +1 -1
  173. package/dist/client/chat/use-reconnect-reader-owner.d.ts +11 -0
  174. package/dist/client/chat/use-reconnect-reader-owner.d.ts.map +1 -0
  175. package/dist/client/chat/use-reconnect-reader-owner.js +21 -0
  176. package/dist/client/chat/use-reconnect-reader-owner.js.map +1 -0
  177. package/dist/client/code-agent-chat-adapter.d.ts +17 -1
  178. package/dist/client/code-agent-chat-adapter.d.ts.map +1 -1
  179. package/dist/client/code-agent-chat-adapter.js +47 -3
  180. package/dist/client/code-agent-chat-adapter.js.map +1 -1
  181. package/dist/client/composer/RealtimeVoiceMode.d.ts +11 -1
  182. package/dist/client/composer/RealtimeVoiceMode.d.ts.map +1 -1
  183. package/dist/client/composer/RealtimeVoiceMode.js +5 -3
  184. package/dist/client/composer/RealtimeVoiceMode.js.map +1 -1
  185. package/dist/client/composer/TiptapComposer.d.ts +25 -2
  186. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  187. package/dist/client/composer/TiptapComposer.js +96 -5
  188. package/dist/client/composer/TiptapComposer.js.map +1 -1
  189. package/dist/client/composer/VoiceButton.d.ts.map +1 -1
  190. package/dist/client/composer/VoiceButton.js +21 -1
  191. package/dist/client/composer/VoiceButton.js.map +1 -1
  192. package/dist/client/composer/useRealtimeVoiceMode.d.ts.map +1 -1
  193. package/dist/client/composer/useRealtimeVoiceMode.js +5 -0
  194. package/dist/client/composer/useRealtimeVoiceMode.js.map +1 -1
  195. package/dist/client/conversation/code-agent-transcript.d.ts +2 -0
  196. package/dist/client/conversation/code-agent-transcript.d.ts.map +1 -1
  197. package/dist/client/conversation/code-agent-transcript.js +3 -5
  198. package/dist/client/conversation/code-agent-transcript.js.map +1 -1
  199. package/dist/client/guided-questions.d.ts.map +1 -1
  200. package/dist/client/guided-questions.js +7 -2
  201. package/dist/client/guided-questions.js.map +1 -1
  202. package/dist/client/index.d.ts +3 -1
  203. package/dist/client/index.d.ts.map +1 -1
  204. package/dist/client/index.js +3 -1
  205. package/dist/client/index.js.map +1 -1
  206. package/dist/client/integrations/IntegrationsPanel.d.ts.map +1 -1
  207. package/dist/client/integrations/IntegrationsPanel.js +5 -7
  208. package/dist/client/integrations/IntegrationsPanel.js.map +1 -1
  209. package/dist/client/sse-event-processor.d.ts.map +1 -1
  210. package/dist/client/sse-event-processor.js +67 -20
  211. package/dist/client/sse-event-processor.js.map +1 -1
  212. package/dist/client/use-chat-threads.d.ts.map +1 -1
  213. package/dist/client/use-chat-threads.js +9 -1
  214. package/dist/client/use-chat-threads.js.map +1 -1
  215. package/dist/client/voice-provider-status.d.ts +10 -0
  216. package/dist/client/voice-provider-status.d.ts.map +1 -0
  217. package/dist/client/voice-provider-status.js +32 -0
  218. package/dist/client/voice-provider-status.js.map +1 -0
  219. package/dist/code-agents/transcript-normalizer.d.ts +29 -0
  220. package/dist/code-agents/transcript-normalizer.d.ts.map +1 -1
  221. package/dist/code-agents/transcript-normalizer.js +55 -0
  222. package/dist/code-agents/transcript-normalizer.js.map +1 -1
  223. package/dist/collab/struct-routes.d.ts +1 -1
  224. package/dist/connections/catalog.d.ts +2 -2
  225. package/dist/connections/catalog.js +2 -2
  226. package/dist/connections/catalog.js.map +1 -1
  227. package/dist/deploy/build.d.ts.map +1 -1
  228. package/dist/deploy/build.js +12 -8
  229. package/dist/deploy/build.js.map +1 -1
  230. package/dist/integrations/a2a-continuation-processor.d.ts.map +1 -1
  231. package/dist/integrations/a2a-continuation-processor.js +25 -5
  232. package/dist/integrations/a2a-continuation-processor.js.map +1 -1
  233. package/dist/integrations/adapters/slack.d.ts.map +1 -1
  234. package/dist/integrations/adapters/slack.js +55 -21
  235. package/dist/integrations/adapters/slack.js.map +1 -1
  236. package/dist/integrations/catalog.js +2 -2
  237. package/dist/integrations/catalog.js.map +1 -1
  238. package/dist/integrations/webhook-handler.d.ts.map +1 -1
  239. package/dist/integrations/webhook-handler.js +11 -0
  240. package/dist/integrations/webhook-handler.js.map +1 -1
  241. package/dist/localization/default-messages.d.ts +5 -0
  242. package/dist/localization/default-messages.d.ts.map +1 -1
  243. package/dist/localization/default-messages.js +5 -0
  244. package/dist/localization/default-messages.js.map +1 -1
  245. package/dist/observability/hosted-model-experiment.d.ts +39 -0
  246. package/dist/observability/hosted-model-experiment.d.ts.map +1 -0
  247. package/dist/observability/hosted-model-experiment.js +90 -0
  248. package/dist/observability/hosted-model-experiment.js.map +1 -0
  249. package/dist/observability/routes.d.ts.map +1 -1
  250. package/dist/observability/routes.js +16 -0
  251. package/dist/observability/routes.js.map +1 -1
  252. package/dist/observability/store.d.ts.map +1 -1
  253. package/dist/observability/store.js +4 -1
  254. package/dist/observability/store.js.map +1 -1
  255. package/dist/observability/traces.d.ts +6 -0
  256. package/dist/observability/traces.d.ts.map +1 -1
  257. package/dist/observability/traces.js +28 -2
  258. package/dist/observability/traces.js.map +1 -1
  259. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  260. package/dist/scripts/agent-engines/list-agent-engines.d.ts.map +1 -1
  261. package/dist/scripts/agent-engines/list-agent-engines.js +19 -1
  262. package/dist/scripts/agent-engines/list-agent-engines.js.map +1 -1
  263. package/dist/scripts/call-agent.d.ts.map +1 -1
  264. package/dist/scripts/call-agent.js +43 -3
  265. package/dist/scripts/call-agent.js.map +1 -1
  266. package/dist/scripts/chat/search-chats.d.ts +1 -1
  267. package/dist/scripts/chat/search-chats.d.ts.map +1 -1
  268. package/dist/scripts/chat/search-chats.js +11 -8
  269. package/dist/scripts/chat/search-chats.js.map +1 -1
  270. package/dist/secrets/register-framework-secrets.js +1 -1
  271. package/dist/secrets/register-framework-secrets.js.map +1 -1
  272. package/dist/server/agent-chat-plugin.d.ts +11 -0
  273. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  274. package/dist/server/agent-chat-plugin.js +27 -6
  275. package/dist/server/agent-chat-plugin.js.map +1 -1
  276. package/dist/server/auth.js +1 -1
  277. package/dist/server/auth.js.map +1 -1
  278. package/dist/server/core-routes-plugin.d.ts +3 -0
  279. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  280. package/dist/server/core-routes-plugin.js +13 -0
  281. package/dist/server/core-routes-plugin.js.map +1 -1
  282. package/dist/server/credential-provider.d.ts +5 -3
  283. package/dist/server/credential-provider.d.ts.map +1 -1
  284. package/dist/server/credential-provider.js +7 -3
  285. package/dist/server/credential-provider.js.map +1 -1
  286. package/dist/server/realtime-voice.d.ts.map +1 -1
  287. package/dist/server/realtime-voice.js +55 -21
  288. package/dist/server/realtime-voice.js.map +1 -1
  289. package/dist/server/voice-providers-status.d.ts.map +1 -1
  290. package/dist/server/voice-providers-status.js +2 -3
  291. package/dist/server/voice-providers-status.js.map +1 -1
  292. package/dist/shared/cache-control.d.ts +6 -6
  293. package/dist/shared/cache-control.d.ts.map +1 -1
  294. package/dist/shared/cache-control.js +3 -3
  295. package/dist/shared/cache-control.js.map +1 -1
  296. package/dist/styles/agent-native.css +1 -0
  297. package/dist/styles/chat-history-list.css +313 -0
  298. package/dist/templates/workspace-core/.agents/skills/observability/SKILL.md +20 -0
  299. package/dist/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +8 -4
  300. package/dist/vite/client.d.ts.map +1 -1
  301. package/dist/vite/client.js +1 -0
  302. package/dist/vite/client.js.map +1 -1
  303. package/docs/content/locales/ar-SA/template-design.mdx +13 -0
  304. package/docs/content/locales/de-DE/template-design.mdx +18 -0
  305. package/docs/content/locales/es-ES/template-design.mdx +16 -0
  306. package/docs/content/locales/fr-FR/template-design.mdx +17 -0
  307. package/docs/content/locales/hi-IN/template-design.mdx +16 -0
  308. package/docs/content/locales/ja-JP/template-design.mdx +17 -0
  309. package/docs/content/locales/ko-KR/template-design.mdx +15 -0
  310. package/docs/content/locales/pt-BR/template-design.mdx +16 -0
  311. package/docs/content/locales/zh-CN/template-design.mdx +11 -0
  312. package/docs/content/locales/zh-TW/template-design.mdx +12 -0
  313. package/docs/content/template-design.mdx +16 -0
  314. package/package.json +4 -2
  315. package/src/templates/workspace-core/.agents/skills/observability/SKILL.md +20 -0
  316. package/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +8 -4
@@ -1 +1 @@
1
- {"version":3,"file":"traces.js","sourceRoot":"","sources":["../../src/observability/traces.ts"],"names":[],"mappings":"AAEA,OAAO,EAAkB,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE5E,OAAO,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC;AAE1D,SAAS,MAAM;IACb,OAAO,QAAQ,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;AACxE,CAAC;AAED,SAAS,qBAAqB,CAAC,KAAyB;IACtD,MAAM,GAAG,GAAG,KAAK,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACxC,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAC;IAC3B,OAAO,GAAG;SACP,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC;SAC/B,OAAO,CAAC,gBAAgB,EAAE,GAAG,CAAC;SAC9B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;AAC7B,CAAC;AAED,SAAS,cAAc,CAAC,KAAyB;IAC/C,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE;QAAE,OAAO,SAAS,CAAC;IACrC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,0BAA0B,CAAC,IAAI,CAAC,KAAK,CAAC;YAChD,CAAC,CAAC,KAAK;YACP,CAAC,CAAC,WAAW,KAAK,EAAE,CAAC;QACvB,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;QACrD,IAAI,QAAQ,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;YAC3C,OAAO,qBAAqB,CAC1B,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAC/C,CAAC;QACJ,CAAC;QACD,OAAO,qBAAqB,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACvD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,SAAS,0BAA0B;IACjC,MAAM,UAAU,GAAG,qBAAqB,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IACvE,MAAM,MAAM,GACV,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;QACnC,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;QAC3C,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;QAC/B,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;QACtC,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC;QACzD,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACzC,MAAM,GAAG,GACP,qBAAqB,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;QACnD,qBAAqB,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC;QACxD,MAAM;QACN,UAAU;QACV,qBAAqB,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC9C,MAAM,QAAQ,GACZ,qBAAqB,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC;QACxD,qBAAqB,CAAC,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC;QAC7D,qBAAqB,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;QAC/C,qBAAqB,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;QACpD,GAAG,CAAC;IAEN,OAAO;QACL,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,gBAAgB,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9C,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,qBAAqB,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACnE,CAAC;AACJ,CAAC;AAED,SAAS,qBAAqB,CAC5B,UAA8B,EAC9B,KAAa;IAEb,MAAM,MAAM,GAAG,UAAU,EAAE,IAAI,EAAE,CAAC;IAClC,IAAI,MAAM,EAAE,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACzE,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAC1B,IAAI,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,WAAW,CAAC;IACxD,IAAI,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAC;IACrD,IAAI,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAC;IAClD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,qBAAqB,CAAC,KAAa;IAC1C,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,MAAM,CAAC,GAAG,SAAS,CAAC,GAAG,SAAS,CAAC;AAC9D,CAAC;AAED,SAAS,8BAA8B,CAAC,IAoBvC;IACC,MAAM,QAAQ,GAAG,qBAAqB,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IACpE,MAAM,OAAO,GAAG,qBAAqB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC1D,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,IAAI,SAAS,CAAC;IAC7C,MAAM,UAAU,GAA4B;QAC1C,GAAG,0BAA0B,EAAE;QAC/B,MAAM,EAAE,qBAAqB;QAC7B,SAAS,EAAE,UAAU;QACrB,MAAM,EAAE,IAAI,CAAC,KAAK;QAClB,SAAS,EAAE,IAAI,CAAC,QAAQ;QACxB,cAAc,EAAE,IAAI,CAAC,YAAY;QACjC,OAAO,EAAE,IAAI,CAAC,SAAS;QACvB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,QAAQ;QACR,YAAY,EAAE,IAAI,CAAC,WAAW;QAC9B,aAAa,EAAE,IAAI,CAAC,YAAY;QAChC,YAAY,EAAE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,YAAY;QAClD,iBAAiB,EAAE,IAAI,CAAC,eAAe;QACvC,kBAAkB,EAAE,IAAI,CAAC,gBAAgB;QACzC,eAAe,EAAE,IAAI,CAAC,aAAa;QACnC,QAAQ,EAAE,OAAO;QACjB,WAAW,EAAE,IAAI,CAAC,UAAU;QAC5B,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,UAAU,EAAE,IAAI,CAAC,SAAS;QAC1B,gBAAgB,EAAE,IAAI,CAAC,eAAe;QACtC,YAAY,EAAE,IAAI,CAAC,WAAW;QAC9B,UAAU,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE;QAClD,aAAa,EAAE,IAAI,CAAC,SAAS;QAC7B,YAAY,EAAE,IAAI,CAAC,KAAK;QACxB,cAAc,EAAE,IAAI,CAAC,QAAQ,IAAI,SAAS;QAC1C,WAAW,EAAE,IAAI,CAAC,SAAS;QAC3B,aAAa,EAAE,WAAW;QAC1B,aAAa,EAAE,IAAI,CAAC,YAAY;QAChC,SAAS,EAAE,IAAI,CAAC,KAAK;QACrB,YAAY,EAAE,QAAQ;QACtB,gBAAgB,EAAE,IAAI,CAAC,WAAW;QAClC,iBAAiB,EAAE,IAAI,CAAC,YAAY;QACpC,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI;QAC/D,YAAY,EAAE,IAAI,CAAC,MAAM,KAAK,OAAO;QACrC,SAAS,EAAE,KAAK;QAChB,2BAA2B,EAAE,IAAI,CAAC,eAAe;QACjD,+BAA+B,EAAE,IAAI,CAAC,gBAAgB;QACtD,iBAAiB,EAAE,CAAC;QACpB,kBAAkB,EAAE,OAAO;KAC5B,CAAC;IACF,IAAI,KAAK;QAAE,UAAU,CAAC,aAAa,GAAG,KAAK,CAAC;IAE5C,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QAC1C,IAAI,UAAU,CAAC,GAAG,CAAC,KAAK,SAAS;YAAE,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC;IAC5D,CAAC;IAED,IAAI,CAAC;QACH,KAAK,MAAM,CAAC,yBAAyB,CAAC;aACnC,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE;YAClB,KAAK,CAAC,gBAAgB,EAAE,UAAU,EAAE;gBAClC,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,SAAS;aACjC,CAAC,CAAC;QACL,CAAC,CAAC;aACD,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACrB,CAAC;IAAC,MAAM,CAAC;QACP,iEAAiE;IACnE,CAAC;AACH,CAAC;AAED;;;;;;2BAM2B;AAC3B,MAAM,uBAAuB,GAC3B,uGAAuG,CAAC;AAE1G;;;wEAGwE;AACxE,MAAM,UAAU,qBAAqB,CAAC,KAAc;IAClD,OAAO,UAAU,CAAC,KAAK,EAAE,IAAI,OAAO,EAAU,CAAC,CAAC;AAClD,CAAC;AAED,SAAS,UAAU,CAAC,KAAc,EAAE,IAAqB;IACvD,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC9D,IAAI,IAAI,CAAC,GAAG,CAAC,KAAe,CAAC;QAAE,OAAO,YAAY,CAAC;IACnD,IAAI,CAAC,GAAG,CAAC,KAAe,CAAC,CAAC;IAC1B,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;IAC/C,CAAC;IACD,MAAM,GAAG,GAA4B,EAAE,CAAC;IACxC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAgC,CAAC,EAAE,CAAC;QACtE,IAAI,uBAAuB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YACpC,GAAG,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC;QACxB,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB;IAC1C,IAAI,CAAC;QACH,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAC;QAC5D,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,sBAAsB,CAAC,CAAC;QACxD,IAAI,MAAM,EAAE,CAAC;YACX,OAAO;gBACL,GAAG,4BAA4B;gBAC/B,GAAG,MAAM;aACa,CAAC;QAC3B,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IACV,OAAO,4BAA4B,CAAC;AACtC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,IAuCzC;IACC,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACzE,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC5B,MAAM,YAAY,GAAG,MAAM,EAAE,CAAC;IAE9B,0EAA0E;IAC1E,2EAA2E;IAC3E,2EAA2E;IAC3E,yEAAyE;IACzE,oDAAoD;IACpD,MAAM,kBAAkB,GAAG,cAAc,CAAC,WAAW,EAAE;QACrD,cAAc,EAAE,KAAK;QACrB,iBAAiB,EAAE,QAAQ,IAAI,SAAS;QACxC,eAAe,EAAE,MAAM,IAAI,SAAS;QACpC,aAAa,EAAE,QAAQ,CAAC,KAAK;KAC9B,CAAC,CAAC;IAEH,MAAM,KAAK,GAAgB,EAAE,CAAC;IAC9B,IAAI,qBAAqB,GAAG,CAAC,CAAC;IAC9B,oEAAoE;IACpE,MAAM,YAAY,GAAG,IAAI,GAAG,EAUzB,CAAC;IACJ,0EAA0E;IAC1E,2EAA2E;IAC3E,8EAA8E;IAC9E,+EAA+E;IAC/E,wEAAwE;IACxE,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAoB,CAAC;IAEvD,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,IAAI,eAAe,GAAG,CAAC,CAAC;IACxB,IAAI,WAAW,GAAG,CAAC,CAAC;IAEpB,wEAAwE;IACxE,gDAAgD;IAChD,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAa,CAAC;IAE/C,MAAM,gBAAgB,GAAG,CAAC,KAAqB,EAAQ,EAAE;QACvD,IAAI,CAAC;YACH,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;gBAChC,MAAM,OAAO,GAAG,qBAAqB,EAAE,CAAC;gBACxC,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC;gBACrB,iEAAiE;gBACjE,oEAAoE;gBACpE,qEAAqE;gBACrE,uEAAuE;gBACvE,MAAM,KAAK,GAYP;oBACF,MAAM,EAAE,GAAG;oBACX,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE;oBACnB,QAAQ,EAAE,KAAK,CAAC,IAAI;oBACpB,KAAK,EAAE,KAAK,CAAC,KAAK;oBAClB,QAAQ,EAAE,IAAI;iBACf,CAAC;gBACF,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;gBACjC,KAAK,cAAc,CAAC,WAAW,EAAE;oBAC/B,WAAW,EAAE,KAAK,CAAC,IAAI;iBACxB,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;oBACf,IAAI,CAAC,IAAI;wBAAE,OAAO;oBAClB,sEAAsE;oBACtE,+DAA+D;oBAC/D,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;wBACpB,YAAY,CAAC,IAAI,EAAE;4BACjB,MAAM,EAAE,KAAK,CAAC,SAAS,CAAC,MAAM;4BAC9B,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC,YAAY;yBAC3C,CAAC,CAAC;oBACL,CAAC;yBAAM,CAAC;wBACN,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC;wBACtB,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;oBAC9B,CAAC;gBACH,CAAC,CAAC,CAAC;gBACH,MAAM,KAAK,GAAG,kBAAkB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACjD,IAAI,KAAK;oBAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;;oBAC1B,kBAAkB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;YACrD,CAAC;iBAAM,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;gBACtC,MAAM,KAAK,GAAG,kBAAkB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACjD,MAAM,OAAO,GAAG,KAAK,EAAE,KAAK,EAAE,CAAC;gBAC/B,MAAM,OAAO,GACX,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;gBAChE,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;oBAC1B,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;oBAC7B,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;wBAC7B,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC1C,CAAC;gBACD,aAAa,EAAE,CAAC;gBAEhB,MAAM,OAAO,GACX,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ;oBAChC,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC;wBAC/B,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC,CAAC;gBAC/C,IAAI,OAAO;oBAAE,WAAW,EAAE,CAAC;;oBACtB,eAAe,EAAE,CAAC;gBAEvB,uEAAuE;gBACvE,oEAAoE;gBACpE,MAAM,aAAa,GAAG;oBACpB,MAAM,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAwB;oBAC9D,YAAY,EAAE,OAAO,CAAC,CAAC,CAAE,KAAK,CAAC,MAAiB,CAAC,CAAC,CAAC,IAAI;iBACxD,CAAC;gBACF,IAAI,OAAO,EAAE,QAAQ,EAAE,CAAC;oBACtB,iBAAiB,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;oBAC3C,YAAY,CAAC,OAAO,CAAC,QAAQ,EAAE;wBAC7B,MAAM,EAAE,aAAa,CAAC,MAAM;wBAC5B,YAAY,EAAE,aAAa,CAAC,YAAY;wBACxC,UAAU,EAAE,EAAE,WAAW,EAAE,KAAK,CAAC,IAAI,EAAE;qBACxC,CAAC,CAAC;gBACL,CAAC;qBAAM,IAAI,OAAO,EAAE,CAAC;oBACnB,OAAO,CAAC,SAAS,GAAG,aAAa,CAAC;gBACpC,CAAC;gBAED,MAAM,IAAI,GAAc;oBACtB,EAAE,EAAE,OAAO,EAAE,MAAM,IAAI,MAAM,EAAE;oBAC/B,KAAK;oBACL,QAAQ;oBACR,MAAM;oBACN,YAAY;oBACZ,QAAQ,EAAE,WAAW;oBACrB,IAAI,EAAE,KAAK,CAAC,IAAI;oBAChB,WAAW,EAAE,CAAC;oBACd,YAAY,EAAE,CAAC;oBACf,eAAe,EAAE,CAAC;oBAClB,gBAAgB,EAAE,CAAC;oBACnB,aAAa,EAAE,CAAC;oBAChB,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;oBACtD,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;oBACrC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI;oBAC3C,QAAQ,EACN,MAAM,CAAC,eAAe,IAAI,OAAO;wBAC/B,CAAC,CAAC,yDAAyD;4BACzD,sDAAsD;4BACtD,uDAAuD;4BACvD,oCAAoC;4BACpC;gCACE,KAAK,EAAE,qBAAqB,CAAC,OAAO,CAAC,KAAK,CAGzC;6BACF;wBACH,CAAC,CAAC,IAAI;oBACV,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;iBACtB,CAAC;gBACF,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnB,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;QAEV,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC,CAAC;IAEF,IAAI,KAAiC,CAAC;IACtC,IAAI,SAAS,GAAwB,SAAS,CAAC;IAC/C,IAAI,YAAY,GAAkB,IAAI,CAAC;IACvC,IAAI,WAAW,GAAmC,IAAI,CAAC;IACvD,IAAI,CAAC;QACH,KAAK,GAAG,MAAM,YAAY,CAAC,EAAE,GAAG,QAAQ,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC,CAAC;IACtE,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,MAAM,cAAc,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;QACzD,SAAS,GAAG,cAAc,EAAE,MAAM,IAAI,OAAO,CAAC;QAC9C,YAAY;YACV,cAAc,EAAE,YAAY,KAAK,SAAS;gBACxC,CAAC,CAAC,CAAC,GAAG,EAAE,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC;gBAC/B,CAAC,CAAC,cAAc,CAAC,YAAY,CAAC;QAClC,WAAW,GAAG,cAAc,EAAE,QAAQ,IAAI,IAAI,CAAC;QAC/C,MAAM,GAAG,CAAC;IACZ,CAAC;YAAS,CAAC;QACT,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC1B,MAAM,eAAe,GAAG,MAAM,GAAG,QAAQ,CAAC;QAE1C,IAAI,aAAa,GAAG,CAAC,CAAC;QACtB,IAAI,CAAC;YACH,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAAC;YAC5D,IAAI,KAAK,EAAE,CAAC;gBACV,aAAa,GAAG,aAAa,CAC3B,KAAK,CAAC,WAAW,EACjB,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,KAAK,EACX,KAAK,CAAC,eAAe,EACrB,KAAK,CAAC,gBAAgB,CACvB,CAAC;YACJ,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;QAEV,IAAI,YAAY,GAAG,CAAC,CAAC;QACrB,IAAI,KAAK,EAAE,CAAC;YACV,YAAY,GAAG,CAAC,CAAC;YACjB,MAAM,SAAS,GAAG,MAAM,EAAE,CAAC;YAC3B,MAAM,OAAO,GAAc;gBACzB,EAAE,EAAE,SAAS;gBACb,KAAK;gBACL,QAAQ;gBACR,MAAM;gBACN,YAAY;gBACZ,QAAQ,EAAE,UAAU;gBACpB,IAAI,EAAE,KAAK,CAAC,KAAK;gBACjB,WAAW,EAAE,KAAK,CAAC,WAAW;gBAC9B,YAAY,EAAE,KAAK,CAAC,YAAY;gBAChC,eAAe,EAAE,KAAK,CAAC,eAAe;gBACtC,gBAAgB,EAAE,KAAK,CAAC,gBAAgB;gBACxC,aAAa;gBACb,UAAU,EAAE,eAAe;gBAC3B,MAAM,EAAE,SAAS;gBACjB,YAAY;gBACZ,QAAQ,EAAE,IAAI;gBACd,SAAS,EAAE,QAAQ;aACpB,CAAC;YACF,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACpB,8BAA8B,CAAC;gBAC7B,KAAK;gBACL,QAAQ;gBACR,MAAM;gBACN,YAAY;gBACZ,SAAS;gBACT,UAAU,EACR,OAAO,QAAQ,CAAC,MAAM,EAAE,IAAI,KAAK,QAAQ;oBACvC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI;oBACtB,CAAC,CAAC,SAAS;gBACf,KAAK,EAAE,KAAK,CAAC,KAAK;gBAClB,WAAW,EAAE,KAAK,CAAC,WAAW;gBAC9B,YAAY,EAAE,KAAK,CAAC,YAAY;gBAChC,eAAe,EAAE,KAAK,CAAC,eAAe;gBACtC,gBAAgB,EAAE,KAAK,CAAC,gBAAgB;gBACxC,aAAa;gBACb,UAAU,EAAE,eAAe;gBAC3B,MAAM,EAAE,SAAS;gBACjB,YAAY;gBACZ,SAAS,EAAE,aAAa;gBACxB,eAAe;gBACf,WAAW;gBACX,SAAS,EAAE,QAAQ;aACpB,CAAC,CAAC;QACL,CAAC;QAED,MAAM,UAAU,GAAc;YAC5B,EAAE,EAAE,YAAY;YAChB,KAAK;YACL,QAAQ;YACR,MAAM;YACN,YAAY,EAAE,IAAI;YAClB,QAAQ,EAAE,WAAW;YACrB,IAAI,EAAE,WAAW;YACjB,WAAW,EAAE,KAAK,EAAE,WAAW,IAAI,CAAC;YACpC,YAAY,EAAE,KAAK,EAAE,YAAY,IAAI,CAAC;YACtC,eAAe,EAAE,KAAK,EAAE,eAAe,IAAI,CAAC;YAC5C,gBAAgB,EAAE,KAAK,EAAE,gBAAgB,IAAI,CAAC;YAC9C,aAAa;YACb,UAAU,EAAE,eAAe;YAC3B,MAAM,EAAE,SAAS;YACjB,YAAY;YACZ,QAAQ,EAAE,WAAW;YACrB,SAAS,EAAE,QAAQ;SACpB,CAAC;QACF,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAEvB,MAAM,OAAO,GAAiB;YAC5B,KAAK;YACL,QAAQ;YACR,MAAM;YACN,UAAU,EAAE,KAAK,CAAC,MAAM;YACxB,QAAQ,EAAE,YAAY;YACtB,SAAS,EAAE,aAAa;YACxB,eAAe;YACf,WAAW;YACX,eAAe;YACf,kBAAkB,EAAE,aAAa;YACjC,gBAAgB,EAAE,KAAK,EAAE,WAAW,IAAI,CAAC;YACzC,iBAAiB,EAAE,KAAK,EAAE,YAAY,IAAI,CAAC;YAC3C,KAAK,EAAE,KAAK,EAAE,KAAK,IAAI,QAAQ,CAAC,KAAK;YACrC,SAAS,EAAE,QAAQ;SACpB,CAAC;QAEF,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAE9D,uEAAuE;QACvE,uEAAuE;QACvE,6EAA6E;QAC7E,0EAA0E;QAC1E,IAAI,CAAC;YACH,IAAI,KAAK,EAAE,CAAC;gBACV,YAAY,CAAC,MAAM,cAAc,CAAC,UAAU,EAAE,EAAE,CAAC,EAAE;oBACjD,MAAM,EAAE,SAAS;oBACjB,YAAY;oBACZ,UAAU,EAAE;wBACV,WAAW,EAAE,KAAK,CAAC,KAAK;wBACxB,kBAAkB,EAAE,KAAK,CAAC,WAAW;wBACrC,mBAAmB,EAAE,KAAK,CAAC,YAAY;wBACvC,uBAAuB,EAAE,KAAK,CAAC,eAAe;wBAC9C,wBAAwB,EAAE,KAAK,CAAC,gBAAgB;wBAChD,qBAAqB,EAAE,aAAa;qBACrC;iBACF,CAAC,CAAC;YACL,CAAC;YACD,KAAK,MAAM,QAAQ,IAAI,iBAAiB,EAAE,CAAC;gBACzC,YAAY,CAAC,QAAQ,EAAE;oBACrB,MAAM,EAAE,OAAO;oBACf,YAAY,EAAE,mCAAmC;iBAClD,CAAC,CAAC;YACL,CAAC;YACD,iBAAiB,CAAC,KAAK,EAAE,CAAC;YAC1B,YAAY,CAAC,MAAM,kBAAkB,EAAE;gBACrC,MAAM,EAAE,SAAS;gBACjB,YAAY;gBACZ,UAAU,EAAE;oBACV,kBAAkB,EAAE,aAAa;oBACjC,wBAAwB,EAAE,eAAe;oBACzC,oBAAoB,EAAE,WAAW;oBACjC,mBAAmB,EAAE,eAAe;oBACpC,oBAAoB,EAAE,KAAK,EAAE,WAAW,IAAI,CAAC;oBAC7C,qBAAqB,EAAE,KAAK,EAAE,YAAY,IAAI,CAAC;oBAC/C,uBAAuB,EAAE,aAAa;iBACvC;aACF,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,wCAAwC;QAC1C,CAAC;IACH,CAAC;IAED,OAAO,KAAM,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,cAAc,CAC3B,KAAkB,EAClB,OAAqB,EACrB,KAAa,EACb,MAA2B;IAE3B,MAAM,EAAE,eAAe,EAAE,kBAAkB,EAAE,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;IAC3E,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACxE,MAAM,kBAAkB,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAElD,qDAAqD;IACrD,IAAI,CAAC;QACH,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;QACnD,MAAM,WAAW,CAAC,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC;IAClE,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;AACZ,CAAC","sourcesContent":["import type { AgentLoopUsage } from \"../agent/production-agent.js\";\nimport type { AgentChatEvent, AgentToolInput } from \"../agent/types.js\";\nimport { type AgentSpan, endAgentSpan, startAgentSpan } from \"./tracing.js\";\nimport type { TraceSpan, TraceSummary, ObservabilityConfig } from \"./types.js\";\nimport { DEFAULT_OBSERVABILITY_CONFIG } from \"./types.js\";\n\nfunction spanId(): string {\n return `span-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n}\n\nfunction normalizeTrackingSlug(value: string | undefined): string | undefined {\n const raw = value?.trim().toLowerCase();\n if (!raw) return undefined;\n return raw\n .replace(/^@agent-native\\//, \"\")\n .replace(/[^a-z0-9._-]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n}\n\nfunction appSlugFromUrl(value: string | undefined): string | undefined {\n if (!value?.trim()) return undefined;\n try {\n const raw = /^[a-z][a-z0-9+.-]*:\\/\\//i.test(value)\n ? value\n : `https://${value}`;\n const hostname = new URL(raw).hostname.toLowerCase();\n if (hostname.endsWith(\".agent-native.com\")) {\n return normalizeTrackingSlug(\n hostname.slice(0, -\".agent-native.com\".length),\n );\n }\n return normalizeTrackingSlug(hostname.split(\".\")[0]);\n } catch {\n return undefined;\n }\n}\n\nfunction trackingIdentityProperties(): Record<string, string> {\n const packageApp = normalizeTrackingSlug(process.env.npm_package_name);\n const urlApp =\n appSlugFromUrl(process.env.APP_URL) ||\n appSlugFromUrl(process.env.BETTER_AUTH_URL) ||\n appSlugFromUrl(process.env.URL) ||\n appSlugFromUrl(process.env.DEPLOY_URL) ||\n appSlugFromUrl(process.env.VERCEL_PROJECT_PRODUCTION_URL) ||\n appSlugFromUrl(process.env.VERCEL_URL);\n const app =\n normalizeTrackingSlug(process.env.AGENT_NATIVE_APP) ||\n normalizeTrackingSlug(process.env.VITE_AGENT_NATIVE_APP) ||\n urlApp ||\n packageApp ||\n normalizeTrackingSlug(process.env.APP_NAME);\n const template =\n normalizeTrackingSlug(process.env.AGENT_NATIVE_TEMPLATE) ||\n normalizeTrackingSlug(process.env.VITE_AGENT_NATIVE_TEMPLATE) ||\n normalizeTrackingSlug(process.env.APP_TEMPLATE) ||\n normalizeTrackingSlug(process.env.VITE_APP_TEMPLATE) ||\n app;\n\n return {\n ...(app ? { app, agent_native_app: app } : {}),\n ...(template ? { template, agent_native_template: template } : {}),\n };\n}\n\nfunction llmProviderFromEngine(\n engineName: string | undefined,\n model: string,\n): string {\n const engine = engineName?.trim();\n if (engine?.startsWith(\"ai-sdk:\")) return engine.slice(\"ai-sdk:\".length);\n if (engine) return engine;\n if (/claude|anthropic/i.test(model)) return \"anthropic\";\n if (/gpt|openai|codex/i.test(model)) return \"openai\";\n if (/gemini|google/i.test(model)) return \"google\";\n return \"unknown\";\n}\n\nfunction costUsdFromCenticents(value: number): number {\n return Math.round((value / 10_000) * 1_000_000) / 1_000_000;\n}\n\nfunction emitLlmGenerationTrackingEvent(args: {\n runId: string;\n threadId: string | null;\n userId: string | null;\n parentSpanId: string;\n llmSpanId: string;\n engineName: string | undefined;\n model: string;\n inputTokens: number;\n outputTokens: number;\n cacheReadTokens: number;\n cacheWriteTokens: number;\n costCentsX100: number;\n durationMs: number;\n status: \"success\" | \"error\";\n errorMessage: string | null;\n toolCalls: number;\n successfulTools: number;\n failedTools: number;\n createdAt: number;\n}): void {\n const provider = llmProviderFromEngine(args.engineName, args.model);\n const costUsd = costUsdFromCenticents(args.costCentsX100);\n const error = args.errorMessage ?? undefined;\n const properties: Record<string, unknown> = {\n ...trackingIdentityProperties(),\n source: \"agent_observability\",\n span_type: \"llm_call\",\n run_id: args.runId,\n thread_id: args.threadId,\n parent_span_id: args.parentSpanId,\n span_id: args.llmSpanId,\n model: args.model,\n provider,\n input_tokens: args.inputTokens,\n output_tokens: args.outputTokens,\n total_tokens: args.inputTokens + args.outputTokens,\n cache_read_tokens: args.cacheReadTokens,\n cache_write_tokens: args.cacheWriteTokens,\n cost_cents_x100: args.costCentsX100,\n cost_usd: costUsd,\n duration_ms: args.durationMs,\n status: args.status,\n tool_calls: args.toolCalls,\n successful_tools: args.successfulTools,\n failed_tools: args.failedTools,\n created_at: new Date(args.createdAt).toISOString(),\n created_at_ms: args.createdAt,\n $ai_trace_id: args.runId,\n $ai_session_id: args.threadId ?? undefined,\n $ai_span_id: args.llmSpanId,\n $ai_span_name: \"agent_run\",\n $ai_parent_id: args.parentSpanId,\n $ai_model: args.model,\n $ai_provider: provider,\n $ai_input_tokens: args.inputTokens,\n $ai_output_tokens: args.outputTokens,\n $ai_latency: Math.round((args.durationMs / 1000) * 1000) / 1000,\n $ai_is_error: args.status === \"error\",\n $ai_error: error,\n $ai_cache_read_input_tokens: args.cacheReadTokens,\n $ai_cache_creation_input_tokens: args.cacheWriteTokens,\n $ai_request_count: 1,\n $ai_total_cost_usd: costUsd,\n };\n if (error) properties.error_message = error;\n\n for (const key of Object.keys(properties)) {\n if (properties[key] === undefined) delete properties[key];\n }\n\n try {\n void import(\"../tracking/registry.js\")\n .then(({ track }) => {\n track(\"$ai_generation\", properties, {\n userId: args.userId ?? undefined,\n });\n })\n .catch(() => {});\n } catch {\n // Tracking must never affect the agent run or trace persistence.\n }\n}\n\n/** Keys whose values are stripped from persisted tool inputs when\n * `captureToolArgs` is enabled. Matched case-insensitively and tolerant\n * of `_` / `-` separators. M14 in the MCP/A2A audit: tool calls\n * routinely receive credentials verbatim (db-exec INSERTs, fetchTool\n * Authorization headers, ad-hoc bearer tokens) — keeping those values\n * out of agent_trace_spans.metadata avoids long-term storage of\n * short-lived secrets. */\nconst SENSITIVE_FIELD_PATTERN =\n /^(authorization|cookie|api[_-]?key|password|secret|token|access[_-]?token|refresh[_-]?token|bearer)$/i;\n\n/** Recursively walk a structured value and replace sensitive field\n * values with the literal string \"[REDACTED]\". Pure (returns a copy);\n * the original input is never mutated. Cycles are tolerated via a\n * small WeakSet seen-tracker that returns \"[Circular]\" for repeats. */\nexport function redactSensitiveFields(value: unknown): unknown {\n return redactWalk(value, new WeakSet<object>());\n}\n\nfunction redactWalk(value: unknown, seen: WeakSet<object>): unknown {\n if (value === null || typeof value !== \"object\") return value;\n if (seen.has(value as object)) return \"[Circular]\";\n seen.add(value as object);\n if (Array.isArray(value)) {\n return value.map((v) => redactWalk(v, seen));\n }\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n if (SENSITIVE_FIELD_PATTERN.test(k)) {\n out[k] = \"[REDACTED]\";\n } else {\n out[k] = redactWalk(v, seen);\n }\n }\n return out;\n}\n\nexport async function getObservabilityConfig(): Promise<ObservabilityConfig> {\n try {\n const { getSetting } = await import(\"../settings/store.js\");\n const stored = await getSetting(\"observability-config\");\n if (stored) {\n return {\n ...DEFAULT_OBSERVABILITY_CONFIG,\n ...stored,\n } as ObservabilityConfig;\n }\n } catch {}\n return DEFAULT_OBSERVABILITY_CONFIG;\n}\n\nexport async function instrumentAgentLoop(opts: {\n runAgentLoop: (loopOpts: {\n engine: any;\n model: string;\n systemPrompt: string;\n tools: any[];\n messages: any[];\n actions: Record<string, any>;\n send: (event: AgentChatEvent) => void;\n signal: AbortSignal;\n providerOptions?: any;\n }) => Promise<AgentLoopUsage>;\n loopOpts: {\n engine: any;\n model: string;\n systemPrompt: string;\n tools: any[];\n messages: any[];\n actions: Record<string, any>;\n send: (event: AgentChatEvent) => void;\n signal: AbortSignal;\n providerOptions?: any;\n };\n runId: string;\n threadId: string | null;\n /** Owner of this run; persisted on every span + summary so dashboard\n * reads can filter to a single user. Null for unauthenticated callers\n * (background tasks, etc.) — those rows aren't returned by per-user\n * reads. */\n userId: string | null;\n config: ObservabilityConfig;\n classifyError?: (error: unknown) =>\n | {\n status?: \"success\" | \"error\";\n errorMessage?: string | null;\n metadata?: Record<string, unknown> | null;\n }\n | null\n | undefined;\n}): Promise<AgentLoopUsage> {\n const { runAgentLoop, loopOpts, runId, threadId, userId, config } = opts;\n const runStart = Date.now();\n const parentSpanId = spanId();\n\n // Optional OpenTelemetry root span for this run. No-ops unless a host has\n // installed `@opentelemetry/api` and registered a provider. The promise is\n // resolved before the loop runs so child tool/model spans can parent under\n // it conceptually (we keep them flat in the same tracer, which is enough\n // for the dashboards an embedding app would build).\n const otelRunSpanPromise = startAgentSpan(\"agent.run\", {\n \"agent.run_id\": runId,\n \"agent.thread_id\": threadId ?? undefined,\n \"agent.user_id\": userId ?? undefined,\n \"agent.model\": loopOpts.model,\n });\n\n const spans: TraceSpan[] = [];\n let toolInvocationCounter = 0;\n // Keyed by counter to handle concurrent calls to the same tool name\n const pendingTools = new Map<\n number,\n {\n spanId: string;\n startMs: number;\n toolName: string;\n input: AgentToolInput;\n otelSpan: AgentSpan | null;\n endResult?: { status: \"success\" | \"error\"; errorMessage: string | null };\n }\n >();\n // Secondary index: tool name → FIFO queue of pending invocation counters.\n // tool_start/tool_done events carry only the tool name (no call id), so to\n // pair starts and dones correctly when the agent runs concurrent calls to the\n // same tool name (read-only / parallelSafe batches via Promise.all), we keep a\n // queue per name and match each done to the OLDEST still-pending start.\n const toolNameToCounters = new Map<string, number[]>();\n\n let toolCallCount = 0;\n let successfulTools = 0;\n let failedTools = 0;\n\n // Track in-flight OTel tool spans so they're all ended even if the loop\n // throws before a matching `tool_done` arrives.\n const openOtelToolSpans = new Set<AgentSpan>();\n\n const instrumentedSend = (event: AgentChatEvent): void => {\n try {\n if (event.type === \"tool_start\") {\n const counter = toolInvocationCounter++;\n const sid = spanId();\n // Start the OTel tool span synchronously-ish: kick off the async\n // resolution and stash the span once it lands. Tool spans are short\n // and the api tracer is synchronous in practice, but we tolerate the\n // microtask gap by recording the span on the pending entry when ready.\n const entry: {\n spanId: string;\n startMs: number;\n toolName: string;\n input: AgentToolInput;\n otelSpan: AgentSpan | null;\n // Set by the done handler if it fires before the span promise\n // resolves, so the resolved span is ended with the correct status.\n endResult?: {\n status: \"success\" | \"error\";\n errorMessage: string | null;\n };\n } = {\n spanId: sid,\n startMs: Date.now(),\n toolName: event.tool,\n input: event.input,\n otelSpan: null,\n };\n pendingTools.set(counter, entry);\n void startAgentSpan(\"tool.call\", {\n \"tool.name\": event.tool,\n }).then((span) => {\n if (!span) return;\n // If `tool_done` already ran for this call, end the span now with the\n // status it recorded; otherwise stash it for the done handler.\n if (entry.endResult) {\n endAgentSpan(span, {\n status: entry.endResult.status,\n errorMessage: entry.endResult.errorMessage,\n });\n } else {\n entry.otelSpan = span;\n openOtelToolSpans.add(span);\n }\n });\n const queue = toolNameToCounters.get(event.tool);\n if (queue) queue.push(counter);\n else toolNameToCounters.set(event.tool, [counter]);\n } else if (event.type === \"tool_done\") {\n const queue = toolNameToCounters.get(event.tool);\n const counter = queue?.shift();\n const pending =\n counter !== undefined ? pendingTools.get(counter) : undefined;\n if (counter !== undefined) {\n pendingTools.delete(counter);\n if (queue && queue.length === 0)\n toolNameToCounters.delete(event.tool);\n }\n toolCallCount++;\n\n const isError =\n typeof event.result === \"string\" &&\n (event.result.startsWith(\"Error\") ||\n event.result.startsWith(\"Error running \"));\n if (isError) failedTools++;\n else successfulTools++;\n\n // Finalize the OTel tool span. If the span promise hasn't resolved yet\n // we record the result on the entry so its `.then` handler ends it.\n const otelEndResult = {\n status: (isError ? \"error\" : \"success\") as \"success\" | \"error\",\n errorMessage: isError ? (event.result as string) : null,\n };\n if (pending?.otelSpan) {\n openOtelToolSpans.delete(pending.otelSpan);\n endAgentSpan(pending.otelSpan, {\n status: otelEndResult.status,\n errorMessage: otelEndResult.errorMessage,\n attributes: { \"tool.name\": event.tool },\n });\n } else if (pending) {\n pending.endResult = otelEndResult;\n }\n\n const span: TraceSpan = {\n id: pending?.spanId ?? spanId(),\n runId,\n threadId,\n userId,\n parentSpanId,\n spanType: \"tool_call\",\n name: event.tool,\n inputTokens: 0,\n outputTokens: 0,\n cacheReadTokens: 0,\n cacheWriteTokens: 0,\n costCentsX100: 0,\n durationMs: pending ? Date.now() - pending.startMs : 0,\n status: isError ? \"error\" : \"success\",\n errorMessage: isError ? event.result : null,\n metadata:\n config.captureToolArgs && pending\n ? // Strip Authorization/api-key/token-shaped values before\n // persisting (M14 in the MCP/A2A audit). Tool-runtime\n // execution still sees the unredacted input — only the\n // long-lived span row is sanitized.\n {\n input: redactSensitiveFields(pending.input) as Record<\n string,\n string\n >,\n }\n : null,\n createdAt: Date.now(),\n };\n spans.push(span);\n }\n } catch {}\n\n loopOpts.send(event);\n };\n\n let usage: AgentLoopUsage | undefined;\n let runStatus: \"success\" | \"error\" = \"success\";\n let errorMessage: string | null = null;\n let runMetadata: Record<string, unknown> | null = null;\n try {\n usage = await runAgentLoop({ ...loopOpts, send: instrumentedSend });\n } catch (err: any) {\n const classification = opts.classifyError?.(err) ?? null;\n runStatus = classification?.status ?? \"error\";\n errorMessage =\n classification?.errorMessage === undefined\n ? (err?.message ?? String(err))\n : classification.errorMessage;\n runMetadata = classification?.metadata ?? null;\n throw err;\n } finally {\n const runEnd = Date.now();\n const totalDurationMs = runEnd - runStart;\n\n let costCentsX100 = 0;\n try {\n const { calculateCost } = await import(\"../usage/store.js\");\n if (usage) {\n costCentsX100 = calculateCost(\n usage.inputTokens,\n usage.outputTokens,\n usage.model,\n usage.cacheReadTokens,\n usage.cacheWriteTokens,\n );\n }\n } catch {}\n\n let llmCallCount = 0;\n if (usage) {\n llmCallCount = 1;\n const llmSpanId = spanId();\n const llmSpan: TraceSpan = {\n id: llmSpanId,\n runId,\n threadId,\n userId,\n parentSpanId,\n spanType: \"llm_call\",\n name: usage.model,\n inputTokens: usage.inputTokens,\n outputTokens: usage.outputTokens,\n cacheReadTokens: usage.cacheReadTokens,\n cacheWriteTokens: usage.cacheWriteTokens,\n costCentsX100,\n durationMs: totalDurationMs,\n status: runStatus,\n errorMessage,\n metadata: null,\n createdAt: runStart,\n };\n spans.push(llmSpan);\n emitLlmGenerationTrackingEvent({\n runId,\n threadId,\n userId,\n parentSpanId,\n llmSpanId,\n engineName:\n typeof loopOpts.engine?.name === \"string\"\n ? loopOpts.engine.name\n : undefined,\n model: usage.model,\n inputTokens: usage.inputTokens,\n outputTokens: usage.outputTokens,\n cacheReadTokens: usage.cacheReadTokens,\n cacheWriteTokens: usage.cacheWriteTokens,\n costCentsX100,\n durationMs: totalDurationMs,\n status: runStatus,\n errorMessage,\n toolCalls: toolCallCount,\n successfulTools,\n failedTools,\n createdAt: runStart,\n });\n }\n\n const parentSpan: TraceSpan = {\n id: parentSpanId,\n runId,\n threadId,\n userId,\n parentSpanId: null,\n spanType: \"agent_run\",\n name: \"agent_run\",\n inputTokens: usage?.inputTokens ?? 0,\n outputTokens: usage?.outputTokens ?? 0,\n cacheReadTokens: usage?.cacheReadTokens ?? 0,\n cacheWriteTokens: usage?.cacheWriteTokens ?? 0,\n costCentsX100,\n durationMs: totalDurationMs,\n status: runStatus,\n errorMessage,\n metadata: runMetadata,\n createdAt: runStart,\n };\n spans.push(parentSpan);\n\n const summary: TraceSummary = {\n runId,\n threadId,\n userId,\n totalSpans: spans.length,\n llmCalls: llmCallCount,\n toolCalls: toolCallCount,\n successfulTools,\n failedTools,\n totalDurationMs,\n totalCostCentsX100: costCentsX100,\n totalInputTokens: usage?.inputTokens ?? 0,\n totalOutputTokens: usage?.outputTokens ?? 0,\n model: usage?.model ?? loopOpts.model,\n createdAt: runStart,\n };\n\n writeTraceData(spans, summary, runId, config).catch(() => {});\n\n // OpenTelemetry export (no-op unless a provider is registered). Emit a\n // self-contained `llm.call` span carrying model + token usage, end any\n // tool spans still open (loop threw mid-tool), and end the run span. Awaited\n // so the spans are emitted before the function returns; cheap when no-op.\n try {\n if (usage) {\n endAgentSpan(await startAgentSpan(\"llm.call\", {}), {\n status: runStatus,\n errorMessage,\n attributes: {\n \"llm.model\": usage.model,\n \"llm.input_tokens\": usage.inputTokens,\n \"llm.output_tokens\": usage.outputTokens,\n \"llm.cache_read_tokens\": usage.cacheReadTokens,\n \"llm.cache_write_tokens\": usage.cacheWriteTokens,\n \"llm.cost_cents_x100\": costCentsX100,\n },\n });\n }\n for (const toolSpan of openOtelToolSpans) {\n endAgentSpan(toolSpan, {\n status: \"error\",\n errorMessage: \"Agent run ended before tool_done.\",\n });\n }\n openOtelToolSpans.clear();\n endAgentSpan(await otelRunSpanPromise, {\n status: runStatus,\n errorMessage,\n attributes: {\n \"agent.tool_calls\": toolCallCount,\n \"agent.successful_tools\": successfulTools,\n \"agent.failed_tools\": failedTools,\n \"agent.duration_ms\": totalDurationMs,\n \"agent.input_tokens\": usage?.inputTokens ?? 0,\n \"agent.output_tokens\": usage?.outputTokens ?? 0,\n \"agent.cost_cents_x100\": costCentsX100,\n },\n });\n } catch {\n // OTel export must never break the run.\n }\n }\n\n return usage!;\n}\n\nasync function writeTraceData(\n spans: TraceSpan[],\n summary: TraceSummary,\n runId: string,\n config: ObservabilityConfig,\n): Promise<void> {\n const { insertTraceSpan, upsertTraceSummary } = await import(\"./store.js\");\n await Promise.all(spans.map((s) => insertTraceSpan(s).catch(() => {})));\n await upsertTraceSummary(summary).catch(() => {});\n\n // Fire automated evals after trace data is persisted\n try {\n const { evaluateRun } = await import(\"./evals.js\");\n await evaluateRun(runId, { sampleRate: config.evalSampleRate });\n } catch {}\n}\n"]}
1
+ {"version":3,"file":"traces.js","sourceRoot":"","sources":["../../src/observability/traces.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentLoopUsage } from \"../agent/production-agent.js\";\nimport type { AgentChatEvent, AgentToolInput } from \"../agent/types.js\";\nimport { type AgentSpan, endAgentSpan, startAgentSpan } from \"./tracing.js\";\nimport type { TraceSpan, TraceSummary, ObservabilityConfig } from \"./types.js\";\nimport { DEFAULT_OBSERVABILITY_CONFIG } from \"./types.js\";\n\nfunction spanId(): string {\n return `span-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n}\n\nfunction normalizeTrackingSlug(value: string | undefined): string | undefined {\n const raw = value?.trim().toLowerCase();\n if (!raw) return undefined;\n return raw\n .replace(/^@agent-native\\//, \"\")\n .replace(/[^a-z0-9._-]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n}\n\nfunction appSlugFromUrl(value: string | undefined): string | undefined {\n if (!value?.trim()) return undefined;\n try {\n const raw = /^[a-z][a-z0-9+.-]*:\\/\\//i.test(value)\n ? value\n : `https://${value}`;\n const hostname = new URL(raw).hostname.toLowerCase();\n if (hostname.endsWith(\".agent-native.com\")) {\n return normalizeTrackingSlug(\n hostname.slice(0, -\".agent-native.com\".length),\n );\n }\n return normalizeTrackingSlug(hostname.split(\".\")[0]);\n } catch {\n return undefined;\n }\n}\n\nfunction trackingIdentityProperties(): Record<string, string> {\n const packageApp = normalizeTrackingSlug(process.env.npm_package_name);\n const urlApp =\n appSlugFromUrl(process.env.APP_URL) ||\n appSlugFromUrl(process.env.BETTER_AUTH_URL) ||\n appSlugFromUrl(process.env.URL) ||\n appSlugFromUrl(process.env.DEPLOY_URL) ||\n appSlugFromUrl(process.env.VERCEL_PROJECT_PRODUCTION_URL) ||\n appSlugFromUrl(process.env.VERCEL_URL);\n const app =\n normalizeTrackingSlug(process.env.AGENT_NATIVE_APP) ||\n normalizeTrackingSlug(process.env.VITE_AGENT_NATIVE_APP) ||\n urlApp ||\n packageApp ||\n normalizeTrackingSlug(process.env.APP_NAME);\n const template =\n normalizeTrackingSlug(process.env.AGENT_NATIVE_TEMPLATE) ||\n normalizeTrackingSlug(process.env.VITE_AGENT_NATIVE_TEMPLATE) ||\n normalizeTrackingSlug(process.env.APP_TEMPLATE) ||\n normalizeTrackingSlug(process.env.VITE_APP_TEMPLATE) ||\n app;\n\n return {\n ...(app ? { app, agent_native_app: app } : {}),\n ...(template ? { template, agent_native_template: template } : {}),\n };\n}\n\nfunction llmProviderFromEngine(\n engineName: string | undefined,\n model: string,\n): string {\n const engine = engineName?.trim();\n if (engine?.startsWith(\"ai-sdk:\")) return engine.slice(\"ai-sdk:\".length);\n if (engine) return engine;\n if (/claude|anthropic/i.test(model)) return \"anthropic\";\n if (/gpt|openai|codex/i.test(model)) return \"openai\";\n if (/gemini|google/i.test(model)) return \"google\";\n return \"unknown\";\n}\n\nfunction costUsdFromCenticents(value: number): number {\n return Math.round((value / 10_000) * 1_000_000) / 1_000_000;\n}\n\nfunction emitLlmGenerationTrackingEvent(args: {\n runId: string;\n threadId: string | null;\n userId: string | null;\n parentSpanId: string;\n llmSpanId: string;\n engineName: string | undefined;\n model: string;\n inputTokens: number;\n outputTokens: number;\n cacheReadTokens: number;\n cacheWriteTokens: number;\n costCentsX100: number;\n durationMs: number;\n status: \"success\" | \"error\";\n errorMessage: string | null;\n toolCalls: number;\n successfulTools: number;\n failedTools: number;\n createdAt: number;\n experimentAssignments?: Array<{\n experimentId: string;\n variantId: string;\n }>;\n modelSelectionSource?: string;\n}): void {\n const provider = llmProviderFromEngine(args.engineName, args.model);\n const costUsd = costUsdFromCenticents(args.costCentsX100);\n const error = args.errorMessage ?? undefined;\n const properties: Record<string, unknown> = {\n ...trackingIdentityProperties(),\n source: \"agent_observability\",\n span_type: \"llm_call\",\n run_id: args.runId,\n thread_id: args.threadId,\n parent_span_id: args.parentSpanId,\n span_id: args.llmSpanId,\n model: args.model,\n provider,\n input_tokens: args.inputTokens,\n output_tokens: args.outputTokens,\n total_tokens: args.inputTokens + args.outputTokens,\n cache_read_tokens: args.cacheReadTokens,\n cache_write_tokens: args.cacheWriteTokens,\n cost_cents_x100: args.costCentsX100,\n cost_usd: costUsd,\n duration_ms: args.durationMs,\n status: args.status,\n tool_calls: args.toolCalls,\n successful_tools: args.successfulTools,\n failed_tools: args.failedTools,\n model_selection_source: args.modelSelectionSource,\n created_at: new Date(args.createdAt).toISOString(),\n created_at_ms: args.createdAt,\n $ai_trace_id: args.runId,\n $ai_session_id: args.threadId ?? undefined,\n $ai_span_id: args.llmSpanId,\n $ai_span_name: \"agent_run\",\n $ai_parent_id: args.parentSpanId,\n $ai_model: args.model,\n $ai_provider: provider,\n $ai_input_tokens: args.inputTokens,\n $ai_output_tokens: args.outputTokens,\n $ai_latency: Math.round((args.durationMs / 1000) * 1000) / 1000,\n $ai_is_error: args.status === \"error\",\n $ai_error: error,\n $ai_cache_read_input_tokens: args.cacheReadTokens,\n $ai_cache_creation_input_tokens: args.cacheWriteTokens,\n $ai_request_count: 1,\n $ai_total_cost_usd: costUsd,\n };\n if (args.experimentAssignments?.length) {\n properties.experiment_ids = args.experimentAssignments\n .map((assignment) => assignment.experimentId)\n .join(\",\");\n properties.experiment_variants = args.experimentAssignments\n .map((assignment) => assignment.variantId)\n .join(\",\");\n if (args.experimentAssignments.length === 1) {\n properties.experiment_id = args.experimentAssignments[0].experimentId;\n properties.experiment_variant = args.experimentAssignments[0].variantId;\n }\n }\n if (error) properties.error_message = error;\n\n for (const key of Object.keys(properties)) {\n if (properties[key] === undefined) delete properties[key];\n }\n\n try {\n void import(\"../tracking/registry.js\")\n .then(({ track }) => {\n track(\"$ai_generation\", properties, {\n userId: args.userId ?? undefined,\n });\n })\n .catch(() => {});\n } catch {\n // Tracking must never affect the agent run or trace persistence.\n }\n}\n\n/** Keys whose values are stripped from persisted tool inputs when\n * `captureToolArgs` is enabled. Matched case-insensitively and tolerant\n * of `_` / `-` separators. M14 in the MCP/A2A audit: tool calls\n * routinely receive credentials verbatim (db-exec INSERTs, fetchTool\n * Authorization headers, ad-hoc bearer tokens) — keeping those values\n * out of agent_trace_spans.metadata avoids long-term storage of\n * short-lived secrets. */\nconst SENSITIVE_FIELD_PATTERN =\n /^(authorization|cookie|api[_-]?key|password|secret|token|access[_-]?token|refresh[_-]?token|bearer)$/i;\n\n/** Recursively walk a structured value and replace sensitive field\n * values with the literal string \"[REDACTED]\". Pure (returns a copy);\n * the original input is never mutated. Cycles are tolerated via a\n * small WeakSet seen-tracker that returns \"[Circular]\" for repeats. */\nexport function redactSensitiveFields(value: unknown): unknown {\n return redactWalk(value, new WeakSet<object>());\n}\n\nfunction redactWalk(value: unknown, seen: WeakSet<object>): unknown {\n if (value === null || typeof value !== \"object\") return value;\n if (seen.has(value as object)) return \"[Circular]\";\n seen.add(value as object);\n if (Array.isArray(value)) {\n return value.map((v) => redactWalk(v, seen));\n }\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n if (SENSITIVE_FIELD_PATTERN.test(k)) {\n out[k] = \"[REDACTED]\";\n } else {\n out[k] = redactWalk(v, seen);\n }\n }\n return out;\n}\n\nexport async function getObservabilityConfig(): Promise<ObservabilityConfig> {\n try {\n const { getSetting } = await import(\"../settings/store.js\");\n const stored = await getSetting(\"observability-config\");\n if (stored) {\n return {\n ...DEFAULT_OBSERVABILITY_CONFIG,\n ...stored,\n } as ObservabilityConfig;\n }\n } catch {}\n return DEFAULT_OBSERVABILITY_CONFIG;\n}\n\nexport async function instrumentAgentLoop(opts: {\n runAgentLoop: (loopOpts: {\n engine: any;\n model: string;\n systemPrompt: string;\n tools: any[];\n messages: any[];\n actions: Record<string, any>;\n send: (event: AgentChatEvent) => void;\n signal: AbortSignal;\n providerOptions?: any;\n }) => Promise<AgentLoopUsage>;\n loopOpts: {\n engine: any;\n model: string;\n systemPrompt: string;\n tools: any[];\n messages: any[];\n actions: Record<string, any>;\n send: (event: AgentChatEvent) => void;\n signal: AbortSignal;\n providerOptions?: any;\n };\n runId: string;\n threadId: string | null;\n /** Owner of this run; persisted on every span + summary so dashboard\n * reads can filter to a single user. Null for unauthenticated callers\n * (background tasks, etc.) — those rows aren't returned by per-user\n * reads. */\n userId: string | null;\n config: ObservabilityConfig;\n metadata?: Record<string, unknown> | null;\n experimentAssignments?: Array<{\n experimentId: string;\n variantId: string;\n }>;\n modelSelectionSource?: string;\n classifyError?: (error: unknown) =>\n | {\n status?: \"success\" | \"error\";\n errorMessage?: string | null;\n metadata?: Record<string, unknown> | null;\n }\n | null\n | undefined;\n}): Promise<AgentLoopUsage> {\n const { runAgentLoop, loopOpts, runId, threadId, userId, config } = opts;\n const runStart = Date.now();\n const parentSpanId = spanId();\n\n // Optional OpenTelemetry root span for this run. No-ops unless a host has\n // installed `@opentelemetry/api` and registered a provider. The promise is\n // resolved before the loop runs so child tool/model spans can parent under\n // it conceptually (we keep them flat in the same tracer, which is enough\n // for the dashboards an embedding app would build).\n const otelRunSpanPromise = startAgentSpan(\"agent.run\", {\n \"agent.run_id\": runId,\n \"agent.thread_id\": threadId ?? undefined,\n \"agent.user_id\": userId ?? undefined,\n \"agent.model\": loopOpts.model,\n \"agent.model_selection_source\": opts.modelSelectionSource,\n \"agent.experiment_id\":\n opts.experimentAssignments?.length === 1\n ? opts.experimentAssignments[0].experimentId\n : undefined,\n \"agent.experiment_variant\":\n opts.experimentAssignments?.length === 1\n ? opts.experimentAssignments[0].variantId\n : undefined,\n });\n\n const spans: TraceSpan[] = [];\n let toolInvocationCounter = 0;\n // Keyed by counter to handle concurrent calls to the same tool name\n const pendingTools = new Map<\n number,\n {\n spanId: string;\n startMs: number;\n toolName: string;\n input: AgentToolInput;\n otelSpan: AgentSpan | null;\n endResult?: { status: \"success\" | \"error\"; errorMessage: string | null };\n }\n >();\n // Secondary index: tool name → FIFO queue of pending invocation counters.\n // tool_start/tool_done events carry only the tool name (no call id), so to\n // pair starts and dones correctly when the agent runs concurrent calls to the\n // same tool name (read-only / parallelSafe batches via Promise.all), we keep a\n // queue per name and match each done to the OLDEST still-pending start.\n const toolNameToCounters = new Map<string, number[]>();\n\n let toolCallCount = 0;\n let successfulTools = 0;\n let failedTools = 0;\n\n // Track in-flight OTel tool spans so they're all ended even if the loop\n // throws before a matching `tool_done` arrives.\n const openOtelToolSpans = new Set<AgentSpan>();\n\n const instrumentedSend = (event: AgentChatEvent): void => {\n try {\n if (event.type === \"tool_start\") {\n const counter = toolInvocationCounter++;\n const sid = spanId();\n // Start the OTel tool span synchronously-ish: kick off the async\n // resolution and stash the span once it lands. Tool spans are short\n // and the api tracer is synchronous in practice, but we tolerate the\n // microtask gap by recording the span on the pending entry when ready.\n const entry: {\n spanId: string;\n startMs: number;\n toolName: string;\n input: AgentToolInput;\n otelSpan: AgentSpan | null;\n // Set by the done handler if it fires before the span promise\n // resolves, so the resolved span is ended with the correct status.\n endResult?: {\n status: \"success\" | \"error\";\n errorMessage: string | null;\n };\n } = {\n spanId: sid,\n startMs: Date.now(),\n toolName: event.tool,\n input: event.input,\n otelSpan: null,\n };\n pendingTools.set(counter, entry);\n void startAgentSpan(\"tool.call\", {\n \"tool.name\": event.tool,\n }).then((span) => {\n if (!span) return;\n // If `tool_done` already ran for this call, end the span now with the\n // status it recorded; otherwise stash it for the done handler.\n if (entry.endResult) {\n endAgentSpan(span, {\n status: entry.endResult.status,\n errorMessage: entry.endResult.errorMessage,\n });\n } else {\n entry.otelSpan = span;\n openOtelToolSpans.add(span);\n }\n });\n const queue = toolNameToCounters.get(event.tool);\n if (queue) queue.push(counter);\n else toolNameToCounters.set(event.tool, [counter]);\n } else if (event.type === \"tool_done\") {\n const queue = toolNameToCounters.get(event.tool);\n const counter = queue?.shift();\n const pending =\n counter !== undefined ? pendingTools.get(counter) : undefined;\n if (counter !== undefined) {\n pendingTools.delete(counter);\n if (queue && queue.length === 0)\n toolNameToCounters.delete(event.tool);\n }\n toolCallCount++;\n\n const isError =\n typeof event.result === \"string\" &&\n (event.result.startsWith(\"Error\") ||\n event.result.startsWith(\"Error running \"));\n if (isError) failedTools++;\n else successfulTools++;\n\n // Finalize the OTel tool span. If the span promise hasn't resolved yet\n // we record the result on the entry so its `.then` handler ends it.\n const otelEndResult = {\n status: (isError ? \"error\" : \"success\") as \"success\" | \"error\",\n errorMessage: isError ? (event.result as string) : null,\n };\n if (pending?.otelSpan) {\n openOtelToolSpans.delete(pending.otelSpan);\n endAgentSpan(pending.otelSpan, {\n status: otelEndResult.status,\n errorMessage: otelEndResult.errorMessage,\n attributes: { \"tool.name\": event.tool },\n });\n } else if (pending) {\n pending.endResult = otelEndResult;\n }\n\n const span: TraceSpan = {\n id: pending?.spanId ?? spanId(),\n runId,\n threadId,\n userId,\n parentSpanId,\n spanType: \"tool_call\",\n name: event.tool,\n inputTokens: 0,\n outputTokens: 0,\n cacheReadTokens: 0,\n cacheWriteTokens: 0,\n costCentsX100: 0,\n durationMs: pending ? Date.now() - pending.startMs : 0,\n status: isError ? \"error\" : \"success\",\n errorMessage: isError ? event.result : null,\n metadata:\n config.captureToolArgs && pending\n ? // Strip Authorization/api-key/token-shaped values before\n // persisting (M14 in the MCP/A2A audit). Tool-runtime\n // execution still sees the unredacted input — only the\n // long-lived span row is sanitized.\n {\n input: redactSensitiveFields(pending.input) as Record<\n string,\n string\n >,\n }\n : null,\n createdAt: Date.now(),\n };\n spans.push(span);\n }\n } catch {}\n\n loopOpts.send(event);\n };\n\n let usage: AgentLoopUsage | undefined;\n let runStatus: \"success\" | \"error\" = \"success\";\n let errorMessage: string | null = null;\n let runMetadata: Record<string, unknown> | null = opts.metadata ?? null;\n try {\n usage = await runAgentLoop({ ...loopOpts, send: instrumentedSend });\n } catch (err: any) {\n const classification = opts.classifyError?.(err) ?? null;\n runStatus = classification?.status ?? \"error\";\n errorMessage =\n classification?.errorMessage === undefined\n ? (err?.message ?? String(err))\n : classification.errorMessage;\n const errorMetadata = classification?.metadata ?? null;\n runMetadata =\n runMetadata || errorMetadata\n ? { ...(runMetadata ?? {}), ...(errorMetadata ?? {}) }\n : null;\n throw err;\n } finally {\n const runEnd = Date.now();\n const totalDurationMs = runEnd - runStart;\n\n let costCentsX100 = 0;\n try {\n const { calculateCost } = await import(\"../usage/store.js\");\n if (usage) {\n costCentsX100 = calculateCost(\n usage.inputTokens,\n usage.outputTokens,\n usage.model,\n usage.cacheReadTokens,\n usage.cacheWriteTokens,\n );\n }\n } catch {}\n\n let llmCallCount = 0;\n if (usage) {\n llmCallCount = 1;\n const llmSpanId = spanId();\n const llmSpan: TraceSpan = {\n id: llmSpanId,\n runId,\n threadId,\n userId,\n parentSpanId,\n spanType: \"llm_call\",\n name: usage.model,\n inputTokens: usage.inputTokens,\n outputTokens: usage.outputTokens,\n cacheReadTokens: usage.cacheReadTokens,\n cacheWriteTokens: usage.cacheWriteTokens,\n costCentsX100,\n durationMs: totalDurationMs,\n status: runStatus,\n errorMessage,\n metadata: null,\n createdAt: runStart,\n };\n spans.push(llmSpan);\n emitLlmGenerationTrackingEvent({\n runId,\n threadId,\n userId,\n parentSpanId,\n llmSpanId,\n engineName:\n typeof loopOpts.engine?.name === \"string\"\n ? loopOpts.engine.name\n : undefined,\n model: usage.model,\n inputTokens: usage.inputTokens,\n outputTokens: usage.outputTokens,\n cacheReadTokens: usage.cacheReadTokens,\n cacheWriteTokens: usage.cacheWriteTokens,\n costCentsX100,\n durationMs: totalDurationMs,\n status: runStatus,\n errorMessage,\n toolCalls: toolCallCount,\n successfulTools,\n failedTools,\n createdAt: runStart,\n experimentAssignments: opts.experimentAssignments,\n modelSelectionSource: opts.modelSelectionSource,\n });\n }\n\n const parentSpan: TraceSpan = {\n id: parentSpanId,\n runId,\n threadId,\n userId,\n parentSpanId: null,\n spanType: \"agent_run\",\n name: \"agent_run\",\n inputTokens: usage?.inputTokens ?? 0,\n outputTokens: usage?.outputTokens ?? 0,\n cacheReadTokens: usage?.cacheReadTokens ?? 0,\n cacheWriteTokens: usage?.cacheWriteTokens ?? 0,\n costCentsX100,\n durationMs: totalDurationMs,\n status: runStatus,\n errorMessage,\n metadata: runMetadata,\n createdAt: runStart,\n };\n spans.push(parentSpan);\n\n const summary: TraceSummary = {\n runId,\n threadId,\n userId,\n totalSpans: spans.length,\n llmCalls: llmCallCount,\n toolCalls: toolCallCount,\n successfulTools,\n failedTools,\n totalDurationMs,\n totalCostCentsX100: costCentsX100,\n totalInputTokens: usage?.inputTokens ?? 0,\n totalOutputTokens: usage?.outputTokens ?? 0,\n model: usage?.model ?? loopOpts.model,\n createdAt: runStart,\n };\n\n writeTraceData(spans, summary, runId, config).catch(() => {});\n\n // OpenTelemetry export (no-op unless a provider is registered). Emit a\n // self-contained `llm.call` span carrying model + token usage, end any\n // tool spans still open (loop threw mid-tool), and end the run span. Awaited\n // so the spans are emitted before the function returns; cheap when no-op.\n try {\n if (usage) {\n endAgentSpan(await startAgentSpan(\"llm.call\", {}), {\n status: runStatus,\n errorMessage,\n attributes: {\n \"llm.model\": usage.model,\n \"llm.input_tokens\": usage.inputTokens,\n \"llm.output_tokens\": usage.outputTokens,\n \"llm.cache_read_tokens\": usage.cacheReadTokens,\n \"llm.cache_write_tokens\": usage.cacheWriteTokens,\n \"llm.cost_cents_x100\": costCentsX100,\n },\n });\n }\n for (const toolSpan of openOtelToolSpans) {\n endAgentSpan(toolSpan, {\n status: \"error\",\n errorMessage: \"Agent run ended before tool_done.\",\n });\n }\n openOtelToolSpans.clear();\n endAgentSpan(await otelRunSpanPromise, {\n status: runStatus,\n errorMessage,\n attributes: {\n \"agent.tool_calls\": toolCallCount,\n \"agent.successful_tools\": successfulTools,\n \"agent.failed_tools\": failedTools,\n \"agent.duration_ms\": totalDurationMs,\n \"agent.input_tokens\": usage?.inputTokens ?? 0,\n \"agent.output_tokens\": usage?.outputTokens ?? 0,\n \"agent.cost_cents_x100\": costCentsX100,\n },\n });\n } catch {\n // OTel export must never break the run.\n }\n }\n\n return usage!;\n}\n\nasync function writeTraceData(\n spans: TraceSpan[],\n summary: TraceSummary,\n runId: string,\n config: ObservabilityConfig,\n): Promise<void> {\n const { insertTraceSpan, upsertTraceSummary } = await import(\"./store.js\");\n await Promise.all(spans.map((s) => insertTraceSpan(s).catch(() => {})));\n await upsertTraceSummary(summary).catch(() => {});\n\n // Fire automated evals after trace data is persisted\n try {\n const { evaluateRun } = await import(\"./evals.js\");\n await evaluateRun(runId, { sampleRate: config.evalSampleRate });\n } catch {}\n}\n"]}
@@ -73,7 +73,6 @@ export declare function createProviderCorpusJobAction(options: CreateProviderCor
73
73
  offset?: unknown;
74
74
  limit?: unknown;
75
75
  }, {
76
- deleted?: undefined;
77
76
  jobs: {
78
77
  id: string;
79
78
  name: string;
@@ -84,6 +83,7 @@ export declare function createProviderCorpusJobAction(options: CreateProviderCor
84
83
  updatedAt: string;
85
84
  }[];
86
85
  total: number;
86
+ deleted?: undefined;
87
87
  jobId?: undefined;
88
88
  } | {
89
89
  jobs?: undefined;
@@ -91,9 +91,9 @@ export declare function createProviderCorpusJobAction(options: CreateProviderCor
91
91
  deleted: boolean;
92
92
  jobId: string;
93
93
  } | {
94
- deleted?: undefined;
95
94
  jobs?: undefined;
96
95
  total?: undefined;
96
+ deleted?: undefined;
97
97
  jobId?: undefined;
98
98
  hits: Record<string, unknown>[];
99
99
  offset: number;
@@ -1 +1 @@
1
- {"version":3,"file":"list-agent-engines.d.ts","sourceRoot":"","sources":["../../../src/scripts/agent-engines/list-agent-engines.ts"],"names":[],"mappings":"AAAA;;GAEG;AAcH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAGvD,eAAO,MAAM,IAAI,EAAE,UAQlB,CAAC;AAEF,wBAAsB,GAAG,CAAC,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAoF5E"}
1
+ {"version":3,"file":"list-agent-engines.d.ts","sourceRoot":"","sources":["../../../src/scripts/agent-engines/list-agent-engines.ts"],"names":[],"mappings":"AAAA;;GAEG;AAcH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAKvD,eAAO,MAAM,IAAI,EAAE,UAQlB,CAAC;AAEF,wBAAsB,GAAG,CAAC,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAoG5E"}
@@ -4,6 +4,8 @@
4
4
  import { getAgentAppModelDefaultForCurrentRequest } from "../../agent/app-model-defaults.js";
5
5
  import { DEFAULT_MODEL } from "../../agent/default-model.js";
6
6
  import { listAgentEngines, registerBuiltinEngines, detectEngineFromEnv, detectEngineFromUserSecrets, getAgentEngineEntry, isAgentEnginePackageInstalled, isStoredEngineUsableForRequest, normalizeModelForEngine, } from "../../agent/engine/index.js";
7
+ import { resolveHostedDefaultModelExperiment } from "../../observability/hosted-model-experiment.js";
8
+ import { getRequestUserEmail } from "../../server/request-context.js";
7
9
  import { getSetting } from "../../settings/index.js";
8
10
  export const tool = {
9
11
  description: 'List all available AI agent engines (Anthropic, OpenAI, Gemini, Groq, etc.) and the currently selected engine. Use this to check what engines are available before calling manage-agent-engine with action="set".',
@@ -59,9 +61,19 @@ export async function run(args = {}) {
59
61
  ? current?.model
60
62
  : undefined;
61
63
  const currentEngineName = currentEntry?.name ?? "anthropic";
62
- const currentModel = currentEntry && !envUnavailable
64
+ let currentModel = currentEntry && !envUnavailable
63
65
  ? normalizeModelForEngine(currentEntry, currentModelCandidate ?? currentEntry.defaultModel)
64
66
  : (currentModelCandidate ?? DEFAULT_MODEL);
67
+ const hostedExperiment = currentEntry && !currentModelCandidate
68
+ ? resolveHostedDefaultModelExperiment({
69
+ userId: getRequestUserEmail(),
70
+ engineName: currentEntry.name,
71
+ isDefaultModelSelection: true,
72
+ supportedModels: currentEntry.supportedModels,
73
+ })
74
+ : null;
75
+ if (hostedExperiment)
76
+ currentModel = hostedExperiment.model;
65
77
  const result = {
66
78
  engines: engines.map((e) => ({
67
79
  name: e.name,
@@ -79,6 +91,12 @@ export async function run(args = {}) {
79
91
  : {
80
92
  engine: currentEngineName,
81
93
  model: currentModel,
94
+ ...(hostedExperiment
95
+ ? {
96
+ modelSelectionSource: "experiment",
97
+ experimentAssignment: hostedExperiment.assignment,
98
+ }
99
+ : {}),
82
100
  },
83
101
  };
84
102
  return JSON.stringify(result, null, 2);
@@ -1 +1 @@
1
- {"version":3,"file":"list-agent-engines.js","sourceRoot":"","sources":["../../../src/scripts/agent-engines/list-agent-engines.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * list-agent-engines — returns the registered engine registry and current selection.\n */\n\nimport { getAgentAppModelDefaultForCurrentRequest } from \"../../agent/app-model-defaults.js\";\nimport { DEFAULT_MODEL } from \"../../agent/default-model.js\";\nimport {\n listAgentEngines,\n registerBuiltinEngines,\n detectEngineFromEnv,\n detectEngineFromUserSecrets,\n getAgentEngineEntry,\n isAgentEnginePackageInstalled,\n isStoredEngineUsableForRequest,\n normalizeModelForEngine,\n} from \"../../agent/engine/index.js\";\nimport type { ActionTool } from \"../../agent/types.js\";\nimport { getSetting } from \"../../settings/index.js\";\n\nexport const tool: ActionTool = {\n description:\n 'List all available AI agent engines (Anthropic, OpenAI, Gemini, Groq, etc.) and the currently selected engine. Use this to check what engines are available before calling manage-agent-engine with action=\"set\".',\n parameters: {\n type: \"object\",\n properties: {},\n required: [],\n },\n};\n\nexport async function run(args: Record<string, string> = {}): Promise<string> {\n registerBuiltinEngines();\n\n const engines = listAgentEngines();\n const currentSetting = await getSetting(\"agent-engine\");\n const current = currentSetting\n ? (currentSetting as { engine?: string; model?: string })\n : null;\n\n // Same priority chain resolveEngine uses after explicit request options:\n // AGENT_ENGINE → app default → stored (if usable) → user/Builder app_secrets\n // → env → anthropic. Gating stored/app defaults on the request-aware helper\n // keeps the picker in step with the runtime.\n const storedEntry =\n typeof current?.engine === \"string\"\n ? getAgentEngineEntry(current.engine)\n : undefined;\n const storedUsable =\n !!storedEntry &&\n (await isStoredEngineUsableForRequest(current, storedEntry));\n const appDefault = await getAgentAppModelDefaultForCurrentRequest(args.appId);\n const appDefaultEntry =\n typeof appDefault?.engine === \"string\"\n ? getAgentEngineEntry(appDefault.engine)\n : undefined;\n const appDefaultUsable =\n !!appDefault &&\n !!appDefaultEntry &&\n (await isStoredEngineUsableForRequest(appDefault, appDefaultEntry));\n const detectedFromUser = await detectEngineFromUserSecrets();\n const envEntry = process.env.AGENT_ENGINE\n ? getAgentEngineEntry(process.env.AGENT_ENGINE)\n : undefined;\n const envUsable =\n !!envEntry &&\n (await isStoredEngineUsableForRequest({ engine: envEntry.name }, envEntry));\n const envUnavailable = !!envEntry && !envUsable;\n const detectedFromEnv = detectEngineFromEnv();\n const envSelectedEntry = envUsable ? envEntry : undefined;\n\n const currentEntry = envUnavailable\n ? undefined\n : (envSelectedEntry ??\n (appDefaultUsable ? appDefaultEntry : undefined) ??\n (storedUsable ? storedEntry : undefined) ??\n detectedFromUser ??\n detectedFromEnv ??\n undefined);\n const currentModelCandidate =\n appDefaultUsable && currentEntry?.name === appDefault?.engine\n ? appDefault?.model\n : storedUsable && currentEntry?.name === current?.engine\n ? current?.model\n : undefined;\n const currentEngineName = currentEntry?.name ?? \"anthropic\";\n const currentModel =\n currentEntry && !envUnavailable\n ? normalizeModelForEngine(\n currentEntry,\n currentModelCandidate ?? currentEntry.defaultModel,\n )\n : (currentModelCandidate ?? DEFAULT_MODEL);\n\n const result = {\n engines: engines.map((e) => ({\n name: e.name,\n label: e.label,\n description: e.description,\n defaultModel: e.defaultModel,\n supportedModels: e.supportedModels,\n capabilities: e.capabilities,\n requiredEnvVars: e.requiredEnvVars,\n installPackage: e.installPackage,\n packageInstalled: isAgentEnginePackageInstalled(e),\n })),\n current: envUnavailable\n ? null\n : {\n engine: currentEngineName,\n model: currentModel,\n },\n };\n\n return JSON.stringify(result, null, 2);\n}\n"]}
1
+ {"version":3,"file":"list-agent-engines.js","sourceRoot":"","sources":["../../../src/scripts/agent-engines/list-agent-engines.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * list-agent-engines — returns the registered engine registry and current selection.\n */\n\nimport { getAgentAppModelDefaultForCurrentRequest } from \"../../agent/app-model-defaults.js\";\nimport { DEFAULT_MODEL } from \"../../agent/default-model.js\";\nimport {\n listAgentEngines,\n registerBuiltinEngines,\n detectEngineFromEnv,\n detectEngineFromUserSecrets,\n getAgentEngineEntry,\n isAgentEnginePackageInstalled,\n isStoredEngineUsableForRequest,\n normalizeModelForEngine,\n} from \"../../agent/engine/index.js\";\nimport type { ActionTool } from \"../../agent/types.js\";\nimport { resolveHostedDefaultModelExperiment } from \"../../observability/hosted-model-experiment.js\";\nimport { getRequestUserEmail } from \"../../server/request-context.js\";\nimport { getSetting } from \"../../settings/index.js\";\n\nexport const tool: ActionTool = {\n description:\n 'List all available AI agent engines (Anthropic, OpenAI, Gemini, Groq, etc.) and the currently selected engine. Use this to check what engines are available before calling manage-agent-engine with action=\"set\".',\n parameters: {\n type: \"object\",\n properties: {},\n required: [],\n },\n};\n\nexport async function run(args: Record<string, string> = {}): Promise<string> {\n registerBuiltinEngines();\n\n const engines = listAgentEngines();\n const currentSetting = await getSetting(\"agent-engine\");\n const current = currentSetting\n ? (currentSetting as { engine?: string; model?: string })\n : null;\n\n // Same priority chain resolveEngine uses after explicit request options:\n // AGENT_ENGINE → app default → stored (if usable) → user/Builder app_secrets\n // → env → anthropic. Gating stored/app defaults on the request-aware helper\n // keeps the picker in step with the runtime.\n const storedEntry =\n typeof current?.engine === \"string\"\n ? getAgentEngineEntry(current.engine)\n : undefined;\n const storedUsable =\n !!storedEntry &&\n (await isStoredEngineUsableForRequest(current, storedEntry));\n const appDefault = await getAgentAppModelDefaultForCurrentRequest(args.appId);\n const appDefaultEntry =\n typeof appDefault?.engine === \"string\"\n ? getAgentEngineEntry(appDefault.engine)\n : undefined;\n const appDefaultUsable =\n !!appDefault &&\n !!appDefaultEntry &&\n (await isStoredEngineUsableForRequest(appDefault, appDefaultEntry));\n const detectedFromUser = await detectEngineFromUserSecrets();\n const envEntry = process.env.AGENT_ENGINE\n ? getAgentEngineEntry(process.env.AGENT_ENGINE)\n : undefined;\n const envUsable =\n !!envEntry &&\n (await isStoredEngineUsableForRequest({ engine: envEntry.name }, envEntry));\n const envUnavailable = !!envEntry && !envUsable;\n const detectedFromEnv = detectEngineFromEnv();\n const envSelectedEntry = envUsable ? envEntry : undefined;\n\n const currentEntry = envUnavailable\n ? undefined\n : (envSelectedEntry ??\n (appDefaultUsable ? appDefaultEntry : undefined) ??\n (storedUsable ? storedEntry : undefined) ??\n detectedFromUser ??\n detectedFromEnv ??\n undefined);\n const currentModelCandidate =\n appDefaultUsable && currentEntry?.name === appDefault?.engine\n ? appDefault?.model\n : storedUsable && currentEntry?.name === current?.engine\n ? current?.model\n : undefined;\n const currentEngineName = currentEntry?.name ?? \"anthropic\";\n let currentModel =\n currentEntry && !envUnavailable\n ? normalizeModelForEngine(\n currentEntry,\n currentModelCandidate ?? currentEntry.defaultModel,\n )\n : (currentModelCandidate ?? DEFAULT_MODEL);\n const hostedExperiment =\n currentEntry && !currentModelCandidate\n ? resolveHostedDefaultModelExperiment({\n userId: getRequestUserEmail(),\n engineName: currentEntry.name,\n isDefaultModelSelection: true,\n supportedModels: currentEntry.supportedModels,\n })\n : null;\n if (hostedExperiment) currentModel = hostedExperiment.model;\n\n const result = {\n engines: engines.map((e) => ({\n name: e.name,\n label: e.label,\n description: e.description,\n defaultModel: e.defaultModel,\n supportedModels: e.supportedModels,\n capabilities: e.capabilities,\n requiredEnvVars: e.requiredEnvVars,\n installPackage: e.installPackage,\n packageInstalled: isAgentEnginePackageInstalled(e),\n })),\n current: envUnavailable\n ? null\n : {\n engine: currentEngineName,\n model: currentModel,\n ...(hostedExperiment\n ? {\n modelSelectionSource: \"experiment\",\n experimentAssignment: hostedExperiment.assignment,\n }\n : {}),\n },\n };\n\n return JSON.stringify(result, null, 2);\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"call-agent.d.ts","sourceRoot":"","sources":["../../src/scripts/call-agent.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAgFpD,eAAO,MAAM,IAAI,EAAE,UAuBlB,CAAC;AAEF,wBAAsB,GAAG,CACvB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,OAAO,CAAC,EAAE,gBAAgB,EAC1B,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC,CA2RjB;AAwID,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CASzE"}
1
+ {"version":3,"file":"call-agent.d.ts","sourceRoot":"","sources":["../../src/scripts/call-agent.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAgFpD,eAAO,MAAM,IAAI,EAAE,UAuBlB,CAAC;AAEF,wBAAsB,GAAG,CACvB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,OAAO,CAAC,EAAE,gBAAgB,EAC1B,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC,CAiTjB;AAoKD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CASzE"}
@@ -270,7 +270,14 @@ export async function run(args, context, selfAppId) {
270
270
  orgDomain: callerOrgDomain,
271
271
  orgSecret: callerOrgSecret,
272
272
  onUpdate: onRemotePollUpdate,
273
- ...(callTimeoutMs ? { timeoutMs: callTimeoutMs } : {}),
273
+ ...(callTimeoutMs
274
+ ? {
275
+ timeoutMs: callTimeoutMs,
276
+ // Integration callers must keep the timeout task id so the
277
+ // catch below can enqueue durable continuation polling.
278
+ returnRecoverableArtifactsOnTimeout: false,
279
+ }
280
+ : {}),
274
281
  });
275
282
  responseText =
276
283
  formatDownstreamLlmCredentialFailure(agent.name, responseText) ??
@@ -295,8 +302,20 @@ export async function run(args, context, selfAppId) {
295
302
  `Do not call ${agent.name} again for this same subtask. Continue any other requested work, then answer with the completed results you have; if needed, mention that ${agent.name} is posting its result separately.`;
296
303
  }
297
304
  else {
298
- const reason = pollErr?.message ?? "unknown error";
299
- responseText = `The ${agent.name} agent is taking longer than expected and didn't reply in time. (${reason})`;
305
+ // The normal integration path must preserve the timeout task id so
306
+ // it can enqueue a durable continuation. If that enqueue fails,
307
+ // do not hide receiver-verified artifacts that were already
308
+ // returned with the last poll; this mirrors callAgent's default
309
+ // timeout behavior without treating arbitrary remote status text
310
+ // as a completed response.
311
+ const recoverableArtifactText = extractRecoverableTimeoutArtifactText(pollErr);
312
+ if (recoverableArtifactText) {
313
+ responseText = expandRelativeUrls(recoverableArtifactText, agent.url);
314
+ }
315
+ else {
316
+ const reason = pollErr?.message ?? "unknown error";
317
+ responseText = `The ${agent.name} agent is taking longer than expected and didn't reply in time. (${reason})`;
318
+ }
300
319
  }
301
320
  }
302
321
  else {
@@ -419,6 +438,27 @@ function getA2ATaskTimeoutTaskId(err) {
419
438
  const match = message.match(/^A2A task ([^\s]+) did not complete\b/);
420
439
  return match?.[1] ?? null;
421
440
  }
441
+ /**
442
+ * Mirrors the A2A client's default timeout recovery for the exceptional case
443
+ * where an integration cannot enqueue a durable continuation. Only an
444
+ * explicitly receiver-marked task message is safe to surface as a completed
445
+ * partial result; ordinary working-state text remains a timeout failure.
446
+ */
447
+ function extractRecoverableTimeoutArtifactText(err) {
448
+ const candidate = err;
449
+ const lastTask = err instanceof A2ATaskTimeoutError
450
+ ? err.lastTask
451
+ : candidate?.name === "A2ATaskTimeoutError"
452
+ ? candidate.lastTask
453
+ : undefined;
454
+ const message = lastTask?.status?.message;
455
+ if (!message?.metadata?.agentNativeRecoverableArtifacts)
456
+ return "";
457
+ return message.parts
458
+ .filter((part) => part.type === "text")
459
+ .map((part) => part.text)
460
+ .join("\n");
461
+ }
422
462
  async function formatExistingIntegrationContinuationIfRetry(agent, message) {
423
463
  const integration = getIntegrationRequestContext();
424
464
  if (!integration || (integration.attempts ?? 1) <= 1)
@@ -1 +1 @@
1
- {"version":3,"file":"call-agent.js","sourceRoot":"","sources":["../../src/scripts/call-agent.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from \"node:crypto\";\n\nimport {\n A2ATaskTimeoutError,\n callAgent,\n shouldPreferGlobalA2ASecret,\n signA2AToken,\n} from \"../a2a/client.js\";\nimport type { Task } from \"../a2a/types.js\";\nimport {\n formatLlmCredentialErrorMessage,\n isLlmCredentialError,\n} from \"../agent/engine/credential-errors.js\";\nimport type { ActionRunContext } from \"../agent/production-agent.js\";\nimport type { ActionTool } from \"../agent/types.js\";\nimport { A2A_CONTINUATION_QUEUED_MARKER } from \"../integrations/a2a-continuation-marker.js\";\nimport { getOrgDomain, getOrgA2ASecret } from \"../org/context.js\";\nimport { findAgent, discoverAgents } from \"../server/agent-discovery.js\";\nimport {\n getRequestUserEmail,\n getRequestOrgId,\n isIntegrationCallerRequest,\n getIntegrationRequestContext,\n} from \"../server/request-context.js\";\n\nconst DEFAULT_SERVERLESS_INTEGRATION_A2A_TIMEOUT_MS = 18_000;\nconst NETLIFY_INTEGRATION_A2A_TIMEOUT_MS = 2_000;\nconst INTEGRATION_A2A_TOKEN_TTL = \"30m\";\n\nfunction parseTimeoutMs(value: string | undefined): number | undefined {\n if (!value) return undefined;\n const parsed = Number(value);\n if (!Number.isFinite(parsed) || parsed <= 0) return undefined;\n return Math.floor(parsed);\n}\n\nfunction isServerlessHost(): boolean {\n // Detection mirrors db/migrations.ts:297-301. On Cloudflare Workers/Pages,\n // `process.env` is shimmed and CF_PAGES isn't reliably populated at runtime —\n // the canonical signal is the `__cf_env` global injected by workerd.\n return (\n !!process.env.NETLIFY ||\n !!process.env.AWS_LAMBDA_FUNCTION_NAME ||\n !!process.env.VERCEL ||\n \"__cf_env\" in globalThis\n );\n}\n\nfunction getIntegrationCallTimeoutMs(): number | undefined {\n if (!isServerlessHost() || !isIntegrationCallerRequest()) return undefined;\n\n const configured = parseTimeoutMs(\n process.env.AGENT_NATIVE_INTEGRATION_A2A_TIMEOUT_MS,\n );\n if (configured !== undefined) return configured;\n\n // Netlify's current synchronous function budget is 60s. Keep delegated\n // calls very short so multi-agent integration requests queue downstream\n // continuations quickly instead of spending the parent Slack/email processor\n // budget waiting on separately deployed apps one-by-one.\n if (process.env.NETLIFY) return NETLIFY_INTEGRATION_A2A_TIMEOUT_MS;\n\n return DEFAULT_SERVERLESS_INTEGRATION_A2A_TIMEOUT_MS;\n}\n\nfunction integrationSourceContextHint(): string {\n const integration = getIntegrationRequestContext();\n const incoming = integration?.incoming;\n if (incoming?.platform !== \"slack\" || !incoming.sourceUrl) return \"\";\n\n try {\n const sourceUrl = new URL(incoming.sourceUrl);\n const isSlackHost =\n sourceUrl.hostname === \"slack.com\" ||\n sourceUrl.hostname.endsWith(\".slack.com\");\n if (sourceUrl.protocol !== \"https:\" || !isSlackHost) return \"\";\n return (\n `\\n\\n[Source Slack thread: ${sourceUrl.toString()} ` +\n \"Preserve this exact URL as request provenance when creating an intake record or other artifact.]\"\n );\n } catch {\n return \"\";\n }\n}\n\nfunction formatDownstreamLlmCredentialFailure(\n agentName: string,\n value: unknown,\n): string | null {\n return isLlmCredentialError(value)\n ? formatLlmCredentialErrorMessage({ agentName })\n : null;\n}\n\nexport const tool: ActionTool = {\n description:\n \"Call a DIFFERENT, separately-deployed agent app to ask a question or delegate a task. This is strictly for cross-app A2A communication — for example, asking the mail agent to send an email while you are the calendar agent. NEVER use this to call your own app or perform actions you can do with your own tools. Using call-agent on yourself will fail and waste time. \" +\n 'For brand-consistent generated media, the first-party Assets agent is available as agent=\"assets\"; use it when another app needs generated heroes, diagrams, product shots, thumbnails, videos, or design imagery, unless the current app has its own generation action that already delegates there. ' +\n \"IMPORTANT — handling the response: \" +\n \"(a) If it contains a URL or ID, copy it VERBATIM into your reply. Do not 'correct' or pluralize the path (e.g. /deck/ → /decks/), normalize casing, or change the slug — any edit breaks the link. \" +\n '(b) If it does NOT contain a URL/ID and the user asked for one, say so explicitly (e.g. \"the agent created the deck/image but didn\\'t return a link — open the app directly to view it\"). NEVER invent a URL, slug, or path — guessing produces broken links that look real. ' +\n \"(c) If the downstream response reports missing credentials, never repeat raw env var names, Vault key names, token names, secret names, or other credential identifiers. Tell the user the target app needs its LLM/provider connection configured.\",\n parameters: {\n type: \"object\",\n properties: {\n agent: {\n type: \"string\",\n description:\n \"Name or URL of a DIFFERENT deployed agent app (e.g. 'mail', 'calendar', 'analytics'). Must not be the current app's own name.\",\n },\n message: {\n type: \"string\",\n description: \"The message/question to send to the other agent\",\n },\n },\n required: [\"agent\", \"message\"],\n },\n};\n\nexport async function run(\n args: Record<string, string>,\n context?: ActionRunContext,\n selfAppId?: string,\n): Promise<string> {\n const { agent: agentIdOrName, message } = args;\n\n if (!agentIdOrName) return \"Error: --agent is required\";\n if (!message) return \"Error: --message is required\";\n\n // Prevent self-calls — the agent must use its own registered tools instead\n if (selfAppId && agentIdOrName.toLowerCase() === selfAppId.toLowerCase()) {\n return `Error: You cannot use call-agent to call yourself (${selfAppId}). Use your own registered actions/tools instead. call-agent is only for communicating with OTHER separately-deployed apps.`;\n }\n\n const agent = await findAgent(agentIdOrName, selfAppId);\n if (!agent) {\n const available = (await discoverAgents(selfAppId))\n .map((a) => a.name)\n .join(\", \");\n return `Error: Agent \"${agentIdOrName}\" not found. Available agents: ${available || \"(none)\"}`;\n }\n\n // Append a small cross-app hint to the outgoing message so the receiving\n // agent (which may be on an older deploy without the receiver-side hint\n // in handlers.ts) still emits fully-qualified URLs. This is belt-and-\n // suspenders with the receiver hint — but it works against any current\n // deployment, no redeploy required.\n const messageWithHint =\n `${message}${integrationSourceContextHint()}\\n\\n` +\n `[Note: this request comes from another app via A2A. The caller cannot see your local UI, deck list, or navigation — only the literal text you put in your reply. ` +\n `If you create or reference a deck/document/design/dashboard, include its FULLY-QUALIFIED URL (e.g. ${agent.url}/deck/<id>) in your reply, not a relative path. ` +\n `Use only artifact IDs and URL paths returned by successful actions — never invent slugs, IDs, or hosts.]`;\n\n try {\n // If we have a send context, use streaming so the UI shows progressive text\n if (context?.send) {\n const callerEmail = getRequestUserEmail();\n\n // Build metadata with identity\n const a2aMetadata: Record<string, unknown> = {};\n if (callerEmail) a2aMetadata.userEmail = callerEmail;\n\n // Include org domain for cross-app org resolution\n let callerOrgDomain: string | undefined;\n let callerOrgSecret: string | undefined;\n const orgId = getRequestOrgId();\n if (orgId) {\n try {\n const domain = await getOrgDomain(orgId);\n if (domain) {\n callerOrgDomain = domain;\n a2aMetadata.orgDomain = domain;\n }\n } catch {}\n try {\n const secret = await getOrgA2ASecret(orgId);\n if (secret) callerOrgSecret = secret;\n } catch {}\n }\n\n // Sign JWT with identity + org domain for the streaming client\n let apiKey: string | undefined;\n if (callerEmail && (callerOrgSecret || process.env.A2A_SECRET)) {\n try {\n apiKey = await signA2AToken(\n callerEmail,\n callerOrgDomain,\n callerOrgSecret,\n {\n expiresIn: INTEGRATION_A2A_TOKEN_TTL,\n preferGlobalSecret: shouldPreferGlobalA2ASecret(callerOrgSecret),\n },\n );\n } catch {}\n }\n\n if (process.env.NODE_ENV === \"production\" && callerEmail) {\n try {\n const { listOAuthAccountsByOwner } =\n await import(\"../oauth-tokens/store.js\");\n const accounts = await listOAuthAccountsByOwner(\n \"google\",\n callerEmail,\n );\n const tokens = accounts[0]?.tokens;\n if (tokens?.access_token) {\n a2aMetadata.googleToken = tokens.access_token;\n }\n } catch {}\n }\n\n let responseText = \"\";\n let lastSentLength = 0;\n const existingContinuationText =\n await formatExistingIntegrationContinuationIfRetry(agent, message);\n if (existingContinuationText) return existingContinuationText;\n\n context.send({\n type: \"agent_call\",\n agent: agent.name,\n status: \"start\",\n });\n\n const emitNewText = (newText: string) => {\n if (newText.length > lastSentLength) {\n context.send!({\n type: \"agent_call_text\",\n agent: agent.name,\n text: newText.slice(lastSentLength),\n });\n lastSentLength = newText.length;\n }\n responseText = newText;\n };\n\n // Skip the SSE streaming attempt and go straight to async + poll.\n // Why: on Netlify (Lambda), the receiving server has no streaming\n // response support, so message/stream returns a single JSON-RPC error\n // body in a 200 response that our SSE parser silently consumes — the\n // `for await` loop yields nothing AND keeps the connection open until\n // the function timeout, eating the current serverless budget. By the\n // time we get to the sync fallback, Lambda is dead and the second fetch\n // errors out as \"fetch failed\". Async+poll has its own short fetches\n // with their own budgets, so it works reliably across hosts. The\n // trade-off is we lose progressive in-UI text streaming for cross-app\n // A2A calls, but the receiving agent's full response still surfaces via\n // the tool_result event below.\n //\n // That trade-off has a second-order cost: callAgent()'s poll (see\n // A2AClient.sendAndWait in a2a/client.ts) can legitimately run for\n // minutes with nothing emitted to the parent between the \"start\" event\n // above and \"done\" below. On the parent run, that silence freezes\n // `last_progress_at` — shouldBumpProgressForEvent in\n // agent/run-manager.ts treats a stream of literally nothing as no\n // progress — which trips the client's stuck-detector\n // (DEFAULT_STUCK_THRESHOLD_MS = 90_000 in\n // client/use-run-stuck-detection.ts) and the server's stale-run sweep\n // (BACKGROUND_RUN_STALE_MS = 90_000 in agent/run-store.ts). In\n // production this handed users a \"still working, no progress\" Retry\n // button that aborted a perfectly healthy call and re-ran the sub-agent\n // from scratch.\n //\n // Fix: surface the REAL remote liveness the poll already gathers. The\n // A2A poll round-trips to the remote agent every ~2s and gets back a\n // task with `status.state` (see A2AClient.sendAndWait / `onUpdate`). We\n // emit an `agent_call_progress` event ONLY from that callback, and ONLY\n // when a poll actually succeeds AND reports an actively-working state.\n // Crucially this is NOT a timer: if the remote hangs or dies, the poll\n // fetch throws, `onUpdate` stops firing, we emit nothing, and the\n // stuck-detector correctly surfaces its banner. A wall-clock heartbeat\n // would instead keep a dead sub-agent looking alive forever — trading a\n // false stuck-positive for a worse false stuck-negative.\n //\n // Throttle: the poll runs every ~2s but both thresholds above are 90s,\n // so emitting per-poll would be ~45 events per stuck-window. We coalesce\n // to at most one emission per 30s — a 3x margin under 90s, so at least\n // two land inside either window even with jitter, without flooding.\n //\n // Shape: a dedicated `agent_call_progress` event type (see\n // agent/types.ts), not an extra `agent_call` status. `agent_call`\n // consumers (production-agent.ts's step summarizer, slack.ts's task\n // cards) render any status that isn't \"start\"/\"done\" as a failure, so a\n // \"progress\" status would surface an in-flight tick as an error. A\n // distinct type is instead ignored gracefully everywhere: the run-event\n // switches fall to their `default`, the client if-chains fall through,\n // and sse-event-processor returns `{action:\"continue\"}`. It still counts\n // as real progress in shouldBumpProgressForEvent (any non-special event\n // type does), which is the whole point.\n const PROGRESS_MIN_INTERVAL_MS = 30_000;\n // Terminal states resolve the poll; \"input-required\" means the remote is\n // blocked waiting on us, not making progress. Only actively-working\n // states count as liveness worth surfacing.\n const ACTIVELY_WORKING_STATES = new Set([\"working\", \"submitted\"]);\n const callStartedAt = Date.now();\n let lastProgressEmitAt = callStartedAt;\n const onRemotePollUpdate = (task: Task) => {\n const state = task?.status?.state;\n if (!state || !ACTIVELY_WORKING_STATES.has(state)) return;\n const now = Date.now();\n if (now - lastProgressEmitAt < PROGRESS_MIN_INTERVAL_MS) return;\n lastProgressEmitAt = now;\n const detail = extractRemoteProgressDetail(task);\n context.send!({\n type: \"agent_call_progress\",\n agent: agent.name,\n state,\n elapsedSeconds: Math.round((now - callStartedAt) / 1000),\n ...(detail ? { detail } : {}),\n });\n };\n\n try {\n // Apply a polling cap ONLY for integration-platform callers on\n // serverless hosts. Normal chat, local Node, self-hosted Node, and\n // Docker can wait for slow-but-valid answers; integration processors\n // still need to finish before their current function execution dies.\n const callTimeoutMs = getIntegrationCallTimeoutMs();\n responseText = await callAgent(agent.url, messageWithHint, {\n apiKey,\n userEmail: callerEmail,\n orgDomain: callerOrgDomain,\n orgSecret: callerOrgSecret,\n onUpdate: onRemotePollUpdate,\n ...(callTimeoutMs ? { timeoutMs: callTimeoutMs } : {}),\n });\n responseText =\n formatDownstreamLlmCredentialFailure(agent.name, responseText) ??\n responseText;\n // Some agents reply with relative paths (e.g. slides emits\n // \"/deck/abc\"). Those resolve against the caller's host, not the\n // receiver's, so they're broken for the user. Expand any leading-slash\n // URL into a fully-qualified one rooted at the receiving agent's host.\n responseText = expandRelativeUrls(responseText, agent.url);\n // Mirror the response into the streaming UI so the user sees it.\n if (responseText) emitNewText(responseText);\n } catch (pollErr: any) {\n const timeoutTaskId = getA2ATaskTimeoutTaskId(pollErr);\n if (timeoutTaskId) {\n const queued = await enqueueIntegrationContinuationIfPossible(\n timeoutTaskId,\n agent,\n message,\n callerEmail,\n );\n if (queued) {\n responseText =\n `${A2A_CONTINUATION_QUEUED_MARKER}\\n` +\n `The ${agent.name} agent accepted this delegated subtask and will post its own final result to the originating integration thread automatically. ` +\n `Do not call ${agent.name} again for this same subtask. Continue any other requested work, then answer with the completed results you have; if needed, mention that ${agent.name} is posting its result separately.`;\n } else {\n const reason = pollErr?.message ?? \"unknown error\";\n responseText = `The ${agent.name} agent is taking longer than expected and didn't reply in time. (${reason})`;\n }\n } else {\n const reason = pollErr?.message ?? \"unknown error\";\n responseText =\n formatDownstreamLlmCredentialFailure(agent.name, pollErr) ??\n `The ${agent.name} agent is taking longer than expected and didn't reply in time. (${reason})`;\n }\n }\n\n context.send({\n type: \"agent_call\",\n agent: agent.name,\n status: \"done\",\n });\n\n return responseText || \"(empty response)\";\n }\n\n // No context — use the async + poll call so we don't get cut off at the\n // serverless gateway's ~30s timeout. callAgent defaults to async:true.\n const email = getRequestUserEmail();\n let domain: string | undefined;\n let orgSecret: string | undefined;\n const currentOrgId = getRequestOrgId();\n if (currentOrgId) {\n try {\n domain = (await getOrgDomain(currentOrgId)) ?? undefined;\n } catch {}\n try {\n orgSecret = (await getOrgA2ASecret(currentOrgId)) ?? undefined;\n } catch {}\n }\n const response = await callAgent(agent.url, messageWithHint, {\n userEmail: email,\n orgDomain: domain,\n orgSecret,\n });\n const sanitized =\n formatDownstreamLlmCredentialFailure(agent.name, response) ?? response;\n return expandRelativeUrls(sanitized, agent.url) || \"(empty response)\";\n } catch (err: any) {\n const msg = err?.message ?? String(err);\n const credentialMessage = formatDownstreamLlmCredentialFailure(\n agent.name,\n err,\n );\n if (credentialMessage) return credentialMessage;\n // Friendlier message for the common timeout case so the calling agent can\n // decide whether to give up or retry.\n if (/timeout|did not complete|Inactivity|504/i.test(msg)) {\n return `The ${agent.name} agent is taking longer than expected. Please try again, ask a simpler question, or open the ${agent.name} app directly.`;\n }\n return `Error calling ${agent.name}: ${msg}`;\n }\n}\n\nasync function enqueueIntegrationContinuationIfPossible(\n taskId: string,\n agent: { name: string; url: string },\n message: string,\n ownerEmail: string | undefined,\n): Promise<boolean> {\n const integration = getIntegrationRequestContext();\n if (!integration || !ownerEmail) return false;\n\n try {\n const [{ insertA2AContinuation }, { dispatchA2AContinuation }] =\n await Promise.all([\n import(\"../integrations/a2a-continuations-store.js\"),\n import(\"../integrations/a2a-continuation-processor.js\"),\n ]);\n const continuation = await insertA2AContinuation({\n integrationTaskId: integration.taskId,\n platform: integration.incoming.platform,\n externalThreadId: integration.incoming.externalThreadId,\n incoming: integration.incoming,\n placeholderRef: integration.placeholderRef,\n progressRef: integration.progressRef,\n ownerEmail,\n orgId: getRequestOrgId() ?? null,\n agentName: agent.name,\n agentUrl: agent.url,\n dedupeKey: getIntegrationContinuationDedupeKey(message),\n a2aTaskId: taskId,\n // Do not persist the short-lived JWT used for the initial send. The\n // continuation processor can mint a fresh token for each poll.\n a2aAuthToken: null,\n });\n await dispatchA2AContinuation(continuation.id).catch((err) => {\n console.error(\n `[call-agent] Failed to dispatch A2A continuation ${continuation.id}:`,\n err,\n );\n });\n return true;\n } catch (err) {\n console.error(\"[call-agent] Failed to enqueue A2A continuation:\", err);\n return false;\n }\n}\n\n// Pull a short human-readable detail from a polled A2A task's status message,\n// when the remote includes one, so the progress event can surface a real\n// signal (e.g. \"Generating hero image…\") instead of a bare elapsed counter.\n// Bounded so a chatty remote can't push a large payload through the event.\nconst MAX_PROGRESS_DETAIL_CHARS = 200;\nfunction extractRemoteProgressDetail(task: Task): string | undefined {\n const parts = task.status?.message?.parts;\n if (!parts) return undefined;\n const text = parts\n .filter((p): p is { type: \"text\"; text: string } => p.type === \"text\")\n .map((p) => p.text)\n .join(\" \")\n .replace(/\\s+/g, \" \")\n .trim();\n if (!text) return undefined;\n return text.length > MAX_PROGRESS_DETAIL_CHARS\n ? `${text.slice(0, MAX_PROGRESS_DETAIL_CHARS - 1)}…`\n : text;\n}\n\nfunction getA2ATaskTimeoutTaskId(err: unknown): string | null {\n if (err instanceof A2ATaskTimeoutError) return err.taskId;\n\n const candidate = err as\n | { name?: unknown; taskId?: unknown; message?: unknown }\n | null\n | undefined;\n const message = String(candidate?.message ?? \"\");\n if (\n candidate?.name === \"A2ATaskTimeoutError\" &&\n typeof candidate.taskId === \"string\"\n ) {\n return candidate.taskId;\n }\n\n const match = message.match(/^A2A task ([^\\s]+) did not complete\\b/);\n return match?.[1] ?? null;\n}\n\nasync function formatExistingIntegrationContinuationIfRetry(\n agent: {\n name: string;\n url: string;\n },\n message: string,\n): Promise<string | null> {\n const integration = getIntegrationRequestContext();\n if (!integration || (integration.attempts ?? 1) <= 1) return null;\n\n try {\n const { getA2AContinuationsForIntegrationTaskAgent } =\n await import(\"../integrations/a2a-continuations-store.js\");\n const continuations = await getA2AContinuationsForIntegrationTaskAgent(\n integration.taskId,\n agent.url,\n getIntegrationContinuationDedupeKey(message),\n );\n const active = continuations.find((continuation) =>\n [\"pending\", \"processing\", \"delivering\", \"completed\"].includes(\n continuation.status,\n ),\n );\n if (!active) return null;\n\n const state =\n active.status === \"completed\"\n ? \"already completed this delegated subtask and posted its result to the originating integration thread\"\n : \"already accepted this delegated subtask and is still working on it for the originating integration thread\";\n return (\n `${A2A_CONTINUATION_QUEUED_MARKER}\\n` +\n `The ${agent.name} agent ${state}. Do not call ${agent.name} again for this same subtask. Continue any other requested work, then answer with the completed results you have; if needed, mention that ${agent.name} is posting or has posted its result separately.`\n );\n } catch (err) {\n console.error(\"[call-agent] Failed to inspect existing continuation:\", err);\n return null;\n }\n}\n\nfunction getIntegrationContinuationDedupeKey(message: string): string {\n const normalized = message.trim().replace(/\\s+/g, \" \");\n return createHash(\"sha256\").update(normalized).digest(\"hex\");\n}\n\n// Expand bare leading-slash paths (e.g. \"/deck/abc\") into fully-qualified URLs\n// rooted at the receiving agent's host. The receiver doesn't always know it's\n// being called cross-app, so it may emit relative paths that resolve against\n// the caller's host (broken). Match a path that starts at a word boundary,\n// begins with `/`, and has at least one path segment after that. Skip if it\n// already looks like a fully-qualified URL.\nexport function expandRelativeUrls(text: string, agentUrl: string): string {\n if (!text || !agentUrl) return text;\n const base = agentUrl.replace(/\\/$/, \"\");\n // Path must start at boundary (start, whitespace, or punctuation that isn't\n // ':' — to avoid mangling `https://example.com/foo` or markdown link bodies).\n return text.replace(\n /(^|[\\s([<\"'`])(\\/[a-z0-9_-][a-z0-9_/?&=%#.,:-]*)/gi,\n (_match, lead, path) => `${lead}${base}${path}`,\n );\n}\n"]}
1
+ {"version":3,"file":"call-agent.js","sourceRoot":"","sources":["../../src/scripts/call-agent.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from \"node:crypto\";\n\nimport {\n A2ATaskTimeoutError,\n callAgent,\n shouldPreferGlobalA2ASecret,\n signA2AToken,\n} from \"../a2a/client.js\";\nimport type { Task } from \"../a2a/types.js\";\nimport {\n formatLlmCredentialErrorMessage,\n isLlmCredentialError,\n} from \"../agent/engine/credential-errors.js\";\nimport type { ActionRunContext } from \"../agent/production-agent.js\";\nimport type { ActionTool } from \"../agent/types.js\";\nimport { A2A_CONTINUATION_QUEUED_MARKER } from \"../integrations/a2a-continuation-marker.js\";\nimport { getOrgDomain, getOrgA2ASecret } from \"../org/context.js\";\nimport { findAgent, discoverAgents } from \"../server/agent-discovery.js\";\nimport {\n getRequestUserEmail,\n getRequestOrgId,\n isIntegrationCallerRequest,\n getIntegrationRequestContext,\n} from \"../server/request-context.js\";\n\nconst DEFAULT_SERVERLESS_INTEGRATION_A2A_TIMEOUT_MS = 18_000;\nconst NETLIFY_INTEGRATION_A2A_TIMEOUT_MS = 2_000;\nconst INTEGRATION_A2A_TOKEN_TTL = \"30m\";\n\nfunction parseTimeoutMs(value: string | undefined): number | undefined {\n if (!value) return undefined;\n const parsed = Number(value);\n if (!Number.isFinite(parsed) || parsed <= 0) return undefined;\n return Math.floor(parsed);\n}\n\nfunction isServerlessHost(): boolean {\n // Detection mirrors db/migrations.ts:297-301. On Cloudflare Workers/Pages,\n // `process.env` is shimmed and CF_PAGES isn't reliably populated at runtime —\n // the canonical signal is the `__cf_env` global injected by workerd.\n return (\n !!process.env.NETLIFY ||\n !!process.env.AWS_LAMBDA_FUNCTION_NAME ||\n !!process.env.VERCEL ||\n \"__cf_env\" in globalThis\n );\n}\n\nfunction getIntegrationCallTimeoutMs(): number | undefined {\n if (!isServerlessHost() || !isIntegrationCallerRequest()) return undefined;\n\n const configured = parseTimeoutMs(\n process.env.AGENT_NATIVE_INTEGRATION_A2A_TIMEOUT_MS,\n );\n if (configured !== undefined) return configured;\n\n // Netlify's current synchronous function budget is 60s. Keep delegated\n // calls very short so multi-agent integration requests queue downstream\n // continuations quickly instead of spending the parent Slack/email processor\n // budget waiting on separately deployed apps one-by-one.\n if (process.env.NETLIFY) return NETLIFY_INTEGRATION_A2A_TIMEOUT_MS;\n\n return DEFAULT_SERVERLESS_INTEGRATION_A2A_TIMEOUT_MS;\n}\n\nfunction integrationSourceContextHint(): string {\n const integration = getIntegrationRequestContext();\n const incoming = integration?.incoming;\n if (incoming?.platform !== \"slack\" || !incoming.sourceUrl) return \"\";\n\n try {\n const sourceUrl = new URL(incoming.sourceUrl);\n const isSlackHost =\n sourceUrl.hostname === \"slack.com\" ||\n sourceUrl.hostname.endsWith(\".slack.com\");\n if (sourceUrl.protocol !== \"https:\" || !isSlackHost) return \"\";\n return (\n `\\n\\n[Source Slack thread: ${sourceUrl.toString()} ` +\n \"Preserve this exact URL as request provenance when creating an intake record or other artifact.]\"\n );\n } catch {\n return \"\";\n }\n}\n\nfunction formatDownstreamLlmCredentialFailure(\n agentName: string,\n value: unknown,\n): string | null {\n return isLlmCredentialError(value)\n ? formatLlmCredentialErrorMessage({ agentName })\n : null;\n}\n\nexport const tool: ActionTool = {\n description:\n \"Call a DIFFERENT, separately-deployed agent app to ask a question or delegate a task. This is strictly for cross-app A2A communication — for example, asking the mail agent to send an email while you are the calendar agent. NEVER use this to call your own app or perform actions you can do with your own tools. Using call-agent on yourself will fail and waste time. \" +\n 'For brand-consistent generated media, the first-party Assets agent is available as agent=\"assets\"; use it when another app needs generated heroes, diagrams, product shots, thumbnails, videos, or design imagery, unless the current app has its own generation action that already delegates there. ' +\n \"IMPORTANT — handling the response: \" +\n \"(a) If it contains a URL or ID, copy it VERBATIM into your reply. Do not 'correct' or pluralize the path (e.g. /deck/ → /decks/), normalize casing, or change the slug — any edit breaks the link. \" +\n '(b) If it does NOT contain a URL/ID and the user asked for one, say so explicitly (e.g. \"the agent created the deck/image but didn\\'t return a link — open the app directly to view it\"). NEVER invent a URL, slug, or path — guessing produces broken links that look real. ' +\n \"(c) If the downstream response reports missing credentials, never repeat raw env var names, Vault key names, token names, secret names, or other credential identifiers. Tell the user the target app needs its LLM/provider connection configured.\",\n parameters: {\n type: \"object\",\n properties: {\n agent: {\n type: \"string\",\n description:\n \"Name or URL of a DIFFERENT deployed agent app (e.g. 'mail', 'calendar', 'analytics'). Must not be the current app's own name.\",\n },\n message: {\n type: \"string\",\n description: \"The message/question to send to the other agent\",\n },\n },\n required: [\"agent\", \"message\"],\n },\n};\n\nexport async function run(\n args: Record<string, string>,\n context?: ActionRunContext,\n selfAppId?: string,\n): Promise<string> {\n const { agent: agentIdOrName, message } = args;\n\n if (!agentIdOrName) return \"Error: --agent is required\";\n if (!message) return \"Error: --message is required\";\n\n // Prevent self-calls — the agent must use its own registered tools instead\n if (selfAppId && agentIdOrName.toLowerCase() === selfAppId.toLowerCase()) {\n return `Error: You cannot use call-agent to call yourself (${selfAppId}). Use your own registered actions/tools instead. call-agent is only for communicating with OTHER separately-deployed apps.`;\n }\n\n const agent = await findAgent(agentIdOrName, selfAppId);\n if (!agent) {\n const available = (await discoverAgents(selfAppId))\n .map((a) => a.name)\n .join(\", \");\n return `Error: Agent \"${agentIdOrName}\" not found. Available agents: ${available || \"(none)\"}`;\n }\n\n // Append a small cross-app hint to the outgoing message so the receiving\n // agent (which may be on an older deploy without the receiver-side hint\n // in handlers.ts) still emits fully-qualified URLs. This is belt-and-\n // suspenders with the receiver hint — but it works against any current\n // deployment, no redeploy required.\n const messageWithHint =\n `${message}${integrationSourceContextHint()}\\n\\n` +\n `[Note: this request comes from another app via A2A. The caller cannot see your local UI, deck list, or navigation — only the literal text you put in your reply. ` +\n `If you create or reference a deck/document/design/dashboard, include its FULLY-QUALIFIED URL (e.g. ${agent.url}/deck/<id>) in your reply, not a relative path. ` +\n `Use only artifact IDs and URL paths returned by successful actions — never invent slugs, IDs, or hosts.]`;\n\n try {\n // If we have a send context, use streaming so the UI shows progressive text\n if (context?.send) {\n const callerEmail = getRequestUserEmail();\n\n // Build metadata with identity\n const a2aMetadata: Record<string, unknown> = {};\n if (callerEmail) a2aMetadata.userEmail = callerEmail;\n\n // Include org domain for cross-app org resolution\n let callerOrgDomain: string | undefined;\n let callerOrgSecret: string | undefined;\n const orgId = getRequestOrgId();\n if (orgId) {\n try {\n const domain = await getOrgDomain(orgId);\n if (domain) {\n callerOrgDomain = domain;\n a2aMetadata.orgDomain = domain;\n }\n } catch {}\n try {\n const secret = await getOrgA2ASecret(orgId);\n if (secret) callerOrgSecret = secret;\n } catch {}\n }\n\n // Sign JWT with identity + org domain for the streaming client\n let apiKey: string | undefined;\n if (callerEmail && (callerOrgSecret || process.env.A2A_SECRET)) {\n try {\n apiKey = await signA2AToken(\n callerEmail,\n callerOrgDomain,\n callerOrgSecret,\n {\n expiresIn: INTEGRATION_A2A_TOKEN_TTL,\n preferGlobalSecret: shouldPreferGlobalA2ASecret(callerOrgSecret),\n },\n );\n } catch {}\n }\n\n if (process.env.NODE_ENV === \"production\" && callerEmail) {\n try {\n const { listOAuthAccountsByOwner } =\n await import(\"../oauth-tokens/store.js\");\n const accounts = await listOAuthAccountsByOwner(\n \"google\",\n callerEmail,\n );\n const tokens = accounts[0]?.tokens;\n if (tokens?.access_token) {\n a2aMetadata.googleToken = tokens.access_token;\n }\n } catch {}\n }\n\n let responseText = \"\";\n let lastSentLength = 0;\n const existingContinuationText =\n await formatExistingIntegrationContinuationIfRetry(agent, message);\n if (existingContinuationText) return existingContinuationText;\n\n context.send({\n type: \"agent_call\",\n agent: agent.name,\n status: \"start\",\n });\n\n const emitNewText = (newText: string) => {\n if (newText.length > lastSentLength) {\n context.send!({\n type: \"agent_call_text\",\n agent: agent.name,\n text: newText.slice(lastSentLength),\n });\n lastSentLength = newText.length;\n }\n responseText = newText;\n };\n\n // Skip the SSE streaming attempt and go straight to async + poll.\n // Why: on Netlify (Lambda), the receiving server has no streaming\n // response support, so message/stream returns a single JSON-RPC error\n // body in a 200 response that our SSE parser silently consumes — the\n // `for await` loop yields nothing AND keeps the connection open until\n // the function timeout, eating the current serverless budget. By the\n // time we get to the sync fallback, Lambda is dead and the second fetch\n // errors out as \"fetch failed\". Async+poll has its own short fetches\n // with their own budgets, so it works reliably across hosts. The\n // trade-off is we lose progressive in-UI text streaming for cross-app\n // A2A calls, but the receiving agent's full response still surfaces via\n // the tool_result event below.\n //\n // That trade-off has a second-order cost: callAgent()'s poll (see\n // A2AClient.sendAndWait in a2a/client.ts) can legitimately run for\n // minutes with nothing emitted to the parent between the \"start\" event\n // above and \"done\" below. On the parent run, that silence freezes\n // `last_progress_at` — shouldBumpProgressForEvent in\n // agent/run-manager.ts treats a stream of literally nothing as no\n // progress — which trips the client's stuck-detector\n // (DEFAULT_STUCK_THRESHOLD_MS = 90_000 in\n // client/use-run-stuck-detection.ts) and the server's stale-run sweep\n // (BACKGROUND_RUN_STALE_MS = 90_000 in agent/run-store.ts). In\n // production this handed users a \"still working, no progress\" Retry\n // button that aborted a perfectly healthy call and re-ran the sub-agent\n // from scratch.\n //\n // Fix: surface the REAL remote liveness the poll already gathers. The\n // A2A poll round-trips to the remote agent every ~2s and gets back a\n // task with `status.state` (see A2AClient.sendAndWait / `onUpdate`). We\n // emit an `agent_call_progress` event ONLY from that callback, and ONLY\n // when a poll actually succeeds AND reports an actively-working state.\n // Crucially this is NOT a timer: if the remote hangs or dies, the poll\n // fetch throws, `onUpdate` stops firing, we emit nothing, and the\n // stuck-detector correctly surfaces its banner. A wall-clock heartbeat\n // would instead keep a dead sub-agent looking alive forever — trading a\n // false stuck-positive for a worse false stuck-negative.\n //\n // Throttle: the poll runs every ~2s but both thresholds above are 90s,\n // so emitting per-poll would be ~45 events per stuck-window. We coalesce\n // to at most one emission per 30s — a 3x margin under 90s, so at least\n // two land inside either window even with jitter, without flooding.\n //\n // Shape: a dedicated `agent_call_progress` event type (see\n // agent/types.ts), not an extra `agent_call` status. `agent_call`\n // consumers (production-agent.ts's step summarizer, slack.ts's task\n // cards) render any status that isn't \"start\"/\"done\" as a failure, so a\n // \"progress\" status would surface an in-flight tick as an error. A\n // distinct type is instead ignored gracefully everywhere: the run-event\n // switches fall to their `default`, the client if-chains fall through,\n // and sse-event-processor returns `{action:\"continue\"}`. It still counts\n // as real progress in shouldBumpProgressForEvent (any non-special event\n // type does), which is the whole point.\n const PROGRESS_MIN_INTERVAL_MS = 30_000;\n // Terminal states resolve the poll; \"input-required\" means the remote is\n // blocked waiting on us, not making progress. Only actively-working\n // states count as liveness worth surfacing.\n const ACTIVELY_WORKING_STATES = new Set([\"working\", \"submitted\"]);\n const callStartedAt = Date.now();\n let lastProgressEmitAt = callStartedAt;\n const onRemotePollUpdate = (task: Task) => {\n const state = task?.status?.state;\n if (!state || !ACTIVELY_WORKING_STATES.has(state)) return;\n const now = Date.now();\n if (now - lastProgressEmitAt < PROGRESS_MIN_INTERVAL_MS) return;\n lastProgressEmitAt = now;\n const detail = extractRemoteProgressDetail(task);\n context.send!({\n type: \"agent_call_progress\",\n agent: agent.name,\n state,\n elapsedSeconds: Math.round((now - callStartedAt) / 1000),\n ...(detail ? { detail } : {}),\n });\n };\n\n try {\n // Apply a polling cap ONLY for integration-platform callers on\n // serverless hosts. Normal chat, local Node, self-hosted Node, and\n // Docker can wait for slow-but-valid answers; integration processors\n // still need to finish before their current function execution dies.\n const callTimeoutMs = getIntegrationCallTimeoutMs();\n responseText = await callAgent(agent.url, messageWithHint, {\n apiKey,\n userEmail: callerEmail,\n orgDomain: callerOrgDomain,\n orgSecret: callerOrgSecret,\n onUpdate: onRemotePollUpdate,\n ...(callTimeoutMs\n ? {\n timeoutMs: callTimeoutMs,\n // Integration callers must keep the timeout task id so the\n // catch below can enqueue durable continuation polling.\n returnRecoverableArtifactsOnTimeout: false,\n }\n : {}),\n });\n responseText =\n formatDownstreamLlmCredentialFailure(agent.name, responseText) ??\n responseText;\n // Some agents reply with relative paths (e.g. slides emits\n // \"/deck/abc\"). Those resolve against the caller's host, not the\n // receiver's, so they're broken for the user. Expand any leading-slash\n // URL into a fully-qualified one rooted at the receiving agent's host.\n responseText = expandRelativeUrls(responseText, agent.url);\n // Mirror the response into the streaming UI so the user sees it.\n if (responseText) emitNewText(responseText);\n } catch (pollErr: any) {\n const timeoutTaskId = getA2ATaskTimeoutTaskId(pollErr);\n if (timeoutTaskId) {\n const queued = await enqueueIntegrationContinuationIfPossible(\n timeoutTaskId,\n agent,\n message,\n callerEmail,\n );\n if (queued) {\n responseText =\n `${A2A_CONTINUATION_QUEUED_MARKER}\\n` +\n `The ${agent.name} agent accepted this delegated subtask and will post its own final result to the originating integration thread automatically. ` +\n `Do not call ${agent.name} again for this same subtask. Continue any other requested work, then answer with the completed results you have; if needed, mention that ${agent.name} is posting its result separately.`;\n } else {\n // The normal integration path must preserve the timeout task id so\n // it can enqueue a durable continuation. If that enqueue fails,\n // do not hide receiver-verified artifacts that were already\n // returned with the last poll; this mirrors callAgent's default\n // timeout behavior without treating arbitrary remote status text\n // as a completed response.\n const recoverableArtifactText =\n extractRecoverableTimeoutArtifactText(pollErr);\n if (recoverableArtifactText) {\n responseText = expandRelativeUrls(\n recoverableArtifactText,\n agent.url,\n );\n } else {\n const reason = pollErr?.message ?? \"unknown error\";\n responseText = `The ${agent.name} agent is taking longer than expected and didn't reply in time. (${reason})`;\n }\n }\n } else {\n const reason = pollErr?.message ?? \"unknown error\";\n responseText =\n formatDownstreamLlmCredentialFailure(agent.name, pollErr) ??\n `The ${agent.name} agent is taking longer than expected and didn't reply in time. (${reason})`;\n }\n }\n\n context.send({\n type: \"agent_call\",\n agent: agent.name,\n status: \"done\",\n });\n\n return responseText || \"(empty response)\";\n }\n\n // No context — use the async + poll call so we don't get cut off at the\n // serverless gateway's ~30s timeout. callAgent defaults to async:true.\n const email = getRequestUserEmail();\n let domain: string | undefined;\n let orgSecret: string | undefined;\n const currentOrgId = getRequestOrgId();\n if (currentOrgId) {\n try {\n domain = (await getOrgDomain(currentOrgId)) ?? undefined;\n } catch {}\n try {\n orgSecret = (await getOrgA2ASecret(currentOrgId)) ?? undefined;\n } catch {}\n }\n const response = await callAgent(agent.url, messageWithHint, {\n userEmail: email,\n orgDomain: domain,\n orgSecret,\n });\n const sanitized =\n formatDownstreamLlmCredentialFailure(agent.name, response) ?? response;\n return expandRelativeUrls(sanitized, agent.url) || \"(empty response)\";\n } catch (err: any) {\n const msg = err?.message ?? String(err);\n const credentialMessage = formatDownstreamLlmCredentialFailure(\n agent.name,\n err,\n );\n if (credentialMessage) return credentialMessage;\n // Friendlier message for the common timeout case so the calling agent can\n // decide whether to give up or retry.\n if (/timeout|did not complete|Inactivity|504/i.test(msg)) {\n return `The ${agent.name} agent is taking longer than expected. Please try again, ask a simpler question, or open the ${agent.name} app directly.`;\n }\n return `Error calling ${agent.name}: ${msg}`;\n }\n}\n\nasync function enqueueIntegrationContinuationIfPossible(\n taskId: string,\n agent: { name: string; url: string },\n message: string,\n ownerEmail: string | undefined,\n): Promise<boolean> {\n const integration = getIntegrationRequestContext();\n if (!integration || !ownerEmail) return false;\n\n try {\n const [{ insertA2AContinuation }, { dispatchA2AContinuation }] =\n await Promise.all([\n import(\"../integrations/a2a-continuations-store.js\"),\n import(\"../integrations/a2a-continuation-processor.js\"),\n ]);\n const continuation = await insertA2AContinuation({\n integrationTaskId: integration.taskId,\n platform: integration.incoming.platform,\n externalThreadId: integration.incoming.externalThreadId,\n incoming: integration.incoming,\n placeholderRef: integration.placeholderRef,\n progressRef: integration.progressRef,\n ownerEmail,\n orgId: getRequestOrgId() ?? null,\n agentName: agent.name,\n agentUrl: agent.url,\n dedupeKey: getIntegrationContinuationDedupeKey(message),\n a2aTaskId: taskId,\n // Do not persist the short-lived JWT used for the initial send. The\n // continuation processor can mint a fresh token for each poll.\n a2aAuthToken: null,\n });\n await dispatchA2AContinuation(continuation.id).catch((err) => {\n console.error(\n `[call-agent] Failed to dispatch A2A continuation ${continuation.id}:`,\n err,\n );\n });\n return true;\n } catch (err) {\n console.error(\"[call-agent] Failed to enqueue A2A continuation:\", err);\n return false;\n }\n}\n\n// Pull a short human-readable detail from a polled A2A task's status message,\n// when the remote includes one, so the progress event can surface a real\n// signal (e.g. \"Generating hero image…\") instead of a bare elapsed counter.\n// Bounded so a chatty remote can't push a large payload through the event.\nconst MAX_PROGRESS_DETAIL_CHARS = 200;\nfunction extractRemoteProgressDetail(task: Task): string | undefined {\n const parts = task.status?.message?.parts;\n if (!parts) return undefined;\n const text = parts\n .filter((p): p is { type: \"text\"; text: string } => p.type === \"text\")\n .map((p) => p.text)\n .join(\" \")\n .replace(/\\s+/g, \" \")\n .trim();\n if (!text) return undefined;\n return text.length > MAX_PROGRESS_DETAIL_CHARS\n ? `${text.slice(0, MAX_PROGRESS_DETAIL_CHARS - 1)}…`\n : text;\n}\n\nfunction getA2ATaskTimeoutTaskId(err: unknown): string | null {\n if (err instanceof A2ATaskTimeoutError) return err.taskId;\n\n const candidate = err as\n | { name?: unknown; taskId?: unknown; message?: unknown }\n | null\n | undefined;\n const message = String(candidate?.message ?? \"\");\n if (\n candidate?.name === \"A2ATaskTimeoutError\" &&\n typeof candidate.taskId === \"string\"\n ) {\n return candidate.taskId;\n }\n\n const match = message.match(/^A2A task ([^\\s]+) did not complete\\b/);\n return match?.[1] ?? null;\n}\n\n/**\n * Mirrors the A2A client's default timeout recovery for the exceptional case\n * where an integration cannot enqueue a durable continuation. Only an\n * explicitly receiver-marked task message is safe to surface as a completed\n * partial result; ordinary working-state text remains a timeout failure.\n */\nfunction extractRecoverableTimeoutArtifactText(err: unknown): string {\n const candidate = err as\n | { lastTask?: Task | unknown; name?: unknown }\n | null\n | undefined;\n const lastTask =\n err instanceof A2ATaskTimeoutError\n ? err.lastTask\n : candidate?.name === \"A2ATaskTimeoutError\"\n ? (candidate.lastTask as Task | undefined)\n : undefined;\n const message = lastTask?.status?.message;\n if (!message?.metadata?.agentNativeRecoverableArtifacts) return \"\";\n\n return message.parts\n .filter(\n (part): part is { type: \"text\"; text: string } => part.type === \"text\",\n )\n .map((part) => part.text)\n .join(\"\\n\");\n}\n\nasync function formatExistingIntegrationContinuationIfRetry(\n agent: {\n name: string;\n url: string;\n },\n message: string,\n): Promise<string | null> {\n const integration = getIntegrationRequestContext();\n if (!integration || (integration.attempts ?? 1) <= 1) return null;\n\n try {\n const { getA2AContinuationsForIntegrationTaskAgent } =\n await import(\"../integrations/a2a-continuations-store.js\");\n const continuations = await getA2AContinuationsForIntegrationTaskAgent(\n integration.taskId,\n agent.url,\n getIntegrationContinuationDedupeKey(message),\n );\n const active = continuations.find((continuation) =>\n [\"pending\", \"processing\", \"delivering\", \"completed\"].includes(\n continuation.status,\n ),\n );\n if (!active) return null;\n\n const state =\n active.status === \"completed\"\n ? \"already completed this delegated subtask and posted its result to the originating integration thread\"\n : \"already accepted this delegated subtask and is still working on it for the originating integration thread\";\n return (\n `${A2A_CONTINUATION_QUEUED_MARKER}\\n` +\n `The ${agent.name} agent ${state}. Do not call ${agent.name} again for this same subtask. Continue any other requested work, then answer with the completed results you have; if needed, mention that ${agent.name} is posting or has posted its result separately.`\n );\n } catch (err) {\n console.error(\"[call-agent] Failed to inspect existing continuation:\", err);\n return null;\n }\n}\n\nfunction getIntegrationContinuationDedupeKey(message: string): string {\n const normalized = message.trim().replace(/\\s+/g, \" \");\n return createHash(\"sha256\").update(normalized).digest(\"hex\");\n}\n\n// Expand bare leading-slash paths (e.g. \"/deck/abc\") into fully-qualified URLs\n// rooted at the receiving agent's host. The receiver doesn't always know it's\n// being called cross-app, so it may emit relative paths that resolve against\n// the caller's host (broken). Match a path that starts at a word boundary,\n// begins with `/`, and has at least one path segment after that. Skip if it\n// already looks like a fully-qualified URL.\nexport function expandRelativeUrls(text: string, agentUrl: string): string {\n if (!text || !agentUrl) return text;\n const base = agentUrl.replace(/\\/$/, \"\");\n // Path must start at boundary (start, whitespace, or punctuation that isn't\n // ':' — to avoid mangling `https://example.com/foo` or markdown link bodies).\n return text.replace(\n /(^|[\\s([<\"'`])(\\/[a-z0-9_-][a-z0-9_/?&=%#.,:-]*)/gi,\n (_match, lead, path) => `${lead}${base}${path}`,\n );\n}\n"]}
@@ -4,7 +4,7 @@
4
4
  * Search or list past agent chat threads.
5
5
  *
6
6
  * Usage:
7
- * pnpm action search-chats [--query "search term"] [--limit N] [--format json]
7
+ * pnpm action search-chats [--query "search term"] [--limit N] [--format json] [--includeArchived]
8
8
  */
9
9
  export default function searchChats(args: string[]): Promise<void>;
10
10
  //# sourceMappingURL=search-chats.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"search-chats.d.ts","sourceRoot":"","sources":["../../../src/scripts/chat/search-chats.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AA4BH,wBAA8B,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAkFvE"}
1
+ {"version":3,"file":"search-chats.d.ts","sourceRoot":"","sources":["../../../src/scripts/chat/search-chats.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AA4BH,wBAA8B,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAqFvE"}