@dxos/plugin-automation 0.7.4-staging.f7e8224 → 0.7.5-labs.071a3e2

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 (280) hide show
  1. package/dist/lib/browser/AutomationPanel-YPD3AGQN.mjs +8 -0
  2. package/dist/lib/browser/ChatContainer-ODZECATM.mjs +12 -0
  3. package/dist/lib/browser/ai-client-UJLNYP7B.mjs +22 -0
  4. package/dist/lib/browser/ai-client-UJLNYP7B.mjs.map +7 -0
  5. package/dist/lib/browser/app-graph-builder-3H5TCRG4.mjs +162 -0
  6. package/dist/lib/browser/app-graph-builder-3H5TCRG4.mjs.map +7 -0
  7. package/dist/lib/browser/chunk-43WRHV2L.mjs +150 -0
  8. package/dist/lib/browser/chunk-43WRHV2L.mjs.map +7 -0
  9. package/dist/lib/browser/chunk-BQHXJZ4K.mjs +15 -0
  10. package/dist/lib/browser/chunk-BQHXJZ4K.mjs.map +7 -0
  11. package/dist/lib/browser/chunk-DL7XA62G.mjs +1531 -0
  12. package/dist/lib/browser/chunk-DL7XA62G.mjs.map +7 -0
  13. package/dist/lib/browser/{chunk-X5KMOH3I.mjs → chunk-DQ7ZSYJJ.mjs} +4 -4
  14. package/dist/lib/browser/chunk-DQ7ZSYJJ.mjs.map +7 -0
  15. package/dist/lib/browser/chunk-PQGFC2ZO.mjs +284 -0
  16. package/dist/lib/browser/chunk-PQGFC2ZO.mjs.map +7 -0
  17. package/dist/lib/browser/chunk-Z54KIF6H.mjs +242 -0
  18. package/dist/lib/browser/chunk-Z54KIF6H.mjs.map +7 -0
  19. package/dist/lib/browser/index.mjs +152 -252
  20. package/dist/lib/browser/index.mjs.map +4 -4
  21. package/dist/lib/browser/intent-resolver-5YVZJFS3.mjs +29 -0
  22. package/dist/lib/browser/intent-resolver-5YVZJFS3.mjs.map +7 -0
  23. package/dist/lib/browser/meta.json +1 -1
  24. package/dist/lib/browser/react-surface-WRHRCEV5.mjs +50 -0
  25. package/dist/lib/browser/react-surface-WRHRCEV5.mjs.map +7 -0
  26. package/dist/lib/browser/types/index.mjs +12 -3
  27. package/dist/lib/node/{meta.cjs → AutomationPanel-CO26O75P.cjs} +7 -11
  28. package/dist/lib/node/AutomationPanel-CO26O75P.cjs.map +7 -0
  29. package/dist/lib/node/ChatContainer-5URBEXQD.cjs +33 -0
  30. package/dist/lib/node/ChatContainer-5URBEXQD.cjs.map +7 -0
  31. package/dist/lib/node/ai-client-AOB6TLNW.cjs +38 -0
  32. package/dist/lib/node/ai-client-AOB6TLNW.cjs.map +7 -0
  33. package/dist/lib/node/app-graph-builder-CDEQJEHY.cjs +178 -0
  34. package/dist/lib/node/app-graph-builder-CDEQJEHY.cjs.map +7 -0
  35. package/dist/lib/node/chunk-AWZVJZ2I.cjs +34 -0
  36. package/dist/lib/node/chunk-AWZVJZ2I.cjs.map +7 -0
  37. package/dist/lib/node/chunk-D2QQXWOY.cjs +302 -0
  38. package/dist/lib/node/chunk-D2QQXWOY.cjs.map +7 -0
  39. package/dist/lib/node/chunk-H3RSMGJG.cjs +173 -0
  40. package/dist/lib/node/chunk-H3RSMGJG.cjs.map +7 -0
  41. package/dist/lib/node/chunk-NH7STAX6.cjs +1515 -0
  42. package/dist/lib/node/chunk-NH7STAX6.cjs.map +7 -0
  43. package/dist/lib/node/chunk-OCW5GAVZ.cjs +266 -0
  44. package/dist/lib/node/chunk-OCW5GAVZ.cjs.map +7 -0
  45. package/dist/lib/node/{chunk-DTJ7XVO2.cjs → chunk-TQEDPRY5.cjs} +8 -8
  46. package/dist/lib/node/chunk-TQEDPRY5.cjs.map +7 -0
  47. package/dist/lib/node/index.cjs +169 -282
  48. package/dist/lib/node/index.cjs.map +4 -4
  49. package/dist/lib/node/intent-resolver-MJFZT5IU.cjs +44 -0
  50. package/dist/lib/node/intent-resolver-MJFZT5IU.cjs.map +7 -0
  51. package/dist/lib/node/meta.json +1 -1
  52. package/dist/lib/node/react-surface-HDAVE6NU.cjs +70 -0
  53. package/dist/lib/node/react-surface-HDAVE6NU.cjs.map +7 -0
  54. package/dist/lib/node/types/index.cjs +16 -7
  55. package/dist/lib/node/types/index.cjs.map +2 -2
  56. package/dist/lib/node-esm/AutomationPanel-VQZUKPK2.mjs +9 -0
  57. package/dist/lib/node-esm/AutomationPanel-VQZUKPK2.mjs.map +7 -0
  58. package/dist/lib/node-esm/ChatContainer-23QIVDG5.mjs +13 -0
  59. package/dist/lib/node-esm/ChatContainer-23QIVDG5.mjs.map +7 -0
  60. package/dist/lib/node-esm/ai-client-RUCCJ7JZ.mjs +23 -0
  61. package/dist/lib/node-esm/ai-client-RUCCJ7JZ.mjs.map +7 -0
  62. package/dist/lib/node-esm/app-graph-builder-GR3URVNX.mjs +163 -0
  63. package/dist/lib/node-esm/app-graph-builder-GR3URVNX.mjs.map +7 -0
  64. package/dist/lib/node-esm/chunk-7JO77AAS.mjs +151 -0
  65. package/dist/lib/node-esm/chunk-7JO77AAS.mjs.map +7 -0
  66. package/dist/lib/node-esm/{chunk-HNOBZHWK.mjs → chunk-JFHI22MF.mjs} +4 -4
  67. package/dist/lib/node-esm/chunk-JFHI22MF.mjs.map +7 -0
  68. package/dist/lib/node-esm/chunk-JJFWFS6P.mjs +1532 -0
  69. package/dist/lib/node-esm/chunk-JJFWFS6P.mjs.map +7 -0
  70. package/dist/lib/node-esm/chunk-LSSWQIQD.mjs +16 -0
  71. package/dist/lib/node-esm/chunk-LSSWQIQD.mjs.map +7 -0
  72. package/dist/lib/node-esm/chunk-NSVQZ3EH.mjs +243 -0
  73. package/dist/lib/node-esm/chunk-NSVQZ3EH.mjs.map +7 -0
  74. package/dist/lib/node-esm/chunk-VN2AFV25.mjs +285 -0
  75. package/dist/lib/node-esm/chunk-VN2AFV25.mjs.map +7 -0
  76. package/dist/lib/node-esm/index.mjs +152 -252
  77. package/dist/lib/node-esm/index.mjs.map +4 -4
  78. package/dist/lib/node-esm/intent-resolver-FCKNRTKQ.mjs +30 -0
  79. package/dist/lib/node-esm/intent-resolver-FCKNRTKQ.mjs.map +7 -0
  80. package/dist/lib/node-esm/meta.json +1 -1
  81. package/dist/lib/node-esm/react-surface-FZ5OFRDE.mjs +51 -0
  82. package/dist/lib/node-esm/react-surface-FZ5OFRDE.mjs.map +7 -0
  83. package/dist/lib/node-esm/types/index.mjs +12 -3
  84. package/dist/types/src/AutomationPlugin.d.ts +1 -3
  85. package/dist/types/src/AutomationPlugin.d.ts.map +1 -1
  86. package/dist/types/src/artifacts.stories.d.ts +16 -0
  87. package/dist/types/src/artifacts.stories.d.ts.map +1 -0
  88. package/dist/types/src/capabilities/ai-client.d.ts +5 -0
  89. package/dist/types/src/capabilities/ai-client.d.ts.map +1 -0
  90. package/dist/types/src/capabilities/app-graph-builder.d.ts +180 -0
  91. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -0
  92. package/dist/types/src/capabilities/capabilities.d.ts +5 -0
  93. package/dist/types/src/capabilities/capabilities.d.ts.map +1 -0
  94. package/dist/types/src/capabilities/index.d.ts +182 -0
  95. package/dist/types/src/capabilities/index.d.ts.map +1 -0
  96. package/dist/types/src/capabilities/intent-resolver.d.ts +4 -0
  97. package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -0
  98. package/dist/types/src/capabilities/react-surface.d.ts +4 -0
  99. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
  100. package/dist/types/src/components/AutomationPanel/AutomationPanel.d.ts +1 -1
  101. package/dist/types/src/components/AutomationPanel/AutomationPanel.d.ts.map +1 -1
  102. package/dist/types/src/components/AutomationPanel/AutomationPanel.stories.d.ts.map +1 -1
  103. package/dist/types/src/components/ChatContainer/ChatContainer.d.ts +7 -0
  104. package/dist/types/src/components/ChatContainer/ChatContainer.d.ts.map +1 -0
  105. package/dist/types/src/components/ChatContainer/index.d.ts +4 -0
  106. package/dist/types/src/components/ChatContainer/index.d.ts.map +1 -0
  107. package/dist/types/src/components/MarkdownViewer/MarkdownViewer.d.ts +14 -0
  108. package/dist/types/src/components/MarkdownViewer/MarkdownViewer.d.ts.map +1 -0
  109. package/dist/types/src/components/MarkdownViewer/MarkdownViewer.stories.d.ts +8 -0
  110. package/dist/types/src/components/MarkdownViewer/MarkdownViewer.stories.d.ts.map +1 -0
  111. package/dist/types/src/components/MarkdownViewer/index.d.ts +2 -0
  112. package/dist/types/src/components/MarkdownViewer/index.d.ts.map +1 -0
  113. package/dist/types/src/components/ServiceRegistry/ServiceRegistry.d.ts +6 -0
  114. package/dist/types/src/components/ServiceRegistry/ServiceRegistry.d.ts.map +1 -0
  115. package/dist/types/src/components/ServiceRegistry/ServiceRegistry.stories.d.ts +8 -0
  116. package/dist/types/src/components/ServiceRegistry/ServiceRegistry.stories.d.ts.map +1 -0
  117. package/dist/types/src/components/ServiceRegistry/index.d.ts +2 -0
  118. package/dist/types/src/components/ServiceRegistry/index.d.ts.map +1 -0
  119. package/dist/types/src/components/Thread/ScrollContainer.d.ts +15 -0
  120. package/dist/types/src/components/Thread/ScrollContainer.d.ts.map +1 -0
  121. package/dist/types/src/components/Thread/StatusLine.d.ts +11 -0
  122. package/dist/types/src/components/Thread/StatusLine.d.ts.map +1 -0
  123. package/dist/types/src/components/Thread/StatusLine.stories.d.ts +9 -0
  124. package/dist/types/src/components/Thread/StatusLine.stories.d.ts.map +1 -0
  125. package/dist/types/src/components/Thread/Tabbed.d.ts +9 -0
  126. package/dist/types/src/components/Thread/Tabbed.d.ts.map +1 -0
  127. package/dist/types/src/components/Thread/Tabbed.stories.d.ts +8 -0
  128. package/dist/types/src/components/Thread/Tabbed.stories.d.ts.map +1 -0
  129. package/dist/types/src/components/Thread/Thread.d.ts +11 -0
  130. package/dist/types/src/components/Thread/Thread.d.ts.map +1 -0
  131. package/dist/types/src/components/Thread/Thread.stories.d.ts +10 -0
  132. package/dist/types/src/components/Thread/Thread.stories.d.ts.map +1 -0
  133. package/dist/types/src/components/Thread/ThreadMessage.d.ts +12 -0
  134. package/dist/types/src/components/Thread/ThreadMessage.d.ts.map +1 -0
  135. package/dist/types/src/components/Thread/ToggleContainer.d.ts +13 -0
  136. package/dist/types/src/components/Thread/ToggleContainer.d.ts.map +1 -0
  137. package/dist/types/src/components/Thread/ToggleContainer.stories.d.ts +9 -0
  138. package/dist/types/src/components/Thread/ToggleContainer.stories.d.ts.map +1 -0
  139. package/dist/types/src/components/Thread/index.d.ts +2 -0
  140. package/dist/types/src/components/Thread/index.d.ts.map +1 -0
  141. package/dist/types/src/components/TriggerEditor/TriggerEditor.d.ts +1 -2
  142. package/dist/types/src/components/TriggerEditor/TriggerEditor.d.ts.map +1 -1
  143. package/dist/types/src/components/TriggerEditor/TriggerEditor.stories.d.ts.map +1 -1
  144. package/dist/types/src/components/index.d.ts +12 -2
  145. package/dist/types/src/components/index.d.ts.map +1 -1
  146. package/dist/types/src/hooks/email.d.ts.map +1 -1
  147. package/dist/types/src/hooks/index.d.ts +4 -0
  148. package/dist/types/src/hooks/index.d.ts.map +1 -1
  149. package/dist/types/src/hooks/invocation-handler.d.ts.map +1 -1
  150. package/dist/types/src/hooks/processor.d.ts +70 -0
  151. package/dist/types/src/hooks/processor.d.ts.map +1 -0
  152. package/dist/types/src/hooks/processor.test.d.ts +2 -0
  153. package/dist/types/src/hooks/processor.test.d.ts.map +1 -0
  154. package/dist/types/src/hooks/useChatProcessor.d.ts +7 -0
  155. package/dist/types/src/hooks/useChatProcessor.d.ts.map +1 -0
  156. package/dist/types/src/hooks/useMessageQueue.d.ts +41 -0
  157. package/dist/types/src/hooks/useMessageQueue.d.ts.map +1 -0
  158. package/dist/types/src/hooks/useServices.d.ts +7 -0
  159. package/dist/types/src/hooks/useServices.d.ts.map +1 -0
  160. package/dist/types/src/index.d.ts +1 -2
  161. package/dist/types/src/index.d.ts.map +1 -1
  162. package/dist/types/src/meta.d.ts +1 -2
  163. package/dist/types/src/meta.d.ts.map +1 -1
  164. package/dist/types/src/testing/index.d.ts +2 -1
  165. package/dist/types/src/testing/index.d.ts.map +1 -1
  166. package/dist/types/src/testing/{testing.d.ts → test-functions.d.ts} +3 -1
  167. package/dist/types/src/testing/test-functions.d.ts.map +1 -0
  168. package/dist/types/src/testing/test-services.d.ts +5 -0
  169. package/dist/types/src/testing/test-services.d.ts.map +1 -0
  170. package/dist/types/src/tools/function.d.ts +5 -0
  171. package/dist/types/src/tools/function.d.ts.map +1 -0
  172. package/dist/types/src/tools/index.d.ts +3 -0
  173. package/dist/types/src/tools/index.d.ts.map +1 -0
  174. package/dist/types/src/tools/openapi.d.ts +10 -0
  175. package/dist/types/src/tools/openapi.d.ts.map +1 -0
  176. package/dist/types/src/tools/openapi.test.d.ts +2 -0
  177. package/dist/types/src/tools/openapi.test.d.ts.map +1 -0
  178. package/dist/types/src/translations.d.ts +81 -2
  179. package/dist/types/src/translations.d.ts.map +1 -1
  180. package/dist/types/src/types/index.d.ts +1 -0
  181. package/dist/types/src/types/index.d.ts.map +1 -1
  182. package/dist/types/src/types/registry.d.ts +10 -0
  183. package/dist/types/src/types/registry.d.ts.map +1 -0
  184. package/dist/types/src/types/schema.d.ts +189 -39
  185. package/dist/types/src/types/schema.d.ts.map +1 -1
  186. package/dist/types/src/types/types.d.ts +16 -5
  187. package/dist/types/src/types/types.d.ts.map +1 -1
  188. package/dist/types/tsconfig.tsbuildinfo +1 -0
  189. package/package.json +54 -48
  190. package/src/AutomationPlugin.tsx +77 -194
  191. package/src/artifacts.stories.tsx +241 -0
  192. package/src/capabilities/ai-client.ts +19 -0
  193. package/src/capabilities/app-graph-builder.ts +156 -0
  194. package/src/capabilities/capabilities.ts +12 -0
  195. package/src/capabilities/index.ts +12 -0
  196. package/src/capabilities/intent-resolver.ts +27 -0
  197. package/src/capabilities/react-surface.tsx +36 -0
  198. package/src/components/AutomationPanel/AutomationPanel.stories.tsx +1 -2
  199. package/src/components/AutomationPanel/AutomationPanel.tsx +61 -39
  200. package/src/components/ChatContainer/ChatContainer.tsx +52 -0
  201. package/src/components/ChatContainer/index.ts +8 -0
  202. package/src/components/MarkdownViewer/MarkdownViewer.stories.tsx +56 -0
  203. package/src/components/MarkdownViewer/MarkdownViewer.tsx +79 -0
  204. package/src/components/MarkdownViewer/index.ts +5 -0
  205. package/src/components/PromptEditor/PromptEditor.stories.tsx +3 -3
  206. package/src/components/ServiceRegistry/ServiceRegistry.stories.tsx +49 -0
  207. package/src/components/ServiceRegistry/ServiceRegistry.tsx +75 -0
  208. package/src/components/ServiceRegistry/index.ts +5 -0
  209. package/src/components/Thread/ScrollContainer.tsx +92 -0
  210. package/src/components/Thread/StatusLine.stories.tsx +52 -0
  211. package/src/components/Thread/StatusLine.tsx +76 -0
  212. package/src/components/Thread/Tabbed.stories.tsx +52 -0
  213. package/src/components/Thread/Tabbed.tsx +72 -0
  214. package/src/components/Thread/Thread.stories.tsx +190 -0
  215. package/src/components/Thread/Thread.tsx +156 -0
  216. package/src/components/Thread/ThreadMessage.tsx +203 -0
  217. package/src/components/Thread/ToggleContainer.stories.tsx +111 -0
  218. package/src/components/Thread/ToggleContainer.tsx +103 -0
  219. package/src/components/Thread/index.ts +5 -0
  220. package/src/components/TriggerEditor/TriggerEditor.stories.tsx +1 -2
  221. package/src/components/TriggerEditor/TriggerEditor.tsx +81 -16
  222. package/src/components/index.ts +9 -1
  223. package/src/hooks/email.ts +2 -2
  224. package/src/hooks/index.ts +5 -0
  225. package/src/hooks/invocation-handler.ts +2 -2
  226. package/src/hooks/processor.test.ts +15 -0
  227. package/src/hooks/processor.ts +210 -0
  228. package/src/hooks/useChatProcessor.tsx +86 -0
  229. package/src/hooks/useMessageQueue.ts +23 -0
  230. package/src/hooks/useServices.ts +28 -0
  231. package/src/index.ts +1 -4
  232. package/src/meta.ts +3 -2
  233. package/src/testing/index.ts +2 -1
  234. package/src/testing/{testing.ts → test-functions.ts} +9 -2
  235. package/src/testing/test-services.ts +131 -0
  236. package/src/tools/function.ts +47 -0
  237. package/src/tools/index.ts +6 -0
  238. package/src/tools/openapi.test.ts +227 -0
  239. package/src/tools/openapi.ts +331 -0
  240. package/src/translations.ts +17 -2
  241. package/src/types/index.ts +1 -0
  242. package/src/types/registry.ts +26 -0
  243. package/src/types/schema.ts +96 -2
  244. package/src/types/types.ts +15 -21
  245. package/dist/lib/browser/AssistantPanel-N3QSALKY.mjs +0 -341
  246. package/dist/lib/browser/AssistantPanel-N3QSALKY.mjs.map +0 -7
  247. package/dist/lib/browser/AutomationPanel-AQMN2CQR.mjs +0 -153
  248. package/dist/lib/browser/AutomationPanel-AQMN2CQR.mjs.map +0 -7
  249. package/dist/lib/browser/chunk-7KB4UMXO.mjs +0 -49
  250. package/dist/lib/browser/chunk-7KB4UMXO.mjs.map +0 -7
  251. package/dist/lib/browser/chunk-X5KMOH3I.mjs.map +0 -7
  252. package/dist/lib/browser/meta.mjs +0 -9
  253. package/dist/lib/node/AssistantPanel-RIA4TI3B.cjs +0 -361
  254. package/dist/lib/node/AssistantPanel-RIA4TI3B.cjs.map +0 -7
  255. package/dist/lib/node/AutomationPanel-HZS5WKI5.cjs +0 -173
  256. package/dist/lib/node/AutomationPanel-HZS5WKI5.cjs.map +0 -7
  257. package/dist/lib/node/chunk-CUCUWUAF.cjs +0 -73
  258. package/dist/lib/node/chunk-CUCUWUAF.cjs.map +0 -7
  259. package/dist/lib/node/chunk-DTJ7XVO2.cjs.map +0 -7
  260. package/dist/lib/node/meta.cjs.map +0 -7
  261. package/dist/lib/node-esm/AssistantPanel-72YH43CH.mjs +0 -342
  262. package/dist/lib/node-esm/AssistantPanel-72YH43CH.mjs.map +0 -7
  263. package/dist/lib/node-esm/AutomationPanel-JUHOWQWW.mjs +0 -154
  264. package/dist/lib/node-esm/AutomationPanel-JUHOWQWW.mjs.map +0 -7
  265. package/dist/lib/node-esm/chunk-23LY7DYS.mjs +0 -51
  266. package/dist/lib/node-esm/chunk-23LY7DYS.mjs.map +0 -7
  267. package/dist/lib/node-esm/chunk-HNOBZHWK.mjs.map +0 -7
  268. package/dist/lib/node-esm/meta.mjs +0 -10
  269. package/dist/types/src/components/AssistantPanel/AssistantPanel.d.ts +0 -8
  270. package/dist/types/src/components/AssistantPanel/AssistantPanel.d.ts.map +0 -1
  271. package/dist/types/src/components/AssistantPanel/index.d.ts +0 -3
  272. package/dist/types/src/components/AssistantPanel/index.d.ts.map +0 -1
  273. package/dist/types/src/components/AssistantPanel/system-instructions.d.ts +0 -6
  274. package/dist/types/src/components/AssistantPanel/system-instructions.d.ts.map +0 -1
  275. package/dist/types/src/testing/testing.d.ts.map +0 -1
  276. package/src/components/AssistantPanel/AssistantPanel.tsx +0 -230
  277. package/src/components/AssistantPanel/index.ts +0 -7
  278. package/src/components/AssistantPanel/system-instructions.ts +0 -166
  279. /package/dist/lib/browser/{meta.mjs.map → AutomationPanel-YPD3AGQN.mjs.map} +0 -0
  280. /package/dist/lib/{node-esm/meta.mjs.map → browser/ChatContainer-ODZECATM.mjs.map} +0 -0
@@ -0,0 +1,1531 @@
1
+ import {
2
+ AutomationCapabilities
3
+ } from "./chunk-BQHXJZ4K.mjs";
4
+ import {
5
+ ServiceType,
6
+ categoryIcons
7
+ } from "./chunk-43WRHV2L.mjs";
8
+ import {
9
+ AUTOMATION_PLUGIN
10
+ } from "./chunk-DQ7ZSYJJ.mjs";
11
+
12
+ // packages/plugins/experimental/plugin-automation/src/components/ChatContainer/ChatContainer.tsx
13
+ import React7, { useCallback as useCallback3 } from "react";
14
+ import { invariant as invariant7 } from "@dxos/invariant";
15
+ import { StackItem } from "@dxos/react-ui-stack";
16
+
17
+ // packages/plugins/experimental/plugin-automation/src/hooks/processor.ts
18
+ import { batch, computed, signal } from "@preact/signals-core";
19
+ import { Message } from "@dxos/artifact";
20
+ import { isToolUse, runTools, MixedStreamParser } from "@dxos/assistant";
21
+ import { createStatic } from "@dxos/echo-schema";
22
+ import { invariant } from "@dxos/invariant";
23
+ import { log } from "@dxos/log";
24
+ var __dxlog_file = "/home/runner/work/dxos/dxos/packages/plugins/experimental/plugin-automation/src/hooks/processor.ts";
25
+ var defaultOptions = {
26
+ model: "@anthropic/claude-3-5-sonnet-20241022",
27
+ systemPrompt: "you are a helpful assistant"
28
+ };
29
+ var ChatProcessor = class {
30
+ constructor(_client, _tools, _extensions, _options = defaultOptions) {
31
+ this._client = _client;
32
+ this._tools = _tools;
33
+ this._extensions = _extensions;
34
+ this._options = _options;
35
+ this._parser = new MixedStreamParser();
36
+ this._pending = signal([]);
37
+ this._block = signal(void 0);
38
+ this._history = [];
39
+ this.streaming = computed(() => this._block.value !== void 0);
40
+ this.messages = computed(() => {
41
+ const messages = [
42
+ ...this._pending.value
43
+ ];
44
+ if (this._block.value) {
45
+ const current = messages.pop();
46
+ invariant(current, void 0, {
47
+ F: __dxlog_file,
48
+ L: 78,
49
+ S: this,
50
+ A: [
51
+ "current",
52
+ ""
53
+ ]
54
+ });
55
+ const { content, ...rest } = current;
56
+ const message = {
57
+ ...rest,
58
+ content: [
59
+ ...content,
60
+ this._block.value
61
+ ]
62
+ };
63
+ messages.push(message);
64
+ }
65
+ return messages;
66
+ });
67
+ this._parser.message.on((message) => {
68
+ batch(() => {
69
+ this._pending.value = [
70
+ ...this._pending.value,
71
+ message
72
+ ];
73
+ this._block.value = void 0;
74
+ });
75
+ });
76
+ this._parser.update.on((block) => {
77
+ batch(() => {
78
+ this._block.value = block;
79
+ });
80
+ });
81
+ }
82
+ /**
83
+ * Update tools.
84
+ */
85
+ setTools(tools) {
86
+ this._tools = tools;
87
+ }
88
+ /**
89
+ * Make GPT request.
90
+ */
91
+ async request(message, options = {}) {
92
+ batch(() => {
93
+ this._history = options.history ?? [];
94
+ this._pending.value = [
95
+ createStatic(Message, {
96
+ role: "user",
97
+ content: [
98
+ {
99
+ type: "text",
100
+ text: message
101
+ }
102
+ ]
103
+ })
104
+ ];
105
+ this._block.value = void 0;
106
+ });
107
+ await this._generate();
108
+ options.onComplete?.(this._pending.value);
109
+ return this._reset();
110
+ }
111
+ /**
112
+ * Cancel pending requests.
113
+ * @returns Pending requests (incl. the request message).
114
+ */
115
+ async cancel() {
116
+ log.info("cancelling...", void 0, {
117
+ F: __dxlog_file,
118
+ L: 141,
119
+ S: this,
120
+ C: (f, a) => f(...a)
121
+ });
122
+ this._stream?.abort();
123
+ return this._reset();
124
+ }
125
+ async _reset() {
126
+ const messages = this._pending.value;
127
+ batch(() => {
128
+ this._history = [];
129
+ this._pending.value = [];
130
+ this._block.value = void 0;
131
+ });
132
+ return messages;
133
+ }
134
+ /**
135
+ * Generate a response from the AI service.
136
+ * Iterates over tool requests.
137
+ */
138
+ async _generate() {
139
+ try {
140
+ let more = false;
141
+ do {
142
+ log.info("requesting...", {
143
+ history: this._history.length,
144
+ messages: this._pending.value.length
145
+ }, {
146
+ F: __dxlog_file,
147
+ L: 165,
148
+ S: this,
149
+ C: (f, a) => f(...a)
150
+ });
151
+ this._stream = await this._client.generate({
152
+ ...this._options,
153
+ // TODO(burdon): Rename messages or separate history/message.
154
+ history: [
155
+ ...this._history,
156
+ ...this._pending.value
157
+ ],
158
+ tools: this._tools
159
+ });
160
+ await this._parser.parse(this._stream);
161
+ await this._stream.complete();
162
+ log.info("response", {
163
+ messages: this._pending.value
164
+ }, {
165
+ F: __dxlog_file,
166
+ L: 178,
167
+ S: this,
168
+ C: (f, a) => f(...a)
169
+ });
170
+ more = false;
171
+ const message = this._pending.value.at(-1);
172
+ invariant(message, void 0, {
173
+ F: __dxlog_file,
174
+ L: 183,
175
+ S: this,
176
+ A: [
177
+ "message",
178
+ ""
179
+ ]
180
+ });
181
+ if (isToolUse(message)) {
182
+ log.info("tool request...", void 0, {
183
+ F: __dxlog_file,
184
+ L: 185,
185
+ S: this,
186
+ C: (f, a) => f(...a)
187
+ });
188
+ const response = await runTools({
189
+ message: this._pending.value.at(-1),
190
+ tools: this._tools ?? [],
191
+ extensions: this._extensions
192
+ });
193
+ log.info("tool response", {
194
+ response
195
+ }, {
196
+ F: __dxlog_file,
197
+ L: 192,
198
+ S: this,
199
+ C: (f, a) => f(...a)
200
+ });
201
+ switch (response.type) {
202
+ case "continue": {
203
+ this._pending.value = [
204
+ ...this._pending.value,
205
+ response.message
206
+ ];
207
+ more = true;
208
+ break;
209
+ }
210
+ }
211
+ }
212
+ } while (more);
213
+ } catch (err) {
214
+ log.catch("request failed", {
215
+ err
216
+ }, {
217
+ F: __dxlog_file,
218
+ L: 204,
219
+ S: this,
220
+ C: (f, a) => f(...a)
221
+ });
222
+ } finally {
223
+ log.info("done", void 0, {
224
+ F: __dxlog_file,
225
+ L: 206,
226
+ S: this,
227
+ C: (f, a) => f(...a)
228
+ });
229
+ this._stream = void 0;
230
+ }
231
+ }
232
+ };
233
+
234
+ // packages/plugins/experimental/plugin-automation/src/hooks/useChatProcessor.tsx
235
+ import { useEffect, useMemo, useState } from "react";
236
+ import { Capabilities, useCapabilities, useCapability, useIntentDispatcher } from "@dxos/app-framework";
237
+ import { createSystemPrompt } from "@dxos/artifact";
238
+ import { FunctionType } from "@dxos/functions";
239
+ import { useConfig } from "@dxos/react-client";
240
+ import { Filter, getSpace, useQuery } from "@dxos/react-client/echo";
241
+ import { isNotNullOrUndefined } from "@dxos/util";
242
+
243
+ // packages/plugins/experimental/plugin-automation/src/capabilities/index.ts
244
+ import { lazy } from "@dxos/app-framework";
245
+ var AiClient = lazy(() => import("./ai-client-UJLNYP7B.mjs"));
246
+ var AppGraphBuilder = lazy(() => import("./app-graph-builder-3H5TCRG4.mjs"));
247
+ var IntentResolver = lazy(() => import("./intent-resolver-5YVZJFS3.mjs"));
248
+ var ReactSurface = lazy(() => import("./react-surface-WRHRCEV5.mjs"));
249
+
250
+ // packages/plugins/experimental/plugin-automation/src/tools/function.ts
251
+ import { defineTool, ToolResult } from "@dxos/artifact";
252
+ import { toEffectSchema } from "@dxos/echo-schema";
253
+ import { getInvocationUrl, getUserFunctionUrlInMetadata } from "@dxos/functions";
254
+ import { log as log2 } from "@dxos/log";
255
+ import { getMeta } from "@dxos/react-client/echo";
256
+ var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/plugins/experimental/plugin-automation/src/tools/function.ts";
257
+ var covertFunctionToTool = (fn, edgeUrl, spaceId) => {
258
+ if (!fn.description || !fn.inputSchema) {
259
+ return void 0;
260
+ }
261
+ const existingFunctionUrl = getUserFunctionUrlInMetadata(getMeta(fn));
262
+ if (!existingFunctionUrl) {
263
+ return void 0;
264
+ }
265
+ const url = getInvocationUrl(existingFunctionUrl, edgeUrl, {
266
+ spaceId
267
+ });
268
+ return defineTool({
269
+ name: fn.name,
270
+ description: fn.description,
271
+ schema: toEffectSchema(fn.inputSchema),
272
+ execute: async (input) => {
273
+ log2.info("execute function tool", {
274
+ name: fn.name,
275
+ url,
276
+ input
277
+ }, {
278
+ F: __dxlog_file2,
279
+ L: 36,
280
+ S: void 0,
281
+ C: (f, a) => f(...a)
282
+ });
283
+ const response = await fetch(url, {
284
+ method: "POST",
285
+ headers: {
286
+ "Content-Type": "application/json"
287
+ },
288
+ body: JSON.stringify(input)
289
+ });
290
+ return ToolResult.Success(await response.text());
291
+ }
292
+ });
293
+ };
294
+
295
+ // packages/plugins/experimental/plugin-automation/src/tools/openapi.ts
296
+ import jsonpointer from "jsonpointer";
297
+ import { ToolResult as ToolResult2 } from "@dxos/artifact";
298
+ import { JsonSchemaType, normalizeSchema, S, toEffectSchema as toEffectSchema2 } from "@dxos/echo-schema";
299
+ import { invariant as invariant2 } from "@dxos/invariant";
300
+ import { log as log3 } from "@dxos/log";
301
+ import { deepMapValues } from "@dxos/util";
302
+ var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/plugins/experimental/plugin-automation/src/tools/openapi.ts";
303
+ var createToolsFromService = async (service) => {
304
+ invariant2(service.interfaces?.length === 1 && service.interfaces[0].kind === "api", void 0, {
305
+ F: __dxlog_file3,
306
+ L: 22,
307
+ S: void 0,
308
+ A: [
309
+ "service.interfaces?.length === 1 && service.interfaces[0].kind === 'api'",
310
+ ""
311
+ ]
312
+ });
313
+ const iface = service.interfaces[0];
314
+ invariant2(iface.schemaUrl, void 0, {
315
+ F: __dxlog_file3,
316
+ L: 24,
317
+ S: void 0,
318
+ A: [
319
+ "iface.schemaUrl",
320
+ ""
321
+ ]
322
+ });
323
+ invariant2(iface.schemaUrl, void 0, {
324
+ F: __dxlog_file3,
325
+ L: 25,
326
+ S: void 0,
327
+ A: [
328
+ "iface.schemaUrl",
329
+ ""
330
+ ]
331
+ });
332
+ return createToolsFromApi(iface.schemaUrl, {
333
+ authorization: iface.authorization
334
+ });
335
+ };
336
+ var createToolsFromApi = async (url, options) => {
337
+ const res = await fetch(url);
338
+ const spec = await res.json();
339
+ log3("spec", {
340
+ spec
341
+ }, {
342
+ F: __dxlog_file3,
343
+ L: 32,
344
+ S: void 0,
345
+ C: (f, a) => f(...a)
346
+ });
347
+ const tools = [];
348
+ for (const [path, pathItem] of Object.entries(spec.paths)) {
349
+ if (typeof pathItem !== "object") {
350
+ continue;
351
+ }
352
+ const { ...methods } = pathItem;
353
+ for (const [method, m] of Object.entries(methods)) {
354
+ const methodItem = m;
355
+ log3("methodItem", {
356
+ path,
357
+ method,
358
+ methodItem
359
+ }, {
360
+ F: __dxlog_file3,
361
+ L: 44,
362
+ S: void 0,
363
+ C: (f, a) => f(...a)
364
+ });
365
+ const parametersResolved = methodItem.parameters?.map((parameter) => {
366
+ const resolved = resolveJsonSchema(parameter, spec);
367
+ return resolved;
368
+ }) ?? [];
369
+ const inputSchema = {
370
+ type: "object",
371
+ properties: {}
372
+ };
373
+ const endpointParameters = [];
374
+ for (const parameter of parametersResolved) {
375
+ log3("parameter", {
376
+ parameter
377
+ }, {
378
+ F: __dxlog_file3,
379
+ L: 59,
380
+ S: void 0,
381
+ C: (f, a) => f(...a)
382
+ });
383
+ if (options?.authorization?.type === "api-key" && options.authorization.placement.type === "query" && parameter.in === "query" && parameter.name === options.authorization.placement.name) {
384
+ continue;
385
+ }
386
+ endpointParameters.push(parameter);
387
+ if (parameter.schema) {
388
+ inputSchema.properties[parameter.name] = normalizeSchema(parameter.schema);
389
+ } else if (typeof parameter.type === "string") {
390
+ const { name, in: _in, required, ...schema } = parameter;
391
+ inputSchema.properties[name] = normalizeSchema(schema);
392
+ if (required) {
393
+ inputSchema.required ??= [];
394
+ inputSchema.required.push(name);
395
+ }
396
+ }
397
+ }
398
+ log3("inputSchema", {
399
+ inputSchema
400
+ }, {
401
+ F: __dxlog_file3,
402
+ L: 84,
403
+ S: void 0,
404
+ C: (f, a) => f(...a)
405
+ });
406
+ S.validateSync(JsonSchemaType)(inputSchema);
407
+ const description = methodItem.description ?? methodItem.summary;
408
+ if (!description) {
409
+ log3.warn("no description", {
410
+ path,
411
+ method
412
+ }, {
413
+ F: __dxlog_file3,
414
+ L: 89,
415
+ S: void 0,
416
+ C: (f, a) => f(...a)
417
+ });
418
+ continue;
419
+ }
420
+ const endpoint = {
421
+ document: spec,
422
+ path,
423
+ method,
424
+ parameters: endpointParameters,
425
+ authorization: options?.authorization
426
+ };
427
+ tools.push({
428
+ name: getToolName(path, method, methodItem),
429
+ description: options?.instructions ? `${options.instructions}
430
+
431
+ ${description}` : description,
432
+ parameters: inputSchema,
433
+ execute: async (input) => {
434
+ const response = await callApiEndpoint(endpoint, input);
435
+ return ToolResult2.Success(response);
436
+ }
437
+ });
438
+ }
439
+ }
440
+ return tools;
441
+ };
442
+ var getToolName = (path, method, methodItem) => {
443
+ if (methodItem.operationId) {
444
+ return methodItem.operationId;
445
+ }
446
+ let name = `${method.toLowerCase()}_${path.replaceAll(/[{}/]/g, "_")}`;
447
+ while (name.length > MAX_TOOL_NAME_LENGTH) {
448
+ const lengthBefore = name.length;
449
+ for (const word of GENERIC_WORDS) {
450
+ if (name.includes(word)) {
451
+ name = name.replace(word, "");
452
+ break;
453
+ }
454
+ }
455
+ name = name.replaceAll("__", "_").replace(/_$/, "");
456
+ const lengthAfter = name.length;
457
+ if (lengthBefore === lengthAfter) {
458
+ break;
459
+ }
460
+ }
461
+ name = name.replaceAll("__", "_").replace(/_$/, "").replace(/^_/, "");
462
+ return name.slice(0, MAX_TOOL_NAME_LENGTH);
463
+ };
464
+ var MAX_TOOL_NAME_LENGTH = 64;
465
+ var GENERIC_WORDS = [
466
+ "services",
467
+ "service",
468
+ "api",
469
+ "rest",
470
+ "endpoint",
471
+ "get",
472
+ "post",
473
+ "put",
474
+ "delete",
475
+ "patch",
476
+ "head",
477
+ "options",
478
+ "trace",
479
+ "service",
480
+ "api",
481
+ "endpoint"
482
+ ];
483
+ var callApiEndpoint = async (endpoint, input) => {
484
+ log3.info("endpoint", {
485
+ method: endpoint.method,
486
+ name: endpoint.path,
487
+ input
488
+ }, {
489
+ F: __dxlog_file3,
490
+ L: 173,
491
+ S: void 0,
492
+ C: (f, a) => f(...a)
493
+ });
494
+ let url = getEndpointUrl(endpoint);
495
+ const request = {
496
+ method: endpoint.method,
497
+ headers: {}
498
+ };
499
+ const query = new URLSearchParams();
500
+ let body;
501
+ for (const parameter of endpoint.parameters) {
502
+ if (input[parameter.name] === void 0) {
503
+ continue;
504
+ }
505
+ switch (parameter.in) {
506
+ case "header": {
507
+ if (parameter.example) {
508
+ request.headers[parameter.name] = parameter.default;
509
+ }
510
+ break;
511
+ }
512
+ case "path": {
513
+ url = url.replace(`{${parameter.name}}`, encodeURIComponent(input[parameter.name]));
514
+ break;
515
+ }
516
+ case "body": {
517
+ const value = input[parameter.name];
518
+ const effectSchema = toEffectSchema2(parameter.schema);
519
+ S.validateSync(effectSchema)(value);
520
+ if (body) {
521
+ throw new Error(`Duplicate body parameter: ${parameter.name}`);
522
+ }
523
+ body = value;
524
+ break;
525
+ }
526
+ case "query": {
527
+ query.set(parameter.name, input[parameter.name]);
528
+ break;
529
+ }
530
+ }
531
+ }
532
+ if (endpoint.authorization?.type === "api-key" && endpoint.authorization.placement.type === "authorization-header" || endpoint.authorization?.type === "oauth") {
533
+ request.headers.Authorization = await resolveAuthorization(endpoint.authorization);
534
+ } else if (endpoint.authorization?.type === "api-key" && endpoint.authorization.placement.type === "query") {
535
+ query.set(endpoint.authorization.placement.name, endpoint.authorization.key);
536
+ }
537
+ if (query.size > 0) {
538
+ url += `?${query.toString()}`;
539
+ }
540
+ if (body) {
541
+ request.body = JSON.stringify(body);
542
+ request.headers["Content-Type"] = "application/json";
543
+ }
544
+ log3.info("request", {
545
+ url,
546
+ request
547
+ }, {
548
+ F: __dxlog_file3,
549
+ L: 236,
550
+ S: void 0,
551
+ C: (f, a) => f(...a)
552
+ });
553
+ const response = await fetch(url, request);
554
+ log3.info("response", {
555
+ ok: response.ok,
556
+ status: response.status,
557
+ statusText: response.statusText
558
+ }, {
559
+ F: __dxlog_file3,
560
+ L: 239,
561
+ S: void 0,
562
+ C: (f, a) => f(...a)
563
+ });
564
+ if (response.ok) {
565
+ const contentType = response.headers.get("Content-Type");
566
+ if (contentType?.includes("application/json")) {
567
+ return await response.json();
568
+ } else {
569
+ return await response.text();
570
+ }
571
+ } else {
572
+ if (response.headers.get("Content-Type")?.includes("application/json")) {
573
+ const responseBody = await response.text();
574
+ let error;
575
+ try {
576
+ error = JSON.parse(responseBody);
577
+ } catch {
578
+ error = responseBody;
579
+ }
580
+ log3.error("error", {
581
+ error
582
+ }, {
583
+ F: __dxlog_file3,
584
+ L: 257,
585
+ S: void 0,
586
+ C: (f, a) => f(...a)
587
+ });
588
+ throw new Error(error.message);
589
+ } else {
590
+ const error = await response.text();
591
+ log3.error("error", {
592
+ error
593
+ }, {
594
+ F: __dxlog_file3,
595
+ L: 261,
596
+ S: void 0,
597
+ C: (f, a) => f(...a)
598
+ });
599
+ throw new Error(error);
600
+ }
601
+ }
602
+ };
603
+ var getEndpointUrl = (endpoint) => {
604
+ let url = "";
605
+ if (isV3_1(endpoint.document) && endpoint.document.servers && endpoint.document.servers.length > 0) {
606
+ url = endpoint.document.servers[0].url;
607
+ } else {
608
+ invariant2(!isV3_1(endpoint.document), void 0, {
609
+ F: __dxlog_file3,
610
+ L: 272,
611
+ S: void 0,
612
+ A: [
613
+ "!isV3_1(endpoint.document)",
614
+ ""
615
+ ]
616
+ });
617
+ url = `${endpoint.document.schemes?.[0] ?? "https"}://${endpoint.document.host}`;
618
+ }
619
+ if (!isV3_1(endpoint.document) && endpoint.document.basePath) {
620
+ url += endpoint.document.basePath;
621
+ }
622
+ url += endpoint.path;
623
+ return url;
624
+ };
625
+ var resolveAuthorization = async (authorization) => {
626
+ switch (authorization.type) {
627
+ case "api-key": {
628
+ invariant2(authorization.placement.type === "authorization-header", void 0, {
629
+ F: __dxlog_file3,
630
+ L: 288,
631
+ S: void 0,
632
+ A: [
633
+ "authorization.placement.type === 'authorization-header'",
634
+ ""
635
+ ]
636
+ });
637
+ return `Bearer ${authorization.key}`;
638
+ }
639
+ case "oauth": {
640
+ const response = await fetch(authorization.tokenUrl, {
641
+ method: "POST",
642
+ headers: {
643
+ "Content-Type": "application/x-www-form-urlencoded"
644
+ },
645
+ body: `grant_type=${authorization.grantType}&client_id=${authorization.clientId}&client_secret=${authorization.clientSecret}`
646
+ });
647
+ const data = await response.json();
648
+ return `Bearer ${data.access_token}`;
649
+ }
650
+ default: {
651
+ throw new Error(`Unknown authorization type: ${authorization.type}`);
652
+ }
653
+ }
654
+ };
655
+ var resolveJsonSchema = (schema, base) => {
656
+ return deepMapValues(schema, (value, recurse) => {
657
+ if (typeof value === "object" && value !== null && "$ref" in value && typeof value.$ref === "string") {
658
+ if (value.$ref.startsWith("#")) {
659
+ const resolved = jsonpointer.get(base, value.$ref.slice(1));
660
+ if (resolved) {
661
+ return recurse(resolved);
662
+ } else {
663
+ log3.warn("unresolved", {
664
+ ref: value.$ref,
665
+ base
666
+ }, {
667
+ F: __dxlog_file3,
668
+ L: 321,
669
+ S: void 0,
670
+ C: (f, a) => f(...a)
671
+ });
672
+ }
673
+ }
674
+ }
675
+ return recurse(value);
676
+ });
677
+ };
678
+ var isV3_1 = (document) => {
679
+ return document.openapi === "3.0.1";
680
+ };
681
+
682
+ // packages/plugins/experimental/plugin-automation/src/hooks/useChatProcessor.tsx
683
+ var useChatProcessor = (chat) => {
684
+ const aiClient = useCapability(AutomationCapabilities.AiClient);
685
+ const globalTools = useCapabilities(Capabilities.Tools);
686
+ const artifactDefinitions = useCapabilities(Capabilities.ArtifactDefinition);
687
+ const { dispatchPromise: dispatch } = useIntentDispatcher();
688
+ const space = getSpace(chat);
689
+ const services = useQuery(space, Filter.schema(ServiceType));
690
+ const [serviceTools, setServiceTools] = useState([]);
691
+ useEffect(() => {
692
+ queueMicrotask(async () => {
693
+ const tools2 = await Promise.all(services.map((service) => createToolsFromService(service)));
694
+ setServiceTools(tools2.flat());
695
+ });
696
+ }, [
697
+ services
698
+ ]);
699
+ const config = useConfig();
700
+ const functions2 = useQuery(space, Filter.schema(FunctionType));
701
+ const tools = useMemo(() => [
702
+ ...globalTools.flat(),
703
+ ...artifactDefinitions.flatMap((definition) => definition.tools),
704
+ ...serviceTools,
705
+ ...functions2.map((fn) => covertFunctionToTool(fn, config.values.runtime?.services?.edge?.url ?? "", space?.id)).filter(isNotNullOrUndefined)
706
+ ], [
707
+ globalTools,
708
+ artifactDefinitions,
709
+ serviceTools,
710
+ functions2,
711
+ space?.id
712
+ ]);
713
+ const systemPrompt = useMemo(() => createSystemPrompt({
714
+ artifacts: artifactDefinitions.map((definition) => definition.instructions)
715
+ }), [
716
+ artifactDefinitions
717
+ ]);
718
+ const processor = useMemo(() => new ChatProcessor(aiClient, tools, {
719
+ space,
720
+ dispatch
721
+ }, {
722
+ model: "@anthropic/claude-3-5-sonnet-20241022",
723
+ systemPrompt
724
+ }), [
725
+ aiClient,
726
+ tools,
727
+ space,
728
+ dispatch,
729
+ systemPrompt
730
+ ]);
731
+ return processor;
732
+ };
733
+
734
+ // packages/plugins/experimental/plugin-automation/src/hooks/useLocalTriggerManager.ts
735
+ import { useEffect as useEffect2, useState as useState2 } from "react";
736
+ import { Mutex } from "@dxos/async";
737
+ import { Context } from "@dxos/context";
738
+ import { createSubscriptionTrigger } from "@dxos/functions";
739
+ import { FunctionTrigger } from "@dxos/functions";
740
+ import { invariant as invariant4 } from "@dxos/invariant";
741
+ import { log as log5 } from "@dxos/log";
742
+ import { useClient } from "@dxos/react-client";
743
+ import { Filter as Filter2, useQuery as useQuery2 } from "@dxos/react-client/echo";
744
+
745
+ // packages/plugins/experimental/plugin-automation/src/hooks/invocation-handler.ts
746
+ import { sleep } from "@dxos/async";
747
+ import { getObjectCore, ResultFormat } from "@dxos/echo-db";
748
+ import { FunctionType as FunctionType2 } from "@dxos/functions";
749
+ import { invariant as invariant3 } from "@dxos/invariant";
750
+ import { DXN, LOCAL_SPACE_TAG } from "@dxos/keys";
751
+ import { log as log4 } from "@dxos/log";
752
+
753
+ // packages/plugins/experimental/plugin-automation/src/hooks/useLocalTriggerManager.ts
754
+ var registerTriggersMutex = new Mutex();
755
+
756
+ // packages/plugins/experimental/plugin-automation/src/hooks/useMessageQueue.ts
757
+ import { useMemo as useMemo2 } from "react";
758
+ import { DXN as DXN2, QueueSubspaceTags } from "@dxos/keys";
759
+ import { getSpace as getSpace2 } from "@dxos/react-client/echo";
760
+ import { useEdgeClient, useQueue } from "@dxos/react-edge-client";
761
+ var useMessageQueue = (chat) => {
762
+ const edgeClient = useEdgeClient();
763
+ const space = getSpace2(chat);
764
+ const queueDxn = useMemo2(() => new DXN2(DXN2.kind.QUEUE, [
765
+ QueueSubspaceTags.DATA,
766
+ space.id,
767
+ chat.queue.dxn.parts.at(-1)
768
+ ]), [
769
+ chat.queue.dxn
770
+ ]);
771
+ return useQueue(edgeClient, queueDxn);
772
+ };
773
+
774
+ // packages/plugins/experimental/plugin-automation/src/hooks/useServices.ts
775
+ import { useEffect as useEffect3, useMemo as useMemo3, useState as useState3 } from "react";
776
+
777
+ // packages/plugins/experimental/plugin-automation/src/testing/test-functions.ts
778
+ import { createSystemPrompt as createSystemPrompt2 } from "@dxos/artifact";
779
+ import { AST, S as S2, toJsonSchema } from "@dxos/echo-schema";
780
+ var functions = [
781
+ {
782
+ name: "example.com/function/chess",
783
+ version: "0.1.0",
784
+ inputSchema: toJsonSchema(S2.Struct({
785
+ level: S2.Number.annotations({
786
+ [AST.TitleAnnotationId]: "Level"
787
+ })
788
+ }))
789
+ },
790
+ {
791
+ name: "example.com/function/forex",
792
+ version: "0.1.0",
793
+ binding: "FOREX",
794
+ inputSchema: toJsonSchema(S2.Struct({
795
+ from: S2.String.annotations({
796
+ [AST.TitleAnnotationId]: "Currency from"
797
+ }),
798
+ to: S2.String.annotations({
799
+ [AST.TitleAnnotationId]: "Currency to"
800
+ })
801
+ }))
802
+ }
803
+ ];
804
+
805
+ // packages/plugins/experimental/plugin-automation/src/testing/test-services.ts
806
+ import { createStatic as createStatic2 } from "@dxos/echo-schema";
807
+ var MockServiceRegistry = class {
808
+ async queryServices(query) {
809
+ return TEST_SERVICES;
810
+ }
811
+ };
812
+ var AMADEUS_AUTH = {
813
+ type: "oauth",
814
+ clientId: "BOEnpLd1sMyKjAPGKYeAPFFy60u53QEG",
815
+ clientSecret: "n4qldSN7usvD57gm",
816
+ tokenUrl: "https://test.api.amadeus.com/v1/security/oauth2/token",
817
+ grantType: "client_credentials"
818
+ };
819
+ var VISUAL_CROSSING_CREDENTIALS = {
820
+ type: "api-key",
821
+ key: "FDPRVS953KB4GQQLD25GRT975",
822
+ placement: {
823
+ type: "query",
824
+ name: "key"
825
+ }
826
+ };
827
+ var TEST_SERVICES = [
828
+ createStatic2(ServiceType, {
829
+ serviceId: "amadeus.com/service/FlightSearch",
830
+ name: "Amadeus Flight Search",
831
+ description: "Search for local and international flights.",
832
+ category: "travel",
833
+ interfaces: [
834
+ {
835
+ kind: "api",
836
+ schemaUrl: "https://api.apis.guru/v2/specs/amadeus.com/amadeus-flight-availabilities-search/1.0.2/swagger.json",
837
+ authorization: AMADEUS_AUTH
838
+ }
839
+ ]
840
+ }),
841
+ createStatic2(ServiceType, {
842
+ serviceId: "amadeus.com/service/HotelSearch",
843
+ name: "Amadeus Hotel Search",
844
+ description: "Search for local and international hotels.",
845
+ category: "travel",
846
+ interfaces: [
847
+ {
848
+ kind: "api",
849
+ schemaUrl: "https://api.apis.guru/v2/specs/amadeus.com/amadeus-hotel-search/3.0.8/swagger.json",
850
+ authorization: AMADEUS_AUTH
851
+ }
852
+ ]
853
+ }),
854
+ createStatic2(ServiceType, {
855
+ serviceId: "visualcrossing.com/service/Weather",
856
+ name: "Visual Crossing Weather",
857
+ description: "Search for global weather forecasts.",
858
+ category: "weather",
859
+ interfaces: [
860
+ {
861
+ kind: "api",
862
+ schemaUrl: "https://api.apis.guru/v2/specs/visualcrossing.com/weather/4.6/openapi.json",
863
+ authorization: VISUAL_CROSSING_CREDENTIALS
864
+ }
865
+ ]
866
+ }),
867
+ // TODO(burdon): Needs auth.
868
+ createStatic2(ServiceType, {
869
+ serviceId: "abstractapi.com/service/GeoLocation",
870
+ name: "Abstract GeoLocation",
871
+ description: "Get the location of any IP address.",
872
+ category: "geolocation",
873
+ interfaces: [
874
+ {
875
+ kind: "api",
876
+ schemaUrl: "https://api.apis.guru/v2/specs/abstractapi.com/geolocation/1.0.0/openapi.json"
877
+ }
878
+ ]
879
+ }),
880
+ //
881
+ // Testing
882
+ //
883
+ ...Array.from({
884
+ length: 20
885
+ }, (_, i) => createStatic2(ServiceType, {
886
+ serviceId: `example.com/service/test-${i}`,
887
+ name: `Test ${i}`,
888
+ description: `Test ${i}`,
889
+ category: Object.keys(categoryIcons)[Math.floor(Math.random() * Object.keys(categoryIcons).length)],
890
+ interfaces: [
891
+ {
892
+ kind: "api",
893
+ schemaUrl: "https://petstore.swagger.io/v2/swagger.json"
894
+ }
895
+ ]
896
+ }))
897
+ ];
898
+
899
+ // packages/plugins/experimental/plugin-automation/src/hooks/useServices.ts
900
+ var useServices = (space, query) => {
901
+ const registry = useMemo3(() => new MockServiceRegistry(), []);
902
+ const [services, setServices] = useState3([]);
903
+ useEffect3(() => {
904
+ const t = setTimeout(async () => {
905
+ const services2 = await registry.queryServices(query);
906
+ setServices(services2);
907
+ });
908
+ return () => clearTimeout(t);
909
+ }, [
910
+ query,
911
+ registry
912
+ ]);
913
+ return services;
914
+ };
915
+
916
+ // packages/plugins/experimental/plugin-automation/src/components/Thread/Thread.tsx
917
+ import React6, { useCallback as useCallback2, useMemo as useMemo4, useRef as useRef3, useState as useState7 } from "react";
918
+ import { IconButton, Input, useTranslation } from "@dxos/react-ui";
919
+ import { Spinner } from "@dxos/react-ui-sfx";
920
+ import { mx as mx6 } from "@dxos/react-ui-theme";
921
+
922
+ // packages/plugins/experimental/plugin-automation/src/components/Thread/ScrollContainer.tsx
923
+ import React, { forwardRef, useCallback, useEffect as useEffect4, useImperativeHandle, useRef, useState as useState4 } from "react";
924
+ import { invariant as invariant5 } from "@dxos/invariant";
925
+ import { mx } from "@dxos/react-ui-theme";
926
+ var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/plugins/experimental/plugin-automation/src/components/Thread/ScrollContainer.tsx";
927
+ var ScrollContainer = /* @__PURE__ */ forwardRef(({ children, classNames }, forwardedRef) => {
928
+ const containerRef = useRef(null);
929
+ const autoScrollRef = useRef(false);
930
+ useImperativeHandle(forwardedRef, () => ({
931
+ scrollToBottom: () => {
932
+ invariant5(containerRef.current, void 0, {
933
+ F: __dxlog_file4,
934
+ L: 41,
935
+ S: void 0,
936
+ A: [
937
+ "containerRef.current",
938
+ ""
939
+ ]
940
+ });
941
+ containerRef.current.scrollTo({
942
+ top: containerRef.current.scrollHeight,
943
+ behavior: "smooth"
944
+ });
945
+ autoScrollRef.current = false;
946
+ }
947
+ }), []);
948
+ const [sticky, setSticky] = useState4(true);
949
+ useEffect4(() => {
950
+ if (!sticky || !containerRef.current) {
951
+ return;
952
+ }
953
+ autoScrollRef.current = true;
954
+ containerRef.current.scrollTo({
955
+ top: containerRef.current.scrollHeight,
956
+ behavior: "smooth"
957
+ });
958
+ }, [
959
+ children
960
+ ]);
961
+ useEffect4(() => {
962
+ invariant5(containerRef.current, void 0, {
963
+ F: __dxlog_file4,
964
+ L: 62,
965
+ S: void 0,
966
+ A: [
967
+ "containerRef.current",
968
+ ""
969
+ ]
970
+ });
971
+ const handleScrollEnd = () => {
972
+ autoScrollRef.current = false;
973
+ };
974
+ containerRef.current.addEventListener("scrollend", handleScrollEnd);
975
+ return () => containerRef.current?.removeEventListener("scrollend", handleScrollEnd);
976
+ }, []);
977
+ const handleScroll = useCallback((ev) => {
978
+ if (autoScrollRef.current) {
979
+ return;
980
+ }
981
+ const { scrollTop, clientHeight, scrollHeight } = ev.currentTarget;
982
+ const sticky2 = scrollTop + clientHeight >= scrollHeight;
983
+ setSticky(sticky2);
984
+ }, []);
985
+ return /* @__PURE__ */ React.createElement("div", {
986
+ ref: containerRef,
987
+ onScroll: handleScroll,
988
+ className: mx("flex flex-col grow overflow-y-scroll scrollbar-none", classNames)
989
+ }, children);
990
+ });
991
+
992
+ // packages/plugins/experimental/plugin-automation/src/components/Thread/ThreadMessage.tsx
993
+ import React5 from "react";
994
+ import { invariant as invariant6 } from "@dxos/invariant";
995
+ import { log as log6 } from "@dxos/log";
996
+ import { Button, ButtonGroup, Icon as Icon2 } from "@dxos/react-ui";
997
+ import { Json } from "@dxos/react-ui-syntax-highlighter";
998
+ import { mx as mx5 } from "@dxos/react-ui-theme";
999
+ import { safeParseJson } from "@dxos/util";
1000
+
1001
+ // packages/plugins/experimental/plugin-automation/src/components/Thread/StatusLine.tsx
1002
+ import React2, { useEffect as useEffect5, useRef as useRef2, useState as useState5 } from "react";
1003
+ import { mx as mx2 } from "@dxos/react-ui-theme";
1004
+ var emptyLines = [];
1005
+ var StatusLine = ({ classNames, line = -1, lines = emptyLines, transition = 300, advance = 1e3, autoAdvance }) => {
1006
+ const containerRef = useRef2(null);
1007
+ const [currentLine, setCurrentLine] = useState5(line);
1008
+ useEffect5(() => {
1009
+ setCurrentLine(line);
1010
+ }, [
1011
+ line
1012
+ ]);
1013
+ useEffect5(() => {
1014
+ if (!autoAdvance) {
1015
+ return;
1016
+ }
1017
+ const next = () => {
1018
+ setCurrentLine((prev) => {
1019
+ if (prev >= lines.length - 1) {
1020
+ clearInterval(interval);
1021
+ return prev;
1022
+ }
1023
+ return prev + 1;
1024
+ });
1025
+ };
1026
+ next();
1027
+ const interval = setInterval(next, advance);
1028
+ return () => clearInterval(interval);
1029
+ }, [
1030
+ lines.length,
1031
+ autoAdvance,
1032
+ advance
1033
+ ]);
1034
+ useEffect5(() => {
1035
+ if (containerRef.current) {
1036
+ containerRef.current.style.transition = `transform ${transition}ms ease-in-out`;
1037
+ containerRef.current.style.transform = `translateY(-${currentLine * 24}px)`;
1038
+ }
1039
+ }, [
1040
+ currentLine
1041
+ ]);
1042
+ return /* @__PURE__ */ React2.createElement("div", {
1043
+ className: mx2("relative h-[24px] overflow-hidden", classNames)
1044
+ }, /* @__PURE__ */ React2.createElement("div", {
1045
+ ref: containerRef,
1046
+ className: "h-[24px]"
1047
+ }, /* @__PURE__ */ React2.createElement("div", {
1048
+ className: "flex flex-col"
1049
+ }, lines.map((line2, i) => /* @__PURE__ */ React2.createElement("div", {
1050
+ key: i,
1051
+ className: mx2("flex h-[24px] items-center")
1052
+ }, /* @__PURE__ */ React2.createElement("span", {
1053
+ className: "truncate"
1054
+ }, line2))))));
1055
+ };
1056
+
1057
+ // packages/plugins/experimental/plugin-automation/src/components/Thread/ToggleContainer.tsx
1058
+ import React3, { useEffect as useEffect6, useState as useState6 } from "react";
1059
+ import { Icon } from "@dxos/react-ui";
1060
+ import { mx as mx3 } from "@dxos/react-ui-theme";
1061
+ var ToggleContainer = ({ title, icon, toggle, defaultOpen, duration = 400, shrinkX = false, children, classNames }) => {
1062
+ const [expand, setExpand] = useState6(defaultOpen || !toggle);
1063
+ const [expandX, setExpandX] = useState6(shrinkX ? expand : true);
1064
+ const [expandY, setExpandY] = useState6(expand);
1065
+ useEffect6(() => {
1066
+ let t;
1067
+ if (expand) {
1068
+ if (shrinkX) {
1069
+ setExpandX(true);
1070
+ }
1071
+ t = setTimeout(() => {
1072
+ setExpandY(true);
1073
+ }, shrinkX ? duration : 0);
1074
+ } else {
1075
+ setExpandY(false);
1076
+ if (shrinkX) {
1077
+ t = setTimeout(() => {
1078
+ setExpandX(false);
1079
+ }, duration);
1080
+ }
1081
+ }
1082
+ return () => clearTimeout(t);
1083
+ }, [
1084
+ expand
1085
+ ]);
1086
+ return /* @__PURE__ */ React3.createElement("div", {
1087
+ className: mx3("overflow-hidden", classNames)
1088
+ }, title && /* @__PURE__ */ React3.createElement("div", {
1089
+ className: "flex gap-1 py-1 items-center text-sm text-subdued cursor-pointer select-none",
1090
+ onClick: toggle ? () => setExpand((open) => !open) : void 0
1091
+ }, toggle && /* @__PURE__ */ React3.createElement("div", {
1092
+ className: "flex w-[24px] h-[24px] items-center justify-center"
1093
+ }, /* @__PURE__ */ React3.createElement(Icon, {
1094
+ size: 4,
1095
+ icon: "ph--caret-right--regular",
1096
+ style: {
1097
+ transitionDuration: `${shrinkX ? duration * 2 : duration}ms`
1098
+ },
1099
+ classNames: [
1100
+ "transition transition-transform ease-in-out",
1101
+ expand ? "rotate-90" : "transform-none"
1102
+ ]
1103
+ })), /* @__PURE__ */ React3.createElement("div", {
1104
+ className: "flex-1 pis-1 pie-1 truncate"
1105
+ }, title), icon), /* @__PURE__ */ React3.createElement("div", {
1106
+ style: {
1107
+ transitionDuration: `${duration}ms`
1108
+ },
1109
+ className: mx3("grid transition-[grid-template-columns] ease-in-out", expandX ? "grid-cols-[1fr]" : "grid-cols-[0fr]")
1110
+ }, /* @__PURE__ */ React3.createElement("div", {
1111
+ className: "overflow-hidden"
1112
+ }, /* @__PURE__ */ React3.createElement("div", {
1113
+ style: {
1114
+ transitionDuration: `${duration}ms`
1115
+ },
1116
+ className: mx3("grid transition-[grid-template-rows] ease-in-out", expandY ? "grid-rows-[1fr]" : "grid-rows-[0fr]")
1117
+ }, /* @__PURE__ */ React3.createElement("div", {
1118
+ className: mx3("flex overflow-hidden transition-opacity")
1119
+ }, children)))));
1120
+ };
1121
+
1122
+ // packages/plugins/experimental/plugin-automation/src/components/MarkdownViewer/MarkdownViewer.tsx
1123
+ import React4 from "react";
1124
+ import ReactMarkdown from "react-markdown";
1125
+ import { SyntaxHighlighter } from "@dxos/react-ui-syntax-highlighter";
1126
+ import { mx as mx4 } from "@dxos/react-ui-theme";
1127
+ import { omit } from "@dxos/util";
1128
+ var MarkdownViewer = ({ classNames, content = "" }) => {
1129
+ return /* @__PURE__ */ React4.createElement("div", {
1130
+ className: mx4("space-y-2", classNames)
1131
+ }, /* @__PURE__ */ React4.createElement(ReactMarkdown, {
1132
+ components: {
1133
+ a: ({ node, children, href, ...props }) => /* @__PURE__ */ React4.createElement("a", {
1134
+ href,
1135
+ className: "text-primary-500 hover:text-primary-500",
1136
+ target: "_blank",
1137
+ rel: "noopener noreferrer",
1138
+ ...props
1139
+ }, children),
1140
+ ol: ({ node, children, ...props }) => /* @__PURE__ */ React4.createElement("ol", {
1141
+ className: "leading-tight list-decimal pl-6",
1142
+ ...omit(props, [
1143
+ "ordered"
1144
+ ])
1145
+ }, children),
1146
+ ul: ({ node, children, ...props }) => /* @__PURE__ */ React4.createElement("ul", {
1147
+ className: "leading-tight list-disc pl-6",
1148
+ ...omit(props, [
1149
+ "ordered"
1150
+ ])
1151
+ }, children),
1152
+ li: ({ node, children, ...props }) => /* @__PURE__ */ React4.createElement("li", {
1153
+ className: "",
1154
+ ...omit(props, [
1155
+ "ordered"
1156
+ ])
1157
+ }, children),
1158
+ blockquote: ({ node, children, ...props }) => /* @__PURE__ */ React4.createElement("blockquote", {
1159
+ className: "border-l-4 border-primary-500 pl-4 my-4 text-primary-500",
1160
+ ...props
1161
+ }, children),
1162
+ code: ({ children, className }) => {
1163
+ const [_, language] = /language-(\w+)/.exec(className || "") || [];
1164
+ return /* @__PURE__ */ React4.createElement(SyntaxHighlighter, {
1165
+ PreTag: "div",
1166
+ language,
1167
+ className: "p-0"
1168
+ }, children);
1169
+ }
1170
+ }
1171
+ }, content));
1172
+ };
1173
+
1174
+ // packages/plugins/experimental/plugin-automation/src/components/Thread/ThreadMessage.tsx
1175
+ var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/plugins/experimental/plugin-automation/src/components/Thread/ThreadMessage.tsx";
1176
+ var ThreadMessage = ({ classNames, message, collapse, debug, onSuggest, onDelete }) => {
1177
+ if (typeof message !== "object") {
1178
+ return /* @__PURE__ */ React5.createElement("div", {
1179
+ className: mx5(classNames)
1180
+ }, message);
1181
+ }
1182
+ const { role, content = [] } = message;
1183
+ const toolBlocks = content.filter((block) => block.type === "tool_use" || block.type === "tool_result");
1184
+ if (collapse && toolBlocks.length > 0) {
1185
+ let request;
1186
+ const json = [];
1187
+ const lines = toolBlocks.map((block) => {
1188
+ switch (block.type) {
1189
+ case "tool_use": {
1190
+ request = block;
1191
+ json.push(block);
1192
+ return `Calling ${block.name}...`;
1193
+ }
1194
+ case "tool_result": {
1195
+ if (!request) {
1196
+ log6.warn("unexpected message", {
1197
+ tool: block
1198
+ }, {
1199
+ F: __dxlog_file5,
1200
+ L: 57,
1201
+ S: void 0,
1202
+ C: (f, a) => f(...a)
1203
+ });
1204
+ return "Error";
1205
+ }
1206
+ json.push(block);
1207
+ return `Processed ${request.name}`;
1208
+ }
1209
+ default: {
1210
+ request = void 0;
1211
+ return "Error";
1212
+ }
1213
+ }
1214
+ });
1215
+ return /* @__PURE__ */ React5.createElement("div", {
1216
+ className: mx5("flex", classNames)
1217
+ }, /* @__PURE__ */ React5.createElement("div", {
1218
+ className: "w-full p-1 px-2 overflow-hidden rounded-md bg-baseSurface"
1219
+ }, /* @__PURE__ */ React5.createElement(ToggleContainer, {
1220
+ title: /* @__PURE__ */ React5.createElement(StatusLine, {
1221
+ lines,
1222
+ autoAdvance: true
1223
+ }),
1224
+ toggle: true
1225
+ }, /* @__PURE__ */ React5.createElement(Json, {
1226
+ data: json,
1227
+ classNames: "!p-1 text-xs"
1228
+ }))));
1229
+ }
1230
+ return /* @__PURE__ */ React5.createElement("div", {
1231
+ className: mx5("flex flex-col shrink-0 gap-2")
1232
+ }, debug && /* @__PURE__ */ React5.createElement("div", {
1233
+ className: "text-xs text-subdued"
1234
+ }, message.id, " ", onDelete && /* @__PURE__ */ React5.createElement("span", {
1235
+ className: "cursor-pointer underline",
1236
+ onClick: () => onDelete(message.id)
1237
+ }, "delete")), content.map((block, idx) => /* @__PURE__ */ React5.createElement("div", {
1238
+ key: idx,
1239
+ className: mx5("flex", classNames, block.type === "text" && role === "user" && "justify-end")
1240
+ }, /* @__PURE__ */ React5.createElement(Block, {
1241
+ role,
1242
+ block,
1243
+ onSuggest: onSuggest ?? (() => {
1244
+ })
1245
+ }))));
1246
+ };
1247
+ var Block = ({ block, role, onSuggest }) => {
1248
+ const Component = componentMap[block.type] ?? componentMap.default;
1249
+ return /* @__PURE__ */ React5.createElement("div", {
1250
+ className: mx5("p-1 px-2 overflow-hidden rounded-md", (block.type !== "text" || block.disposition) && "w-full bg-baseSurface", block.type === "text" && role === "user" && "bg-primary-200 dark:bg-primary-500")
1251
+ }, /* @__PURE__ */ React5.createElement(Component, {
1252
+ block,
1253
+ onSuggest
1254
+ }));
1255
+ };
1256
+ var titles = {
1257
+ ["cot"]: "Chain of thought",
1258
+ ["artifact"]: "Artifact",
1259
+ ["tool_use"]: "Tool request",
1260
+ ["tool_result"]: "Tool result"
1261
+ };
1262
+ var componentMap = {
1263
+ text: ({ block }) => {
1264
+ invariant6(block.type === "text", void 0, {
1265
+ F: __dxlog_file5,
1266
+ L: 134,
1267
+ S: void 0,
1268
+ A: [
1269
+ "block.type === 'text'",
1270
+ ""
1271
+ ]
1272
+ });
1273
+ const title = block.disposition ? titles[block.disposition] : void 0;
1274
+ if (!title) {
1275
+ return /* @__PURE__ */ React5.createElement(MarkdownViewer, {
1276
+ content: block.text,
1277
+ classNames: [
1278
+ block.disposition === "cot" && "text-sm text-subdued"
1279
+ ]
1280
+ });
1281
+ }
1282
+ return /* @__PURE__ */ React5.createElement(ToggleContainer, {
1283
+ title,
1284
+ icon: block.pending ? /* @__PURE__ */ React5.createElement(Icon2, {
1285
+ icon: "ph--circle-notch--regular",
1286
+ classNames: "text-subdued ml-2 animate-spin",
1287
+ size: 4
1288
+ }) : void 0,
1289
+ defaultOpen: block.disposition === "cot",
1290
+ toggle: true
1291
+ }, /* @__PURE__ */ React5.createElement(MarkdownViewer, {
1292
+ content: block.text,
1293
+ classNames: [
1294
+ block.disposition === "cot" && "text-sm text-subdued"
1295
+ ]
1296
+ }));
1297
+ },
1298
+ json: ({ block, onSuggest }) => {
1299
+ invariant6(block.type === "json", void 0, {
1300
+ F: __dxlog_file5,
1301
+ L: 159,
1302
+ S: void 0,
1303
+ A: [
1304
+ "block.type === 'json'",
1305
+ ""
1306
+ ]
1307
+ });
1308
+ switch (block.disposition) {
1309
+ case "suggest": {
1310
+ const { text = "" } = safeParseJson(block.json ?? "{}") ?? {};
1311
+ return /* @__PURE__ */ React5.createElement(Button, {
1312
+ onClick: () => onSuggest(text)
1313
+ }, text);
1314
+ }
1315
+ case "select": {
1316
+ const { options = [] } = safeParseJson(block.json ?? "{}") ?? {};
1317
+ return /* @__PURE__ */ React5.createElement(ButtonGroup, null, options.map((option) => /* @__PURE__ */ React5.createElement(Button, {
1318
+ key: option,
1319
+ onClick: () => onSuggest(option)
1320
+ }, option)));
1321
+ }
1322
+ default: {
1323
+ const title = block.disposition ? titles[block.disposition] : void 0;
1324
+ return /* @__PURE__ */ React5.createElement(ToggleContainer, {
1325
+ title: title ?? "JSON",
1326
+ toggle: true
1327
+ }, /* @__PURE__ */ React5.createElement(Json, {
1328
+ data: safeParseJson(block.json ?? block),
1329
+ classNames: "!p-1 text-xs"
1330
+ }));
1331
+ }
1332
+ }
1333
+ },
1334
+ default: ({ block }) => {
1335
+ let title = titles[block.type];
1336
+ if (block.type === "tool_use") {
1337
+ title = `Tool [${block.name}]`;
1338
+ }
1339
+ return /* @__PURE__ */ React5.createElement(ToggleContainer, {
1340
+ title: title ?? "JSON",
1341
+ toggle: true
1342
+ }, /* @__PURE__ */ React5.createElement(Json, {
1343
+ data: block,
1344
+ classNames: "!p-1 text-xs"
1345
+ }));
1346
+ }
1347
+ };
1348
+
1349
+ // packages/plugins/experimental/plugin-automation/src/components/Thread/Thread.tsx
1350
+ var Thread = ({ messages, streaming, collapse, debug, onSubmit, onStop, onSuggest, onDelete }) => {
1351
+ const { t } = useTranslation(AUTOMATION_PLUGIN);
1352
+ const scroller = useRef3(null);
1353
+ const [text, setText] = useState7("");
1354
+ const handleKeyDown = useCallback2((ev) => {
1355
+ switch (ev.key) {
1356
+ case "Escape": {
1357
+ setText("");
1358
+ break;
1359
+ }
1360
+ case "Enter": {
1361
+ const value = text.trim();
1362
+ if (value.length > 0) {
1363
+ scroller.current?.scrollToBottom();
1364
+ onSubmit?.(value);
1365
+ setText("");
1366
+ }
1367
+ break;
1368
+ }
1369
+ }
1370
+ }, [
1371
+ text
1372
+ ]);
1373
+ const { messages: lines = [] } = useMemo4(() => {
1374
+ if (!collapse) {
1375
+ return {
1376
+ messages: messages ?? []
1377
+ };
1378
+ }
1379
+ return (messages ?? []).reduce(({ current, messages: messages2 }, message) => {
1380
+ let i = 0;
1381
+ for (const block of message.content) {
1382
+ switch (block.type) {
1383
+ case "tool_use":
1384
+ case "tool_result": {
1385
+ if (current) {
1386
+ current.content.push(block);
1387
+ } else {
1388
+ current = {
1389
+ id: [
1390
+ message.id,
1391
+ i
1392
+ ].join("_"),
1393
+ role: message.role,
1394
+ content: [
1395
+ block
1396
+ ]
1397
+ };
1398
+ messages2.push(current);
1399
+ }
1400
+ break;
1401
+ }
1402
+ case "text":
1403
+ default: {
1404
+ current = void 0;
1405
+ messages2.push({
1406
+ id: [
1407
+ message.id,
1408
+ i
1409
+ ].join("_"),
1410
+ role: message.role,
1411
+ content: [
1412
+ block
1413
+ ]
1414
+ });
1415
+ break;
1416
+ }
1417
+ }
1418
+ i++;
1419
+ }
1420
+ return {
1421
+ current,
1422
+ messages: messages2
1423
+ };
1424
+ }, {
1425
+ messages: []
1426
+ });
1427
+ }, [
1428
+ messages,
1429
+ collapse
1430
+ ]);
1431
+ return /* @__PURE__ */ React6.createElement("div", {
1432
+ className: "flex flex-col grow overflow-hidden"
1433
+ }, /* @__PURE__ */ React6.createElement(ScrollContainer, {
1434
+ ref: scroller,
1435
+ classNames: "py-2 gap-2 overflow-x-hidden"
1436
+ }, lines.map((message) => /* @__PURE__ */ React6.createElement(ThreadMessage, {
1437
+ key: message.id,
1438
+ classNames: "px-4",
1439
+ message,
1440
+ collapse,
1441
+ debug,
1442
+ onSuggest,
1443
+ onDelete
1444
+ }))), onSubmit && /* @__PURE__ */ React6.createElement("div", {
1445
+ className: "flex p-4 gap-3 items-center"
1446
+ }, /* @__PURE__ */ React6.createElement(Spinner, {
1447
+ active: streaming
1448
+ }), /* @__PURE__ */ React6.createElement(Input.Root, null, /* @__PURE__ */ React6.createElement(Input.TextInput, {
1449
+ autoFocus: true,
1450
+ classNames: "px-2 baseSurface rounded",
1451
+ placeholder: t("chat input placeholder"),
1452
+ value: text,
1453
+ onChange: (ev) => setText(ev.target.value),
1454
+ onKeyDown: handleKeyDown
1455
+ })), onStop && /* @__PURE__ */ React6.createElement(IconButton, {
1456
+ disabled: !streaming,
1457
+ classNames: mx6("!p-1 !opacity-20 transition", streaming && "!opacity-80"),
1458
+ variant: "ghost",
1459
+ size: 5,
1460
+ onClick: onStop,
1461
+ icon: "ph--x--regular",
1462
+ label: t("chat stop"),
1463
+ iconOnly: true
1464
+ })));
1465
+ };
1466
+
1467
+ // packages/plugins/experimental/plugin-automation/src/components/ChatContainer/ChatContainer.tsx
1468
+ var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/plugins/experimental/plugin-automation/src/components/ChatContainer/ChatContainer.tsx";
1469
+ var ChatContainer = ({ chat, role }) => {
1470
+ const processor = useChatProcessor(chat);
1471
+ const messageQueue = useMessageQueue(chat);
1472
+ const messages = [
1473
+ ...messageQueue?.items ?? [],
1474
+ ...processor.messages.value
1475
+ ];
1476
+ const handleSubmit = useCallback3(async (text) => {
1477
+ if (processor.streaming.value) {
1478
+ await processor.cancel();
1479
+ }
1480
+ invariant7(messageQueue, void 0, {
1481
+ F: __dxlog_file6,
1482
+ L: 25,
1483
+ S: void 0,
1484
+ A: [
1485
+ "messageQueue",
1486
+ ""
1487
+ ]
1488
+ });
1489
+ await processor.request(text, {
1490
+ history: messageQueue.items,
1491
+ onComplete: (messages2) => messageQueue.append(messages2)
1492
+ });
1493
+ }, [
1494
+ processor,
1495
+ messageQueue
1496
+ ]);
1497
+ const handleStop = useCallback3(() => {
1498
+ if (processor.streaming.value) {
1499
+ void processor.cancel();
1500
+ }
1501
+ }, [
1502
+ processor
1503
+ ]);
1504
+ return /* @__PURE__ */ React7.createElement(StackItem.Content, {
1505
+ toolbar: false,
1506
+ role
1507
+ }, /* @__PURE__ */ React7.createElement(Thread, {
1508
+ messages,
1509
+ streaming: processor.streaming.value,
1510
+ collapse: true,
1511
+ onSubmit: handleSubmit,
1512
+ onSuggest: handleSubmit,
1513
+ onStop: handleStop
1514
+ }));
1515
+ };
1516
+
1517
+ // packages/plugins/experimental/plugin-automation/src/components/ChatContainer/index.ts
1518
+ var ChatContainer_default = ChatContainer;
1519
+
1520
+ export {
1521
+ useServices,
1522
+ MarkdownViewer,
1523
+ Thread,
1524
+ ChatContainer,
1525
+ ChatContainer_default,
1526
+ AiClient,
1527
+ AppGraphBuilder,
1528
+ IntentResolver,
1529
+ ReactSurface
1530
+ };
1531
+ //# sourceMappingURL=chunk-DL7XA62G.mjs.map