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