@dxos/plugin-assistant 0.8.4-main.2c6827d → 0.8.4-main.3c1ae3b

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 (159) hide show
  1. package/dist/lib/browser/{BlueprintArticle-IMCR3642.mjs → BlueprintArticle-BWSLH6LG.mjs} +2 -2
  2. package/dist/lib/browser/{ChatCompanion-4MS4NMZY.mjs → ChatCompanion-U7VMDYO6.mjs} +11 -10
  3. package/dist/lib/browser/ChatCompanion-U7VMDYO6.mjs.map +7 -0
  4. package/dist/lib/browser/{ChatContainer-GJZN3SIJ.mjs → ChatContainer-JXDZQ2EY.mjs} +11 -9
  5. package/dist/lib/browser/ChatContainer-JXDZQ2EY.mjs.map +7 -0
  6. package/dist/lib/browser/{ChatDialog-E2X6DTDX.mjs → ChatDialog-5NNGCRKJ.mjs} +5 -5
  7. package/dist/lib/browser/{PromptArticle-45QX25Y5.mjs → PromptArticle-Q7JYGFQV.mjs} +3 -3
  8. package/dist/lib/browser/{PromptArticle-45QX25Y5.mjs.map → PromptArticle-Q7JYGFQV.mjs.map} +3 -3
  9. package/dist/lib/browser/{app-graph-builder-VZEXMDTY.mjs → app-graph-builder-ADZRPJ3V.mjs} +7 -7
  10. package/dist/lib/browser/{app-graph-builder-VZEXMDTY.mjs.map → app-graph-builder-ADZRPJ3V.mjs.map} +3 -3
  11. package/dist/lib/browser/{blueprint-definition-5FT5JGPY.mjs → blueprint-definition-7HPQPCL7.mjs} +2 -2
  12. package/dist/lib/browser/{chunk-BNTPFZ7O.mjs → chunk-5JZRYQZL.mjs} +8 -8
  13. package/dist/lib/browser/chunk-5JZRYQZL.mjs.map +7 -0
  14. package/dist/lib/browser/{chunk-FJQ4ZRYJ.mjs → chunk-7ZJIXQ2Y.mjs} +2 -2
  15. package/dist/lib/browser/chunk-7ZJIXQ2Y.mjs.map +7 -0
  16. package/dist/lib/browser/{chunk-2BOE3OTW.mjs → chunk-F6YX2HHA.mjs} +1 -1
  17. package/dist/lib/browser/{chunk-2BOE3OTW.mjs.map → chunk-F6YX2HHA.mjs.map} +2 -2
  18. package/dist/lib/browser/{chunk-TCAQJ26D.mjs → chunk-SWEOO227.mjs} +44 -43
  19. package/dist/lib/browser/chunk-SWEOO227.mjs.map +7 -0
  20. package/dist/lib/browser/{chunk-IXIIS4QA.mjs → chunk-YDSFERCV.mjs} +9 -7
  21. package/dist/lib/browser/chunk-YDSFERCV.mjs.map +7 -0
  22. package/dist/lib/browser/index.mjs +45 -53
  23. package/dist/lib/browser/index.mjs.map +3 -3
  24. package/dist/lib/browser/{intent-resolver-AK5O4GUW.mjs → intent-resolver-Q7TX3MV7.mjs} +16 -16
  25. package/dist/lib/browser/intent-resolver-Q7TX3MV7.mjs.map +7 -0
  26. package/dist/lib/browser/meta.json +1 -1
  27. package/dist/lib/browser/{react-surface-XWAR5ZVL.mjs → react-surface-VXXS6ZVC.mjs} +11 -9
  28. package/dist/lib/browser/react-surface-VXXS6ZVC.mjs.map +7 -0
  29. package/dist/lib/browser/repair-3MZXLUHO.mjs +44 -0
  30. package/dist/lib/browser/repair-3MZXLUHO.mjs.map +7 -0
  31. package/dist/lib/browser/{settings-NYJGNQ5I.mjs → settings-HD5WA24I.mjs} +2 -2
  32. package/dist/lib/browser/types/index.mjs +1 -1
  33. package/dist/lib/node-esm/{BlueprintArticle-OL2HUY6Q.mjs → BlueprintArticle-R2XYBRCK.mjs} +2 -2
  34. package/dist/lib/node-esm/{ChatCompanion-TYRR7BXD.mjs → ChatCompanion-O4T7PMMC.mjs} +11 -10
  35. package/dist/lib/node-esm/ChatCompanion-O4T7PMMC.mjs.map +7 -0
  36. package/dist/lib/node-esm/{ChatContainer-MT4INE7Z.mjs → ChatContainer-OWAZI6ZF.mjs} +11 -9
  37. package/dist/lib/node-esm/ChatContainer-OWAZI6ZF.mjs.map +7 -0
  38. package/dist/lib/node-esm/{ChatDialog-G4EWBIJM.mjs → ChatDialog-IBXH5FRI.mjs} +5 -5
  39. package/dist/lib/node-esm/{PromptArticle-OUKFSJQV.mjs → PromptArticle-IV7O5UZ3.mjs} +3 -3
  40. package/dist/lib/node-esm/{PromptArticle-OUKFSJQV.mjs.map → PromptArticle-IV7O5UZ3.mjs.map} +3 -3
  41. package/dist/lib/node-esm/{app-graph-builder-VRN6ESRR.mjs → app-graph-builder-26KXQ5ZY.mjs} +7 -7
  42. package/dist/lib/node-esm/{app-graph-builder-VRN6ESRR.mjs.map → app-graph-builder-26KXQ5ZY.mjs.map} +3 -3
  43. package/dist/lib/node-esm/{blueprint-definition-XW6QQVLV.mjs → blueprint-definition-S3DNWJFV.mjs} +2 -2
  44. package/dist/lib/node-esm/{chunk-KJGD4EBJ.mjs → chunk-CKW4IYLY.mjs} +2 -2
  45. package/dist/lib/node-esm/chunk-CKW4IYLY.mjs.map +7 -0
  46. package/dist/lib/node-esm/{chunk-AB74FOA2.mjs → chunk-E4JSYCWZ.mjs} +8 -8
  47. package/dist/lib/node-esm/chunk-E4JSYCWZ.mjs.map +7 -0
  48. package/dist/lib/node-esm/{chunk-3Q22TTXW.mjs → chunk-GWKWQSEQ.mjs} +1 -1
  49. package/dist/lib/node-esm/{chunk-3Q22TTXW.mjs.map → chunk-GWKWQSEQ.mjs.map} +2 -2
  50. package/dist/lib/node-esm/{chunk-UXTUHH24.mjs → chunk-VGSP5WMV.mjs} +9 -7
  51. package/dist/lib/node-esm/chunk-VGSP5WMV.mjs.map +7 -0
  52. package/dist/lib/node-esm/{chunk-KM24SYPM.mjs → chunk-ZNSHGWE4.mjs} +44 -43
  53. package/dist/lib/node-esm/chunk-ZNSHGWE4.mjs.map +7 -0
  54. package/dist/lib/node-esm/index.mjs +45 -53
  55. package/dist/lib/node-esm/index.mjs.map +3 -3
  56. package/dist/lib/node-esm/{intent-resolver-L2F3N45L.mjs → intent-resolver-LTKMN3YB.mjs} +16 -16
  57. package/dist/lib/node-esm/intent-resolver-LTKMN3YB.mjs.map +7 -0
  58. package/dist/lib/node-esm/meta.json +1 -1
  59. package/dist/lib/node-esm/{react-surface-JXB7Q6QR.mjs → react-surface-AOBQALOV.mjs} +11 -9
  60. package/dist/lib/node-esm/react-surface-AOBQALOV.mjs.map +7 -0
  61. package/dist/lib/node-esm/repair-RER5H7Y6.mjs +45 -0
  62. package/dist/lib/node-esm/repair-RER5H7Y6.mjs.map +7 -0
  63. package/dist/lib/node-esm/{settings-RRHYI5KO.mjs → settings-YJQVKHH5.mjs} +2 -2
  64. package/dist/lib/node-esm/types/index.mjs +1 -1
  65. package/dist/types/src/AssistantPlugin.d.ts.map +1 -1
  66. package/dist/types/src/capabilities/index.d.ts +1 -0
  67. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  68. package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -1
  69. package/dist/types/src/capabilities/repair.d.ts +4 -0
  70. package/dist/types/src/capabilities/repair.d.ts.map +1 -0
  71. package/dist/types/src/components/ChatCompanion.d.ts +1 -1
  72. package/dist/types/src/components/ChatCompanion.d.ts.map +1 -1
  73. package/dist/types/src/components/ChatContainer.d.ts +6 -1
  74. package/dist/types/src/components/ChatContainer.d.ts.map +1 -1
  75. package/dist/types/src/components/ChatPrompt/ChatOptions.d.ts.map +1 -1
  76. package/dist/types/src/components/ChatThread/ChatThread.stories.d.ts +8 -2
  77. package/dist/types/src/components/ChatThread/ChatThread.stories.d.ts.map +1 -1
  78. package/dist/types/src/components/TemplateEditor/TemplateEditor.stories.d.ts +5 -0
  79. package/dist/types/src/components/TemplateEditor/TemplateEditor.stories.d.ts.map +1 -1
  80. package/dist/types/src/components/TemplateEditor/TemplateForm.stories.d.ts +5 -0
  81. package/dist/types/src/components/TemplateEditor/TemplateForm.stories.d.ts.map +1 -1
  82. package/dist/types/src/components/Toolbox/Toolbox.stories.d.ts +5 -0
  83. package/dist/types/src/components/Toolbox/Toolbox.stories.d.ts.map +1 -1
  84. package/dist/types/src/components/index.d.ts +7 -2
  85. package/dist/types/src/components/index.d.ts.map +1 -1
  86. package/dist/types/src/functions/object-list.d.ts.map +1 -1
  87. package/dist/types/src/functions/object-load.d.ts.map +1 -1
  88. package/dist/types/src/hooks/index.d.ts +1 -1
  89. package/dist/types/src/hooks/index.d.ts.map +1 -1
  90. package/dist/types/src/hooks/useFilteredTypes.d.ts +4 -0
  91. package/dist/types/src/hooks/useFilteredTypes.d.ts.map +1 -0
  92. package/dist/types/src/processor/processor.d.ts +3 -2
  93. package/dist/types/src/processor/processor.d.ts.map +1 -1
  94. package/dist/types/src/testing/test-generator.d.ts +3 -2
  95. package/dist/types/src/testing/test-generator.d.ts.map +1 -1
  96. package/dist/types/src/translations.d.ts +5 -0
  97. package/dist/types/src/translations.d.ts.map +1 -1
  98. package/dist/types/src/types/Assistant.d.ts +8 -11
  99. package/dist/types/src/types/Assistant.d.ts.map +1 -1
  100. package/dist/types/src/types/AssistantAction.d.ts +10 -13
  101. package/dist/types/src/types/AssistantAction.d.ts.map +1 -1
  102. package/dist/types/src/types/service.d.ts +126 -85
  103. package/dist/types/src/types/service.d.ts.map +1 -1
  104. package/dist/types/tsconfig.tsbuildinfo +1 -1
  105. package/package.json +72 -71
  106. package/src/AssistantPlugin.tsx +21 -42
  107. package/src/capabilities/app-graph-builder.ts +5 -7
  108. package/src/capabilities/index.ts +1 -0
  109. package/src/capabilities/intent-resolver.ts +6 -18
  110. package/src/capabilities/react-surface.tsx +2 -2
  111. package/src/capabilities/repair.ts +49 -0
  112. package/src/components/ChatCompanion.tsx +130 -119
  113. package/src/components/ChatContainer.tsx +5 -4
  114. package/src/components/ChatPrompt/ChatOptions.tsx +8 -2
  115. package/src/components/ChatThread/ChatThread.stories.tsx +4 -3
  116. package/src/components/ChatThread/Link.tsx +2 -2
  117. package/src/components/ChatThread/registry.tsx +1 -1
  118. package/src/components/PromptArticle.tsx +1 -1
  119. package/src/components/TemplateEditor/TemplateEditor.tsx +1 -1
  120. package/src/functions/object-list.ts +4 -3
  121. package/src/functions/object-load.ts +4 -3
  122. package/src/hooks/index.ts +1 -1
  123. package/src/hooks/useBlueprintRegistry.ts +1 -1
  124. package/src/hooks/useChatToolbarActions.ts +1 -1
  125. package/src/hooks/useContextObjects.ts +1 -1
  126. package/src/hooks/{useItemTypes.ts → useFilteredTypes.ts} +7 -6
  127. package/src/hooks/useReferencesProvider.ts +3 -3
  128. package/src/processor/processor.test.ts +2 -1
  129. package/src/processor/processor.ts +3 -3
  130. package/src/testing/test-generator.ts +4 -3
  131. package/src/translations.ts +4 -0
  132. package/src/types/Assistant.ts +4 -4
  133. package/src/types/AssistantAction.ts +1 -1
  134. package/dist/lib/browser/ChatCompanion-4MS4NMZY.mjs.map +0 -7
  135. package/dist/lib/browser/ChatContainer-GJZN3SIJ.mjs.map +0 -7
  136. package/dist/lib/browser/chunk-BNTPFZ7O.mjs.map +0 -7
  137. package/dist/lib/browser/chunk-FJQ4ZRYJ.mjs.map +0 -7
  138. package/dist/lib/browser/chunk-IXIIS4QA.mjs.map +0 -7
  139. package/dist/lib/browser/chunk-TCAQJ26D.mjs.map +0 -7
  140. package/dist/lib/browser/intent-resolver-AK5O4GUW.mjs.map +0 -7
  141. package/dist/lib/browser/react-surface-XWAR5ZVL.mjs.map +0 -7
  142. package/dist/lib/node-esm/ChatCompanion-TYRR7BXD.mjs.map +0 -7
  143. package/dist/lib/node-esm/ChatContainer-MT4INE7Z.mjs.map +0 -7
  144. package/dist/lib/node-esm/chunk-AB74FOA2.mjs.map +0 -7
  145. package/dist/lib/node-esm/chunk-KJGD4EBJ.mjs.map +0 -7
  146. package/dist/lib/node-esm/chunk-KM24SYPM.mjs.map +0 -7
  147. package/dist/lib/node-esm/chunk-UXTUHH24.mjs.map +0 -7
  148. package/dist/lib/node-esm/intent-resolver-L2F3N45L.mjs.map +0 -7
  149. package/dist/lib/node-esm/react-surface-JXB7Q6QR.mjs.map +0 -7
  150. package/dist/types/src/hooks/useItemTypes.d.ts +0 -4
  151. package/dist/types/src/hooks/useItemTypes.d.ts.map +0 -1
  152. /package/dist/lib/browser/{BlueprintArticle-IMCR3642.mjs.map → BlueprintArticle-BWSLH6LG.mjs.map} +0 -0
  153. /package/dist/lib/browser/{ChatDialog-E2X6DTDX.mjs.map → ChatDialog-5NNGCRKJ.mjs.map} +0 -0
  154. /package/dist/lib/browser/{blueprint-definition-5FT5JGPY.mjs.map → blueprint-definition-7HPQPCL7.mjs.map} +0 -0
  155. /package/dist/lib/browser/{settings-NYJGNQ5I.mjs.map → settings-HD5WA24I.mjs.map} +0 -0
  156. /package/dist/lib/node-esm/{BlueprintArticle-OL2HUY6Q.mjs.map → BlueprintArticle-R2XYBRCK.mjs.map} +0 -0
  157. /package/dist/lib/node-esm/{ChatDialog-G4EWBIJM.mjs.map → ChatDialog-IBXH5FRI.mjs.map} +0 -0
  158. /package/dist/lib/node-esm/{blueprint-definition-XW6QQVLV.mjs.map → blueprint-definition-S3DNWJFV.mjs.map} +0 -0
  159. /package/dist/lib/node-esm/{settings-RRHYI5KO.mjs.map → settings-YJQVKHH5.mjs.map} +0 -0
@@ -5,7 +5,7 @@
5
5
  import * as Array from 'effect/Array';
6
6
  import * as Function from 'effect/Function';
7
7
  import * as Option from 'effect/Option';
8
- import React, { useCallback, useEffect, useMemo, useState } from 'react';
8
+ import React, { forwardRef, useCallback, useEffect, useMemo, useState } from 'react';
9
9
 
10
10
  import { Capabilities, createIntent } from '@dxos/app-framework';
11
11
  import { useCapabilities, useIntentDispatcher } from '@dxos/app-framework/react';
@@ -25,131 +25,142 @@ export type ChatCompanionProps = {
25
25
  data: { subject: Assistant.Chat | 'assistant-chat'; companionTo: Obj.Any };
26
26
  };
27
27
 
28
- export const ChatCompanion = ({ role, data }: ChatCompanionProps) => {
29
- const { dispatchPromise: dispatch } = useIntentDispatcher();
30
- const blueprintRegistry = useBlueprintRegistry();
31
- const companionTo = data.companionTo;
32
-
33
- const space = getSpace(companionTo);
34
- const [chat, setChat] = useState(data.subject === 'assistant-chat' ? undefined : data.subject);
35
- useEffect(() => {
36
- setChat(data.subject === 'assistant-chat' ? undefined : data.subject);
37
- }, [data.subject]);
38
-
39
- const chatQueue = space && chat ? space.queues.get(chat.queue.dxn) : undefined;
40
- const binder = useContextBinder(chatQueue);
41
-
42
- // Initialize companion chat if it doesn't exist, but don't add it to the space immediately.
43
- useAsyncEffect(async () => {
44
- if (!space || chat) {
45
- return;
46
- }
47
-
48
- const { data } = await dispatch(createIntent(AssistantAction.CreateChat, { space }));
49
- setChat(data?.object);
50
- }, [chat, space]);
51
-
52
- // Add chat to space when user submits the first message.
53
- const handleEvent = useCallback(
54
- async (event: ChatEvent) => {
55
- const chatInSpace = !!getSpace(chat);
56
- if (chatInSpace || !chat || !space) {
28
+ export const ChatCompanion = forwardRef<HTMLDivElement, ChatCompanionProps>(
29
+ ({ role, data }: ChatCompanionProps, forwardedRef) => {
30
+ const { dispatchPromise: dispatch } = useIntentDispatcher();
31
+ const blueprintRegistry = useBlueprintRegistry();
32
+ const companionTo = data.companionTo;
33
+
34
+ const space = getSpace(companionTo);
35
+ const [chat, setChat] = useState(data.subject === 'assistant-chat' ? undefined : data.subject);
36
+ useEffect(() => {
37
+ setChat(data.subject === 'assistant-chat' ? undefined : data.subject);
38
+ }, [data.subject]);
39
+
40
+ const chatQueue = space && chat ? space.queues.get(chat.queue.dxn) : undefined;
41
+ const binder = useContextBinder(chatQueue);
42
+
43
+ // Initialize companion chat if it doesn't exist, but don't add it to the space immediately.
44
+ useAsyncEffect(async () => {
45
+ if (!space || chat) {
57
46
  return;
58
47
  }
59
48
 
60
- if (event.type === 'submit') {
61
- await dispatch(
62
- createIntent(SpaceAction.AddObject, {
63
- object: chat,
64
- target: space,
65
- hidden: true,
66
- }),
67
- );
68
- await dispatch(
69
- createIntent(SpaceAction.AddRelation, {
70
- space,
71
- schema: Assistant.CompanionTo,
72
- source: chat,
73
- target: companionTo,
74
- }),
75
- );
76
- await dispatch(
77
- createIntent(AssistantAction.SetCurrentChat, {
78
- companionTo,
79
- chat,
80
- }),
81
- );
82
- }
83
- },
84
- [chat, space, companionTo, dispatch],
85
- );
86
-
87
- const metadata = useCapabilities(Capabilities.Metadata);
88
- const blueprintKeys = useMemo(
89
- () =>
90
- Function.pipe(
91
- metadata,
92
- Array.findFirst(
93
- (
94
- capability,
95
- ): capability is {
96
- id: string;
97
- metadata: { blueprints?: string[] };
98
- } => capability.id === Obj.getTypename(companionTo),
49
+ const { data } = await dispatch(createIntent(AssistantAction.CreateChat, { space }));
50
+ setChat(data?.object);
51
+ }, [chat, space]);
52
+
53
+ // Add chat to space when user submits the first message.
54
+ const handleEvent = useCallback(
55
+ async (event: ChatEvent) => {
56
+ const chatInSpace = !!getSpace(chat);
57
+ if (chatInSpace || !chat || !space) {
58
+ return;
59
+ }
60
+
61
+ if (event.type === 'submit') {
62
+ await dispatch(
63
+ createIntent(SpaceAction.AddObject, {
64
+ object: chat,
65
+ target: space,
66
+ hidden: true,
67
+ }),
68
+ );
69
+ await dispatch(
70
+ createIntent(SpaceAction.AddRelation, {
71
+ space,
72
+ schema: Assistant.CompanionTo,
73
+ source: chat,
74
+ target: companionTo,
75
+ }),
76
+ );
77
+ await dispatch(
78
+ createIntent(AssistantAction.SetCurrentChat, {
79
+ companionTo,
80
+ chat,
81
+ }),
82
+ );
83
+ }
84
+ },
85
+ [chat, space, companionTo, dispatch],
86
+ );
87
+
88
+ const metadata = useCapabilities(Capabilities.Metadata);
89
+ const blueprintKeys = useMemo(
90
+ () =>
91
+ Function.pipe(
92
+ metadata,
93
+ Array.findFirst(
94
+ (
95
+ capability,
96
+ ): capability is {
97
+ id: string;
98
+ metadata: { blueprints?: string[] };
99
+ } => capability.id === Obj.getTypename(companionTo),
100
+ ),
101
+ Option.flatMap((c) => Option.fromNullable(c.metadata.blueprints)),
102
+ Option.getOrElse(() => [] as string[]),
99
103
  ),
100
- Option.flatMap((c) => Option.fromNullable(c.metadata.blueprints)),
101
- Option.getOrElse(() => [] as string[]),
102
- ),
103
- [metadata, companionTo],
104
- );
105
- const existingBlueprints = useQuery(space, Filter.type(Blueprint.Blueprint));
106
- const pluginBlueprints = useMemo(
107
- () => existingBlueprints.filter((blueprint) => blueprintKeys.includes(blueprint.key)),
108
- [existingBlueprints, blueprintKeys],
109
- );
110
-
111
- // Initialize related blueprints that are not already in the space.
112
- useAsyncEffect(async () => {
113
- if (!space) {
114
- return;
115
- }
116
-
117
- // NOTE: This must be run instead of using the useQuery result to avoid duplicates.
118
- const { objects: existingBlueprints } = await space.db.query(Filter.type(Blueprint.Blueprint)).run();
119
- for (const key of blueprintKeys) {
120
- const existingBlueprint = existingBlueprints.find((blueprint) => blueprint.key === key);
121
- if (existingBlueprint) {
122
- continue;
104
+ [metadata, companionTo],
105
+ );
106
+ const existingBlueprints = useQuery(space, Filter.type(Blueprint.Blueprint));
107
+ const pluginBlueprints = useMemo(
108
+ () => existingBlueprints.filter((blueprint) => blueprintKeys.includes(blueprint.key)),
109
+ [existingBlueprints, blueprintKeys],
110
+ );
111
+
112
+ // Initialize related blueprints that are not already in the space.
113
+ useAsyncEffect(async () => {
114
+ if (!space) {
115
+ return;
116
+ }
117
+
118
+ // NOTE: This must be run instead of using the useQuery result to avoid duplicates.
119
+ const existingBlueprints = await space.db.query(Filter.type(Blueprint.Blueprint)).run();
120
+ for (const key of blueprintKeys) {
121
+ const existingBlueprint = existingBlueprints.find((blueprint) => blueprint.key === key);
122
+ if (existingBlueprint) {
123
+ continue;
124
+ }
125
+
126
+ const blueprint = blueprintRegistry.getByKey(key);
127
+ if (!blueprint) {
128
+ continue;
129
+ }
130
+
131
+ space.db.add(Obj.clone(blueprint));
123
132
  }
133
+ }, [space, blueprintRegistry, blueprintKeys]);
124
134
 
125
- const blueprint = blueprintRegistry.getByKey(key);
126
- if (!blueprint) {
127
- continue;
135
+ useAsyncEffect(async () => {
136
+ if (!binder?.isOpen) {
137
+ return;
128
138
  }
129
139
 
130
- space.db.add(Obj.clone(blueprint));
131
- }
132
- }, [space, blueprintRegistry, blueprintKeys]);
133
-
134
- useAsyncEffect(async () => {
135
- if (!binder?.isOpen) {
136
- return;
137
- }
138
-
139
- if (pluginBlueprints.length > 0) {
140
- await binder.bind({
141
- blueprints: pluginBlueprints.map((blueprint) => Ref.make(blueprint)),
142
- });
143
- }
144
-
145
- if (Obj.instanceOf(Blueprint.Blueprint, companionTo)) {
146
- await binder.bind({ blueprints: [Ref.make(companionTo)] });
147
- } else {
148
- await binder.bind({ objects: [Ref.make(companionTo)] });
149
- }
150
- }, [binder, companionTo, blueprintKeys]);
151
-
152
- return <ChatContainer role={role} space={space} chat={chat} companionTo={companionTo} onEvent={handleEvent} />;
153
- };
140
+ if (pluginBlueprints.length > 0) {
141
+ await binder.bind({
142
+ blueprints: pluginBlueprints.map((blueprint) => Ref.make(blueprint)),
143
+ });
144
+ }
145
+
146
+ if (Obj.instanceOf(Blueprint.Blueprint, companionTo)) {
147
+ await binder.bind({ blueprints: [Ref.make(companionTo)] });
148
+ } else {
149
+ await binder.bind({ objects: [Ref.make(companionTo)] });
150
+ }
151
+ }, [binder, companionTo, blueprintKeys]);
152
+
153
+ return (
154
+ <ChatContainer
155
+ role={role}
156
+ space={space}
157
+ chat={chat}
158
+ companionTo={companionTo}
159
+ onEvent={handleEvent}
160
+ ref={forwardedRef}
161
+ />
162
+ );
163
+ },
164
+ );
154
165
 
155
166
  export default ChatCompanion;
@@ -2,7 +2,7 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import React from 'react';
5
+ import React, { forwardRef } from 'react';
6
6
 
7
7
  import { Capabilities } from '@dxos/app-framework';
8
8
  import { useCapability } from '@dxos/app-framework/react';
@@ -23,7 +23,8 @@ export type ChatContainerProps = {
23
23
  companionTo?: Obj.Any;
24
24
  } & Pick<ChatRootProps, 'onEvent'>;
25
25
 
26
- export const ChatContainer = ({ space: spaceProp, chat, companionTo, onEvent }: ChatContainerProps) => {
26
+ export const ChatContainer = forwardRef<HTMLDivElement, ChatContainerProps>((props, forwardedRef) => {
27
+ const { space: spaceProp, chat, companionTo, onEvent } = props;
27
28
  const space = spaceProp ?? getSpace(chat);
28
29
  const settings = useCapability(Capabilities.SettingsStore).getStore<Assistant.Settings>(meta.id)?.value;
29
30
  const services = useChatServices({ space, chat });
@@ -44,7 +45,7 @@ export const ChatContainer = ({ space: spaceProp, chat, companionTo, onEvent }:
44
45
  }
45
46
 
46
47
  return (
47
- <StackItem.Content toolbar>
48
+ <StackItem.Content toolbar ref={forwardedRef}>
48
49
  <Chat.Root space={space} chat={chat} processor={processor} onEvent={onEvent}>
49
50
  <Chat.Toolbar companionTo={companionTo} />
50
51
  <Chat.Viewport classNames='container-max-width'>
@@ -56,6 +57,6 @@ export const ChatContainer = ({ space: spaceProp, chat, companionTo, onEvent }:
56
57
  </Chat.Root>
57
58
  </StackItem.Content>
58
59
  );
59
- };
60
+ });
60
61
 
61
62
  export default ChatContainer;
@@ -12,7 +12,13 @@ import { Icon, IconButton, Popover, Select, useTranslation } from '@dxos/react-u
12
12
  import { Listbox, SearchList } from '@dxos/react-ui-searchlist';
13
13
  import { Tabs } from '@dxos/react-ui-tabs';
14
14
 
15
- import { useActiveBlueprints, useBlueprintHandlers, useBlueprints, useContextObjects, useItemTypes } from '../../hooks';
15
+ import {
16
+ useActiveBlueprints,
17
+ useBlueprintHandlers,
18
+ useBlueprints,
19
+ useContextObjects,
20
+ useFilteredTypes,
21
+ } from '../../hooks';
16
22
  import { meta } from '../../meta';
17
23
 
18
24
  const panelClassNames = 'is-[calc(100dvw-.5rem)] sm:is-max md:is-72 max-is-[--text-content]';
@@ -153,7 +159,7 @@ const ObjectsPanel = ({ space, context }: Pick<ChatOptionsProps, 'space' | 'cont
153
159
  const { t } = useTranslation(meta.id);
154
160
 
155
161
  // Item types sorted by label.
156
- const types = useItemTypes(space);
162
+ const types = useFilteredTypes(space);
157
163
  const typenames = useMemo(() => {
158
164
  const typenames = types.map((type) => {
159
165
  const typename = Type.getTypename(type);
@@ -8,7 +8,8 @@ import * as Fiber from 'effect/Fiber';
8
8
  import * as Layer from 'effect/Layer';
9
9
  import React, { type CSSProperties, useEffect, useMemo, useState } from 'react';
10
10
 
11
- import { ContextQueueService, DatabaseService } from '@dxos/functions';
11
+ import { Database } from '@dxos/echo';
12
+ import { ContextQueueService } from '@dxos/functions';
12
13
  import { faker } from '@dxos/random';
13
14
  import { useQueue, useSpace } from '@dxos/react-client/echo';
14
15
  import { withClientProvider } from '@dxos/react-client/testing';
@@ -29,7 +30,7 @@ import TEXT from './testing/thread.md?raw';
29
30
 
30
31
  faker.seed(1);
31
32
 
32
- type MessageGenerator = Effect.Effect<void, never, DatabaseService | ContextQueueService>;
33
+ type MessageGenerator = Effect.Effect<void, never, Database.Service | ContextQueueService>;
33
34
 
34
35
  type StoryProps = { generator?: MessageGenerator[]; delay?: number; wait?: boolean } & ChatThreadProps;
35
36
 
@@ -54,7 +55,7 @@ const DefaultStory = ({ generator = [], delay = 0, wait, ...props }: StoryProps)
54
55
  }
55
56
  }
56
57
  setDone(true);
57
- }).pipe(Effect.provide(Layer.mergeAll(DatabaseService.layer(space.db), ContextQueueService.layer(queue)))),
58
+ }).pipe(Effect.provide(Layer.mergeAll(Database.Service.layer(space.db), ContextQueueService.layer(queue)))),
58
59
  );
59
60
 
60
61
  return () => {
@@ -15,9 +15,9 @@ export type ObjectLinkProps = {
15
15
  };
16
16
 
17
17
  export const ObjectLink = ({ space, dxn }: ObjectLinkProps) => {
18
- const ref = useMemo(() => space.db.ref(dxn), [space, dxn.toString()]);
18
+ const ref = useMemo(() => space.db.makeRef(dxn), [space, dxn.toString()]);
19
19
 
20
- const title = Obj.getLabel(ref.target) ?? ref.target?.id ?? ref.dxn.toString();
20
+ const title = (ref.target && Obj.getLabel(ref.target)) ?? ref.target?.id ?? ref.dxn.toString();
21
21
  return (
22
22
  <DxAnchor rootclassname='dx-tag--anchor' refid={dxn.toString()}>
23
23
  {title}
@@ -5,13 +5,13 @@
5
5
  import React from 'react';
6
6
 
7
7
  import { log } from '@dxos/log';
8
+ import { ToggleContainer } from '@dxos/react-ui-components';
8
9
  import {
9
10
  PromptWidget,
10
11
  ReferenceWidget,
11
12
  SelectWidget,
12
13
  SuggestionWidget,
13
14
  SummaryWidget,
14
- ToggleContainer,
15
15
  } from '@dxos/react-ui-components';
16
16
  import { type XmlWidgetProps, type XmlWidgetRegistry, getXmlTextChild } from '@dxos/react-ui-editor';
17
17
  import { Json } from '@dxos/react-ui-syntax-highlighter';
@@ -28,7 +28,7 @@ export const PromptArticle = ({ subject }: PromptArticleProps) => {
28
28
  const inputData = useMemo(
29
29
  () =>
30
30
  subject && {
31
- prompt: space?.db.ref(Obj.getDXN(subject)),
31
+ prompt: space?.db.makeRef(Obj.getDXN(subject)),
32
32
  input: {},
33
33
  },
34
34
  [subject, space],
@@ -6,7 +6,7 @@ import { defaultHighlightStyle, syntaxHighlighting } from '@codemirror/language'
6
6
  import React from 'react';
7
7
 
8
8
  import { type Template } from '@dxos/blueprints';
9
- import { createDocAccessor } from '@dxos/react-client/echo';
9
+ import { createDocAccessor } from '@dxos/echo-db';
10
10
  import { type ThemedClassName, useThemeContext, useTranslation } from '@dxos/react-ui';
11
11
  import {
12
12
  createBasicExtensions,
@@ -6,7 +6,8 @@ import * as Effect from 'effect/Effect';
6
6
  import * as Schema from 'effect/Schema';
7
7
 
8
8
  import { Filter, Obj, Query } from '@dxos/echo';
9
- import { DatabaseService, defineFunction } from '@dxos/functions';
9
+ import { Database } from '@dxos/echo';
10
+ import { defineFunction } from '@dxos/functions';
10
11
  import { trim } from '@dxos/util';
11
12
 
12
13
  // TODO(burdon): Move to toolkit (i.e., tool not function).
@@ -34,10 +35,10 @@ export default defineFunction({
34
35
  }),
35
36
  handler: Effect.fn(function* ({ data: { typename } }) {
36
37
  // TODO(wittjosiah): Typename query is not working for dynamic schemas.
37
- const [schema] = yield* DatabaseService.runSchemaQuery({ typename });
38
+ const [schema] = yield* Database.Service.runSchemaQuery({ typename });
38
39
  const filter = schema ? Filter.type(schema) : Filter.typename(typename);
39
40
 
40
- const { objects } = yield* DatabaseService.runQuery(Query.select(filter));
41
+ const objects = yield* Database.Service.runQuery(Query.select(filter));
41
42
  const results = objects.map((object) => ({
42
43
  dxn: Obj.getDXN(object).toString(),
43
44
  label: Obj.getLabel(object),
@@ -9,7 +9,8 @@ import * as Schema from 'effect/Schema';
9
9
 
10
10
  import { ArtifactId } from '@dxos/assistant';
11
11
  import { Obj } from '@dxos/echo';
12
- import { DatabaseService, defineFunction } from '@dxos/functions';
12
+ import { Database } from '@dxos/echo';
13
+ import { defineFunction } from '@dxos/functions';
13
14
 
14
15
  // TODO(burdon): Move to toolkit (i.e., tool not function).
15
16
  export default defineFunction({
@@ -25,11 +26,11 @@ export default defineFunction({
25
26
  }),
26
27
  }),
27
28
  outputSchema: Schema.Struct({
28
- // TODO(wittjosiah): Type.Obj.Any | Type.Relation.Any
29
+ // TODO(wittjosiah): Type.Entity.Any
29
30
  object: Schema.Any,
30
31
  }),
31
32
  handler: Effect.fn(function* ({ data: { id, typename } }) {
32
- const object = yield* DatabaseService.resolve(ArtifactId.toDXN(id));
33
+ const object = yield* Database.Service.resolve(ArtifactId.toDXN(id));
33
34
  return yield* Function.pipe(
34
35
  Option.fromNullable(object),
35
36
  Option.flatMap((object) => (Obj.getTypename(object) === typename ? Option.some(object) : Option.none())),
@@ -8,8 +8,8 @@ export * from './useChatServices';
8
8
  export * from './useChatToolbarActions';
9
9
  export * from './useContextBinder';
10
10
  export * from './useContextObjects';
11
+ export * from './useFilteredTypes';
11
12
  export * from './useFlush';
12
- export * from './useItemTypes';
13
13
  export * from './useOnline';
14
14
  export * from './usePresets';
15
15
  export * from './useReferencesProvider';
@@ -71,7 +71,7 @@ export const useBlueprintHandlers = ({
71
71
  }
72
72
 
73
73
  // Find existing cloned blueprint.
74
- const { objects } = await space.db.query(Filter.type(Blueprint.Blueprint)).run();
74
+ const objects = await space.db.query(Filter.type(Blueprint.Blueprint)).run();
75
75
  let storedBlueprint = objects.find((blueprint) => blueprint.key === key);
76
76
  if (checked) {
77
77
  if (!storedBlueprint) {
@@ -26,7 +26,7 @@ export const useChatToolbarActions = ({ chat, companionTo }: ChatToolbarActionsP
26
26
  const { dispatch } = useIntentDispatcher();
27
27
  const { space } = useChatContext('useChatToolbarActions');
28
28
  const query = companionTo
29
- ? Query.select(Filter.ids(companionTo.id)).targetOf(Assistant.CompanionTo).source()
29
+ ? Query.select(Filter.id(companionTo.id)).targetOf(Assistant.CompanionTo).source()
30
30
  : Query.select(Filter.nothing());
31
31
 
32
32
  // TODO(wittjosiah): Query in react vs query in atom?
@@ -35,7 +35,7 @@ export const useContextObjects = ({
35
35
 
36
36
  // Load the object by DXN/id from the current space.
37
37
  const id = dxn.asEchoDXN();
38
- const object = id && (await space.db.getObjectById(id.echoId));
38
+ const object = id && space.db.getObjectById(id.echoId);
39
39
  if (!object) {
40
40
  log.warn('Object not found', { dxn, id });
41
41
  return;
@@ -6,12 +6,13 @@ import * as Option from 'effect/Option';
6
6
  import { useEffect, useState } from 'react';
7
7
 
8
8
  import { type Type } from '@dxos/echo';
9
+ import { EntityKind, SystemTypeAnnotation, getTypeAnnotation } from '@dxos/echo/internal';
9
10
  import { type Space } from '@dxos/react-client/echo';
10
- import { ItemAnnotation } from '@dxos/schema';
11
11
 
12
12
  // TODO(burdon): Pass in filter.
13
- export const useItemTypes = (space?: Space): Type.Obj.Any[] => {
14
- const [types, setTypes] = useState<Type.Obj.Any[]>([]);
13
+ // TODO(wittjosiah): Factor out.
14
+ export const useFilteredTypes = (space?: Space): Type.Entity.Any[] => {
15
+ const [types, setTypes] = useState<Type.Entity.Any[]>([]);
15
16
  useEffect(() => {
16
17
  if (!space) {
17
18
  return;
@@ -21,9 +22,9 @@ export const useItemTypes = (space?: Space): Type.Obj.Any[] => {
21
22
  (query) => {
22
23
  const types = Array.from(
23
24
  new Set(
24
- [...space.db.graph.schemaRegistry.schemas, ...query.results].filter((type) =>
25
- Option.isSome(ItemAnnotation.get(type)),
26
- ),
25
+ [...space.db.graph.schemaRegistry.schemas, ...query.results]
26
+ .filter((schema) => getTypeAnnotation(schema)?.kind !== EntityKind.Relation)
27
+ .filter((schema) => SystemTypeAnnotation.get(schema).pipe(Option.getOrElse(() => false))),
27
28
  ),
28
29
  );
29
30
 
@@ -25,11 +25,11 @@ export const useReferencesProvider = (space?: Space): ReferencesProvider | undef
25
25
  getReferences: async ({ query }) => {
26
26
  // TODO(burdon): Previously we filtered by types declared by the artifact definitions.
27
27
  // const schemas = blueprints.map((blueprint) => blueprint.schema).flat();
28
- // const { objects } = await space.db
28
+ // const objects = await space.db
29
29
  // .query(Filter.or(...schemas.map((schema) => Filter.type(schema as Type.Schema))))
30
30
  // .run();
31
31
 
32
- const { objects } = await space.db.query(Filter.everything()).run();
32
+ const objects = await space.db.query(Filter.everything()).run();
33
33
 
34
34
  return (
35
35
  objects
@@ -48,7 +48,7 @@ export const useReferencesProvider = (space?: Space): ReferencesProvider | undef
48
48
  );
49
49
  },
50
50
  resolveReference: async ({ uri }) => {
51
- const object = await space.db.query(Filter.ids(uri)).first();
51
+ const object = await space.db.query(Filter.id(uri)).first();
52
52
  return { uri, label: Obj.getLabel(object) ?? '' };
53
53
  },
54
54
  } satisfies ReferencesProvider;
@@ -12,7 +12,8 @@ import * as Schema from 'effect/Schema';
12
12
  import { AiService } from '@dxos/ai';
13
13
  import { AiServiceTestingPreset } from '@dxos/ai/testing';
14
14
  import { AiConversation, makeToolExecutionServiceFromFunctions, makeToolResolverFromFunctions } from '@dxos/assistant';
15
- import { TestHelpers, acquireReleaseResource } from '@dxos/effect';
15
+ import { acquireReleaseResource } from '@dxos/effect';
16
+ import { TestHelpers } from '@dxos/effect/testing';
16
17
  import { CredentialsService, QueueService, TracingService } from '@dxos/functions';
17
18
  import { FunctionInvocationServiceLayerTestMocked, TestDatabaseLayer } from '@dxos/functions-runtime/testing';
18
19
  import { type Message } from '@dxos/types';
@@ -27,10 +27,10 @@ import {
27
27
  } from '@dxos/assistant';
28
28
  import { type Blueprint } from '@dxos/blueprints';
29
29
  import { Obj } from '@dxos/echo';
30
+ import { type Database } from '@dxos/echo';
30
31
  import { throwCause } from '@dxos/effect';
31
32
  import {
32
33
  type CredentialsService,
33
- type DatabaseService,
34
34
  type FunctionInvocationService,
35
35
  type QueueService,
36
36
  type TracingService,
@@ -44,7 +44,7 @@ import { updateName } from './update-name';
44
44
 
45
45
  export type AiChatServices =
46
46
  | CredentialsService
47
- | DatabaseService
47
+ | Database.Service
48
48
  | QueueService
49
49
  | FunctionInvocationService
50
50
  | AiService.AiService
@@ -233,7 +233,7 @@ export class AiChatProcessor {
233
233
  // artifacts.map(async (artifact) => {
234
234
  // const {
235
235
  // objects: [object],
236
- // } = await space.db.query(Filter.ids(artifact.id)).run();
236
+ // } = await space.db.query(Filter.id(artifact.id)).run();
237
237
  // if (!object) {
238
238
  // return;
239
239
  // }
@@ -5,7 +5,8 @@
5
5
  import * as Effect from 'effect/Effect';
6
6
 
7
7
  import { Obj } from '@dxos/echo';
8
- import { ContextQueueService, DatabaseService } from '@dxos/functions';
8
+ import { Database } from '@dxos/echo';
9
+ import { ContextQueueService } from '@dxos/functions';
9
10
  import { faker } from '@dxos/random';
10
11
  import { renderObjectLink } from '@dxos/react-ui-components';
11
12
  import { type Actor, type ContentBlock, Message, Organization } from '@dxos/types';
@@ -19,7 +20,7 @@ export const createMessage = (role: Actor.Role, blocks: ContentBlock.Any[]): Mes
19
20
  });
20
21
  };
21
22
 
22
- export type MessageGenerator = Effect.Effect<void, never, DatabaseService | ContextQueueService>;
23
+ export type MessageGenerator = Effect.Effect<void, never, Database.Service | ContextQueueService>;
23
24
 
24
25
  export const createMessageGenerator = (): MessageGenerator[] => [
25
26
  Effect.gen(function* () {
@@ -145,7 +146,7 @@ export const createMessageGenerator = (): MessageGenerator[] => [
145
146
 
146
147
  Effect.gen(function* () {
147
148
  const { queue } = yield* ContextQueueService;
148
- const { db } = yield* DatabaseService;
149
+ const { db } = yield* Database.Service;
149
150
  const obj1 = db.add(Obj.make(Organization.Organization, { name: 'DXOS' }));
150
151
  // const obj2 = db.add(Obj.make(Person.Person, { fullName: 'Alice' }));
151
152
  // const obj3 = db.add(Obj.make(Person.Person, { fullName: 'Bob' }));