@agent-native/core 0.7.18 → 0.7.20

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 (269) hide show
  1. package/README.md +1 -1
  2. package/dist/agent/engine/builder-engine.d.ts.map +1 -1
  3. package/dist/agent/engine/builder-engine.js +60 -5
  4. package/dist/agent/engine/builder-engine.js.map +1 -1
  5. package/dist/agent/loop-settings.d.ts +37 -0
  6. package/dist/agent/loop-settings.d.ts.map +1 -0
  7. package/dist/agent/loop-settings.js +127 -0
  8. package/dist/agent/loop-settings.js.map +1 -0
  9. package/dist/agent/production-agent.d.ts +8 -0
  10. package/dist/agent/production-agent.d.ts.map +1 -1
  11. package/dist/agent/production-agent.js +268 -29
  12. package/dist/agent/production-agent.js.map +1 -1
  13. package/dist/agent/run-manager.d.ts.map +1 -1
  14. package/dist/agent/run-manager.js +76 -3
  15. package/dist/agent/run-manager.js.map +1 -1
  16. package/dist/agent/run-store.d.ts +1 -1
  17. package/dist/agent/run-store.d.ts.map +1 -1
  18. package/dist/agent/run-store.js +65 -2
  19. package/dist/agent/run-store.js.map +1 -1
  20. package/dist/agent/thread-data-builder.d.ts +3 -0
  21. package/dist/agent/thread-data-builder.d.ts.map +1 -1
  22. package/dist/agent/thread-data-builder.js +52 -10
  23. package/dist/agent/thread-data-builder.js.map +1 -1
  24. package/dist/agent/tool-search.d.ts +37 -0
  25. package/dist/agent/tool-search.d.ts.map +1 -0
  26. package/dist/agent/tool-search.js +201 -0
  27. package/dist/agent/tool-search.js.map +1 -0
  28. package/dist/agent/types.d.ts +8 -1
  29. package/dist/agent/types.d.ts.map +1 -1
  30. package/dist/agent/types.js.map +1 -1
  31. package/dist/cli/create.d.ts.map +1 -1
  32. package/dist/cli/create.js +57 -11
  33. package/dist/cli/create.js.map +1 -1
  34. package/dist/cli/workspacify.d.ts +2 -0
  35. package/dist/cli/workspacify.d.ts.map +1 -1
  36. package/dist/cli/workspacify.js +34 -1
  37. package/dist/cli/workspacify.js.map +1 -1
  38. package/dist/client/AssistantChat.d.ts.map +1 -1
  39. package/dist/client/AssistantChat.js +303 -14
  40. package/dist/client/AssistantChat.js.map +1 -1
  41. package/dist/client/ConnectBuilderCard.d.ts.map +1 -1
  42. package/dist/client/ConnectBuilderCard.js +1 -1
  43. package/dist/client/ConnectBuilderCard.js.map +1 -1
  44. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  45. package/dist/client/MultiTabAssistantChat.js +16 -24
  46. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  47. package/dist/client/NewWorkspaceAppFlow.d.ts +14 -0
  48. package/dist/client/NewWorkspaceAppFlow.d.ts.map +1 -0
  49. package/dist/client/NewWorkspaceAppFlow.js +200 -0
  50. package/dist/client/NewWorkspaceAppFlow.js.map +1 -0
  51. package/dist/client/PoweredByBadge.d.ts +10 -1
  52. package/dist/client/PoweredByBadge.d.ts.map +1 -1
  53. package/dist/client/PoweredByBadge.js +120 -8
  54. package/dist/client/PoweredByBadge.js.map +1 -1
  55. package/dist/client/agent-chat-adapter.d.ts +8 -0
  56. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  57. package/dist/client/agent-chat-adapter.js +32 -5
  58. package/dist/client/agent-chat-adapter.js.map +1 -1
  59. package/dist/client/agent-chat.d.ts.map +1 -1
  60. package/dist/client/agent-chat.js +15 -3
  61. package/dist/client/agent-chat.js.map +1 -1
  62. package/dist/client/analytics.d.ts +1 -1
  63. package/dist/client/analytics.d.ts.map +1 -1
  64. package/dist/client/analytics.js +141 -1
  65. package/dist/client/analytics.js.map +1 -1
  66. package/dist/client/builder-frame.d.ts +10 -0
  67. package/dist/client/builder-frame.d.ts.map +1 -0
  68. package/dist/client/builder-frame.js +94 -0
  69. package/dist/client/builder-frame.js.map +1 -0
  70. package/dist/client/composer/MentionPopover.d.ts.map +1 -1
  71. package/dist/client/composer/MentionPopover.js +5 -1
  72. package/dist/client/composer/MentionPopover.js.map +1 -1
  73. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  74. package/dist/client/composer/TiptapComposer.js +11 -6
  75. package/dist/client/composer/TiptapComposer.js.map +1 -1
  76. package/dist/client/error-format.d.ts +20 -1
  77. package/dist/client/error-format.d.ts.map +1 -1
  78. package/dist/client/error-format.js +53 -5
  79. package/dist/client/error-format.js.map +1 -1
  80. package/dist/client/index.d.ts +3 -1
  81. package/dist/client/index.d.ts.map +1 -1
  82. package/dist/client/index.js +3 -1
  83. package/dist/client/index.js.map +1 -1
  84. package/dist/client/onboarding/OnboardingPanel.d.ts.map +1 -1
  85. package/dist/client/onboarding/OnboardingPanel.js +88 -6
  86. package/dist/client/onboarding/OnboardingPanel.js.map +1 -1
  87. package/dist/client/org/TeamPage.d.ts.map +1 -1
  88. package/dist/client/org/TeamPage.js +14 -2
  89. package/dist/client/org/TeamPage.js.map +1 -1
  90. package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
  91. package/dist/client/settings/SettingsPanel.js +145 -9
  92. package/dist/client/settings/SettingsPanel.js.map +1 -1
  93. package/dist/client/settings/useBuilderStatus.d.ts +13 -0
  94. package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
  95. package/dist/client/settings/useBuilderStatus.js +50 -9
  96. package/dist/client/settings/useBuilderStatus.js.map +1 -1
  97. package/dist/client/sse-event-processor.d.ts +9 -1
  98. package/dist/client/sse-event-processor.d.ts.map +1 -1
  99. package/dist/client/sse-event-processor.js +95 -8
  100. package/dist/client/sse-event-processor.js.map +1 -1
  101. package/dist/client/tools/ToolsListPage.d.ts.map +1 -1
  102. package/dist/client/tools/ToolsListPage.js +16 -1
  103. package/dist/client/tools/ToolsListPage.js.map +1 -1
  104. package/dist/client/tools/ToolsSidebarSection.d.ts.map +1 -1
  105. package/dist/client/tools/ToolsSidebarSection.js +63 -8
  106. package/dist/client/tools/ToolsSidebarSection.js.map +1 -1
  107. package/dist/client/tools/tool-order.d.ts +7 -0
  108. package/dist/client/tools/tool-order.d.ts.map +1 -0
  109. package/dist/client/tools/tool-order.js +47 -0
  110. package/dist/client/tools/tool-order.js.map +1 -0
  111. package/dist/client/transcription/BuilderTranscriptionCta.d.ts.map +1 -1
  112. package/dist/client/transcription/BuilderTranscriptionCta.js +71 -6
  113. package/dist/client/transcription/BuilderTranscriptionCta.js.map +1 -1
  114. package/dist/client/use-send-to-agent-chat.d.ts.map +1 -1
  115. package/dist/client/use-send-to-agent-chat.js +11 -3
  116. package/dist/client/use-send-to-agent-chat.js.map +1 -1
  117. package/dist/client/useProductionAgent.d.ts.map +1 -1
  118. package/dist/client/useProductionAgent.js +1 -1
  119. package/dist/client/useProductionAgent.js.map +1 -1
  120. package/dist/db/client.d.ts.map +1 -1
  121. package/dist/db/client.js +5 -1
  122. package/dist/db/client.js.map +1 -1
  123. package/dist/deploy/build.d.ts +1 -0
  124. package/dist/deploy/build.d.ts.map +1 -1
  125. package/dist/deploy/build.js +4 -1
  126. package/dist/deploy/build.js.map +1 -1
  127. package/dist/integrations/pending-tasks-retry-job.d.ts.map +1 -1
  128. package/dist/integrations/pending-tasks-retry-job.js +1 -1
  129. package/dist/integrations/pending-tasks-retry-job.js.map +1 -1
  130. package/dist/oauth-tokens/index.d.ts +1 -1
  131. package/dist/oauth-tokens/index.d.ts.map +1 -1
  132. package/dist/oauth-tokens/index.js +1 -1
  133. package/dist/oauth-tokens/index.js.map +1 -1
  134. package/dist/oauth-tokens/store.d.ts.map +1 -1
  135. package/dist/oauth-tokens/store.js +6 -0
  136. package/dist/oauth-tokens/store.js.map +1 -1
  137. package/dist/observability/store.d.ts.map +1 -1
  138. package/dist/observability/store.js +19 -19
  139. package/dist/observability/store.js.map +1 -1
  140. package/dist/onboarding/default-steps.d.ts.map +1 -1
  141. package/dist/onboarding/default-steps.js +95 -61
  142. package/dist/onboarding/default-steps.js.map +1 -1
  143. package/dist/onboarding/plugin.d.ts.map +1 -1
  144. package/dist/onboarding/plugin.js +17 -8
  145. package/dist/onboarding/plugin.js.map +1 -1
  146. package/dist/org/migrations.js +2 -2
  147. package/dist/org/migrations.js.map +1 -1
  148. package/dist/scripts/agent-engines/list-agent-engines.d.ts.map +1 -1
  149. package/dist/scripts/agent-engines/list-agent-engines.js +2 -3
  150. package/dist/scripts/agent-engines/list-agent-engines.js.map +1 -1
  151. package/dist/scripts/db/exec.d.ts +2 -1
  152. package/dist/scripts/db/exec.d.ts.map +1 -1
  153. package/dist/scripts/db/exec.js +264 -61
  154. package/dist/scripts/db/exec.js.map +1 -1
  155. package/dist/scripts/db/schema.d.ts.map +1 -1
  156. package/dist/scripts/db/schema.js +16 -4
  157. package/dist/scripts/db/schema.js.map +1 -1
  158. package/dist/scripts/dev/index.d.ts.map +1 -1
  159. package/dist/scripts/dev/index.js +36 -11
  160. package/dist/scripts/dev/index.js.map +1 -1
  161. package/dist/scripts/manage-agent-loop-settings.d.ts +7 -0
  162. package/dist/scripts/manage-agent-loop-settings.d.ts.map +1 -0
  163. package/dist/scripts/manage-agent-loop-settings.js +63 -0
  164. package/dist/scripts/manage-agent-loop-settings.js.map +1 -0
  165. package/dist/scripts/runner.d.ts.map +1 -1
  166. package/dist/scripts/runner.js +11 -0
  167. package/dist/scripts/runner.js.map +1 -1
  168. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  169. package/dist/server/agent-chat-plugin.js +60 -18
  170. package/dist/server/agent-chat-plugin.js.map +1 -1
  171. package/dist/server/app-url.d.ts +5 -4
  172. package/dist/server/app-url.d.ts.map +1 -1
  173. package/dist/server/app-url.js +8 -4
  174. package/dist/server/app-url.js.map +1 -1
  175. package/dist/server/auth.d.ts +37 -0
  176. package/dist/server/auth.d.ts.map +1 -1
  177. package/dist/server/auth.js +114 -35
  178. package/dist/server/auth.js.map +1 -1
  179. package/dist/server/better-auth-instance.d.ts +15 -0
  180. package/dist/server/better-auth-instance.d.ts.map +1 -1
  181. package/dist/server/better-auth-instance.js +131 -5
  182. package/dist/server/better-auth-instance.js.map +1 -1
  183. package/dist/server/builder-browser.d.ts +12 -0
  184. package/dist/server/builder-browser.d.ts.map +1 -1
  185. package/dist/server/builder-browser.js +36 -4
  186. package/dist/server/builder-browser.js.map +1 -1
  187. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  188. package/dist/server/core-routes-plugin.js +350 -53
  189. package/dist/server/core-routes-plugin.js.map +1 -1
  190. package/dist/server/credential-provider.d.ts +21 -3
  191. package/dist/server/credential-provider.d.ts.map +1 -1
  192. package/dist/server/credential-provider.js +51 -21
  193. package/dist/server/credential-provider.js.map +1 -1
  194. package/dist/server/google-oauth.d.ts +3 -0
  195. package/dist/server/google-oauth.d.ts.map +1 -1
  196. package/dist/server/google-oauth.js +35 -18
  197. package/dist/server/google-oauth.js.map +1 -1
  198. package/dist/server/index.d.ts +4 -3
  199. package/dist/server/index.d.ts.map +1 -1
  200. package/dist/server/index.js +4 -3
  201. package/dist/server/index.js.map +1 -1
  202. package/dist/server/schema-prompt.d.ts.map +1 -1
  203. package/dist/server/schema-prompt.js +2 -1
  204. package/dist/server/schema-prompt.js.map +1 -1
  205. package/dist/server/security-headers.d.ts +3 -0
  206. package/dist/server/security-headers.d.ts.map +1 -1
  207. package/dist/server/security-headers.js +7 -1
  208. package/dist/server/security-headers.js.map +1 -1
  209. package/dist/server/ssr-handler.d.ts.map +1 -1
  210. package/dist/server/ssr-handler.js +24 -4
  211. package/dist/server/ssr-handler.js.map +1 -1
  212. package/dist/server/voice-providers-status.d.ts +7 -0
  213. package/dist/server/voice-providers-status.d.ts.map +1 -1
  214. package/dist/server/voice-providers-status.js +1 -0
  215. package/dist/server/voice-providers-status.js.map +1 -1
  216. package/dist/templates/default/_gitignore +5 -1
  217. package/dist/templates/default/app/root.tsx +1 -0
  218. package/dist/templates/default/public/favicon.svg +3 -3
  219. package/dist/templates/default/public/icon-180.svg +3 -3
  220. package/dist/templates/default/public/icon-192.svg +3 -3
  221. package/dist/templates/default/public/icon-512.svg +3 -3
  222. package/dist/templates/workspace-core/AGENTS.md +23 -7
  223. package/dist/templates/workspace-core/package.json +2 -1
  224. package/dist/templates/workspace-core/src/credentials.ts +22 -11
  225. package/dist/templates/workspace-root/.env.example +7 -0
  226. package/dist/templates/workspace-root/README.md +6 -3
  227. package/dist/templates/workspace-root/_gitignore +3 -0
  228. package/dist/templates/workspace-root/package.json +3 -1
  229. package/dist/templates/workspace-root/scripts/workspace-dev.ts +410 -0
  230. package/dist/tools/actions.d.ts.map +1 -1
  231. package/dist/tools/actions.js +2 -0
  232. package/dist/tools/actions.js.map +1 -1
  233. package/dist/tools/html-shell.d.ts.map +1 -1
  234. package/dist/tools/html-shell.js +13 -1
  235. package/dist/tools/html-shell.js.map +1 -1
  236. package/dist/tools/store.d.ts.map +1 -1
  237. package/dist/tools/store.js +16 -11
  238. package/dist/tools/store.js.map +1 -1
  239. package/dist/tracking/providers.d.ts +1 -0
  240. package/dist/tracking/providers.d.ts.map +1 -1
  241. package/dist/tracking/providers.js +72 -0
  242. package/dist/tracking/providers.js.map +1 -1
  243. package/dist/vite/action-types-plugin.d.ts.map +1 -1
  244. package/dist/vite/action-types-plugin.js +106 -9
  245. package/dist/vite/action-types-plugin.js.map +1 -1
  246. package/dist/vite/client.d.ts.map +1 -1
  247. package/dist/vite/client.js +67 -2
  248. package/dist/vite/client.js.map +1 -1
  249. package/docs/content/authentication.md +17 -13
  250. package/docs/content/deployment.md +11 -11
  251. package/docs/content/mcp-clients.md +2 -2
  252. package/docs/content/onboarding.md +32 -30
  253. package/docs/content/security.md +1 -1
  254. package/docs/content/tools.md +4 -0
  255. package/package.json +2 -2
  256. package/src/templates/default/_gitignore +5 -1
  257. package/src/templates/default/app/root.tsx +1 -0
  258. package/src/templates/default/public/favicon.svg +3 -3
  259. package/src/templates/default/public/icon-180.svg +3 -3
  260. package/src/templates/default/public/icon-192.svg +3 -3
  261. package/src/templates/default/public/icon-512.svg +3 -3
  262. package/src/templates/workspace-core/AGENTS.md +23 -7
  263. package/src/templates/workspace-core/package.json +2 -1
  264. package/src/templates/workspace-core/src/credentials.ts +22 -11
  265. package/src/templates/workspace-root/.env.example +7 -0
  266. package/src/templates/workspace-root/README.md +6 -3
  267. package/src/templates/workspace-root/_gitignore +3 -0
  268. package/src/templates/workspace-root/package.json +3 -1
  269. package/src/templates/workspace-root/scripts/workspace-dev.ts +410 -0
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantChat.d.ts","sourceRoot":"","sources":["../../src/client/AssistantChat.tsx"],"names":[],"mappings":"AACA,OAAO,KAQN,MAAM,OAAO,CAAC;AAo5Cf,MAAM,WAAW,mBAAmB;IAClC,qDAAqD;IACrD,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,6DAA6D;IAC7D,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,4CAA4C;IAC5C,SAAS,IAAI,OAAO,CAAC;IACrB,+BAA+B;IAC/B,aAAa,IAAI,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IACjC,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wGAAwG;IACxG,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uCAAuC;IACvC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gDAAgD;IAChD,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,oDAAoD;IACpD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iDAAiD;IACjD,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,0CAA0C;IAC1C,oBAAoB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,8EAA8E;IAC9E,YAAY,CAAC,EAAE,CACb,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE;QACJ,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,YAAY,EAAE,MAAM,CAAC;KACtB,KACE,IAAI,CAAC;IACV,+DAA+D;IAC/D,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9D,8DAA8D;IAC9D,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC/B,+FAA+F;IAC/F,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,mEAAmE;IACnE,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC5B,wCAAwC;IACxC,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,KAAK,IAAI,CAAC;IACpD,qFAAqF;IACrF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iFAAiF;IACjF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qDAAqD;IACrD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,uDAAuD;IACvD,eAAe,CAAC,EAAE,KAAK,CAAC;QACtB,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,EAAE,CAAC;QACjB,UAAU,EAAE,OAAO,CAAC;KACrB,CAAC,CAAC;IACH,uDAAuD;IACvD,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACxD,wEAAwE;IACxE,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB;AAED,eAAO,MAAM,mBAAmB,gBAAgB,CAAC;AAEjD,8DAA8D;AAC9D,wBAAgB,gBAAgB,CAAC,KAAK,CAAC,EAAE,MAAM,QAI9C;AAyBD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,CAAC;AA4gC7B,eAAO,MAAM,aAAa,gGA+CxB,CAAC"}
1
+ {"version":3,"file":"AssistantChat.d.ts","sourceRoot":"","sources":["../../src/client/AssistantChat.tsx"],"names":[],"mappings":"AACA,OAAO,KAQN,MAAM,OAAO,CAAC;AA22Df,MAAM,WAAW,mBAAmB;IAClC,qDAAqD;IACrD,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,6DAA6D;IAC7D,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,4CAA4C;IAC5C,SAAS,IAAI,OAAO,CAAC;IACrB,+BAA+B;IAC/B,aAAa,IAAI,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IACjC,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wGAAwG;IACxG,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uCAAuC;IACvC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gDAAgD;IAChD,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,oDAAoD;IACpD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iDAAiD;IACjD,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,0CAA0C;IAC1C,oBAAoB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,8EAA8E;IAC9E,YAAY,CAAC,EAAE,CACb,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE;QACJ,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,YAAY,EAAE,MAAM,CAAC;KACtB,KACE,IAAI,CAAC;IACV,+DAA+D;IAC/D,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9D,8DAA8D;IAC9D,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC/B,+FAA+F;IAC/F,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,mEAAmE;IACnE,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC5B,wCAAwC;IACxC,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,KAAK,IAAI,CAAC;IACpD,qFAAqF;IACrF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iFAAiF;IACjF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qDAAqD;IACrD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,uDAAuD;IACvD,eAAe,CAAC,EAAE,KAAK,CAAC;QACtB,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,EAAE,CAAC;QACjB,UAAU,EAAE,OAAO,CAAC;KACrB,CAAC,CAAC;IACH,uDAAuD;IACvD,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACxD,wEAAwE;IACxE,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB;AAED,eAAO,MAAM,mBAAmB,gBAAgB,CAAC;AAEjD,8DAA8D;AAC9D,wBAAgB,gBAAgB,CAAC,KAAK,CAAC,EAAE,MAAM,QAI9C;AAyBD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,CAAC;AAymC7B,eAAO,MAAM,aAAa,gGAwDxB,CAAC"}
@@ -7,6 +7,7 @@ import { MarkdownTextPrimitive } from "@assistant-ui/react-markdown";
7
7
  import ReactMarkdown from "react-markdown";
8
8
  import remarkGfm from "remark-gfm";
9
9
  import { createAgentChatAdapter } from "./agent-chat-adapter.js";
10
+ import { getActiveRun } from "./active-run-state.js";
10
11
  import { readSSEStreamRaw } from "./sse-event-processor.js";
11
12
  import { cn } from "./utils.js";
12
13
  import { AgentTaskCard } from "./AgentTaskCard.js";
@@ -15,8 +16,9 @@ import { useBuilderConnectFlow } from "./settings/useBuilderStatus.js";
15
16
  import { IframeEmbed, parseEmbedBody } from "./IframeEmbed.js";
16
17
  import { useDevMode } from "./use-dev-mode.js";
17
18
  import { agentNativePath } from "./api-path.js";
19
+ import { BUILDER_SPACE_SETTINGS_URL } from "./error-format.js";
18
20
  import { TiptapComposer, } from "./composer/TiptapComposer.js";
19
- import { IconMessage, IconX, IconPlayerStop, IconCheck, IconChevronDown, IconCopy, IconTerminal, IconLoader2, IconCircleX, IconSquareFilled, IconClock, IconFile, IconFolder, IconFileText, IconCheckbox, IconMail, IconUser, IconPresentation, IconStack2, IconMessageChatbot, IconLock, IconArrowBackUp, IconExternalLink, IconDots, IconGitFork, IconId, IconQuote, } from "@tabler/icons-react";
21
+ import { IconMessage, IconX, IconPlayerStop, IconCheck, IconChevronDown, IconCopy, IconTerminal, IconLoader2, IconCircleX, IconSquareFilled, IconClock, IconFile, IconFolder, IconFileText, IconCheckbox, IconMail, IconUser, IconPresentation, IconStack2, IconMessageChatbot, IconLock, IconArrowBackUp, IconExternalLink, IconDots, IconGitFork, IconId, IconQuote, IconGauge, IconArrowRight, IconSettings, IconAlertTriangle, IconRefresh, IconPlayerPlay, } from "@tabler/icons-react";
20
22
  const ThumbsFeedbackLazy = React.lazy(() => import("./observability/ThumbsFeedback.js").then((m) => ({
21
23
  default: m.ThumbsFeedback,
22
24
  })));
@@ -45,6 +47,7 @@ const markdownStyles = `
45
47
  @media (prefers-color-scheme: dark) { :root:not(.light) .agent-markdown-shiki pre { background: var(--shiki-dark-bg); color: var(--shiki-dark); } :root:not(.light) .agent-markdown-shiki pre span { color: var(--shiki-dark); background: var(--shiki-dark-bg); } }
46
48
  .agent-markdown hr { border: none; border-top: 1px solid hsl(var(--border, 0 0% 20%)); margin: 0.75em 0; }
47
49
  .agent-markdown a { text-decoration: underline; text-underline-offset: 2px; }
50
+ .agent-markdown a.agent-markdown-cta { text-decoration: none; }
48
51
  .agent-markdown blockquote { border-left: 2px solid hsl(var(--border, 0 0% 20%)); padding-left: 0.75em; margin: 0.5em 0; opacity: 0.8; }
49
52
  .agent-markdown table { border-collapse: collapse; margin: 0.5em 0; font-size: 0.875em; }
50
53
  .agent-markdown th, .agent-markdown td { border: 1px solid hsl(var(--border, 0 0% 20%)); padding: 0.35em 0.65em; text-align: left; }
@@ -218,6 +221,14 @@ function HighlightedCodeBlock({ code, lang }) {
218
221
  return (_jsx("pre", { children: _jsx("code", { className: lang ? `language-${lang}` : undefined, children: code }) }));
219
222
  }
220
223
  const markdownComponents = {
224
+ a(props) {
225
+ const { href, children, className, rel: _rel, target: _target, ...rest } = props;
226
+ const isBuilderCta = isBuilderErrorCtaHref(href);
227
+ if (!isBuilderCta) {
228
+ return (_jsx("a", { href: href, className: className, ...rest, children: children }));
229
+ }
230
+ return (_jsxs("a", { href: href, target: "_blank", rel: "noreferrer", className: cn("agent-markdown-cta mt-1 inline-flex items-center gap-1.5 rounded-md bg-foreground px-3 py-1.5 text-xs font-medium text-background no-underline shadow-sm transition-colors hover:bg-foreground/90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background", className), ...rest, children: [_jsx("span", { children: children }), _jsx(IconExternalLink, { size: 13, strokeWidth: 2, "aria-hidden": "true" })] }));
231
+ },
221
232
  pre(props) {
222
233
  const { children, ...rest } = props;
223
234
  if (React.isValidElement(children)) {
@@ -237,6 +248,22 @@ const markdownComponents = {
237
248
  return _jsx("pre", { ...rest, children: children });
238
249
  },
239
250
  };
251
+ function isBuilderErrorCtaHref(href) {
252
+ if (!href)
253
+ return false;
254
+ try {
255
+ const url = new URL(href);
256
+ if (url.protocol !== "https:" || url.hostname !== "builder.io") {
257
+ return false;
258
+ }
259
+ return (url.href === BUILDER_SPACE_SETTINGS_URL ||
260
+ url.pathname === "/account/billing" ||
261
+ /^\/app\/organizations\/[^/]+\/billing$/.test(url.pathname));
262
+ }
263
+ catch {
264
+ return false;
265
+ }
266
+ }
240
267
  function MarkdownText() {
241
268
  useEffect(() => {
242
269
  injectMarkdownStyles();
@@ -543,7 +570,17 @@ function MessageActionsMenu({ showRevert, onRevert, } = {}) {
543
570
  }, [messageRuntime]);
544
571
  const handleCopyRequestId = useCallback(() => {
545
572
  const m = messageRuntime.getState();
546
- const runId = m.metadata?.runId || m.id || "";
573
+ const meta = m.metadata;
574
+ // Live yields put the trace ID at metadata.custom.runId; server-persisted
575
+ // messages put it at metadata.runId. If neither is present (e.g. the run
576
+ // is still in flight and this is the first message), fall back to the
577
+ // active-run state so a hung / mid-stream chat still surfaces a usable
578
+ // trace ID. Last resort is the assistant-ui local message id.
579
+ const runId = (typeof meta?.custom?.runId === "string" && meta.custom.runId) ||
580
+ (typeof meta?.runId === "string" && meta.runId) ||
581
+ (typeof window !== "undefined" ? getActiveRun()?.runId : null) ||
582
+ m.id ||
583
+ "";
547
584
  navigator.clipboard.writeText(runId);
548
585
  setCopied("id");
549
586
  setTimeout(() => {
@@ -574,10 +611,11 @@ function AssistantMessage() {
574
611
  const [restoreState, setRestoreState] = useState("idle");
575
612
  const messageRuntime = useMessageRuntime();
576
613
  const thread = useThread();
614
+ const chatRunning = React.useContext(ChatRunningContext);
577
615
  const msg = messageRuntime.getState();
578
616
  const isLast = thread.messages.length > 0 &&
579
617
  thread.messages[thread.messages.length - 1].id === msg.id;
580
- const isComplete = !isLast || !thread.isRunning;
618
+ const isComplete = !isLast || !chatRunning;
581
619
  const cpCtx = React.useContext(CheckpointContext);
582
620
  const handleRestore = useCallback(async () => {
583
621
  if (restoreState === "idle") {
@@ -589,7 +627,10 @@ function AssistantMessage() {
589
627
  setRestoreState("restoring");
590
628
  try {
591
629
  const m = messageRuntime.getState();
592
- const runId = m.metadata?.runId;
630
+ const meta = m.metadata;
631
+ const runId = (typeof meta?.custom?.runId === "string" && meta.custom.runId) ||
632
+ (typeof meta?.runId === "string" && meta.runId) ||
633
+ null;
593
634
  if (!runId) {
594
635
  setRestoreState("idle");
595
636
  return;
@@ -627,7 +668,13 @@ function AssistantMessage() {
627
668
  tools: {
628
669
  Fallback: ToolCallFallback,
629
670
  },
630
- } }) }), isComplete && (_jsxs("div", { className: "mt-1 flex items-center justify-between", children: [_jsx(MessageActionsMenu, { showRevert: showRestore && restoreState === "idle", onRevert: handleRestore }), showRestore && restoreState === "confirming" ? (_jsxs("div", { className: "flex items-center gap-1 text-xs", children: [_jsx("button", { onClick: handleRestore, className: "rounded-md bg-destructive px-1.5 py-0.5 text-destructive-foreground hover:bg-destructive/90", children: "Restore to here?" }), _jsx("button", { onClick: cancelRestore, className: "rounded-md px-1.5 py-0.5 text-muted-foreground hover:bg-accent", children: "Cancel" })] })) : showRestore && restoreState === "restoring" ? (_jsxs("span", { className: "flex items-center gap-1 text-xs text-muted-foreground", children: [_jsx(IconLoader2, { className: "h-3 w-3 animate-spin" }), "Restoring..."] })) : (_jsx(React.Suspense, { fallback: null, children: _jsx(ThumbsFeedbackLazy, { threadId: cpCtx?.threadId ?? "", runId: messageRuntime.getState().metadata?.runId ?? "", messageSeq: thread.messages.findIndex((m) => m.id === msg.id) }) }))] }))] }));
671
+ } }) }), isComplete && (_jsxs("div", { className: "mt-1 flex items-center justify-between", children: [_jsx(MessageActionsMenu, { showRevert: showRestore && restoreState === "idle", onRevert: handleRestore }), showRestore && restoreState === "confirming" ? (_jsxs("div", { className: "flex items-center gap-1 text-xs", children: [_jsx("button", { onClick: handleRestore, className: "rounded-md bg-destructive px-1.5 py-0.5 text-destructive-foreground hover:bg-destructive/90", children: "Restore to here?" }), _jsx("button", { onClick: cancelRestore, className: "rounded-md px-1.5 py-0.5 text-muted-foreground hover:bg-accent", children: "Cancel" })] })) : showRestore && restoreState === "restoring" ? (_jsxs("span", { className: "flex items-center gap-1 text-xs text-muted-foreground", children: [_jsx(IconLoader2, { className: "h-3 w-3 animate-spin" }), "Restoring..."] })) : (_jsx(React.Suspense, { fallback: null, children: _jsx(ThumbsFeedbackLazy, { threadId: cpCtx?.threadId ?? "", runId: (() => {
672
+ const meta = messageRuntime.getState().metadata;
673
+ return ((typeof meta?.custom?.runId === "string" &&
674
+ meta.custom.runId) ||
675
+ (typeof meta?.runId === "string" && meta.runId) ||
676
+ "");
677
+ })(), messageSeq: thread.messages.findIndex((m) => m.id === msg.id) }) }))] }))] }));
631
678
  }
632
679
  // ─── Thinking Indicator ─────────────────────────────────────────────────────
633
680
  function ThinkingIndicator({ label = "Thinking" } = {}) {
@@ -709,6 +756,163 @@ function ApiKeySetupCard({ apiUrl }) {
709
756
  handleSave();
710
757
  }, placeholder: "sk-ant-...", className: "w-full rounded-md border border-input bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground/50 outline-none focus:ring-1 focus:ring-ring", autoComplete: "off" }), error && _jsx("p", { className: "text-xs text-destructive", children: error }), apiKey.trim() && (_jsx("button", { onClick: handleSave, disabled: saving, className: "w-full rounded-md bg-primary px-3 py-2 text-sm font-medium text-primary-foreground hover:opacity-90 disabled:opacity-40 disabled:cursor-not-allowed", children: saving ? "Saving..." : "Save API key" })), _jsx("p", { className: "text-[10px] text-muted-foreground/60 text-center", children: _jsx("a", { href: "https://console.anthropic.com/settings/keys", target: "_blank", rel: "noopener noreferrer", className: "underline hover:text-foreground/80", children: "Get an Anthropic key" }) })] })] }));
711
758
  }
759
+ function getLoopLimitMetadata(message) {
760
+ const meta = message?.metadata;
761
+ const loopLimit = meta?.custom?.loopLimit ?? meta?.loopLimit;
762
+ if (!loopLimit || typeof loopLimit !== "object")
763
+ return null;
764
+ return {
765
+ ...(typeof loopLimit.maxIterations === "number"
766
+ ? { maxIterations: loopLimit.maxIterations }
767
+ : {}),
768
+ };
769
+ }
770
+ function getRunErrorMetadata(message) {
771
+ const meta = message?.metadata;
772
+ const runError = meta?.custom?.runError ?? meta?.runError;
773
+ if (!runError || typeof runError !== "object")
774
+ return null;
775
+ const messageText = typeof runError.message === "string" ? runError.message : "";
776
+ if (!messageText)
777
+ return null;
778
+ const runId = typeof runError.runId === "string"
779
+ ? runError.runId
780
+ : typeof meta?.custom?.runId === "string"
781
+ ? meta.custom.runId
782
+ : typeof meta?.runId === "string"
783
+ ? meta.runId
784
+ : undefined;
785
+ return {
786
+ message: messageText,
787
+ ...(typeof runError.details === "string"
788
+ ? { details: runError.details }
789
+ : {}),
790
+ ...(typeof runError.errorCode === "string"
791
+ ? { errorCode: runError.errorCode }
792
+ : {}),
793
+ ...(runId ? { runId } : {}),
794
+ ...(runError.recoverable ? { recoverable: true } : {}),
795
+ };
796
+ }
797
+ function getMessageText(message) {
798
+ const msg = message?.message ?? message;
799
+ const content = msg?.content;
800
+ if (Array.isArray(content)) {
801
+ return content
802
+ .filter((p) => p?.type === "text" && typeof p.text === "string")
803
+ .map((p) => p.text)
804
+ .join("\n")
805
+ .trim();
806
+ }
807
+ return typeof content === "string" ? content.trim() : "";
808
+ }
809
+ function RunErrorRecoveryCard({ info, onContinue, onRetry, onFork, onDismiss, }) {
810
+ const [detailsOpen, setDetailsOpen] = useState(false);
811
+ const [copied, setCopied] = useState(false);
812
+ const copyDetails = useCallback(() => {
813
+ const text = [
814
+ info.message,
815
+ info.errorCode ? `Code: ${info.errorCode}` : "",
816
+ info.runId ? `Run: ${info.runId}` : "",
817
+ info.details ? `Details:\n${info.details}` : "",
818
+ ]
819
+ .filter(Boolean)
820
+ .join("\n\n");
821
+ navigator.clipboard.writeText(text);
822
+ setCopied(true);
823
+ setTimeout(() => setCopied(false), 1200);
824
+ }, [info]);
825
+ return (_jsxs("div", { className: "rounded-lg border border-amber-500/25 bg-amber-500/[0.06] p-3 text-sm", children: [_jsxs("div", { className: "flex items-start gap-2", children: [_jsx("span", { className: "mt-0.5 flex h-6 w-6 shrink-0 items-center justify-center rounded-md bg-amber-500/10 text-amber-700 dark:text-amber-300", children: _jsx(IconAlertTriangle, { size: 14 }) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: "font-medium text-foreground", children: "The agent stopped before finishing" }), _jsx("p", { className: "mt-1 text-xs leading-relaxed text-muted-foreground", children: info.message }), (info.runId || info.errorCode || info.details) && (_jsxs("button", { type: "button", onClick: () => setDetailsOpen((v) => !v), className: "mt-2 inline-flex items-center gap-1 text-[11px] font-medium text-muted-foreground hover:text-foreground", children: [_jsx(IconChevronDown, { size: 12, className: cn("transition-transform", detailsOpen && "rotate-180") }), "Details"] })), detailsOpen && (_jsxs("div", { className: "mt-2 rounded-md border border-border/60 bg-background/70 p-2 font-mono text-[11px] leading-relaxed text-muted-foreground", children: [info.runId && _jsxs("div", { children: ["run: ", info.runId] }), info.errorCode && _jsxs("div", { children: ["code: ", info.errorCode] }), info.details && (_jsx("pre", { className: "mt-2 max-h-28 overflow-auto whitespace-pre-wrap break-words font-mono", children: info.details }))] }))] }), _jsx("button", { type: "button", onClick: onDismiss, "aria-label": "Dismiss", className: "flex h-6 w-6 shrink-0 items-center justify-center rounded-md text-muted-foreground hover:bg-background/80 hover:text-foreground", children: _jsx(IconX, { size: 14 }) })] }), _jsxs("div", { className: "mt-3 flex flex-wrap items-center gap-2", children: [_jsxs("button", { type: "button", onClick: onContinue, className: "inline-flex h-8 items-center gap-1.5 rounded-md bg-foreground px-3 text-xs font-medium text-background hover:opacity-90", children: [_jsx(IconPlayerPlay, { size: 13 }), "Continue"] }), _jsxs("button", { type: "button", onClick: onRetry, className: "inline-flex h-8 items-center gap-1.5 rounded-md border border-border bg-background px-3 text-xs font-medium text-foreground hover:bg-accent", children: [_jsx(IconRefresh, { size: 13 }), "Retry"] }), onFork && (_jsxs("button", { type: "button", onClick: onFork, className: "inline-flex h-8 items-center gap-1.5 rounded-md border border-border bg-background px-3 text-xs font-medium text-foreground hover:bg-accent", children: [_jsx(IconGitFork, { size: 13 }), "Fork"] })), _jsxs("button", { type: "button", onClick: copyDetails, className: "ml-auto inline-flex h-8 items-center gap-1.5 rounded-md px-2.5 text-xs font-medium text-muted-foreground hover:bg-background/80 hover:text-foreground", children: [copied ? _jsx(IconCheck, { size: 13 }) : _jsx(IconCopy, { size: 13 }), copied ? "Copied" : "Copy"] })] })] }));
826
+ }
827
+ function LoopLimitContinueCard({ info, onContinue, }) {
828
+ const [settings, setSettings] = useState(null);
829
+ const [value, setValue] = useState("");
830
+ const [saving, setSaving] = useState(false);
831
+ const [saved, setSaved] = useState(false);
832
+ const [error, setError] = useState(null);
833
+ const load = useCallback(() => {
834
+ let cancelled = false;
835
+ fetch(agentNativePath("/_agent-native/agent-loop-settings"))
836
+ .then((r) => (r.ok ? r.json() : null))
837
+ .then((data) => {
838
+ if (cancelled || !data)
839
+ return;
840
+ setSettings(data);
841
+ setValue(String(data.maxIterations));
842
+ })
843
+ .catch(() => {
844
+ if (!cancelled)
845
+ setValue(String(info.maxIterations ?? ""));
846
+ });
847
+ return () => {
848
+ cancelled = true;
849
+ };
850
+ }, [info.maxIterations]);
851
+ useEffect(() => load(), [load]);
852
+ const currentLimit = settings?.maxIterations ?? info.maxIterations;
853
+ const numericValue = Number(value);
854
+ const hasPendingChange = !!settings &&
855
+ settings.canUpdate &&
856
+ Number.isInteger(numericValue) &&
857
+ numericValue !== settings.maxIterations;
858
+ const scopeLabel = settings?.scope === "org"
859
+ ? settings.orgName
860
+ ? `${settings.orgName} org`
861
+ : "org"
862
+ : "your account";
863
+ const saveLimit = useCallback(async () => {
864
+ if (!settings?.canUpdate)
865
+ return false;
866
+ setSaving(true);
867
+ setSaved(false);
868
+ setError(null);
869
+ try {
870
+ const res = await fetch(agentNativePath("/_agent-native/agent-loop-settings"), {
871
+ method: "PUT",
872
+ headers: { "Content-Type": "application/json" },
873
+ body: JSON.stringify({ maxIterations: numericValue }),
874
+ });
875
+ const body = await res.json().catch(() => ({}));
876
+ if (!res.ok) {
877
+ throw new Error(body?.error ?? `Save failed (${res.status})`);
878
+ }
879
+ setSettings(body);
880
+ setValue(String(body.maxIterations));
881
+ setSaved(true);
882
+ window.dispatchEvent(new CustomEvent("agent-loop-settings:changed", { detail: body }));
883
+ setTimeout(() => setSaved(false), 2000);
884
+ return true;
885
+ }
886
+ catch (err) {
887
+ setError(err instanceof Error ? err.message : "Save failed");
888
+ return false;
889
+ }
890
+ finally {
891
+ setSaving(false);
892
+ }
893
+ }, [numericValue, settings?.canUpdate]);
894
+ const handleContinue = useCallback(async () => {
895
+ if (hasPendingChange) {
896
+ const ok = await saveLimit();
897
+ if (!ok)
898
+ return;
899
+ }
900
+ onContinue();
901
+ }, [hasPendingChange, onContinue, saveLimit]);
902
+ const openSettings = useCallback(() => {
903
+ try {
904
+ window.location.hash = "agent-limits";
905
+ }
906
+ catch { }
907
+ window.dispatchEvent(new CustomEvent("agent-panel:open-settings"));
908
+ }, []);
909
+ return (_jsxs("div", { className: "rounded-lg border border-amber-500/25 bg-amber-500/[0.06] px-3 py-3 shadow-sm", children: [_jsxs("div", { className: "flex items-start gap-2.5", children: [_jsx("span", { className: "mt-0.5 flex h-6 w-6 shrink-0 items-center justify-center rounded-md bg-amber-500/10 text-amber-600 dark:text-amber-400", children: _jsx(IconGauge, { size: 14 }) }), _jsxs("div", { className: "min-w-0", children: [_jsx("p", { className: "text-sm font-medium text-foreground", children: "Step limit reached" }), _jsxs("p", { className: "mt-0.5 text-xs leading-relaxed text-muted-foreground", children: ["The agent used", " ", currentLimit
910
+ ? `${currentLimit.toLocaleString()} steps`
911
+ : "all available steps", ". Keep going in a fresh turn, or raise the ", scopeLabel, " limit first."] })] })] }), _jsxs("div", { className: "mt-3 flex flex-wrap items-end gap-2", children: [_jsxs("label", { className: "min-w-[116px] flex-1 space-y-1", children: [_jsx("span", { className: "text-[10px] font-medium uppercase tracking-wide text-muted-foreground", children: "Max steps" }), _jsx("input", { type: "number", min: settings?.minMaxIterations ?? 1, max: settings?.maxMaxIterations ?? 1000, value: value, disabled: !settings?.canUpdate || saving, onChange: (e) => {
912
+ setValue(e.target.value);
913
+ setError(null);
914
+ }, className: "h-8 w-full rounded-md border border-border bg-background px-2 text-xs text-foreground outline-none focus:ring-1 focus:ring-ring disabled:opacity-60" })] }), _jsx("button", { type: "button", onClick: saveLimit, disabled: !hasPendingChange || saving, className: "inline-flex h-8 items-center gap-1 rounded-md border border-border px-2.5 text-xs font-medium text-foreground hover:bg-accent disabled:opacity-50", children: saving ? (_jsx(IconLoader2, { size: 12, className: "animate-spin" })) : saved ? (_jsx(IconCheck, { size: 12 })) : ("Save") }), _jsxs("button", { type: "button", onClick: openSettings, className: "inline-flex h-8 items-center gap-1 rounded-md border border-border px-2.5 text-xs font-medium text-muted-foreground hover:bg-accent hover:text-foreground", children: [_jsx(IconSettings, { size: 12 }), "Settings"] }), _jsxs("button", { type: "button", onClick: handleContinue, disabled: saving, className: "ml-auto inline-flex h-8 items-center gap-1 rounded-md bg-foreground px-3 text-xs font-medium text-background hover:opacity-90 disabled:opacity-60", children: [hasPendingChange ? "Save and keep going" : "Keep going", _jsx(IconArrowRight, { size: 12 })] })] }), settings && !settings.canUpdate && (_jsx("p", { className: "mt-2 text-[11px] text-muted-foreground", children: "Only organization owners and admins can change this limit." })), error && _jsx("p", { className: "mt-2 text-[11px] text-destructive", children: error })] }));
915
+ }
712
916
  export const CHAT_STORAGE_PREFIX = "agent-chat:";
713
917
  /** Remove persisted chat for a given tabId (or "default"). */
714
918
  export function clearChatStorage(tabId) {
@@ -757,6 +961,9 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
757
961
  // on mount, or queue state that hasn't actually changed).
758
962
  const lastPersistedQueueRef = useRef("[]");
759
963
  const [showContinue, setShowContinue] = useState(false);
964
+ const [loopLimitInfo, setLoopLimitInfo] = useState(null);
965
+ const [runErrorInfo, setRunErrorInfo] = useState(null);
966
+ const [dismissedRunErrorKey, setDismissedRunErrorKey] = useState(null);
760
967
  const [isReconnecting, setIsReconnecting] = useState(false);
761
968
  const [reconnectContent, setReconnectContent] = useState([]);
762
969
  // When stop is clicked during reconnect, keep content visible (don't wipe it)
@@ -1191,12 +1398,36 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
1191
1398
  const handler = (e) => {
1192
1399
  const detail = e.detail;
1193
1400
  if (!tabId || detail?.tabId === tabId) {
1401
+ setLoopLimitInfo({
1402
+ ...(typeof detail?.maxIterations === "number"
1403
+ ? { maxIterations: detail.maxIterations }
1404
+ : {}),
1405
+ });
1194
1406
  setShowContinue(true);
1195
1407
  }
1196
1408
  };
1197
1409
  window.addEventListener("agent-chat:loop-limit", handler);
1198
1410
  return () => window.removeEventListener("agent-chat:loop-limit", handler);
1199
1411
  }, [tabId]);
1412
+ useEffect(() => {
1413
+ const handler = (e) => {
1414
+ const detail = e.detail;
1415
+ if (tabId && detail?.tabId && detail.tabId !== tabId)
1416
+ return;
1417
+ if (!detail?.message)
1418
+ return;
1419
+ setRunErrorInfo({
1420
+ message: detail.message,
1421
+ ...(detail.details ? { details: detail.details } : {}),
1422
+ ...(detail.errorCode ? { errorCode: detail.errorCode } : {}),
1423
+ ...(detail.runId ? { runId: detail.runId } : {}),
1424
+ ...(detail.recoverable ? { recoverable: detail.recoverable } : {}),
1425
+ });
1426
+ setDismissedRunErrorKey(null);
1427
+ };
1428
+ window.addEventListener("agent-chat:run-error", handler);
1429
+ return () => window.removeEventListener("agent-chat:run-error", handler);
1430
+ }, [tabId]);
1200
1431
  // Auto-dequeue: when agent finishes running, send the next queued message
1201
1432
  useEffect(() => {
1202
1433
  if (wasRunningRef.current && !isRunning && queuedMessages.length > 0) {
@@ -1252,6 +1483,9 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
1252
1483
  }, [isReconnecting, forceStopped]);
1253
1484
  const addToQueue = useCallback((text, images, references) => {
1254
1485
  setShowContinue(false);
1486
+ setLoopLimitInfo(null);
1487
+ setRunErrorInfo(null);
1488
+ setDismissedRunErrorKey(null);
1255
1489
  // Selection context attached via Cmd+I is one-shot — clear it as soon
1256
1490
  // as the user actually sends a message so it can't be re-used.
1257
1491
  clearPendingSelection();
@@ -1353,6 +1587,35 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
1353
1587
  const { isDevMode: cpDevMode } = useDevMode(apiUrl);
1354
1588
  const checkpointCtx = useMemo(() => ({ apiUrl, devMode: cpDevMode, threadId }), [apiUrl, cpDevMode, threadId]);
1355
1589
  const messageActionsCtx = useMemo(() => ({ onForkChat }), [onForkChat]);
1590
+ const lastMessageLoopLimit = useMemo(() => {
1591
+ const last = messages[messages.length - 1];
1592
+ if (!last || last.role !== "assistant")
1593
+ return null;
1594
+ return getLoopLimitMetadata(last);
1595
+ }, [messages]);
1596
+ const lastMessageRunError = useMemo(() => {
1597
+ const last = messages[messages.length - 1];
1598
+ if (!last || last.role !== "assistant")
1599
+ return null;
1600
+ return getRunErrorMetadata(last);
1601
+ }, [messages]);
1602
+ const lastUserText = useMemo(() => {
1603
+ for (let i = messages.length - 1; i >= 0; i--) {
1604
+ if (messages[i]?.role === "user")
1605
+ return getMessageText(messages[i]);
1606
+ }
1607
+ return "";
1608
+ }, [messages]);
1609
+ const visibleLoopLimit = showContinue
1610
+ ? (loopLimitInfo ?? lastMessageLoopLimit ?? {})
1611
+ : lastMessageLoopLimit;
1612
+ const visibleRunError = runErrorInfo ?? lastMessageRunError;
1613
+ const visibleRunErrorKey = visibleRunError
1614
+ ? `${visibleRunError.runId ?? ""}:${visibleRunError.errorCode ?? ""}:${visibleRunError.message}`
1615
+ : null;
1616
+ const shouldShowRunError = !!visibleRunError &&
1617
+ !showRunningInUI &&
1618
+ visibleRunErrorKey !== dismissedRunErrorKey;
1356
1619
  return (_jsx(CheckpointContext.Provider, { value: checkpointCtx, children: _jsx(MessageActionsContext.Provider, { value: messageActionsCtx, children: _jsx(ChatRunningContext.Provider, { value: isRunning, children: _jsxs("div", { className: cn("flex flex-1 flex-col h-full min-h-0 text-foreground", className), children: [showHeader && (_jsxs("div", { className: "flex h-11 shrink-0 items-center justify-between border-b border-border px-4", children: [_jsx("span", { className: "text-[13px] font-medium text-muted-foreground", children: "Agent" }), _jsx("div", { className: "flex items-center gap-1", children: onSwitchToCli && (_jsxs("button", { onClick: onSwitchToCli, className: "flex items-center gap-1 text-[12px] text-muted-foreground hover:text-foreground px-2 py-1 rounded-md hover:bg-accent", title: "Switch to CLI", children: [_jsx(IconTerminal, { className: "h-3.5 w-3.5" }), "CLI"] })) })] })), _jsx("div", { ref: scrollRef, className: "flex-1 overflow-y-auto overflow-x-hidden min-h-0", children: authError ? (_jsxs("div", { className: "flex flex-col items-center justify-center h-full px-4 gap-3", children: [_jsx("div", { className: "flex h-10 w-10 items-center justify-center rounded-full bg-destructive/10", children: _jsx(IconLock, { className: "h-5 w-5 text-destructive" }) }), _jsxs("div", { className: "text-center max-w-[280px]", children: [_jsx("p", { className: "text-sm font-medium text-foreground mb-1", children: authError.sessionExpired
1357
1620
  ? "Session expired"
1358
1621
  : "Authentication required" }), _jsx("p", { className: "text-xs text-muted-foreground leading-relaxed", children: authError.sessionExpired ? ("Your session may have expired. Log out and log back in to reconnect.") : (_jsxs(_Fragment, { children: ["You need to log in to use the agent. If you're running locally, add", " ", _jsx("code", { className: "bg-muted px-1 py-0.5 rounded text-[10px]", children: "AUTH_MODE=local" }), " ", "to your", " ", _jsx("code", { className: "bg-muted px-1 py-0.5 rounded text-[10px]", children: ".env" }), " ", "file and restart the dev server."] })) })] }), _jsxs("div", { className: "flex gap-2", children: [authError.sessionExpired && (_jsx("button", { onClick: async () => {
@@ -1374,16 +1637,31 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
1374
1637
  }, className: "w-full rounded-lg border border-border px-3 py-2 text-left text-[13px] text-muted-foreground hover:bg-accent hover:text-foreground", children: suggestion }, suggestion))) }))] })) : (_jsxs("div", { className: "agent-thread-content flex flex-col gap-4 px-4 py-4", children: [_jsx(ThreadPrimitive.Messages, { components: {
1375
1638
  UserMessage,
1376
1639
  AssistantMessage,
1377
- } }), showContinue && !showRunningInUI && (_jsx("div", { className: "flex justify-center py-2", children: _jsx("button", { type: "button", onClick: () => {
1378
- setShowContinue(false);
1379
- addToQueue("Continue from where you left off.");
1380
- }, className: "rounded-lg border border-border bg-background px-4 py-2 text-sm font-medium text-foreground hover:bg-accent", children: "Continue" }) })), (isReconnecting || reconnectFrozen) &&
1640
+ } }), visibleLoopLimit && !showRunningInUI && (_jsx(LoopLimitContinueCard, { info: visibleLoopLimit, onContinue: () => {
1641
+ setShowContinue(false);
1642
+ setLoopLimitInfo(null);
1643
+ addToQueue("Continue from where you left off.");
1644
+ } })), shouldShowRunError && visibleRunError && (_jsx(RunErrorRecoveryCard, { info: visibleRunError, onContinue: () => {
1645
+ setRunErrorInfo(null);
1646
+ addToQueue("Continue from where you stopped. Use the partial work above, verify what succeeded, and finish the original request. Prefer dedicated app actions over raw database edits when they exist.");
1647
+ }, onRetry: () => {
1648
+ setRunErrorInfo(null);
1649
+ addToQueue(lastUserText
1650
+ ? `Retry the previous request from a clean approach. Original request:\n\n${lastUserText}`
1651
+ : "Retry the previous request from a clean approach.");
1652
+ }, onFork: onForkChat, onDismiss: () => {
1653
+ if (visibleRunErrorKey) {
1654
+ setDismissedRunErrorKey(visibleRunErrorKey);
1655
+ }
1656
+ setRunErrorInfo(null);
1657
+ } })), (isReconnecting || reconnectFrozen) &&
1381
1658
  reconnectContent.length > 0 && (_jsx(ReconnectStreamMessage, { content: reconnectContent })), showRunningInUI && (_jsx(ThinkingIndicator, { label: isReconnecting ? "Reconnecting" : "Thinking" })), queuedMessages.map((msg) => {
1382
1659
  const displayText = msg.text
1383
1660
  .replace(/<context>[\s\S]*?<\/context>\n?/g, "")
1384
1661
  .trim();
1385
1662
  return (_jsx("div", { className: "flex justify-end group", children: _jsxs("div", { className: "relative max-w-[85%] rounded-lg bg-accent/50 text-foreground/60 px-3 py-2 text-sm leading-relaxed whitespace-pre-wrap break-words", children: [_jsxs("div", { className: "flex items-center gap-1.5 text-[10px] text-muted-foreground mb-1 font-medium uppercase tracking-wide", children: [_jsx(IconClock, { className: "h-3 w-3" }), "Queued"] }), displayText, msg.images && msg.images.length > 0 && (_jsx("div", { className: "flex flex-wrap gap-1.5 mt-1.5", children: msg.images.map((img, j) => (_jsx("img", { src: img, alt: "", className: "h-12 w-12 rounded object-cover border border-border/50" }, j))) })), _jsx("button", { type: "button", onClick: () => setQueuedMessages((prev) => prev.filter((m) => m.id !== msg.id)), "aria-label": "Remove from queue", className: "absolute -top-2 -right-2 flex h-5 w-5 items-center justify-center rounded-full border border-border bg-background text-muted-foreground opacity-0 group-hover:opacity-100 focus-visible:opacity-100 hover:text-foreground hover:bg-accent shadow-sm", children: _jsx(IconX, { className: "h-3 w-3" }) })] }) }, msg.id));
1386
- })] })) }), showScrollToBottom && (_jsx("div", { className: "shrink-0 flex justify-center -mb-1", children: _jsx("button", { type: "button", onClick: scrollToBottom, className: "flex h-7 w-7 items-center justify-center rounded-full border border-border bg-background shadow-sm hover:bg-accent", "aria-label": "Scroll to bottom", children: _jsx(IconChevronDown, { className: "h-3.5 w-3.5 text-muted-foreground" }) }) })), composerSlot, _jsx(SelectionAttachedPill, {}), _jsx("div", { className: "agent-composer-area shrink-0 px-3 py-2", children: _jsxs(ComposerPrimitive.Root, { className: "flex flex-col rounded-lg border border-input bg-background focus-within:ring-1 focus-within:ring-ring", children: [_jsx(ComposerAttachmentPreviewStrip, {}), _jsx(TiptapComposer, { focusRef: tiptapRef, disabled: missingApiKey, placeholder: missingApiKey
1663
+ })] })) }), showScrollToBottom && (_jsx("div", { className: "shrink-0 flex justify-center -mb-1", children: _jsx("button", { type: "button", onClick: scrollToBottom, className: "flex h-7 w-7 items-center justify-center rounded-full border border-border bg-background shadow-sm hover:bg-accent", "aria-label": "Scroll to bottom", children: _jsx(IconChevronDown, { className: "h-3.5 w-3.5 text-muted-foreground" }) }) })), composerSlot, _jsx(SelectionAttachedPill, {}), _jsx("div", { className: "agent-composer-area shrink-0 px-3 py-2", children: _jsxs(ComposerPrimitive.Root, { className: cn("flex flex-col rounded-lg border border-input bg-background focus-within:ring-1 focus-within:ring-ring", execMode === "plan" &&
1664
+ "border-amber-500/50 bg-amber-500/[0.03] focus-within:ring-amber-500/30"), children: [_jsx(ComposerAttachmentPreviewStrip, {}), _jsx(TiptapComposer, { focusRef: tiptapRef, disabled: missingApiKey, placeholder: missingApiKey
1387
1665
  ? "Connect an AI engine above to start chatting…"
1388
1666
  : isRunning
1389
1667
  ? queuedMessages.length > 0
@@ -1396,10 +1674,12 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
1396
1674
  // immediately. This unblocks submission even if the
1397
1675
  // runtime or reconnect state is stuck.
1398
1676
  setForceStopped(true);
1677
+ const activeRun = getActiveRun();
1678
+ const runIdToAbort = reconnectRunIdRef.current ?? activeRun?.runId;
1679
+ if (runIdToAbort) {
1680
+ fetch(`${apiUrl}/runs/${encodeURIComponent(runIdToAbort)}/abort`, { method: "POST" }).catch(() => { });
1681
+ }
1399
1682
  if (isReconnecting) {
1400
- if (reconnectRunIdRef.current) {
1401
- fetch(`${apiUrl}/runs/${encodeURIComponent(reconnectRunIdRef.current)}/abort`, { method: "POST" });
1402
- }
1403
1683
  reconnectAbortRef.current?.abort();
1404
1684
  reconnectAbortRef.current = null;
1405
1685
  reconnectRunIdRef.current = null;
@@ -1420,7 +1700,16 @@ export const AssistantChat = forwardRef(function AssistantChat({ apiUrl = agentN
1420
1700
  modelRef.current = props.selectedModel;
1421
1701
  const engineRef = useRef(props.selectedEngine);
1422
1702
  engineRef.current = props.selectedEngine;
1423
- const adapter = useMemo(() => createAgentChatAdapter({ apiUrl, tabId, threadId, modelRef, engineRef }), [apiUrl, tabId, threadId]);
1703
+ const execModeRef = useRef(props.execMode);
1704
+ execModeRef.current = props.execMode;
1705
+ const adapter = useMemo(() => createAgentChatAdapter({
1706
+ apiUrl,
1707
+ tabId,
1708
+ threadId,
1709
+ modelRef,
1710
+ engineRef,
1711
+ execModeRef,
1712
+ }), [apiUrl, tabId, threadId]);
1424
1713
  const attachmentAdapter = useMemo(() => new CompositeAttachmentAdapter([
1425
1714
  new SimpleImageAttachmentAdapter(),
1426
1715
  new SimpleTextAttachmentAdapter(),