@dxos/plugin-automation 0.7.4 → 0.7.5-labs.a279d8c
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/{AssistantPanel-N3QSALKY.mjs → AssistantPanel-KO6DZBTU.mjs} +10 -11
- package/dist/lib/browser/AssistantPanel-KO6DZBTU.mjs.map +7 -0
- package/dist/lib/browser/AutomationPanel-BMLM533Z.mjs +131 -0
- package/dist/lib/browser/AutomationPanel-BMLM533Z.mjs.map +7 -0
- package/dist/lib/browser/ChatContainer-SIAJFRFF.mjs +300 -0
- package/dist/lib/browser/ChatContainer-SIAJFRFF.mjs.map +7 -0
- package/dist/lib/browser/ai-client-6CRYUC6D.mjs +22 -0
- package/dist/lib/browser/ai-client-6CRYUC6D.mjs.map +7 -0
- package/dist/lib/browser/app-graph-builder-IJTTULDP.mjs +131 -0
- package/dist/lib/browser/app-graph-builder-IJTTULDP.mjs.map +7 -0
- package/dist/lib/browser/{chunk-7KB4UMXO.mjs → chunk-C3VRGDR6.mjs} +30 -4
- package/dist/lib/browser/chunk-C3VRGDR6.mjs.map +7 -0
- package/dist/lib/browser/chunk-EKJVAFT2.mjs +226 -0
- package/dist/lib/browser/chunk-EKJVAFT2.mjs.map +7 -0
- package/dist/lib/browser/{chunk-X5KMOH3I.mjs → chunk-HKX3D3ZP.mjs} +3 -3
- package/dist/lib/browser/chunk-HKX3D3ZP.mjs.map +7 -0
- package/dist/lib/browser/chunk-HZ4TA7HY.mjs +15 -0
- package/dist/lib/browser/chunk-HZ4TA7HY.mjs.map +7 -0
- package/dist/lib/browser/chunk-JSNPW6JF.mjs +14 -0
- package/dist/lib/browser/chunk-JSNPW6JF.mjs.map +7 -0
- package/dist/lib/browser/chunk-KPSDH6XZ.mjs +118 -0
- package/dist/lib/browser/chunk-KPSDH6XZ.mjs.map +7 -0
- package/dist/lib/browser/chunk-YZF3SDZL.mjs +139 -0
- package/dist/lib/browser/chunk-YZF3SDZL.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +143 -249
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/intent-resolver-AHDQ3KQP.mjs +24 -0
- package/dist/lib/browser/intent-resolver-AHDQ3KQP.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/react-surface-IGMBLSV7.mjs +49 -0
- package/dist/lib/browser/react-surface-IGMBLSV7.mjs.map +7 -0
- package/dist/lib/browser/types/index.mjs +6 -3
- package/dist/lib/node/{AssistantPanel-RIA4TI3B.cjs → AssistantPanel-PPFS2HKK.cjs} +20 -21
- package/dist/lib/node/AssistantPanel-PPFS2HKK.cjs.map +7 -0
- package/dist/lib/node/{AutomationPanel-HZS5WKI5.cjs → AutomationPanel-RXJDVLCF.cjs} +52 -72
- package/dist/lib/node/AutomationPanel-RXJDVLCF.cjs.map +7 -0
- package/dist/lib/node/ChatContainer-GS2SC5OG.cjs +318 -0
- package/dist/lib/node/ChatContainer-GS2SC5OG.cjs.map +7 -0
- package/dist/lib/node/ai-client-A3RRU55B.cjs +38 -0
- package/dist/lib/node/ai-client-A3RRU55B.cjs.map +7 -0
- package/dist/lib/node/app-graph-builder-MF5M4QRS.cjs +147 -0
- package/dist/lib/node/app-graph-builder-MF5M4QRS.cjs.map +7 -0
- package/dist/lib/node/{chunk-DTJ7XVO2.cjs → chunk-5VF5JKUN.cjs} +7 -7
- package/dist/lib/node/chunk-5VF5JKUN.cjs.map +7 -0
- package/dist/lib/node/{chunk-CUCUWUAF.cjs → chunk-BUQOZA4N.cjs} +32 -8
- package/dist/lib/node/chunk-BUQOZA4N.cjs.map +7 -0
- package/dist/lib/node/chunk-DNLBVFR7.cjs +147 -0
- package/dist/lib/node/chunk-DNLBVFR7.cjs.map +7 -0
- package/dist/lib/node/chunk-TWDGP26W.cjs +172 -0
- package/dist/lib/node/chunk-TWDGP26W.cjs.map +7 -0
- package/dist/lib/node/chunk-VEGLN4YN.cjs +250 -0
- package/dist/lib/node/chunk-VEGLN4YN.cjs.map +7 -0
- package/dist/lib/node/chunk-Z2YFE5SJ.cjs +49 -0
- package/dist/lib/node/chunk-Z2YFE5SJ.cjs.map +7 -0
- package/dist/lib/node/{meta.cjs → chunk-ZS5RZ7RM.cjs} +12 -8
- package/dist/lib/node/chunk-ZS5RZ7RM.cjs.map +7 -0
- package/dist/lib/node/index.cjs +159 -279
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/intent-resolver-TBHYXBDI.cjs +39 -0
- package/dist/lib/node/intent-resolver-TBHYXBDI.cjs.map +7 -0
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/react-surface-BVUZMKYS.cjs +69 -0
- package/dist/lib/node/react-surface-BVUZMKYS.cjs.map +7 -0
- package/dist/lib/node/types/index.cjs +10 -7
- package/dist/lib/node/types/index.cjs.map +2 -2
- package/dist/lib/node-esm/{AssistantPanel-72YH43CH.mjs → AssistantPanel-XSSKKCJY.mjs} +10 -11
- package/dist/lib/node-esm/AssistantPanel-XSSKKCJY.mjs.map +7 -0
- package/dist/lib/node-esm/AutomationPanel-GQZZ4UBI.mjs +132 -0
- package/dist/lib/node-esm/AutomationPanel-GQZZ4UBI.mjs.map +7 -0
- package/dist/lib/node-esm/ChatContainer-57ILGC3R.mjs +301 -0
- package/dist/lib/node-esm/ChatContainer-57ILGC3R.mjs.map +7 -0
- package/dist/lib/node-esm/ai-client-2GBZRHBA.mjs +23 -0
- package/dist/lib/node-esm/ai-client-2GBZRHBA.mjs.map +7 -0
- package/dist/lib/node-esm/app-graph-builder-5N7OK23B.mjs +132 -0
- package/dist/lib/node-esm/app-graph-builder-5N7OK23B.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-5QUXIXNB.mjs +227 -0
- package/dist/lib/node-esm/chunk-5QUXIXNB.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-ICHNUP5M.mjs +119 -0
- package/dist/lib/node-esm/chunk-ICHNUP5M.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-ISYLEDVU.mjs +16 -0
- package/dist/lib/node-esm/chunk-ISYLEDVU.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-23LY7DYS.mjs → chunk-JCYVS5GG.mjs} +29 -4
- package/dist/lib/node-esm/chunk-JCYVS5GG.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-L2B6VGMG.mjs +16 -0
- package/dist/lib/node-esm/chunk-L2B6VGMG.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-U7HXYMPZ.mjs +141 -0
- package/dist/lib/node-esm/chunk-U7HXYMPZ.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-HNOBZHWK.mjs → chunk-X3LPRWIL.mjs} +3 -3
- package/dist/lib/node-esm/chunk-X3LPRWIL.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +143 -249
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/intent-resolver-DPJJHFGK.mjs +25 -0
- package/dist/lib/node-esm/intent-resolver-DPJJHFGK.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/react-surface-77S6XJOM.mjs +50 -0
- package/dist/lib/node-esm/react-surface-77S6XJOM.mjs.map +7 -0
- package/dist/lib/node-esm/types/index.mjs +6 -3
- package/dist/types/src/AutomationPlugin.d.ts +1 -3
- package/dist/types/src/AutomationPlugin.d.ts.map +1 -1
- package/dist/types/src/artifacts.stories.d.ts +30 -0
- package/dist/types/src/artifacts.stories.d.ts.map +1 -0
- package/dist/types/src/capabilities/ai-client.d.ts +5 -0
- package/dist/types/src/capabilities/ai-client.d.ts.map +1 -0
- package/dist/types/src/capabilities/app-graph-builder.d.ts +180 -0
- package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -0
- package/dist/types/src/capabilities/capabilities.d.ts +5 -0
- package/dist/types/src/capabilities/capabilities.d.ts.map +1 -0
- package/dist/types/src/capabilities/index.d.ts +182 -0
- package/dist/types/src/capabilities/index.d.ts.map +1 -0
- package/dist/types/src/capabilities/intent-resolver.d.ts +4 -0
- package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -0
- package/dist/types/src/capabilities/react-surface.d.ts +4 -0
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
- package/dist/types/src/components/AssistantPanel/AssistantPanel.d.ts.map +1 -1
- package/dist/types/src/components/AutomationPanel/AutomationPanel.d.ts +1 -1
- package/dist/types/src/components/AutomationPanel/AutomationPanel.d.ts.map +1 -1
- package/dist/types/src/components/AutomationPanel/AutomationPanel.stories.d.ts.map +1 -1
- package/dist/types/src/components/ChatContainer.d.ts +8 -0
- package/dist/types/src/components/ChatContainer.d.ts.map +1 -0
- package/dist/types/src/components/Thread/Thread.d.ts +14 -0
- package/dist/types/src/components/Thread/Thread.d.ts.map +1 -0
- package/dist/types/src/components/Thread/Thread.stories.d.ts +12 -0
- package/dist/types/src/components/Thread/Thread.stories.d.ts.map +1 -0
- package/dist/types/src/components/Thread/index.d.ts +2 -0
- package/dist/types/src/components/Thread/index.d.ts.map +1 -0
- package/dist/types/src/components/TriggerEditor/TriggerEditor.d.ts +1 -2
- package/dist/types/src/components/TriggerEditor/TriggerEditor.d.ts.map +1 -1
- package/dist/types/src/components/TriggerEditor/TriggerEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +8 -1
- 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.map +1 -1
- package/dist/types/src/hooks/processor.d.ts +46 -0
- package/dist/types/src/hooks/processor.d.ts.map +1 -0
- package/dist/types/src/hooks/processor.test.d.ts +2 -0
- package/dist/types/src/hooks/processor.test.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +1 -2
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +1 -2
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/testing/testing.d.ts +2 -0
- package/dist/types/src/testing/testing.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +76 -0
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/schema.d.ts +40 -39
- package/dist/types/src/types/schema.d.ts.map +1 -1
- package/dist/types/src/types/types.d.ts +16 -5
- package/dist/types/src/types/types.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -0
- package/package.json +48 -47
- package/src/AutomationPlugin.tsx +85 -194
- package/src/artifacts.stories.tsx +180 -0
- package/src/capabilities/ai-client.ts +19 -0
- package/src/capabilities/app-graph-builder.ts +127 -0
- package/src/capabilities/capabilities.ts +12 -0
- package/src/capabilities/index.ts +12 -0
- package/src/capabilities/intent-resolver.ts +22 -0
- package/src/capabilities/react-surface.tsx +34 -0
- package/src/components/AssistantPanel/AssistantPanel.tsx +10 -8
- package/src/components/AutomationPanel/AutomationPanel.stories.tsx +1 -2
- package/src/components/AutomationPanel/AutomationPanel.tsx +61 -39
- package/src/components/ChatContainer.tsx +80 -0
- package/src/components/PromptEditor/PromptEditor.stories.tsx +3 -3
- package/src/components/Thread/Thread.stories.tsx +142 -0
- package/src/components/Thread/Thread.tsx +149 -0
- package/src/components/Thread/index.ts +5 -0
- package/src/components/TriggerEditor/TriggerEditor.stories.tsx +1 -2
- package/src/components/TriggerEditor/TriggerEditor.tsx +83 -16
- package/src/components/index.ts +5 -0
- package/src/hooks/email.ts +2 -2
- package/src/hooks/index.ts +1 -0
- package/src/hooks/invocation-handler.ts +2 -2
- package/src/hooks/processor.test.ts +15 -0
- package/src/hooks/processor.ts +161 -0
- package/src/index.ts +1 -4
- package/src/meta.ts +1 -1
- package/src/testing/testing.ts +9 -2
- package/src/translations.ts +13 -0
- package/src/types/schema.ts +9 -2
- package/src/types/types.ts +15 -21
- package/dist/lib/browser/AssistantPanel-N3QSALKY.mjs.map +0 -7
- package/dist/lib/browser/AutomationPanel-AQMN2CQR.mjs +0 -153
- package/dist/lib/browser/AutomationPanel-AQMN2CQR.mjs.map +0 -7
- package/dist/lib/browser/chunk-7KB4UMXO.mjs.map +0 -7
- package/dist/lib/browser/chunk-X5KMOH3I.mjs.map +0 -7
- package/dist/lib/browser/meta.mjs +0 -9
- package/dist/lib/browser/meta.mjs.map +0 -7
- package/dist/lib/node/AssistantPanel-RIA4TI3B.cjs.map +0 -7
- package/dist/lib/node/AutomationPanel-HZS5WKI5.cjs.map +0 -7
- package/dist/lib/node/chunk-CUCUWUAF.cjs.map +0 -7
- package/dist/lib/node/chunk-DTJ7XVO2.cjs.map +0 -7
- package/dist/lib/node/meta.cjs.map +0 -7
- package/dist/lib/node-esm/AssistantPanel-72YH43CH.mjs.map +0 -7
- package/dist/lib/node-esm/AutomationPanel-JUHOWQWW.mjs +0 -154
- package/dist/lib/node-esm/AutomationPanel-JUHOWQWW.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-23LY7DYS.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-HNOBZHWK.mjs.map +0 -7
- package/dist/lib/node-esm/meta.mjs +0 -10
- package/dist/lib/node-esm/meta.mjs.map +0 -7
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import '@dxos-theme';
|
|
6
|
+
|
|
7
|
+
import { type Meta } from '@storybook/react';
|
|
8
|
+
import React, { useMemo, useState } from 'react';
|
|
9
|
+
|
|
10
|
+
import { Capabilities, Surface, useCapabilities } from '@dxos/app-framework';
|
|
11
|
+
import { withPluginManager } from '@dxos/app-framework/testing';
|
|
12
|
+
import { type Tool, type Message } from '@dxos/artifact';
|
|
13
|
+
import { type ArtifactsContext, capabilities, genericTools, localServiceEndpoints } from '@dxos/artifact-testing';
|
|
14
|
+
import { AIServiceClientImpl } from '@dxos/assistant';
|
|
15
|
+
import { create } from '@dxos/client/echo';
|
|
16
|
+
import { createStatic, ObjectId } from '@dxos/echo-schema';
|
|
17
|
+
import { EdgeHttpClient } from '@dxos/edge-client';
|
|
18
|
+
import { DXN, QueueSubspaceTags, SpaceId } from '@dxos/keys';
|
|
19
|
+
import { ChessPlugin } from '@dxos/plugin-chess';
|
|
20
|
+
import { ChessType } from '@dxos/plugin-chess/types';
|
|
21
|
+
import { MapPlugin } from '@dxos/plugin-map';
|
|
22
|
+
import { useQueue } from '@dxos/react-edge-client';
|
|
23
|
+
import { IconButton, Input, Toolbar } from '@dxos/react-ui';
|
|
24
|
+
import { mx } from '@dxos/react-ui-theme';
|
|
25
|
+
import { withLayout, withSignals, withTheme } from '@dxos/storybook-utils';
|
|
26
|
+
|
|
27
|
+
import { Thread } from './components';
|
|
28
|
+
import { ChatProcessor } from './hooks';
|
|
29
|
+
import { createProcessorOptions } from './testing';
|
|
30
|
+
|
|
31
|
+
const endpoints = localServiceEndpoints;
|
|
32
|
+
|
|
33
|
+
type RenderProps = {
|
|
34
|
+
items?: ArtifactsContext['items']; // TODO(burdon): Typedef.
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const Render = ({ items: _items }: RenderProps) => {
|
|
38
|
+
const artifactDefinitions = useCapabilities(Capabilities.ArtifactDefinition);
|
|
39
|
+
|
|
40
|
+
// Configuration.
|
|
41
|
+
const tools = useMemo<Tool[]>(
|
|
42
|
+
() => [
|
|
43
|
+
// prettier-ignore
|
|
44
|
+
...genericTools,
|
|
45
|
+
...artifactDefinitions.flatMap((definition) => definition.tools),
|
|
46
|
+
],
|
|
47
|
+
[genericTools, artifactDefinitions],
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
// TODO(burdon): Common naming/packaging.
|
|
51
|
+
const [edgeClient] = useState(() => new EdgeHttpClient(endpoints.edge));
|
|
52
|
+
const [aiClient] = useState(() => new AIServiceClientImpl({ endpoint: endpoints.ai }));
|
|
53
|
+
|
|
54
|
+
// Queue.
|
|
55
|
+
const [queueDxn, setQueueDxn] = useState(() => randomQueueDxn());
|
|
56
|
+
const queue = useQueue<Message>(edgeClient, DXN.parse(queueDxn, true));
|
|
57
|
+
|
|
58
|
+
// Artifacts.
|
|
59
|
+
// TODO(burdon): Factor out class.
|
|
60
|
+
const [artifactsContext] = useState(() =>
|
|
61
|
+
create<ArtifactsContext>({
|
|
62
|
+
items: _items ?? [],
|
|
63
|
+
getArtifacts() {
|
|
64
|
+
return this.items;
|
|
65
|
+
},
|
|
66
|
+
addArtifact(artifact) {
|
|
67
|
+
this.items.push(artifact);
|
|
68
|
+
},
|
|
69
|
+
}),
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
// TODO(burdon): Create hook.
|
|
73
|
+
const processor = useMemo(
|
|
74
|
+
() =>
|
|
75
|
+
new ChatProcessor(
|
|
76
|
+
aiClient,
|
|
77
|
+
tools,
|
|
78
|
+
{ artifacts: artifactsContext },
|
|
79
|
+
createProcessorOptions(artifactDefinitions.map((definition) => definition.instructions)),
|
|
80
|
+
),
|
|
81
|
+
[aiClient, tools, artifactsContext, artifactDefinitions],
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
// State.
|
|
85
|
+
const artifactItems = artifactsContext.items.toReversed();
|
|
86
|
+
const messages = [...queue.items, ...processor.messages.value];
|
|
87
|
+
|
|
88
|
+
const handleSubmit = async (message: string) => {
|
|
89
|
+
// TODO(burdon): Button to cancel. Otherwise queue request.
|
|
90
|
+
if (processor.isStreaming) {
|
|
91
|
+
await processor.cancel();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const messages = await processor.request(message, queue.items);
|
|
95
|
+
// TODO(burdon): Append on success only? If approved by user? Clinet/server.
|
|
96
|
+
queue.append(messages);
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
return (
|
|
100
|
+
<div className='grid grid-cols-2 w-full h-full divide-x divide-separator overflow-hidden'>
|
|
101
|
+
{/* Thread */}
|
|
102
|
+
<div className='flex flex-col gap-4 overflow-hidden'>
|
|
103
|
+
<Toolbar.Root classNames='p-2'>
|
|
104
|
+
<Input.Root>
|
|
105
|
+
<Input.TextInput
|
|
106
|
+
spellCheck={false}
|
|
107
|
+
placeholder='Queue DXN'
|
|
108
|
+
value={queueDxn}
|
|
109
|
+
onClick={() => setQueueDxn('')}
|
|
110
|
+
onChange={(ev) => setQueueDxn(ev.target.value)}
|
|
111
|
+
/>
|
|
112
|
+
<IconButton
|
|
113
|
+
iconOnly
|
|
114
|
+
label='Copy DXN'
|
|
115
|
+
icon='ph--copy--regular'
|
|
116
|
+
onClick={() => navigator.clipboard.writeText(queueDxn)}
|
|
117
|
+
/>
|
|
118
|
+
<IconButton
|
|
119
|
+
iconOnly
|
|
120
|
+
label='Clear history'
|
|
121
|
+
icon='ph--trash--regular'
|
|
122
|
+
onClick={() => setQueueDxn(randomQueueDxn())}
|
|
123
|
+
/>
|
|
124
|
+
<IconButton iconOnly label='Stop' icon='ph--stop--regular' onClick={() => processor.cancel()} />
|
|
125
|
+
</Input.Root>
|
|
126
|
+
</Toolbar.Root>
|
|
127
|
+
|
|
128
|
+
<Thread messages={messages} streaming={processor.isStreaming.value} onSubmit={handleSubmit} />
|
|
129
|
+
</div>
|
|
130
|
+
|
|
131
|
+
{/* Artifacts Deck/Mosaic */}
|
|
132
|
+
<div className='overflow-hidden grid grid-rows-[2fr_1fr] divide-y divide-separator'>
|
|
133
|
+
{artifactItems.length > 0 && (
|
|
134
|
+
<div className={mx('flex grow overflow-hidden', artifactItems.length === 1 && 'row-span-2')}>
|
|
135
|
+
<Surface role='canvas-node' limit={1} data={artifactItems[0]} />
|
|
136
|
+
</div>
|
|
137
|
+
)}
|
|
138
|
+
|
|
139
|
+
{artifactItems.length > 1 && (
|
|
140
|
+
<div className='flex shrink-0 overflow-hidden divide-x divide-separator'>
|
|
141
|
+
<div className='flex flex-1 h-full'>
|
|
142
|
+
{artifactItems.slice(1, 3).map((item, idx) => (
|
|
143
|
+
<Surface key={idx} role='canvas-node' limit={1} data={item} />
|
|
144
|
+
))}
|
|
145
|
+
</div>
|
|
146
|
+
</div>
|
|
147
|
+
)}
|
|
148
|
+
</div>
|
|
149
|
+
</div>
|
|
150
|
+
);
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
const randomQueueDxn = () =>
|
|
154
|
+
new DXN(DXN.kind.QUEUE, [QueueSubspaceTags.DATA, SpaceId.random(), ObjectId.random()]).toString();
|
|
155
|
+
|
|
156
|
+
const meta: Meta<typeof Render> = {
|
|
157
|
+
title: 'plugins/plugin-automation/artifacts',
|
|
158
|
+
render: Render,
|
|
159
|
+
decorators: [
|
|
160
|
+
//
|
|
161
|
+
withSignals,
|
|
162
|
+
withTheme,
|
|
163
|
+
withLayout({ fullscreen: true, tooltips: true }),
|
|
164
|
+
withPluginManager({ plugins: [ChessPlugin(), MapPlugin()], capabilities }),
|
|
165
|
+
],
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
export default meta;
|
|
169
|
+
|
|
170
|
+
export const Default = {};
|
|
171
|
+
|
|
172
|
+
export const WithInitialItems = {
|
|
173
|
+
args: {
|
|
174
|
+
items: [
|
|
175
|
+
createStatic(ChessType, {
|
|
176
|
+
fen: 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1',
|
|
177
|
+
}),
|
|
178
|
+
],
|
|
179
|
+
},
|
|
180
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { contributes, type PluginsContext } from '@dxos/app-framework';
|
|
6
|
+
import { AIServiceClientImpl } from '@dxos/assistant';
|
|
7
|
+
import { ClientCapabilities } from '@dxos/plugin-client';
|
|
8
|
+
|
|
9
|
+
import { AutomationCapabilities } from './capabilities';
|
|
10
|
+
|
|
11
|
+
// TODO(wittjosiah): Factor out.
|
|
12
|
+
const DEFAULT_AI_SERVICE_URL = 'http://localhost:8788';
|
|
13
|
+
|
|
14
|
+
export default (context: PluginsContext) => {
|
|
15
|
+
const client = context.requestCapability(ClientCapabilities.Client);
|
|
16
|
+
const endpoint = client.config.values.runtime?.app?.env?.DX_AI_SERVICE_URL ?? DEFAULT_AI_SERVICE_URL;
|
|
17
|
+
const aiClient = new AIServiceClientImpl({ endpoint });
|
|
18
|
+
return contributes(AutomationCapabilities.AiClient, aiClient);
|
|
19
|
+
};
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { Capabilities, contributes, type PluginsContext } from '@dxos/app-framework';
|
|
6
|
+
import { ClientCapabilities } from '@dxos/plugin-client';
|
|
7
|
+
import { createExtension, toSignal } from '@dxos/plugin-graph';
|
|
8
|
+
import { memoizeQuery } from '@dxos/plugin-space';
|
|
9
|
+
import { getTypename, parseId, SpaceState } from '@dxos/react-client/echo';
|
|
10
|
+
|
|
11
|
+
import { AUTOMATION_PLUGIN } from '../meta';
|
|
12
|
+
|
|
13
|
+
export default (context: PluginsContext) => {
|
|
14
|
+
const resolve = (typename: string) =>
|
|
15
|
+
context.requestCapabilities(Capabilities.Metadata).find(({ id }) => id === typename)?.metadata ?? {};
|
|
16
|
+
|
|
17
|
+
return contributes(Capabilities.AppGraphBuilder, [
|
|
18
|
+
createExtension({
|
|
19
|
+
id: `${AUTOMATION_PLUGIN}/automation-for-subject`,
|
|
20
|
+
resolver: ({ id }) => {
|
|
21
|
+
if (!id.endsWith('~automation')) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const type = 'orphan-settings-for-subject';
|
|
26
|
+
const icon = 'ph--magic-wand--regular';
|
|
27
|
+
|
|
28
|
+
const client = context.requestCapability(ClientCapabilities.Client);
|
|
29
|
+
const [subjectId] = id.split('~');
|
|
30
|
+
const { spaceId, objectId } = parseId(subjectId);
|
|
31
|
+
const spaces = toSignal(
|
|
32
|
+
(onChange) => client.spaces.subscribe(() => onChange()).unsubscribe,
|
|
33
|
+
() => client.spaces.get(),
|
|
34
|
+
);
|
|
35
|
+
const space = spaces?.find((space) => space.id === spaceId && space.state.get() === SpaceState.SPACE_READY);
|
|
36
|
+
if (!objectId) {
|
|
37
|
+
// TODO(burdon): Ref SPACE_PLUGIN ns.
|
|
38
|
+
const label = space
|
|
39
|
+
? space.properties.name || ['unnamed space label', { ns: AUTOMATION_PLUGIN }]
|
|
40
|
+
: ['unnamed object settings label', { ns: AUTOMATION_PLUGIN }];
|
|
41
|
+
|
|
42
|
+
// TODO(wittjosiah): Support comments for arbitrary subjects.
|
|
43
|
+
// This is to ensure that the comments panel is not stuck on an old object.
|
|
44
|
+
return {
|
|
45
|
+
id,
|
|
46
|
+
type,
|
|
47
|
+
data: null,
|
|
48
|
+
properties: {
|
|
49
|
+
icon,
|
|
50
|
+
label,
|
|
51
|
+
showResolvedThreads: false,
|
|
52
|
+
object: null,
|
|
53
|
+
space,
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const [object] = memoizeQuery(space, { id: objectId });
|
|
59
|
+
if (!object || !subjectId) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const meta = resolve(getTypename(object) ?? '');
|
|
64
|
+
const label = meta.label?.(object) ||
|
|
65
|
+
object.name ||
|
|
66
|
+
meta.placeholder || ['unnamed object settings label', { ns: AUTOMATION_PLUGIN }];
|
|
67
|
+
|
|
68
|
+
return {
|
|
69
|
+
id,
|
|
70
|
+
type,
|
|
71
|
+
data: null,
|
|
72
|
+
properties: {
|
|
73
|
+
icon,
|
|
74
|
+
label,
|
|
75
|
+
object,
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
},
|
|
79
|
+
}),
|
|
80
|
+
createExtension({
|
|
81
|
+
id: `${AUTOMATION_PLUGIN}/assistant-for-subject`,
|
|
82
|
+
resolver: ({ id }) => {
|
|
83
|
+
// TODO(Zan): Find util (or make one). Effect schema!!
|
|
84
|
+
if (!id.endsWith('~assistant')) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const client = context.requestCapability(ClientCapabilities.Client);
|
|
89
|
+
const [subjectId] = id.split('~');
|
|
90
|
+
const { spaceId, objectId } = parseId(subjectId);
|
|
91
|
+
const spaces = toSignal(
|
|
92
|
+
(onChange) => client.spaces.subscribe(() => onChange()).unsubscribe,
|
|
93
|
+
() => client.spaces.get(),
|
|
94
|
+
);
|
|
95
|
+
const space = spaces?.find((space) => space.id === spaceId && space.state.get() === SpaceState.SPACE_READY);
|
|
96
|
+
if (!objectId) {
|
|
97
|
+
// TODO(wittjosiah): Support assistant for arbitrary subjects.
|
|
98
|
+
// This is to ensure that the assistant panel is not stuck on an old object.
|
|
99
|
+
return {
|
|
100
|
+
id,
|
|
101
|
+
type: 'orphan-automation-for-subject',
|
|
102
|
+
data: null,
|
|
103
|
+
properties: {
|
|
104
|
+
icon: 'ph--atom--regular',
|
|
105
|
+
label: ['assistant panel label', { ns: AUTOMATION_PLUGIN }],
|
|
106
|
+
object: null,
|
|
107
|
+
space,
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const [object] = memoizeQuery(space, { id: objectId });
|
|
113
|
+
|
|
114
|
+
return {
|
|
115
|
+
id,
|
|
116
|
+
type: 'orphan-automation-for-subject',
|
|
117
|
+
data: null,
|
|
118
|
+
properties: {
|
|
119
|
+
icon: 'ph--atom--regular',
|
|
120
|
+
label: ['assistant panel label', { ns: AUTOMATION_PLUGIN }],
|
|
121
|
+
object,
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
},
|
|
125
|
+
}),
|
|
126
|
+
]);
|
|
127
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { defineCapability } from '@dxos/app-framework';
|
|
6
|
+
import { type AIServiceClientImpl } from '@dxos/assistant';
|
|
7
|
+
|
|
8
|
+
import { AUTOMATION_PLUGIN } from '../meta';
|
|
9
|
+
|
|
10
|
+
export namespace AutomationCapabilities {
|
|
11
|
+
export const AiClient = defineCapability<AIServiceClientImpl>(`${AUTOMATION_PLUGIN}/capability/ai-client`);
|
|
12
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { lazy } from '@dxos/app-framework';
|
|
6
|
+
|
|
7
|
+
export const AiClient = lazy(() => import('./ai-client'));
|
|
8
|
+
export const AppGraphBuilder = lazy(() => import('./app-graph-builder'));
|
|
9
|
+
export const IntentResolver = lazy(() => import('./intent-resolver'));
|
|
10
|
+
export const ReactSurface = lazy(() => import('./react-surface'));
|
|
11
|
+
|
|
12
|
+
export * from './capabilities';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { Capabilities, contributes, createResolver } from '@dxos/app-framework';
|
|
6
|
+
import { ObjectId } from '@dxos/echo-schema';
|
|
7
|
+
import { create, makeRef } from '@dxos/live-object';
|
|
8
|
+
|
|
9
|
+
import { AutomationAction, GptChatType } from '../types';
|
|
10
|
+
|
|
11
|
+
export default () =>
|
|
12
|
+
contributes(
|
|
13
|
+
Capabilities.IntentResolver,
|
|
14
|
+
createResolver(AutomationAction.Create, ({ name }) => ({
|
|
15
|
+
data: {
|
|
16
|
+
object: create(GptChatType, {
|
|
17
|
+
name,
|
|
18
|
+
queue: makeRef({ id: ObjectId.random() }), // new DXN(DXN.kind.QUEUE, [QueueSubspaceTags.DATA, SpaceId.random(), ObjectId.random()]).toString(),
|
|
19
|
+
}),
|
|
20
|
+
},
|
|
21
|
+
})),
|
|
22
|
+
);
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import React from 'react';
|
|
6
|
+
|
|
7
|
+
import { Capabilities, contributes, createSurface } from '@dxos/app-framework';
|
|
8
|
+
import { getSpace, isEchoObject, type ReactiveEchoObject } from '@dxos/react-client/echo';
|
|
9
|
+
|
|
10
|
+
import { AssistantPanel, AutomationPanel, ChatContainer } from '../components';
|
|
11
|
+
import { AUTOMATION_PLUGIN } from '../meta';
|
|
12
|
+
import { GptChatType } from '../types';
|
|
13
|
+
|
|
14
|
+
export default () =>
|
|
15
|
+
contributes(Capabilities.ReactSurface, [
|
|
16
|
+
createSurface({
|
|
17
|
+
id: `${AUTOMATION_PLUGIN}/assistant`,
|
|
18
|
+
role: 'complementary--assistant',
|
|
19
|
+
component: ({ data }) => <AssistantPanel subject={data.subject} />,
|
|
20
|
+
}),
|
|
21
|
+
createSurface({
|
|
22
|
+
id: `${AUTOMATION_PLUGIN}/automation`,
|
|
23
|
+
role: 'complementary--automation',
|
|
24
|
+
filter: (data): data is { subject: ReactiveEchoObject<any> } =>
|
|
25
|
+
isEchoObject(data.subject) && !!getSpace(data.subject),
|
|
26
|
+
component: ({ data }) => <AutomationPanel space={getSpace(data.subject)!} object={data.subject} />,
|
|
27
|
+
}),
|
|
28
|
+
createSurface({
|
|
29
|
+
id: `${AUTOMATION_PLUGIN}/gpt-chat`,
|
|
30
|
+
role: 'article',
|
|
31
|
+
filter: (data): data is { subject: GptChatType } => data.subject instanceof GptChatType,
|
|
32
|
+
component: ({ data, role }) => <ChatContainer role={role} chat={data.subject} />,
|
|
33
|
+
}),
|
|
34
|
+
]);
|
|
@@ -6,8 +6,10 @@
|
|
|
6
6
|
|
|
7
7
|
import React, { useEffect, useRef, useState } from 'react';
|
|
8
8
|
|
|
9
|
-
import { type
|
|
9
|
+
import { type Message } from '@dxos/artifact';
|
|
10
|
+
import { type AIServiceClient, AIServiceClientImpl } from '@dxos/assistant';
|
|
10
11
|
import type { ReactiveEchoObject } from '@dxos/echo-db';
|
|
12
|
+
import { ObjectId } from '@dxos/echo-schema';
|
|
11
13
|
import { SpaceId } from '@dxos/keys';
|
|
12
14
|
import { useClient, useConfig } from '@dxos/react-client';
|
|
13
15
|
import { ContextMenu, type ThemedClassName } from '@dxos/react-ui';
|
|
@@ -58,13 +60,13 @@ export const AssistantPanel = ({ subject, classNames }: AssistantPanelProps) =>
|
|
|
58
60
|
setContextSpaceId(contextSpaceId);
|
|
59
61
|
setThreadId(threadId);
|
|
60
62
|
|
|
61
|
-
const messages = await aiClient.current!.
|
|
63
|
+
const messages = await aiClient.current!.getMessages(contextSpaceId, threadId);
|
|
62
64
|
setHistory(messages);
|
|
63
65
|
});
|
|
64
66
|
}, []);
|
|
65
67
|
|
|
66
68
|
const handleRequest = async (input: string) => {
|
|
67
|
-
if (input === '') {
|
|
69
|
+
if (!aiClient.current || input === '') {
|
|
68
70
|
return;
|
|
69
71
|
}
|
|
70
72
|
|
|
@@ -78,10 +80,10 @@ export const AssistantPanel = ({ subject, classNames }: AssistantPanelProps) =>
|
|
|
78
80
|
role: 'user',
|
|
79
81
|
content: [{ type: 'text', text: input }],
|
|
80
82
|
};
|
|
81
|
-
await aiClient.current
|
|
83
|
+
await aiClient.current.appendMessages([userMessage]);
|
|
82
84
|
setHistory([...history, userMessage]);
|
|
83
85
|
|
|
84
|
-
const generationStream = await aiClient.current
|
|
86
|
+
const generationStream = await aiClient.current.generate({
|
|
85
87
|
model: '@anthropic/claude-3-5-sonnet-20241022',
|
|
86
88
|
spaceId: contextSpaceId!,
|
|
87
89
|
threadId: threadId!,
|
|
@@ -94,7 +96,7 @@ export const AssistantPanel = ({ subject, classNames }: AssistantPanelProps) =>
|
|
|
94
96
|
setHistory([...historyBefore, ...generationStream.accumulatedMessages]);
|
|
95
97
|
}
|
|
96
98
|
|
|
97
|
-
await aiClient.current!.
|
|
99
|
+
await aiClient.current!.appendMessages(await generationStream.complete());
|
|
98
100
|
};
|
|
99
101
|
|
|
100
102
|
const getSystemPrompt = async () => {
|
|
@@ -114,7 +116,7 @@ export const AssistantPanel = ({ subject, classNames }: AssistantPanelProps) =>
|
|
|
114
116
|
// setContextSpaceId(contextSpaceId);
|
|
115
117
|
setThreadId(threadId);
|
|
116
118
|
|
|
117
|
-
const messages = await aiClient.current!.
|
|
119
|
+
const messages = await aiClient.current!.getMessages(contextSpaceId!, threadId);
|
|
118
120
|
setHistory(messages);
|
|
119
121
|
};
|
|
120
122
|
|
|
@@ -146,7 +148,7 @@ export const AssistantPanel = ({ subject, classNames }: AssistantPanelProps) =>
|
|
|
146
148
|
</Toolbar.Button>
|
|
147
149
|
</ContextMenu.Trigger>
|
|
148
150
|
<ContextMenu.Portal>
|
|
149
|
-
<ContextMenu.Content
|
|
151
|
+
<ContextMenu.Content>
|
|
150
152
|
<ContextMenu.Viewport>
|
|
151
153
|
<ContextMenu.Item onClick={clearThread}>Clear thread</ContextMenu.Item>
|
|
152
154
|
<ContextMenu.Item onClick={async () => console.log(await getSystemPrompt())}>
|
|
@@ -7,8 +7,7 @@ import '@dxos-theme';
|
|
|
7
7
|
import { type Meta } from '@storybook/react';
|
|
8
8
|
import React from 'react';
|
|
9
9
|
|
|
10
|
-
import { FunctionTrigger } from '@dxos/functions';
|
|
11
|
-
import { FunctionType } from '@dxos/plugin-script/types';
|
|
10
|
+
import { FunctionType, FunctionTrigger } from '@dxos/functions';
|
|
12
11
|
import { create, useSpaces } from '@dxos/react-client/echo';
|
|
13
12
|
import { withClientProvider } from '@dxos/react-client/testing';
|
|
14
13
|
import { withLayout, withTheme } from '@dxos/storybook-utils';
|
|
@@ -5,8 +5,14 @@
|
|
|
5
5
|
import React, { useState } from 'react';
|
|
6
6
|
|
|
7
7
|
import { S } from '@dxos/echo-schema';
|
|
8
|
-
import {
|
|
9
|
-
|
|
8
|
+
import {
|
|
9
|
+
FunctionType,
|
|
10
|
+
FunctionTrigger,
|
|
11
|
+
FunctionTriggerSchema,
|
|
12
|
+
TriggerKind,
|
|
13
|
+
type FunctionTriggerType,
|
|
14
|
+
ScriptType,
|
|
15
|
+
} from '@dxos/functions';
|
|
10
16
|
import { type Client, useClient } from '@dxos/react-client';
|
|
11
17
|
import { create, Filter, useQuery, type Space, type ReactiveObject, getSpace } from '@dxos/react-client/echo';
|
|
12
18
|
import { IconButton, Input, useTranslation, Button } from '@dxos/react-ui';
|
|
@@ -24,7 +30,7 @@ export type AutomationPanelProps = {
|
|
|
24
30
|
};
|
|
25
31
|
|
|
26
32
|
// TODO(burdon): Factor out common layout with ViewEditor.
|
|
27
|
-
export const AutomationPanel = ({ space }: AutomationPanelProps) => {
|
|
33
|
+
export const AutomationPanel = ({ space, object }: AutomationPanelProps) => {
|
|
28
34
|
const { t } = useTranslation(AUTOMATION_PLUGIN);
|
|
29
35
|
const client = useClient();
|
|
30
36
|
const triggers = useQuery(space, Filter.schema(FunctionTrigger));
|
|
@@ -41,7 +47,7 @@ export const AutomationPanel = ({ space }: AutomationPanelProps) => {
|
|
|
41
47
|
};
|
|
42
48
|
|
|
43
49
|
const handleAdd = () => {
|
|
44
|
-
setTrigger(create(FunctionTriggerSchema, {}));
|
|
50
|
+
setTrigger(create(FunctionTriggerSchema, { meta: {} }));
|
|
45
51
|
setSelected(undefined);
|
|
46
52
|
};
|
|
47
53
|
|
|
@@ -71,43 +77,46 @@ export const AutomationPanel = ({ space }: AutomationPanelProps) => {
|
|
|
71
77
|
<List.Root<FunctionTrigger> items={triggers} isItem={S.is(FunctionTrigger)} getId={(field) => field.id}>
|
|
72
78
|
{({ items: triggers }) => (
|
|
73
79
|
<div role='list' className='flex flex-col w-full'>
|
|
74
|
-
{triggers?.map((trigger) =>
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
</
|
|
88
|
-
|
|
89
|
-
{
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
80
|
+
{triggers?.map((trigger) => {
|
|
81
|
+
const copyAction = getCopyAction(client, trigger);
|
|
82
|
+
return (
|
|
83
|
+
<List.Item<FunctionTrigger>
|
|
84
|
+
key={trigger.id}
|
|
85
|
+
item={trigger}
|
|
86
|
+
classNames={mx(grid, ghostHover, 'items-center', 'px-2')}
|
|
87
|
+
>
|
|
88
|
+
<Input.Root>
|
|
89
|
+
<Input.Switch
|
|
90
|
+
checked={trigger.enabled}
|
|
91
|
+
onCheckedChange={(checked) => (trigger.enabled = checked)}
|
|
92
|
+
/>
|
|
93
|
+
</Input.Root>
|
|
94
|
+
|
|
95
|
+
<div className={'flex'}>
|
|
96
|
+
<List.ItemTitle
|
|
97
|
+
classNames='px-1 cursor-pointer w-0 shrink truncate'
|
|
98
|
+
onClick={() => handleSelect(trigger)}
|
|
99
|
+
>
|
|
100
|
+
{getFunctionName(scripts, functions, trigger) ?? '∅'}
|
|
101
|
+
</List.ItemTitle>
|
|
102
|
+
|
|
103
|
+
{/* TODO: a better way to expose copy action */}
|
|
104
|
+
{copyAction && (
|
|
105
|
+
<Button onClick={() => navigator.clipboard.writeText(copyAction.contentProvider())}>
|
|
106
|
+
{t(copyAction.translationKey)}
|
|
107
|
+
</Button>
|
|
108
|
+
)}
|
|
109
|
+
</div>
|
|
110
|
+
|
|
111
|
+
<List.ItemDeleteButton onClick={() => handleDelete(trigger)} />
|
|
112
|
+
</List.Item>
|
|
113
|
+
);
|
|
114
|
+
})}
|
|
98
115
|
</div>
|
|
99
116
|
)}
|
|
100
117
|
</List.Root>
|
|
101
118
|
|
|
102
|
-
{trigger &&
|
|
103
|
-
<TriggerEditor
|
|
104
|
-
space={space}
|
|
105
|
-
storedTrigger={selected}
|
|
106
|
-
trigger={trigger}
|
|
107
|
-
onSave={handleSave}
|
|
108
|
-
onCancel={handleCancel}
|
|
109
|
-
/>
|
|
110
|
-
)}
|
|
119
|
+
{trigger && <TriggerEditor space={space} trigger={trigger} onSave={handleSave} onCancel={handleCancel} />}
|
|
111
120
|
|
|
112
121
|
{!trigger && (
|
|
113
122
|
<div className='flex p-2 justify-center'>
|
|
@@ -118,6 +127,18 @@ export const AutomationPanel = ({ space }: AutomationPanelProps) => {
|
|
|
118
127
|
);
|
|
119
128
|
};
|
|
120
129
|
|
|
130
|
+
const getCopyAction = (client: Client, trigger: FunctionTrigger | undefined) => {
|
|
131
|
+
if (trigger?.spec?.type === TriggerKind.Email) {
|
|
132
|
+
return { translationKey: 'trigger copy email', contentProvider: () => `${getSpace(trigger)!.id}@dxos.network` };
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (trigger?.spec?.type === TriggerKind.Webhook) {
|
|
136
|
+
return { translationKey: 'trigger copy url', contentProvider: () => getWebhookUrl(client, trigger) };
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return undefined;
|
|
140
|
+
};
|
|
141
|
+
|
|
121
142
|
const getWebhookUrl = (client: Client, trigger: FunctionTrigger) => {
|
|
122
143
|
const spaceId = getSpace(trigger)!.id;
|
|
123
144
|
const edgeUrl = new URL(client.config.values.runtime!.services!.edge!.url!);
|
|
@@ -127,9 +148,10 @@ const getWebhookUrl = (client: Client, trigger: FunctionTrigger) => {
|
|
|
127
148
|
};
|
|
128
149
|
|
|
129
150
|
const getFunctionName = (scripts: ScriptType[], functions: FunctionType[], trigger: FunctionTriggerType) => {
|
|
151
|
+
const shortId = trigger.function && `${trigger.function?.slice(0, 16)}…`;
|
|
130
152
|
const functionObject = functions.find((fn) => fn.name === trigger.function);
|
|
131
153
|
if (!functionObject) {
|
|
132
|
-
return
|
|
154
|
+
return shortId;
|
|
133
155
|
}
|
|
134
|
-
return scripts.find((s) => functionObject.source?.id === s.id)?.name ??
|
|
156
|
+
return scripts.find((s) => functionObject.source?.target?.id === s.id)?.name ?? shortId;
|
|
135
157
|
};
|