@dxos/plugin-assistant 0.8.1-main.303c73a → 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.
- package/dist/lib/browser/{AssistantDialog-T5OJUIIV.mjs → AssistantDialog-L5RHNMU4.mjs} +6 -5
- package/dist/lib/browser/{AssistantDialog-T5OJUIIV.mjs.map → AssistantDialog-L5RHNMU4.mjs.map} +3 -3
- package/dist/lib/browser/{ChatContainer-FEZ323HB.mjs → ChatContainer-EEEVE62F.mjs} +5 -5
- package/dist/lib/browser/TemplateContainer-7IQ6V5AD.mjs +78 -0
- package/dist/lib/browser/TemplateContainer-7IQ6V5AD.mjs.map +7 -0
- package/dist/lib/browser/ai-client-BAPVMSNX.mjs +35 -0
- package/dist/lib/browser/ai-client-BAPVMSNX.mjs.map +7 -0
- package/dist/lib/browser/{app-graph-builder-AXAIFOGV.mjs → app-graph-builder-DTCUWBKB.mjs} +57 -13
- package/dist/lib/browser/app-graph-builder-DTCUWBKB.mjs.map +7 -0
- package/dist/lib/browser/{chunk-TCAE72QU.mjs → chunk-5RMJYOT7.mjs} +34 -12
- package/dist/lib/browser/chunk-5RMJYOT7.mjs.map +7 -0
- package/dist/lib/browser/{chunk-EUMPBC4T.mjs → chunk-6FTPLBSC.mjs} +2 -2
- package/dist/lib/browser/{chunk-NV7SVHMV.mjs → chunk-AF7VQAKS.mjs} +1 -1
- package/dist/lib/browser/{chunk-NV7SVHMV.mjs.map → chunk-AF7VQAKS.mjs.map} +2 -2
- package/dist/lib/browser/{chunk-NTLTGYYS.mjs → chunk-SVUCJXGN.mjs} +2 -2
- package/dist/lib/browser/chunk-SVUCJXGN.mjs.map +7 -0
- package/dist/lib/browser/{chunk-FRIKXDDQ.mjs → chunk-X6ALDUA5.mjs} +26 -4
- package/dist/lib/browser/chunk-X6ALDUA5.mjs.map +7 -0
- package/dist/lib/browser/{chunk-SUUECBDM.mjs → chunk-XFUCWOMV.mjs} +261 -60
- package/dist/lib/browser/chunk-XFUCWOMV.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +21 -11
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/{intent-resolver-QRVRZL6K.mjs → intent-resolver-U57FXP3I.mjs} +6 -3
- package/dist/lib/browser/{intent-resolver-QRVRZL6K.mjs.map → intent-resolver-U57FXP3I.mjs.map} +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/{react-surface-B463WHMD.mjs → react-surface-KFLHNDNR.mjs} +10 -9
- package/dist/lib/browser/react-surface-KFLHNDNR.mjs.map +7 -0
- package/dist/lib/browser/{settings-JTT62IHD.mjs → settings-VAW6UWFL.mjs} +3 -3
- package/dist/lib/browser/types/index.mjs +6 -2
- package/dist/lib/node/{AssistantDialog-EZ5RBGPX.cjs → AssistantDialog-VIB7GPQN.cjs} +12 -11
- package/dist/lib/node/{AssistantDialog-EZ5RBGPX.cjs.map → AssistantDialog-VIB7GPQN.cjs.map} +3 -3
- package/dist/lib/node/{ChatContainer-FNYVBPZZ.cjs → ChatContainer-BPI3GEZS.cjs} +10 -10
- package/dist/lib/node/TemplateContainer-VPAZRFQA.cjs +104 -0
- package/dist/lib/node/TemplateContainer-VPAZRFQA.cjs.map +7 -0
- package/dist/lib/node/{ai-client-RBDOGK6W.cjs → ai-client-5ESLYXAV.cjs} +19 -19
- package/dist/lib/node/ai-client-5ESLYXAV.cjs.map +7 -0
- package/dist/lib/node/{app-graph-builder-D7SHQTZS.cjs → app-graph-builder-3P6WSON2.cjs} +63 -20
- package/dist/lib/node/app-graph-builder-3P6WSON2.cjs.map +7 -0
- package/dist/lib/node/{chunk-37GI4NYH.cjs → chunk-KLSNCP34.cjs} +33 -9
- package/dist/lib/node/chunk-KLSNCP34.cjs.map +7 -0
- package/dist/lib/node/{chunk-NV4TQQSU.cjs → chunk-N3SW6DJ6.cjs} +6 -6
- package/dist/lib/node/{chunk-RWY7LVFJ.cjs → chunk-OJJ4F6KP.cjs} +266 -69
- package/dist/lib/node/chunk-OJJ4F6KP.cjs.map +7 -0
- package/dist/lib/node/{chunk-GNPXCHFT.cjs → chunk-U6J2GO7I.cjs} +4 -4
- package/dist/lib/node/{chunk-GNPXCHFT.cjs.map → chunk-U6J2GO7I.cjs.map} +2 -2
- package/dist/lib/node/{chunk-3WXG6WA6.cjs → chunk-VRXFIS4X.cjs} +6 -6
- package/dist/lib/node/chunk-VRXFIS4X.cjs.map +7 -0
- package/dist/lib/node/{chunk-PMA7XUWM.cjs → chunk-WFVOWPKV.cjs} +40 -18
- package/dist/lib/node/chunk-WFVOWPKV.cjs.map +7 -0
- package/dist/lib/node/index.cjs +73 -63
- package/dist/lib/node/index.cjs.map +3 -3
- package/dist/lib/node/{intent-resolver-YMMAFVOB.cjs → intent-resolver-YIFAMM3B.cjs} +13 -10
- package/dist/lib/node/{intent-resolver-YMMAFVOB.cjs.map → intent-resolver-YIFAMM3B.cjs.map} +3 -3
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/{react-surface-RTYCL4GP.cjs → react-surface-REI6G6B3.cjs} +25 -24
- package/dist/lib/node/react-surface-REI6G6B3.cjs.map +7 -0
- package/dist/lib/node/{settings-4YEO7KXF.cjs → settings-2FEYGLYU.cjs} +8 -8
- package/dist/lib/node/types/index.cjs +15 -11
- package/dist/lib/node/types/index.cjs.map +2 -2
- package/dist/lib/node-esm/{AssistantDialog-57ZCJNSL.mjs → AssistantDialog-R3EPF2KL.mjs} +6 -5
- package/dist/lib/node-esm/{AssistantDialog-57ZCJNSL.mjs.map → AssistantDialog-R3EPF2KL.mjs.map} +3 -3
- package/dist/lib/node-esm/{ChatContainer-XYNXFPFT.mjs → ChatContainer-UJ7MV7GU.mjs} +5 -5
- package/dist/lib/node-esm/TemplateContainer-YLA6BJY6.mjs +79 -0
- package/dist/lib/node-esm/TemplateContainer-YLA6BJY6.mjs.map +7 -0
- package/dist/lib/node-esm/ai-client-XYZ5N7CR.mjs +36 -0
- package/dist/lib/node-esm/ai-client-XYZ5N7CR.mjs.map +7 -0
- package/dist/lib/node-esm/{app-graph-builder-H2GC2AZA.mjs → app-graph-builder-PMAQLTTN.mjs} +57 -13
- package/dist/lib/node-esm/app-graph-builder-PMAQLTTN.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-ICQN3TDS.mjs → chunk-2CIYX3SD.mjs} +2 -2
- package/dist/lib/node-esm/chunk-2CIYX3SD.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-YVEPFSWR.mjs → chunk-6GBMQIW7.mjs} +34 -12
- package/dist/lib/node-esm/chunk-6GBMQIW7.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-3HFSWIA5.mjs → chunk-AMTHOYNB.mjs} +261 -60
- package/dist/lib/node-esm/chunk-AMTHOYNB.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-LBQGJE5T.mjs → chunk-J63VQFQO.mjs} +2 -2
- package/dist/lib/node-esm/{chunk-7SV6X6XU.mjs → chunk-N6BVC2C2.mjs} +1 -1
- package/dist/lib/node-esm/{chunk-7SV6X6XU.mjs.map → chunk-N6BVC2C2.mjs.map} +2 -2
- package/dist/lib/node-esm/{chunk-CJ4Y3QW5.mjs → chunk-NMMRHHAR.mjs} +26 -4
- package/dist/lib/node-esm/chunk-NMMRHHAR.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +21 -11
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/{intent-resolver-MR7BOKEW.mjs → intent-resolver-SQ4HLL5L.mjs} +6 -3
- package/dist/lib/node-esm/{intent-resolver-MR7BOKEW.mjs.map → intent-resolver-SQ4HLL5L.mjs.map} +3 -3
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/{react-surface-Y4RK56TT.mjs → react-surface-LE57AGPI.mjs} +10 -9
- package/dist/lib/node-esm/react-surface-LE57AGPI.mjs.map +7 -0
- package/dist/lib/node-esm/{settings-S7P5RWQI.mjs → settings-VHR5KT4J.mjs} +3 -3
- package/dist/lib/node-esm/types/index.mjs +6 -2
- package/dist/types/src/AssistantPlugin.d.ts.map +1 -1
- package/dist/types/src/capabilities/ai-client.d.ts +2 -1
- package/dist/types/src/capabilities/ai-client.d.ts.map +1 -1
- package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
- package/dist/types/src/capabilities/capabilities.d.ts +2 -1
- package/dist/types/src/capabilities/capabilities.d.ts.map +1 -1
- package/dist/types/src/capabilities/index.d.ts +1 -1
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
- package/dist/types/src/components/AssistantDialog.d.ts.map +1 -1
- package/dist/types/src/components/AssistantSettings/AssistantSettings.d.ts.map +1 -1
- package/dist/types/src/components/Prompt/Prompt.d.ts +3 -0
- package/dist/types/src/components/Prompt/Prompt.d.ts.map +1 -1
- package/dist/types/src/components/Prompt/Prompt.stories.d.ts +1 -0
- package/dist/types/src/components/Prompt/Prompt.stories.d.ts.map +1 -1
- package/dist/types/src/components/Prompt/PromptBar.d.ts +2 -2
- package/dist/types/src/components/Prompt/PromptBar.d.ts.map +1 -1
- package/dist/types/src/components/Prompt/references.d.ts +30 -0
- package/dist/types/src/components/Prompt/references.d.ts.map +1 -0
- package/dist/types/src/components/TemplateContainer.d.ts.map +1 -1
- package/dist/types/src/components/Thread/Thread.d.ts +11 -1
- package/dist/types/src/components/Thread/Thread.d.ts.map +1 -1
- package/dist/types/src/components/Thread/ThreadContainer.d.ts +1 -0
- package/dist/types/src/components/Thread/ThreadContainer.d.ts.map +1 -1
- package/dist/types/src/components/Thread/ThreadContainer.stories.d.ts.map +1 -1
- package/dist/types/src/components/Thread/ThreadMessage.d.ts.map +1 -1
- package/dist/types/src/components/Toolbox/Toolbox.d.ts +1 -1
- package/dist/types/src/components/Toolbox/Toolbox.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +1 -0
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/invocation-handler.d.ts +1 -1
- package/dist/types/src/hooks/invocation-handler.d.ts.map +1 -1
- package/dist/types/src/hooks/processor.d.ts +2 -2
- package/dist/types/src/hooks/processor.d.ts.map +1 -1
- package/dist/types/src/hooks/useChatProcessor.d.ts +9 -2
- package/dist/types/src/hooks/useChatProcessor.d.ts.map +1 -1
- package/dist/types/src/hooks/useContextProvider.d.ts +17 -0
- package/dist/types/src/hooks/useContextProvider.d.ts.map +1 -0
- package/dist/types/src/hooks/useMessageQueue.d.ts +4 -4
- package/dist/types/src/hooks/useMessageQueue.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +2 -8
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/testing/test-functions.d.ts.map +1 -1
- package/dist/types/src/tools/function.d.ts +1 -1
- package/dist/types/src/tools/function.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +21 -6
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/service.d.ts +1 -1
- package/dist/types/src/types/service.d.ts.map +1 -1
- package/dist/types/src/types/template.d.ts +36 -0
- package/dist/types/src/types/template.d.ts.map +1 -1
- package/dist/types/src/types/types.d.ts +3 -1
- package/dist/types/src/types/types.d.ts.map +1 -1
- package/package.json +56 -55
- package/src/AssistantPlugin.tsx +11 -2
- package/src/capabilities/ai-client.ts +23 -7
- package/src/capabilities/app-graph-builder.ts +48 -4
- package/src/capabilities/capabilities.ts +3 -1
- package/src/capabilities/intent-resolver.ts +1 -1
- package/src/capabilities/react-surface.tsx +3 -2
- package/src/components/AssistantDialog.tsx +7 -1
- package/src/components/AssistantSettings/AssistantSettings.tsx +39 -5
- package/src/components/Prompt/Prompt.stories.tsx +34 -0
- package/src/components/Prompt/Prompt.tsx +9 -2
- package/src/components/Prompt/PromptBar.tsx +3 -1
- package/src/components/Prompt/references.ts +180 -0
- package/src/components/TemplateContainer.tsx +79 -4
- package/src/components/TemplateEditor/TemplateEditor.stories.tsx +1 -1
- package/src/components/TemplateEditor/TemplateForm.stories.tsx +1 -1
- package/src/components/Thread/Thread.tsx +21 -0
- package/src/components/Thread/ThreadContainer.stories.tsx +3 -6
- package/src/components/Thread/ThreadContainer.tsx +7 -4
- package/src/components/Thread/ThreadMessage.tsx +17 -9
- package/src/components/Toolbox/Toolbox.tsx +1 -1
- package/src/components/index.ts +3 -0
- package/src/hooks/index.ts +1 -0
- package/src/hooks/invocation-handler.ts +3 -5
- package/src/hooks/processor.ts +5 -5
- package/src/hooks/useChatProcessor.tsx +24 -15
- package/src/hooks/useContextProvider.ts +55 -0
- package/src/hooks/useLocalTriggerManager.ts +1 -1
- package/src/hooks/useMessageQueue.ts +2 -4
- package/src/meta.ts +2 -2
- package/src/testing/test-functions.ts +2 -2
- package/src/tools/function.ts +2 -2
- package/src/translations.ts +8 -3
- package/src/types/service.ts +1 -1
- package/src/types/template.ts +22 -0
- package/src/types/types.ts +3 -1
- package/dist/lib/browser/TemplateContainer-B7MQNUPY.mjs +0 -23
- package/dist/lib/browser/TemplateContainer-B7MQNUPY.mjs.map +0 -7
- package/dist/lib/browser/ai-client-PORKRZXM.mjs +0 -33
- package/dist/lib/browser/ai-client-PORKRZXM.mjs.map +0 -7
- package/dist/lib/browser/app-graph-builder-AXAIFOGV.mjs.map +0 -7
- package/dist/lib/browser/chunk-FRIKXDDQ.mjs.map +0 -7
- package/dist/lib/browser/chunk-NTLTGYYS.mjs.map +0 -7
- package/dist/lib/browser/chunk-SUUECBDM.mjs.map +0 -7
- package/dist/lib/browser/chunk-TCAE72QU.mjs.map +0 -7
- package/dist/lib/browser/react-surface-B463WHMD.mjs.map +0 -7
- package/dist/lib/node/TemplateContainer-R4BZZP3E.cjs +0 -53
- package/dist/lib/node/TemplateContainer-R4BZZP3E.cjs.map +0 -7
- package/dist/lib/node/ai-client-RBDOGK6W.cjs.map +0 -7
- package/dist/lib/node/app-graph-builder-D7SHQTZS.cjs.map +0 -7
- package/dist/lib/node/chunk-37GI4NYH.cjs.map +0 -7
- package/dist/lib/node/chunk-3WXG6WA6.cjs.map +0 -7
- package/dist/lib/node/chunk-PMA7XUWM.cjs.map +0 -7
- package/dist/lib/node/chunk-RWY7LVFJ.cjs.map +0 -7
- package/dist/lib/node/react-surface-RTYCL4GP.cjs.map +0 -7
- package/dist/lib/node-esm/TemplateContainer-WSHTZBB5.mjs +0 -24
- package/dist/lib/node-esm/TemplateContainer-WSHTZBB5.mjs.map +0 -7
- package/dist/lib/node-esm/ai-client-OTZVBDUH.mjs +0 -34
- package/dist/lib/node-esm/ai-client-OTZVBDUH.mjs.map +0 -7
- package/dist/lib/node-esm/app-graph-builder-H2GC2AZA.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-3HFSWIA5.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-CJ4Y3QW5.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-ICQN3TDS.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-YVEPFSWR.mjs.map +0 -7
- package/dist/lib/node-esm/react-surface-Y4RK56TT.mjs.map +0 -7
- /package/dist/lib/browser/{ChatContainer-FEZ323HB.mjs.map → ChatContainer-EEEVE62F.mjs.map} +0 -0
- /package/dist/lib/browser/{chunk-EUMPBC4T.mjs.map → chunk-6FTPLBSC.mjs.map} +0 -0
- /package/dist/lib/browser/{settings-JTT62IHD.mjs.map → settings-VAW6UWFL.mjs.map} +0 -0
- /package/dist/lib/node/{ChatContainer-FNYVBPZZ.cjs.map → ChatContainer-BPI3GEZS.cjs.map} +0 -0
- /package/dist/lib/node/{chunk-NV4TQQSU.cjs.map → chunk-N3SW6DJ6.cjs.map} +0 -0
- /package/dist/lib/node/{settings-4YEO7KXF.cjs.map → settings-2FEYGLYU.cjs.map} +0 -0
- /package/dist/lib/node-esm/{ChatContainer-XYNXFPFT.mjs.map → ChatContainer-UJ7MV7GU.mjs.map} +0 -0
- /package/dist/lib/node-esm/{chunk-LBQGJE5T.mjs.map → chunk-J63VQFQO.mjs.map} +0 -0
- /package/dist/lib/node-esm/{settings-S7P5RWQI.mjs.map → settings-VHR5KT4J.mjs.map} +0 -0
|
@@ -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
|
-
(
|
|
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
|
|
105
|
+
return <div ref={parentRef} className={mx('w-full', classNames)} />;
|
|
99
106
|
},
|
|
100
107
|
);
|
|
@@ -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);
|
|
@@ -72,6 +73,7 @@ export const PromptBar = ({
|
|
|
72
73
|
classNames='pbs-2'
|
|
73
74
|
lineWrapping={true}
|
|
74
75
|
placeholder={placeholder ?? t('prompt placeholder')}
|
|
76
|
+
references={references}
|
|
75
77
|
{...props}
|
|
76
78
|
/>
|
|
77
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
|
|
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 {
|
|
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
|
|
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 (
|
|
@@ -15,6 +15,13 @@ import { keyToFallback } from '@dxos/util';
|
|
|
15
15
|
import { ThreadMessage, type ThreadMessageProps } from './ThreadMessage';
|
|
16
16
|
import { messageReducer } from './reducer';
|
|
17
17
|
import { PromptBar, type PromptBarProps } from '../Prompt';
|
|
18
|
+
import type { ReferenceData, ReferencesProvider } from '../Prompt/references';
|
|
19
|
+
|
|
20
|
+
export interface ContextProvider {
|
|
21
|
+
query({ query }: { query: string }): Promise<ReferenceData[]>;
|
|
22
|
+
|
|
23
|
+
resolveMetadata({ uri }: { uri: string }): Promise<ReferenceData | null>;
|
|
24
|
+
}
|
|
18
25
|
|
|
19
26
|
export type ThreadProps = ThemedClassName<{
|
|
20
27
|
space?: Space;
|
|
@@ -22,6 +29,7 @@ export type ThreadProps = ThemedClassName<{
|
|
|
22
29
|
collapse?: boolean;
|
|
23
30
|
transcription?: boolean;
|
|
24
31
|
onOpenChange?: (open: boolean) => void;
|
|
32
|
+
contextProvider?: ContextProvider;
|
|
25
33
|
}> &
|
|
26
34
|
Pick<PromptBarProps, 'processing' | 'error' | 'onSubmit' | 'onSuggest' | 'onCancel'> &
|
|
27
35
|
Pick<ThreadMessageProps, 'debug' | 'tools' | 'onPrompt' | 'onDelete'>;
|
|
@@ -40,6 +48,7 @@ export const Thread = ({
|
|
|
40
48
|
onSubmit,
|
|
41
49
|
onCancel,
|
|
42
50
|
onOpenChange,
|
|
51
|
+
contextProvider,
|
|
43
52
|
...props
|
|
44
53
|
}: ThreadProps) => {
|
|
45
54
|
const scroller = useRef<ScrollController>(null);
|
|
@@ -68,6 +77,17 @@ export const Thread = ({
|
|
|
68
77
|
}
|
|
69
78
|
}, [messages, collapse]);
|
|
70
79
|
|
|
80
|
+
const references = useMemo<ReferencesProvider | undefined>(() => {
|
|
81
|
+
if (!contextProvider) {
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return {
|
|
86
|
+
getReferences: async ({ query }: { query: string }) => contextProvider.query({ query }),
|
|
87
|
+
resolveReference: async ({ uri }: { uri: string }) => contextProvider.resolveMetadata({ uri }),
|
|
88
|
+
};
|
|
89
|
+
}, [contextProvider]);
|
|
90
|
+
|
|
71
91
|
return (
|
|
72
92
|
<div role='none' className={mx('flex flex-col grow overflow-hidden', classNames)}>
|
|
73
93
|
<ScrollContainer ref={scroller} fade>
|
|
@@ -90,6 +110,7 @@ export const Thread = ({
|
|
|
90
110
|
onSubmit={handleSubmit}
|
|
91
111
|
onCancel={onCancel}
|
|
92
112
|
onOpenChange={onOpenChange}
|
|
113
|
+
references={references}
|
|
93
114
|
/>
|
|
94
115
|
)}
|
|
95
116
|
</div>
|
|
@@ -21,7 +21,6 @@ import { Message, type Tool } from '@dxos/artifact';
|
|
|
21
21
|
import { genericTools, localServiceEndpoints, type IsObject } from '@dxos/artifact-testing';
|
|
22
22
|
import { AIServiceEdgeClient } from '@dxos/assistant';
|
|
23
23
|
import { createStatic, ObjectId } from '@dxos/echo-schema';
|
|
24
|
-
import { EdgeHttpClient } from '@dxos/edge-client';
|
|
25
24
|
import { invariant } from '@dxos/invariant';
|
|
26
25
|
import { DXN, QueueSubspaceTags, SpaceId } from '@dxos/keys';
|
|
27
26
|
import { ChessPlugin } from '@dxos/plugin-chess';
|
|
@@ -31,9 +30,8 @@ import { InboxPlugin } from '@dxos/plugin-inbox';
|
|
|
31
30
|
import { MapPlugin } from '@dxos/plugin-map';
|
|
32
31
|
import { SpacePlugin } from '@dxos/plugin-space';
|
|
33
32
|
import { TablePlugin } from '@dxos/plugin-table';
|
|
34
|
-
import { useSpace } from '@dxos/react-client/echo';
|
|
33
|
+
import { useQueue, useSpace } from '@dxos/react-client/echo';
|
|
35
34
|
import { withClientProvider } from '@dxos/react-client/testing';
|
|
36
|
-
import { useQueue } from '@dxos/react-edge-client';
|
|
37
35
|
import { IconButton, Input, Toolbar } from '@dxos/react-ui';
|
|
38
36
|
import { mx } from '@dxos/react-ui-theme';
|
|
39
37
|
import { withLayout, withSignals, withTheme } from '@dxos/storybook-utils';
|
|
@@ -60,7 +58,6 @@ const Render = ({ items: _items, prompts = [], ...props }: RenderProps) => {
|
|
|
60
58
|
);
|
|
61
59
|
|
|
62
60
|
const [aiClient] = useState(() => new AIServiceEdgeClient({ endpoint: endpoints.ai }));
|
|
63
|
-
const [edgeClient] = useState(() => new EdgeHttpClient(endpoints.edge));
|
|
64
61
|
const { dispatchPromise: dispatch } = useIntentDispatcher();
|
|
65
62
|
|
|
66
63
|
// TODO(burdon): Replace with useChatProcessor.
|
|
@@ -82,8 +79,8 @@ const Render = ({ items: _items, prompts = [], ...props }: RenderProps) => {
|
|
|
82
79
|
}, [aiClient, tools, space, dispatch, artifactDefinitions]);
|
|
83
80
|
|
|
84
81
|
// Queue.
|
|
85
|
-
const [queueDxn, setQueueDxn] = useState(() => randomQueueDxn());
|
|
86
|
-
const queue = useQueue<Message>(
|
|
82
|
+
const [queueDxn, setQueueDxn] = useState<string>(() => randomQueueDxn());
|
|
83
|
+
const queue = useQueue<Message>(DXN.tryParse(queueDxn));
|
|
87
84
|
|
|
88
85
|
useEffect(() => {
|
|
89
86
|
if (queue?.items.length === 0 && !queue.isLoading && prompts.length > 0) {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import React, { type FC
|
|
5
|
+
import React, { useCallback, type FC } from 'react';
|
|
6
6
|
|
|
7
7
|
import { invariant } from '@dxos/invariant';
|
|
8
8
|
import { log } from '@dxos/log';
|
|
@@ -10,12 +10,13 @@ import { getSpace } from '@dxos/react-client/echo';
|
|
|
10
10
|
import { type ThemedClassName } from '@dxos/react-ui';
|
|
11
11
|
|
|
12
12
|
import { Thread, type ThreadProps } from './Thread';
|
|
13
|
-
import { useChatProcessor, useMessageQueue } from '../../hooks';
|
|
13
|
+
import { useChatProcessor, useContextProvider, useMessageQueue } from '../../hooks';
|
|
14
14
|
import { type AIChatType, type AssistantSettingsProps } from '../../types';
|
|
15
15
|
|
|
16
16
|
export type ThreadContainerProps = {
|
|
17
17
|
chat?: AIChatType;
|
|
18
18
|
settings?: AssistantSettingsProps;
|
|
19
|
+
part?: 'deck' | 'dialog';
|
|
19
20
|
} & Pick<ThreadProps, 'debug' | 'transcription' | 'onOpenChange'>;
|
|
20
21
|
|
|
21
22
|
// TODO(burdon): Since this only wraps Thread, just separate out hook?
|
|
@@ -23,12 +24,13 @@ export const ThreadContainer: FC<ThemedClassName<ThreadContainerProps>> = ({
|
|
|
23
24
|
classNames,
|
|
24
25
|
chat,
|
|
25
26
|
settings,
|
|
27
|
+
part,
|
|
26
28
|
onOpenChange,
|
|
27
29
|
...props
|
|
28
30
|
}) => {
|
|
29
|
-
// Push up capabilities hooks out of components.
|
|
30
31
|
const space = getSpace(chat);
|
|
31
|
-
const
|
|
32
|
+
const contextProvider = useContextProvider(space);
|
|
33
|
+
const processor = useChatProcessor({ chat, space, settings, part });
|
|
32
34
|
const messageQueue = useMessageQueue(chat);
|
|
33
35
|
const messages = [...(messageQueue?.items ?? []), ...processor.messages.value];
|
|
34
36
|
|
|
@@ -73,6 +75,7 @@ export const ThreadContainer: FC<ThemedClassName<ThreadContainerProps>> = ({
|
|
|
73
75
|
onCancel={handleCancel}
|
|
74
76
|
onPrompt={handleSubmit}
|
|
75
77
|
onOpenChange={onOpenChange}
|
|
78
|
+
contextProvider={contextProvider}
|
|
76
79
|
{...props}
|
|
77
80
|
/>
|
|
78
81
|
);
|
|
@@ -7,7 +7,7 @@ import React, { type PropsWithChildren, type FC } from 'react';
|
|
|
7
7
|
import { type MessageContentBlock, type Message, type ToolType } from '@dxos/artifact';
|
|
8
8
|
import { invariant } from '@dxos/invariant';
|
|
9
9
|
import { type Space } from '@dxos/react-client/echo';
|
|
10
|
-
import { Button,
|
|
10
|
+
import { Button, Icon, IconButton, type ThemedClassName } from '@dxos/react-ui';
|
|
11
11
|
import {
|
|
12
12
|
MarkdownViewer,
|
|
13
13
|
ToggleContainer as NativeToggleContainer,
|
|
@@ -21,7 +21,7 @@ import { ToolBlock, isToolMessage } from './ToolInvocations';
|
|
|
21
21
|
import { ToolboxContainer } from '../Toolbox';
|
|
22
22
|
|
|
23
23
|
const panelClassNames = 'flex flex-col w-full px-2 bg-groupSurface rounded-md';
|
|
24
|
-
const userClassNames = 'bg-[--user-fill]';
|
|
24
|
+
const userClassNames = 'bg-[--user-fill] text-inverse';
|
|
25
25
|
|
|
26
26
|
const ToggleContainer = (props: ToggleContainerProps) => {
|
|
27
27
|
return <NativeToggleContainer {...props} classNames={mx(panelClassNames, props.classNames)} />;
|
|
@@ -54,7 +54,7 @@ export const ThreadMessage: FC<ThreadMessageProps> = ({ classNames, space, messa
|
|
|
54
54
|
// TODO(burdon): Restructure types to make check unnecessary.
|
|
55
55
|
if (isToolMessage(message)) {
|
|
56
56
|
return (
|
|
57
|
-
<MessageContainer classNames={classNames}>
|
|
57
|
+
<MessageContainer classNames={mx(classNames, 'animate-[fadeIn_0.5s]')}>
|
|
58
58
|
<ToolBlock space={space} classNames={panelClassNames} message={message} tools={tools} />
|
|
59
59
|
</MessageContainer>
|
|
60
60
|
);
|
|
@@ -69,7 +69,11 @@ export const ThreadMessage: FC<ThreadMessageProps> = ({ classNames, space, messa
|
|
|
69
69
|
const Component = components[block.type] ?? components.default;
|
|
70
70
|
|
|
71
71
|
return (
|
|
72
|
-
<MessageContainer
|
|
72
|
+
<MessageContainer
|
|
73
|
+
key={idx}
|
|
74
|
+
classNames={mx(classNames, 'animate-[fadeIn_0.5s]')}
|
|
75
|
+
user={block.type === 'text' && role === 'user'}
|
|
76
|
+
>
|
|
73
77
|
<Component space={space} block={block} onPrompt={onPrompt} />
|
|
74
78
|
</MessageContainer>
|
|
75
79
|
);
|
|
@@ -87,7 +91,7 @@ const components: Record<string, BlockComponent> = {
|
|
|
87
91
|
// const [open, setOpen] = useState(block.disposition === 'cot' && block.pending);
|
|
88
92
|
const title = block.disposition ? titles[block.disposition] : undefined;
|
|
89
93
|
if (!title) {
|
|
90
|
-
return <MarkdownViewer content={block.text} />;
|
|
94
|
+
return <MarkdownViewer classNames='[&>p]:animate-[fadeIn_0.5s]' content={block.text} />;
|
|
91
95
|
}
|
|
92
96
|
|
|
93
97
|
// TOOD(burdon): Store last time user opened/closed COT.
|
|
@@ -140,13 +144,17 @@ const components: Record<string, BlockComponent> = {
|
|
|
140
144
|
case 'select': {
|
|
141
145
|
const { options = [] }: { options: string[] } = safeParseJson(block.json ?? '{}') ?? ({} as any);
|
|
142
146
|
return (
|
|
143
|
-
<
|
|
144
|
-
{options.map((option) => (
|
|
145
|
-
<Button
|
|
147
|
+
<div className='flex flex-wrap gap-1'>
|
|
148
|
+
{options.map((option, idx) => (
|
|
149
|
+
<Button
|
|
150
|
+
classNames={'animate-[fadeIn_0.5s] rounded-2xl text-sm'}
|
|
151
|
+
key={option}
|
|
152
|
+
onClick={() => onPrompt?.(option)}
|
|
153
|
+
>
|
|
146
154
|
{option}
|
|
147
155
|
</Button>
|
|
148
156
|
))}
|
|
149
|
-
</
|
|
157
|
+
</div>
|
|
150
158
|
);
|
|
151
159
|
}
|
|
152
160
|
|
|
@@ -6,7 +6,7 @@ import React, { useState, useEffect, Fragment, type FC } from 'react';
|
|
|
6
6
|
|
|
7
7
|
import { Capabilities, useCapabilities } from '@dxos/app-framework';
|
|
8
8
|
import { parseToolName, type ArtifactDefinition, type Tool } from '@dxos/artifact';
|
|
9
|
-
import { FunctionType } from '@dxos/functions';
|
|
9
|
+
import { FunctionType } from '@dxos/functions/types';
|
|
10
10
|
import { log } from '@dxos/log';
|
|
11
11
|
import { Filter, type Space, useQuery } from '@dxos/react-client/echo';
|
|
12
12
|
import { type ThemedClassName } from '@dxos/react-ui';
|
package/src/components/index.ts
CHANGED
|
@@ -10,6 +10,9 @@ export * from './TemplateEditor';
|
|
|
10
10
|
export * from './Thread';
|
|
11
11
|
export * from './Toolbox';
|
|
12
12
|
|
|
13
|
+
// TODO(burdon): Lazy loading causes issues with Tabster.
|
|
14
|
+
// Repro: open assistant dialog then close.
|
|
15
|
+
// https://github.com/microsoft/fluentui/issues/34020
|
|
13
16
|
export const AssistantDialog = lazy(() => import('./AssistantDialog'));
|
|
14
17
|
export const ChatContainer = lazy(() => import('./ChatContainer'));
|
|
15
18
|
export const TemplateContainer = lazy(() => import('./TemplateContainer'));
|
package/src/hooks/index.ts
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
import { sleep } from '@dxos/async';
|
|
6
6
|
import { getObjectCore, ResultFormat } from '@dxos/echo-db';
|
|
7
7
|
import { type AnyObjectData } from '@dxos/echo-schema';
|
|
8
|
-
import { FunctionType } from '@dxos/functions';
|
|
9
|
-
import { type FunctionTrigger } from '@dxos/functions';
|
|
8
|
+
import { FunctionType, getUserFunctionUrlInMetadata } from '@dxos/functions/types';
|
|
9
|
+
import { type FunctionTrigger } from '@dxos/functions/types';
|
|
10
10
|
import { invariant } from '@dxos/invariant';
|
|
11
11
|
import { DXN, LOCAL_SPACE_TAG } from '@dxos/keys';
|
|
12
12
|
import { log } from '@dxos/log';
|
|
@@ -53,7 +53,7 @@ export const invokeFunction = async (client: Client, space: Space, trigger: Func
|
|
|
53
53
|
.query({ __typename: FunctionType.typename }, { format: ResultFormat.Plain })
|
|
54
54
|
.run();
|
|
55
55
|
const func = functions.find((fn) => referenceEquals(fn.source, trigger.function!)) as AnyObjectData | undefined;
|
|
56
|
-
const funcSlug = func
|
|
56
|
+
const funcSlug = func && getUserFunctionUrlInMetadata(func.__meta);
|
|
57
57
|
if (!funcSlug) {
|
|
58
58
|
log.warn('function not deployed', { scriptId: script.id, name: script.name });
|
|
59
59
|
return 404;
|
|
@@ -72,8 +72,6 @@ export const invokeFunction = async (client: Client, space: Space, trigger: Func
|
|
|
72
72
|
}
|
|
73
73
|
};
|
|
74
74
|
|
|
75
|
-
const USERFUNCTIONS_META_KEY = 'dxos.org/service/function';
|
|
76
|
-
|
|
77
75
|
const getFunctionUrl = (config: Config, slug: string, spaceId?: string) => {
|
|
78
76
|
const baseUrl = new URL('functions/', config.values.runtime?.services?.edge?.url);
|
|
79
77
|
|