@dxos/plugin-assistant 0.8.0 → 0.8.1-main.013e445
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-TX6YYBUG.mjs → AssistantDialog-EIUUSXDS.mjs} +11 -10
- package/dist/lib/browser/AssistantDialog-EIUUSXDS.mjs.map +7 -0
- package/dist/lib/browser/{ChatContainer-AT3OAUT3.mjs → ChatContainer-NHHA6CSP.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-G7B54APW.mjs → chunk-25APJ3ZK.mjs} +34 -12
- package/dist/lib/browser/chunk-25APJ3ZK.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-NFVIZS3B.mjs → chunk-KGIACFAX.mjs} +351 -207
- package/dist/lib/browser/chunk-KGIACFAX.mjs.map +7 -0
- package/dist/lib/browser/{chunk-VZ4W6SHE.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/index.mjs +25 -27
- 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-JLXNWOI6.mjs → react-surface-YNN5NYJW.mjs} +10 -9
- package/dist/lib/browser/react-surface-YNN5NYJW.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-U4GBPZD6.cjs → AssistantDialog-GT7R7MKH.cjs} +17 -16
- package/dist/lib/node/AssistantDialog-GT7R7MKH.cjs.map +7 -0
- package/dist/lib/node/{ChatContainer-CVHXNHGA.cjs → ChatContainer-JUZOEZZ7.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-YANJEPO3.cjs → ai-client-5ESLYXAV.cjs} +19 -8
- 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-IXJCGW7U.cjs → chunk-G2HY3UJ4.cjs} +40 -18
- package/dist/lib/node/chunk-G2HY3UJ4.cjs.map +7 -0
- package/dist/lib/node/{chunk-XUTDR7HI.cjs → chunk-JAB6KLPP.cjs} +356 -216
- package/dist/lib/node/chunk-JAB6KLPP.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-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-ZGH6F5YA.cjs → chunk-VRXFIS4X.cjs} +6 -6
- package/dist/lib/node/chunk-VRXFIS4X.cjs.map +7 -0
- package/dist/lib/node/index.cjs +75 -77
- 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-BSUZQ3HZ.cjs → react-surface-IDGIN55C.cjs} +25 -24
- package/dist/lib/node/react-surface-IDGIN55C.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-5AT5JAZL.mjs → AssistantDialog-JMBFM6QH.mjs} +11 -10
- package/dist/lib/node-esm/AssistantDialog-JMBFM6QH.mjs.map +7 -0
- package/dist/lib/node-esm/{ChatContainer-VR766C4M.mjs → ChatContainer-ZNN5CMVL.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-77ARTFBA.mjs → chunk-2CIYX3SD.mjs} +2 -2
- package/dist/lib/node-esm/chunk-2CIYX3SD.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/{chunk-7JENJTLB.mjs → chunk-PK5JCOYB.mjs} +351 -207
- package/dist/lib/node-esm/chunk-PK5JCOYB.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-AMQMVQJO.mjs → chunk-SMUINDXQ.mjs} +34 -12
- package/dist/lib/node-esm/chunk-SMUINDXQ.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +25 -27
- 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-IGVYAOGL.mjs → react-surface-424JZTZ4.mjs} +10 -9
- package/dist/lib/node-esm/react-surface-424JZTZ4.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 -2
- 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 +3 -2
- 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/AmbientDialog/AmbientDialog.d.ts +5 -4
- package/dist/types/src/components/AmbientDialog/AmbientDialog.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 +2 -1
- package/dist/types/src/components/AssistantSettings/AssistantSettings.d.ts.map +1 -1
- package/dist/types/src/components/ChatContainer.d.ts +2 -1
- package/dist/types/src/components/ChatContainer.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 +3 -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/ServiceRegistry/ServiceRegistry.d.ts +2 -1
- package/dist/types/src/components/ServiceRegistry/ServiceRegistry.d.ts.map +1 -1
- package/dist/types/src/components/TemplateContainer.d.ts +2 -1
- package/dist/types/src/components/TemplateContainer.d.ts.map +1 -1
- package/dist/types/src/components/TemplateEditor/TemplateEditor.d.ts +2 -1
- package/dist/types/src/components/TemplateEditor/TemplateEditor.d.ts.map +1 -1
- package/dist/types/src/components/TemplateEditor/TemplateEditor.stories.d.ts +2 -1
- package/dist/types/src/components/TemplateEditor/TemplateEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/TemplateEditor/TemplateForm.d.ts +3 -2
- package/dist/types/src/components/TemplateEditor/TemplateForm.d.ts.map +1 -1
- package/dist/types/src/components/Thread/Thread.d.ts +12 -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 +2 -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 +4 -3
- package/dist/types/src/components/Toolbox/Toolbox.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +2 -2
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/hooks/email.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 +10 -15
- 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 +23 -12
- 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 -56
- package/src/AssistantPlugin.tsx +11 -4
- package/src/capabilities/ai-client.ts +23 -4
- package/src/capabilities/app-graph-builder.ts +48 -4
- package/src/capabilities/capabilities.ts +4 -2
- package/src/capabilities/intent-resolver.ts +1 -1
- package/src/capabilities/react-surface.tsx +3 -2
- package/src/components/AmbientDialog/AmbientDialog.tsx +11 -11
- 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 +28 -18
- package/src/components/Prompt/PromptBar.tsx +18 -7
- 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/TemplateEditor/TemplateForm.tsx +1 -1
- package/src/components/Thread/Thread.tsx +21 -0
- package/src/components/Thread/ThreadContainer.stories.tsx +7 -12
- 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/email.ts +3 -3
- package/src/hooks/index.ts +1 -0
- package/src/hooks/invocation-handler.ts +3 -5
- package/src/hooks/processor.ts +60 -110
- package/src/hooks/useChatProcessor.tsx +25 -17
- 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/tools/openapi.test.ts +4 -4
- package/src/translations.ts +10 -5
- 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/AssistantDialog-TX6YYBUG.mjs.map +0 -7
- 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-RTCGRKZE.mjs +0 -22
- package/dist/lib/browser/ai-client-RTCGRKZE.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-G7B54APW.mjs.map +0 -7
- package/dist/lib/browser/chunk-NFVIZS3B.mjs.map +0 -7
- package/dist/lib/browser/chunk-VZ4W6SHE.mjs.map +0 -7
- package/dist/lib/browser/react-surface-JLXNWOI6.mjs.map +0 -7
- package/dist/lib/node/AssistantDialog-U4GBPZD6.cjs.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-YANJEPO3.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-IXJCGW7U.cjs.map +0 -7
- package/dist/lib/node/chunk-XUTDR7HI.cjs.map +0 -7
- package/dist/lib/node/chunk-ZGH6F5YA.cjs.map +0 -7
- package/dist/lib/node/react-surface-BSUZQ3HZ.cjs.map +0 -7
- package/dist/lib/node-esm/AssistantDialog-5AT5JAZL.mjs.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-66IBZVCX.mjs +0 -23
- package/dist/lib/node-esm/ai-client-66IBZVCX.mjs.map +0 -7
- package/dist/lib/node-esm/app-graph-builder-H2GC2AZA.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-77ARTFBA.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-7JENJTLB.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-AMQMVQJO.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-CJ4Y3QW5.mjs.map +0 -7
- package/dist/lib/node-esm/react-surface-IGVYAOGL.mjs.map +0 -7
- /package/dist/lib/browser/{ChatContainer-AT3OAUT3.mjs.map → ChatContainer-NHHA6CSP.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-CVHXNHGA.cjs.map → ChatContainer-JUZOEZZ7.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-VR766C4M.mjs.map → ChatContainer-ZNN5CMVL.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
|
@@ -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>
|
|
@@ -19,9 +19,8 @@ import {
|
|
|
19
19
|
import { withPluginManager } from '@dxos/app-framework/testing';
|
|
20
20
|
import { Message, type Tool } from '@dxos/artifact';
|
|
21
21
|
import { genericTools, localServiceEndpoints, type IsObject } from '@dxos/artifact-testing';
|
|
22
|
-
import {
|
|
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';
|
|
@@ -54,13 +52,9 @@ type RenderProps = {
|
|
|
54
52
|
const Render = ({ items: _items, prompts = [], ...props }: RenderProps) => {
|
|
55
53
|
const space = useSpace();
|
|
56
54
|
const artifactDefinitions = useCapabilities(Capabilities.ArtifactDefinition);
|
|
57
|
-
const tools = useMemo<Tool[]>(
|
|
58
|
-
() => [...genericTools, ...artifactDefinitions.flatMap((definition) => definition.tools)],
|
|
59
|
-
[genericTools, artifactDefinitions],
|
|
60
|
-
);
|
|
55
|
+
const tools = useMemo<Tool[]>(() => [...genericTools], []);
|
|
61
56
|
|
|
62
|
-
const [aiClient] = useState(() => new
|
|
63
|
-
const [edgeClient] = useState(() => new EdgeHttpClient(endpoints.edge));
|
|
57
|
+
const [aiClient] = useState(() => new AIServiceEdgeClient({ endpoint: endpoints.ai }));
|
|
64
58
|
const { dispatchPromise: dispatch } = useIntentDispatcher();
|
|
65
59
|
|
|
66
60
|
// TODO(burdon): Replace with useChatProcessor.
|
|
@@ -73,6 +67,7 @@ const Render = ({ items: _items, prompts = [], ...props }: RenderProps) => {
|
|
|
73
67
|
return new ChatProcessor(
|
|
74
68
|
aiClient,
|
|
75
69
|
tools,
|
|
70
|
+
artifactDefinitions,
|
|
76
71
|
{
|
|
77
72
|
space,
|
|
78
73
|
dispatch,
|
|
@@ -82,8 +77,8 @@ const Render = ({ items: _items, prompts = [], ...props }: RenderProps) => {
|
|
|
82
77
|
}, [aiClient, tools, space, dispatch, artifactDefinitions]);
|
|
83
78
|
|
|
84
79
|
// Queue.
|
|
85
|
-
const [queueDxn, setQueueDxn] = useState(() => randomQueueDxn());
|
|
86
|
-
const queue = useQueue<Message>(
|
|
80
|
+
const [queueDxn, setQueueDxn] = useState<string>(() => randomQueueDxn());
|
|
81
|
+
const queue = useQueue<Message>(DXN.tryParse(queueDxn));
|
|
87
82
|
|
|
88
83
|
useEffect(() => {
|
|
89
84
|
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/email.ts
CHANGED
|
@@ -6,8 +6,8 @@ import { findObjectWithForeignKey } from '@dxos/echo-db';
|
|
|
6
6
|
import { foreignKey } from '@dxos/echo-schema';
|
|
7
7
|
import { log } from '@dxos/log';
|
|
8
8
|
import { MailboxType } from '@dxos/plugin-inbox/types';
|
|
9
|
-
import { MessageType } from '@dxos/plugin-space/types';
|
|
10
9
|
import { type Space, Filter, create, makeRef } from '@dxos/react-client/echo';
|
|
10
|
+
import { MessageType } from '@dxos/schema';
|
|
11
11
|
|
|
12
12
|
export const SOURCE_ID = 'hub.dxos.network/api/mailbox';
|
|
13
13
|
|
|
@@ -29,8 +29,8 @@ export const handleEmail = async (space: Space, data: any) => {
|
|
|
29
29
|
MessageType,
|
|
30
30
|
{
|
|
31
31
|
sender: { email: message.from },
|
|
32
|
-
|
|
33
|
-
text: message.body,
|
|
32
|
+
created: new Date(message.created).toISOString(),
|
|
33
|
+
blocks: [{ type: 'text', text: message.body }],
|
|
34
34
|
properties: {
|
|
35
35
|
subject: message.subject,
|
|
36
36
|
to: [{ email: message.to }],
|
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
|
|
package/src/hooks/processor.ts
CHANGED
|
@@ -5,17 +5,8 @@
|
|
|
5
5
|
import { type Signal, batch, computed, signal } from '@preact/signals-core';
|
|
6
6
|
|
|
7
7
|
import { type PromiseIntentDispatcher } from '@dxos/app-framework';
|
|
8
|
-
import { type
|
|
9
|
-
import {
|
|
10
|
-
isToolUse,
|
|
11
|
-
runTools,
|
|
12
|
-
type GenerateRequest,
|
|
13
|
-
type GenerationStream,
|
|
14
|
-
MixedStreamParser,
|
|
15
|
-
DEFAULT_LLM_MODEL,
|
|
16
|
-
type AIService,
|
|
17
|
-
} from '@dxos/assistant';
|
|
18
|
-
import { createStatic } from '@dxos/echo-schema';
|
|
8
|
+
import { type ArtifactDefinition, type Message, type MessageContentBlock, type Tool } from '@dxos/artifact';
|
|
9
|
+
import { type AIServiceClient, AISession, DEFAULT_EDGE_MODEL, type GenerateRequest } from '@dxos/assistant';
|
|
19
10
|
import { invariant } from '@dxos/invariant';
|
|
20
11
|
import { log } from '@dxos/log';
|
|
21
12
|
import { type Space } from '@dxos/react-client/echo';
|
|
@@ -36,7 +27,7 @@ type RequestOptions = {
|
|
|
36
27
|
export type ChatProcessorOptions = Pick<GenerateRequest, 'model' | 'systemPrompt'>;
|
|
37
28
|
|
|
38
29
|
const defaultOptions: ChatProcessorOptions = {
|
|
39
|
-
model:
|
|
30
|
+
model: DEFAULT_EDGE_MODEL,
|
|
40
31
|
systemPrompt: 'you are a helpful assistant',
|
|
41
32
|
};
|
|
42
33
|
|
|
@@ -47,20 +38,14 @@ const defaultOptions: ChatProcessorOptions = {
|
|
|
47
38
|
* Supports cancellation of in-progress requests.
|
|
48
39
|
*/
|
|
49
40
|
export class ChatProcessor {
|
|
50
|
-
/** SSE stream parser. */
|
|
51
|
-
private readonly _parser = new MixedStreamParser();
|
|
52
|
-
|
|
53
|
-
/** Current streaming response. */
|
|
54
|
-
private _stream: GenerationStream | undefined;
|
|
55
|
-
|
|
56
41
|
/** Pending messages (incl. the current user request). */
|
|
57
42
|
private readonly _pending: Signal<Message[]> = signal([]);
|
|
58
43
|
|
|
59
44
|
/** Current streaming block (from the AI service). */
|
|
60
45
|
private readonly _block: Signal<MessageContentBlock | undefined> = signal(undefined);
|
|
61
46
|
|
|
62
|
-
/**
|
|
63
|
-
private
|
|
47
|
+
/** Current streaming response. */
|
|
48
|
+
private _session: AISession | undefined;
|
|
64
49
|
|
|
65
50
|
/**
|
|
66
51
|
* Streaming state.
|
|
@@ -92,26 +77,12 @@ export class ChatProcessor {
|
|
|
92
77
|
});
|
|
93
78
|
|
|
94
79
|
constructor(
|
|
95
|
-
private readonly
|
|
80
|
+
private readonly _ai: AIServiceClient,
|
|
96
81
|
private _tools?: Tool[],
|
|
82
|
+
private _artifacts?: ArtifactDefinition[],
|
|
97
83
|
private readonly _extensions?: ToolContextExtensions,
|
|
98
84
|
private readonly _options: ChatProcessorOptions = defaultOptions,
|
|
99
|
-
) {
|
|
100
|
-
// Message complete.
|
|
101
|
-
this._parser.message.on((message) => {
|
|
102
|
-
batch(() => {
|
|
103
|
-
this._pending.value = [...this._pending.value, message];
|
|
104
|
-
this._block.value = undefined;
|
|
105
|
-
});
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
// Streaming update (happens before message complete).
|
|
109
|
-
this._parser.update.on((block) => {
|
|
110
|
-
batch(() => {
|
|
111
|
-
this._block.value = block;
|
|
112
|
-
});
|
|
113
|
-
});
|
|
114
|
-
}
|
|
85
|
+
) {}
|
|
115
86
|
|
|
116
87
|
get tools() {
|
|
117
88
|
return this._tools;
|
|
@@ -128,19 +99,55 @@ export class ChatProcessor {
|
|
|
128
99
|
* Make GPT request.
|
|
129
100
|
*/
|
|
130
101
|
async request(message: string, options: RequestOptions = {}): Promise<Message[]> {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
this._block.value = undefined;
|
|
102
|
+
this._session = new AISession({ operationModel: 'immediate' });
|
|
103
|
+
|
|
104
|
+
// Message complete.
|
|
105
|
+
this._session.message.on((message) => {
|
|
106
|
+
batch(() => {
|
|
107
|
+
this._pending.value = [...this._pending.value, message];
|
|
108
|
+
this._block.value = undefined;
|
|
109
|
+
});
|
|
140
110
|
});
|
|
141
111
|
|
|
142
|
-
|
|
143
|
-
|
|
112
|
+
// Streaming update (happens before message complete).
|
|
113
|
+
this._session.update.on((block) => {
|
|
114
|
+
batch(() => {
|
|
115
|
+
this._block.value = block;
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
this._session.userMessage.on((message) => {
|
|
120
|
+
this._pending.value = [...this._pending.value, message];
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
try {
|
|
124
|
+
const messages = await this._session.run({
|
|
125
|
+
client: this._ai,
|
|
126
|
+
history: options.history ?? [],
|
|
127
|
+
artifacts: this._artifacts ?? [],
|
|
128
|
+
tools: this._tools ?? [],
|
|
129
|
+
prompt: message,
|
|
130
|
+
extensions: this._extensions,
|
|
131
|
+
generationOptions: {
|
|
132
|
+
model: this._options.model,
|
|
133
|
+
systemPrompt: this._options.systemPrompt,
|
|
134
|
+
},
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
log.info('completed', { messages });
|
|
138
|
+
|
|
139
|
+
options.onComplete?.(this._pending.value);
|
|
140
|
+
} catch (err) {
|
|
141
|
+
log.catch(err);
|
|
142
|
+
if (err instanceof Error && err.message.includes('Overloaded')) {
|
|
143
|
+
this.error.value = new AIServiceOverloadedError('AI service overloaded', { cause: err });
|
|
144
|
+
} else {
|
|
145
|
+
this.error.value = new Error('AI service error', { cause: err });
|
|
146
|
+
}
|
|
147
|
+
} finally {
|
|
148
|
+
this._session = undefined;
|
|
149
|
+
}
|
|
150
|
+
|
|
144
151
|
return this._reset();
|
|
145
152
|
}
|
|
146
153
|
|
|
@@ -150,79 +157,22 @@ export class ChatProcessor {
|
|
|
150
157
|
*/
|
|
151
158
|
async cancel(): Promise<Message[]> {
|
|
152
159
|
log.info('cancelling...');
|
|
153
|
-
this.
|
|
160
|
+
this._session?.abort();
|
|
154
161
|
return this._reset();
|
|
155
162
|
}
|
|
156
163
|
|
|
157
164
|
private async _reset(): Promise<Message[]> {
|
|
158
165
|
const messages = this._pending.value;
|
|
159
166
|
batch(() => {
|
|
160
|
-
this._history = [];
|
|
161
167
|
this._pending.value = [];
|
|
162
168
|
this._block.value = undefined;
|
|
163
169
|
});
|
|
164
170
|
|
|
165
171
|
return messages;
|
|
166
172
|
}
|
|
173
|
+
}
|
|
167
174
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
*/
|
|
172
|
-
private async _request() {
|
|
173
|
-
try {
|
|
174
|
-
let more = false;
|
|
175
|
-
do {
|
|
176
|
-
log('request', {
|
|
177
|
-
pending: this._pending.value.length,
|
|
178
|
-
history: this._history.length,
|
|
179
|
-
tools: this._tools?.map((tool) => tool.name),
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
// Open request stream.
|
|
183
|
-
this._stream = await this._service.exec({
|
|
184
|
-
...this._options,
|
|
185
|
-
// TODO(burdon): Rename messages or separate history/message.
|
|
186
|
-
history: [...this._history, ...this._pending.value],
|
|
187
|
-
tools: this._tools,
|
|
188
|
-
});
|
|
189
|
-
|
|
190
|
-
// Wait until complete.
|
|
191
|
-
await this._parser.parse(this._stream);
|
|
192
|
-
await this._stream.complete();
|
|
193
|
-
|
|
194
|
-
// Add messages.
|
|
195
|
-
log('response', { pending: this._pending.value });
|
|
196
|
-
|
|
197
|
-
// Resolve tool use locally.
|
|
198
|
-
more = false;
|
|
199
|
-
const message = this._pending.value.at(-1);
|
|
200
|
-
invariant(message);
|
|
201
|
-
if (isToolUse(message)) {
|
|
202
|
-
log('tool request...');
|
|
203
|
-
const response = await runTools({
|
|
204
|
-
message: this._pending.value.at(-1)!,
|
|
205
|
-
tools: this._tools ?? [],
|
|
206
|
-
extensions: this._extensions,
|
|
207
|
-
});
|
|
208
|
-
|
|
209
|
-
log('tool response', { response });
|
|
210
|
-
switch (response.type) {
|
|
211
|
-
case 'continue': {
|
|
212
|
-
this._pending.value = [...this._pending.value, response.message];
|
|
213
|
-
more = true;
|
|
214
|
-
break;
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
} while (more);
|
|
219
|
-
|
|
220
|
-
this.error.value = undefined;
|
|
221
|
-
} catch (err) {
|
|
222
|
-
log.catch(err);
|
|
223
|
-
this.error.value = new Error('AI service error', { cause: err });
|
|
224
|
-
} finally {
|
|
225
|
-
this._stream = undefined;
|
|
226
|
-
}
|
|
227
|
-
}
|
|
175
|
+
// TODO(wittjosiah): Move to ai-service-client.
|
|
176
|
+
export class AIServiceOverloadedError extends Error {
|
|
177
|
+
code = 'AI_SERVICE_OVERLOADED';
|
|
228
178
|
}
|