@dxos/plugin-assistant 0.8.0 → 0.8.1-main.81238a8

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 (234) hide show
  1. package/dist/lib/browser/{AssistantDialog-TX6YYBUG.mjs → AssistantDialog-L5RHNMU4.mjs} +6 -5
  2. package/dist/lib/browser/{AssistantDialog-TX6YYBUG.mjs.map → AssistantDialog-L5RHNMU4.mjs.map} +3 -3
  3. package/dist/lib/browser/{ChatContainer-AT3OAUT3.mjs → ChatContainer-EEEVE62F.mjs} +5 -5
  4. package/dist/lib/browser/TemplateContainer-7IQ6V5AD.mjs +78 -0
  5. package/dist/lib/browser/TemplateContainer-7IQ6V5AD.mjs.map +7 -0
  6. package/dist/lib/browser/ai-client-BAPVMSNX.mjs +35 -0
  7. package/dist/lib/browser/ai-client-BAPVMSNX.mjs.map +7 -0
  8. package/dist/lib/browser/{app-graph-builder-AXAIFOGV.mjs → app-graph-builder-DTCUWBKB.mjs} +57 -13
  9. package/dist/lib/browser/app-graph-builder-DTCUWBKB.mjs.map +7 -0
  10. package/dist/lib/browser/{chunk-G7B54APW.mjs → chunk-5RMJYOT7.mjs} +34 -12
  11. package/dist/lib/browser/chunk-5RMJYOT7.mjs.map +7 -0
  12. package/dist/lib/browser/{chunk-EUMPBC4T.mjs → chunk-6FTPLBSC.mjs} +2 -2
  13. package/dist/lib/browser/{chunk-NV7SVHMV.mjs → chunk-AF7VQAKS.mjs} +1 -1
  14. package/dist/lib/browser/{chunk-NV7SVHMV.mjs.map → chunk-AF7VQAKS.mjs.map} +2 -2
  15. package/dist/lib/browser/{chunk-VZ4W6SHE.mjs → chunk-SVUCJXGN.mjs} +2 -2
  16. package/dist/lib/browser/chunk-SVUCJXGN.mjs.map +7 -0
  17. package/dist/lib/browser/{chunk-FRIKXDDQ.mjs → chunk-X6ALDUA5.mjs} +26 -4
  18. package/dist/lib/browser/chunk-X6ALDUA5.mjs.map +7 -0
  19. package/dist/lib/browser/{chunk-NFVIZS3B.mjs → chunk-XFUCWOMV.mjs} +287 -70
  20. package/dist/lib/browser/chunk-XFUCWOMV.mjs.map +7 -0
  21. package/dist/lib/browser/index.mjs +21 -11
  22. package/dist/lib/browser/index.mjs.map +3 -3
  23. package/dist/lib/browser/{intent-resolver-QRVRZL6K.mjs → intent-resolver-U57FXP3I.mjs} +6 -3
  24. package/dist/lib/browser/{intent-resolver-QRVRZL6K.mjs.map → intent-resolver-U57FXP3I.mjs.map} +3 -3
  25. package/dist/lib/browser/meta.json +1 -1
  26. package/dist/lib/browser/{react-surface-JLXNWOI6.mjs → react-surface-KFLHNDNR.mjs} +10 -9
  27. package/dist/lib/browser/react-surface-KFLHNDNR.mjs.map +7 -0
  28. package/dist/lib/browser/{settings-JTT62IHD.mjs → settings-VAW6UWFL.mjs} +3 -3
  29. package/dist/lib/browser/types/index.mjs +6 -2
  30. package/dist/lib/node/{AssistantDialog-U4GBPZD6.cjs → AssistantDialog-VIB7GPQN.cjs} +12 -11
  31. package/dist/lib/node/{AssistantDialog-U4GBPZD6.cjs.map → AssistantDialog-VIB7GPQN.cjs.map} +3 -3
  32. package/dist/lib/node/{ChatContainer-CVHXNHGA.cjs → ChatContainer-BPI3GEZS.cjs} +10 -10
  33. package/dist/lib/node/TemplateContainer-VPAZRFQA.cjs +104 -0
  34. package/dist/lib/node/TemplateContainer-VPAZRFQA.cjs.map +7 -0
  35. package/dist/lib/node/{ai-client-YANJEPO3.cjs → ai-client-5ESLYXAV.cjs} +19 -8
  36. package/dist/lib/node/ai-client-5ESLYXAV.cjs.map +7 -0
  37. package/dist/lib/node/{app-graph-builder-D7SHQTZS.cjs → app-graph-builder-3P6WSON2.cjs} +63 -20
  38. package/dist/lib/node/app-graph-builder-3P6WSON2.cjs.map +7 -0
  39. package/dist/lib/node/{chunk-37GI4NYH.cjs → chunk-KLSNCP34.cjs} +33 -9
  40. package/dist/lib/node/chunk-KLSNCP34.cjs.map +7 -0
  41. package/dist/lib/node/{chunk-NV4TQQSU.cjs → chunk-N3SW6DJ6.cjs} +6 -6
  42. package/dist/lib/node/{chunk-XUTDR7HI.cjs → chunk-OJJ4F6KP.cjs} +291 -78
  43. package/dist/lib/node/chunk-OJJ4F6KP.cjs.map +7 -0
  44. package/dist/lib/node/{chunk-GNPXCHFT.cjs → chunk-U6J2GO7I.cjs} +4 -4
  45. package/dist/lib/node/{chunk-GNPXCHFT.cjs.map → chunk-U6J2GO7I.cjs.map} +2 -2
  46. package/dist/lib/node/{chunk-ZGH6F5YA.cjs → chunk-VRXFIS4X.cjs} +6 -6
  47. package/dist/lib/node/chunk-VRXFIS4X.cjs.map +7 -0
  48. package/dist/lib/node/{chunk-IXJCGW7U.cjs → chunk-WFVOWPKV.cjs} +40 -18
  49. package/dist/lib/node/chunk-WFVOWPKV.cjs.map +7 -0
  50. package/dist/lib/node/index.cjs +73 -63
  51. package/dist/lib/node/index.cjs.map +3 -3
  52. package/dist/lib/node/{intent-resolver-YMMAFVOB.cjs → intent-resolver-YIFAMM3B.cjs} +13 -10
  53. package/dist/lib/node/{intent-resolver-YMMAFVOB.cjs.map → intent-resolver-YIFAMM3B.cjs.map} +3 -3
  54. package/dist/lib/node/meta.json +1 -1
  55. package/dist/lib/node/{react-surface-BSUZQ3HZ.cjs → react-surface-REI6G6B3.cjs} +25 -24
  56. package/dist/lib/node/react-surface-REI6G6B3.cjs.map +7 -0
  57. package/dist/lib/node/{settings-4YEO7KXF.cjs → settings-2FEYGLYU.cjs} +8 -8
  58. package/dist/lib/node/types/index.cjs +15 -11
  59. package/dist/lib/node/types/index.cjs.map +2 -2
  60. package/dist/lib/node-esm/{AssistantDialog-5AT5JAZL.mjs → AssistantDialog-R3EPF2KL.mjs} +6 -5
  61. package/dist/lib/node-esm/{AssistantDialog-5AT5JAZL.mjs.map → AssistantDialog-R3EPF2KL.mjs.map} +3 -3
  62. package/dist/lib/node-esm/{ChatContainer-VR766C4M.mjs → ChatContainer-UJ7MV7GU.mjs} +5 -5
  63. package/dist/lib/node-esm/TemplateContainer-YLA6BJY6.mjs +79 -0
  64. package/dist/lib/node-esm/TemplateContainer-YLA6BJY6.mjs.map +7 -0
  65. package/dist/lib/node-esm/ai-client-XYZ5N7CR.mjs +36 -0
  66. package/dist/lib/node-esm/ai-client-XYZ5N7CR.mjs.map +7 -0
  67. package/dist/lib/node-esm/{app-graph-builder-H2GC2AZA.mjs → app-graph-builder-PMAQLTTN.mjs} +57 -13
  68. package/dist/lib/node-esm/app-graph-builder-PMAQLTTN.mjs.map +7 -0
  69. package/dist/lib/node-esm/{chunk-77ARTFBA.mjs → chunk-2CIYX3SD.mjs} +2 -2
  70. package/dist/lib/node-esm/chunk-2CIYX3SD.mjs.map +7 -0
  71. package/dist/lib/node-esm/{chunk-AMQMVQJO.mjs → chunk-6GBMQIW7.mjs} +34 -12
  72. package/dist/lib/node-esm/chunk-6GBMQIW7.mjs.map +7 -0
  73. package/dist/lib/node-esm/{chunk-7JENJTLB.mjs → chunk-AMTHOYNB.mjs} +287 -70
  74. package/dist/lib/node-esm/chunk-AMTHOYNB.mjs.map +7 -0
  75. package/dist/lib/node-esm/{chunk-LBQGJE5T.mjs → chunk-J63VQFQO.mjs} +2 -2
  76. package/dist/lib/node-esm/{chunk-7SV6X6XU.mjs → chunk-N6BVC2C2.mjs} +1 -1
  77. package/dist/lib/node-esm/{chunk-7SV6X6XU.mjs.map → chunk-N6BVC2C2.mjs.map} +2 -2
  78. package/dist/lib/node-esm/{chunk-CJ4Y3QW5.mjs → chunk-NMMRHHAR.mjs} +26 -4
  79. package/dist/lib/node-esm/chunk-NMMRHHAR.mjs.map +7 -0
  80. package/dist/lib/node-esm/index.mjs +21 -11
  81. package/dist/lib/node-esm/index.mjs.map +3 -3
  82. package/dist/lib/node-esm/{intent-resolver-MR7BOKEW.mjs → intent-resolver-SQ4HLL5L.mjs} +6 -3
  83. package/dist/lib/node-esm/{intent-resolver-MR7BOKEW.mjs.map → intent-resolver-SQ4HLL5L.mjs.map} +3 -3
  84. package/dist/lib/node-esm/meta.json +1 -1
  85. package/dist/lib/node-esm/{react-surface-IGVYAOGL.mjs → react-surface-LE57AGPI.mjs} +10 -9
  86. package/dist/lib/node-esm/react-surface-LE57AGPI.mjs.map +7 -0
  87. package/dist/lib/node-esm/{settings-S7P5RWQI.mjs → settings-VHR5KT4J.mjs} +3 -3
  88. package/dist/lib/node-esm/types/index.mjs +6 -2
  89. package/dist/types/src/AssistantPlugin.d.ts.map +1 -1
  90. package/dist/types/src/capabilities/ai-client.d.ts +2 -2
  91. package/dist/types/src/capabilities/ai-client.d.ts.map +1 -1
  92. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
  93. package/dist/types/src/capabilities/capabilities.d.ts +3 -2
  94. package/dist/types/src/capabilities/capabilities.d.ts.map +1 -1
  95. package/dist/types/src/capabilities/index.d.ts +1 -1
  96. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  97. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  98. package/dist/types/src/components/AmbientDialog/AmbientDialog.d.ts +2 -2
  99. package/dist/types/src/components/AmbientDialog/AmbientDialog.d.ts.map +1 -1
  100. package/dist/types/src/components/AssistantDialog.d.ts.map +1 -1
  101. package/dist/types/src/components/AssistantSettings/AssistantSettings.d.ts +2 -1
  102. package/dist/types/src/components/AssistantSettings/AssistantSettings.d.ts.map +1 -1
  103. package/dist/types/src/components/ChatContainer.d.ts +2 -1
  104. package/dist/types/src/components/ChatContainer.d.ts.map +1 -1
  105. package/dist/types/src/components/Prompt/Prompt.d.ts +3 -0
  106. package/dist/types/src/components/Prompt/Prompt.d.ts.map +1 -1
  107. package/dist/types/src/components/Prompt/Prompt.stories.d.ts +1 -0
  108. package/dist/types/src/components/Prompt/Prompt.stories.d.ts.map +1 -1
  109. package/dist/types/src/components/Prompt/PromptBar.d.ts +3 -2
  110. package/dist/types/src/components/Prompt/PromptBar.d.ts.map +1 -1
  111. package/dist/types/src/components/Prompt/references.d.ts +30 -0
  112. package/dist/types/src/components/Prompt/references.d.ts.map +1 -0
  113. package/dist/types/src/components/ServiceRegistry/ServiceRegistry.d.ts +2 -1
  114. package/dist/types/src/components/ServiceRegistry/ServiceRegistry.d.ts.map +1 -1
  115. package/dist/types/src/components/TemplateContainer.d.ts +2 -1
  116. package/dist/types/src/components/TemplateContainer.d.ts.map +1 -1
  117. package/dist/types/src/components/TemplateEditor/TemplateEditor.d.ts +2 -1
  118. package/dist/types/src/components/TemplateEditor/TemplateEditor.d.ts.map +1 -1
  119. package/dist/types/src/components/TemplateEditor/TemplateEditor.stories.d.ts +2 -1
  120. package/dist/types/src/components/TemplateEditor/TemplateEditor.stories.d.ts.map +1 -1
  121. package/dist/types/src/components/TemplateEditor/TemplateForm.d.ts +3 -2
  122. package/dist/types/src/components/TemplateEditor/TemplateForm.d.ts.map +1 -1
  123. package/dist/types/src/components/Thread/Thread.d.ts +12 -1
  124. package/dist/types/src/components/Thread/Thread.d.ts.map +1 -1
  125. package/dist/types/src/components/Thread/ThreadContainer.d.ts +1 -0
  126. package/dist/types/src/components/Thread/ThreadContainer.d.ts.map +1 -1
  127. package/dist/types/src/components/Thread/ThreadContainer.stories.d.ts +2 -1
  128. package/dist/types/src/components/Thread/ThreadContainer.stories.d.ts.map +1 -1
  129. package/dist/types/src/components/Thread/ThreadMessage.d.ts.map +1 -1
  130. package/dist/types/src/components/Toolbox/Toolbox.d.ts +4 -3
  131. package/dist/types/src/components/Toolbox/Toolbox.d.ts.map +1 -1
  132. package/dist/types/src/components/index.d.ts +2 -2
  133. package/dist/types/src/components/index.d.ts.map +1 -1
  134. package/dist/types/src/hooks/index.d.ts +1 -0
  135. package/dist/types/src/hooks/index.d.ts.map +1 -1
  136. package/dist/types/src/hooks/invocation-handler.d.ts +1 -1
  137. package/dist/types/src/hooks/invocation-handler.d.ts.map +1 -1
  138. package/dist/types/src/hooks/processor.d.ts +8 -5
  139. package/dist/types/src/hooks/processor.d.ts.map +1 -1
  140. package/dist/types/src/hooks/useChatProcessor.d.ts +9 -2
  141. package/dist/types/src/hooks/useChatProcessor.d.ts.map +1 -1
  142. package/dist/types/src/hooks/useContextProvider.d.ts +17 -0
  143. package/dist/types/src/hooks/useContextProvider.d.ts.map +1 -0
  144. package/dist/types/src/hooks/useMessageQueue.d.ts +4 -4
  145. package/dist/types/src/hooks/useMessageQueue.d.ts.map +1 -1
  146. package/dist/types/src/meta.d.ts +2 -8
  147. package/dist/types/src/meta.d.ts.map +1 -1
  148. package/dist/types/src/testing/test-functions.d.ts.map +1 -1
  149. package/dist/types/src/tools/function.d.ts +1 -1
  150. package/dist/types/src/tools/function.d.ts.map +1 -1
  151. package/dist/types/src/translations.d.ts +21 -6
  152. package/dist/types/src/translations.d.ts.map +1 -1
  153. package/dist/types/src/types/service.d.ts +1 -1
  154. package/dist/types/src/types/service.d.ts.map +1 -1
  155. package/dist/types/src/types/template.d.ts +36 -0
  156. package/dist/types/src/types/template.d.ts.map +1 -1
  157. package/dist/types/src/types/types.d.ts +3 -1
  158. package/dist/types/src/types/types.d.ts.map +1 -1
  159. package/package.json +56 -56
  160. package/src/AssistantPlugin.tsx +11 -2
  161. package/src/capabilities/ai-client.ts +23 -4
  162. package/src/capabilities/app-graph-builder.ts +48 -4
  163. package/src/capabilities/capabilities.ts +4 -2
  164. package/src/capabilities/intent-resolver.ts +1 -1
  165. package/src/capabilities/react-surface.tsx +3 -2
  166. package/src/components/AssistantDialog.tsx +7 -1
  167. package/src/components/AssistantSettings/AssistantSettings.tsx +39 -5
  168. package/src/components/Prompt/Prompt.stories.tsx +34 -0
  169. package/src/components/Prompt/Prompt.tsx +9 -2
  170. package/src/components/Prompt/PromptBar.tsx +18 -7
  171. package/src/components/Prompt/references.ts +180 -0
  172. package/src/components/TemplateContainer.tsx +79 -4
  173. package/src/components/TemplateEditor/TemplateEditor.stories.tsx +1 -1
  174. package/src/components/TemplateEditor/TemplateForm.stories.tsx +1 -1
  175. package/src/components/TemplateEditor/TemplateForm.tsx +1 -1
  176. package/src/components/Thread/Thread.tsx +21 -0
  177. package/src/components/Thread/ThreadContainer.stories.tsx +5 -8
  178. package/src/components/Thread/ThreadContainer.tsx +7 -4
  179. package/src/components/Thread/ThreadMessage.tsx +17 -9
  180. package/src/components/Toolbox/Toolbox.tsx +1 -1
  181. package/src/components/index.ts +3 -0
  182. package/src/hooks/index.ts +1 -0
  183. package/src/hooks/invocation-handler.ts +3 -5
  184. package/src/hooks/processor.ts +18 -9
  185. package/src/hooks/useChatProcessor.tsx +24 -15
  186. package/src/hooks/useContextProvider.ts +55 -0
  187. package/src/hooks/useLocalTriggerManager.ts +1 -1
  188. package/src/hooks/useMessageQueue.ts +2 -4
  189. package/src/meta.ts +2 -2
  190. package/src/testing/test-functions.ts +2 -2
  191. package/src/tools/function.ts +2 -2
  192. package/src/tools/openapi.test.ts +4 -4
  193. package/src/translations.ts +8 -3
  194. package/src/types/service.ts +1 -1
  195. package/src/types/template.ts +22 -0
  196. package/src/types/types.ts +3 -1
  197. package/dist/lib/browser/TemplateContainer-B7MQNUPY.mjs +0 -23
  198. package/dist/lib/browser/TemplateContainer-B7MQNUPY.mjs.map +0 -7
  199. package/dist/lib/browser/ai-client-RTCGRKZE.mjs +0 -22
  200. package/dist/lib/browser/ai-client-RTCGRKZE.mjs.map +0 -7
  201. package/dist/lib/browser/app-graph-builder-AXAIFOGV.mjs.map +0 -7
  202. package/dist/lib/browser/chunk-FRIKXDDQ.mjs.map +0 -7
  203. package/dist/lib/browser/chunk-G7B54APW.mjs.map +0 -7
  204. package/dist/lib/browser/chunk-NFVIZS3B.mjs.map +0 -7
  205. package/dist/lib/browser/chunk-VZ4W6SHE.mjs.map +0 -7
  206. package/dist/lib/browser/react-surface-JLXNWOI6.mjs.map +0 -7
  207. package/dist/lib/node/TemplateContainer-R4BZZP3E.cjs +0 -53
  208. package/dist/lib/node/TemplateContainer-R4BZZP3E.cjs.map +0 -7
  209. package/dist/lib/node/ai-client-YANJEPO3.cjs.map +0 -7
  210. package/dist/lib/node/app-graph-builder-D7SHQTZS.cjs.map +0 -7
  211. package/dist/lib/node/chunk-37GI4NYH.cjs.map +0 -7
  212. package/dist/lib/node/chunk-IXJCGW7U.cjs.map +0 -7
  213. package/dist/lib/node/chunk-XUTDR7HI.cjs.map +0 -7
  214. package/dist/lib/node/chunk-ZGH6F5YA.cjs.map +0 -7
  215. package/dist/lib/node/react-surface-BSUZQ3HZ.cjs.map +0 -7
  216. package/dist/lib/node-esm/TemplateContainer-WSHTZBB5.mjs +0 -24
  217. package/dist/lib/node-esm/TemplateContainer-WSHTZBB5.mjs.map +0 -7
  218. package/dist/lib/node-esm/ai-client-66IBZVCX.mjs +0 -23
  219. package/dist/lib/node-esm/ai-client-66IBZVCX.mjs.map +0 -7
  220. package/dist/lib/node-esm/app-graph-builder-H2GC2AZA.mjs.map +0 -7
  221. package/dist/lib/node-esm/chunk-77ARTFBA.mjs.map +0 -7
  222. package/dist/lib/node-esm/chunk-7JENJTLB.mjs.map +0 -7
  223. package/dist/lib/node-esm/chunk-AMQMVQJO.mjs.map +0 -7
  224. package/dist/lib/node-esm/chunk-CJ4Y3QW5.mjs.map +0 -7
  225. package/dist/lib/node-esm/react-surface-IGVYAOGL.mjs.map +0 -7
  226. /package/dist/lib/browser/{ChatContainer-AT3OAUT3.mjs.map → ChatContainer-EEEVE62F.mjs.map} +0 -0
  227. /package/dist/lib/browser/{chunk-EUMPBC4T.mjs.map → chunk-6FTPLBSC.mjs.map} +0 -0
  228. /package/dist/lib/browser/{settings-JTT62IHD.mjs.map → settings-VAW6UWFL.mjs.map} +0 -0
  229. /package/dist/lib/node/{ChatContainer-CVHXNHGA.cjs.map → ChatContainer-BPI3GEZS.cjs.map} +0 -0
  230. /package/dist/lib/node/{chunk-NV4TQQSU.cjs.map → chunk-N3SW6DJ6.cjs.map} +0 -0
  231. /package/dist/lib/node/{settings-4YEO7KXF.cjs.map → settings-2FEYGLYU.cjs.map} +0 -0
  232. /package/dist/lib/node-esm/{ChatContainer-VR766C4M.mjs.map → ChatContainer-UJ7MV7GU.mjs.map} +0 -0
  233. /package/dist/lib/node-esm/{chunk-LBQGJE5T.mjs.map → chunk-J63VQFQO.mjs.map} +0 -0
  234. /package/dist/lib/node-esm/{settings-S7P5RWQI.mjs.map → settings-VHR5KT4J.mjs.map} +0 -0
@@ -11,14 +11,14 @@ import {
11
11
  type PluginsContext,
12
12
  } from '@dxos/app-framework';
13
13
  import { invariant } from '@dxos/invariant';
14
- import { log } from '@dxos/log';
15
14
  import { ClientCapabilities } from '@dxos/plugin-client';
16
15
  import { createExtension, type Node, ROOT_ID } from '@dxos/plugin-graph';
16
+ import { memoizeQuery } from '@dxos/plugin-space';
17
17
  import { SpaceAction } from '@dxos/plugin-space/types';
18
- import { type Space, Filter, getSpace } from '@dxos/react-client/echo';
18
+ import { type Space, Filter, fullyQualifiedId, getSpace, isSpace } from '@dxos/react-client/echo';
19
19
 
20
20
  import { ASSISTANT_DIALOG, ASSISTANT_PLUGIN } from '../meta';
21
- import { AIChatType, AssistantAction } from '../types';
21
+ import { AIChatType, AssistantAction, TemplateType } from '../types';
22
22
 
23
23
  export default (context: PluginsContext) =>
24
24
  contributes(Capabilities.AppGraphBuilder, [
@@ -51,7 +51,6 @@ export default (context: PluginsContext) =>
51
51
  }
52
52
 
53
53
  if (!chat) {
54
- log.warn('no chat found');
55
54
  return;
56
55
  }
57
56
 
@@ -82,6 +81,51 @@ export default (context: PluginsContext) =>
82
81
  },
83
82
  ],
84
83
  }),
84
+
85
+ createExtension({
86
+ id: `${ASSISTANT_PLUGIN}/root`,
87
+ filter: (node): node is Node<Space> => isSpace(node.data),
88
+ connector: ({ node }) => {
89
+ const templates = memoizeQuery(node.data, Filter.schema(TemplateType));
90
+ return templates.length > 0
91
+ ? [
92
+ {
93
+ id: `${ASSISTANT_PLUGIN}/templates`,
94
+ type: `${ASSISTANT_PLUGIN}/templates`,
95
+ data: null,
96
+ properties: {
97
+ label: ['templates label', { ns: ASSISTANT_PLUGIN }],
98
+ icon: 'ph--file-code--regular',
99
+ space: node.data,
100
+ },
101
+ },
102
+ ]
103
+ : [];
104
+ },
105
+ }),
106
+
107
+ createExtension({
108
+ id: `${ASSISTANT_PLUGIN}/templates`,
109
+ filter: (node): node is Node<null, { space: Space }> => node.id === `${ASSISTANT_PLUGIN}/templates`,
110
+ connector: ({ node }) => {
111
+ const templates = memoizeQuery(node.properties.space, Filter.schema(TemplateType));
112
+ return templates
113
+ .toSorted((a, b) => {
114
+ const nameA = a.name ?? '';
115
+ const nameB = b.name ?? '';
116
+ return nameA.localeCompare(nameB);
117
+ })
118
+ .map((template) => ({
119
+ id: fullyQualifiedId(template),
120
+ type: `${ASSISTANT_PLUGIN}/template`,
121
+ data: template,
122
+ properties: {
123
+ label: template.name ?? ['template title placeholder', { ns: ASSISTANT_PLUGIN }],
124
+ icon: 'ph--file-code--regular',
125
+ },
126
+ }));
127
+ },
128
+ }),
85
129
  ]);
86
130
 
87
131
  // TODO(burdon): Factor out.
@@ -2,11 +2,13 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
+ import { type ReadonlySignal } from '@preact/signals-core';
6
+
5
7
  import { defineCapability } from '@dxos/app-framework';
6
- import { type AIServiceClientImpl } from '@dxos/assistant';
8
+ import { type AIServiceClient } from '@dxos/assistant';
7
9
 
8
10
  import { ASSISTANT_PLUGIN } from '../meta';
9
11
 
10
12
  export namespace AssistantCapabilities {
11
- export const AiClient = defineCapability<AIServiceClientImpl>(`${ASSISTANT_PLUGIN}/capability/ai-client`);
13
+ export const AiClient = defineCapability<ReadonlySignal<AIServiceClient>>(`${ASSISTANT_PLUGIN}/capability/ai-client`);
12
14
  }
@@ -30,7 +30,7 @@ export default () => [
30
30
  intent: AssistantAction.CreateTemplate,
31
31
  resolve: ({ name }) => ({
32
32
  data: {
33
- object: create(TemplateType, { name, source: '{{! Template }}' }),
33
+ object: create(TemplateType, { name, kind: { include: 'manual' }, source: '{{! Template }}' }),
34
34
  },
35
35
  }),
36
36
  }),
@@ -5,6 +5,7 @@
5
5
  import React from 'react';
6
6
 
7
7
  import { Capabilities, contributes, createSurface } from '@dxos/app-framework';
8
+ import { isInstanceOf } from '@dxos/echo-schema';
8
9
  import { SettingsStore } from '@dxos/local-storage';
9
10
  import { getSpace, isSpace } from '@dxos/react-client/echo';
10
11
 
@@ -30,13 +31,13 @@ export default () =>
30
31
  createSurface({
31
32
  id: `${ASSISTANT_PLUGIN}/chat`,
32
33
  role: 'article',
33
- filter: (data): data is { subject: AIChatType } => data.subject instanceof AIChatType,
34
+ filter: (data): data is { subject: AIChatType } => isInstanceOf(AIChatType, data.subject),
34
35
  component: ({ data, role }) => <ChatContainer role={role} chat={data.subject} />,
35
36
  }),
36
37
  createSurface({
37
38
  id: `${ASSISTANT_PLUGIN}/template`,
38
39
  role: 'article',
39
- filter: (data): data is { subject: TemplateType } => data.subject instanceof TemplateType,
40
+ filter: (data): data is { subject: TemplateType } => isInstanceOf(TemplateType, data.subject),
40
41
  component: ({ data, role }) => <TemplateContainer role={role} template={data.subject} />,
41
42
  }),
42
43
  createSurface({
@@ -23,7 +23,13 @@ export const AssistantDialog: FC<{ chat?: AIChatType }> = ({ chat }) => {
23
23
 
24
24
  return (
25
25
  <AmbientDialog open={open} onOpenChange={setOpen} title={t('assistant dialog title')}>
26
- <ThreadContainer chat={chat} onOpenChange={setOpen} settings={settings} transcription={transcription} />
26
+ <ThreadContainer
27
+ chat={chat}
28
+ onOpenChange={setOpen}
29
+ settings={settings}
30
+ part={'dialog'}
31
+ transcription={transcription}
32
+ />
27
33
  </AmbientDialog>
28
34
  );
29
35
  };
@@ -4,13 +4,16 @@
4
4
 
5
5
  import React from 'react';
6
6
 
7
- import { DEFAULT_LLM_MODELS } from '@dxos/assistant';
7
+ import { DEFAULT_EDGE_MODELS, DEFAULT_OLLAMA_MODELS } from '@dxos/assistant';
8
8
  import { Input, Select, useTranslation } from '@dxos/react-ui';
9
9
  import { DeprecatedFormContainer, DeprecatedFormInput } from '@dxos/react-ui-form';
10
10
 
11
11
  import { ASSISTANT_PLUGIN } from '../../meta';
12
12
  import { type AssistantSettingsProps } from '../../types';
13
13
 
14
+ // TODO(burdon): Factor out.
15
+ const DEFAULT_VALUE = '__default';
16
+
14
17
  export const AssistantSettings = ({ settings }: { settings: AssistantSettingsProps }) => {
15
18
  const { t } = useTranslation(ASSISTANT_PLUGIN);
16
19
 
@@ -23,18 +26,49 @@ export const AssistantSettings = ({ settings }: { settings: AssistantSettingsPro
23
26
  />
24
27
  </DeprecatedFormInput>
25
28
 
26
- <DeprecatedFormInput label={t('settings llm model label')}>
29
+ <DeprecatedFormInput label={t('settings llm provider label')}>
30
+ <Input.Switch
31
+ checked={!!settings.llmProvider}
32
+ onCheckedChange={(checked) => (settings.llmProvider = checked ? 'ollama' : 'edge')}
33
+ />
34
+ </DeprecatedFormInput>
35
+
36
+ <DeprecatedFormInput label={t('settings edge llm model label')}>
37
+ <Select.Root
38
+ value={settings.edgeModel ?? DEFAULT_VALUE}
39
+ onValueChange={(value) => {
40
+ settings.edgeModel = value === DEFAULT_VALUE ? undefined : value;
41
+ }}
42
+ >
43
+ <Select.TriggerButton placeholder={t('settings default llm model label')} />
44
+ <Select.Portal>
45
+ <Select.Content>
46
+ <Select.Viewport>
47
+ <Select.Option value={DEFAULT_VALUE}>{t('settings default label')}</Select.Option>
48
+ {DEFAULT_EDGE_MODELS.map((model) => (
49
+ <Select.Option key={model} value={model}>
50
+ {model}
51
+ </Select.Option>
52
+ ))}
53
+ </Select.Viewport>
54
+ </Select.Content>
55
+ </Select.Portal>
56
+ </Select.Root>
57
+ </DeprecatedFormInput>
58
+
59
+ <DeprecatedFormInput label={t('settings ollama llm model label')}>
27
60
  <Select.Root
28
- value={settings.llmModel ?? 'default'}
61
+ value={settings.ollamaModel ?? DEFAULT_VALUE}
29
62
  onValueChange={(value) => {
30
- settings.llmModel = value;
63
+ settings.ollamaModel = value === DEFAULT_VALUE ? undefined : value;
31
64
  }}
32
65
  >
33
66
  <Select.TriggerButton placeholder={t('settings default llm model label')} />
34
67
  <Select.Portal>
35
68
  <Select.Content>
36
69
  <Select.Viewport>
37
- {DEFAULT_LLM_MODELS.map((model) => (
70
+ <Select.Option value={DEFAULT_VALUE}>{t('settings default label')}</Select.Option>
71
+ {DEFAULT_OLLAMA_MODELS.map((model) => (
38
72
  <Select.Option key={model} value={model}>
39
73
  {model}
40
74
  </Select.Option>
@@ -11,6 +11,7 @@ import { withTheme, withLayout } from '@dxos/storybook-utils';
11
11
 
12
12
  import { Prompt } from './Prompt';
13
13
  import { PromptBar } from './PromptBar';
14
+ import type { ReferenceData } from './references';
14
15
  import translations from '../../translations';
15
16
 
16
17
  const meta: Meta<typeof Prompt> = {
@@ -77,3 +78,36 @@ export const Toolbar: Story = {
77
78
  );
78
79
  },
79
80
  };
81
+
82
+ export const Includes: Story = {
83
+ args: {
84
+ classNames: 'w-96 p-4 rounded outline outline-gray-200',
85
+ references: {
86
+ getReferences: async ({ query }) => {
87
+ const res = references.filter((i) => i.label.toLowerCase().startsWith(query.toLowerCase()));
88
+ console.log('getReferences', { query, res });
89
+ return res;
90
+ },
91
+ resolveReference: async ({ uri }) => {
92
+ const res = references.find((i) => i.uri === uri);
93
+ console.log('resolveReference', { uri, res });
94
+ return res ?? null;
95
+ },
96
+ },
97
+ },
98
+ };
99
+
100
+ const references: ReferenceData[] = [
101
+ {
102
+ uri: 'dxn:echo:@:AAAAAAAA',
103
+ label: 'Meeting Notes',
104
+ },
105
+ {
106
+ uri: 'dxn:echo:@:BBBBBBBB',
107
+ label: 'Project Plan',
108
+ },
109
+ {
110
+ uri: 'dxn:echo:@:CCCCCCCC',
111
+ label: 'Meeting Plan',
112
+ },
113
+ ];
@@ -16,6 +16,7 @@ import {
16
16
  import { mx } from '@dxos/react-ui-theme';
17
17
 
18
18
  import { createAutocompleteExtension, type AutocompleteOptions } from './autocomplete';
19
+ import { promptReferences, type ReferencesProvider } from './references';
19
20
 
20
21
  // TODO(burdon): Handle object references.
21
22
 
@@ -27,16 +28,21 @@ export interface PromptController {
27
28
  export type PromptProps = ThemedClassName<
28
29
  {
29
30
  onOpenChange?: (open: boolean) => void;
31
+ references?: ReferencesProvider;
30
32
  } & AutocompleteOptions &
31
33
  Pick<UseTextEditorProps, 'autoFocus'> &
32
34
  Pick<BasicExtensionsOptions, 'lineWrapping' | 'placeholder'>
33
35
  >;
34
36
 
35
37
  export const Prompt = forwardRef<PromptController, PromptProps>(
36
- ({ classNames, autoFocus, lineWrapping = false, placeholder, onSubmit, onSuggest, onOpenChange }, forwardRef) => {
38
+ (
39
+ { classNames, autoFocus, lineWrapping = false, placeholder, onSubmit, onSuggest, onOpenChange, references },
40
+ forwardRef,
41
+ ) => {
37
42
  const { themeMode } = useThemeContext();
38
43
  const { parentRef, view } = useTextEditor(
39
44
  {
45
+ debug: true,
40
46
  autoFocus,
41
47
  extensions: [
42
48
  createBasicExtensions({
@@ -45,6 +51,7 @@ export const Prompt = forwardRef<PromptController, PromptProps>(
45
51
  placeholder,
46
52
  }),
47
53
  createThemeExtensions({ themeMode }),
54
+ references ? promptReferences({ provider: references }) : [],
48
55
  createAutocompleteExtension({ onSubmit, onSuggest }),
49
56
  keymap.of([
50
57
  {
@@ -95,6 +102,6 @@ export const Prompt = forwardRef<PromptController, PromptProps>(
95
102
  [view, onSubmit],
96
103
  );
97
104
 
98
- return <div ref={parentRef} className={mx('w-full overflow-hidden', classNames)} />;
105
+ return <div ref={parentRef} className={mx('w-full', classNames)} />;
99
106
  },
100
107
  );
@@ -5,7 +5,7 @@
5
5
  import React, { useRef, useState } from 'react';
6
6
 
7
7
  import { useVoiceInput } from '@dxos/plugin-transcription';
8
- import { Icon, IconButton, type ThemedClassName, useTranslation } from '@dxos/react-ui';
8
+ import { Icon, IconButton, type ThemedClassName, Tooltip, useTranslation } from '@dxos/react-ui';
9
9
  import { Spinner } from '@dxos/react-ui-sfx';
10
10
  import { errorText, mx } from '@dxos/react-ui-theme';
11
11
 
@@ -13,7 +13,7 @@ import { Prompt, type PromptController, type PromptProps } from './Prompt';
13
13
  import { ASSISTANT_PLUGIN } from '../../meta';
14
14
 
15
15
  export type PromptBarProps = ThemedClassName<
16
- Pick<PromptProps, 'placeholder' | 'lineWrapping' | 'onSubmit' | 'onSuggest' | 'onOpenChange'> & {
16
+ Pick<PromptProps, 'placeholder' | 'lineWrapping' | 'onSubmit' | 'onSuggest' | 'onOpenChange' | 'references'> & {
17
17
  processing?: boolean;
18
18
  error?: Error;
19
19
  microphone?: boolean;
@@ -28,6 +28,7 @@ export const PromptBar = ({
28
28
  error,
29
29
  microphone,
30
30
  onCancel,
31
+ references,
31
32
  ...props
32
33
  }: PromptBarProps) => {
33
34
  const { t } = useTranslation(ASSISTANT_PLUGIN);
@@ -44,18 +45,27 @@ export const PromptBar = ({
44
45
  },
45
46
  });
46
47
 
47
- // TODO(burdon): Tooltip for error.
48
48
  return (
49
49
  <div
50
50
  className={mx(
51
- 'flex shrink-0 w-full grid grid-cols-[var(--rail-action)_1fr_var(--rail-action)] overflow-hidden',
51
+ 'shrink-0 w-full grid grid-cols-[var(--rail-action)_1fr_var(--rail-action)] overflow-hidden',
52
52
  classNames,
53
53
  )}
54
54
  >
55
55
  <div className='flex w-[--rail-action] h-[--rail-action] items-center justify-center'>
56
- {(error && <Icon icon='ph--warning-circle--regular' classNames={errorText} size={5} />) || (
57
- <Spinner active={processing} />
58
- )}
56
+ {(error && (
57
+ <Tooltip.Root delayDuration={0}>
58
+ <Tooltip.Trigger>
59
+ <Icon icon='ph--warning-circle--regular' classNames={errorText} size={5} />
60
+ </Tooltip.Trigger>
61
+ <Tooltip.Portal>
62
+ <Tooltip.Content>
63
+ <div className='text-sm text-error-500'>{error.message}</div>
64
+ <Tooltip.Arrow />
65
+ </Tooltip.Content>
66
+ </Tooltip.Portal>
67
+ </Tooltip.Root>
68
+ )) || <Spinner active={processing} />}
59
69
  </div>
60
70
  <Prompt
61
71
  ref={promptRef}
@@ -63,6 +73,7 @@ export const PromptBar = ({
63
73
  classNames='pbs-2'
64
74
  lineWrapping={true}
65
75
  placeholder={placeholder ?? t('prompt placeholder')}
76
+ references={references}
66
77
  {...props}
67
78
  />
68
79
  {(onCancel || microphone) && (
@@ -0,0 +1,180 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { autocompletion, completionKeymap, type CompletionResult } from '@codemirror/autocomplete';
6
+ import { type Extension, RangeSet } from '@codemirror/state';
7
+ import {
8
+ Decoration,
9
+ EditorView,
10
+ keymap,
11
+ ViewPlugin,
12
+ WidgetType,
13
+ type DecorationSet,
14
+ type ViewUpdate,
15
+ } from '@codemirror/view';
16
+
17
+ import { Mutex } from '@dxos/async';
18
+
19
+ export type ReferenceData = {
20
+ uri: string;
21
+ label: string;
22
+ // TODO(dmaretskyi): Consider adding details renderer for when you hover over the reference.
23
+ };
24
+
25
+ export interface ReferencesProvider {
26
+ getReferences({ query }: { query: string }): Promise<ReferenceData[]>;
27
+
28
+ resolveReference({ uri }: { uri: string }): Promise<ReferenceData | null>;
29
+ }
30
+
31
+ export type PromptReferencesOptions = {
32
+ provider: ReferencesProvider;
33
+ /**
34
+ * Will prevent the autocomplete from closing when the user blurs the editor.
35
+ * @default false
36
+ */
37
+ debug?: boolean;
38
+ /**
39
+ * @default '@'
40
+ */
41
+ triggerCharacter?: string;
42
+ };
43
+
44
+ /**
45
+ * Include references into text.
46
+ */
47
+ export const promptReferences = ({
48
+ provider,
49
+ debug = false,
50
+ triggerCharacter = '@',
51
+ }: PromptReferencesOptions): Extension => {
52
+ if (triggerCharacter.length !== 1) {
53
+ throw new Error('triggerCharacter must be a single character');
54
+ }
55
+
56
+ const decorationField = ViewPlugin.fromClass(
57
+ class ReferenceView {
58
+ private _mutex = new Mutex();
59
+
60
+ decorations: DecorationSet = Decoration.set([]);
61
+
62
+ constructor(view: EditorView) {
63
+ queueMicrotask(async () => {
64
+ const guard = await this._mutex.acquire();
65
+ try {
66
+ this.decorations = await this._computeDecorations(view);
67
+ } finally {
68
+ guard.release();
69
+ }
70
+ });
71
+ }
72
+
73
+ update(update: ViewUpdate) {
74
+ if (update.docChanged) {
75
+ queueMicrotask(async () => {
76
+ const guard = await this._mutex.acquire();
77
+ try {
78
+ this.decorations = await this._computeDecorations(update.view);
79
+ } finally {
80
+ guard.release();
81
+ }
82
+ });
83
+ }
84
+ }
85
+
86
+ private async _computeDecorations(view: EditorView): Promise<DecorationSet> {
87
+ const text = view.state.doc.toString();
88
+ const references = text.matchAll(new RegExp(`${triggerCharacter}[a-zA-Z0-9@:]+\\s`, 'g'));
89
+
90
+ const decorations = [];
91
+ for (const match of references) {
92
+ const reference = match[0];
93
+ const uri = reference.slice(1, -1);
94
+ const data = await provider.resolveReference({ uri });
95
+ if (data) {
96
+ decorations.push(
97
+ Decoration.replace({
98
+ widget: new ReferenceWidget(data),
99
+ }).range(match.index!, match.index! + reference.length),
100
+ );
101
+ }
102
+ }
103
+
104
+ return Decoration.set(decorations);
105
+ }
106
+ },
107
+ {
108
+ decorations: (v) => v.decorations,
109
+ provide: (plugin) => [
110
+ EditorView.atomicRanges.of(
111
+ (view): DecorationSet => view.plugin(decorationField)?.decorations ?? RangeSet.empty,
112
+ ),
113
+ ],
114
+ },
115
+ );
116
+
117
+ return [
118
+ decorationField,
119
+
120
+ EditorView.theme({
121
+ '.cm-reference-pill': {
122
+ borderRadius: '0.25rem',
123
+ borderWidth: '1px',
124
+ marginRight: '0.25rem',
125
+ marginLeft: '0.25rem',
126
+ },
127
+ }),
128
+
129
+ autocompletion({
130
+ activateOnTyping: true,
131
+ override: [
132
+ async (context): Promise<CompletionResult | null> => {
133
+ const match = context.matchBefore(new RegExp(`${triggerCharacter}[a-zA-Z0-9]+`));
134
+
135
+ if (!match || match?.to === match?.from) {
136
+ return null;
137
+ }
138
+
139
+ const query = match.text.slice(1);
140
+ const references = await provider.getReferences({ query });
141
+
142
+ return {
143
+ from: match.from,
144
+ filter: false,
145
+ options: references.map((reference) => ({
146
+ label: reference.label,
147
+ apply: `${triggerCharacter}${reference.uri} `,
148
+ })),
149
+ };
150
+ },
151
+ ],
152
+ closeOnBlur: !debug,
153
+ tooltipClass: () => 'shadow rounded',
154
+ aboveCursor: true,
155
+ }),
156
+
157
+ keymap.of(completionKeymap),
158
+ ];
159
+ };
160
+
161
+ class ReferenceWidget extends WidgetType {
162
+ constructor(private data: ReferenceData) {
163
+ super();
164
+ }
165
+
166
+ override toDOM() {
167
+ const span = document.createElement('span');
168
+ span.textContent = `@ ${this.data.label}`;
169
+ span.className = 'cm-reference-pill';
170
+ return span;
171
+ }
172
+
173
+ override eq(other: ReferenceWidget) {
174
+ return other.data.uri === this.data.uri;
175
+ }
176
+
177
+ override ignoreEvent() {
178
+ return true;
179
+ }
180
+ }
@@ -2,17 +2,92 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import React from 'react';
5
+ import { Match, type Schema as S } from 'effect';
6
+ import React, { type ChangeEvent, useCallback } from 'react';
6
7
 
8
+ import { debounce } from '@dxos/async';
9
+ import { Input, Select, Toolbar, useTranslation } from '@dxos/react-ui';
7
10
  import { StackItem } from '@dxos/react-ui-stack';
8
11
 
9
12
  import { TemplateEditor } from './TemplateEditor';
10
- import { type TemplateType } from '../types';
13
+ import { ASSISTANT_PLUGIN } from '../meta';
14
+ import { TemplateKinds, type TemplateKindSchema, type TemplateType } from '../types';
11
15
 
12
- // TODO(burdon): Attention.
13
16
  export const TemplateContainer = ({ template, role }: { template: TemplateType; role: string }) => {
17
+ const { t } = useTranslation(ASSISTANT_PLUGIN);
18
+
19
+ const handleKindChange = useCallback(
20
+ (value: string) => {
21
+ const kind = Match.type<string>().pipe(
22
+ Match.withReturnType<S.Schema.Type<typeof TemplateKindSchema>>(),
23
+ Match.when('always', () => ({ include: 'always' })),
24
+ Match.when('schema-matching', () => ({ include: 'schema-matching', typename: '' })),
25
+ Match.when('automatically', () => ({ include: 'automatically', description: '' })),
26
+ Match.orElse(() => ({ include: 'manual' })),
27
+ )(value);
28
+
29
+ template.kind = kind;
30
+ },
31
+ [template],
32
+ );
33
+
34
+ const handleTypenameChange = useCallback(
35
+ debounce((event: ChangeEvent<HTMLInputElement>) => {
36
+ if (template.kind.include === 'schema-matching') {
37
+ template.kind.typename = event.target.value;
38
+ }
39
+ }, 300),
40
+ [template.kind.include],
41
+ );
42
+
43
+ const handleDescriptionChange = useCallback(
44
+ debounce((event: ChangeEvent<HTMLInputElement>) => {
45
+ if (template.kind.include === 'automatically') {
46
+ template.kind.description = event.target.value;
47
+ }
48
+ }, 300),
49
+ [template.kind.include],
50
+ );
51
+
14
52
  return (
15
- <StackItem.Content toolbar={false} role={role} classNames='mli-auto w-full max-w-[50rem]'>
53
+ <StackItem.Content toolbar role={role} classNames='mli-auto w-full max-w-[50rem]'>
54
+ {/* TODO(wittjosiah): Move this toolbar into c11y sidebar. */}
55
+ <Toolbar.Root>
56
+ <Select.Root value={template.kind.include} onValueChange={handleKindChange}>
57
+ <Toolbar.Button asChild>
58
+ <Select.TriggerButton />
59
+ </Toolbar.Button>
60
+ <Select.Portal>
61
+ <Select.Content>
62
+ <Select.Viewport>
63
+ {TemplateKinds.map((kind) => (
64
+ <Select.Option key={kind} value={kind}>
65
+ {kind}
66
+ </Select.Option>
67
+ ))}
68
+ </Select.Viewport>
69
+ </Select.Content>
70
+ </Select.Portal>
71
+ </Select.Root>
72
+ {template.kind.include === 'schema-matching' && (
73
+ <Input.Root>
74
+ <Input.TextInput
75
+ placeholder={t('typename placeholder')}
76
+ defaultValue={template.kind.typename}
77
+ onChange={handleTypenameChange}
78
+ />
79
+ </Input.Root>
80
+ )}
81
+ {template.kind.include === 'automatically' && (
82
+ <Input.Root>
83
+ <Input.TextInput
84
+ placeholder={t('description placeholder')}
85
+ defaultValue={template.kind.description}
86
+ onChange={handleDescriptionChange}
87
+ />
88
+ </Input.Root>
89
+ )}
90
+ </Toolbar.Root>
16
91
  <TemplateEditor template={template} />
17
92
  </StackItem.Content>
18
93
  );
@@ -38,7 +38,7 @@ const Render = ({ text }: TemplateEditorProps & { text: string }) => {
38
38
  const client = useClient();
39
39
  const [template] = useState(() => {
40
40
  const space = client.spaces.default;
41
- return space.db.add(create(TemplateType, { source: text }));
41
+ return space.db.add(create(TemplateType, { source: text, kind: { include: 'manual' } }));
42
42
  });
43
43
 
44
44
  return (
@@ -30,7 +30,7 @@ const Render = () => {
30
30
  const client = useClient();
31
31
  const [template] = useState(() => {
32
32
  const space = client.spaces.default;
33
- return space.db.add(create(TemplateType, { source: TEMPLATE }));
33
+ return space.db.add(create(TemplateType, { source: TEMPLATE, kind: { include: 'manual' } }));
34
34
  });
35
35
 
36
36
  return (
@@ -2,7 +2,7 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { type Schema as S } from '@effect/schema';
5
+ import { type Schema as S } from 'effect';
6
6
  import React, { Fragment, useEffect } from 'react';
7
7
 
8
8
  import { Input, Select, useTranslation } from '@dxos/react-ui';