@dxos/plugin-assistant 0.8.2-staging.7ac8446 → 0.8.2

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 (357) hide show
  1. package/dist/lib/browser/AssistantDialog-K6POM23O.mjs +46 -0
  2. package/dist/lib/browser/AssistantDialog-K6POM23O.mjs.map +7 -0
  3. package/dist/lib/browser/ChatContainer-QTO4LE2C.mjs +39 -0
  4. package/dist/lib/browser/ChatContainer-QTO4LE2C.mjs.map +7 -0
  5. package/dist/lib/browser/TemplateContainer-AKUYL4AV.mjs +28 -0
  6. package/dist/lib/browser/TemplateContainer-AKUYL4AV.mjs.map +7 -0
  7. package/dist/lib/browser/{ai-client-CDZLSNXE.mjs → ai-client-COXVUC6V.mjs} +6 -6
  8. package/dist/lib/browser/ai-client-COXVUC6V.mjs.map +7 -0
  9. package/dist/lib/browser/app-graph-builder-YH4EGNBC.mjs +206 -0
  10. package/dist/lib/browser/app-graph-builder-YH4EGNBC.mjs.map +7 -0
  11. package/dist/lib/browser/{chunk-TXJWGWJ7.mjs → chunk-3F44MBHU.mjs} +3 -3
  12. package/dist/lib/browser/chunk-3F44MBHU.mjs.map +7 -0
  13. package/dist/lib/browser/chunk-IHEBFO5O.mjs +205 -0
  14. package/dist/lib/browser/chunk-IHEBFO5O.mjs.map +7 -0
  15. package/dist/lib/browser/chunk-JQFUME3B.mjs +87 -0
  16. package/dist/lib/{node-esm/chunk-PBZA7XJR.mjs.map → browser/chunk-JQFUME3B.mjs.map} +1 -1
  17. package/dist/lib/browser/chunk-Q6UZ4F3H.mjs +96 -0
  18. package/dist/lib/browser/chunk-Q6UZ4F3H.mjs.map +7 -0
  19. package/dist/lib/browser/{chunk-FMB7RGMP.mjs → chunk-QTW7KVDO.mjs} +1669 -1515
  20. package/dist/lib/browser/chunk-QTW7KVDO.mjs.map +7 -0
  21. package/dist/lib/browser/chunk-USJBRB3H.mjs +155 -0
  22. package/dist/lib/browser/chunk-USJBRB3H.mjs.map +7 -0
  23. package/dist/lib/browser/{chunk-3HCI5FIL.mjs → chunk-XOZ7YMO3.mjs} +3 -3
  24. package/dist/lib/browser/{chunk-3HCI5FIL.mjs.map → chunk-XOZ7YMO3.mjs.map} +1 -1
  25. package/dist/lib/browser/index.mjs +35 -18
  26. package/dist/lib/browser/index.mjs.map +3 -3
  27. package/dist/lib/browser/{intent-resolver-WJGLKKVO.mjs → intent-resolver-63EAHENI.mjs} +10 -14
  28. package/dist/lib/browser/intent-resolver-63EAHENI.mjs.map +7 -0
  29. package/dist/lib/browser/meta.json +1 -1
  30. package/dist/lib/browser/react-surface-XCV6NR75.mjs +131 -0
  31. package/dist/lib/browser/react-surface-XCV6NR75.mjs.map +7 -0
  32. package/dist/lib/browser/{settings-U6UFQX32.mjs → settings-SHNQ4XXP.mjs} +5 -5
  33. package/dist/lib/browser/settings-SHNQ4XXP.mjs.map +7 -0
  34. package/dist/lib/browser/types/index.mjs +6 -2
  35. package/dist/lib/node/AssistantDialog-FDATKYE5.cjs +72 -0
  36. package/dist/lib/node/AssistantDialog-FDATKYE5.cjs.map +7 -0
  37. package/dist/lib/node/{ChatContainer-ZJ5JXF6A.cjs → ChatContainer-5CLHJOIQ.cjs} +25 -19
  38. package/dist/lib/node/ChatContainer-5CLHJOIQ.cjs.map +7 -0
  39. package/dist/lib/node/TemplateContainer-CTG2MB4W.cjs +58 -0
  40. package/dist/lib/node/TemplateContainer-CTG2MB4W.cjs.map +7 -0
  41. package/dist/lib/node/{ai-client-URCCYU6B.cjs → ai-client-R2CGEYZW.cjs} +13 -13
  42. package/dist/lib/node/ai-client-R2CGEYZW.cjs.map +7 -0
  43. package/dist/lib/node/app-graph-builder-PSHIOW3Q.cjs +216 -0
  44. package/dist/lib/node/app-graph-builder-PSHIOW3Q.cjs.map +7 -0
  45. package/dist/lib/node/{chunk-XI2ARIEO.cjs → chunk-4EEWTDQK.cjs} +45 -39
  46. package/dist/lib/node/{chunk-XI2ARIEO.cjs.map → chunk-4EEWTDQK.cjs.map} +1 -1
  47. package/dist/lib/node/chunk-FLJWJ35M.cjs +181 -0
  48. package/dist/lib/node/chunk-FLJWJ35M.cjs.map +7 -0
  49. package/dist/lib/node/{chunk-RPBKMP2E.cjs → chunk-H4A42LNR.cjs} +1504 -1343
  50. package/dist/lib/node/chunk-H4A42LNR.cjs.map +7 -0
  51. package/dist/lib/node/chunk-HRNIUYVQ.cjs +128 -0
  52. package/dist/lib/node/chunk-HRNIUYVQ.cjs.map +7 -0
  53. package/dist/lib/node/{chunk-Q5XWEMHB.cjs → chunk-P74TWGMG.cjs} +6 -6
  54. package/dist/lib/node/{chunk-Q5XWEMHB.cjs.map → chunk-P74TWGMG.cjs.map} +1 -1
  55. package/dist/lib/node/chunk-RXPA2C2A.cjs +230 -0
  56. package/dist/lib/node/chunk-RXPA2C2A.cjs.map +7 -0
  57. package/dist/lib/node/{chunk-GBUNQ257.cjs → chunk-TS3H5OSX.cjs} +7 -7
  58. package/dist/lib/node/chunk-TS3H5OSX.cjs.map +7 -0
  59. package/dist/lib/node/index.cjs +79 -63
  60. package/dist/lib/node/index.cjs.map +3 -3
  61. package/dist/lib/node/{intent-resolver-R3OSTIMH.cjs → intent-resolver-66F7WLW6.cjs} +13 -17
  62. package/dist/lib/node/intent-resolver-66F7WLW6.cjs.map +7 -0
  63. package/dist/lib/node/meta.json +1 -1
  64. package/dist/lib/node/react-surface-TASAPRPQ.cjs +145 -0
  65. package/dist/lib/node/react-surface-TASAPRPQ.cjs.map +7 -0
  66. package/dist/lib/node/{settings-TXGRCYAL.cjs → settings-ERKLO6IO.cjs} +9 -9
  67. package/dist/lib/node/settings-ERKLO6IO.cjs.map +7 -0
  68. package/dist/lib/node/types/index.cjs +17 -13
  69. package/dist/lib/node/types/index.cjs.map +2 -2
  70. package/dist/lib/node-esm/AssistantDialog-PIMYK774.mjs +47 -0
  71. package/dist/lib/node-esm/AssistantDialog-PIMYK774.mjs.map +7 -0
  72. package/dist/lib/node-esm/ChatContainer-QTC5NYE2.mjs +40 -0
  73. package/dist/lib/node-esm/ChatContainer-QTC5NYE2.mjs.map +7 -0
  74. package/dist/lib/node-esm/TemplateContainer-IVDQ4XQG.mjs +29 -0
  75. package/dist/lib/node-esm/TemplateContainer-IVDQ4XQG.mjs.map +7 -0
  76. package/dist/lib/node-esm/{ai-client-WMHS5EGV.mjs → ai-client-I5LXHMOZ.mjs} +6 -6
  77. package/dist/lib/node-esm/ai-client-I5LXHMOZ.mjs.map +7 -0
  78. package/dist/lib/node-esm/app-graph-builder-Z3GMMJMD.mjs +207 -0
  79. package/dist/lib/node-esm/app-graph-builder-Z3GMMJMD.mjs.map +7 -0
  80. package/dist/lib/node-esm/{chunk-ECRK6TUQ.mjs → chunk-BB2TAT4P.mjs} +3 -3
  81. package/dist/lib/node-esm/{chunk-ECRK6TUQ.mjs.map → chunk-BB2TAT4P.mjs.map} +1 -1
  82. package/dist/lib/node-esm/chunk-CDAILLCU.mjs +98 -0
  83. package/dist/lib/node-esm/chunk-CDAILLCU.mjs.map +7 -0
  84. package/dist/lib/node-esm/{chunk-6JK5HEUQ.mjs → chunk-HLPGKJ7N.mjs} +3 -3
  85. package/dist/lib/node-esm/chunk-HLPGKJ7N.mjs.map +7 -0
  86. package/dist/lib/node-esm/{chunk-PBZA7XJR.mjs → chunk-OYN6HLXZ.mjs} +42 -36
  87. package/dist/lib/{browser/chunk-NFUHCW2J.mjs.map → node-esm/chunk-OYN6HLXZ.mjs.map} +1 -1
  88. package/dist/lib/node-esm/chunk-QU626JMR.mjs +156 -0
  89. package/dist/lib/node-esm/chunk-QU626JMR.mjs.map +7 -0
  90. package/dist/lib/node-esm/{chunk-MVDAY3CZ.mjs → chunk-SI5LOQEO.mjs} +1669 -1515
  91. package/dist/lib/node-esm/chunk-SI5LOQEO.mjs.map +7 -0
  92. package/dist/lib/node-esm/chunk-ZKBACPIW.mjs +206 -0
  93. package/dist/lib/node-esm/chunk-ZKBACPIW.mjs.map +7 -0
  94. package/dist/lib/node-esm/index.mjs +35 -18
  95. package/dist/lib/node-esm/index.mjs.map +3 -3
  96. package/dist/lib/node-esm/{intent-resolver-H32TL4X6.mjs → intent-resolver-X3PWH7KM.mjs} +10 -14
  97. package/dist/lib/node-esm/intent-resolver-X3PWH7KM.mjs.map +7 -0
  98. package/dist/lib/node-esm/meta.json +1 -1
  99. package/dist/lib/node-esm/react-surface-QMIQCXUM.mjs +132 -0
  100. package/dist/lib/node-esm/react-surface-QMIQCXUM.mjs.map +7 -0
  101. package/dist/lib/node-esm/{settings-DZU5PNXM.mjs → settings-IVQRZUCU.mjs} +5 -5
  102. package/dist/lib/node-esm/settings-IVQRZUCU.mjs.map +7 -0
  103. package/dist/lib/node-esm/types/index.mjs +6 -2
  104. package/dist/types/src/AssistantPlugin.d.ts.map +1 -1
  105. package/dist/types/src/capabilities/ai-client.d.ts +3 -3
  106. package/dist/types/src/capabilities/ai-client.d.ts.map +1 -1
  107. package/dist/types/src/capabilities/app-graph-builder.d.ts +2 -179
  108. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
  109. package/dist/types/src/capabilities/capabilities.d.ts +1 -1
  110. package/dist/types/src/capabilities/capabilities.d.ts.map +1 -1
  111. package/dist/types/src/capabilities/index.d.ts +3 -179
  112. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  113. package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -1
  114. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  115. package/dist/types/src/components/AmbientDialog/AmbientDialog.d.ts +3 -1
  116. package/dist/types/src/components/AmbientDialog/AmbientDialog.d.ts.map +1 -1
  117. package/dist/types/src/components/AssistantSettings/AssistantSettings.d.ts.map +1 -1
  118. package/dist/types/src/components/BlueprintEditor/BlueprintEditor.d.ts +8 -0
  119. package/dist/types/src/components/BlueprintEditor/BlueprintEditor.d.ts.map +1 -0
  120. package/dist/types/src/components/BlueprintEditor/BlueprintEditor.stories.d.ts +8 -0
  121. package/dist/types/src/components/BlueprintEditor/BlueprintEditor.stories.d.ts.map +1 -0
  122. package/dist/types/src/components/BlueprintEditor/index.d.ts +2 -0
  123. package/dist/types/src/components/BlueprintEditor/index.d.ts.map +1 -0
  124. package/dist/types/src/components/ChatContainer.d.ts +4 -3
  125. package/dist/types/src/components/ChatContainer.d.ts.map +1 -1
  126. package/dist/types/src/components/Prompt/Prompt.d.ts +5 -2
  127. package/dist/types/src/components/Prompt/Prompt.d.ts.map +1 -1
  128. package/dist/types/src/components/Prompt/Prompt.stories.d.ts +6 -3
  129. package/dist/types/src/components/Prompt/Prompt.stories.d.ts.map +1 -1
  130. package/dist/types/src/components/Prompt/PromptBar.d.ts +9 -4
  131. package/dist/types/src/components/Prompt/PromptBar.d.ts.map +1 -1
  132. package/dist/types/src/components/Prompt/PromptBar.stories.d.ts +9 -0
  133. package/dist/types/src/components/Prompt/PromptBar.stories.d.ts.map +1 -0
  134. package/dist/types/src/components/Prompt/autocomplete.d.ts +5 -1
  135. package/dist/types/src/components/Prompt/autocomplete.d.ts.map +1 -1
  136. package/dist/types/src/components/Prompt/references.d.ts.map +1 -1
  137. package/dist/types/src/components/PromptSettings.d.ts +6 -0
  138. package/dist/types/src/components/PromptSettings.d.ts.map +1 -0
  139. package/dist/types/src/components/TemplateContainer.d.ts.map +1 -1
  140. package/dist/types/src/components/TemplateEditor/TemplateEditor.d.ts.map +1 -1
  141. package/dist/types/src/components/TemplateEditor/TemplateEditor.stories.d.ts.map +1 -1
  142. package/dist/types/src/components/TemplateEditor/TemplateForm.d.ts +2 -2
  143. package/dist/types/src/components/TemplateEditor/TemplateForm.d.ts.map +1 -1
  144. package/dist/types/src/components/Thread/Thread.d.ts +2 -2
  145. package/dist/types/src/components/Thread/Thread.d.ts.map +1 -1
  146. package/dist/types/src/components/Thread/Thread.stories.d.ts.map +1 -1
  147. package/dist/types/src/components/Thread/ThreadContainer.d.ts +1 -1
  148. package/dist/types/src/components/Thread/ThreadContainer.d.ts.map +1 -1
  149. package/dist/types/src/components/Thread/ThreadContainer.stories.d.ts +2 -2
  150. package/dist/types/src/components/Thread/ThreadContainer.stories.d.ts.map +1 -1
  151. package/dist/types/src/components/Thread/ThreadMessage.d.ts +4 -2
  152. package/dist/types/src/components/Thread/ThreadMessage.d.ts.map +1 -1
  153. package/dist/types/src/components/Thread/ToolInvocations.d.ts +1 -1
  154. package/dist/types/src/components/Thread/ToolInvocations.d.ts.map +1 -1
  155. package/dist/types/src/components/Thread/reducer.d.ts +1 -1
  156. package/dist/types/src/components/Thread/reducer.d.ts.map +1 -1
  157. package/dist/types/src/components/Toolbox/Toolbox.d.ts +3 -2
  158. package/dist/types/src/components/Toolbox/Toolbox.d.ts.map +1 -1
  159. package/dist/types/src/components/index.d.ts +4 -6
  160. package/dist/types/src/components/index.d.ts.map +1 -1
  161. package/dist/types/src/experimental/transcription/index.d.ts +1 -0
  162. package/dist/types/src/experimental/transcription/index.d.ts.map +1 -0
  163. package/dist/types/src/hooks/index.d.ts +0 -1
  164. package/dist/types/src/hooks/index.d.ts.map +1 -1
  165. package/dist/types/src/hooks/processor.d.ts +6 -5
  166. package/dist/types/src/hooks/processor.d.ts.map +1 -1
  167. package/dist/types/src/hooks/useChatProcessor.d.ts.map +1 -1
  168. package/dist/types/src/hooks/useContextProvider.d.ts +1 -1
  169. package/dist/types/src/hooks/useContextProvider.d.ts.map +1 -1
  170. package/dist/types/src/hooks/useMessageQueue.d.ts +11 -10
  171. package/dist/types/src/hooks/useMessageQueue.d.ts.map +1 -1
  172. package/dist/types/src/hooks/useServices.d.ts.map +1 -1
  173. package/dist/types/src/hooks/useTextInputEvents.d.ts.map +1 -1
  174. package/dist/types/src/parser/filter-generator.d.ts +4 -0
  175. package/dist/types/src/parser/filter-generator.d.ts.map +1 -0
  176. package/dist/types/src/parser/filter-generator.test.d.ts +2 -0
  177. package/dist/types/src/parser/filter-generator.test.d.ts.map +1 -0
  178. package/dist/types/src/parser/index.d.ts +4 -0
  179. package/dist/types/src/parser/index.d.ts.map +1 -0
  180. package/dist/types/src/parser/query-parser.d.ts +15 -0
  181. package/dist/types/src/parser/query-parser.d.ts.map +1 -0
  182. package/dist/types/src/parser/query-parser.test.d.ts +2 -0
  183. package/dist/types/src/parser/query-parser.test.d.ts.map +1 -0
  184. package/dist/types/src/parser/types.d.ts +24 -0
  185. package/dist/types/src/parser/types.d.ts.map +1 -0
  186. package/dist/types/src/stories/Prompt.stories.d.ts +8 -0
  187. package/dist/types/src/stories/Prompt.stories.d.ts.map +1 -0
  188. package/dist/types/src/stories/Query.stories.d.ts +19 -0
  189. package/dist/types/src/stories/Query.stories.d.ts.map +1 -0
  190. package/dist/types/src/stories/Research.stories.d.ts +15 -0
  191. package/dist/types/src/stories/Research.stories.d.ts.map +1 -0
  192. package/dist/types/src/stories/test-data.d.ts +3 -0
  193. package/dist/types/src/stories/test-data.d.ts.map +1 -0
  194. package/dist/types/src/stories/testing.d.ts +12 -0
  195. package/dist/types/src/stories/testing.d.ts.map +1 -0
  196. package/dist/types/src/testing/blueprint.d.ts +7 -0
  197. package/dist/types/src/testing/blueprint.d.ts.map +1 -0
  198. package/dist/types/src/testing/index.d.ts +1 -0
  199. package/dist/types/src/testing/index.d.ts.map +1 -1
  200. package/dist/types/src/testing/test-functions.d.ts +1 -1
  201. package/dist/types/src/testing/test-functions.d.ts.map +1 -1
  202. package/dist/types/src/tools/function.d.ts +4 -4
  203. package/dist/types/src/tools/function.d.ts.map +1 -1
  204. package/dist/types/src/tools/openapi.d.ts +3 -3
  205. package/dist/types/src/tools/openapi.d.ts.map +1 -1
  206. package/dist/types/src/translations.d.ts +6 -0
  207. package/dist/types/src/translations.d.ts.map +1 -1
  208. package/dist/types/src/types/chat.d.ts +18 -8
  209. package/dist/types/src/types/chat.d.ts.map +1 -1
  210. package/dist/types/src/types/service.d.ts +96 -95
  211. package/dist/types/src/types/service.d.ts.map +1 -1
  212. package/dist/types/src/types/template.d.ts +52 -52
  213. package/dist/types/src/types/template.d.ts.map +1 -1
  214. package/dist/types/src/types/types.d.ts +25 -20
  215. package/dist/types/src/types/types.d.ts.map +1 -1
  216. package/dist/types/tsconfig.tsbuildinfo +1 -1
  217. package/package.json +79 -61
  218. package/src/AssistantPlugin.tsx +7 -6
  219. package/src/capabilities/ai-client.ts +5 -6
  220. package/src/capabilities/app-graph-builder.ts +173 -135
  221. package/src/capabilities/capabilities.ts +1 -1
  222. package/src/capabilities/index.ts +1 -1
  223. package/src/capabilities/intent-resolver.ts +7 -9
  224. package/src/capabilities/react-surface.tsx +63 -16
  225. package/src/capabilities/settings.ts +2 -2
  226. package/src/components/AmbientDialog/AmbientDialog.stories.tsx +2 -2
  227. package/src/components/AmbientDialog/AmbientDialog.tsx +27 -13
  228. package/src/components/AssistantDialog.tsx +1 -1
  229. package/src/components/AssistantSettings/AssistantSettings.tsx +29 -7
  230. package/src/components/BlueprintEditor/BlueprintEditor.stories.tsx +32 -0
  231. package/src/components/BlueprintEditor/BlueprintEditor.tsx +41 -0
  232. package/src/components/BlueprintEditor/index.ts +5 -0
  233. package/src/components/ChatContainer.tsx +6 -8
  234. package/src/components/Prompt/Prompt.stories.tsx +59 -52
  235. package/src/components/Prompt/Prompt.tsx +24 -10
  236. package/src/components/Prompt/PromptBar.stories.tsx +68 -0
  237. package/src/components/Prompt/PromptBar.tsx +82 -88
  238. package/src/components/Prompt/autocomplete.ts +14 -8
  239. package/src/components/Prompt/references.ts +3 -3
  240. package/src/components/PromptSettings.tsx +91 -0
  241. package/src/components/TemplateContainer.tsx +3 -79
  242. package/src/components/TemplateEditor/TemplateEditor.stories.tsx +4 -4
  243. package/src/components/TemplateEditor/TemplateForm.stories.tsx +3 -3
  244. package/src/components/TemplateEditor/TemplateForm.tsx +2 -2
  245. package/src/components/Thread/Thread.stories.tsx +14 -17
  246. package/src/components/Thread/Thread.tsx +2 -2
  247. package/src/components/Thread/ThreadContainer.stories.tsx +83 -62
  248. package/src/components/Thread/ThreadContainer.tsx +26 -5
  249. package/src/components/Thread/ThreadMessage.tsx +49 -11
  250. package/src/components/Thread/ToolInvocations.tsx +9 -7
  251. package/src/components/Thread/reducer.ts +1 -1
  252. package/src/components/Toolbox/Toolbox.stories.tsx +4 -4
  253. package/src/components/Toolbox/Toolbox.tsx +5 -4
  254. package/src/components/index.ts +3 -1
  255. package/src/experimental/transcription/index.ts +3 -0
  256. package/src/hooks/index.ts +0 -1
  257. package/src/hooks/processor.ts +68 -8
  258. package/src/hooks/useChatProcessor.tsx +12 -11
  259. package/src/hooks/useContextProvider.ts +21 -17
  260. package/src/hooks/useMessageQueue.ts +5 -5
  261. package/src/meta.ts +2 -2
  262. package/src/parser/filter-generator.test.ts +32 -0
  263. package/src/parser/filter-generator.ts +81 -0
  264. package/src/parser/index.ts +7 -0
  265. package/src/parser/query-parser.test.ts +139 -0
  266. package/src/parser/query-parser.ts +199 -0
  267. package/src/parser/types.ts +34 -0
  268. package/src/shims.d.ts +8 -0
  269. package/src/stories/Prompt.stories.tsx +59 -0
  270. package/src/stories/Query.stories.tsx +448 -0
  271. package/src/stories/Research.stories.tsx +495 -0
  272. package/src/stories/test-data.ts +128 -0
  273. package/src/stories/testing.ts +64 -0
  274. package/src/testing/blueprint.ts +47 -0
  275. package/src/testing/index.ts +1 -0
  276. package/src/testing/test-functions.ts +1 -1
  277. package/src/testing/test-services.ts +6 -6
  278. package/src/tools/function.ts +11 -12
  279. package/src/tools/openapi.test.ts +18 -19
  280. package/src/tools/openapi.ts +24 -17
  281. package/src/translations.ts +9 -6
  282. package/src/types/chat.ts +27 -4
  283. package/src/types/service.ts +39 -37
  284. package/src/types/template.ts +27 -25
  285. package/src/types/types.ts +22 -17
  286. package/dist/lib/browser/AssistantDialog-YSHMAHW5.mjs +0 -117
  287. package/dist/lib/browser/AssistantDialog-YSHMAHW5.mjs.map +0 -7
  288. package/dist/lib/browser/ChatContainer-V5GP7DYF.mjs +0 -33
  289. package/dist/lib/browser/ChatContainer-V5GP7DYF.mjs.map +0 -7
  290. package/dist/lib/browser/TemplateContainer-K4EJNGIL.mjs +0 -78
  291. package/dist/lib/browser/TemplateContainer-K4EJNGIL.mjs.map +0 -7
  292. package/dist/lib/browser/ai-client-CDZLSNXE.mjs.map +0 -7
  293. package/dist/lib/browser/app-graph-builder-MF5EVDWW.mjs +0 -209
  294. package/dist/lib/browser/app-graph-builder-MF5EVDWW.mjs.map +0 -7
  295. package/dist/lib/browser/chunk-FMB7RGMP.mjs.map +0 -7
  296. package/dist/lib/browser/chunk-IAMR2FAE.mjs +0 -183
  297. package/dist/lib/browser/chunk-IAMR2FAE.mjs.map +0 -7
  298. package/dist/lib/browser/chunk-KYMKVE6M.mjs +0 -128
  299. package/dist/lib/browser/chunk-KYMKVE6M.mjs.map +0 -7
  300. package/dist/lib/browser/chunk-NFUHCW2J.mjs +0 -81
  301. package/dist/lib/browser/chunk-TXJWGWJ7.mjs.map +0 -7
  302. package/dist/lib/browser/intent-resolver-WJGLKKVO.mjs.map +0 -7
  303. package/dist/lib/browser/react-surface-57VRDOQT.mjs +0 -90
  304. package/dist/lib/browser/react-surface-57VRDOQT.mjs.map +0 -7
  305. package/dist/lib/browser/settings-U6UFQX32.mjs.map +0 -7
  306. package/dist/lib/node/AssistantDialog-YI2BSGSX.cjs +0 -141
  307. package/dist/lib/node/AssistantDialog-YI2BSGSX.cjs.map +0 -7
  308. package/dist/lib/node/ChatContainer-ZJ5JXF6A.cjs.map +0 -7
  309. package/dist/lib/node/TemplateContainer-XWFYJB4T.cjs +0 -104
  310. package/dist/lib/node/TemplateContainer-XWFYJB4T.cjs.map +0 -7
  311. package/dist/lib/node/ai-client-URCCYU6B.cjs.map +0 -7
  312. package/dist/lib/node/app-graph-builder-N5ZUUI2Z.cjs +0 -220
  313. package/dist/lib/node/app-graph-builder-N5ZUUI2Z.cjs.map +0 -7
  314. package/dist/lib/node/chunk-APRU3QWK.cjs +0 -206
  315. package/dist/lib/node/chunk-APRU3QWK.cjs.map +0 -7
  316. package/dist/lib/node/chunk-GBUNQ257.cjs.map +0 -7
  317. package/dist/lib/node/chunk-RPBKMP2E.cjs.map +0 -7
  318. package/dist/lib/node/chunk-ZKOC4ZFY.cjs +0 -152
  319. package/dist/lib/node/chunk-ZKOC4ZFY.cjs.map +0 -7
  320. package/dist/lib/node/intent-resolver-R3OSTIMH.cjs.map +0 -7
  321. package/dist/lib/node/react-surface-NUQTM6MS.cjs +0 -106
  322. package/dist/lib/node/react-surface-NUQTM6MS.cjs.map +0 -7
  323. package/dist/lib/node/settings-TXGRCYAL.cjs.map +0 -7
  324. package/dist/lib/node-esm/AssistantDialog-U2FQX5TD.mjs +0 -118
  325. package/dist/lib/node-esm/AssistantDialog-U2FQX5TD.mjs.map +0 -7
  326. package/dist/lib/node-esm/ChatContainer-QW3OOXTT.mjs +0 -34
  327. package/dist/lib/node-esm/ChatContainer-QW3OOXTT.mjs.map +0 -7
  328. package/dist/lib/node-esm/TemplateContainer-EUM2X65J.mjs +0 -79
  329. package/dist/lib/node-esm/TemplateContainer-EUM2X65J.mjs.map +0 -7
  330. package/dist/lib/node-esm/ai-client-WMHS5EGV.mjs.map +0 -7
  331. package/dist/lib/node-esm/app-graph-builder-DWBNIMHM.mjs +0 -210
  332. package/dist/lib/node-esm/app-graph-builder-DWBNIMHM.mjs.map +0 -7
  333. package/dist/lib/node-esm/chunk-6JK5HEUQ.mjs.map +0 -7
  334. package/dist/lib/node-esm/chunk-GBBXIW5F.mjs +0 -129
  335. package/dist/lib/node-esm/chunk-GBBXIW5F.mjs.map +0 -7
  336. package/dist/lib/node-esm/chunk-MVDAY3CZ.mjs.map +0 -7
  337. package/dist/lib/node-esm/chunk-MXK2EANZ.mjs +0 -184
  338. package/dist/lib/node-esm/chunk-MXK2EANZ.mjs.map +0 -7
  339. package/dist/lib/node-esm/intent-resolver-H32TL4X6.mjs.map +0 -7
  340. package/dist/lib/node-esm/react-surface-JBVZF6CP.mjs +0 -91
  341. package/dist/lib/node-esm/react-surface-JBVZF6CP.mjs.map +0 -7
  342. package/dist/lib/node-esm/settings-DZU5PNXM.mjs.map +0 -7
  343. package/dist/types/src/components/ServiceRegistry/ServiceRegistry.d.ts +0 -6
  344. package/dist/types/src/components/ServiceRegistry/ServiceRegistry.d.ts.map +0 -1
  345. package/dist/types/src/components/ServiceRegistry/ServiceRegistry.stories.d.ts +0 -8
  346. package/dist/types/src/components/ServiceRegistry/ServiceRegistry.stories.d.ts.map +0 -1
  347. package/dist/types/src/components/ServiceRegistry/index.d.ts +0 -2
  348. package/dist/types/src/components/ServiceRegistry/index.d.ts.map +0 -1
  349. package/dist/types/src/hooks/invocation-handler.d.ts +0 -5
  350. package/dist/types/src/hooks/invocation-handler.d.ts.map +0 -1
  351. package/dist/types/src/hooks/useLocalTriggerManager.d.ts +0 -3
  352. package/dist/types/src/hooks/useLocalTriggerManager.d.ts.map +0 -1
  353. package/src/components/ServiceRegistry/ServiceRegistry.stories.tsx +0 -49
  354. package/src/components/ServiceRegistry/ServiceRegistry.tsx +0 -76
  355. package/src/components/ServiceRegistry/index.ts +0 -5
  356. package/src/hooks/invocation-handler.ts +0 -107
  357. package/src/hooks/useLocalTriggerManager.ts +0 -82
@@ -1,1396 +1,1503 @@
1
1
  import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
2
  import {
3
3
  AssistantCapabilities
4
- } from "./chunk-6JK5HEUQ.mjs";
4
+ } from "./chunk-HLPGKJ7N.mjs";
5
5
  import {
6
6
  ServiceType,
7
7
  categoryIcons
8
- } from "./chunk-MXK2EANZ.mjs";
8
+ } from "./chunk-ZKBACPIW.mjs";
9
9
  import {
10
10
  ASSISTANT_PLUGIN
11
- } from "./chunk-ECRK6TUQ.mjs";
11
+ } from "./chunk-BB2TAT4P.mjs";
12
12
 
13
- // packages/plugins/plugin-assistant/src/components/Toolbox/Toolbox.tsx
14
- import React, { useState, useEffect, Fragment } from "react";
15
- import { Capabilities, useCapabilities } from "@dxos/app-framework";
16
- import { parseToolName } from "@dxos/artifact";
17
- import { FunctionType } from "@dxos/functions/types";
18
- import { log as log3 } from "@dxos/log";
19
- import { Filter, useQuery } from "@dxos/react-client/echo";
13
+ // packages/plugins/plugin-assistant/src/components/Prompt/Prompt.tsx
14
+ import { useSignals as _useSignals } from "@preact-signals/safe-react/tracking";
15
+ import { Prec as Prec2 } from "@codemirror/state";
16
+ import React, { forwardRef, useImperativeHandle } from "react";
17
+ import { useThemeContext } from "@dxos/react-ui";
18
+ import { createBasicExtensions, createThemeExtensions, keymap as keymap3, useTextEditor } from "@dxos/react-ui-editor";
20
19
  import { mx } from "@dxos/react-ui-theme";
20
+ import { isNonNullable } from "@dxos/util";
21
21
 
22
- // packages/plugins/plugin-assistant/src/tools/function.ts
23
- import { defineTool, ToolResult } from "@dxos/artifact";
24
- import { toEffectSchema } from "@dxos/echo-schema";
25
- import { getInvocationUrl, getUserFunctionUrlInMetadata } from "@dxos/functions/types";
26
- import { log } from "@dxos/log";
27
- import { getMeta } from "@dxos/react-client/echo";
28
- var __dxlog_file = "/home/runner/work/dxos/dxos/packages/plugins/plugin-assistant/src/tools/function.ts";
29
- var covertFunctionToTool = (fn, edgeUrl, spaceId) => {
30
- if (!fn.description || !fn.inputSchema) {
31
- return void 0;
32
- }
33
- const existingFunctionUrl = getUserFunctionUrlInMetadata(getMeta(fn));
34
- if (!existingFunctionUrl) {
35
- return void 0;
36
- }
37
- const url = getInvocationUrl(existingFunctionUrl, edgeUrl, {
38
- spaceId
39
- });
40
- return defineTool("user-function", {
41
- name: fn.name,
42
- description: fn.description,
43
- schema: toEffectSchema(fn.inputSchema),
44
- execute: async (input) => {
45
- log.info("execute function tool", {
46
- name: fn.name,
47
- url,
48
- input
49
- }, {
50
- F: __dxlog_file,
51
- L: 36,
52
- S: void 0,
53
- C: (f, a) => f(...a)
54
- });
55
- const response = await fetch(url, {
56
- method: "POST",
57
- headers: {
58
- "Content-Type": "application/json"
22
+ // packages/plugins/plugin-assistant/src/components/Prompt/autocomplete.ts
23
+ import { Prec } from "@codemirror/state";
24
+ import { EditorView, Decoration, ViewPlugin, keymap, WidgetType } from "@codemirror/view";
25
+ var autocompleteExtension = ({ onSubmit, onSuggest, onCancel }) => {
26
+ const suggest = ViewPlugin.fromClass(class {
27
+ constructor(view) {
28
+ this._currentSuggestion = null;
29
+ this._decorations = this.computeDecorations(view);
30
+ }
31
+ update(update) {
32
+ if (update.docChanged || update.selectionSet) {
33
+ this._decorations = this.computeDecorations(update.view);
34
+ }
35
+ }
36
+ computeDecorations(view) {
37
+ const text = view.state.doc.toString();
38
+ const suggestions = onSuggest?.(text) ?? [];
39
+ if (!suggestions.length) {
40
+ this._currentSuggestion = null;
41
+ return Decoration.none;
42
+ }
43
+ this._currentSuggestion = suggestions[0];
44
+ const suffix = this._currentSuggestion.slice(text.length);
45
+ if (!suffix) {
46
+ return Decoration.none;
47
+ }
48
+ return Decoration.set([
49
+ Decoration.widget({
50
+ widget: new InlineSuggestionWidget(suffix),
51
+ side: 1
52
+ }).range(view.state.doc.length)
53
+ ]);
54
+ }
55
+ completeSuggestion(view) {
56
+ if (!this._currentSuggestion) {
57
+ return false;
58
+ }
59
+ const text = view.state.doc.toString();
60
+ const suffix = this._currentSuggestion.slice(text.length);
61
+ if (!suffix) {
62
+ return false;
63
+ }
64
+ view.dispatch({
65
+ changes: {
66
+ from: view.state.doc.length,
67
+ insert: suffix
59
68
  },
60
- body: JSON.stringify(input)
69
+ selection: {
70
+ anchor: view.state.doc.length + suffix.length
71
+ }
61
72
  });
62
- return ToolResult.Success(await response.text());
73
+ return true;
63
74
  }
64
- });
65
- };
66
-
67
- // packages/plugins/plugin-assistant/src/tools/openapi.ts
68
- import jsonpointer from "jsonpointer";
69
- import { ToolResult as ToolResult2 } from "@dxos/artifact";
70
- import { JsonSchemaType, normalizeSchema, S, toEffectSchema as toEffectSchema2 } from "@dxos/echo-schema";
71
- import { invariant } from "@dxos/invariant";
72
- import { log as log2 } from "@dxos/log";
73
- import { deepMapValues } from "@dxos/util";
74
- var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-assistant/src/tools/openapi.ts";
75
- var createToolsFromService = async (service) => {
76
- invariant(service.interfaces?.length === 1 && service.interfaces[0].kind === "api", void 0, {
77
- F: __dxlog_file2,
78
- L: 22,
79
- S: void 0,
80
- A: [
81
- "service.interfaces?.length === 1 && service.interfaces[0].kind === 'api'",
82
- ""
83
- ]
84
- });
85
- const iface = service.interfaces[0];
86
- invariant(iface.schemaUrl, void 0, {
87
- F: __dxlog_file2,
88
- L: 24,
89
- S: void 0,
90
- A: [
91
- "iface.schemaUrl",
92
- ""
93
- ]
94
- });
95
- invariant(iface.schemaUrl, void 0, {
96
- F: __dxlog_file2,
97
- L: 25,
98
- S: void 0,
99
- A: [
100
- "iface.schemaUrl",
101
- ""
102
- ]
103
- });
104
- return createToolsFromApi(iface.schemaUrl, {
105
- authorization: iface.authorization
106
- });
107
- };
108
- var createToolsFromApi = async (url, options) => {
109
- const res = await fetch(url);
110
- const spec = await res.json();
111
- log2("spec", {
112
- spec
113
75
  }, {
114
- F: __dxlog_file2,
115
- L: 32,
116
- S: void 0,
117
- C: (f, a) => f(...a)
76
+ decorations: (v) => v._decorations
118
77
  });
119
- const tools = [];
120
- for (const [path, pathItem] of Object.entries(spec.paths)) {
121
- if (typeof pathItem !== "object") {
122
- continue;
123
- }
124
- const { ...methods } = pathItem;
125
- for (const [method, m] of Object.entries(methods)) {
126
- const methodItem = m;
127
- log2("methodItem", {
128
- path,
129
- method,
130
- methodItem
131
- }, {
132
- F: __dxlog_file2,
133
- L: 44,
134
- S: void 0,
135
- C: (f, a) => f(...a)
136
- });
137
- const parametersResolved = methodItem.parameters?.map((parameter) => {
138
- const resolved = resolveJsonSchema(parameter, spec);
139
- return resolved;
140
- }) ?? [];
141
- const inputSchema = {
142
- type: "object",
143
- properties: {}
144
- };
145
- const endpointParameters = [];
146
- for (const parameter of parametersResolved) {
147
- log2("parameter", {
148
- parameter
149
- }, {
150
- F: __dxlog_file2,
151
- L: 59,
152
- S: void 0,
153
- C: (f, a) => f(...a)
154
- });
155
- if (options?.authorization?.type === "api-key" && options.authorization.placement.type === "query" && parameter.in === "query" && parameter.name === options.authorization.placement.name) {
156
- continue;
78
+ return [
79
+ suggest,
80
+ EditorView.theme({
81
+ ".cm-inline-suggestion": {
82
+ opacity: 0.4
83
+ }
84
+ }),
85
+ Prec.highest(keymap.of([
86
+ {
87
+ key: "Tab",
88
+ preventDefault: true,
89
+ run: (view) => {
90
+ const plugin = view.plugin(suggest);
91
+ return plugin?.completeSuggestion(view) ?? false;
157
92
  }
158
- endpointParameters.push(parameter);
159
- if (parameter.schema) {
160
- inputSchema.properties[parameter.name] = normalizeSchema(parameter.schema);
161
- } else if (typeof parameter.type === "string") {
162
- const { name, in: _in, required, ...schema } = parameter;
163
- inputSchema.properties[name] = normalizeSchema(schema);
164
- if (required) {
165
- inputSchema.required ??= [];
166
- inputSchema.required.push(name);
93
+ },
94
+ {
95
+ key: "ArrowRight",
96
+ preventDefault: true,
97
+ run: (view) => {
98
+ if (view.state.selection.main.head !== view.state.doc.length) {
99
+ return false;
167
100
  }
101
+ const plugin = view.plugin(suggest);
102
+ return plugin?.completeSuggestion(view) ?? false;
103
+ }
104
+ },
105
+ {
106
+ key: "Enter",
107
+ preventDefault: true,
108
+ run: (view) => {
109
+ const text = view.state.doc.toString().trim();
110
+ if (text.length > 0 && onSubmit) {
111
+ const reset = onSubmit(text);
112
+ if (reset) {
113
+ view.dispatch({
114
+ changes: {
115
+ from: 0,
116
+ to: view.state.doc.length,
117
+ insert: ""
118
+ }
119
+ });
120
+ }
121
+ }
122
+ return true;
123
+ }
124
+ },
125
+ {
126
+ key: "Shift-Enter",
127
+ preventDefault: true,
128
+ run: (view) => {
129
+ view.dispatch({
130
+ changes: {
131
+ from: view.state.selection.main.head,
132
+ insert: "\n"
133
+ },
134
+ selection: {
135
+ anchor: view.state.selection.main.head + 1,
136
+ head: view.state.selection.main.head + 1
137
+ }
138
+ });
139
+ return true;
140
+ }
141
+ },
142
+ {
143
+ key: "Escape",
144
+ preventDefault: true,
145
+ run: (view) => {
146
+ view.dispatch({
147
+ changes: {
148
+ from: 0,
149
+ to: view.state.doc.length,
150
+ insert: ""
151
+ }
152
+ });
153
+ onCancel?.();
154
+ return true;
168
155
  }
169
156
  }
170
- log2("inputSchema", {
171
- inputSchema
172
- }, {
173
- F: __dxlog_file2,
174
- L: 84,
175
- S: void 0,
176
- C: (f, a) => f(...a)
157
+ ]))
158
+ ];
159
+ };
160
+ var InlineSuggestionWidget = class extends WidgetType {
161
+ constructor(suffix) {
162
+ super(), this.suffix = suffix;
163
+ }
164
+ toDOM() {
165
+ const span = document.createElement("span");
166
+ span.textContent = this.suffix;
167
+ span.className = "cm-inline-suggestion";
168
+ return span;
169
+ }
170
+ eq(other) {
171
+ return other.suffix === this.suffix;
172
+ }
173
+ };
174
+
175
+ // packages/plugins/plugin-assistant/src/components/Prompt/references.ts
176
+ import { autocompletion, completionKeymap } from "@codemirror/autocomplete";
177
+ import { RangeSet } from "@codemirror/state";
178
+ import { Decoration as Decoration2, EditorView as EditorView2, keymap as keymap2, ViewPlugin as ViewPlugin2, WidgetType as WidgetType2 } from "@codemirror/view";
179
+ import { Mutex } from "@dxos/async";
180
+ var promptReferences = ({ provider, debug = false, triggerCharacter = "@" }) => {
181
+ if (triggerCharacter.length !== 1) {
182
+ throw new Error("triggerCharacter must be a single character");
183
+ }
184
+ const decorationField = ViewPlugin2.fromClass(class ReferenceView {
185
+ constructor(view) {
186
+ this._mutex = new Mutex();
187
+ this.decorations = Decoration2.set([]);
188
+ queueMicrotask(async () => {
189
+ const guard = await this._mutex.acquire();
190
+ try {
191
+ this.decorations = await this._computeDecorations(view);
192
+ } finally {
193
+ guard.release();
194
+ }
177
195
  });
178
- S.validateSync(JsonSchemaType)(inputSchema);
179
- const description = methodItem.description ?? methodItem.summary;
180
- if (!description) {
181
- log2.warn("no description", {
182
- path,
183
- method
184
- }, {
185
- F: __dxlog_file2,
186
- L: 89,
187
- S: void 0,
188
- C: (f, a) => f(...a)
196
+ }
197
+ update(update) {
198
+ if (update.docChanged) {
199
+ queueMicrotask(async () => {
200
+ const guard = await this._mutex.acquire();
201
+ try {
202
+ this.decorations = await this._computeDecorations(update.view);
203
+ } finally {
204
+ guard.release();
205
+ }
206
+ });
207
+ }
208
+ }
209
+ async _computeDecorations(view) {
210
+ const text = view.state.doc.toString();
211
+ const references = text.matchAll(new RegExp(`${triggerCharacter}[a-zA-Z0-9@:]+\\s`, "g"));
212
+ const decorations = [];
213
+ for (const match of references) {
214
+ const reference = match[0];
215
+ const uri = reference.slice(1, -1);
216
+ const data = await provider.resolveReference({
217
+ uri
189
218
  });
190
- continue;
191
- }
192
- const endpoint = {
193
- document: spec,
194
- path,
195
- method,
196
- parameters: endpointParameters,
197
- authorization: options?.authorization
198
- };
199
- tools.push({
200
- name: getToolName(path, method, methodItem),
201
- description: options?.instructions ? `${options.instructions}
202
-
203
- ${description}` : description,
204
- parameters: inputSchema,
205
- execute: async (input) => {
206
- const response = await callApiEndpoint(endpoint, input);
207
- return ToolResult2.Success(response);
219
+ if (data) {
220
+ decorations.push(Decoration2.replace({
221
+ widget: new ReferenceWidget(data)
222
+ }).range(match.index, match.index + reference.length));
208
223
  }
209
- });
210
- }
211
- }
212
- return tools;
213
- };
214
- var getToolName = (path, method, methodItem) => {
215
- if (methodItem.operationId) {
216
- return methodItem.operationId;
217
- }
218
- let name = `${method.toLowerCase()}_${path.replaceAll(/[{}/]/g, "_")}`;
219
- while (name.length > MAX_TOOL_NAME_LENGTH) {
220
- const lengthBefore = name.length;
221
- for (const word of GENERIC_WORDS) {
222
- if (name.includes(word)) {
223
- name = name.replace(word, "");
224
- break;
225
224
  }
225
+ return Decoration2.set(decorations);
226
226
  }
227
- name = name.replaceAll("__", "_").replace(/_$/, "");
228
- const lengthAfter = name.length;
229
- if (lengthBefore === lengthAfter) {
230
- break;
231
- }
232
- }
233
- name = name.replaceAll("__", "_").replace(/_$/, "").replace(/^_/, "");
234
- return name.slice(0, MAX_TOOL_NAME_LENGTH);
235
- };
236
- var MAX_TOOL_NAME_LENGTH = 64;
237
- var GENERIC_WORDS = [
238
- "services",
239
- "service",
240
- "api",
241
- "rest",
242
- "endpoint",
243
- "get",
244
- "post",
245
- "put",
246
- "delete",
247
- "patch",
248
- "head",
249
- "options",
250
- "trace",
251
- "service",
252
- "api",
253
- "endpoint"
254
- ];
255
- var callApiEndpoint = async (endpoint, input) => {
256
- log2.info("endpoint", {
257
- method: endpoint.method,
258
- name: endpoint.path,
259
- input
260
227
  }, {
261
- F: __dxlog_file2,
262
- L: 173,
263
- S: void 0,
264
- C: (f, a) => f(...a)
228
+ decorations: (v) => v.decorations,
229
+ provide: (plugin) => [
230
+ EditorView2.atomicRanges.of((view) => view.plugin(decorationField)?.decorations ?? RangeSet.empty)
231
+ ]
265
232
  });
266
- let url = getEndpointUrl(endpoint);
267
- const request = {
268
- method: endpoint.method,
269
- headers: {}
270
- };
271
- const query = new URLSearchParams();
272
- let body;
273
- for (const parameter of endpoint.parameters) {
274
- if (input[parameter.name] === void 0) {
275
- continue;
276
- }
277
- switch (parameter.in) {
278
- case "header": {
279
- if (parameter.example) {
280
- request.headers[parameter.name] = parameter.default;
281
- }
282
- break;
283
- }
284
- case "path": {
285
- url = url.replace(`{${parameter.name}}`, encodeURIComponent(input[parameter.name]));
286
- break;
233
+ return [
234
+ decorationField,
235
+ EditorView2.theme({
236
+ ".cm-reference-pill": {
237
+ borderRadius: "0.25rem",
238
+ borderWidth: "1px",
239
+ marginRight: "0.25rem",
240
+ marginLeft: "0.25rem"
287
241
  }
288
- case "body": {
289
- const value = input[parameter.name];
290
- const effectSchema = toEffectSchema2(parameter.schema);
291
- S.validateSync(effectSchema)(value);
292
- if (body) {
293
- throw new Error(`Duplicate body parameter: ${parameter.name}`);
242
+ }),
243
+ autocompletion({
244
+ activateOnTyping: true,
245
+ override: [
246
+ async (context) => {
247
+ const match = context.matchBefore(new RegExp(`${triggerCharacter}[a-zA-Z0-9]+`));
248
+ if (!match || match?.to === match?.from) {
249
+ return null;
250
+ }
251
+ const query = match.text.slice(1);
252
+ const references = await provider.getReferences({
253
+ query
254
+ });
255
+ return {
256
+ from: match.from,
257
+ filter: false,
258
+ options: references.map((reference) => ({
259
+ label: reference.label,
260
+ apply: `${triggerCharacter}${reference.uri} `
261
+ }))
262
+ };
294
263
  }
295
- body = value;
296
- break;
297
- }
298
- case "query": {
299
- query.set(parameter.name, input[parameter.name]);
300
- break;
301
- }
302
- }
303
- }
304
- if (endpoint.authorization?.type === "api-key" && endpoint.authorization.placement.type === "authorization-header" || endpoint.authorization?.type === "oauth") {
305
- request.headers.Authorization = await resolveAuthorization(endpoint.authorization);
306
- } else if (endpoint.authorization?.type === "api-key" && endpoint.authorization.placement.type === "query") {
307
- query.set(endpoint.authorization.placement.name, endpoint.authorization.key);
264
+ ],
265
+ closeOnBlur: !debug,
266
+ tooltipClass: () => "shadow rounded",
267
+ aboveCursor: true
268
+ }),
269
+ keymap2.of(completionKeymap)
270
+ ];
271
+ };
272
+ var ReferenceWidget = class extends WidgetType2 {
273
+ constructor(data) {
274
+ super(), this.data = data;
308
275
  }
309
- if (query.size > 0) {
310
- url += `?${query.toString()}`;
276
+ toDOM() {
277
+ const span = document.createElement("span");
278
+ span.textContent = `@ ${this.data.label}`;
279
+ span.className = "cm-reference-pill";
280
+ return span;
311
281
  }
312
- if (body) {
313
- request.body = JSON.stringify(body);
314
- request.headers["Content-Type"] = "application/json";
282
+ eq(other) {
283
+ return other.data.uri === this.data.uri;
315
284
  }
316
- log2.info("request", {
317
- url,
318
- request
319
- }, {
320
- F: __dxlog_file2,
321
- L: 236,
322
- S: void 0,
323
- C: (f, a) => f(...a)
324
- });
325
- const response = await fetch(url, request);
326
- log2.info("response", {
327
- ok: response.ok,
328
- status: response.status,
329
- statusText: response.statusText
330
- }, {
331
- F: __dxlog_file2,
332
- L: 239,
333
- S: void 0,
334
- C: (f, a) => f(...a)
335
- });
336
- if (response.ok) {
337
- const contentType = response.headers.get("Content-Type");
338
- if (contentType?.includes("application/json")) {
339
- return await response.json();
340
- } else {
341
- return await response.text();
342
- }
343
- } else {
344
- if (response.headers.get("Content-Type")?.includes("application/json")) {
345
- const responseBody = await response.text();
346
- let error;
347
- try {
348
- error = JSON.parse(responseBody);
349
- } catch {
350
- error = responseBody;
351
- }
352
- log2.error("error", {
353
- error
354
- }, {
355
- F: __dxlog_file2,
356
- L: 257,
357
- S: void 0,
358
- C: (f, a) => f(...a)
359
- });
360
- throw new Error(error.message);
361
- } else {
362
- const error = await response.text();
363
- log2.error("error", {
364
- error
365
- }, {
366
- F: __dxlog_file2,
367
- L: 261,
368
- S: void 0,
369
- C: (f, a) => f(...a)
370
- });
371
- throw new Error(error);
372
- }
285
+ ignoreEvent() {
286
+ return true;
373
287
  }
374
288
  };
375
- var getEndpointUrl = (endpoint) => {
376
- let url = "";
377
- if (isV3_1(endpoint.document) && endpoint.document.servers && endpoint.document.servers.length > 0) {
378
- url = endpoint.document.servers[0].url;
379
- } else {
380
- invariant(!isV3_1(endpoint.document), void 0, {
381
- F: __dxlog_file2,
382
- L: 272,
383
- S: void 0,
384
- A: [
385
- "!isV3_1(endpoint.document)",
386
- ""
387
- ]
289
+
290
+ // packages/plugins/plugin-assistant/src/components/Prompt/Prompt.tsx
291
+ var Prompt = /* @__PURE__ */ forwardRef(({ classNames, extensions, references, autoFocus, lineWrapping = false, placeholder, onSubmit, onSuggest, onCancel, onOpenChange }, forwardRef3) => {
292
+ var _effect = _useSignals();
293
+ try {
294
+ const { themeMode } = useThemeContext();
295
+ const { parentRef, view } = useTextEditor({
296
+ debug: true,
297
+ autoFocus,
298
+ extensions: [
299
+ autocompleteExtension({
300
+ onSubmit,
301
+ onSuggest,
302
+ onCancel
303
+ }),
304
+ createBasicExtensions({
305
+ bracketMatching: false,
306
+ lineWrapping,
307
+ placeholder
308
+ }),
309
+ createThemeExtensions({
310
+ themeMode
311
+ }),
312
+ references ? promptReferences({
313
+ provider: references
314
+ }) : [],
315
+ Prec2.highest(keymap3.of([
316
+ {
317
+ key: "cmd-ArrowUp",
318
+ preventDefault: true,
319
+ run: () => {
320
+ onOpenChange?.(true);
321
+ return true;
322
+ }
323
+ },
324
+ {
325
+ key: "cmd-ArrowDown",
326
+ preventDefault: true,
327
+ run: () => {
328
+ onOpenChange?.(false);
329
+ return true;
330
+ }
331
+ }
332
+ ])),
333
+ extensions
334
+ ].filter(isNonNullable)
335
+ }, [
336
+ themeMode,
337
+ extensions,
338
+ onSubmit,
339
+ onSuggest
340
+ ]);
341
+ useImperativeHandle(forwardRef3, () => {
342
+ return {
343
+ focus: () => {
344
+ view?.focus();
345
+ },
346
+ setText: (text) => {
347
+ view?.dispatch({
348
+ changes: {
349
+ from: 0,
350
+ to: view.state.doc.length,
351
+ insert: text
352
+ },
353
+ selection: {
354
+ anchor: text.length,
355
+ head: text.length
356
+ }
357
+ });
358
+ }
359
+ };
360
+ }, [
361
+ view,
362
+ onSubmit
363
+ ]);
364
+ return /* @__PURE__ */ React.createElement("div", {
365
+ ref: parentRef,
366
+ className: mx("w-full", classNames)
367
+ });
368
+ } finally {
369
+ _effect.f();
370
+ }
371
+ });
372
+
373
+ // packages/plugins/plugin-assistant/src/components/Prompt/PromptBar.tsx
374
+ import { useSignals as _useSignals2 } from "@preact-signals/safe-react/tracking";
375
+ import React2, { forwardRef as forwardRef2, useState } from "react";
376
+ import { useVoiceInput } from "@dxos/plugin-transcription";
377
+ import { Icon, IconButton, Tooltip, useForwardedRef, useTranslation } from "@dxos/react-ui";
378
+ import { Spinner } from "@dxos/react-ui-sfx";
379
+ import { errorText, mx as mx2 } from "@dxos/react-ui-theme";
380
+ var PromptBar = /* @__PURE__ */ forwardRef2(({ classNames, placeholder, processing, error, microphone, references, onCancel, ...props }, forwardedRef) => {
381
+ var _effect = _useSignals2();
382
+ try {
383
+ const { t } = useTranslation(ASSISTANT_PLUGIN);
384
+ const promptRef = useForwardedRef(forwardedRef);
385
+ const [active, setActive] = useState(false);
386
+ const { recording } = useVoiceInput({
387
+ active,
388
+ onUpdate: (text) => {
389
+ promptRef.current?.setText(text);
390
+ promptRef.current?.focus();
391
+ }
388
392
  });
389
- url = `${endpoint.document.schemes?.[0] ?? "https"}://${endpoint.document.host}`;
393
+ return /* @__PURE__ */ React2.createElement("div", {
394
+ className: mx2("shrink-0 w-full grid grid-cols-[var(--rail-action)_1fr_var(--rail-action)] overflow-hidden", classNames)
395
+ }, /* @__PURE__ */ React2.createElement("div", {
396
+ className: "flex w-[--rail-action] h-[--rail-action] items-center justify-center"
397
+ }, error && /* @__PURE__ */ React2.createElement(Tooltip.Trigger, {
398
+ content: error.message,
399
+ delayDuration: 0
400
+ }, /* @__PURE__ */ React2.createElement(Icon, {
401
+ icon: "ph--warning-circle--regular",
402
+ classNames: errorText,
403
+ size: 5
404
+ })) || /* @__PURE__ */ React2.createElement(Spinner, {
405
+ active: processing
406
+ })), /* @__PURE__ */ React2.createElement(Prompt, {
407
+ ref: promptRef,
408
+ autoFocus: true,
409
+ classNames: "pbs-2",
410
+ lineWrapping: true,
411
+ placeholder: placeholder ?? t("prompt placeholder"),
412
+ references,
413
+ onCancel,
414
+ ...props
415
+ }), (onCancel || microphone) && /* @__PURE__ */ React2.createElement("div", {
416
+ className: "flex w-[--rail-action] h-[--rail-action] items-center justify-center"
417
+ }, processing && onCancel && /* @__PURE__ */ React2.createElement(IconButton, {
418
+ classNames: "px-1.5",
419
+ variant: "ghost",
420
+ size: 5,
421
+ icon: "ph--x--regular",
422
+ iconOnly: true,
423
+ label: t("cancel processing button"),
424
+ onClick: onCancel
425
+ }), !processing && microphone && /* @__PURE__ */ React2.createElement(IconButton, {
426
+ classNames: mx2("px-1.5", recording && "bg-primary-500"),
427
+ variant: "ghost",
428
+ size: 5,
429
+ icon: "ph--microphone--regular",
430
+ iconOnly: true,
431
+ noTooltip: true,
432
+ label: t("microphone button"),
433
+ onMouseDown: () => setActive(true),
434
+ onMouseUp: () => setActive(false),
435
+ onTouchStart: () => setActive(true),
436
+ onTouchEnd: () => setActive(false)
437
+ })));
438
+ } finally {
439
+ _effect.f();
390
440
  }
391
- if (!isV3_1(endpoint.document) && endpoint.document.basePath) {
392
- url += endpoint.document.basePath;
441
+ });
442
+
443
+ // packages/plugins/plugin-assistant/src/components/Toolbox/Toolbox.tsx
444
+ import { useSignals as _useSignals3 } from "@preact-signals/safe-react/tracking";
445
+ import React3, { useState as useState2, useEffect, Fragment } from "react";
446
+ import { parseToolName } from "@dxos/ai";
447
+ import { Capabilities, useCapabilities } from "@dxos/app-framework";
448
+ import { FunctionType } from "@dxos/functions";
449
+ import { log as log3 } from "@dxos/log";
450
+ import { Filter, useQuery } from "@dxos/react-client/echo";
451
+ import { mx as mx3 } from "@dxos/react-ui-theme";
452
+
453
+ // packages/plugins/plugin-assistant/src/tools/function.ts
454
+ import { createTool, ToolResult } from "@dxos/ai";
455
+ import { toEffectSchema } from "@dxos/echo-schema";
456
+ import { getInvocationUrl, getUserFunctionUrlInMetadata } from "@dxos/functions";
457
+ import { log } from "@dxos/log";
458
+ import { getMeta } from "@dxos/react-client/echo";
459
+ var __dxlog_file = "/home/runner/work/dxos/dxos/packages/plugins/plugin-assistant/src/tools/function.ts";
460
+ var convertFunctionToTool = (fn, edgeUrl, spaceId) => {
461
+ if (!fn.description || !fn.inputSchema) {
462
+ return void 0;
393
463
  }
394
- url += endpoint.path;
395
- return url;
396
- };
397
- var resolveAuthorization = async (authorization) => {
398
- switch (authorization.type) {
399
- case "api-key": {
400
- invariant(authorization.placement.type === "authorization-header", void 0, {
401
- F: __dxlog_file2,
402
- L: 288,
464
+ const existingFunctionUrl = getUserFunctionUrlInMetadata(getMeta(fn));
465
+ if (!existingFunctionUrl) {
466
+ return void 0;
467
+ }
468
+ const url = getInvocationUrl(existingFunctionUrl, edgeUrl, {
469
+ spaceId
470
+ });
471
+ return createTool("user-function", {
472
+ name: fn.name,
473
+ description: fn.description,
474
+ schema: toEffectSchema(fn.inputSchema),
475
+ execute: async (input) => {
476
+ log.info("execute function tool", {
477
+ name: fn.name,
478
+ url,
479
+ input
480
+ }, {
481
+ F: __dxlog_file,
482
+ L: 34,
403
483
  S: void 0,
404
- A: [
405
- "authorization.placement.type === 'authorization-header'",
406
- ""
407
- ]
484
+ C: (f, a) => f(...a)
408
485
  });
409
- return `Bearer ${authorization.key}`;
410
- }
411
- case "oauth": {
412
- const response = await fetch(authorization.tokenUrl, {
486
+ const response = await fetch(url, {
413
487
  method: "POST",
414
488
  headers: {
415
- "Content-Type": "application/x-www-form-urlencoded"
489
+ "Content-Type": "application/json"
416
490
  },
417
- body: `grant_type=${authorization.grantType}&client_id=${authorization.clientId}&client_secret=${authorization.clientSecret}`
491
+ body: JSON.stringify(input)
418
492
  });
419
- const data = await response.json();
420
- return `Bearer ${data.access_token}`;
421
- }
422
- default: {
423
- throw new Error(`Unknown authorization type: ${authorization.type}`);
424
- }
425
- }
426
- };
427
- var resolveJsonSchema = (schema, base) => {
428
- return deepMapValues(schema, (value, recurse) => {
429
- if (typeof value === "object" && value !== null && "$ref" in value && typeof value.$ref === "string") {
430
- if (value.$ref.startsWith("#")) {
431
- const resolved = jsonpointer.get(base, value.$ref.slice(1));
432
- if (resolved) {
433
- return recurse(resolved);
434
- } else {
435
- log2.warn("unresolved", {
436
- ref: value.$ref,
437
- base
438
- }, {
439
- F: __dxlog_file2,
440
- L: 321,
441
- S: void 0,
442
- C: (f, a) => f(...a)
443
- });
444
- }
445
- }
493
+ return ToolResult.Success(await response.text());
446
494
  }
447
- return recurse(value);
448
495
  });
449
496
  };
450
- var isV3_1 = (document2) => {
451
- return document2.openapi === "3.0.1";
452
- };
453
497
 
454
- // packages/plugins/plugin-assistant/src/components/Toolbox/Toolbox.tsx
455
- var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-assistant/src/components/Toolbox/Toolbox.tsx";
456
- var Toolbox = ({ classNames, artifacts, functions, services, striped }) => {
457
- return /* @__PURE__ */ React.createElement("div", {
458
- className: mx("flex flex-col overflow-y-auto box-content", classNames)
459
- }, artifacts && artifacts.length > 0 && /* @__PURE__ */ React.createElement(Section, {
460
- title: "Artifacts",
461
- items: artifacts.map(({ name, description, tools }) => ({
462
- name,
463
- description,
464
- subitems: tools.map(({ name: name2, description: description2 }) => ({
465
- name: `\u2219 ${parseToolName(name2)}`,
466
- description: description2
467
- }))
468
- }))
469
- }), services && services.length > 0 && /* @__PURE__ */ React.createElement(Section, {
470
- title: "Services",
471
- items: services.map(({ service: { serviceId, name, description }, tools }) => ({
472
- name: name ?? serviceId,
473
- description,
474
- subitems: tools.map(({ name: name2, description: description2 }) => ({
475
- name: `\u2219 ${name2}`,
476
- description: description2
477
- }))
478
- }))
479
- }), functions && functions.length > 0 && /* @__PURE__ */ React.createElement(Section, {
480
- title: "Functions",
481
- items: functions.map(({ name, description }) => ({
482
- name,
483
- description
484
- }))
485
- }));
486
- };
487
- var Section = ({ title, items, striped }) => {
488
- const stripeClassNames = "odd:bg-neutral-50 dark:odd:bg-neutral-800";
489
- const gridClassNames = "grid grid-cols-[8rem_1fr]";
490
- const subGridClassNames = mx("col-span-full grid grid-cols-subgrid text-xs px-2", striped && stripeClassNames);
491
- return /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h1", {
492
- className: "px-2 text-sm"
493
- }, title), /* @__PURE__ */ React.createElement("div", {
494
- className: gridClassNames
495
- }, items.map(({ name, description, subitems }, i) => /* @__PURE__ */ React.createElement(Fragment, {
496
- key: i
497
- }, name && /* @__PURE__ */ React.createElement("div", {
498
- className: subGridClassNames
499
- }, /* @__PURE__ */ React.createElement("div", {
500
- className: "truncate text-primary-500"
501
- }, name), /* @__PURE__ */ React.createElement("div", {
502
- className: "line-clamp-2"
503
- }, description)), subitems?.map(({ name: name2, description: description2 }, i2) => /* @__PURE__ */ React.createElement("div", {
504
- key: i2,
505
- className: mx(subGridClassNames, striped && stripeClassNames)
506
- }, /* @__PURE__ */ React.createElement("div", {
507
- className: "truncate"
508
- }, name2), /* @__PURE__ */ React.createElement("div", {
509
- className: "line-clamp-3 text-subdued"
510
- }, description2)))))));
511
- };
512
- var ToolboxContainer = ({ classNames, space }) => {
513
- const artifactDefinitions = useCapabilities(Capabilities.ArtifactDefinition);
514
- const services = useQuery(space, Filter.schema(ServiceType));
515
- const [serviceTools, setServiceTools] = useState([]);
516
- useEffect(() => {
517
- log3("creating service tools...", {
518
- services: services.length
519
- }, {
520
- F: __dxlog_file3,
521
- L: 99,
522
- S: void 0,
523
- C: (f, a) => f(...a)
524
- });
525
- queueMicrotask(async () => {
526
- const tools = await Promise.all(services.map(async (service) => ({
527
- service,
528
- tools: await createToolsFromService(service)
529
- })));
530
- setServiceTools(tools);
531
- });
532
- }, [
533
- services
534
- ]);
535
- const functions = useQuery(space, Filter.schema(FunctionType));
536
- return /* @__PURE__ */ React.createElement(Toolbox, {
537
- classNames,
538
- artifacts: artifactDefinitions,
539
- services: serviceTools,
540
- functions
498
+ // packages/plugins/plugin-assistant/src/tools/openapi.ts
499
+ import { Schema } from "effect";
500
+ import jsonpointer from "jsonpointer";
501
+ import { ToolResult as ToolResult2, createRawTool } from "@dxos/ai";
502
+ import { JsonSchemaType, normalizeSchema, toEffectSchema as toEffectSchema2 } from "@dxos/echo-schema";
503
+ import { invariant } from "@dxos/invariant";
504
+ import { log as log2 } from "@dxos/log";
505
+ import { deepMapValues } from "@dxos/util";
506
+ var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-assistant/src/tools/openapi.ts";
507
+ var createToolsFromService = async (service) => {
508
+ invariant(service.interfaces?.length === 1 && service.interfaces[0].kind === "api", void 0, {
509
+ F: __dxlog_file2,
510
+ L: 23,
511
+ S: void 0,
512
+ A: [
513
+ "service.interfaces?.length === 1 && service.interfaces[0].kind === 'api'",
514
+ ""
515
+ ]
541
516
  });
542
- };
543
-
544
- // packages/plugins/plugin-assistant/src/components/Thread/Thread.tsx
545
- import React6, { useCallback, useMemo as useMemo2, useRef as useRef3 } from "react";
546
- import { useIdentity } from "@dxos/react-client/halo";
547
- import { ScrollContainer } from "@dxos/react-ui-components";
548
- import { mx as mx5 } from "@dxos/react-ui-theme";
549
- import { keyToFallback } from "@dxos/util";
550
-
551
- // packages/plugins/plugin-assistant/src/components/Thread/ThreadMessage.tsx
552
- import React3 from "react";
553
- import { invariant as invariant2 } from "@dxos/invariant";
554
- import { Button, Icon, IconButton } from "@dxos/react-ui";
555
- import { MarkdownViewer, ToggleContainer as NativeToggleContainer } from "@dxos/react-ui-components";
556
- import { Json as Json2 } from "@dxos/react-ui-syntax-highlighter";
557
- import { mx as mx2 } from "@dxos/react-ui-theme";
558
- import { safeParseJson } from "@dxos/util";
559
-
560
- // packages/plugins/plugin-assistant/src/components/Thread/ToolInvocations.tsx
561
- import React2, { useEffect as useEffect2, useMemo, useRef, useState as useState2 } from "react";
562
- import { log as log4 } from "@dxos/log";
563
- import { NumericTabs, StatusRoll, ToggleContainer } from "@dxos/react-ui-components";
564
- import { Json } from "@dxos/react-ui-syntax-highlighter";
565
- import { isNonNullable, isNotFalsy } from "@dxos/util";
566
- var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-assistant/src/components/Thread/ToolInvocations.tsx";
567
- var isToolMessage = (message) => {
568
- return message.content.some((block) => block.type === "tool_use" || block.type === "tool_result");
569
- };
570
- var getToolName2 = (tool) => {
571
- return tool.namespace && tool.function ? `${tool.namespace}:${tool.function}` : tool.name.split("_").pop();
572
- };
573
- var getToolCaption = (tool) => {
574
- if (!tool) {
575
- return "Calling tool...";
576
- }
577
- return tool.caption ?? `Calling ${getToolName2(tool)}...`;
578
- };
579
- var ToolBlock = ({ classNames, message, tools }) => {
580
- const { content = [] } = message;
581
- let request;
582
- const blocks = content.filter((block) => block.type === "tool_use" || block.type === "tool_result");
583
- const items = blocks.map((block) => {
584
- switch (block.type) {
585
- case "tool_use": {
586
- if (block.pending && request?.block.id === block.id) {
587
- return null;
588
- }
589
- request = {
590
- tool: tools?.find((tool) => tool.name === block.name),
591
- block
592
- };
593
- return {
594
- title: getToolCaption(request.tool),
595
- block
596
- };
597
- }
598
- case "tool_result": {
599
- if (!request) {
600
- log4.warn("unexpected message", {
601
- block
602
- }, {
603
- F: __dxlog_file4,
604
- L: 52,
605
- S: void 0,
606
- C: (f, a) => f(...a)
607
- });
608
- return {
609
- title: "Error",
610
- block
611
- };
612
- }
613
- return {
614
- title: `${getToolCaption(request.tool)} (Success)`,
615
- block
616
- };
617
- }
618
- default: {
619
- request = void 0;
620
- return {
621
- title: "Error",
622
- block
623
- };
624
- }
625
- }
626
- }).filter(isNonNullable);
627
- return /* @__PURE__ */ React2.createElement(ToolContainer, {
628
- classNames,
629
- items
517
+ const iface = service.interfaces[0];
518
+ invariant(iface.schemaUrl, void 0, {
519
+ F: __dxlog_file2,
520
+ L: 25,
521
+ S: void 0,
522
+ A: [
523
+ "iface.schemaUrl",
524
+ ""
525
+ ]
630
526
  });
631
- };
632
- var ToolContainer = ({ classNames, items }) => {
633
- const tabsRef = useRef(null);
634
- const [selected, setSelected] = useState2(0);
635
- const [open, setOpen] = useState2(false);
636
- useEffect2(() => {
637
- if (open) {
638
- tabsRef.current?.focus();
639
- }
640
- }, [
641
- open
642
- ]);
643
- const handleSelect = (index) => {
644
- if (index === selected) {
645
- setOpen(false);
646
- } else {
647
- setSelected(index);
648
- }
649
- };
650
- const title = useMemo(() => {
651
- const lines = items.map((item) => item.title).filter(isNotFalsy);
652
- return /* @__PURE__ */ React2.createElement(StatusRoll, {
653
- key: "status-roll",
654
- lines,
655
- duration: 1e3,
656
- autoAdvance: true
657
- });
658
- }, [
659
- items
660
- ]);
661
- return /* @__PURE__ */ React2.createElement(ToggleContainer, {
662
- classNames: [
663
- "flex flex-col",
664
- classNames
665
- ],
666
- title,
667
- open,
668
- onChangeOpen: setOpen
669
- }, /* @__PURE__ */ React2.createElement("div", {
670
- className: "grid grid-cols-[32px_1fr]"
671
- }, /* @__PURE__ */ React2.createElement(NumericTabs, {
672
- ref: tabsRef,
673
- length: items.length,
674
- selected,
675
- onSelect: handleSelect
676
- }), /* @__PURE__ */ React2.createElement(Json, {
677
- data: items[selected].block,
678
- classNames: "!p-1 text-xs"
679
- })));
680
- };
681
-
682
- // packages/plugins/plugin-assistant/src/components/Thread/ThreadMessage.tsx
683
- var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-assistant/src/components/Thread/ThreadMessage.tsx";
684
- var panelClassNames = "flex flex-col w-full px-2 bg-groupSurface rounded-md";
685
- var userClassNames = "bg-[--user-fill] text-inverse";
686
- var ToggleContainer2 = (props) => {
687
- return /* @__PURE__ */ React3.createElement(NativeToggleContainer, {
688
- ...props,
689
- classNames: mx2(panelClassNames, props.classNames)
527
+ invariant(iface.schemaUrl, void 0, {
528
+ F: __dxlog_file2,
529
+ L: 26,
530
+ S: void 0,
531
+ A: [
532
+ "iface.schemaUrl",
533
+ ""
534
+ ]
690
535
  });
691
- };
692
- var MessageContainer = ({ children, classNames, user }) => {
693
- if (!children) {
694
- return null;
695
- }
696
- return /* @__PURE__ */ React3.createElement("div", {
697
- role: "list-item",
698
- className: mx2("flex w-full", user && "justify-end", classNames)
699
- }, /* @__PURE__ */ React3.createElement("div", {
700
- className: mx2(user ? [
701
- "px-2 py-1 rounded-md",
702
- userClassNames
703
- ] : "w-full")
704
- }, children));
705
- };
706
- var ThreadMessage = ({ classNames, space, message, tools, onPrompt }) => {
707
- const { role, content = [] } = message;
708
- if (isToolMessage(message)) {
709
- return /* @__PURE__ */ React3.createElement(MessageContainer, {
710
- classNames: mx2(classNames, "animate-[fadeIn_0.5s]")
711
- }, /* @__PURE__ */ React3.createElement(ToolBlock, {
712
- space,
713
- classNames: panelClassNames,
714
- message,
715
- tools
716
- }));
717
- }
718
- return content.map((block, idx) => {
719
- if (block.type === "text" && block.text.replaceAll(/\s+/g, "").length === 0) {
720
- return null;
721
- }
722
- const Component = components[block.type] ?? components.default;
723
- return /* @__PURE__ */ React3.createElement(MessageContainer, {
724
- key: idx,
725
- classNames: mx2(classNames, "animate-[fadeIn_0.5s]"),
726
- user: block.type === "text" && role === "user"
727
- }, /* @__PURE__ */ React3.createElement(Component, {
728
- space,
729
- block,
730
- onPrompt
731
- }));
536
+ return createToolsFromApi(iface.schemaUrl, {
537
+ authorization: iface.authorization
732
538
  });
733
539
  };
734
- var components = {
735
- //
736
- // Text
737
- //
738
- ["text"]: ({ block }) => {
739
- invariant2(block.type === "text", void 0, {
740
- F: __dxlog_file5,
741
- L: 90,
742
- S: void 0,
743
- A: [
744
- "block.type === 'text'",
745
- ""
746
- ]
747
- });
748
- const title = block.disposition ? titles[block.disposition] : void 0;
749
- if (!title) {
750
- return /* @__PURE__ */ React3.createElement(MarkdownViewer, {
751
- classNames: "[&>p]:animate-[fadeIn_0.5s]",
752
- content: block.text
540
+ var createToolsFromApi = async (url, options) => {
541
+ const res = await fetch(url);
542
+ const spec = await res.json();
543
+ log2("spec", {
544
+ spec
545
+ }, {
546
+ F: __dxlog_file2,
547
+ L: 36,
548
+ S: void 0,
549
+ C: (f, a) => f(...a)
550
+ });
551
+ const tools = [];
552
+ for (const [path, pathItem] of Object.entries(spec.paths)) {
553
+ if (typeof pathItem !== "object") {
554
+ continue;
555
+ }
556
+ const { ...methods } = pathItem;
557
+ for (const [method, m] of Object.entries(methods)) {
558
+ const methodItem = m;
559
+ log2("methodItem", {
560
+ path,
561
+ method,
562
+ methodItem
563
+ }, {
564
+ F: __dxlog_file2,
565
+ L: 47,
566
+ S: void 0,
567
+ C: (f, a) => f(...a)
753
568
  });
754
- }
755
- return /* @__PURE__ */ React3.createElement(ToggleContainer2, {
756
- // open={open}
757
- defaultOpen: block.disposition === "cot" && block.pending,
758
- title,
759
- icon: block.pending ? /* @__PURE__ */ React3.createElement(Icon, {
760
- icon: "ph--circle-notch--regular",
761
- classNames: "text-subdued ml-2 animate-spin",
762
- size: 4
763
- }) : void 0
764
- }, /* @__PURE__ */ React3.createElement(MarkdownViewer, {
765
- content: block.text,
766
- classNames: [
767
- "pbe-2",
768
- block.disposition === "cot" && "text-sm text-subdued"
769
- ]
770
- }));
771
- },
772
- //
773
- // JSON
774
- //
775
- ["json"]: ({ space, block, onPrompt }) => {
776
- invariant2(block.type === "json", void 0, {
777
- F: __dxlog_file5,
778
- L: 128,
779
- S: void 0,
780
- A: [
781
- "block.type === 'json'",
782
- ""
783
- ]
784
- });
785
- switch (block.disposition) {
786
- case "tool_list": {
787
- return /* @__PURE__ */ React3.createElement(ToggleContainer2, {
788
- title: titles[block.disposition],
789
- defaultOpen: true
790
- }, /* @__PURE__ */ React3.createElement(ToolboxContainer, {
791
- space,
792
- classNames: "pbe-2"
793
- }));
794
- }
795
- case "suggest": {
796
- const { text = "" } = safeParseJson(block.json ?? "{}") ?? {};
797
- return /* @__PURE__ */ React3.createElement(IconButton, {
798
- icon: "ph--lightning--regular",
799
- label: text,
800
- onClick: () => onPrompt?.(text)
569
+ const parametersResolved = methodItem.parameters?.map((parameter) => {
570
+ const resolved = resolveJsonSchema(parameter, spec);
571
+ return resolved;
572
+ }) ?? [];
573
+ const inputSchema = {
574
+ type: "object",
575
+ properties: {}
576
+ };
577
+ const endpointParameters = [];
578
+ for (const parameter of parametersResolved) {
579
+ log2("parameter", {
580
+ parameter
581
+ }, {
582
+ F: __dxlog_file2,
583
+ L: 63,
584
+ S: void 0,
585
+ C: (f, a) => f(...a)
801
586
  });
587
+ if (options?.authorization?.type === "api-key" && options.authorization.placement.type === "query" && parameter.in === "query" && parameter.name === options.authorization.placement.name) {
588
+ continue;
589
+ }
590
+ endpointParameters.push(parameter);
591
+ if (parameter.schema) {
592
+ inputSchema.properties[parameter.name] = normalizeSchema(parameter.schema);
593
+ } else if (typeof parameter.type === "string") {
594
+ const { name, in: _in, required, ...schema } = parameter;
595
+ inputSchema.properties[name] = normalizeSchema(schema);
596
+ if (required) {
597
+ inputSchema.required ??= [];
598
+ inputSchema.required.push(name);
599
+ }
600
+ }
802
601
  }
803
- case "select": {
804
- const { options = [] } = safeParseJson(block.json ?? "{}") ?? {};
805
- return /* @__PURE__ */ React3.createElement("div", {
806
- className: "flex flex-wrap gap-1"
807
- }, options.map((option, idx) => /* @__PURE__ */ React3.createElement(Button, {
808
- classNames: "animate-[fadeIn_0.5s] rounded-2xl text-sm",
809
- key: option,
810
- onClick: () => onPrompt?.(option)
811
- }, option)));
812
- }
813
- default: {
814
- const title = block.disposition ? titles[block.disposition] : void 0;
815
- return /* @__PURE__ */ React3.createElement(ToggleContainer2, {
816
- title: title ?? "JSON"
817
- }, /* @__PURE__ */ React3.createElement(Json2, {
818
- data: safeParseJson(block.json ?? block),
819
- classNames: "!p-1 text-xs"
820
- }));
602
+ log2("inputSchema", {
603
+ inputSchema
604
+ }, {
605
+ F: __dxlog_file2,
606
+ L: 88,
607
+ S: void 0,
608
+ C: (f, a) => f(...a)
609
+ });
610
+ Schema.validateSync(JsonSchemaType)(inputSchema);
611
+ const description = methodItem.description ?? methodItem.summary;
612
+ if (!description) {
613
+ log2.warn("no description", {
614
+ path,
615
+ method
616
+ }, {
617
+ F: __dxlog_file2,
618
+ L: 93,
619
+ S: void 0,
620
+ C: (f, a) => f(...a)
621
+ });
622
+ continue;
821
623
  }
624
+ const endpoint = {
625
+ document: spec,
626
+ path,
627
+ method,
628
+ parameters: endpointParameters,
629
+ authorization: options?.authorization
630
+ };
631
+ tools.push(
632
+ // TODO(burdon): Namespace?
633
+ createRawTool("openapi", {
634
+ name: getToolName(path, method, methodItem),
635
+ description: options?.instructions ? `${options.instructions}
636
+
637
+ ${description}` : description,
638
+ parameters: inputSchema,
639
+ execute: async (input) => {
640
+ const response = await callApiEndpoint(endpoint, input);
641
+ return ToolResult2.Success(response);
642
+ }
643
+ })
644
+ );
822
645
  }
823
- },
824
- //
825
- // Default
826
- //
827
- default: ({ block }) => {
828
- let title = titles[block.type];
829
- if (block.type === "tool_use") {
830
- title = `Tool [${block.name}]`;
831
- }
832
- return /* @__PURE__ */ React3.createElement(ToggleContainer2, {
833
- title: title ?? "JSON"
834
- }, /* @__PURE__ */ React3.createElement(Json2, {
835
- data: block,
836
- classNames: "!p-1 text-xs"
837
- }));
838
646
  }
647
+ return tools;
839
648
  };
840
- var titles = {
841
- ["cot"]: "Chain of thought",
842
- ["artifact"]: "Artifact",
843
- ["tool_use"]: "Tool request",
844
- ["tool_result"]: "Tool result",
845
- ["tool_list"]: "Tools"
846
- };
847
-
848
- // packages/plugins/plugin-assistant/src/components/Thread/reducer.ts
849
- var messageReducer = ({ current, messages }, message) => {
850
- let i = 0;
851
- for (const block of message.content) {
852
- switch (block.type) {
853
- case "tool_use":
854
- case "tool_result": {
855
- if (current) {
856
- current.content.push(block);
857
- } else {
858
- current = {
859
- id: [
860
- message.id,
861
- i
862
- ].join("_"),
863
- role: message.role,
864
- content: [
865
- block
866
- ]
867
- };
868
- messages.push(current);
869
- }
870
- break;
871
- }
872
- case "text":
873
- default: {
874
- current = void 0;
875
- messages.push({
876
- id: [
877
- message.id,
878
- i
879
- ].join("_"),
880
- role: message.role,
881
- content: [
882
- block
883
- ]
884
- });
649
+ var getToolName = (path, method, methodItem) => {
650
+ if (methodItem.operationId) {
651
+ return methodItem.operationId;
652
+ }
653
+ let name = `${method.toLowerCase()}_${path.replaceAll(/[{}/]/g, "_")}`;
654
+ while (name.length > MAX_TOOL_NAME_LENGTH) {
655
+ const lengthBefore = name.length;
656
+ for (const word of GENERIC_WORDS) {
657
+ if (name.includes(word)) {
658
+ name = name.replace(word, "");
885
659
  break;
886
660
  }
887
661
  }
888
- i++;
662
+ name = name.replaceAll("__", "_").replace(/_$/, "");
663
+ const lengthAfter = name.length;
664
+ if (lengthBefore === lengthAfter) {
665
+ break;
666
+ }
889
667
  }
890
- return {
891
- current,
892
- messages
893
- };
668
+ name = name.replaceAll("__", "_").replace(/_$/, "").replace(/^_/, "");
669
+ return name.slice(0, MAX_TOOL_NAME_LENGTH);
894
670
  };
895
-
896
- // packages/plugins/plugin-assistant/src/components/Prompt/Prompt.tsx
897
- import { Prec as Prec2 } from "@codemirror/state";
898
- import React4, { forwardRef, useImperativeHandle } from "react";
899
- import { useThemeContext } from "@dxos/react-ui";
900
- import { createBasicExtensions, createThemeExtensions, keymap as keymap3, useTextEditor } from "@dxos/react-ui-editor";
901
- import { mx as mx3 } from "@dxos/react-ui-theme";
902
-
903
- // packages/plugins/plugin-assistant/src/components/Prompt/autocomplete.ts
904
- import { Prec } from "@codemirror/state";
905
- import { EditorView, Decoration, ViewPlugin, keymap, WidgetType } from "@codemirror/view";
906
- var createAutocompleteExtension = ({ onSubmit, onSuggest }) => {
907
- const suggestionPlugin = ViewPlugin.fromClass(class {
908
- constructor(view) {
909
- this._currentSuggestion = null;
910
- this._decorations = this.computeDecorations(view);
911
- }
912
- update(update) {
913
- if (update.docChanged || update.selectionSet) {
914
- this._decorations = this.computeDecorations(update.view);
915
- }
671
+ var MAX_TOOL_NAME_LENGTH = 64;
672
+ var GENERIC_WORDS = [
673
+ "services",
674
+ "service",
675
+ "api",
676
+ "rest",
677
+ "endpoint",
678
+ "get",
679
+ "post",
680
+ "put",
681
+ "delete",
682
+ "patch",
683
+ "head",
684
+ "options",
685
+ "trace",
686
+ "service",
687
+ "api",
688
+ "endpoint"
689
+ ];
690
+ var callApiEndpoint = async (endpoint, input) => {
691
+ log2.info("endpoint", {
692
+ method: endpoint.method,
693
+ name: endpoint.path,
694
+ input
695
+ }, {
696
+ F: __dxlog_file2,
697
+ L: 180,
698
+ S: void 0,
699
+ C: (f, a) => f(...a)
700
+ });
701
+ let url = getEndpointUrl(endpoint);
702
+ const request = {
703
+ method: endpoint.method,
704
+ headers: {}
705
+ };
706
+ const query = new URLSearchParams();
707
+ let body;
708
+ for (const parameter of endpoint.parameters) {
709
+ if (input[parameter.name] === void 0) {
710
+ continue;
916
711
  }
917
- computeDecorations(view) {
918
- const text = view.state.doc.toString();
919
- const suggestions = onSuggest?.(text) ?? [];
920
- if (!suggestions.length) {
921
- this._currentSuggestion = null;
922
- return Decoration.none;
712
+ switch (parameter.in) {
713
+ case "header": {
714
+ if (parameter.example) {
715
+ request.headers[parameter.name] = parameter.default;
716
+ }
717
+ break;
923
718
  }
924
- this._currentSuggestion = suggestions[0];
925
- const suffix = this._currentSuggestion.slice(text.length);
926
- if (!suffix) {
927
- return Decoration.none;
719
+ case "path": {
720
+ url = url.replace(`{${parameter.name}}`, encodeURIComponent(input[parameter.name]));
721
+ break;
928
722
  }
929
- return Decoration.set([
930
- Decoration.widget({
931
- widget: new InlineSuggestionWidget(suffix),
932
- side: 1
933
- }).range(view.state.doc.length)
934
- ]);
935
- }
936
- completeSuggestion(view) {
937
- if (!this._currentSuggestion) {
938
- return false;
723
+ case "body": {
724
+ const value = input[parameter.name];
725
+ const effectSchema = toEffectSchema2(parameter.schema);
726
+ Schema.validateSync(effectSchema)(value);
727
+ if (body) {
728
+ throw new Error(`Duplicate body parameter: ${parameter.name}`);
729
+ }
730
+ body = value;
731
+ break;
939
732
  }
940
- const text = view.state.doc.toString();
941
- const suffix = this._currentSuggestion.slice(text.length);
942
- if (!suffix) {
943
- return false;
733
+ case "query": {
734
+ query.set(parameter.name, input[parameter.name]);
735
+ break;
944
736
  }
945
- view.dispatch({
946
- changes: {
947
- from: view.state.doc.length,
948
- insert: suffix
949
- },
950
- selection: {
951
- anchor: view.state.doc.length + suffix.length
952
- }
953
- });
954
- return true;
955
737
  }
738
+ }
739
+ if (endpoint.authorization?.type === "api-key" && endpoint.authorization.placement.type === "authorization-header" || endpoint.authorization?.type === "oauth") {
740
+ request.headers.Authorization = await resolveAuthorization(endpoint.authorization);
741
+ } else if (endpoint.authorization?.type === "api-key" && endpoint.authorization.placement.type === "query") {
742
+ query.set(endpoint.authorization.placement.name, endpoint.authorization.key);
743
+ }
744
+ if (query.size > 0) {
745
+ url += `?${query.toString()}`;
746
+ }
747
+ if (body) {
748
+ request.body = JSON.stringify(body);
749
+ request.headers["Content-Type"] = "application/json";
750
+ }
751
+ log2.info("request", {
752
+ url,
753
+ request
956
754
  }, {
957
- decorations: (v) => v._decorations
755
+ F: __dxlog_file2,
756
+ L: 243,
757
+ S: void 0,
758
+ C: (f, a) => f(...a)
958
759
  });
959
- return [
960
- suggestionPlugin,
961
- EditorView.theme({
962
- ".cm-inline-suggestion": {
963
- opacity: 0.4
964
- }
965
- }),
966
- // Accept the current suggestion.
967
- Prec.highest(keymap.of([
968
- {
969
- key: "Tab",
970
- preventDefault: true,
971
- run: (view) => {
972
- const plugin = view.plugin(suggestionPlugin);
973
- return plugin?.completeSuggestion(view) ?? false;
974
- }
975
- },
976
- {
977
- key: "ArrowRight",
978
- preventDefault: true,
979
- run: (view) => {
980
- if (view.state.selection.main.head !== view.state.doc.length) {
981
- return false;
982
- }
983
- const plugin = view.plugin(suggestionPlugin);
984
- return plugin?.completeSuggestion(view) ?? false;
985
- }
986
- },
987
- {
988
- key: "Enter",
989
- preventDefault: true,
990
- run: (view) => {
991
- const text = view.state.doc.toString().trim();
992
- if (text.length > 0 && onSubmit) {
993
- const reset = onSubmit(text);
994
- if (reset) {
995
- view.dispatch({
996
- changes: {
997
- from: 0,
998
- to: view.state.doc.length,
999
- insert: ""
1000
- }
1001
- });
1002
- }
1003
- }
1004
- return true;
1005
- }
1006
- },
1007
- {
1008
- key: "Shift-Enter",
1009
- preventDefault: true,
1010
- run: (view) => {
1011
- view.dispatch({
1012
- changes: {
1013
- from: view.state.selection.main.head,
1014
- insert: "\n"
1015
- },
1016
- selection: {
1017
- anchor: view.state.selection.main.head + 1,
1018
- head: view.state.selection.main.head + 1
1019
- }
1020
- });
1021
- return true;
1022
- }
1023
- },
1024
- {
1025
- key: "Escape",
1026
- preventDefault: true,
1027
- run: (view) => {
1028
- view.dispatch({
1029
- changes: {
1030
- from: 0,
1031
- to: view.state.doc.length,
1032
- insert: ""
1033
- }
1034
- });
1035
- return true;
1036
- }
760
+ const response = await fetch(url, request);
761
+ log2.info("response", {
762
+ ok: response.ok,
763
+ status: response.status,
764
+ statusText: response.statusText
765
+ }, {
766
+ F: __dxlog_file2,
767
+ L: 246,
768
+ S: void 0,
769
+ C: (f, a) => f(...a)
770
+ });
771
+ if (response.ok) {
772
+ const contentType = response.headers.get("Content-Type");
773
+ if (contentType?.includes("application/json")) {
774
+ return await response.json();
775
+ } else {
776
+ return await response.text();
777
+ }
778
+ } else {
779
+ if (response.headers.get("Content-Type")?.includes("application/json")) {
780
+ const responseBody = await response.text();
781
+ let error;
782
+ try {
783
+ error = JSON.parse(responseBody);
784
+ } catch {
785
+ error = responseBody;
1037
786
  }
1038
- ]))
1039
- ];
1040
- };
1041
- var InlineSuggestionWidget = class extends WidgetType {
1042
- constructor(suffix) {
1043
- super();
1044
- this.suffix = suffix;
787
+ log2.error("error", {
788
+ error
789
+ }, {
790
+ F: __dxlog_file2,
791
+ L: 264,
792
+ S: void 0,
793
+ C: (f, a) => f(...a)
794
+ });
795
+ throw new Error(error.message);
796
+ } else {
797
+ const error = await response.text();
798
+ log2.error("error", {
799
+ error
800
+ }, {
801
+ F: __dxlog_file2,
802
+ L: 268,
803
+ S: void 0,
804
+ C: (f, a) => f(...a)
805
+ });
806
+ throw new Error(error);
807
+ }
1045
808
  }
1046
- toDOM() {
1047
- const span = document.createElement("span");
1048
- span.textContent = this.suffix;
1049
- span.className = "cm-inline-suggestion";
1050
- return span;
809
+ };
810
+ var getEndpointUrl = (endpoint) => {
811
+ let url = "";
812
+ if (isV3_1(endpoint.document) && endpoint.document.servers && endpoint.document.servers.length > 0) {
813
+ url = endpoint.document.servers[0].url;
814
+ } else {
815
+ invariant(!isV3_1(endpoint.document), void 0, {
816
+ F: __dxlog_file2,
817
+ L: 279,
818
+ S: void 0,
819
+ A: [
820
+ "!isV3_1(endpoint.document)",
821
+ ""
822
+ ]
823
+ });
824
+ url = `${endpoint.document.schemes?.[0] ?? "https"}://${endpoint.document.host}`;
1051
825
  }
1052
- eq(other) {
1053
- return other.suffix === this.suffix;
826
+ if (!isV3_1(endpoint.document) && endpoint.document.basePath) {
827
+ url += endpoint.document.basePath;
1054
828
  }
829
+ url += endpoint.path;
830
+ return url;
1055
831
  };
1056
-
1057
- // packages/plugins/plugin-assistant/src/components/Prompt/references.ts
1058
- import { autocompletion, completionKeymap } from "@codemirror/autocomplete";
1059
- import { RangeSet } from "@codemirror/state";
1060
- import { Decoration as Decoration2, EditorView as EditorView2, keymap as keymap2, ViewPlugin as ViewPlugin2, WidgetType as WidgetType2 } from "@codemirror/view";
1061
- import { Mutex } from "@dxos/async";
1062
- var promptReferences = ({ provider, debug = false, triggerCharacter = "@" }) => {
1063
- if (triggerCharacter.length !== 1) {
1064
- throw new Error("triggerCharacter must be a single character");
1065
- }
1066
- const decorationField = ViewPlugin2.fromClass(class ReferenceView {
1067
- constructor(view) {
1068
- this._mutex = new Mutex();
1069
- this.decorations = Decoration2.set([]);
1070
- queueMicrotask(async () => {
1071
- const guard = await this._mutex.acquire();
1072
- try {
1073
- this.decorations = await this._computeDecorations(view);
1074
- } finally {
1075
- guard.release();
1076
- }
832
+ var resolveAuthorization = async (authorization) => {
833
+ switch (authorization.type) {
834
+ case "api-key": {
835
+ invariant(authorization.placement.type === "authorization-header", void 0, {
836
+ F: __dxlog_file2,
837
+ L: 295,
838
+ S: void 0,
839
+ A: [
840
+ "authorization.placement.type === 'authorization-header'",
841
+ ""
842
+ ]
843
+ });
844
+ return `Bearer ${authorization.key}`;
845
+ }
846
+ case "oauth": {
847
+ const response = await fetch(authorization.tokenUrl, {
848
+ method: "POST",
849
+ headers: {
850
+ "Content-Type": "application/x-www-form-urlencoded"
851
+ },
852
+ body: `grant_type=${authorization.grantType}&client_id=${authorization.clientId}&client_secret=${authorization.clientSecret}`
1077
853
  });
854
+ const data = await response.json();
855
+ return `Bearer ${data.access_token}`;
1078
856
  }
1079
- update(update) {
1080
- if (update.docChanged) {
1081
- queueMicrotask(async () => {
1082
- const guard = await this._mutex.acquire();
1083
- try {
1084
- this.decorations = await this._computeDecorations(update.view);
1085
- } finally {
1086
- guard.release();
1087
- }
1088
- });
1089
- }
857
+ default: {
858
+ throw new Error(`Unknown authorization type: ${authorization.type}`);
1090
859
  }
1091
- async _computeDecorations(view) {
1092
- const text = view.state.doc.toString();
1093
- const references = text.matchAll(new RegExp(`${triggerCharacter}[a-zA-Z0-9@:]+\\s`, "g"));
1094
- const decorations = [];
1095
- for (const match of references) {
1096
- const reference = match[0];
1097
- const uri = reference.slice(1, -1);
1098
- const data = await provider.resolveReference({
1099
- uri
1100
- });
1101
- if (data) {
1102
- decorations.push(Decoration2.replace({
1103
- widget: new ReferenceWidget(data)
1104
- }).range(match.index, match.index + reference.length));
860
+ }
861
+ };
862
+ var resolveJsonSchema = (schema, base) => {
863
+ return deepMapValues(schema, (value, recurse) => {
864
+ if (typeof value === "object" && value !== null && "$ref" in value && typeof value.$ref === "string") {
865
+ if (value.$ref.startsWith("#")) {
866
+ const resolved = jsonpointer.get(base, value.$ref.slice(1));
867
+ if (resolved) {
868
+ return recurse(resolved);
869
+ } else {
870
+ log2.warn("unresolved", {
871
+ ref: value.$ref,
872
+ base
873
+ }, {
874
+ F: __dxlog_file2,
875
+ L: 328,
876
+ S: void 0,
877
+ C: (f, a) => f(...a)
878
+ });
1105
879
  }
1106
880
  }
1107
- return Decoration2.set(decorations);
1108
881
  }
1109
- }, {
1110
- decorations: (v) => v.decorations,
1111
- provide: (plugin) => [
1112
- EditorView2.atomicRanges.of((view) => view.plugin(decorationField)?.decorations ?? RangeSet.empty)
1113
- ]
882
+ return recurse(value);
1114
883
  });
1115
- return [
1116
- decorationField,
1117
- EditorView2.theme({
1118
- ".cm-reference-pill": {
1119
- borderRadius: "0.25rem",
1120
- borderWidth: "1px",
1121
- marginRight: "0.25rem",
1122
- marginLeft: "0.25rem"
1123
- }
1124
- }),
1125
- autocompletion({
1126
- activateOnTyping: true,
1127
- override: [
1128
- async (context) => {
1129
- const match = context.matchBefore(new RegExp(`${triggerCharacter}[a-zA-Z0-9]+`));
1130
- if (!match || match?.to === match?.from) {
884
+ };
885
+ var isV3_1 = (document2) => {
886
+ return document2.openapi === "3.0.1";
887
+ };
888
+
889
+ // packages/plugins/plugin-assistant/src/components/Toolbox/Toolbox.tsx
890
+ var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-assistant/src/components/Toolbox/Toolbox.tsx";
891
+ var Toolbox = ({ classNames, artifacts, functions, services, striped }) => {
892
+ var _effect = _useSignals3();
893
+ try {
894
+ return /* @__PURE__ */ React3.createElement("div", {
895
+ className: mx3("flex flex-col overflow-y-auto box-content", classNames)
896
+ }, artifacts && artifacts.length > 0 && /* @__PURE__ */ React3.createElement(Section, {
897
+ title: "Artifacts",
898
+ items: artifacts.map(({ name, description, tools }) => ({
899
+ name,
900
+ description,
901
+ subitems: tools.map(({ name: name2, description: description2 }) => ({
902
+ name: `\u2219 ${parseToolName(name2)}`,
903
+ description: description2
904
+ }))
905
+ }))
906
+ }), services && services.length > 0 && /* @__PURE__ */ React3.createElement(Section, {
907
+ title: "Services",
908
+ items: services.map(({ service: { serviceId, name, description }, tools }) => ({
909
+ name: name ?? serviceId,
910
+ description,
911
+ subitems: tools.map(({ name: name2, description: description2 }) => ({
912
+ name: `\u2219 ${name2}`,
913
+ description: description2
914
+ }))
915
+ }))
916
+ }), functions && functions.length > 0 && /* @__PURE__ */ React3.createElement(Section, {
917
+ title: "Functions",
918
+ items: functions.map(({ name, description }) => ({
919
+ name,
920
+ description
921
+ }))
922
+ }));
923
+ } finally {
924
+ _effect.f();
925
+ }
926
+ };
927
+ var Section = ({ title, items, striped }) => {
928
+ var _effect = _useSignals3();
929
+ try {
930
+ const stripeClassNames = "odd:bg-neutral-50 dark:odd:bg-neutral-800";
931
+ const gridClassNames = "grid grid-cols-[8rem_1fr]";
932
+ const subGridClassNames = mx3("col-span-full grid grid-cols-subgrid text-xs px-2", striped && stripeClassNames);
933
+ return /* @__PURE__ */ React3.createElement("div", null, /* @__PURE__ */ React3.createElement("h1", {
934
+ className: "px-2 text-sm"
935
+ }, title), /* @__PURE__ */ React3.createElement("div", {
936
+ className: gridClassNames
937
+ }, items.map(({ name, description, subitems }, i) => /* @__PURE__ */ React3.createElement(Fragment, {
938
+ key: i
939
+ }, name && /* @__PURE__ */ React3.createElement("div", {
940
+ className: subGridClassNames
941
+ }, /* @__PURE__ */ React3.createElement("div", {
942
+ className: "truncate text-primary-500"
943
+ }, name), /* @__PURE__ */ React3.createElement("div", {
944
+ className: "line-clamp-2"
945
+ }, description)), subitems?.map(({ name: name2, description: description2 }, i2) => /* @__PURE__ */ React3.createElement("div", {
946
+ key: i2,
947
+ className: mx3(subGridClassNames, striped && stripeClassNames)
948
+ }, /* @__PURE__ */ React3.createElement("div", {
949
+ className: "truncate"
950
+ }, name2), /* @__PURE__ */ React3.createElement("div", {
951
+ className: "line-clamp-3 text-subdued"
952
+ }, description2)))))));
953
+ } finally {
954
+ _effect.f();
955
+ }
956
+ };
957
+ var ToolboxContainer = ({ classNames, space }) => {
958
+ var _effect = _useSignals3();
959
+ try {
960
+ const artifactDefinitions = useCapabilities(Capabilities.ArtifactDefinition);
961
+ const services = useQuery(space, Filter.type(ServiceType));
962
+ const [serviceTools, setServiceTools] = useState2([]);
963
+ useEffect(() => {
964
+ log3("creating service tools...", {
965
+ services: services.length
966
+ }, {
967
+ F: __dxlog_file3,
968
+ L: 100,
969
+ S: void 0,
970
+ C: (f, a) => f(...a)
971
+ });
972
+ queueMicrotask(async () => {
973
+ const tools = await Promise.all(services.map(async (service) => ({
974
+ service,
975
+ tools: await createToolsFromService(service)
976
+ })));
977
+ setServiceTools(tools);
978
+ });
979
+ }, [
980
+ services
981
+ ]);
982
+ const functions = useQuery(space, Filter.type(FunctionType));
983
+ return /* @__PURE__ */ React3.createElement(Toolbox, {
984
+ classNames,
985
+ artifacts: artifactDefinitions,
986
+ services: serviceTools,
987
+ functions
988
+ });
989
+ } finally {
990
+ _effect.f();
991
+ }
992
+ };
993
+
994
+ // packages/plugins/plugin-assistant/src/components/Thread/Thread.tsx
995
+ import { useSignals as _useSignals6 } from "@preact-signals/safe-react/tracking";
996
+ import React6, { useCallback, useMemo as useMemo2, useRef as useRef2 } from "react";
997
+ import { useIdentity } from "@dxos/react-client/halo";
998
+ import { ScrollContainer } from "@dxos/react-ui-components";
999
+ import { mx as mx5 } from "@dxos/react-ui-theme";
1000
+ import { keyToFallback } from "@dxos/util";
1001
+
1002
+ // packages/plugins/plugin-assistant/src/components/Thread/ThreadMessage.tsx
1003
+ import { useSignals as _useSignals5 } from "@preact-signals/safe-react/tracking";
1004
+ import React5 from "react";
1005
+ import { Surface } from "@dxos/app-framework";
1006
+ import { invariant as invariant2 } from "@dxos/invariant";
1007
+ import { Button, Icon as Icon2, IconButton as IconButton2 } from "@dxos/react-ui";
1008
+ import { MarkdownViewer, ToggleContainer as NativeToggleContainer } from "@dxos/react-ui-components";
1009
+ import { Json as Json2 } from "@dxos/react-ui-syntax-highlighter";
1010
+ import { mx as mx4 } from "@dxos/react-ui-theme";
1011
+ import { safeParseJson } from "@dxos/util";
1012
+
1013
+ // packages/plugins/plugin-assistant/src/components/Thread/ToolInvocations.tsx
1014
+ import { useSignals as _useSignals4 } from "@preact-signals/safe-react/tracking";
1015
+ import React4, { useEffect as useEffect2, useMemo, useRef, useState as useState3 } from "react";
1016
+ import { log as log4 } from "@dxos/log";
1017
+ import { NumericTabs, StatusRoll, ToggleContainer } from "@dxos/react-ui-components";
1018
+ import { Json } from "@dxos/react-ui-syntax-highlighter";
1019
+ import { isNonNullable as isNonNullable2, isNotFalsy } from "@dxos/util";
1020
+ var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-assistant/src/components/Thread/ToolInvocations.tsx";
1021
+ var isToolMessage = (message) => {
1022
+ return message.content.some((block) => block.type === "tool_use" || block.type === "tool_result");
1023
+ };
1024
+ var getToolName2 = (tool) => {
1025
+ return tool.namespace && tool.function ? `${tool.namespace}:${tool.function}` : tool.name.split("_").pop();
1026
+ };
1027
+ var getToolCaption = (tool, status) => {
1028
+ if (!tool) {
1029
+ return "Calling tool...";
1030
+ }
1031
+ return status?.message ?? tool.caption ?? `Calling ${getToolName2(tool)}...`;
1032
+ };
1033
+ var ToolBlock = ({ classNames, message, tools }) => {
1034
+ var _effect = _useSignals4();
1035
+ try {
1036
+ const { content = [] } = message;
1037
+ let request;
1038
+ const blocks = content.filter((block) => block.type === "tool_use" || block.type === "tool_result");
1039
+ const items = blocks.map((block) => {
1040
+ switch (block.type) {
1041
+ case "tool_use": {
1042
+ if (block.pending && request?.block.id === block.id) {
1131
1043
  return null;
1132
1044
  }
1133
- const query = match.text.slice(1);
1134
- const references = await provider.getReferences({
1135
- query
1045
+ log4.info("tool_use", {
1046
+ tool: request?.tool,
1047
+ status: block.currentStatus
1048
+ }, {
1049
+ F: __dxlog_file4,
1050
+ L: 46,
1051
+ S: void 0,
1052
+ C: (f, a) => f(...a)
1136
1053
  });
1054
+ request = {
1055
+ tool: tools?.find((tool) => tool.name === block.name),
1056
+ block
1057
+ };
1137
1058
  return {
1138
- from: match.from,
1139
- filter: false,
1140
- options: references.map((reference) => ({
1141
- label: reference.label,
1142
- apply: `${triggerCharacter}${reference.uri} `
1143
- }))
1059
+ title: getToolCaption(request.tool, block.currentStatus),
1060
+ block
1061
+ };
1062
+ }
1063
+ case "tool_result": {
1064
+ if (!request) {
1065
+ log4.warn("unexpected message", {
1066
+ block
1067
+ }, {
1068
+ F: __dxlog_file4,
1069
+ L: 54,
1070
+ S: void 0,
1071
+ C: (f, a) => f(...a)
1072
+ });
1073
+ return {
1074
+ title: "Error",
1075
+ block
1076
+ };
1077
+ }
1078
+ return {
1079
+ title: `${getToolCaption(request.tool, void 0)} (Success)`,
1080
+ block
1081
+ };
1082
+ }
1083
+ default: {
1084
+ request = void 0;
1085
+ return {
1086
+ title: "Error",
1087
+ block
1144
1088
  };
1145
1089
  }
1090
+ }
1091
+ }).filter(isNonNullable2);
1092
+ return /* @__PURE__ */ React4.createElement(ToolContainer, {
1093
+ classNames,
1094
+ items
1095
+ });
1096
+ } finally {
1097
+ _effect.f();
1098
+ }
1099
+ };
1100
+ var ToolContainer = ({ classNames, items }) => {
1101
+ var _effect = _useSignals4();
1102
+ try {
1103
+ const tabsRef = useRef(null);
1104
+ const [selected, setSelected] = useState3(0);
1105
+ const [open, setOpen] = useState3(false);
1106
+ useEffect2(() => {
1107
+ if (open) {
1108
+ tabsRef.current?.focus();
1109
+ }
1110
+ }, [
1111
+ open
1112
+ ]);
1113
+ const handleSelect = (index) => {
1114
+ if (index === selected) {
1115
+ setOpen(false);
1116
+ } else {
1117
+ setSelected(index);
1118
+ }
1119
+ };
1120
+ const title = useMemo(() => {
1121
+ const lines = items.map((item) => item.title).filter(isNotFalsy);
1122
+ return /* @__PURE__ */ React4.createElement(StatusRoll, {
1123
+ key: "status-roll",
1124
+ lines,
1125
+ duration: 1e3,
1126
+ autoAdvance: true
1127
+ });
1128
+ }, [
1129
+ items
1130
+ ]);
1131
+ return /* @__PURE__ */ React4.createElement(ToggleContainer, {
1132
+ classNames: [
1133
+ "flex flex-col",
1134
+ classNames
1146
1135
  ],
1147
- closeOnBlur: !debug,
1148
- tooltipClass: () => "shadow rounded",
1149
- aboveCursor: true
1150
- }),
1151
- keymap2.of(completionKeymap)
1152
- ];
1136
+ title,
1137
+ open,
1138
+ onChangeOpen: setOpen
1139
+ }, /* @__PURE__ */ React4.createElement("div", {
1140
+ className: "grid grid-cols-[32px_1fr]"
1141
+ }, /* @__PURE__ */ React4.createElement(NumericTabs, {
1142
+ ref: tabsRef,
1143
+ length: items.length,
1144
+ selected,
1145
+ onSelect: handleSelect
1146
+ }), /* @__PURE__ */ React4.createElement(Json, {
1147
+ data: items[selected].block,
1148
+ classNames: "!p-1 text-xs"
1149
+ })));
1150
+ } finally {
1151
+ _effect.f();
1152
+ }
1153
1153
  };
1154
- var ReferenceWidget = class extends WidgetType2 {
1155
- constructor(data) {
1156
- super();
1157
- this.data = data;
1154
+
1155
+ // packages/plugins/plugin-assistant/src/components/Thread/ThreadMessage.tsx
1156
+ var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-assistant/src/components/Thread/ThreadMessage.tsx";
1157
+ var panelClassNames = "flex flex-col w-full px-2 bg-activeSurface rounded-md";
1158
+ var userClassNames = "bg-[--user-fill] text-accentSurfaceText";
1159
+ var ToggleContainer2 = (props) => {
1160
+ var _effect = _useSignals5();
1161
+ try {
1162
+ return /* @__PURE__ */ React5.createElement(NativeToggleContainer, {
1163
+ ...props,
1164
+ classNames: mx4(panelClassNames, props.classNames)
1165
+ });
1166
+ } finally {
1167
+ _effect.f();
1158
1168
  }
1159
- toDOM() {
1160
- const span = document.createElement("span");
1161
- span.textContent = `@ ${this.data.label}`;
1162
- span.className = "cm-reference-pill";
1163
- return span;
1169
+ };
1170
+ var MessageContainer = ({ children, classNames, user }) => {
1171
+ var _effect = _useSignals5();
1172
+ try {
1173
+ if (!children) {
1174
+ return null;
1175
+ }
1176
+ return /* @__PURE__ */ React5.createElement("div", {
1177
+ role: "list-item",
1178
+ className: mx4("flex w-full", user && "justify-end", classNames)
1179
+ }, /* @__PURE__ */ React5.createElement("div", {
1180
+ className: mx4(user ? [
1181
+ "px-2 py-1 rounded-md",
1182
+ userClassNames
1183
+ ] : "w-full")
1184
+ }, children));
1185
+ } finally {
1186
+ _effect.f();
1164
1187
  }
1165
- eq(other) {
1166
- return other.data.uri === this.data.uri;
1188
+ };
1189
+ var ThreadMessage = ({ classNames, space, message, tools, onPrompt, onAddToGraph }) => {
1190
+ var _effect = _useSignals5();
1191
+ try {
1192
+ const { role, content = [] } = message;
1193
+ if (isToolMessage(message)) {
1194
+ return /* @__PURE__ */ React5.createElement(MessageContainer, {
1195
+ classNames: mx4(classNames, "animate-[fadeIn_0.5s]")
1196
+ }, /* @__PURE__ */ React5.createElement(ToolBlock, {
1197
+ space,
1198
+ classNames: panelClassNames,
1199
+ message,
1200
+ tools
1201
+ }));
1202
+ }
1203
+ return content.map((block, idx) => {
1204
+ if (block.type === "text" && block.text.replaceAll(/\s+/g, "").length === 0) {
1205
+ return null;
1206
+ }
1207
+ const Component = components[block.type] ?? components.default;
1208
+ return /* @__PURE__ */ React5.createElement(MessageContainer, {
1209
+ key: idx,
1210
+ classNames: mx4(classNames, "animate-[fadeIn_0.5s]"),
1211
+ user: block.type === "text" && role === "user"
1212
+ }, /* @__PURE__ */ React5.createElement(Component, {
1213
+ space,
1214
+ block,
1215
+ onPrompt,
1216
+ onAddToGraph
1217
+ }));
1218
+ });
1219
+ } finally {
1220
+ _effect.f();
1167
1221
  }
1168
- ignoreEvent() {
1169
- return true;
1222
+ };
1223
+ var components = {
1224
+ //
1225
+ // Text
1226
+ //
1227
+ ["text"]: ({ block }) => {
1228
+ invariant2(block.type === "text", void 0, {
1229
+ F: __dxlog_file5,
1230
+ L: 105,
1231
+ S: void 0,
1232
+ A: [
1233
+ "block.type === 'text'",
1234
+ ""
1235
+ ]
1236
+ });
1237
+ const title = block.disposition ? titles[block.disposition] : void 0;
1238
+ if (!title) {
1239
+ return /* @__PURE__ */ React5.createElement(MarkdownViewer, {
1240
+ classNames: "[&>p]:animate-[fadeIn_0.5s]",
1241
+ content: block.text
1242
+ });
1243
+ }
1244
+ return /* @__PURE__ */ React5.createElement(ToggleContainer2, {
1245
+ // open={open}
1246
+ defaultOpen: systemDispositions.includes(block.disposition ?? "") && block.pending,
1247
+ title,
1248
+ icon: block.pending ? /* @__PURE__ */ React5.createElement(Icon2, {
1249
+ icon: "ph--circle-notch--regular",
1250
+ classNames: "text-subdued ml-2 animate-spin",
1251
+ size: 4
1252
+ }) : void 0
1253
+ }, /* @__PURE__ */ React5.createElement(MarkdownViewer, {
1254
+ content: block.text,
1255
+ classNames: [
1256
+ "pbe-2",
1257
+ systemDispositions.includes(block.disposition ?? "") && "text-sm text-subdued"
1258
+ ]
1259
+ }));
1260
+ },
1261
+ //
1262
+ // JSON
1263
+ //
1264
+ ["json"]: ({ space, block, onPrompt, onAddToGraph }) => {
1265
+ invariant2(block.type === "json", void 0, {
1266
+ F: __dxlog_file5,
1267
+ L: 143,
1268
+ S: void 0,
1269
+ A: [
1270
+ "block.type === 'json'",
1271
+ ""
1272
+ ]
1273
+ });
1274
+ switch (block.disposition) {
1275
+ case "tool_list": {
1276
+ return /* @__PURE__ */ React5.createElement(ToggleContainer2, {
1277
+ title: titles[block.disposition],
1278
+ defaultOpen: true
1279
+ }, /* @__PURE__ */ React5.createElement(ToolboxContainer, {
1280
+ space,
1281
+ classNames: "pbe-2"
1282
+ }));
1283
+ }
1284
+ case "suggest": {
1285
+ const { text = "" } = safeParseJson(block.json ?? "{}") ?? {};
1286
+ return /* @__PURE__ */ React5.createElement(IconButton2, {
1287
+ icon: "ph--lightning--regular",
1288
+ label: text,
1289
+ onClick: () => onPrompt?.(text)
1290
+ });
1291
+ }
1292
+ case "select": {
1293
+ const { options = [] } = safeParseJson(block.json ?? "{}") ?? {};
1294
+ return /* @__PURE__ */ React5.createElement("div", {
1295
+ className: "flex flex-wrap gap-1"
1296
+ }, options.map((option, idx) => /* @__PURE__ */ React5.createElement(Button, {
1297
+ classNames: "animate-[fadeIn_0.5s] rounded-2xl text-sm",
1298
+ key: option,
1299
+ onClick: () => onPrompt?.(option)
1300
+ }, option)));
1301
+ }
1302
+ case "graph": {
1303
+ return /* @__PURE__ */ React5.createElement("div", {
1304
+ className: "flex flex-wrap gap-1"
1305
+ }, /* @__PURE__ */ React5.createElement(Surface, {
1306
+ role: "card",
1307
+ data: {
1308
+ subject: JSON.parse(block.json ?? "{}")
1309
+ },
1310
+ limit: 1,
1311
+ fallback: /* @__PURE__ */ React5.createElement("div", {
1312
+ className: "font-mono text-xs text-pre"
1313
+ }, block.json)
1314
+ }), onAddToGraph && /* @__PURE__ */ React5.createElement(IconButton2, {
1315
+ icon: "ph--plus--regular",
1316
+ label: "Add to graph",
1317
+ onClick: () => onAddToGraph?.(JSON.parse(block.json ?? "{}"))
1318
+ }));
1319
+ }
1320
+ default: {
1321
+ const title = block.disposition ? titles[block.disposition] : void 0;
1322
+ return /* @__PURE__ */ React5.createElement(ToggleContainer2, {
1323
+ title: title ?? "JSON"
1324
+ }, /* @__PURE__ */ React5.createElement(Json2, {
1325
+ data: safeParseJson(block.json ?? block),
1326
+ classNames: "!p-1 text-xs"
1327
+ }));
1328
+ }
1329
+ }
1330
+ },
1331
+ //
1332
+ // Default
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(ToggleContainer2, {
1340
+ title: title ?? "JSON"
1341
+ }, /* @__PURE__ */ React5.createElement(Json2, {
1342
+ data: block,
1343
+ classNames: "!p-1 text-xs"
1344
+ }));
1170
1345
  }
1171
1346
  };
1347
+ var titles = {
1348
+ ["cot"]: "Chain of thought",
1349
+ ["artifact"]: "Artifact",
1350
+ ["tool_use"]: "Tool request",
1351
+ ["tool_result"]: "Tool result",
1352
+ ["tool_list"]: "Tools",
1353
+ ["artifact-update"]: "Artifact(s) changed"
1354
+ };
1355
+ var systemDispositions = [
1356
+ "cot",
1357
+ "artifact-update"
1358
+ ];
1172
1359
 
1173
- // packages/plugins/plugin-assistant/src/components/Prompt/Prompt.tsx
1174
- var Prompt = /* @__PURE__ */ forwardRef(({ classNames, autoFocus, lineWrapping = false, placeholder, onSubmit, onSuggest, onOpenChange, references }, forwardRef2) => {
1175
- const { themeMode } = useThemeContext();
1176
- const { parentRef, view } = useTextEditor({
1177
- debug: true,
1178
- autoFocus,
1179
- extensions: [
1180
- createBasicExtensions({
1181
- bracketMatching: false,
1182
- lineWrapping,
1183
- placeholder
1184
- }),
1185
- createThemeExtensions({
1186
- themeMode
1187
- }),
1188
- references ? promptReferences({
1189
- provider: references
1190
- }) : [],
1191
- createAutocompleteExtension({
1192
- onSubmit,
1193
- onSuggest
1194
- }),
1195
- Prec2.highest(keymap3.of([
1196
- {
1197
- key: "cmd-ArrowUp",
1198
- preventDefault: true,
1199
- run: (view2) => {
1200
- onOpenChange?.(true);
1201
- return true;
1202
- }
1203
- },
1204
- {
1205
- key: "cmd-ArrowDown",
1206
- preventDefault: true,
1207
- run: (view2) => {
1208
- onOpenChange?.(false);
1209
- return true;
1210
- }
1360
+ // packages/plugins/plugin-assistant/src/components/Thread/reducer.ts
1361
+ var messageReducer = ({ current, messages }, message) => {
1362
+ let i = 0;
1363
+ for (const block of message.content) {
1364
+ switch (block.type) {
1365
+ case "tool_use":
1366
+ case "tool_result": {
1367
+ if (current) {
1368
+ current.content.push(block);
1369
+ } else {
1370
+ current = {
1371
+ id: [
1372
+ message.id,
1373
+ i
1374
+ ].join("_"),
1375
+ role: message.role,
1376
+ content: [
1377
+ block
1378
+ ]
1379
+ };
1380
+ messages.push(current);
1211
1381
  }
1212
- ]))
1213
- ]
1214
- }, [
1215
- themeMode,
1216
- onSubmit,
1217
- onSuggest
1218
- ]);
1219
- useImperativeHandle(forwardRef2, () => {
1220
- return {
1221
- focus: () => {
1222
- view?.focus();
1223
- },
1224
- setText: (text) => {
1225
- view?.dispatch({
1226
- changes: {
1227
- from: 0,
1228
- to: view.state.doc.length,
1229
- insert: text
1230
- },
1231
- selection: {
1232
- anchor: text.length,
1233
- head: text.length
1234
- }
1382
+ break;
1383
+ }
1384
+ case "text":
1385
+ default: {
1386
+ current = void 0;
1387
+ messages.push({
1388
+ id: [
1389
+ message.id,
1390
+ i
1391
+ ].join("_"),
1392
+ role: message.role,
1393
+ content: [
1394
+ block
1395
+ ]
1235
1396
  });
1397
+ break;
1236
1398
  }
1237
- };
1238
- }, [
1239
- view,
1240
- onSubmit
1241
- ]);
1242
- return /* @__PURE__ */ React4.createElement("div", {
1243
- ref: parentRef,
1244
- className: mx3("w-full", classNames)
1245
- });
1246
- });
1247
-
1248
- // packages/plugins/plugin-assistant/src/components/Prompt/PromptBar.tsx
1249
- import React5, { useRef as useRef2, useState as useState3 } from "react";
1250
- import { useVoiceInput } from "@dxos/plugin-transcription";
1251
- import { Icon as Icon2, IconButton as IconButton2, Tooltip, useTranslation } from "@dxos/react-ui";
1252
- import { Spinner } from "@dxos/react-ui-sfx";
1253
- import { errorMessageColors, errorText, mx as mx4 } from "@dxos/react-ui-theme";
1254
- var PromptBar = ({ classNames, placeholder, processing, error, microphone, onCancel, references, ...props }) => {
1255
- const { t } = useTranslation(ASSISTANT_PLUGIN);
1256
- const promptRef = useRef2(null);
1257
- const [active, setActive] = useState3(false);
1258
- const { recording } = useVoiceInput({
1259
- active,
1260
- onUpdate: (text) => {
1261
- promptRef.current?.setText(text);
1262
- promptRef.current?.focus();
1263
1399
  }
1264
- });
1265
- return /* @__PURE__ */ React5.createElement("div", {
1266
- className: mx4("shrink-0 w-full grid grid-cols-[var(--rail-action)_1fr_var(--rail-action)] overflow-hidden", classNames)
1267
- }, /* @__PURE__ */ React5.createElement("div", {
1268
- className: "flex w-[--rail-action] h-[--rail-action] items-center justify-center"
1269
- }, error && /* @__PURE__ */ React5.createElement(Tooltip.Root, {
1270
- delayDuration: 0
1271
- }, /* @__PURE__ */ React5.createElement(Tooltip.Trigger, null, /* @__PURE__ */ React5.createElement(Icon2, {
1272
- icon: "ph--warning-circle--regular",
1273
- classNames: errorText,
1274
- size: 5
1275
- })), /* @__PURE__ */ React5.createElement(Tooltip.Portal, null, /* @__PURE__ */ React5.createElement(Tooltip.Content, null, /* @__PURE__ */ React5.createElement("div", {
1276
- className: mx4("text-sm", errorMessageColors)
1277
- }, error.message), /* @__PURE__ */ React5.createElement(Tooltip.Arrow, null)))) || /* @__PURE__ */ React5.createElement(Spinner, {
1278
- active: processing
1279
- })), /* @__PURE__ */ React5.createElement(Prompt, {
1280
- ref: promptRef,
1281
- autoFocus: true,
1282
- classNames: "pbs-2",
1283
- lineWrapping: true,
1284
- placeholder: placeholder ?? t("prompt placeholder"),
1285
- references,
1286
- ...props
1287
- }), (onCancel || microphone) && /* @__PURE__ */ React5.createElement("div", {
1288
- className: "flex w-[--rail-action] h-[--rail-action] items-center justify-center"
1289
- }, processing && onCancel && /* @__PURE__ */ React5.createElement(IconButton2, {
1290
- classNames: "px-1.5",
1291
- variant: "ghost",
1292
- size: 5,
1293
- icon: "ph--x--regular",
1294
- iconOnly: true,
1295
- label: t("cancel processing button"),
1296
- onClick: onCancel
1297
- }), !processing && microphone && /* @__PURE__ */ React5.createElement(IconButton2, {
1298
- classNames: mx4("px-1.5", recording && "bg-primary-500"),
1299
- variant: "ghost",
1300
- size: 5,
1301
- icon: "ph--microphone--regular",
1302
- iconOnly: true,
1303
- noTooltip: true,
1304
- label: t("microphone button"),
1305
- onMouseDown: () => setActive(true),
1306
- onMouseUp: () => setActive(false),
1307
- onTouchStart: () => setActive(true),
1308
- onTouchEnd: () => setActive(false)
1309
- })));
1400
+ i++;
1401
+ }
1402
+ return {
1403
+ current,
1404
+ messages
1405
+ };
1310
1406
  };
1311
1407
 
1312
1408
  // packages/plugins/plugin-assistant/src/components/Thread/Thread.tsx
1313
1409
  var Thread = ({ classNames, space, messages, collapse = true, transcription, processing, error, onSubmit, onCancel, onOpenChange, contextProvider, ...props }) => {
1314
- const scroller = useRef3(null);
1315
- const identity = useIdentity();
1316
- const fallbackValue = keyToFallback(identity.identityKey);
1317
- const userHue = identity.profile?.data?.hue || fallbackValue.hue;
1318
- const handleSubmit = useCallback((value) => {
1319
- onSubmit?.(value);
1320
- scroller.current?.scrollToBottom();
1321
- return true;
1322
- }, [
1323
- onSubmit
1324
- ]);
1325
- const { messages: filteredMessages = [] } = useMemo2(() => {
1326
- if (collapse) {
1327
- return (messages ?? []).reduce(messageReducer, {
1328
- messages: []
1329
- });
1330
- } else {
1410
+ var _effect = _useSignals6();
1411
+ try {
1412
+ const scroller = useRef2(null);
1413
+ const identity = useIdentity();
1414
+ const fallbackValue = keyToFallback(identity.identityKey);
1415
+ const userHue = identity.profile?.data?.hue || fallbackValue.hue;
1416
+ const handleSubmit = useCallback((value) => {
1417
+ onSubmit?.(value);
1418
+ scroller.current?.scrollToBottom();
1419
+ return true;
1420
+ }, [
1421
+ onSubmit
1422
+ ]);
1423
+ const { messages: filteredMessages = [] } = useMemo2(() => {
1424
+ if (collapse) {
1425
+ return (messages ?? []).reduce(messageReducer, {
1426
+ messages: []
1427
+ });
1428
+ } else {
1429
+ return {
1430
+ messages: messages ?? []
1431
+ };
1432
+ }
1433
+ }, [
1434
+ messages,
1435
+ collapse
1436
+ ]);
1437
+ const references = useMemo2(() => {
1438
+ if (!contextProvider) {
1439
+ return void 0;
1440
+ }
1331
1441
  return {
1332
- messages: messages ?? []
1442
+ getReferences: async ({ query }) => contextProvider.query({
1443
+ query
1444
+ }),
1445
+ resolveReference: async ({ uri }) => contextProvider.resolveMetadata({
1446
+ uri
1447
+ })
1333
1448
  };
1334
- }
1335
- }, [
1336
- messages,
1337
- collapse
1338
- ]);
1339
- const references = useMemo2(() => {
1340
- if (!contextProvider) {
1341
- return void 0;
1342
- }
1343
- return {
1344
- getReferences: async ({ query }) => contextProvider.query({
1345
- query
1346
- }),
1347
- resolveReference: async ({ uri }) => contextProvider.resolveMetadata({
1348
- uri
1349
- })
1350
- };
1351
- }, [
1352
- contextProvider
1353
- ]);
1354
- return /* @__PURE__ */ React6.createElement("div", {
1355
- role: "none",
1356
- className: mx5("flex flex-col grow overflow-hidden", classNames)
1357
- }, /* @__PURE__ */ React6.createElement(ScrollContainer, {
1358
- ref: scroller,
1359
- fade: true
1360
- }, /* @__PURE__ */ React6.createElement("div", {
1361
- role: "none",
1362
- className: mx5(filteredMessages.length > 0 && "pbs-6 pbe-6"),
1363
- style: {
1364
- "--user-fill": `var(--dx-${userHue}Fill)`
1365
- }
1366
- }, filteredMessages.map((message) => /* @__PURE__ */ React6.createElement(ThreadMessage, {
1367
- key: message.id,
1368
- classNames: "px-4 pbe-4",
1369
- space,
1370
- message,
1371
- ...props
1372
- })))), onSubmit && /* @__PURE__ */ React6.createElement(PromptBar, {
1373
- microphone: transcription,
1374
- processing,
1375
- error,
1376
- onSubmit: handleSubmit,
1377
- onCancel,
1378
- onOpenChange,
1379
- references
1380
- }));
1449
+ }, [
1450
+ contextProvider
1451
+ ]);
1452
+ return /* @__PURE__ */ React6.createElement("div", {
1453
+ role: "none",
1454
+ className: mx5("flex flex-col grow overflow-hidden", classNames)
1455
+ }, /* @__PURE__ */ React6.createElement(ScrollContainer, {
1456
+ ref: scroller,
1457
+ fade: true
1458
+ }, /* @__PURE__ */ React6.createElement("div", {
1459
+ role: "none",
1460
+ className: mx5(filteredMessages.length > 0 && "pbs-6 pbe-6"),
1461
+ style: {
1462
+ "--user-fill": `var(--dx-${userHue}Fill)`
1463
+ }
1464
+ }, filteredMessages.map((message) => /* @__PURE__ */ React6.createElement(ThreadMessage, {
1465
+ key: message.id,
1466
+ classNames: "px-4 pbe-4",
1467
+ space,
1468
+ message,
1469
+ ...props
1470
+ })))), onSubmit && /* @__PURE__ */ React6.createElement(PromptBar, {
1471
+ microphone: transcription,
1472
+ processing,
1473
+ error,
1474
+ onSubmit: handleSubmit,
1475
+ onCancel,
1476
+ onOpenChange,
1477
+ references
1478
+ }));
1479
+ } finally {
1480
+ _effect.f();
1481
+ }
1381
1482
  };
1382
1483
 
1383
1484
  // packages/plugins/plugin-assistant/src/components/Thread/ThreadContainer.tsx
1384
- import React7, { useCallback as useCallback3 } from "react";
1385
- import { invariant as invariant6 } from "@dxos/invariant";
1386
- import { log as log10 } from "@dxos/log";
1485
+ import { useSignals as _useSignals9 } from "@preact-signals/safe-react/tracking";
1486
+ import React7, { useCallback as useCallback3, useEffect as useEffect5 } from "react";
1487
+ import { CollaborationActions, createIntent, useIntentDispatcher as useIntentDispatcher2 } from "@dxos/app-framework";
1488
+ import { invariant as invariant4 } from "@dxos/invariant";
1489
+ import { DXN } from "@dxos/keys";
1490
+ import { refFromDXN } from "@dxos/live-object";
1491
+ import { log as log8 } from "@dxos/log";
1387
1492
  import { getSpace as getSpace2 } from "@dxos/react-client/echo";
1388
1493
 
1389
1494
  // packages/plugins/plugin-assistant/src/hooks/processor.ts
1390
1495
  import { batch, computed, signal } from "@preact/signals-core";
1391
- import { AISession, DEFAULT_EDGE_MODEL } from "@dxos/assistant";
1496
+ import { DEFAULT_EDGE_MODEL } from "@dxos/ai";
1497
+ import { AISession } from "@dxos/assistant";
1392
1498
  import { invariant as invariant3 } from "@dxos/invariant";
1393
1499
  import { log as log5 } from "@dxos/log";
1500
+ import { Filter as Filter2, getVersion } from "@dxos/react-client/echo";
1394
1501
  var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-assistant/src/hooks/processor.ts";
1395
1502
  var defaultOptions = {
1396
1503
  model: DEFAULT_EDGE_MODEL,
@@ -1415,7 +1522,7 @@ var ChatProcessor = class {
1415
1522
  const current = messages.pop();
1416
1523
  invariant3(current, void 0, {
1417
1524
  F: __dxlog_file6,
1418
- L: 70,
1525
+ L: 79,
1419
1526
  S: this,
1420
1527
  A: [
1421
1528
  "current",
@@ -1434,6 +1541,24 @@ var ChatProcessor = class {
1434
1541
  }
1435
1542
  return messages;
1436
1543
  });
1544
+ this._artifactDiffResolver = async (artifacts) => {
1545
+ const space = this._extensions?.space;
1546
+ if (!space) {
1547
+ return /* @__PURE__ */ new Map();
1548
+ }
1549
+ const versions = /* @__PURE__ */ new Map();
1550
+ await Promise.all(artifacts.map(async (artifact) => {
1551
+ const { objects: [object] } = await space.db.query(Filter2.ids(artifact.id)).run();
1552
+ if (!object) {
1553
+ return;
1554
+ }
1555
+ versions.set(artifact.id, {
1556
+ version: getVersion(object),
1557
+ diff: `Current state: ${JSON.stringify(object)}`
1558
+ });
1559
+ }));
1560
+ return versions;
1561
+ };
1437
1562
  }
1438
1563
  get tools() {
1439
1564
  return this._tools;
@@ -1449,7 +1574,7 @@ var ChatProcessor = class {
1449
1574
  */
1450
1575
  async request(message, options = {}) {
1451
1576
  this._session = new AISession({
1452
- operationModel: "immediate"
1577
+ operationModel: "configured"
1453
1578
  });
1454
1579
  this._session.message.on((message2) => {
1455
1580
  batch(() => {
@@ -1471,24 +1596,55 @@ var ChatProcessor = class {
1471
1596
  message2
1472
1597
  ];
1473
1598
  });
1599
+ this._session.toolStatusReport.on(({ message: message2, status }) => {
1600
+ const msg = this._pending.peek().find((m) => m.id === message2.id);
1601
+ const toolUse = msg?.content.find((block2) => block2.type === "tool_use");
1602
+ if (!toolUse) {
1603
+ return;
1604
+ }
1605
+ const block = msg?.content.find((block2) => block2.type === "tool_use" && block2.id === toolUse.id);
1606
+ if (block) {
1607
+ this._pending.value = this._pending.value.map((m) => {
1608
+ if (m.id === message2.id) {
1609
+ return {
1610
+ ...m,
1611
+ content: m.content.map((b) => b.type === "tool_use" && b.id === toolUse.id ? {
1612
+ ...b,
1613
+ currentStatus: status
1614
+ } : b)
1615
+ };
1616
+ }
1617
+ return m;
1618
+ });
1619
+ } else {
1620
+ log5.warn("no block for status report", void 0, {
1621
+ F: __dxlog_file6,
1622
+ L: 155,
1623
+ S: this,
1624
+ C: (f, a) => f(...a)
1625
+ });
1626
+ }
1627
+ });
1474
1628
  try {
1475
1629
  const messages = await this._session.run({
1476
1630
  client: this._ai,
1477
1631
  history: options.history ?? [],
1478
1632
  artifacts: this._artifacts ?? [],
1633
+ requiredArtifactIds: this._artifacts?.map((artifact) => artifact.id) ?? [],
1479
1634
  tools: this._tools ?? [],
1480
1635
  prompt: message,
1481
1636
  systemPrompt: this._options.systemPrompt,
1482
1637
  extensions: this._extensions,
1638
+ artifactDiffResolver: this._artifactDiffResolver,
1483
1639
  generationOptions: {
1484
1640
  model: this._options.model
1485
1641
  }
1486
1642
  });
1487
- log5.info("completed", {
1643
+ log5("completed", {
1488
1644
  messages
1489
1645
  }, {
1490
1646
  F: __dxlog_file6,
1491
- L: 137,
1647
+ L: 175,
1492
1648
  S: this,
1493
1649
  C: (f, a) => f(...a)
1494
1650
  });
@@ -1496,7 +1652,7 @@ var ChatProcessor = class {
1496
1652
  } catch (err) {
1497
1653
  log5.catch(err, void 0, {
1498
1654
  F: __dxlog_file6,
1499
- L: 141,
1655
+ L: 178,
1500
1656
  S: this,
1501
1657
  C: (f, a) => f(...a)
1502
1658
  });
@@ -1521,7 +1677,7 @@ var ChatProcessor = class {
1521
1677
  async cancel() {
1522
1678
  log5.info("cancelling...", void 0, {
1523
1679
  F: __dxlog_file6,
1524
- L: 159,
1680
+ L: 196,
1525
1681
  S: this,
1526
1682
  C: (f, a) => f(...a)
1527
1683
  });
@@ -1545,170 +1701,159 @@ var AIServiceOverloadedError = class extends Error {
1545
1701
  };
1546
1702
 
1547
1703
  // packages/plugins/plugin-assistant/src/hooks/useChatProcessor.tsx
1704
+ import { useSignals as _useSignals7 } from "@preact-signals/safe-react/tracking";
1548
1705
  import { useEffect as useEffect3, useMemo as useMemo3, useState as useState4 } from "react";
1706
+ import { DEFAULT_EDGE_MODEL as DEFAULT_EDGE_MODEL2, DEFAULT_OLLAMA_MODEL } from "@dxos/ai";
1549
1707
  import { Capabilities as Capabilities2, useCapabilities as useCapabilities2, useCapability, useIntentDispatcher } from "@dxos/app-framework";
1550
1708
  import { createSystemPrompt } from "@dxos/artifact";
1551
- import { DEFAULT_EDGE_MODEL as DEFAULT_EDGE_MODEL2, DEFAULT_OLLAMA_MODEL } from "@dxos/assistant";
1552
- import { FunctionType as FunctionType2 } from "@dxos/functions/types";
1709
+ import { FunctionType as FunctionType2 } from "@dxos/functions";
1553
1710
  import { log as log6 } from "@dxos/log";
1554
1711
  import { useConfig } from "@dxos/react-client";
1555
- import { Filter as Filter2, fullyQualifiedId, useQuery as useQuery2 } from "@dxos/react-client/echo";
1556
- import { isNonNullable as isNonNullable2 } from "@dxos/util";
1712
+ import { Filter as Filter3, fullyQualifiedId, useQuery as useQuery2 } from "@dxos/react-client/echo";
1713
+ import { isNonNullable as isNonNullable3 } from "@dxos/util";
1557
1714
 
1558
1715
  // packages/plugins/plugin-assistant/src/capabilities/index.ts
1559
1716
  import { lazy } from "@dxos/app-framework";
1560
- var AiClient = lazy(() => import("./ai-client-WMHS5EGV.mjs"));
1561
- var AppGraphBuilder = lazy(() => import("./app-graph-builder-DWBNIMHM.mjs"));
1562
- var IntentResolver = lazy(() => import("./intent-resolver-H32TL4X6.mjs"));
1563
- var ReactSurface = lazy(() => import("./react-surface-JBVZF6CP.mjs"));
1564
- var AssistantSettings = lazy(() => import("./settings-DZU5PNXM.mjs"));
1717
+ var AiClient = lazy(() => import("./ai-client-I5LXHMOZ.mjs"));
1718
+ var AppGraphBuilder = lazy(() => import("./app-graph-builder-Z3GMMJMD.mjs"));
1719
+ var IntentResolver = lazy(() => import("./intent-resolver-X3PWH7KM.mjs"));
1720
+ var ReactSurface = lazy(() => import("./react-surface-QMIQCXUM.mjs"));
1721
+ var Settings = lazy(() => import("./settings-IVQRZUCU.mjs"));
1565
1722
 
1566
1723
  // packages/plugins/plugin-assistant/src/hooks/useChatProcessor.tsx
1567
1724
  var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-assistant/src/hooks/useChatProcessor.tsx";
1568
- var useChatProcessor = ({ chat, space, settings, part = "deck", associatedArtifact }) => {
1569
- const aiClient = useCapability(AssistantCapabilities.AiClient);
1570
- const globalTools = useCapabilities2(Capabilities2.Tools);
1571
- const artifactDefinitions = useCapabilities2(Capabilities2.ArtifactDefinition);
1572
- const { dispatchPromise: dispatch } = useIntentDispatcher();
1573
- const services = useQuery2(space, Filter2.schema(ServiceType));
1574
- const [serviceTools, setServiceTools] = useState4([]);
1575
- useEffect3(() => {
1576
- log6("creating service tools...", void 0, {
1577
- F: __dxlog_file7,
1578
- L: 48,
1579
- S: void 0,
1580
- C: (f, a) => f(...a)
1581
- });
1582
- queueMicrotask(async () => {
1583
- const tools2 = await Promise.all(services.map((service) => createToolsFromService(service)));
1584
- setServiceTools(tools2.flat());
1585
- });
1586
- }, [
1587
- services
1588
- ]);
1589
- const config = useConfig();
1590
- const functions = useQuery2(space, Filter2.schema(FunctionType2));
1591
- const chatId = useMemo3(() => chat ? fullyQualifiedId(chat) : void 0, [
1592
- chat
1593
- ]);
1594
- const [tools, extensions] = useMemo3(() => {
1595
- log6("creating tools...", void 0, {
1596
- F: __dxlog_file7,
1597
- L: 60,
1598
- S: void 0,
1599
- C: (f, a) => f(...a)
1600
- });
1601
- const tools2 = [
1602
- ...globalTools.flat(),
1603
- ...serviceTools,
1604
- ...functions.map((fn) => covertFunctionToTool(fn, config.values.runtime?.services?.edge?.url ?? "", space?.id)).filter(isNonNullable2)
1605
- ];
1606
- const extensions2 = {
1607
- space,
1725
+ var useChatProcessor = ({
1726
+ chat,
1727
+ space,
1728
+ settings,
1729
+ // part = 'deck',
1730
+ part,
1731
+ associatedArtifact
1732
+ }) => {
1733
+ var _effect = _useSignals7();
1734
+ try {
1735
+ const aiClient = useCapability(AssistantCapabilities.AiClient);
1736
+ const globalTools = useCapabilities2(Capabilities2.Tools);
1737
+ const artifactDefinitions = useCapabilities2(Capabilities2.ArtifactDefinition);
1738
+ const { dispatchPromise: dispatch } = useIntentDispatcher();
1739
+ const services = useQuery2(space, Filter3.type(ServiceType));
1740
+ const [serviceTools, setServiceTools] = useState4([]);
1741
+ useEffect3(() => {
1742
+ log6("creating service tools...", void 0, {
1743
+ F: __dxlog_file7,
1744
+ L: 49,
1745
+ S: void 0,
1746
+ C: (f, a) => f(...a)
1747
+ });
1748
+ queueMicrotask(async () => {
1749
+ const tools2 = await Promise.all(services.map((service) => createToolsFromService(service)));
1750
+ setServiceTools(tools2.flat());
1751
+ });
1752
+ }, [
1753
+ services
1754
+ ]);
1755
+ const config = useConfig();
1756
+ const functions = useQuery2(space, Filter3.type(FunctionType2));
1757
+ const chatId = useMemo3(() => chat ? fullyQualifiedId(chat) : void 0, [
1758
+ chat
1759
+ ]);
1760
+ const [tools, extensions] = useMemo3(() => {
1761
+ log6("creating tools...", void 0, {
1762
+ F: __dxlog_file7,
1763
+ L: 61,
1764
+ S: void 0,
1765
+ C: (f, a) => f(...a)
1766
+ });
1767
+ const tools2 = [
1768
+ ...globalTools.flat(),
1769
+ ...serviceTools,
1770
+ ...functions.map((fn) => convertFunctionToTool(fn, config.values.runtime?.services?.edge?.url ?? "", space?.id)).filter(isNonNullable3)
1771
+ ];
1772
+ const extensions2 = {
1773
+ space,
1774
+ dispatch,
1775
+ pivotId: chatId,
1776
+ part
1777
+ };
1778
+ return [
1779
+ tools2,
1780
+ extensions2
1781
+ ];
1782
+ }, [
1608
1783
  dispatch,
1609
- pivotId: chatId,
1610
- part
1611
- };
1612
- return [
1613
- tools2,
1614
- extensions2
1615
- ];
1616
- }, [
1617
- dispatch,
1618
- globalTools,
1619
- space,
1620
- chatId,
1621
- serviceTools,
1622
- functions
1623
- ]);
1624
- const systemPrompt = useMemo3(() => createSystemPrompt({
1625
- artifacts: artifactDefinitions.map((definition) => `${definition.name}
1784
+ globalTools,
1785
+ space,
1786
+ chatId,
1787
+ serviceTools,
1788
+ functions
1789
+ ]);
1790
+ const systemPrompt = useMemo3(() => createSystemPrompt({
1791
+ artifacts: artifactDefinitions.map((definition) => `${definition.name}
1626
1792
  ${definition.instructions}`),
1627
- associatedArtifact
1628
- }), [
1629
- artifactDefinitions,
1630
- associatedArtifact
1631
- ]);
1632
- const model = settings?.llmProvider === "ollama" ? settings?.ollamaModel ?? DEFAULT_OLLAMA_MODEL : settings?.edgeModel ?? DEFAULT_EDGE_MODEL2;
1633
- const processor = useMemo3(() => {
1634
- log6("creating processor...", {
1635
- settings
1636
- }, {
1637
- F: __dxlog_file7,
1638
- L: 91,
1639
- S: void 0,
1640
- C: (f, a) => f(...a)
1641
- });
1642
- return new ChatProcessor(aiClient.value, tools, artifactDefinitions, extensions, {
1793
+ associatedArtifact
1794
+ }), [
1795
+ artifactDefinitions,
1796
+ associatedArtifact
1797
+ ]);
1798
+ const model = settings?.llmProvider === "ollama" ? settings?.ollamaModel ?? DEFAULT_OLLAMA_MODEL : settings?.edgeModel ?? DEFAULT_EDGE_MODEL2;
1799
+ const processor = useMemo3(() => {
1800
+ log6("creating processor...", {
1801
+ settings
1802
+ }, {
1803
+ F: __dxlog_file7,
1804
+ L: 92,
1805
+ S: void 0,
1806
+ C: (f, a) => f(...a)
1807
+ });
1808
+ return new ChatProcessor(aiClient.value, tools, artifactDefinitions, extensions, {
1809
+ model,
1810
+ systemPrompt
1811
+ });
1812
+ }, [
1813
+ aiClient.value,
1814
+ tools,
1815
+ artifactDefinitions,
1816
+ extensions,
1643
1817
  model,
1644
1818
  systemPrompt
1645
- });
1646
- }, [
1647
- aiClient.value,
1648
- tools,
1649
- extensions,
1650
- model,
1651
- systemPrompt
1652
- ]);
1653
- return processor;
1819
+ ]);
1820
+ return processor;
1821
+ } finally {
1822
+ _effect.f();
1823
+ }
1654
1824
  };
1655
1825
 
1656
- // packages/plugins/plugin-assistant/src/hooks/useLocalTriggerManager.ts
1657
- import { useEffect as useEffect4, useState as useState5 } from "react";
1658
- import { Mutex as Mutex2 } from "@dxos/async";
1659
- import { Context } from "@dxos/context";
1660
- import { createSubscriptionTrigger } from "@dxos/functions";
1661
- import { FunctionTrigger } from "@dxos/functions/types";
1662
- import { invariant as invariant5 } from "@dxos/invariant";
1663
- import { log as log8 } from "@dxos/log";
1664
- import { useClient } from "@dxos/react-client";
1665
- import { Filter as Filter3, useQuery as useQuery3 } from "@dxos/react-client/echo";
1666
-
1667
- // packages/plugins/plugin-assistant/src/hooks/invocation-handler.ts
1668
- import { sleep } from "@dxos/async";
1669
- import { getObjectCore, ResultFormat } from "@dxos/echo-db";
1670
- import { FunctionType as FunctionType3, getUserFunctionUrlInMetadata as getUserFunctionUrlInMetadata2 } from "@dxos/functions/types";
1671
- import { invariant as invariant4 } from "@dxos/invariant";
1672
- import { DXN, LOCAL_SPACE_TAG } from "@dxos/keys";
1673
- import { log as log7 } from "@dxos/log";
1674
-
1675
- // packages/plugins/plugin-assistant/src/hooks/useLocalTriggerManager.ts
1676
- var registerTriggersMutex = new Mutex2();
1677
-
1678
1826
  // packages/plugins/plugin-assistant/src/hooks/useMessageQueue.ts
1679
1827
  import { useMemo as useMemo4 } from "react";
1680
- import { DXN as DXN2, QueueSubspaceTags } from "@dxos/keys";
1828
+ import { createQueueDxn } from "@dxos/echo-schema";
1681
1829
  import { getSpace, useQueue } from "@dxos/react-client/echo";
1682
1830
  var useMessageQueue = (chat) => {
1683
1831
  const space = getSpace(chat);
1684
1832
  const queueDxn = useMemo4(() => {
1685
- const dxn = space && chat?.assistantChatQueue.dxn;
1686
- return dxn ? new DXN2(DXN2.kind.QUEUE, [
1687
- QueueSubspaceTags.DATA,
1688
- space.id,
1689
- dxn.parts.at(-1)
1690
- ]) : void 0;
1833
+ const dxn = space && chat?.queue.dxn;
1834
+ return dxn ? createQueueDxn(space.id, dxn.parts.at(-1)) : void 0;
1691
1835
  }, [
1692
1836
  space,
1693
- chat?.assistantChatQueue.dxn
1837
+ chat?.queue.dxn
1694
1838
  ]);
1695
1839
  return useQueue(queueDxn);
1696
1840
  };
1697
1841
 
1698
1842
  // packages/plugins/plugin-assistant/src/hooks/useServices.ts
1699
- import { useEffect as useEffect5, useMemo as useMemo5, useState as useState6 } from "react";
1843
+ import { useEffect as useEffect4, useMemo as useMemo5, useState as useState5 } from "react";
1844
+
1845
+ // packages/plugins/plugin-assistant/src/testing/blueprint.ts
1846
+ import { EXA_API_KEY } from "@dxos/ai/testing";
1847
+ import { createExaTool, createGraphWriterTool, createLocalSearchTool } from "@dxos/assistant";
1848
+ import { DataTypes } from "@dxos/schema";
1849
+ import { isNonNullable as isNonNullable4 } from "@dxos/util";
1700
1850
 
1701
1851
  // packages/plugins/plugin-assistant/src/testing/test-functions.ts
1852
+ import { DEFAULT_EDGE_MODEL as DEFAULT_EDGE_MODEL3 } from "@dxos/ai";
1702
1853
  import { createSystemPrompt as createSystemPrompt2 } from "@dxos/artifact";
1703
- import { DEFAULT_EDGE_MODEL as DEFAULT_EDGE_MODEL3 } from "@dxos/assistant";
1704
1854
 
1705
1855
  // packages/plugins/plugin-assistant/src/testing/test-services.ts
1706
- import { createStatic } from "@dxos/echo-schema";
1707
- var MockServiceRegistry = class {
1708
- async queryServices(query) {
1709
- return TEST_SERVICES;
1710
- }
1711
- };
1856
+ import { create } from "@dxos/echo-schema";
1712
1857
  var AMADEUS_AUTH = {
1713
1858
  type: "oauth",
1714
1859
  clientId: "BOEnpLd1sMyKjAPGKYeAPFFy60u53QEG",
@@ -1725,7 +1870,7 @@ var VISUAL_CROSSING_CREDENTIALS = {
1725
1870
  }
1726
1871
  };
1727
1872
  var TEST_SERVICES = [
1728
- createStatic(ServiceType, {
1873
+ create(ServiceType, {
1729
1874
  serviceId: "amadeus.com/service/FlightSearch",
1730
1875
  name: "Amadeus Flight Search",
1731
1876
  description: "Search for local and international flights.",
@@ -1738,7 +1883,7 @@ var TEST_SERVICES = [
1738
1883
  }
1739
1884
  ]
1740
1885
  }),
1741
- createStatic(ServiceType, {
1886
+ create(ServiceType, {
1742
1887
  serviceId: "amadeus.com/service/HotelSearch",
1743
1888
  name: "Amadeus Hotel Search",
1744
1889
  description: "Search for local and international hotels.",
@@ -1751,7 +1896,7 @@ var TEST_SERVICES = [
1751
1896
  }
1752
1897
  ]
1753
1898
  }),
1754
- createStatic(ServiceType, {
1899
+ create(ServiceType, {
1755
1900
  serviceId: "visualcrossing.com/service/Weather",
1756
1901
  name: "Visual Crossing Weather",
1757
1902
  description: "Search for global weather forecasts.",
@@ -1765,7 +1910,7 @@ var TEST_SERVICES = [
1765
1910
  ]
1766
1911
  }),
1767
1912
  // TODO(burdon): Needs auth.
1768
- createStatic(ServiceType, {
1913
+ create(ServiceType, {
1769
1914
  serviceId: "abstractapi.com/service/GeoLocation",
1770
1915
  name: "Abstract GeoLocation",
1771
1916
  description: "Get the location of any IP address.",
@@ -1782,7 +1927,7 @@ var TEST_SERVICES = [
1782
1927
  //
1783
1928
  ...Array.from({
1784
1929
  length: 20
1785
- }, (_, i) => createStatic(ServiceType, {
1930
+ }, (_, i) => create(ServiceType, {
1786
1931
  serviceId: `example.com/service/test-${i}`,
1787
1932
  name: `Test ${i}`,
1788
1933
  description: `Test ${i}`,
@@ -1796,32 +1941,17 @@ var TEST_SERVICES = [
1796
1941
  }))
1797
1942
  ];
1798
1943
 
1799
- // packages/plugins/plugin-assistant/src/hooks/useServices.ts
1800
- var useServices = (space, query) => {
1801
- const registry = useMemo5(() => new MockServiceRegistry(), []);
1802
- const [services, setServices] = useState6([]);
1803
- useEffect5(() => {
1804
- const t = setTimeout(async () => {
1805
- const services2 = await registry.queryServices(query);
1806
- setServices(services2);
1807
- });
1808
- return () => clearTimeout(t);
1809
- }, [
1810
- query,
1811
- registry
1812
- ]);
1813
- return services;
1814
- };
1815
-
1816
1944
  // packages/plugins/plugin-assistant/src/hooks/useTextInputEvents.ts
1817
- import { useState as useState7, useCallback as useCallback2 } from "react";
1945
+ import { useSignals as _useSignals8 } from "@preact-signals/safe-react/tracking";
1946
+ import { useState as useState6, useCallback as useCallback2 } from "react";
1818
1947
 
1819
1948
  // packages/plugins/plugin-assistant/src/hooks/useContextProvider.ts
1820
1949
  import { useMemo as useMemo6 } from "react";
1821
1950
  import { Capabilities as Capabilities3, useCapabilities as useCapabilities3 } from "@dxos/app-framework";
1822
- import { getDXN, getLabel, getSchema } from "@dxos/echo-schema";
1823
- import { log as log9 } from "@dxos/log";
1824
- import { Filter as Filter4 } from "@dxos/react-client/echo";
1951
+ import { Filter as Filter4 } from "@dxos/client/echo";
1952
+ import { Obj } from "@dxos/echo";
1953
+ import { getDXN, getLabel } from "@dxos/echo-schema";
1954
+ import { log as log7 } from "@dxos/log";
1825
1955
  var __dxlog_file8 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-assistant/src/hooks/useContextProvider.ts";
1826
1956
  var stringMatch = (query, label) => label.toLowerCase().startsWith(query.toLowerCase());
1827
1957
  var useContextProvider = (space) => {
@@ -1833,30 +1963,28 @@ var useContextProvider = (space) => {
1833
1963
  return {
1834
1964
  query: async ({ query }) => {
1835
1965
  const artifactSchemas = artifactDefinitions.map((artifact) => artifact.schema);
1836
- const { objects } = await space.db.query(Filter4.or(...artifactSchemas.map((schema) => Filter4.schema(schema)))).run();
1966
+ const { objects } = await space.db.query(Filter4.or(...artifactSchemas.map((schema) => Filter4.type(schema)))).run();
1837
1967
  return objects.map((object) => {
1838
- log9.info("object", {
1968
+ log7.info("object", {
1839
1969
  object,
1840
- label: getLabel(getSchema(object), object)
1970
+ label: getLabel(Obj.getSchema(object), object)
1841
1971
  }, {
1842
1972
  F: __dxlog_file8,
1843
- L: 36,
1973
+ L: 38,
1844
1974
  S: void 0,
1845
1975
  C: (f, a) => f(...a)
1846
1976
  });
1847
1977
  return object;
1848
- }).filter((object) => stringMatch(query, getLabel(getSchema(object), object) ?? "")).filter((object) => !!getDXN(object)).map((object) => ({
1978
+ }).filter((object) => stringMatch(query, getLabel(Obj.getSchema(object), object) ?? "")).filter((object) => !!getDXN(object)).map((object) => ({
1849
1979
  uri: getDXN(object).toString(),
1850
- label: getLabel(getSchema(object), object) ?? ""
1980
+ label: getLabel(Obj.getSchema(object), object) ?? ""
1851
1981
  }));
1852
1982
  },
1853
1983
  resolveMetadata: async ({ uri }) => {
1854
- const object = await space.db.query({
1855
- id: uri
1856
- }).first();
1984
+ const object = await space.db.query(Filter4.ids(uri)).first();
1857
1985
  return {
1858
1986
  uri,
1859
- label: getLabel(getSchema(object), object) ?? ""
1987
+ label: getLabel(Obj.getSchema(object), object) ?? ""
1860
1988
  };
1861
1989
  }
1862
1990
  };
@@ -1869,85 +1997,111 @@ var useContextProvider = (space) => {
1869
1997
  // packages/plugins/plugin-assistant/src/components/Thread/ThreadContainer.tsx
1870
1998
  var __dxlog_file9 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-assistant/src/components/Thread/ThreadContainer.tsx";
1871
1999
  var ThreadContainer = ({ classNames, chat, settings, part, associatedArtifact, onOpenChange, ...props }) => {
1872
- const space = getSpace2(chat);
1873
- const contextProvider = useContextProvider(space);
1874
- const processor = useChatProcessor({
1875
- chat,
1876
- space,
1877
- settings,
1878
- part,
1879
- associatedArtifact
1880
- });
1881
- const messageQueue = useMessageQueue(chat);
1882
- const messages = [
1883
- ...messageQueue?.items ?? [],
1884
- ...processor.messages.value
1885
- ];
1886
- const handleSubmit = useCallback3((text) => {
1887
- if (processor.streaming.value) {
1888
- log10.warn("ignoring submit; still processing.", void 0, {
2000
+ var _effect = _useSignals9();
2001
+ try {
2002
+ const space = getSpace2(chat);
2003
+ const contextProvider = useContextProvider(space);
2004
+ const processor = useChatProcessor({
2005
+ chat,
2006
+ space,
2007
+ settings,
2008
+ part,
2009
+ associatedArtifact
2010
+ });
2011
+ const messageQueue = useMessageQueue(chat);
2012
+ const { dispatchPromise: dispatch } = useIntentDispatcher2();
2013
+ const messages = [
2014
+ ...messageQueue?.objects ?? [],
2015
+ ...processor.messages.value
2016
+ ];
2017
+ useEffect5(() => {
2018
+ if (!processor.streaming.value && messageQueue?.objects) {
2019
+ const message = messageQueue.objects[messageQueue.objects.length - 1];
2020
+ if (space && chat && message && dispatch && associatedArtifact) {
2021
+ void dispatch(createIntent(CollaborationActions.InsertContent, {
2022
+ target: associatedArtifact,
2023
+ object: refFromDXN(new DXN(DXN.kind.QUEUE, [
2024
+ ...chat.queue.dxn.parts,
2025
+ message.id
2026
+ ])),
2027
+ label: "View proposal"
2028
+ }));
2029
+ }
2030
+ }
2031
+ }, [
2032
+ messageQueue,
2033
+ associatedArtifact,
2034
+ processor.streaming.value
2035
+ ]);
2036
+ const handleSubmit = useCallback3((text) => {
2037
+ if (processor.streaming.value) {
2038
+ log8.warn("ignoring submit; still processing.", void 0, {
2039
+ F: __dxlog_file9,
2040
+ L: 65,
2041
+ S: void 0,
2042
+ C: (f, a) => f(...a)
2043
+ });
2044
+ return false;
2045
+ }
2046
+ onOpenChange?.(true);
2047
+ invariant4(messageQueue, void 0, {
1889
2048
  F: __dxlog_file9,
1890
- L: 44,
2049
+ L: 71,
1891
2050
  S: void 0,
1892
- C: (f, a) => f(...a)
2051
+ A: [
2052
+ "messageQueue",
2053
+ ""
2054
+ ]
1893
2055
  });
1894
- return false;
1895
- }
1896
- onOpenChange?.(true);
1897
- invariant6(messageQueue, void 0, {
1898
- F: __dxlog_file9,
1899
- L: 50,
1900
- S: void 0,
1901
- A: [
1902
- "messageQueue",
1903
- ""
1904
- ]
1905
- });
1906
- void processor.request(text, {
1907
- history: messageQueue.items,
1908
- onComplete: (messages2) => {
1909
- messageQueue.append(messages2);
2056
+ void processor.request(text, {
2057
+ history: messageQueue.objects,
2058
+ onComplete: (messages2) => {
2059
+ messageQueue.append(messages2);
2060
+ }
2061
+ });
2062
+ return true;
2063
+ }, [
2064
+ processor,
2065
+ messageQueue,
2066
+ onOpenChange
2067
+ ]);
2068
+ const handleCancel = useCallback3(() => {
2069
+ if (processor.streaming.value) {
2070
+ void processor.cancel();
1910
2071
  }
2072
+ }, [
2073
+ processor
2074
+ ]);
2075
+ return /* @__PURE__ */ React7.createElement(Thread, {
2076
+ classNames,
2077
+ space,
2078
+ messages,
2079
+ processing: processor.streaming.value,
2080
+ error: processor.error.value,
2081
+ tools: processor.tools,
2082
+ contextProvider,
2083
+ onSubmit: handleSubmit,
2084
+ onCancel: handleCancel,
2085
+ onPrompt: handleSubmit,
2086
+ onOpenChange,
2087
+ ...props
1911
2088
  });
1912
- return true;
1913
- }, [
1914
- processor,
1915
- messageQueue,
1916
- onOpenChange
1917
- ]);
1918
- const handleCancel = useCallback3(() => {
1919
- if (processor.streaming.value) {
1920
- void processor.cancel();
1921
- }
1922
- }, [
1923
- processor
1924
- ]);
1925
- return /* @__PURE__ */ React7.createElement(Thread, {
1926
- classNames,
1927
- space,
1928
- messages,
1929
- processing: processor.streaming.value,
1930
- error: processor.error.value,
1931
- tools: processor.tools,
1932
- onSubmit: handleSubmit,
1933
- onCancel: handleCancel,
1934
- onPrompt: handleSubmit,
1935
- onOpenChange,
1936
- contextProvider,
1937
- ...props
1938
- });
2089
+ } finally {
2090
+ _effect.f();
2091
+ }
1939
2092
  };
1940
2093
 
1941
2094
  export {
2095
+ Prompt,
2096
+ PromptBar,
2097
+ Toolbox,
2098
+ ToolboxContainer,
2099
+ Thread,
1942
2100
  AiClient,
1943
2101
  AppGraphBuilder,
1944
2102
  IntentResolver,
1945
2103
  ReactSurface,
1946
- AssistantSettings,
1947
- useServices,
1948
- Toolbox,
1949
- ToolboxContainer,
1950
- Thread,
2104
+ Settings,
1951
2105
  ThreadContainer
1952
2106
  };
1953
- //# sourceMappingURL=chunk-MVDAY3CZ.mjs.map
2107
+ //# sourceMappingURL=chunk-SI5LOQEO.mjs.map