@dxos/plugin-automation 0.7.5-labs.e27f9b9 → 0.7.5-labs.ea4b4c2
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/AutomationPanel-VW2XIUPU.mjs +8 -0
- package/dist/lib/browser/ChatContainer-5TAVTN3T.mjs +12 -0
- package/dist/lib/browser/{ai-client-AARXEMMJ.mjs → ai-client-5CNY6JBF.mjs} +3 -3
- package/dist/lib/browser/{app-graph-builder-B4U34VSR.mjs → app-graph-builder-FZGK55G7.mjs} +39 -4
- package/dist/lib/browser/app-graph-builder-FZGK55G7.mjs.map +7 -0
- package/dist/lib/browser/{chunk-HZ4TA7HY.mjs → chunk-2H2EUYXL.mjs} +2 -2
- package/dist/lib/browser/{chunk-5SLV6AUA.mjs → chunk-DVE33EZL.mjs} +525 -290
- package/dist/lib/browser/chunk-DVE33EZL.mjs.map +7 -0
- package/dist/lib/browser/{chunk-IYSMXX6Q.mjs → chunk-MJK7GL5P.mjs} +68 -44
- package/dist/lib/browser/chunk-MJK7GL5P.mjs.map +7 -0
- package/dist/lib/browser/{chunk-RAVNWHNE.mjs → chunk-NQFZ6XRX.mjs} +6 -5
- package/dist/lib/browser/chunk-NQFZ6XRX.mjs.map +7 -0
- package/dist/lib/browser/{chunk-7XADMUOW.mjs → chunk-Q4IMHYGH.mjs} +21 -76
- package/dist/lib/browser/chunk-Q4IMHYGH.mjs.map +7 -0
- package/dist/lib/browser/{chunk-HKX3D3ZP.mjs → chunk-R4JH4TLE.mjs} +4 -2
- package/dist/lib/browser/chunk-R4JH4TLE.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +21 -15
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/{intent-resolver-754MPV7H.mjs → intent-resolver-BWAXKT27.mjs} +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/{react-surface-4QZ6AKBF.mjs → react-surface-ILBDBZCN.mjs} +17 -9
- package/dist/lib/browser/react-surface-ILBDBZCN.mjs.map +7 -0
- package/dist/lib/browser/types/index.mjs +6 -6
- package/dist/lib/node/{AutomationPanel-LRDEDGXI.cjs → AutomationPanel-G6EDDYWW.cjs} +7 -7
- package/dist/lib/node/{AutomationPanel-LRDEDGXI.cjs.map → AutomationPanel-G6EDDYWW.cjs.map} +2 -2
- package/dist/lib/node/{ChatContainer-6LZX4K2Z.cjs → ChatContainer-EN24W3K4.cjs} +10 -10
- package/dist/lib/node/ChatContainer-EN24W3K4.cjs.map +7 -0
- package/dist/lib/node/{ai-client-SA35GN5Q.cjs → ai-client-FKLPDELV.cjs} +7 -7
- package/dist/lib/node/{app-graph-builder-ENVDOPS4.cjs → app-graph-builder-T76NYV42.cjs} +48 -14
- package/dist/lib/node/app-graph-builder-T76NYV42.cjs.map +7 -0
- package/dist/lib/node/{chunk-6VMSH4P6.cjs → chunk-CJGJXNY3.cjs} +549 -327
- package/dist/lib/node/chunk-CJGJXNY3.cjs.map +7 -0
- package/dist/lib/node/{chunk-5VF5JKUN.cjs → chunk-EQYHOTGG.cjs} +8 -5
- package/dist/lib/node/chunk-EQYHOTGG.cjs.map +7 -0
- package/dist/lib/node/chunk-GB7245FH.cjs +173 -0
- package/dist/lib/node/chunk-GB7245FH.cjs.map +7 -0
- package/dist/lib/node/{chunk-HEYQONXC.cjs → chunk-HMBKP6VG.cjs} +82 -60
- package/dist/lib/node/chunk-HMBKP6VG.cjs.map +7 -0
- package/dist/lib/node/{chunk-WWU5FVAO.cjs → chunk-QXIHYOMF.cjs} +10 -9
- package/dist/lib/node/chunk-QXIHYOMF.cjs.map +7 -0
- package/dist/lib/node/{chunk-ZS5RZ7RM.cjs → chunk-U5Z7LFWB.cjs} +6 -6
- package/dist/lib/node/index.cjs +81 -75
- package/dist/lib/node/index.cjs.map +3 -3
- package/dist/lib/node/{intent-resolver-CNVBSG4E.cjs → intent-resolver-C6OKFVEW.cjs} +8 -8
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/{react-surface-5HYLBDC3.cjs → react-surface-LWDY7SQG.cjs} +24 -18
- package/dist/lib/node/react-surface-LWDY7SQG.cjs.map +7 -0
- package/dist/lib/node/types/index.cjs +13 -13
- package/dist/lib/node/types/index.cjs.map +1 -1
- package/dist/lib/node-esm/{AutomationPanel-ZV7VEEPP.mjs → AutomationPanel-V3IWQAMO.mjs} +3 -3
- package/dist/lib/node-esm/{ChatContainer-PPVMC2FC.mjs → ChatContainer-CNTY3C2D.mjs} +5 -5
- package/dist/lib/node-esm/{ai-client-2ZA4TYFZ.mjs → ai-client-XGNA6SJ5.mjs} +3 -3
- package/dist/lib/node-esm/{app-graph-builder-IYOUCQZT.mjs → app-graph-builder-IJQEN7WT.mjs} +39 -4
- package/dist/lib/node-esm/app-graph-builder-IJQEN7WT.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-MS7OIGVR.mjs → chunk-6HLBYDUI.mjs} +6 -5
- package/dist/lib/node-esm/chunk-6HLBYDUI.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-EVTLHDM2.mjs → chunk-DNCXRGAF.mjs} +21 -76
- package/dist/lib/node-esm/chunk-DNCXRGAF.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-X3LPRWIL.mjs → chunk-EMVA6QUT.mjs} +4 -2
- package/dist/lib/node-esm/chunk-EMVA6QUT.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-ISYLEDVU.mjs → chunk-IJRTDSKN.mjs} +2 -2
- package/dist/lib/node-esm/{chunk-WISKXX7U.mjs → chunk-QP47VJT6.mjs} +525 -290
- package/dist/lib/node-esm/chunk-QP47VJT6.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-3KB5HRXA.mjs → chunk-ZLIAMW45.mjs} +68 -44
- package/dist/lib/node-esm/chunk-ZLIAMW45.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +21 -15
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/{intent-resolver-RQBXW442.mjs → intent-resolver-DCP4ZDBA.mjs} +3 -3
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/{react-surface-SS5WCRJ2.mjs → react-surface-SBDXFVIN.mjs} +17 -9
- package/dist/lib/node-esm/react-surface-SBDXFVIN.mjs.map +7 -0
- package/dist/lib/node-esm/types/index.mjs +6 -6
- package/dist/types/src/capabilities/app-graph-builder.d.ts +23 -22
- package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
- package/dist/types/src/components/AmbientChatDialog/AmbientChatDialog.d.ts +3 -0
- package/dist/types/src/components/AmbientChatDialog/AmbientChatDialog.d.ts.map +1 -0
- package/dist/types/src/components/AmbientChatDialog/index.d.ts +2 -0
- package/dist/types/src/components/AmbientChatDialog/index.d.ts.map +1 -0
- package/dist/types/src/components/Box/StatusLine.d.ts.map +1 -0
- package/dist/types/src/components/Box/StatusLine.stories.d.ts.map +1 -0
- package/dist/types/src/components/Box/Tabbed.d.ts +15 -0
- package/dist/types/src/components/Box/Tabbed.d.ts.map +1 -0
- package/dist/types/src/components/Box/Tabbed.stories.d.ts.map +1 -0
- package/dist/types/src/components/{Thread → Box}/ToggleContainer.d.ts +3 -3
- package/dist/types/src/components/Box/ToggleContainer.d.ts.map +1 -0
- package/dist/types/src/components/Box/ToggleContainer.stories.d.ts.map +1 -0
- package/dist/types/src/components/Box/index.d.ts +4 -0
- package/dist/types/src/components/Box/index.d.ts.map +1 -0
- package/dist/types/src/components/ChatContainer/ChatContainer.d.ts +0 -1
- package/dist/types/src/components/ChatContainer/ChatContainer.d.ts.map +1 -1
- package/dist/types/src/components/Prompt/Prompt.d.ts +7 -0
- package/dist/types/src/components/Prompt/Prompt.d.ts.map +1 -0
- package/dist/types/src/components/Prompt/Prompt.stories.d.ts +8 -0
- package/dist/types/src/components/Prompt/Prompt.stories.d.ts.map +1 -0
- package/dist/types/src/components/Prompt/index.d.ts +2 -0
- package/dist/types/src/components/Prompt/index.d.ts.map +1 -0
- package/dist/types/src/components/Prompt/prompt-autocomplete.d.ts +20 -0
- package/dist/types/src/components/Prompt/prompt-autocomplete.d.ts.map +1 -0
- package/dist/types/src/components/ServiceRegistry/ServiceRegistry.stories.d.ts.map +1 -1
- package/dist/types/src/components/Thread/Thread.stories.d.ts +1 -0
- package/dist/types/src/components/Thread/Thread.stories.d.ts.map +1 -1
- package/dist/types/src/components/Thread/ThreadMessage.d.ts.map +1 -1
- package/dist/types/src/components/TriggerEditor/TriggerEditor.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +1 -0
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +3 -1
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/processor.d.ts +7 -2
- package/dist/types/src/hooks/processor.d.ts.map +1 -1
- package/dist/types/src/hooks/useChatProcessor.d.ts +7 -0
- package/dist/types/src/hooks/useChatProcessor.d.ts.map +1 -0
- package/dist/types/src/hooks/useMessageQueue.d.ts +41 -0
- package/dist/types/src/hooks/useMessageQueue.d.ts.map +1 -0
- package/dist/types/src/hooks/useServices.d.ts +7 -0
- package/dist/types/src/hooks/useServices.d.ts.map +1 -0
- package/dist/types/src/meta.d.ts +1 -0
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/testing/index.d.ts +2 -1
- package/dist/types/src/testing/index.d.ts.map +1 -1
- package/dist/types/src/testing/{testing.d.ts → test-functions.d.ts} +1 -1
- package/dist/types/src/testing/test-functions.d.ts.map +1 -0
- package/dist/types/src/testing/test-services.d.ts +5 -0
- package/dist/types/src/testing/test-services.d.ts.map +1 -0
- package/dist/types/src/translations.d.ts +3 -0
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/registry.d.ts +7 -6
- package/dist/types/src/types/registry.d.ts.map +1 -1
- package/dist/types/src/types/schema.d.ts +94 -69
- package/dist/types/src/types/schema.d.ts.map +1 -1
- package/package.json +52 -50
- package/src/AutomationPlugin.tsx +7 -7
- package/src/capabilities/app-graph-builder.ts +34 -3
- package/src/capabilities/react-surface.tsx +12 -4
- package/src/components/AmbientChatDialog/AmbientChatDialog.tsx +26 -0
- package/src/components/AmbientChatDialog/index.ts +5 -0
- package/src/components/{Thread → Box}/StatusLine.tsx +1 -1
- package/src/components/{Thread → Box}/Tabbed.stories.tsx +2 -3
- package/src/components/Box/Tabbed.tsx +89 -0
- package/src/components/{Thread → Box}/ToggleContainer.stories.tsx +1 -2
- package/src/components/{Thread → Box}/ToggleContainer.tsx +28 -23
- package/src/components/Box/index.ts +7 -0
- package/src/components/ChatContainer/ChatContainer.tsx +15 -80
- package/src/components/Prompt/Prompt.stories.tsx +50 -0
- package/src/components/Prompt/Prompt.tsx +36 -0
- package/src/components/Prompt/index.ts +5 -0
- package/src/components/Prompt/prompt-autocomplete.ts +200 -0
- package/src/components/PromptEditor/PromptEditor.stories.tsx +3 -3
- package/src/components/ServiceRegistry/ServiceRegistry.stories.tsx +2 -1
- package/src/components/ServiceRegistry/ServiceRegistry.tsx +7 -7
- package/src/components/Thread/Thread.stories.tsx +8 -1
- package/src/components/Thread/Thread.tsx +2 -2
- package/src/components/Thread/ThreadMessage.tsx +58 -28
- package/src/components/TriggerEditor/TriggerEditor.tsx +8 -5
- package/src/components/index.ts +1 -0
- package/src/hooks/index.ts +3 -1
- package/src/hooks/processor.ts +16 -7
- package/src/hooks/useChatProcessor.tsx +86 -0
- package/src/hooks/useMessageQueue.ts +23 -0
- package/src/hooks/{useServiceRegistry.ts → useServices.ts} +8 -2
- package/src/meta.ts +4 -1
- package/src/testing/index.ts +2 -1
- package/src/testing/test-services.ts +131 -0
- package/src/translations.ts +1 -0
- package/src/types/registry.ts +17 -80
- package/src/types/schema.ts +20 -8
- package/dist/lib/browser/AutomationPanel-WFJZAW4F.mjs +0 -8
- package/dist/lib/browser/ChatContainer-OFCOZ5T2.mjs +0 -12
- package/dist/lib/browser/app-graph-builder-B4U34VSR.mjs.map +0 -7
- package/dist/lib/browser/chunk-5SLV6AUA.mjs.map +0 -7
- package/dist/lib/browser/chunk-7XADMUOW.mjs.map +0 -7
- package/dist/lib/browser/chunk-HKX3D3ZP.mjs.map +0 -7
- package/dist/lib/browser/chunk-IYSMXX6Q.mjs.map +0 -7
- package/dist/lib/browser/chunk-RAVNWHNE.mjs.map +0 -7
- package/dist/lib/browser/react-surface-4QZ6AKBF.mjs.map +0 -7
- package/dist/lib/node/ChatContainer-6LZX4K2Z.cjs.map +0 -7
- package/dist/lib/node/app-graph-builder-ENVDOPS4.cjs.map +0 -7
- package/dist/lib/node/chunk-5VF5JKUN.cjs.map +0 -7
- package/dist/lib/node/chunk-6VMSH4P6.cjs.map +0 -7
- package/dist/lib/node/chunk-HEYQONXC.cjs.map +0 -7
- package/dist/lib/node/chunk-LU4HQWJD.cjs +0 -226
- package/dist/lib/node/chunk-LU4HQWJD.cjs.map +0 -7
- package/dist/lib/node/chunk-WWU5FVAO.cjs.map +0 -7
- package/dist/lib/node/react-surface-5HYLBDC3.cjs.map +0 -7
- package/dist/lib/node-esm/app-graph-builder-IYOUCQZT.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-3KB5HRXA.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-EVTLHDM2.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-MS7OIGVR.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-WISKXX7U.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-X3LPRWIL.mjs.map +0 -7
- package/dist/lib/node-esm/react-surface-SS5WCRJ2.mjs.map +0 -7
- package/dist/types/src/components/Thread/ScrollContainer.d.ts +0 -15
- package/dist/types/src/components/Thread/ScrollContainer.d.ts.map +0 -1
- package/dist/types/src/components/Thread/StatusLine.d.ts.map +0 -1
- package/dist/types/src/components/Thread/StatusLine.stories.d.ts.map +0 -1
- package/dist/types/src/components/Thread/Tabbed.d.ts +0 -9
- package/dist/types/src/components/Thread/Tabbed.d.ts.map +0 -1
- package/dist/types/src/components/Thread/Tabbed.stories.d.ts.map +0 -1
- package/dist/types/src/components/Thread/ToggleContainer.d.ts.map +0 -1
- package/dist/types/src/components/Thread/ToggleContainer.stories.d.ts.map +0 -1
- package/dist/types/src/hooks/useServiceRegistry.d.ts +0 -3
- package/dist/types/src/hooks/useServiceRegistry.d.ts.map +0 -1
- package/dist/types/src/testing/testing.d.ts.map +0 -1
- package/src/components/Thread/ScrollContainer.tsx +0 -92
- package/src/components/Thread/Tabbed.tsx +0 -72
- /package/dist/lib/browser/{AutomationPanel-WFJZAW4F.mjs.map → AutomationPanel-VW2XIUPU.mjs.map} +0 -0
- /package/dist/lib/browser/{ChatContainer-OFCOZ5T2.mjs.map → ChatContainer-5TAVTN3T.mjs.map} +0 -0
- /package/dist/lib/browser/{ai-client-AARXEMMJ.mjs.map → ai-client-5CNY6JBF.mjs.map} +0 -0
- /package/dist/lib/browser/{chunk-HZ4TA7HY.mjs.map → chunk-2H2EUYXL.mjs.map} +0 -0
- /package/dist/lib/browser/{intent-resolver-754MPV7H.mjs.map → intent-resolver-BWAXKT27.mjs.map} +0 -0
- /package/dist/lib/node/{ai-client-SA35GN5Q.cjs.map → ai-client-FKLPDELV.cjs.map} +0 -0
- /package/dist/lib/node/{chunk-ZS5RZ7RM.cjs.map → chunk-U5Z7LFWB.cjs.map} +0 -0
- /package/dist/lib/node/{intent-resolver-CNVBSG4E.cjs.map → intent-resolver-C6OKFVEW.cjs.map} +0 -0
- /package/dist/lib/node-esm/{AutomationPanel-ZV7VEEPP.mjs.map → AutomationPanel-V3IWQAMO.mjs.map} +0 -0
- /package/dist/lib/node-esm/{ChatContainer-PPVMC2FC.mjs.map → ChatContainer-CNTY3C2D.mjs.map} +0 -0
- /package/dist/lib/node-esm/{ai-client-2ZA4TYFZ.mjs.map → ai-client-XGNA6SJ5.mjs.map} +0 -0
- /package/dist/lib/node-esm/{chunk-ISYLEDVU.mjs.map → chunk-IJRTDSKN.mjs.map} +0 -0
- /package/dist/lib/node-esm/{intent-resolver-RQBXW442.mjs.map → intent-resolver-DCP4ZDBA.mjs.map} +0 -0
- /package/dist/types/src/components/{Thread → Box}/StatusLine.d.ts +0 -0
- /package/dist/types/src/components/{Thread → Box}/StatusLine.stories.d.ts +0 -0
- /package/dist/types/src/components/{Thread → Box}/Tabbed.stories.d.ts +0 -0
- /package/dist/types/src/components/{Thread → Box}/ToggleContainer.stories.d.ts +0 -0
- /package/src/components/{Thread → Box}/StatusLine.stories.tsx +0 -0
- /package/src/testing/{testing.ts → test-functions.ts} +0 -0
|
@@ -71,7 +71,6 @@ const Render = ({ shrinkX, ...props }: ToggleContainerProps) => {
|
|
|
71
71
|
<ToggleContainer
|
|
72
72
|
{...props}
|
|
73
73
|
shrinkX={shrinkX}
|
|
74
|
-
toggle
|
|
75
74
|
icon={
|
|
76
75
|
running ? (
|
|
77
76
|
<Icon icon={'ph--circle-notch--regular'} classNames='text-subdued ml-2 animate-spin' size={4} />
|
|
@@ -90,7 +89,7 @@ const meta: Meta<typeof ToggleContainer> = {
|
|
|
90
89
|
title: 'plugins/plugin-automation/ToggleContainer',
|
|
91
90
|
component: ToggleContainer,
|
|
92
91
|
render: Render,
|
|
93
|
-
decorators: [withSignals, withTheme, withLayout({ fullscreen: true, classNames: 'justify-center bg-
|
|
92
|
+
decorators: [withSignals, withTheme, withLayout({ fullscreen: true, classNames: 'justify-center bg-baseSurface' })],
|
|
94
93
|
};
|
|
95
94
|
|
|
96
95
|
export default meta;
|
|
@@ -4,39 +4,38 @@
|
|
|
4
4
|
|
|
5
5
|
import React, { type JSX, type PropsWithChildren, useEffect, useState } from 'react';
|
|
6
6
|
|
|
7
|
-
import { Icon, type ThemedClassName } from '@dxos/react-ui';
|
|
7
|
+
import { Icon, useControlledState, type ThemedClassName } from '@dxos/react-ui';
|
|
8
8
|
import { mx } from '@dxos/react-ui-theme';
|
|
9
9
|
|
|
10
10
|
export type ToggleContainerProps = ThemedClassName<
|
|
11
11
|
PropsWithChildren<{
|
|
12
12
|
title?: string | JSX.Element;
|
|
13
13
|
icon?: JSX.Element;
|
|
14
|
-
|
|
15
|
-
defaultOpen?: boolean;
|
|
14
|
+
open?: boolean;
|
|
16
15
|
duration?: number;
|
|
17
16
|
/** Should shrink the width when closed. */
|
|
18
17
|
shrinkX?: boolean;
|
|
18
|
+
onChangeOpen?: (open: boolean) => void;
|
|
19
19
|
}>
|
|
20
20
|
>;
|
|
21
21
|
|
|
22
|
-
// TODO(burdon): Externalize toggle state.
|
|
23
22
|
export const ToggleContainer = ({
|
|
23
|
+
classNames,
|
|
24
24
|
title,
|
|
25
25
|
icon,
|
|
26
|
-
|
|
27
|
-
defaultOpen,
|
|
26
|
+
open: _open,
|
|
28
27
|
duration = 400,
|
|
29
28
|
shrinkX = false,
|
|
30
29
|
children,
|
|
31
|
-
|
|
30
|
+
onChangeOpen,
|
|
32
31
|
}: ToggleContainerProps) => {
|
|
33
|
-
const [
|
|
34
|
-
const [expandX, setExpandX] = useState(shrinkX ?
|
|
35
|
-
const [expandY, setExpandY] = useState(
|
|
32
|
+
const [open, setOpen] = useControlledState(_open);
|
|
33
|
+
const [expandX, setExpandX] = useState(shrinkX ? open : true);
|
|
34
|
+
const [expandY, setExpandY] = useState(open);
|
|
36
35
|
|
|
37
36
|
useEffect(() => {
|
|
38
37
|
let t: NodeJS.Timeout;
|
|
39
|
-
if (
|
|
38
|
+
if (open) {
|
|
40
39
|
if (shrinkX) {
|
|
41
40
|
setExpandX(true);
|
|
42
41
|
}
|
|
@@ -56,25 +55,31 @@ export const ToggleContainer = ({
|
|
|
56
55
|
}
|
|
57
56
|
|
|
58
57
|
return () => clearTimeout(t);
|
|
59
|
-
}, [
|
|
58
|
+
}, [open]);
|
|
59
|
+
|
|
60
|
+
const handleToggle = () => {
|
|
61
|
+
if (onChangeOpen) {
|
|
62
|
+
onChangeOpen(!open);
|
|
63
|
+
} else {
|
|
64
|
+
setOpen((open) => !open);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
60
67
|
|
|
61
68
|
return (
|
|
62
69
|
<div className={mx('overflow-hidden', classNames)}>
|
|
63
70
|
{title && (
|
|
64
71
|
<div
|
|
65
72
|
className='flex gap-1 py-1 items-center text-sm text-subdued cursor-pointer select-none'
|
|
66
|
-
onClick={
|
|
73
|
+
onClick={handleToggle}
|
|
67
74
|
>
|
|
68
|
-
|
|
69
|
-
<
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
</div>
|
|
77
|
-
)}
|
|
75
|
+
<div className='flex w-[24px] h-[24px] items-center justify-center'>
|
|
76
|
+
<Icon
|
|
77
|
+
size={4}
|
|
78
|
+
icon={'ph--caret-right--regular'}
|
|
79
|
+
style={{ transitionDuration: `${shrinkX ? duration * 2 : duration}ms` }}
|
|
80
|
+
classNames={['transition transition-transform ease-in-out', open ? 'rotate-90' : 'transform-none']}
|
|
81
|
+
/>
|
|
82
|
+
</div>
|
|
78
83
|
<div className='flex-1 pis-1 pie-1 truncate'>{title}</div>
|
|
79
84
|
{icon}
|
|
80
85
|
</div>
|
|
@@ -2,98 +2,28 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import React, { useCallback
|
|
5
|
+
import React, { useCallback } from 'react';
|
|
6
6
|
|
|
7
|
-
import { Capabilities, useCapabilities, useCapability, useIntentDispatcher } from '@dxos/app-framework';
|
|
8
|
-
import { createSystemPrompt, type Message, type Tool } from '@dxos/artifact';
|
|
9
|
-
import { FunctionType } from '@dxos/functions';
|
|
10
7
|
import { invariant } from '@dxos/invariant';
|
|
11
|
-
import { DXN, QueueSubspaceTags } from '@dxos/keys';
|
|
12
|
-
import { useConfig } from '@dxos/react-client';
|
|
13
|
-
import { Filter, getSpace, useQuery } from '@dxos/react-client/echo';
|
|
14
|
-
import { useEdgeClient, useQueue } from '@dxos/react-edge-client';
|
|
15
8
|
import { StackItem } from '@dxos/react-ui-stack';
|
|
16
|
-
import { isNotNullOrUndefined } from '@dxos/util';
|
|
17
9
|
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import { covertFunctionToTool, createToolsFromService } from '../../tools';
|
|
21
|
-
import { MockServiceRegistry, type AIChatType } from '../../types';
|
|
10
|
+
import { useChatProcessor, useMessageQueue } from '../../hooks';
|
|
11
|
+
import { type AIChatType } from '../../types';
|
|
22
12
|
import { Thread } from '../Thread';
|
|
23
13
|
|
|
24
14
|
export const ChatContainer = ({ chat, role }: { chat: AIChatType; role: string }) => {
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
const aiClient = useCapability(AutomationCapabilities.AiClient);
|
|
28
|
-
|
|
29
|
-
const artifactDefinitions = useCapabilities(Capabilities.ArtifactDefinition);
|
|
30
|
-
const globalTools = useCapabilities(Capabilities.Tools);
|
|
31
|
-
const functions = useQuery(space, Filter.schema(FunctionType));
|
|
32
|
-
const serviceRegistry = useMemo(() => new MockServiceRegistry(), []);
|
|
33
|
-
|
|
34
|
-
const [serviceTools, setServiceTools] = useState<Tool[]>([]);
|
|
35
|
-
useEffect(() => {
|
|
36
|
-
queueMicrotask(async () => {
|
|
37
|
-
const services = await serviceRegistry.queryServices({});
|
|
38
|
-
const tools = await Promise.all(services.map((service) => createToolsFromService(service)));
|
|
39
|
-
setServiceTools(tools.flat());
|
|
40
|
-
});
|
|
41
|
-
}, []);
|
|
42
|
-
|
|
43
|
-
const tools = useMemo(
|
|
44
|
-
() => [
|
|
45
|
-
...globalTools.flat(),
|
|
46
|
-
...artifactDefinitions.flatMap((definition) => definition.tools),
|
|
47
|
-
...functions
|
|
48
|
-
.map((fn) => covertFunctionToTool(fn, config.values.runtime?.services?.edge?.url ?? '', space?.id))
|
|
49
|
-
.filter(isNotNullOrUndefined),
|
|
50
|
-
...serviceTools,
|
|
51
|
-
],
|
|
52
|
-
[globalTools, artifactDefinitions, functions, serviceTools, space?.id],
|
|
53
|
-
);
|
|
54
|
-
const systemPrompt = useMemo(
|
|
55
|
-
() => createSystemPrompt({ artifacts: artifactDefinitions.map((definition) => definition.instructions) }),
|
|
56
|
-
[artifactDefinitions],
|
|
57
|
-
);
|
|
58
|
-
|
|
59
|
-
// TODO(burdon): Create hook.
|
|
60
|
-
// TODO(wittjosiah): Should these be created in the component?
|
|
61
|
-
// TODO(zan): Combine with ai service client?
|
|
62
|
-
const { dispatchPromise: dispatch } = useIntentDispatcher();
|
|
63
|
-
const processor = useMemo(
|
|
64
|
-
() =>
|
|
65
|
-
new ChatProcessor(
|
|
66
|
-
aiClient,
|
|
67
|
-
tools,
|
|
68
|
-
{
|
|
69
|
-
space,
|
|
70
|
-
dispatch,
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
model: '@anthropic/claude-3-5-sonnet-20241022',
|
|
74
|
-
systemPrompt,
|
|
75
|
-
},
|
|
76
|
-
),
|
|
77
|
-
[aiClient, tools, space, dispatch, systemPrompt],
|
|
78
|
-
);
|
|
79
|
-
|
|
80
|
-
// TODO(wittjosiah): Remove transformation.
|
|
81
|
-
const queueDxn = useMemo(
|
|
82
|
-
() => new DXN(DXN.kind.QUEUE, [QueueSubspaceTags.DATA, space!.id, chat.queue.dxn.parts.at(-1)!]),
|
|
83
|
-
[chat.queue.dxn],
|
|
84
|
-
);
|
|
85
|
-
const edgeClient = useEdgeClient();
|
|
86
|
-
const messageQueue = useQueue<Message>(edgeClient, queueDxn);
|
|
15
|
+
const processor = useChatProcessor(chat);
|
|
16
|
+
const messageQueue = useMessageQueue(chat);
|
|
87
17
|
const messages = [...(messageQueue?.items ?? []), ...processor.messages.value];
|
|
88
18
|
|
|
89
19
|
const handleSubmit = useCallback(
|
|
90
|
-
async (
|
|
20
|
+
async (text: string) => {
|
|
91
21
|
if (processor.streaming.value) {
|
|
92
22
|
await processor.cancel();
|
|
93
23
|
}
|
|
94
24
|
|
|
95
25
|
invariant(messageQueue);
|
|
96
|
-
await processor.request(
|
|
26
|
+
await processor.request(text, {
|
|
97
27
|
history: messageQueue.items,
|
|
98
28
|
onComplete: (messages) => messageQueue.append(messages),
|
|
99
29
|
});
|
|
@@ -109,9 +39,14 @@ export const ChatContainer = ({ chat, role }: { chat: AIChatType; role: string }
|
|
|
109
39
|
|
|
110
40
|
return (
|
|
111
41
|
<StackItem.Content toolbar={false} role={role}>
|
|
112
|
-
<Thread
|
|
42
|
+
<Thread
|
|
43
|
+
messages={messages}
|
|
44
|
+
streaming={processor.streaming.value}
|
|
45
|
+
collapse={true}
|
|
46
|
+
onSubmit={handleSubmit}
|
|
47
|
+
onSuggest={handleSubmit}
|
|
48
|
+
onStop={handleStop}
|
|
49
|
+
/>
|
|
113
50
|
</StackItem.Content>
|
|
114
51
|
);
|
|
115
52
|
};
|
|
116
|
-
|
|
117
|
-
export default ChatContainer;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import '@dxos-theme';
|
|
6
|
+
|
|
7
|
+
import { type StoryObj, type Meta } from '@storybook/react';
|
|
8
|
+
|
|
9
|
+
import { withTheme } from '@dxos/storybook-utils';
|
|
10
|
+
|
|
11
|
+
import { Prompt } from './Prompt';
|
|
12
|
+
|
|
13
|
+
const meta: Meta<typeof Prompt> = {
|
|
14
|
+
title: 'plugins/plugin-automation/Prompt',
|
|
15
|
+
component: Prompt,
|
|
16
|
+
decorators: [withTheme],
|
|
17
|
+
parameters: {
|
|
18
|
+
layout: 'centered',
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default meta;
|
|
23
|
+
|
|
24
|
+
type Story = StoryObj<typeof Prompt>;
|
|
25
|
+
|
|
26
|
+
export const Default: Story = {
|
|
27
|
+
args: {
|
|
28
|
+
classNames: 'w-96 p-4 rounded outline outline-gray-200',
|
|
29
|
+
autoFocus: true,
|
|
30
|
+
onEnter: (text) => {
|
|
31
|
+
console.log('onEnter', text);
|
|
32
|
+
},
|
|
33
|
+
onSuggest: (text) => {
|
|
34
|
+
const trimmed = text.trim().toLowerCase();
|
|
35
|
+
if (trimmed.length < 2) {
|
|
36
|
+
return [];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const suggestions = [
|
|
40
|
+
'Create a CRM',
|
|
41
|
+
'Create a new project',
|
|
42
|
+
'Find flights to Tokyo',
|
|
43
|
+
"Let's play chess",
|
|
44
|
+
'Show me Paris on a map',
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
return suggestions.filter((s) => s.toLowerCase().startsWith(text));
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import React from 'react';
|
|
6
|
+
|
|
7
|
+
import { type ThemedClassName, useThemeContext } from '@dxos/react-ui';
|
|
8
|
+
import {
|
|
9
|
+
createBasicExtensions,
|
|
10
|
+
createThemeExtensions,
|
|
11
|
+
useTextEditor,
|
|
12
|
+
type UseTextEditorProps,
|
|
13
|
+
} from '@dxos/react-ui-editor';
|
|
14
|
+
import { mx } from '@dxos/react-ui-theme';
|
|
15
|
+
|
|
16
|
+
import { createAutocompleteExtension, type AutocompleteOptions } from './prompt-autocomplete';
|
|
17
|
+
|
|
18
|
+
export type PromptProps = ThemedClassName<AutocompleteOptions & Pick<UseTextEditorProps, 'autoFocus'>>;
|
|
19
|
+
|
|
20
|
+
export const Prompt = ({ classNames, autoFocus, onEnter, onSuggest }: PromptProps) => {
|
|
21
|
+
const { themeMode } = useThemeContext();
|
|
22
|
+
const { parentRef } = useTextEditor({
|
|
23
|
+
autoFocus,
|
|
24
|
+
extensions: [
|
|
25
|
+
createBasicExtensions({
|
|
26
|
+
bracketMatching: false,
|
|
27
|
+
lineWrapping: false,
|
|
28
|
+
placeholder: 'Ask a question...',
|
|
29
|
+
}),
|
|
30
|
+
createThemeExtensions({ themeMode }),
|
|
31
|
+
createAutocompleteExtension({ onEnter, onSuggest }),
|
|
32
|
+
],
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
return <div ref={parentRef} className={mx(classNames)} />;
|
|
36
|
+
};
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { Prec, type Extension } from '@codemirror/state';
|
|
6
|
+
import {
|
|
7
|
+
EditorView,
|
|
8
|
+
Decoration,
|
|
9
|
+
ViewPlugin,
|
|
10
|
+
keymap,
|
|
11
|
+
type DecorationSet,
|
|
12
|
+
type ViewUpdate,
|
|
13
|
+
WidgetType,
|
|
14
|
+
} from '@codemirror/view';
|
|
15
|
+
|
|
16
|
+
export type AutocompleteOptions = {
|
|
17
|
+
/**
|
|
18
|
+
* Callback triggered when Enter is pressed.
|
|
19
|
+
* @param text The current text in the editor
|
|
20
|
+
*/
|
|
21
|
+
onEnter?: (text: string) => void;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Function that returns a list of suggestions based on the current text.
|
|
25
|
+
* @param text The current text before the cursor
|
|
26
|
+
* @returns Array of suggestion strings
|
|
27
|
+
*/
|
|
28
|
+
onSuggest: (text: string) => string[];
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
class InlineSuggestionWidget extends WidgetType {
|
|
32
|
+
constructor(private suffix: string) {
|
|
33
|
+
super();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
override toDOM() {
|
|
37
|
+
const span = document.createElement('span');
|
|
38
|
+
span.textContent = this.suffix;
|
|
39
|
+
span.className = 'cm-inline-suggestion';
|
|
40
|
+
return span;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
override eq(other: InlineSuggestionWidget) {
|
|
44
|
+
return other.suffix === this.suffix;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Creates an autocomplete extension that shows inline suggestions.
|
|
50
|
+
* Pressing Tab will complete the suggestion.
|
|
51
|
+
*/
|
|
52
|
+
export const createAutocompleteExtension = ({ onEnter, onSuggest }: AutocompleteOptions): Extension => {
|
|
53
|
+
const suggestionPlugin = ViewPlugin.fromClass(
|
|
54
|
+
class {
|
|
55
|
+
_decorations: DecorationSet;
|
|
56
|
+
_currentSuggestion: string | null = null;
|
|
57
|
+
|
|
58
|
+
constructor(view: EditorView) {
|
|
59
|
+
this._decorations = this.computeDecorations(view);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
update(update: ViewUpdate) {
|
|
63
|
+
if (update.docChanged || update.selectionSet) {
|
|
64
|
+
this._decorations = this.computeDecorations(update.view);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
private computeDecorations(view: EditorView): DecorationSet {
|
|
69
|
+
const text = view.state.doc.toString();
|
|
70
|
+
const suggestions = onSuggest(text);
|
|
71
|
+
if (!suggestions.length) {
|
|
72
|
+
this._currentSuggestion = null;
|
|
73
|
+
return Decoration.none;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Get the first suggestion.
|
|
77
|
+
this._currentSuggestion = suggestions[0];
|
|
78
|
+
const suffix = this._currentSuggestion.slice(text.length);
|
|
79
|
+
if (!suffix) {
|
|
80
|
+
return Decoration.none;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Always show ghost text at the end of the document.
|
|
84
|
+
return Decoration.set([
|
|
85
|
+
Decoration.widget({
|
|
86
|
+
widget: new InlineSuggestionWidget(suffix),
|
|
87
|
+
side: 1,
|
|
88
|
+
}).range(view.state.doc.length),
|
|
89
|
+
]);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
completeSuggestion(view: EditorView): boolean {
|
|
93
|
+
if (!this._currentSuggestion) {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const text = view.state.doc.toString();
|
|
98
|
+
const suffix = this._currentSuggestion.slice(text.length);
|
|
99
|
+
if (!suffix) {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
view.dispatch({
|
|
104
|
+
changes: {
|
|
105
|
+
from: view.state.doc.length,
|
|
106
|
+
insert: suffix,
|
|
107
|
+
},
|
|
108
|
+
selection: {
|
|
109
|
+
anchor: view.state.doc.length + suffix.length,
|
|
110
|
+
},
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
return true;
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
decorations: (v) => v._decorations,
|
|
118
|
+
},
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
return [
|
|
122
|
+
suggestionPlugin,
|
|
123
|
+
EditorView.theme({
|
|
124
|
+
'.cm-inline-suggestion': {
|
|
125
|
+
opacity: 0.4,
|
|
126
|
+
},
|
|
127
|
+
}),
|
|
128
|
+
|
|
129
|
+
// Accept the current suggestion.
|
|
130
|
+
Prec.highest(
|
|
131
|
+
keymap.of([
|
|
132
|
+
{
|
|
133
|
+
key: 'Tab',
|
|
134
|
+
run: (view) => {
|
|
135
|
+
const plugin = view.plugin(suggestionPlugin);
|
|
136
|
+
return plugin?.completeSuggestion(view) ?? false;
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
key: 'ArrowRight',
|
|
141
|
+
run: (view) => {
|
|
142
|
+
// Only complete if cursor is at the end
|
|
143
|
+
if (view.state.selection.main.head !== view.state.doc.length) {
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const plugin = view.plugin(suggestionPlugin);
|
|
148
|
+
return plugin?.completeSuggestion(view) ?? false;
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
key: 'Enter',
|
|
153
|
+
preventDefault: true,
|
|
154
|
+
run: (view) => {
|
|
155
|
+
const text = view.state.doc.toString();
|
|
156
|
+
if (onEnter) {
|
|
157
|
+
onEnter(text);
|
|
158
|
+
// Clear the document after calling onEnter
|
|
159
|
+
view.dispatch({
|
|
160
|
+
changes: {
|
|
161
|
+
from: 0,
|
|
162
|
+
to: view.state.doc.length,
|
|
163
|
+
insert: '',
|
|
164
|
+
},
|
|
165
|
+
});
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
return false;
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
key: 'Shift-Enter',
|
|
173
|
+
run: (view) => {
|
|
174
|
+
view.dispatch({
|
|
175
|
+
changes: {
|
|
176
|
+
from: view.state.selection.main.head,
|
|
177
|
+
insert: '\n',
|
|
178
|
+
},
|
|
179
|
+
});
|
|
180
|
+
return true;
|
|
181
|
+
},
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
key: 'Escape',
|
|
185
|
+
run: (view) => {
|
|
186
|
+
// Clear the entire document.
|
|
187
|
+
view.dispatch({
|
|
188
|
+
changes: {
|
|
189
|
+
from: 0,
|
|
190
|
+
to: view.state.doc.length,
|
|
191
|
+
insert: '',
|
|
192
|
+
},
|
|
193
|
+
});
|
|
194
|
+
return true;
|
|
195
|
+
},
|
|
196
|
+
},
|
|
197
|
+
]),
|
|
198
|
+
),
|
|
199
|
+
];
|
|
200
|
+
};
|
|
@@ -28,7 +28,7 @@ const template = [
|
|
|
28
28
|
'{input}',
|
|
29
29
|
].join('\n');
|
|
30
30
|
|
|
31
|
-
const
|
|
31
|
+
const Render = () => {
|
|
32
32
|
const client = useClient();
|
|
33
33
|
const [chain] = useState(() => {
|
|
34
34
|
const space = client.spaces.default;
|
|
@@ -49,8 +49,8 @@ const DefaultStory = () => {
|
|
|
49
49
|
export const Default = {};
|
|
50
50
|
|
|
51
51
|
const meta: Meta = {
|
|
52
|
-
title: 'plugins/plugin-automation/
|
|
53
|
-
render:
|
|
52
|
+
title: 'plugins/plugin-automation/PromptEditor',
|
|
53
|
+
render: Render,
|
|
54
54
|
decorators: [
|
|
55
55
|
withClientProvider({ createIdentity: true, createSpace: true, types: [ChainType, ChainPromptType] }),
|
|
56
56
|
withLayout({ fullscreen: true, classNames: 'flex justify-center m-2' }),
|
|
@@ -12,6 +12,7 @@ import { withClientProvider } from '@dxos/react-client/testing';
|
|
|
12
12
|
import { withLayout, withTheme } from '@dxos/storybook-utils';
|
|
13
13
|
|
|
14
14
|
import { ServiceRegistry } from './ServiceRegistry';
|
|
15
|
+
import { ServiceType } from '../../types';
|
|
15
16
|
|
|
16
17
|
const meta: Meta<typeof ServiceRegistry> = {
|
|
17
18
|
title: 'plugins/plugin-automation/ServiceRegistry',
|
|
@@ -32,7 +33,7 @@ const meta: Meta<typeof ServiceRegistry> = {
|
|
|
32
33
|
withClientProvider({
|
|
33
34
|
createIdentity: true,
|
|
34
35
|
createSpace: true,
|
|
35
|
-
|
|
36
|
+
types: [ServiceType],
|
|
36
37
|
}),
|
|
37
38
|
withLayout({ fullscreen: true, tooltips: true, classNames: 'flex justify-center' }),
|
|
38
39
|
withTheme,
|
|
@@ -8,12 +8,12 @@ import { Filter, type Space } from '@dxos/client/echo';
|
|
|
8
8
|
import { useQuery } from '@dxos/react-client/echo';
|
|
9
9
|
import { Icon, Input, List, ListItem } from '@dxos/react-ui';
|
|
10
10
|
|
|
11
|
-
import {
|
|
12
|
-
import { ServiceType } from '../../types';
|
|
11
|
+
import { useServices } from '../../hooks';
|
|
12
|
+
import { categoryIcons, ServiceType } from '../../types';
|
|
13
13
|
|
|
14
|
-
// TODO(burdon): Option to show all/enabled.
|
|
14
|
+
// TODO(burdon): Option to show all/enabled/filter.
|
|
15
15
|
export const ServiceRegistry = ({ space }: { space: Space }) => {
|
|
16
|
-
const matchingServices =
|
|
16
|
+
const matchingServices = useServices(space);
|
|
17
17
|
const enabledServices = useQuery(space, Filter.schema(ServiceType));
|
|
18
18
|
|
|
19
19
|
// Join matching services with enabled services.
|
|
@@ -31,7 +31,7 @@ export const ServiceRegistry = ({ space }: { space: Space }) => {
|
|
|
31
31
|
};
|
|
32
32
|
|
|
33
33
|
return (
|
|
34
|
-
<List classNames='h-full grid auto-rows-[5rem] gap-2 p-2 pis-2 pie-
|
|
34
|
+
<List classNames='h-full grid auto-rows-[5rem] gap-2 p-2 pis-2 pie-2 overflow-y-auto scrollbar-thin'>
|
|
35
35
|
{services.map((service) => (
|
|
36
36
|
<ServiceItem
|
|
37
37
|
key={service.serviceId}
|
|
@@ -57,7 +57,7 @@ const ServiceItem = ({
|
|
|
57
57
|
<ListItem.Root classNames='flex flex-col gap-1 p-1 overflow-hidden rounded-md border border-separator'>
|
|
58
58
|
<div className='grid grid-cols-[40px_1fr_40px]'>
|
|
59
59
|
<div className='flex gow justify-center items-center'>
|
|
60
|
-
<Icon icon='ph--placeholder--regular' size={6} />
|
|
60
|
+
<Icon icon={categoryIcons[service.category ?? 'default'] ?? 'ph--placeholder--regular'} size={6} />
|
|
61
61
|
</div>
|
|
62
62
|
<div className='grow items-center truncate mie-2'>{service.name}</div>
|
|
63
63
|
<div className='flex gow justify-center items-center'>
|
|
@@ -68,7 +68,7 @@ const ServiceItem = ({
|
|
|
68
68
|
</div>
|
|
69
69
|
<div className='grid grid-cols-[40px_1fr]'>
|
|
70
70
|
<div />
|
|
71
|
-
<div className='text-sm text-subdued line-clamp-2'>{service.description}</div>
|
|
71
|
+
<div className='text-sm text-subdued line-clamp-2 mie-1'>{service.description}</div>
|
|
72
72
|
</div>
|
|
73
73
|
</ListItem.Root>
|
|
74
74
|
);
|
|
@@ -159,7 +159,7 @@ const TEST_MESSAGES: Message[] = [
|
|
|
159
159
|
|
|
160
160
|
export const Default: Story = {
|
|
161
161
|
args: {
|
|
162
|
-
debug: true,
|
|
162
|
+
// debug: true,
|
|
163
163
|
messages: TEST_MESSAGES,
|
|
164
164
|
},
|
|
165
165
|
};
|
|
@@ -170,6 +170,13 @@ export const Input: Story = {
|
|
|
170
170
|
},
|
|
171
171
|
};
|
|
172
172
|
|
|
173
|
+
export const Collapse: Story = {
|
|
174
|
+
args: {
|
|
175
|
+
collapse: true,
|
|
176
|
+
messages: TEST_MESSAGES,
|
|
177
|
+
},
|
|
178
|
+
};
|
|
179
|
+
|
|
173
180
|
export const Incremental: Story = {
|
|
174
181
|
render: () => {
|
|
175
182
|
const [messages, setMessages] = useState<Message[]>([]);
|
|
@@ -6,10 +6,10 @@ import React, { type KeyboardEventHandler, useCallback, useMemo, useRef, useStat
|
|
|
6
6
|
|
|
7
7
|
import { type Message } from '@dxos/artifact';
|
|
8
8
|
import { IconButton, Input, useTranslation } from '@dxos/react-ui';
|
|
9
|
+
import { ScrollContainer, type ScrollController } from '@dxos/react-ui-components';
|
|
9
10
|
import { Spinner } from '@dxos/react-ui-sfx';
|
|
10
11
|
import { mx } from '@dxos/react-ui-theme';
|
|
11
12
|
|
|
12
|
-
import { ScrollContainer, type ScrollController } from './ScrollContainer';
|
|
13
13
|
import { ThreadMessage, type ThreadMessageProps } from './ThreadMessage';
|
|
14
14
|
import { AUTOMATION_PLUGIN } from '../../meta';
|
|
15
15
|
|
|
@@ -130,7 +130,7 @@ export const Thread = ({
|
|
|
130
130
|
<Input.Root>
|
|
131
131
|
<Input.TextInput
|
|
132
132
|
autoFocus
|
|
133
|
-
classNames='px-2
|
|
133
|
+
classNames='px-2 baseSurface rounded'
|
|
134
134
|
placeholder={t('chat input placeholder')}
|
|
135
135
|
value={text}
|
|
136
136
|
onChange={(ev) => setText(ev.target.value)}
|