@dxos/plugin-automation 0.6.14-main.69511f5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/LICENSE +8 -0
  2. package/README.md +15 -0
  3. package/dist/lib/browser/PromptContainer-RFMJXMUA.mjs +19 -0
  4. package/dist/lib/browser/PromptContainer-RFMJXMUA.mjs.map +7 -0
  5. package/dist/lib/browser/chunk-3TNRXJTD.mjs +14 -0
  6. package/dist/lib/browser/chunk-3TNRXJTD.mjs.map +7 -0
  7. package/dist/lib/browser/chunk-GGA62V7D.mjs +55 -0
  8. package/dist/lib/browser/chunk-GGA62V7D.mjs.map +7 -0
  9. package/dist/lib/browser/chunk-PSSWFA6A.mjs +217 -0
  10. package/dist/lib/browser/chunk-PSSWFA6A.mjs.map +7 -0
  11. package/dist/lib/browser/index.mjs +1135 -0
  12. package/dist/lib/browser/index.mjs.map +7 -0
  13. package/dist/lib/browser/meta.json +1 -0
  14. package/dist/lib/browser/meta.mjs +9 -0
  15. package/dist/lib/browser/meta.mjs.map +7 -0
  16. package/dist/lib/browser/types/index.mjs +16 -0
  17. package/dist/lib/browser/types/index.mjs.map +7 -0
  18. package/dist/lib/node/PromptContainer-FRSY6FNL.cjs +45 -0
  19. package/dist/lib/node/PromptContainer-FRSY6FNL.cjs.map +7 -0
  20. package/dist/lib/node/chunk-E2H3AGKB.cjs +240 -0
  21. package/dist/lib/node/chunk-E2H3AGKB.cjs.map +7 -0
  22. package/dist/lib/node/chunk-N5IDAUFU.cjs +76 -0
  23. package/dist/lib/node/chunk-N5IDAUFU.cjs.map +7 -0
  24. package/dist/lib/node/chunk-UPPUTAPL.cjs +37 -0
  25. package/dist/lib/node/chunk-UPPUTAPL.cjs.map +7 -0
  26. package/dist/lib/node/index.cjs +1137 -0
  27. package/dist/lib/node/index.cjs.map +7 -0
  28. package/dist/lib/node/meta.cjs +30 -0
  29. package/dist/lib/node/meta.cjs.map +7 -0
  30. package/dist/lib/node/meta.json +1 -0
  31. package/dist/lib/node/types/index.cjs +38 -0
  32. package/dist/lib/node/types/index.cjs.map +7 -0
  33. package/dist/lib/node-esm/PromptContainer-4VHFPEQH.mjs +20 -0
  34. package/dist/lib/node-esm/PromptContainer-4VHFPEQH.mjs.map +7 -0
  35. package/dist/lib/node-esm/chunk-HFTXKLRR.mjs +218 -0
  36. package/dist/lib/node-esm/chunk-HFTXKLRR.mjs.map +7 -0
  37. package/dist/lib/node-esm/chunk-QAPWYK2P.mjs +16 -0
  38. package/dist/lib/node-esm/chunk-QAPWYK2P.mjs.map +7 -0
  39. package/dist/lib/node-esm/chunk-UT6QKU6J.mjs +56 -0
  40. package/dist/lib/node-esm/chunk-UT6QKU6J.mjs.map +7 -0
  41. package/dist/lib/node-esm/index.mjs +1136 -0
  42. package/dist/lib/node-esm/index.mjs.map +7 -0
  43. package/dist/lib/node-esm/meta.json +1 -0
  44. package/dist/lib/node-esm/meta.mjs +10 -0
  45. package/dist/lib/node-esm/meta.mjs.map +7 -0
  46. package/dist/lib/node-esm/types/index.mjs +17 -0
  47. package/dist/lib/node-esm/types/index.mjs.map +7 -0
  48. package/dist/types/src/AutomationPlugin.d.ts +4 -0
  49. package/dist/types/src/AutomationPlugin.d.ts.map +1 -0
  50. package/dist/types/src/components/AutomationPanel.d.ts +3 -0
  51. package/dist/types/src/components/AutomationPanel.d.ts.map +1 -0
  52. package/dist/types/src/components/Chain.d.ts +12 -0
  53. package/dist/types/src/components/Chain.d.ts.map +1 -0
  54. package/dist/types/src/components/PromptContainer.d.ts +6 -0
  55. package/dist/types/src/components/PromptContainer.d.ts.map +1 -0
  56. package/dist/types/src/components/PromptEditor/PromptEditor.d.ts +10 -0
  57. package/dist/types/src/components/PromptEditor/PromptEditor.d.ts.map +1 -0
  58. package/dist/types/src/components/PromptEditor/PromptEditor.stories.d.ts +6 -0
  59. package/dist/types/src/components/PromptEditor/PromptEditor.stories.d.ts.map +1 -0
  60. package/dist/types/src/components/PromptEditor/index.d.ts +2 -0
  61. package/dist/types/src/components/PromptEditor/index.d.ts.map +1 -0
  62. package/dist/types/src/components/PromptEditor/prompt-extension.d.ts +4 -0
  63. package/dist/types/src/components/PromptEditor/prompt-extension.d.ts.map +1 -0
  64. package/dist/types/src/components/PromptEditor/types.d.ts +18 -0
  65. package/dist/types/src/components/PromptEditor/types.d.ts.map +1 -0
  66. package/dist/types/src/components/TriggerEditor/Form.d.ts +5 -0
  67. package/dist/types/src/components/TriggerEditor/Form.d.ts.map +1 -0
  68. package/dist/types/src/components/TriggerEditor/TriggerEditor.d.ts +8 -0
  69. package/dist/types/src/components/TriggerEditor/TriggerEditor.d.ts.map +1 -0
  70. package/dist/types/src/components/TriggerEditor/TriggerEditor.stories.d.ts +5 -0
  71. package/dist/types/src/components/TriggerEditor/TriggerEditor.stories.d.ts.map +1 -0
  72. package/dist/types/src/components/TriggerEditor/email.d.ts +4 -0
  73. package/dist/types/src/components/TriggerEditor/email.d.ts.map +1 -0
  74. package/dist/types/src/components/TriggerEditor/index.d.ts +2 -0
  75. package/dist/types/src/components/TriggerEditor/index.d.ts.map +1 -0
  76. package/dist/types/src/components/TriggerEditor/invokation-handler.d.ts +5 -0
  77. package/dist/types/src/components/TriggerEditor/invokation-handler.d.ts.map +1 -0
  78. package/dist/types/src/components/TriggerEditor/meta.d.ts +25 -0
  79. package/dist/types/src/components/TriggerEditor/meta.d.ts.map +1 -0
  80. package/dist/types/src/components/index.d.ts +6 -0
  81. package/dist/types/src/components/index.d.ts.map +1 -0
  82. package/dist/types/src/index.d.ts +7 -0
  83. package/dist/types/src/index.d.ts.map +1 -0
  84. package/dist/types/src/meta.d.ts +9 -0
  85. package/dist/types/src/meta.d.ts.map +1 -0
  86. package/dist/types/src/presets.d.ts +9 -0
  87. package/dist/types/src/presets.d.ts.map +1 -0
  88. package/dist/types/src/translations.d.ts +17 -0
  89. package/dist/types/src/translations.d.ts.map +1 -0
  90. package/dist/types/src/types/chain.d.ts +71 -0
  91. package/dist/types/src/types/chain.d.ts.map +1 -0
  92. package/dist/types/src/types/index.d.ts +3 -0
  93. package/dist/types/src/types/index.d.ts.map +1 -0
  94. package/dist/types/src/types/types.d.ts +7 -0
  95. package/dist/types/src/types/types.d.ts.map +1 -0
  96. package/package.json +98 -0
  97. package/src/AutomationPlugin.tsx +149 -0
  98. package/src/components/AutomationPanel.tsx +21 -0
  99. package/src/components/Chain.tsx +66 -0
  100. package/src/components/PromptContainer.tsx +19 -0
  101. package/src/components/PromptEditor/PromptEditor.stories.tsx +64 -0
  102. package/src/components/PromptEditor/PromptEditor.tsx +222 -0
  103. package/src/components/PromptEditor/index.ts +5 -0
  104. package/src/components/PromptEditor/prompt-extension.ts +43 -0
  105. package/src/components/PromptEditor/types.tsx +28 -0
  106. package/src/components/TriggerEditor/Form.tsx +18 -0
  107. package/src/components/TriggerEditor/TriggerEditor.stories.tsx +82 -0
  108. package/src/components/TriggerEditor/TriggerEditor.tsx +346 -0
  109. package/src/components/TriggerEditor/email.ts +49 -0
  110. package/src/components/TriggerEditor/index.ts +5 -0
  111. package/src/components/TriggerEditor/invokation-handler.ts +110 -0
  112. package/src/components/TriggerEditor/meta.tsx +225 -0
  113. package/src/components/index.ts +12 -0
  114. package/src/index.ts +12 -0
  115. package/src/meta.ts +14 -0
  116. package/src/presets.ts +248 -0
  117. package/src/translations.ts +30 -0
  118. package/src/types/chain.ts +38 -0
  119. package/src/types/index.ts +6 -0
  120. package/src/types/types.ts +27 -0
@@ -0,0 +1,222 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import { type Schema as S } from '@effect/schema';
6
+ import React, { useEffect } from 'react';
7
+
8
+ import { createDocAccessor } from '@dxos/react-client/echo';
9
+ import { Input, Select, useThemeContext, useTranslation } from '@dxos/react-ui';
10
+ import {
11
+ createBasicExtensions,
12
+ createDataExtensions,
13
+ createThemeExtensions,
14
+ useTextEditor,
15
+ } from '@dxos/react-ui-editor';
16
+ import { attentionSurface, groupBorder, mx } from '@dxos/react-ui-theme';
17
+ import { nonNullable } from '@dxos/util';
18
+
19
+ import { nameRegex, promptExtension } from './prompt-extension';
20
+ import { AUTOMATION_PLUGIN } from '../../meta';
21
+ import { type ChainInput, ChainInputType, type ChainPromptType } from '../../types';
22
+
23
+ const inputTypes = [
24
+ {
25
+ value: ChainInputType.VALUE,
26
+ label: 'Value',
27
+ },
28
+ {
29
+ value: ChainInputType.PASS_THROUGH,
30
+ label: 'Pass through',
31
+ },
32
+ {
33
+ value: ChainInputType.RETRIEVER,
34
+ label: 'Retriever',
35
+ },
36
+ // {
37
+ // value: ChainInputType.FUNCTION,
38
+ // label: 'Function',
39
+ // },
40
+ // {
41
+ // value: ChainInputType.QUERY,
42
+ // label: 'Query',
43
+ // },
44
+ {
45
+ value: ChainInputType.RESOLVER,
46
+ label: 'Resolver',
47
+ },
48
+ {
49
+ value: ChainInputType.CONTEXT,
50
+ label: 'Context',
51
+ },
52
+ {
53
+ value: ChainInputType.SCHEMA,
54
+ label: 'Schema',
55
+ },
56
+ ];
57
+
58
+ const getInputType = (type: string) => inputTypes.find(({ value }) => String(value) === type)?.value;
59
+
60
+ const usePromptInputs = (prompt: ChainPromptType) => {
61
+ useEffect(() => {
62
+ const text = prompt.template ?? '';
63
+ if (!prompt.inputs) {
64
+ prompt.inputs = []; // TODO(burdon): Required?
65
+ }
66
+
67
+ const regex = new RegExp(nameRegex, 'g');
68
+ const variables = new Set<string>([...text.matchAll(regex)].map((m) => m[1]));
69
+
70
+ // Create map of unclaimed inputs.
71
+ const unclaimed = new Map<string, ChainInput>(
72
+ prompt.inputs?.filter(nonNullable).map((input) => [input.name, input]),
73
+ );
74
+ const missing: string[] = [];
75
+ Array.from(variables.values()).forEach((name) => {
76
+ if (unclaimed.has(name)) {
77
+ unclaimed.delete(name);
78
+ } else {
79
+ missing.push(name);
80
+ }
81
+ });
82
+
83
+ // Match or create new inputs.
84
+ const values = unclaimed.values();
85
+ missing.forEach((name) => {
86
+ const next = values.next().value;
87
+ if (next) {
88
+ next.name = name;
89
+ } else {
90
+ prompt.inputs?.push({ name });
91
+ }
92
+ });
93
+
94
+ // Remove unclaimed (deleted) inputs.
95
+ // TODO(burdon): If user types incorrect name value, it will be deleted. Garbage collect?
96
+ for (const input of values) {
97
+ prompt.inputs.splice(prompt.inputs.indexOf(input), 1);
98
+ }
99
+ }, [prompt.template]);
100
+ };
101
+
102
+ export type PromptEditorProps = {
103
+ prompt: ChainPromptType;
104
+ commandEditable?: boolean;
105
+ schema?: S.Schema<any, any, any>;
106
+ };
107
+
108
+ export const PromptEditor = ({ prompt, commandEditable = true }: PromptEditorProps) => {
109
+ const { t } = useTranslation(AUTOMATION_PLUGIN);
110
+ const { themeMode } = useThemeContext();
111
+
112
+ const { parentRef } = useTextEditor(
113
+ () => ({
114
+ initialValue: prompt.template,
115
+ extensions: [
116
+ createDataExtensions({
117
+ id: prompt.id,
118
+ text: prompt.template !== undefined ? createDocAccessor(prompt, ['template']) : undefined,
119
+ }),
120
+ createBasicExtensions({
121
+ bracketMatching: false,
122
+ lineWrapping: true,
123
+ placeholder: t('template placeholder'),
124
+ }),
125
+ createThemeExtensions({
126
+ themeMode,
127
+ slots: {
128
+ content: { className: '!p-3' },
129
+ },
130
+ }),
131
+ promptExtension,
132
+ ],
133
+ }),
134
+ [themeMode, prompt],
135
+ );
136
+
137
+ usePromptInputs(prompt);
138
+
139
+ return (
140
+ <div className={mx('flex flex-col w-full overflow-hidden gap-4', groupBorder)}>
141
+ {commandEditable && (
142
+ <div className='flex items-center pl-4'>
143
+ <span className='text-neutral-500'>/</span>
144
+ <Input.Root>
145
+ <Input.TextInput
146
+ placeholder={t('command placeholder')}
147
+ classNames={mx('is-full bg-transparent m-2')}
148
+ value={prompt.command ?? ''}
149
+ onChange={(event) => {
150
+ prompt.command = event.target.value.replace(/\w/g, '');
151
+ }}
152
+ />
153
+ </Input.Root>
154
+ </div>
155
+ )}
156
+
157
+ <div ref={parentRef} className={mx(attentionSurface, 'rounded', 'min-h-[120px]')} />
158
+
159
+ {(prompt.inputs?.length ?? 0) > 0 && (
160
+ <div className='flex flex-col'>
161
+ {/* TODO(zan): Improve layout with grid */}
162
+ <table className='w-full table-fixed border-collapse my-2'>
163
+ <tbody>
164
+ {prompt.inputs?.filter(nonNullable).map((input) => (
165
+ <tr key={input.name}>
166
+ <td className='w-[160px] p-1 font-mono text-sm whitespace-nowrap truncate'>
167
+ <code className='px-2'>{input.name}</code>
168
+ </td>
169
+ <td className='w-[120px] p-1'>
170
+ <Input.Root>
171
+ <Select.Root
172
+ value={String(input.type)}
173
+ onValueChange={(type) => {
174
+ input.type = getInputType(type) ?? ChainInputType.VALUE;
175
+ }}
176
+ >
177
+ <Select.TriggerButton placeholder='Type' classNames='is-full' />
178
+ <Select.Portal>
179
+ <Select.Content>
180
+ <Select.Viewport>
181
+ {inputTypes.map(({ value, label }) => (
182
+ <Select.Option key={value} value={String(value)}>
183
+ {label}
184
+ </Select.Option>
185
+ ))}
186
+ </Select.Viewport>
187
+ </Select.Content>
188
+ </Select.Portal>
189
+ </Select.Root>
190
+ </Input.Root>
191
+ </td>
192
+ <td className='p-1 pr-2'>
193
+ {input.type !== undefined &&
194
+ [
195
+ ChainInputType.VALUE,
196
+ ChainInputType.CONTEXT,
197
+ ChainInputType.RESOLVER,
198
+ ChainInputType.SCHEMA,
199
+ ].includes(input.type) && (
200
+ <div>
201
+ <Input.Root>
202
+ <Input.TextInput
203
+ placeholder={t('command placeholder')}
204
+ classNames={mx('is-full bg-transparent')}
205
+ value={input.value ?? ''}
206
+ onChange={(event) => {
207
+ input.value = event.target.value;
208
+ }}
209
+ />
210
+ </Input.Root>
211
+ </div>
212
+ )}
213
+ </td>
214
+ </tr>
215
+ ))}
216
+ </tbody>
217
+ </table>
218
+ </div>
219
+ )}
220
+ </div>
221
+ );
222
+ };
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ export * from './PromptEditor';
@@ -0,0 +1,43 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import { HighlightStyle, StreamLanguage, syntaxHighlighting } from '@codemirror/language';
6
+ import { type Extension } from '@codemirror/state';
7
+
8
+ import { tags } from '@dxos/react-ui-editor';
9
+ import { mx } from '@dxos/react-ui-theme';
10
+
11
+ export const nameRegex = /\{([\w-]+)}/;
12
+
13
+ const parser = StreamLanguage.define({
14
+ token: (stream) => {
15
+ if (stream.eatSpace()) {
16
+ return null;
17
+ }
18
+ if (stream.match(/^#.*/)) {
19
+ return 'lineComment';
20
+ }
21
+ if (stream.match(/^-+$/)) {
22
+ return 'lineComment';
23
+ }
24
+ if (stream.match(nameRegex)) {
25
+ return 'variableName';
26
+ }
27
+ stream.next();
28
+ return null;
29
+ },
30
+ });
31
+
32
+ /**
33
+ * https://codemirror.net/examples/styling
34
+ * https://lezer.codemirror.net/docs/ref/#highlight
35
+ */
36
+ const highlightStyles = HighlightStyle.define([
37
+ {
38
+ tag: tags.variableName,
39
+ class: mx('rounded border border-yellow-500 bg-yellow-100 text-black font-mono text-sm'),
40
+ },
41
+ ]);
42
+
43
+ export const promptExtension: Extension = [parser, syntaxHighlighting(highlightStyles)];
@@ -0,0 +1,28 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ // TODO(burdon): Factor out (shared with backend). core/chain (@dxos/chain).
6
+ // TODO(burdon): Agent/plan-and-execute (with tools). Create design doc/ontology of sequence/agent.
7
+
8
+ export type Step = {
9
+ id: string;
10
+ };
11
+
12
+ export type Variable = {
13
+ name: string;
14
+ type: 'value' | 'function' | 'query' | 'retriever' | 'pass-through';
15
+ };
16
+
17
+ export type Prompt = Step & {
18
+ title?: string;
19
+ description?: string;
20
+ template: string;
21
+ variables: Variable[];
22
+ };
23
+
24
+ export type Sequence = Step & {
25
+ runnable: Step[];
26
+ };
27
+
28
+ export type Chain = {};
@@ -0,0 +1,18 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import React, { type PropsWithChildren } from 'react';
6
+
7
+ import { Input } from '@dxos/react-ui';
8
+
9
+ export const InputRow = ({ label, children }: PropsWithChildren<{ label?: string }>) => (
10
+ <Input.Root>
11
+ <tr>
12
+ <td className='w-[80px] px-2 text-right align-top pt-3 overflow-hidden'>
13
+ <Input.Label classNames='truncate text-xs'>{label}</Input.Label>
14
+ </td>
15
+ <td className='p-1 pr-2'>{children}</td>
16
+ </tr>
17
+ </Input.Root>
18
+ );
@@ -0,0 +1,82 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import { type Meta } from '@storybook/react';
6
+ import React, { useEffect, useState } from 'react';
7
+
8
+ import { create } from '@dxos/echo-schema';
9
+ import { FunctionDef, FunctionTrigger } from '@dxos/functions/types';
10
+ import { useClient } from '@dxos/react-client';
11
+ import { withClientProvider } from '@dxos/react-client/testing';
12
+ import { withLayout, withTheme } from '@dxos/storybook-utils';
13
+
14
+ import { TriggerEditor } from './TriggerEditor';
15
+ import translations from '../../translations';
16
+ import { ChainPromptType } from '../../types';
17
+
18
+ const functions: Omit<FunctionDef, 'id'>[] = [
19
+ {
20
+ uri: 'dxos.org/function/email-worker',
21
+ route: '/email',
22
+ handler: 'email-worker',
23
+ description: 'Email Sync',
24
+ },
25
+ {
26
+ uri: 'dxos.org/function/gpt',
27
+ route: '/gpt',
28
+ handler: 'gpt',
29
+ description: 'GPT Chat',
30
+ },
31
+ ];
32
+
33
+ const Story = () => {
34
+ const [trigger, setTrigger] = useState<FunctionTrigger>();
35
+ const client = useClient();
36
+ const space = client.spaces.default;
37
+ useEffect(() => {
38
+ if (!space) {
39
+ return;
40
+ }
41
+
42
+ const trigger = space.db.add(create(FunctionTrigger, { function: '', spec: { type: 'timer', cron: '0 0 * * *' } }));
43
+ setTrigger(trigger);
44
+ }, [space, setTrigger]);
45
+ if (!space || !trigger) {
46
+ return <div />;
47
+ }
48
+
49
+ return (
50
+ <div role='none' className='flex w-[350px] border border-separator overflow-hidden'>
51
+ <TriggerEditor space={space} trigger={trigger} />
52
+ </div>
53
+ );
54
+ };
55
+
56
+ export const Default = {};
57
+
58
+ const meta: Meta = {
59
+ title: 'plugins/plugin-automation/TriggerEditor',
60
+ component: TriggerEditor,
61
+ render: Story,
62
+ decorators: [
63
+ withClientProvider({
64
+ createIdentity: true,
65
+ createSpace: true,
66
+ types: [FunctionTrigger, FunctionDef, ChainPromptType],
67
+ onInitialized: (client) => {
68
+ const space = client.spaces.default;
69
+ for (const fn of functions) {
70
+ space.db.add(create(FunctionDef, fn));
71
+ }
72
+ },
73
+ }),
74
+ withLayout({ fullscreen: true, classNames: 'flex justify-center m-2' }),
75
+ withTheme,
76
+ ],
77
+ parameters: {
78
+ translations,
79
+ },
80
+ };
81
+
82
+ export default meta;