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

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 (226) hide show
  1. package/dist/lib/browser/{AssistantDialog-DTWVEQBB.mjs → AssistantDialog-YSHMAHW5.mjs} +3 -3
  2. package/dist/lib/browser/{ChatContainer-ZNKENYKZ.mjs → ChatContainer-V5GP7DYF.mjs} +3 -3
  3. package/dist/lib/browser/ChatContainer-V5GP7DYF.mjs.map +7 -0
  4. package/dist/lib/browser/TemplateContainer-K4EJNGIL.mjs +78 -0
  5. package/dist/lib/browser/TemplateContainer-K4EJNGIL.mjs.map +7 -0
  6. package/dist/lib/browser/{ai-client-5PRCXI7N.mjs → ai-client-CDZLSNXE.mjs} +3 -3
  7. package/dist/lib/browser/ai-client-CDZLSNXE.mjs.map +7 -0
  8. package/dist/lib/browser/app-graph-builder-MF5EVDWW.mjs +209 -0
  9. package/dist/lib/browser/app-graph-builder-MF5EVDWW.mjs.map +7 -0
  10. package/dist/lib/browser/{chunk-OWZHLWW5.mjs → chunk-FMB7RGMP.mjs} +136 -147
  11. package/dist/lib/browser/chunk-FMB7RGMP.mjs.map +7 -0
  12. package/dist/lib/browser/chunk-IAMR2FAE.mjs +183 -0
  13. package/dist/lib/browser/chunk-IAMR2FAE.mjs.map +7 -0
  14. package/dist/lib/browser/chunk-KYMKVE6M.mjs +128 -0
  15. package/dist/lib/browser/chunk-KYMKVE6M.mjs.map +7 -0
  16. package/dist/lib/browser/index.mjs +11 -14
  17. package/dist/lib/browser/index.mjs.map +3 -3
  18. package/dist/lib/browser/{intent-resolver-QV5AAVJZ.mjs → intent-resolver-WJGLKKVO.mjs} +12 -7
  19. package/dist/lib/browser/intent-resolver-WJGLKKVO.mjs.map +7 -0
  20. package/dist/lib/browser/meta.json +1 -1
  21. package/dist/lib/browser/{react-surface-JJPYWEIN.mjs → react-surface-57VRDOQT.mjs} +17 -17
  22. package/dist/lib/browser/react-surface-57VRDOQT.mjs.map +7 -0
  23. package/dist/lib/browser/{settings-OZX7J65A.mjs → settings-U6UFQX32.mjs} +4 -4
  24. package/dist/lib/browser/settings-U6UFQX32.mjs.map +7 -0
  25. package/dist/lib/browser/types/index.mjs +1 -3
  26. package/dist/lib/node/{AssistantDialog-RJJHZI63.cjs → AssistantDialog-YI2BSGSX.cjs} +7 -7
  27. package/dist/lib/node/{ChatContainer-WVAAOEOH.cjs → ChatContainer-ZJ5JXF6A.cjs} +7 -7
  28. package/dist/lib/node/ChatContainer-ZJ5JXF6A.cjs.map +7 -0
  29. package/dist/lib/node/TemplateContainer-XWFYJB4T.cjs +104 -0
  30. package/dist/lib/node/TemplateContainer-XWFYJB4T.cjs.map +7 -0
  31. package/dist/lib/node/{ai-client-OUPSRQT7.cjs → ai-client-URCCYU6B.cjs} +6 -6
  32. package/dist/lib/node/ai-client-URCCYU6B.cjs.map +7 -0
  33. package/dist/lib/node/{app-graph-builder-LEO63CZZ.cjs → app-graph-builder-N5ZUUI2Z.cjs} +94 -74
  34. package/dist/lib/node/app-graph-builder-N5ZUUI2Z.cjs.map +7 -0
  35. package/dist/lib/node/chunk-APRU3QWK.cjs +206 -0
  36. package/dist/lib/node/chunk-APRU3QWK.cjs.map +7 -0
  37. package/dist/lib/node/{chunk-OOHFSPWR.cjs → chunk-RPBKMP2E.cjs} +141 -159
  38. package/dist/lib/node/chunk-RPBKMP2E.cjs.map +7 -0
  39. package/dist/lib/node/{chunk-GQ3XS5FZ.cjs → chunk-ZKOC4ZFY.cjs} +61 -78
  40. package/dist/lib/node/chunk-ZKOC4ZFY.cjs.map +7 -0
  41. package/dist/lib/node/index.cjs +43 -46
  42. package/dist/lib/node/index.cjs.map +3 -3
  43. package/dist/lib/node/{intent-resolver-QDGZMWLY.cjs → intent-resolver-R3OSTIMH.cjs} +15 -10
  44. package/dist/lib/node/intent-resolver-R3OSTIMH.cjs.map +7 -0
  45. package/dist/lib/node/meta.json +1 -1
  46. package/dist/lib/node/{react-surface-XNEIJJYJ.cjs → react-surface-NUQTM6MS.cjs} +25 -25
  47. package/dist/lib/node/react-surface-NUQTM6MS.cjs.map +7 -0
  48. package/dist/lib/node/{settings-WLTC7XO5.cjs → settings-TXGRCYAL.cjs} +7 -7
  49. package/dist/lib/node/settings-TXGRCYAL.cjs.map +7 -0
  50. package/dist/lib/node/types/index.cjs +12 -14
  51. package/dist/lib/node/types/index.cjs.map +2 -2
  52. package/dist/lib/node-esm/{AssistantDialog-D33WZUGR.mjs → AssistantDialog-U2FQX5TD.mjs} +3 -3
  53. package/dist/lib/node-esm/{ChatContainer-FAYGNMQW.mjs → ChatContainer-QW3OOXTT.mjs} +3 -3
  54. package/dist/lib/node-esm/ChatContainer-QW3OOXTT.mjs.map +7 -0
  55. package/dist/lib/node-esm/TemplateContainer-EUM2X65J.mjs +79 -0
  56. package/dist/lib/node-esm/TemplateContainer-EUM2X65J.mjs.map +7 -0
  57. package/dist/lib/node-esm/{ai-client-RZQWEDUX.mjs → ai-client-WMHS5EGV.mjs} +3 -3
  58. package/dist/lib/node-esm/ai-client-WMHS5EGV.mjs.map +7 -0
  59. package/dist/lib/node-esm/app-graph-builder-DWBNIMHM.mjs +210 -0
  60. package/dist/lib/node-esm/app-graph-builder-DWBNIMHM.mjs.map +7 -0
  61. package/dist/lib/node-esm/chunk-GBBXIW5F.mjs +129 -0
  62. package/dist/lib/node-esm/chunk-GBBXIW5F.mjs.map +7 -0
  63. package/dist/lib/node-esm/{chunk-ED55ZE4G.mjs → chunk-MVDAY3CZ.mjs} +136 -147
  64. package/dist/lib/node-esm/chunk-MVDAY3CZ.mjs.map +7 -0
  65. package/dist/lib/node-esm/chunk-MXK2EANZ.mjs +184 -0
  66. package/dist/lib/node-esm/chunk-MXK2EANZ.mjs.map +7 -0
  67. package/dist/lib/node-esm/index.mjs +11 -14
  68. package/dist/lib/node-esm/index.mjs.map +3 -3
  69. package/dist/lib/node-esm/{intent-resolver-Q3I6S6HN.mjs → intent-resolver-H32TL4X6.mjs} +12 -7
  70. package/dist/lib/node-esm/intent-resolver-H32TL4X6.mjs.map +7 -0
  71. package/dist/lib/node-esm/meta.json +1 -1
  72. package/dist/lib/node-esm/{react-surface-RI3JONQY.mjs → react-surface-JBVZF6CP.mjs} +17 -17
  73. package/dist/lib/node-esm/react-surface-JBVZF6CP.mjs.map +7 -0
  74. package/dist/lib/node-esm/{settings-CLE57WEP.mjs → settings-DZU5PNXM.mjs} +4 -4
  75. package/dist/lib/node-esm/settings-DZU5PNXM.mjs.map +7 -0
  76. package/dist/lib/node-esm/types/index.mjs +1 -3
  77. package/dist/types/src/capabilities/ai-client.d.ts +2 -2
  78. package/dist/types/src/capabilities/ai-client.d.ts.map +1 -1
  79. package/dist/types/src/capabilities/app-graph-builder.d.ts +179 -2
  80. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
  81. package/dist/types/src/capabilities/index.d.ts +179 -3
  82. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  83. package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -1
  84. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  85. package/dist/types/src/components/AmbientDialog/AmbientDialog.d.ts.map +1 -1
  86. package/dist/types/src/components/AssistantSettings/AssistantSettings.d.ts.map +1 -1
  87. package/dist/types/src/components/ChatContainer.d.ts +3 -4
  88. package/dist/types/src/components/ChatContainer.d.ts.map +1 -1
  89. package/dist/types/src/components/Prompt/PromptBar.d.ts.map +1 -1
  90. package/dist/types/src/components/Prompt/autocomplete.d.ts.map +1 -1
  91. package/dist/types/src/components/Prompt/references.d.ts.map +1 -1
  92. package/dist/types/src/components/ServiceRegistry/ServiceRegistry.d.ts +6 -0
  93. package/dist/types/src/components/ServiceRegistry/ServiceRegistry.d.ts.map +1 -0
  94. package/dist/types/src/components/ServiceRegistry/ServiceRegistry.stories.d.ts +8 -0
  95. package/dist/types/src/components/ServiceRegistry/ServiceRegistry.stories.d.ts.map +1 -0
  96. package/dist/types/src/components/ServiceRegistry/index.d.ts +2 -0
  97. package/dist/types/src/components/ServiceRegistry/index.d.ts.map +1 -0
  98. package/dist/types/src/components/TemplateContainer.d.ts.map +1 -1
  99. package/dist/types/src/components/TemplateEditor/TemplateEditor.d.ts.map +1 -1
  100. package/dist/types/src/components/TemplateEditor/TemplateEditor.stories.d.ts.map +1 -1
  101. package/dist/types/src/components/TemplateEditor/TemplateForm.d.ts +2 -2
  102. package/dist/types/src/components/TemplateEditor/TemplateForm.d.ts.map +1 -1
  103. package/dist/types/src/components/Thread/Thread.d.ts.map +1 -1
  104. package/dist/types/src/components/Thread/Thread.stories.d.ts.map +1 -1
  105. package/dist/types/src/components/Thread/ThreadContainer.d.ts.map +1 -1
  106. package/dist/types/src/components/Thread/ThreadContainer.stories.d.ts +2 -2
  107. package/dist/types/src/components/Thread/ThreadContainer.stories.d.ts.map +1 -1
  108. package/dist/types/src/components/Thread/ToolInvocations.d.ts.map +1 -1
  109. package/dist/types/src/components/Toolbox/Toolbox.d.ts +1 -1
  110. package/dist/types/src/components/Toolbox/Toolbox.d.ts.map +1 -1
  111. package/dist/types/src/components/index.d.ts +6 -2
  112. package/dist/types/src/components/index.d.ts.map +1 -1
  113. package/dist/types/src/hooks/index.d.ts +1 -0
  114. package/dist/types/src/hooks/index.d.ts.map +1 -1
  115. package/dist/types/src/hooks/invocation-handler.d.ts +5 -0
  116. package/dist/types/src/hooks/invocation-handler.d.ts.map +1 -0
  117. package/dist/types/src/hooks/processor.d.ts.map +1 -1
  118. package/dist/types/src/hooks/useChatProcessor.d.ts.map +1 -1
  119. package/dist/types/src/hooks/useContextProvider.d.ts +1 -1
  120. package/dist/types/src/hooks/useContextProvider.d.ts.map +1 -1
  121. package/dist/types/src/hooks/useLocalTriggerManager.d.ts +3 -0
  122. package/dist/types/src/hooks/useLocalTriggerManager.d.ts.map +1 -0
  123. package/dist/types/src/hooks/useMessageQueue.d.ts +3 -0
  124. package/dist/types/src/hooks/useMessageQueue.d.ts.map +1 -1
  125. package/dist/types/src/hooks/useServices.d.ts.map +1 -1
  126. package/dist/types/src/hooks/useTextInputEvents.d.ts.map +1 -1
  127. package/dist/types/src/testing/test-functions.d.ts.map +1 -1
  128. package/dist/types/src/tools/function.d.ts +2 -2
  129. package/dist/types/src/tools/function.d.ts.map +1 -1
  130. package/dist/types/src/tools/openapi.d.ts.map +1 -1
  131. package/dist/types/src/translations.d.ts +58 -7
  132. package/dist/types/src/translations.d.ts.map +1 -1
  133. package/dist/types/src/types/service.d.ts +95 -96
  134. package/dist/types/src/types/service.d.ts.map +1 -1
  135. package/dist/types/src/types/template.d.ts +52 -52
  136. package/dist/types/src/types/template.d.ts.map +1 -1
  137. package/dist/types/src/types/types.d.ts +18 -20
  138. package/dist/types/src/types/types.d.ts.map +1 -1
  139. package/dist/types/tsconfig.tsbuildinfo +1 -1
  140. package/package.json +58 -64
  141. package/src/AssistantPlugin.tsx +2 -2
  142. package/src/capabilities/ai-client.ts +5 -4
  143. package/src/capabilities/app-graph-builder.ts +133 -161
  144. package/src/capabilities/index.ts +1 -1
  145. package/src/capabilities/intent-resolver.ts +8 -5
  146. package/src/capabilities/react-surface.tsx +11 -13
  147. package/src/capabilities/settings.ts +2 -2
  148. package/src/components/AmbientDialog/AmbientDialog.stories.tsx +1 -1
  149. package/src/components/AssistantSettings/AssistantSettings.tsx +6 -28
  150. package/src/components/ChatContainer.tsx +8 -6
  151. package/src/components/Prompt/Prompt.stories.tsx +1 -1
  152. package/src/components/Prompt/PromptBar.tsx +12 -4
  153. package/src/components/ServiceRegistry/ServiceRegistry.stories.tsx +49 -0
  154. package/src/components/ServiceRegistry/ServiceRegistry.tsx +76 -0
  155. package/src/components/ServiceRegistry/index.ts +5 -0
  156. package/src/components/TemplateContainer.tsx +79 -3
  157. package/src/components/TemplateEditor/TemplateEditor.stories.tsx +2 -2
  158. package/src/components/TemplateEditor/TemplateForm.stories.tsx +2 -2
  159. package/src/components/TemplateEditor/TemplateForm.tsx +2 -2
  160. package/src/components/Thread/Thread.stories.tsx +15 -12
  161. package/src/components/Thread/ThreadContainer.stories.tsx +21 -12
  162. package/src/components/Thread/ThreadContainer.tsx +2 -24
  163. package/src/components/Thread/ThreadMessage.tsx +3 -6
  164. package/src/components/Toolbox/Toolbox.stories.tsx +3 -3
  165. package/src/components/Toolbox/Toolbox.tsx +3 -3
  166. package/src/components/index.ts +1 -1
  167. package/src/hooks/index.ts +1 -0
  168. package/src/hooks/invocation-handler.ts +107 -0
  169. package/src/hooks/processor.ts +4 -26
  170. package/src/hooks/useChatProcessor.tsx +7 -8
  171. package/src/hooks/useContextProvider.ts +16 -20
  172. package/src/hooks/useLocalTriggerManager.ts +82 -0
  173. package/src/hooks/useMessageQueue.ts +2 -2
  174. package/src/testing/test-services.ts +6 -6
  175. package/src/tools/function.ts +6 -4
  176. package/src/tools/openapi.ts +3 -4
  177. package/src/translations.ts +4 -5
  178. package/src/types/service.ts +37 -39
  179. package/src/types/template.ts +25 -27
  180. package/src/types/types.ts +17 -20
  181. package/dist/lib/browser/ChatContainer-ZNKENYKZ.mjs.map +0 -7
  182. package/dist/lib/browser/TemplateContainer-WKU5XFSO.mjs +0 -22
  183. package/dist/lib/browser/TemplateContainer-WKU5XFSO.mjs.map +0 -7
  184. package/dist/lib/browser/ai-client-5PRCXI7N.mjs.map +0 -7
  185. package/dist/lib/browser/app-graph-builder-HTK3HFGM.mjs +0 -189
  186. package/dist/lib/browser/app-graph-builder-HTK3HFGM.mjs.map +0 -7
  187. package/dist/lib/browser/chunk-5P7U35RJ.mjs +0 -192
  188. package/dist/lib/browser/chunk-5P7U35RJ.mjs.map +0 -7
  189. package/dist/lib/browser/chunk-7VDZP5WX.mjs +0 -143
  190. package/dist/lib/browser/chunk-7VDZP5WX.mjs.map +0 -7
  191. package/dist/lib/browser/chunk-OWZHLWW5.mjs.map +0 -7
  192. package/dist/lib/browser/intent-resolver-QV5AAVJZ.mjs.map +0 -7
  193. package/dist/lib/browser/react-surface-JJPYWEIN.mjs.map +0 -7
  194. package/dist/lib/browser/settings-OZX7J65A.mjs.map +0 -7
  195. package/dist/lib/node/ChatContainer-WVAAOEOH.cjs.map +0 -7
  196. package/dist/lib/node/TemplateContainer-EQXKHWTF.cjs +0 -52
  197. package/dist/lib/node/TemplateContainer-EQXKHWTF.cjs.map +0 -7
  198. package/dist/lib/node/ai-client-OUPSRQT7.cjs.map +0 -7
  199. package/dist/lib/node/app-graph-builder-LEO63CZZ.cjs.map +0 -7
  200. package/dist/lib/node/chunk-GQ3XS5FZ.cjs.map +0 -7
  201. package/dist/lib/node/chunk-OOHFSPWR.cjs.map +0 -7
  202. package/dist/lib/node/chunk-VG2UQY4S.cjs +0 -216
  203. package/dist/lib/node/chunk-VG2UQY4S.cjs.map +0 -7
  204. package/dist/lib/node/intent-resolver-QDGZMWLY.cjs.map +0 -7
  205. package/dist/lib/node/react-surface-XNEIJJYJ.cjs.map +0 -7
  206. package/dist/lib/node/settings-WLTC7XO5.cjs.map +0 -7
  207. package/dist/lib/node-esm/ChatContainer-FAYGNMQW.mjs.map +0 -7
  208. package/dist/lib/node-esm/TemplateContainer-3LEBT5ZC.mjs +0 -23
  209. package/dist/lib/node-esm/TemplateContainer-3LEBT5ZC.mjs.map +0 -7
  210. package/dist/lib/node-esm/ai-client-RZQWEDUX.mjs.map +0 -7
  211. package/dist/lib/node-esm/app-graph-builder-WXJNZDYB.mjs +0 -190
  212. package/dist/lib/node-esm/app-graph-builder-WXJNZDYB.mjs.map +0 -7
  213. package/dist/lib/node-esm/chunk-74GFINWJ.mjs +0 -144
  214. package/dist/lib/node-esm/chunk-74GFINWJ.mjs.map +0 -7
  215. package/dist/lib/node-esm/chunk-ED55ZE4G.mjs.map +0 -7
  216. package/dist/lib/node-esm/chunk-UZWYXNR5.mjs +0 -193
  217. package/dist/lib/node-esm/chunk-UZWYXNR5.mjs.map +0 -7
  218. package/dist/lib/node-esm/intent-resolver-Q3I6S6HN.mjs.map +0 -7
  219. package/dist/lib/node-esm/react-surface-RI3JONQY.mjs.map +0 -7
  220. package/dist/lib/node-esm/settings-CLE57WEP.mjs.map +0 -7
  221. package/dist/types/src/components/PromptSettings.d.ts +0 -6
  222. package/dist/types/src/components/PromptSettings.d.ts.map +0 -1
  223. package/src/components/PromptSettings.tsx +0 -91
  224. /package/dist/lib/browser/{AssistantDialog-DTWVEQBB.mjs.map → AssistantDialog-YSHMAHW5.mjs.map} +0 -0
  225. /package/dist/lib/node/{AssistantDialog-RJJHZI63.cjs.map → AssistantDialog-YI2BSGSX.cjs.map} +0 -0
  226. /package/dist/lib/node-esm/{AssistantDialog-D33WZUGR.mjs.map → AssistantDialog-U2FQX5TD.mjs.map} +0 -0
@@ -2,214 +2,186 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { Rx } from '@effect-rx/rx-react';
6
- import { Option, pipe } from 'effect';
7
-
8
5
  import {
9
6
  Capabilities,
10
7
  contributes,
11
8
  createIntent,
12
9
  LayoutAction,
13
10
  type PromiseIntentDispatcher,
14
- type PluginContext,
11
+ type PluginsContext,
15
12
  } from '@dxos/app-framework';
16
13
  import { invariant } from '@dxos/invariant';
17
14
  import { ClientCapabilities } from '@dxos/plugin-client';
18
- import { PLANK_COMPANION_TYPE, ATTENDABLE_PATH_SEPARATOR } from '@dxos/plugin-deck/types';
19
- import { createExtension, ROOT_ID } from '@dxos/plugin-graph';
20
- import { rxFromQuery } from '@dxos/plugin-space';
21
- import { SPACE_TYPE, SpaceAction } from '@dxos/plugin-space/types';
15
+ import { PLANK_COMPANION_TYPE, ATTENDABLE_PATH_SEPARATOR, DECK_COMPANION_TYPE } from '@dxos/plugin-deck/types';
16
+ import { createExtension, type Node, ROOT_ID } from '@dxos/plugin-graph';
17
+ import { memoizeQuery } from '@dxos/plugin-space';
18
+ import { SpaceAction } from '@dxos/plugin-space/types';
22
19
  import {
23
20
  type Space,
24
21
  Filter,
25
22
  fullyQualifiedId,
26
23
  getSpace,
27
- isLiveObject,
28
24
  isSpace,
29
- Query,
30
- type QueryResult,
25
+ isReactiveObject,
26
+ parseId,
31
27
  } from '@dxos/react-client/echo';
32
28
 
33
29
  import { ASSISTANT_DIALOG, ASSISTANT_PLUGIN } from '../meta';
34
30
  import { AIChatType, AssistantAction, TemplateType } from '../types';
35
31
 
36
- export default (context: PluginContext) =>
32
+ export default (context: PluginsContext) =>
37
33
  contributes(Capabilities.AppGraphBuilder, [
38
34
  createExtension({
39
35
  id: `${ASSISTANT_PLUGIN}/assistant`,
40
- actions: (node) =>
41
- Rx.make((get) =>
42
- pipe(
43
- get(node),
44
- Option.flatMap((node) => (node.id === ROOT_ID ? Option.some(node) : Option.none())),
45
- Option.map(() => [
46
- {
47
- id: `${LayoutAction.UpdateDialog._tag}/assistant/open`,
48
- data: async () => {
49
- const { dispatchPromise: dispatch } = context.getCapability(Capabilities.IntentDispatcher);
50
- const client = context.getCapability(ClientCapabilities.Client);
51
- const layout = context.getCapability(Capabilities.Layout);
52
- const { graph } = context.getCapability(Capabilities.AppGraph);
36
+ filter: (node): node is Node<null> => node.id === ROOT_ID,
37
+ actions: () => [
38
+ {
39
+ id: `${LayoutAction.UpdateDialog._tag}/assistant/open`,
40
+ data: async () => {
41
+ const { dispatchPromise: dispatch } = context.requestCapability(Capabilities.IntentDispatcher);
42
+ const client = context.requestCapability(ClientCapabilities.Client);
43
+ const layout = context.requestCapability(Capabilities.Layout);
44
+ const { graph } = context.requestCapability(Capabilities.AppGraph);
53
45
 
54
- // TODO(burdon): Get space from workspace.
55
- // TODO(burdon): If need to create chat, then add to dispatch stack below.
56
- let chat: AIChatType | undefined;
57
- if (layout.active.length > 0) {
58
- const node = graph.getNode(layout.active[0]).pipe(Option.getOrNull);
59
- if (node) {
60
- const space = getSpace(node.data);
61
- if (space) {
62
- chat = await getOrCreateChat(dispatch, space);
63
- }
64
- }
65
- } else {
66
- const space = client.spaces.default;
67
- chat = await getOrCreateChat(dispatch, space);
68
- }
46
+ // TODO(burdon): Get space from workspace.
47
+ // TODO(burdon): If need to create chat, then add to dispatch stack below.
48
+ let chat: AIChatType | undefined;
49
+ if (layout.active.length > 0) {
50
+ const node = graph.findNode(layout.active[0]);
51
+ if (node) {
52
+ const space = getSpace(node.data);
53
+ if (space) {
54
+ chat = await getOrCreateChat(dispatch, space);
55
+ }
56
+ }
57
+ } else {
58
+ const space = client.spaces.default;
59
+ chat = await getOrCreateChat(dispatch, space);
60
+ }
69
61
 
70
- if (!chat) {
71
- return;
72
- }
62
+ if (!chat) {
63
+ return;
64
+ }
73
65
 
74
- await dispatch(
75
- createIntent(LayoutAction.UpdateDialog, {
76
- part: 'dialog',
77
- subject: ASSISTANT_DIALOG,
78
- options: {
79
- state: true,
80
- blockAlign: 'end',
81
- props: {
82
- chat,
83
- },
84
- },
85
- }),
86
- );
87
- },
88
- properties: {
89
- label: ['open assistant label', { ns: ASSISTANT_PLUGIN }],
90
- icon: 'ph--sparkle--regular',
91
- disposition: 'pin-end',
92
- position: 'hoist',
93
- keyBinding: {
94
- macos: 'shift+meta+k',
95
- windows: 'shift+ctrl+k',
66
+ await dispatch(
67
+ createIntent(LayoutAction.UpdateDialog, {
68
+ part: 'dialog',
69
+ subject: ASSISTANT_DIALOG,
70
+ options: {
71
+ state: true,
72
+ blockAlign: 'end',
73
+ props: {
74
+ chat,
96
75
  },
97
76
  },
98
- },
99
- ]),
100
- Option.getOrElse(() => []),
101
- ),
102
- ),
77
+ }),
78
+ );
79
+ },
80
+ properties: {
81
+ label: ['open assistant label', { ns: ASSISTANT_PLUGIN }],
82
+ icon: 'ph--star-four--regular',
83
+ disposition: 'pin-end',
84
+ position: 'hoist',
85
+ keyBinding: {
86
+ macos: 'shift+meta+k',
87
+ windows: 'shift+ctrl+k',
88
+ },
89
+ },
90
+ },
91
+ ],
92
+ }),
93
+
94
+ createExtension({
95
+ id: `${ASSISTANT_PLUGIN}/service-registry`,
96
+ filter: (node): node is Node<null> => node.id === 'root',
97
+ connector: ({ node }) => {
98
+ const layout = context.requestCapability(Capabilities.Layout);
99
+ const client = context.requestCapability(ClientCapabilities.Client);
100
+ const { spaceId } = parseId(layout.workspace);
101
+ const space = spaceId ? client.spaces.get(spaceId) : null;
102
+
103
+ return [
104
+ {
105
+ id: [node.id, 'service-registry'].join(ATTENDABLE_PATH_SEPARATOR),
106
+ type: DECK_COMPANION_TYPE,
107
+ data: space,
108
+ properties: {
109
+ label: ['service registry label', { ns: ASSISTANT_PLUGIN }],
110
+ icon: 'ph--plugs--regular',
111
+ disposition: 'hidden',
112
+ },
113
+ },
114
+ ];
115
+ },
103
116
  }),
104
117
 
105
118
  createExtension({
106
119
  id: `${ASSISTANT_PLUGIN}/object-chat-companion`,
107
- // TODO(burdon): Add to all objects?
108
- connector: (node) =>
109
- Rx.make((get) =>
110
- pipe(
111
- get(node),
112
- Option.flatMap((node) =>
113
- isLiveObject(node.data) && node.data.assistantChatQueue && node.data.type !== AIChatType.typename
114
- ? Option.some(node)
115
- : Option.none(),
116
- ),
117
- Option.map((node) => [
118
- {
119
- id: [node.id, 'assistant-chat'].join(ATTENDABLE_PATH_SEPARATOR),
120
- type: PLANK_COMPANION_TYPE,
121
- data: 'assistant-chat',
122
- properties: {
123
- label: ['assistant chat label', { ns: ASSISTANT_PLUGIN }],
124
- icon: 'ph--sparkle--regular',
125
- position: 'hoist',
126
- },
127
- },
128
- ]),
129
- Option.getOrElse(() => []),
130
- ),
131
- ),
120
+ filter: (node): node is Node<AIChatType> =>
121
+ isReactiveObject(node.data) && node.data.assistantChatQueue && node.data.type !== AIChatType.typename,
122
+ connector: ({ node }) => [
123
+ {
124
+ id: [node.id, 'assistant-chat'].join(ATTENDABLE_PATH_SEPARATOR),
125
+ type: PLANK_COMPANION_TYPE,
126
+ data: 'assistant-chat',
127
+ properties: {
128
+ label: ['assistant chat label', { ns: ASSISTANT_PLUGIN }],
129
+ icon: 'ph--star-four--regular',
130
+ position: 'hoist',
131
+ },
132
+ },
133
+ ],
132
134
  }),
133
135
 
134
136
  createExtension({
135
137
  id: `${ASSISTANT_PLUGIN}/root`,
136
- connector: (node) => {
137
- let query: QueryResult<TemplateType> | undefined;
138
- return Rx.make((get) =>
139
- pipe(
140
- get(node),
141
- Option.flatMap((node) =>
142
- node.type === SPACE_TYPE && isSpace(node.data) ? Option.some(node.data) : Option.none(),
143
- ),
144
- Option.map((space) => {
145
- if (!query) {
146
- query = space.db.query(Query.type(TemplateType));
147
- }
148
-
149
- const templates = get(rxFromQuery(query));
150
- return templates.length > 0
151
- ? [
152
- {
153
- id: `${ASSISTANT_PLUGIN}/templates`,
154
- type: `${ASSISTANT_PLUGIN}/templates`,
155
- data: null,
156
- properties: {
157
- label: ['templates label', { ns: ASSISTANT_PLUGIN }],
158
- icon: 'ph--file-code--regular',
159
- space,
160
- },
161
- },
162
- ]
163
- : [];
164
- }),
165
- Option.getOrElse(() => []),
166
- ),
167
- );
138
+ filter: (node): node is Node<Space> => isSpace(node.data),
139
+ connector: ({ node }) => {
140
+ const templates = memoizeQuery(node.data, Filter.schema(TemplateType));
141
+ return templates.length > 0
142
+ ? [
143
+ {
144
+ id: `${ASSISTANT_PLUGIN}/templates`,
145
+ type: `${ASSISTANT_PLUGIN}/templates`,
146
+ data: null,
147
+ properties: {
148
+ label: ['templates label', { ns: ASSISTANT_PLUGIN }],
149
+ icon: 'ph--file-code--regular',
150
+ space: node.data,
151
+ },
152
+ },
153
+ ]
154
+ : [];
168
155
  },
169
156
  }),
170
157
 
171
158
  createExtension({
172
159
  id: `${ASSISTANT_PLUGIN}/templates`,
173
- connector: (node) => {
174
- let query: QueryResult<TemplateType> | undefined;
175
- return Rx.make((get) =>
176
- pipe(
177
- get(node),
178
- Option.flatMap((node) =>
179
- node.id === `${ASSISTANT_PLUGIN}/templates` && isSpace(node.properties.space)
180
- ? Option.some(node.properties.space)
181
- : Option.none(),
182
- ),
183
- Option.map((space) => {
184
- if (!query) {
185
- query = space.db.query(Query.type(TemplateType));
186
- }
187
- return get(rxFromQuery(query))
188
- .toSorted((a, b) => {
189
- const nameA = a.name ?? '';
190
- const nameB = b.name ?? '';
191
- return nameA.localeCompare(nameB);
192
- })
193
- .map((template) => ({
194
- id: fullyQualifiedId(template),
195
- type: `${ASSISTANT_PLUGIN}/template`,
196
- data: template,
197
- properties: {
198
- label: template.name ?? ['object placeholder', { ns: ASSISTANT_PLUGIN }],
199
- icon: 'ph--file-code--regular',
200
- },
201
- }));
202
- }),
203
- Option.getOrElse(() => []),
204
- ),
205
- );
160
+ filter: (node): node is Node<null, { space: Space }> => node.id === `${ASSISTANT_PLUGIN}/templates`,
161
+ connector: ({ node }) => {
162
+ const templates = memoizeQuery(node.properties.space, Filter.schema(TemplateType));
163
+ return templates
164
+ .toSorted((a, b) => {
165
+ const nameA = a.name ?? '';
166
+ const nameB = b.name ?? '';
167
+ return nameA.localeCompare(nameB);
168
+ })
169
+ .map((template) => ({
170
+ id: fullyQualifiedId(template),
171
+ type: `${ASSISTANT_PLUGIN}/template`,
172
+ data: template,
173
+ properties: {
174
+ label: template.name ?? ['template title placeholder', { ns: ASSISTANT_PLUGIN }],
175
+ icon: 'ph--file-code--regular',
176
+ },
177
+ }));
206
178
  },
207
179
  }),
208
180
  ]);
209
181
 
210
182
  // TODO(burdon): Factor out.
211
183
  const getOrCreateChat = async (dispatch: PromiseIntentDispatcher, space: Space): Promise<AIChatType | undefined> => {
212
- const { objects } = await space.db.query(Filter.type(AIChatType)).run();
184
+ const { objects } = await space.db.query(Filter.schema(AIChatType)).run();
213
185
  // console.log('objects', JSON.stringify(objects, null, 2));
214
186
  if (objects.length > 0) {
215
187
  // TODO(burdon): Is this the most recent?
@@ -8,6 +8,6 @@ export const AiClient = lazy(() => import('./ai-client'));
8
8
  export const AppGraphBuilder = lazy(() => import('./app-graph-builder'));
9
9
  export const IntentResolver = lazy(() => import('./intent-resolver'));
10
10
  export const ReactSurface = lazy(() => import('./react-surface'));
11
- export const Settings = lazy(() => import('./settings'));
11
+ export const AssistantSettings = lazy(() => import('./settings'));
12
12
 
13
13
  export * from './capabilities';
@@ -3,8 +3,9 @@
3
3
  //
4
4
 
5
5
  import { Capabilities, contributes, createResolver } from '@dxos/app-framework';
6
- import { createQueueDxn } from '@dxos/echo-schema';
7
- import { live, refFromDXN } from '@dxos/live-object';
6
+ import { ObjectId } from '@dxos/echo-schema';
7
+ import { DXN, QueueSubspaceTags } from '@dxos/keys';
8
+ import { create, refFromDXN } from '@dxos/live-object';
8
9
 
9
10
  import { AssistantAction, AIChatType, TemplateType } from '../types';
10
11
 
@@ -15,8 +16,10 @@ export default () => [
15
16
  intent: AssistantAction.CreateChat,
16
17
  resolve: ({ spaceId, name }) => ({
17
18
  data: {
18
- object: live(AIChatType, {
19
- assistantChatQueue: refFromDXN(createQueueDxn(spaceId)),
19
+ object: create(AIChatType, {
20
+ assistantChatQueue: refFromDXN(
21
+ new DXN(DXN.kind.QUEUE, [QueueSubspaceTags.DATA, spaceId, ObjectId.random()]),
22
+ ),
20
23
  }),
21
24
  },
22
25
  }),
@@ -28,7 +31,7 @@ export default () => [
28
31
  intent: AssistantAction.CreateTemplate,
29
32
  resolve: ({ name }) => ({
30
33
  data: {
31
- object: live(TemplateType, { name, kind: { include: 'manual' }, source: '{{! Template }}' }),
34
+ object: create(TemplateType, { name, kind: { include: 'manual' }, source: '{{! Template }}' }),
32
35
  },
33
36
  }),
34
37
  }),
@@ -5,11 +5,12 @@
5
5
  import React, { useMemo } from 'react';
6
6
 
7
7
  import { Capabilities, contributes, createSurface } from '@dxos/app-framework';
8
- import { Type } from '@dxos/echo';
8
+ import { isInstanceOf } from '@dxos/echo-schema';
9
+ import { getTypename } from '@dxos/live-object';
9
10
  import { SettingsStore } from '@dxos/local-storage';
10
- import { fullyQualifiedId, getSpace, getTypename, isLiveObject, type SpaceId } from '@dxos/react-client/echo';
11
+ import { fullyQualifiedId, isReactiveObject, isSpace, type Space } from '@dxos/react-client/echo';
11
12
 
12
- import { AssistantDialog, AssistantSettings, ChatContainer, PromptSettings, TemplateContainer } from '../components';
13
+ import { AssistantDialog, AssistantSettings, ChatContainer, ServiceRegistry, TemplateContainer } from '../components';
13
14
  import { ASSISTANT_PLUGIN, ASSISTANT_DIALOG } from '../meta';
14
15
  import { AIChatType, type AssistantSettingsProps, TemplateType } from '../types';
15
16
 
@@ -32,22 +33,19 @@ export default () =>
32
33
  id: `${ASSISTANT_PLUGIN}/chat`,
33
34
  role: 'article',
34
35
  filter: (data): data is { subject: AIChatType; variant: undefined } =>
35
- Type.instanceOf(AIChatType, data.subject) && data.variant !== 'assistant-chat',
36
+ isInstanceOf(AIChatType, data.subject) && data.variant !== 'assistant-chat',
36
37
  component: ({ data, role }) => <ChatContainer role={role} chat={data.subject} />,
37
38
  }),
38
39
  createSurface({
39
40
  id: `${ASSISTANT_PLUGIN}/object-chat`,
40
41
  role: 'article',
41
42
  filter: (data): data is { companionTo: AIChatType; subject: 'assistant-chat' } =>
42
- isLiveObject(data.companionTo) &&
43
- (data as any).companionTo.assistantChatQueue &&
44
- data.subject === 'assistant-chat',
43
+ isReactiveObject(data.companionTo) && data.companionTo.assistantChatQueue && data.subject === 'assistant-chat',
45
44
  component: ({ data, role }) => {
46
45
  const associatedArtifact = useMemo(
47
46
  () => ({
48
47
  id: fullyQualifiedId(data.companionTo),
49
48
  typename: getTypename(data.companionTo) ?? 'unknown',
50
- spaceId: (getSpace(data.companionTo)?.id ?? 'unknown') as SpaceId,
51
49
  }),
52
50
  [data.companionTo],
53
51
  );
@@ -57,13 +55,13 @@ export default () =>
57
55
  createSurface({
58
56
  id: `${ASSISTANT_PLUGIN}/template`,
59
57
  role: 'article',
60
- filter: (data): data is { subject: TemplateType } => Type.instanceOf(TemplateType, data.subject),
58
+ filter: (data): data is { subject: TemplateType } => isInstanceOf(TemplateType, data.subject),
61
59
  component: ({ data, role }) => <TemplateContainer role={role} template={data.subject} />,
62
60
  }),
63
61
  createSurface({
64
- id: `${ASSISTANT_PLUGIN}/prompt-settings`,
65
- role: 'object-settings',
66
- filter: (data): data is { subject: TemplateType } => Type.instanceOf(TemplateType, data.subject),
67
- component: ({ data }) => <PromptSettings template={data.subject} />,
62
+ id: `${ASSISTANT_PLUGIN}/service-registry`,
63
+ role: 'deck-companion--service-registry',
64
+ filter: (data): data is { subject: Space } => isSpace(data.subject),
65
+ component: ({ data }) => <ServiceRegistry space={data.subject} />,
68
66
  }),
69
67
  ]);
@@ -3,13 +3,13 @@
3
3
  //
4
4
 
5
5
  import { Capabilities, contributes } from '@dxos/app-framework';
6
- import { live } from '@dxos/live-object';
6
+ import { create } from '@dxos/live-object';
7
7
 
8
8
  import { ASSISTANT_PLUGIN } from '../meta';
9
9
  import { type AssistantSettingsProps, AssistantSettingsSchema } from '../types';
10
10
 
11
11
  export default () => {
12
- const settings = live<AssistantSettingsProps>({});
12
+ const settings = create<AssistantSettingsProps>({});
13
13
 
14
14
  return contributes(Capabilities.Settings, {
15
15
  schema: AssistantSettingsSchema,
@@ -69,7 +69,7 @@ const meta: Meta<typeof AmbientDialog> = {
69
69
  plugins: [IntentPlugin()],
70
70
  }),
71
71
  withTheme,
72
- withLayout({ fullscreen: true }),
72
+ withLayout({ fullscreen: true, tooltips: true }),
73
73
  ],
74
74
  parameters: {
75
75
  translations,
@@ -9,17 +9,11 @@ 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
- import { LLM_PROVIDERS, type AssistantSettingsProps } from '../../types';
12
+ import { type AssistantSettingsProps } from '../../types';
13
13
 
14
- // TODO(burdon): Factor out default Selector.
14
+ // TODO(burdon): Factor out.
15
15
  const DEFAULT_VALUE = '__default';
16
16
 
17
- const LLM_PROVIDER_LABELS = {
18
- edge: 'DXOS',
19
- ollama: 'Ollama',
20
- lmstudio: 'LM Studio',
21
- } as const;
22
-
23
17
  export const AssistantSettings = ({ settings }: { settings: AssistantSettingsProps }) => {
24
18
  const { t } = useTranslation(ASSISTANT_PLUGIN);
25
19
 
@@ -33,26 +27,10 @@ export const AssistantSettings = ({ settings }: { settings: AssistantSettingsPro
33
27
  </DeprecatedFormInput>
34
28
 
35
29
  <DeprecatedFormInput label={t('settings llm provider label')}>
36
- <Select.Root
37
- value={settings.llmProvider ?? 'edge'}
38
- onValueChange={(value) => {
39
- settings.llmProvider = value === DEFAULT_VALUE ? undefined : (value as any);
40
- }}
41
- >
42
- <Select.TriggerButton placeholder={t('settings llm provider label')} />
43
- <Select.Portal>
44
- <Select.Content>
45
- <Select.Viewport>
46
- <Select.Option value={DEFAULT_VALUE}>{t('settings default label')}</Select.Option>
47
- {LLM_PROVIDERS.map((model) => (
48
- <Select.Option key={model} value={model}>
49
- {LLM_PROVIDER_LABELS[model]}
50
- </Select.Option>
51
- ))}
52
- </Select.Viewport>
53
- </Select.Content>
54
- </Select.Portal>
55
- </Select.Root>
30
+ <Input.Switch
31
+ checked={settings.llmProvider === 'ollama'}
32
+ onCheckedChange={(checked) => (settings.llmProvider = checked ? 'ollama' : 'edge')}
33
+ />
56
34
  </DeprecatedFormInput>
57
35
 
58
36
  <DeprecatedFormInput label={t('settings edge llm model label')}>
@@ -2,7 +2,7 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import React, { type FC } from 'react';
5
+ import React from 'react';
6
6
 
7
7
  import { Capabilities, useCapabilities, useCapability } from '@dxos/app-framework';
8
8
  import { type AssociatedArtifact } from '@dxos/artifact';
@@ -13,14 +13,16 @@ import { ThreadContainer } from './Thread';
13
13
  import { ASSISTANT_PLUGIN } from '../meta';
14
14
  import { type AssistantSettingsProps, type AIChatType } from '../types';
15
15
 
16
- export type ChatContainerProps = {
16
+ // TODO(burdon): Attention.
17
+ export const ChatContainer = ({
18
+ role,
19
+ chat,
20
+ associatedArtifact,
21
+ }: {
17
22
  role: string;
18
23
  chat: AIChatType;
19
24
  associatedArtifact?: AssociatedArtifact;
20
- };
21
-
22
- // TODO(burdon): Attention.
23
- export const ChatContainer: FC<ChatContainerProps> = ({ role, chat, associatedArtifact }) => {
25
+ }) => {
24
26
  const transcription = useCapabilities(TranscriptionCapabilities.Transcriber).length > 0;
25
27
  const settings = useCapability(Capabilities.SettingsStore).getStore<AssistantSettingsProps>(ASSISTANT_PLUGIN)?.value;
26
28
 
@@ -17,7 +17,7 @@ import translations from '../../translations';
17
17
  const meta: Meta<typeof Prompt> = {
18
18
  title: 'plugins/plugin-automation/Prompt',
19
19
  component: Prompt,
20
- decorators: [withTheme, withLayout()],
20
+ decorators: [withTheme, withLayout({ tooltips: true })],
21
21
  parameters: {
22
22
  layout: 'centered',
23
23
  translations,
@@ -7,7 +7,7 @@ import React, { useRef, useState } from 'react';
7
7
  import { useVoiceInput } from '@dxos/plugin-transcription';
8
8
  import { Icon, IconButton, type ThemedClassName, Tooltip, useTranslation } from '@dxos/react-ui';
9
9
  import { Spinner } from '@dxos/react-ui-sfx';
10
- import { errorText, mx } from '@dxos/react-ui-theme';
10
+ import { errorMessageColors, errorText, mx } from '@dxos/react-ui-theme';
11
11
 
12
12
  import { Prompt, type PromptController, type PromptProps } from './Prompt';
13
13
  import { ASSISTANT_PLUGIN } from '../../meta';
@@ -54,9 +54,17 @@ export const PromptBar = ({
54
54
  >
55
55
  <div className='flex w-[--rail-action] h-[--rail-action] items-center justify-center'>
56
56
  {(error && (
57
- <Tooltip.Trigger content={error.message} delayDuration={0}>
58
- <Icon icon='ph--warning-circle--regular' classNames={errorText} size={5} />
59
- </Tooltip.Trigger>
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={mx('text-sm', errorMessageColors)}>{error.message}</div>
64
+ <Tooltip.Arrow />
65
+ </Tooltip.Content>
66
+ </Tooltip.Portal>
67
+ </Tooltip.Root>
60
68
  )) || <Spinner active={processing} />}
61
69
  </div>
62
70
  <Prompt
@@ -0,0 +1,49 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import '@dxos-theme';
6
+
7
+ import { type Meta, type StoryObj } from '@storybook/react';
8
+ import React from 'react';
9
+
10
+ import { useSpace } from '@dxos/react-client/echo';
11
+ import { withClientProvider } from '@dxos/react-client/testing';
12
+ import { withLayout, withTheme } from '@dxos/storybook-utils';
13
+
14
+ import { ServiceRegistry } from './ServiceRegistry';
15
+ import { ServiceType } from '../../types';
16
+
17
+ const meta: Meta<typeof ServiceRegistry> = {
18
+ title: 'plugins/plugin-automation/ServiceRegistry',
19
+ component: ServiceRegistry,
20
+ render: ({ space: _ignore, ...args }) => {
21
+ const space = useSpace();
22
+ if (!space) {
23
+ return <div />;
24
+ }
25
+
26
+ return (
27
+ <div className='h-full w-[300px] overflow-hidden'>
28
+ <ServiceRegistry space={space} {...args} />
29
+ </div>
30
+ );
31
+ },
32
+ decorators: [
33
+ withClientProvider({
34
+ createIdentity: true,
35
+ createSpace: true,
36
+ types: [ServiceType],
37
+ }),
38
+ withLayout({ fullscreen: true, tooltips: true, classNames: 'flex justify-center' }),
39
+ withTheme,
40
+ ],
41
+ };
42
+
43
+ export default meta;
44
+
45
+ type Story = StoryObj<typeof ServiceRegistry>;
46
+
47
+ export const Default: Story = {
48
+ args: {},
49
+ };