@dxos/plugin-automation 0.6.14-staging.9e90729
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/LICENSE +8 -0
- package/README.md +15 -0
- package/dist/lib/browser/PromptContainer-RFMJXMUA.mjs +19 -0
- package/dist/lib/browser/PromptContainer-RFMJXMUA.mjs.map +7 -0
- package/dist/lib/browser/chunk-3TNRXJTD.mjs +14 -0
- package/dist/lib/browser/chunk-3TNRXJTD.mjs.map +7 -0
- package/dist/lib/browser/chunk-GGA62V7D.mjs +55 -0
- package/dist/lib/browser/chunk-GGA62V7D.mjs.map +7 -0
- package/dist/lib/browser/chunk-PSSWFA6A.mjs +217 -0
- package/dist/lib/browser/chunk-PSSWFA6A.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +1135 -0
- package/dist/lib/browser/index.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -0
- package/dist/lib/browser/meta.mjs +9 -0
- package/dist/lib/browser/meta.mjs.map +7 -0
- package/dist/lib/browser/types/index.mjs +16 -0
- package/dist/lib/browser/types/index.mjs.map +7 -0
- package/dist/lib/node/PromptContainer-FRSY6FNL.cjs +45 -0
- package/dist/lib/node/PromptContainer-FRSY6FNL.cjs.map +7 -0
- package/dist/lib/node/chunk-E2H3AGKB.cjs +240 -0
- package/dist/lib/node/chunk-E2H3AGKB.cjs.map +7 -0
- package/dist/lib/node/chunk-N5IDAUFU.cjs +76 -0
- package/dist/lib/node/chunk-N5IDAUFU.cjs.map +7 -0
- package/dist/lib/node/chunk-UPPUTAPL.cjs +37 -0
- package/dist/lib/node/chunk-UPPUTAPL.cjs.map +7 -0
- package/dist/lib/node/index.cjs +1137 -0
- package/dist/lib/node/index.cjs.map +7 -0
- package/dist/lib/node/meta.cjs +30 -0
- package/dist/lib/node/meta.cjs.map +7 -0
- package/dist/lib/node/meta.json +1 -0
- package/dist/lib/node/types/index.cjs +38 -0
- package/dist/lib/node/types/index.cjs.map +7 -0
- package/dist/lib/node-esm/PromptContainer-4VHFPEQH.mjs +20 -0
- package/dist/lib/node-esm/PromptContainer-4VHFPEQH.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-HFTXKLRR.mjs +218 -0
- package/dist/lib/node-esm/chunk-HFTXKLRR.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-QAPWYK2P.mjs +16 -0
- package/dist/lib/node-esm/chunk-QAPWYK2P.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-UT6QKU6J.mjs +56 -0
- package/dist/lib/node-esm/chunk-UT6QKU6J.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +1136 -0
- package/dist/lib/node-esm/index.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -0
- package/dist/lib/node-esm/meta.mjs +10 -0
- package/dist/lib/node-esm/meta.mjs.map +7 -0
- package/dist/lib/node-esm/types/index.mjs +17 -0
- package/dist/lib/node-esm/types/index.mjs.map +7 -0
- package/dist/types/src/AutomationPlugin.d.ts +4 -0
- package/dist/types/src/AutomationPlugin.d.ts.map +1 -0
- package/dist/types/src/components/AutomationPanel.d.ts +3 -0
- package/dist/types/src/components/AutomationPanel.d.ts.map +1 -0
- package/dist/types/src/components/Chain.d.ts +12 -0
- package/dist/types/src/components/Chain.d.ts.map +1 -0
- package/dist/types/src/components/PromptContainer.d.ts +6 -0
- package/dist/types/src/components/PromptContainer.d.ts.map +1 -0
- package/dist/types/src/components/PromptEditor/PromptEditor.d.ts +10 -0
- package/dist/types/src/components/PromptEditor/PromptEditor.d.ts.map +1 -0
- package/dist/types/src/components/PromptEditor/PromptEditor.stories.d.ts +6 -0
- package/dist/types/src/components/PromptEditor/PromptEditor.stories.d.ts.map +1 -0
- package/dist/types/src/components/PromptEditor/index.d.ts +2 -0
- package/dist/types/src/components/PromptEditor/index.d.ts.map +1 -0
- package/dist/types/src/components/PromptEditor/prompt-extension.d.ts +4 -0
- package/dist/types/src/components/PromptEditor/prompt-extension.d.ts.map +1 -0
- package/dist/types/src/components/PromptEditor/types.d.ts +18 -0
- package/dist/types/src/components/PromptEditor/types.d.ts.map +1 -0
- package/dist/types/src/components/TriggerEditor/Form.d.ts +5 -0
- package/dist/types/src/components/TriggerEditor/Form.d.ts.map +1 -0
- package/dist/types/src/components/TriggerEditor/TriggerEditor.d.ts +8 -0
- package/dist/types/src/components/TriggerEditor/TriggerEditor.d.ts.map +1 -0
- package/dist/types/src/components/TriggerEditor/TriggerEditor.stories.d.ts +5 -0
- package/dist/types/src/components/TriggerEditor/TriggerEditor.stories.d.ts.map +1 -0
- package/dist/types/src/components/TriggerEditor/email.d.ts +4 -0
- package/dist/types/src/components/TriggerEditor/email.d.ts.map +1 -0
- package/dist/types/src/components/TriggerEditor/index.d.ts +2 -0
- package/dist/types/src/components/TriggerEditor/index.d.ts.map +1 -0
- package/dist/types/src/components/TriggerEditor/invokation-handler.d.ts +5 -0
- package/dist/types/src/components/TriggerEditor/invokation-handler.d.ts.map +1 -0
- package/dist/types/src/components/TriggerEditor/meta.d.ts +25 -0
- package/dist/types/src/components/TriggerEditor/meta.d.ts.map +1 -0
- package/dist/types/src/components/index.d.ts +6 -0
- package/dist/types/src/components/index.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +7 -0
- package/dist/types/src/index.d.ts.map +1 -0
- package/dist/types/src/meta.d.ts +9 -0
- package/dist/types/src/meta.d.ts.map +1 -0
- package/dist/types/src/presets.d.ts +9 -0
- package/dist/types/src/presets.d.ts.map +1 -0
- package/dist/types/src/translations.d.ts +17 -0
- package/dist/types/src/translations.d.ts.map +1 -0
- package/dist/types/src/types/chain.d.ts +71 -0
- package/dist/types/src/types/chain.d.ts.map +1 -0
- package/dist/types/src/types/index.d.ts +3 -0
- package/dist/types/src/types/index.d.ts.map +1 -0
- package/dist/types/src/types/types.d.ts +7 -0
- package/dist/types/src/types/types.d.ts.map +1 -0
- package/package.json +98 -0
- package/src/AutomationPlugin.tsx +149 -0
- package/src/components/AutomationPanel.tsx +21 -0
- package/src/components/Chain.tsx +66 -0
- package/src/components/PromptContainer.tsx +19 -0
- package/src/components/PromptEditor/PromptEditor.stories.tsx +64 -0
- package/src/components/PromptEditor/PromptEditor.tsx +222 -0
- package/src/components/PromptEditor/index.ts +5 -0
- package/src/components/PromptEditor/prompt-extension.ts +43 -0
- package/src/components/PromptEditor/types.tsx +28 -0
- package/src/components/TriggerEditor/Form.tsx +18 -0
- package/src/components/TriggerEditor/TriggerEditor.stories.tsx +82 -0
- package/src/components/TriggerEditor/TriggerEditor.tsx +346 -0
- package/src/components/TriggerEditor/email.ts +49 -0
- package/src/components/TriggerEditor/index.ts +5 -0
- package/src/components/TriggerEditor/invokation-handler.ts +110 -0
- package/src/components/TriggerEditor/meta.tsx +225 -0
- package/src/components/index.ts +12 -0
- package/src/index.ts +12 -0
- package/src/meta.ts +14 -0
- package/src/presets.ts +248 -0
- package/src/translations.ts +30 -0
- package/src/types/chain.ts +38 -0
- package/src/types/index.ts +6 -0
- package/src/types/types.ts +27 -0
|
@@ -0,0 +1,1135 @@
|
|
|
1
|
+
import {
|
|
2
|
+
PromptEditor
|
|
3
|
+
} from "./chunk-PSSWFA6A.mjs";
|
|
4
|
+
import {
|
|
5
|
+
AutomationAction,
|
|
6
|
+
ChainInputSchema,
|
|
7
|
+
ChainInputType,
|
|
8
|
+
ChainPromptType,
|
|
9
|
+
ChainType
|
|
10
|
+
} from "./chunk-GGA62V7D.mjs";
|
|
11
|
+
import {
|
|
12
|
+
AUTOMATION_PLUGIN,
|
|
13
|
+
meta_default
|
|
14
|
+
} from "./chunk-3TNRXJTD.mjs";
|
|
15
|
+
|
|
16
|
+
// packages/plugins/experimental/plugin-automation/src/AutomationPlugin.tsx
|
|
17
|
+
import React6 from "react";
|
|
18
|
+
import { parseMetadataResolverPlugin, resolvePlugin } from "@dxos/app-framework";
|
|
19
|
+
import { FunctionDef, FunctionTrigger as FunctionTrigger2 } from "@dxos/functions/types";
|
|
20
|
+
import { invariant as invariant2 } from "@dxos/invariant";
|
|
21
|
+
import { parseClientPlugin } from "@dxos/plugin-client";
|
|
22
|
+
import { createExtension, toSignal } from "@dxos/plugin-graph";
|
|
23
|
+
import { getTypename, loadObjectReferences, parseId } from "@dxos/react-client/echo";
|
|
24
|
+
|
|
25
|
+
// packages/plugins/experimental/plugin-automation/src/components/index.ts
|
|
26
|
+
import { lazy } from "react";
|
|
27
|
+
|
|
28
|
+
// packages/plugins/experimental/plugin-automation/src/components/AutomationPanel.tsx
|
|
29
|
+
import React from "react";
|
|
30
|
+
import { Button, Icon, Toolbar } from "@dxos/react-ui";
|
|
31
|
+
var AutomationPanel = () => {
|
|
32
|
+
const handleCreate = () => {
|
|
33
|
+
};
|
|
34
|
+
return /* @__PURE__ */ React.createElement("div", {
|
|
35
|
+
className: "flex flex-col"
|
|
36
|
+
}, /* @__PURE__ */ React.createElement(Toolbar.Root, {
|
|
37
|
+
classNames: "p-2"
|
|
38
|
+
}, /* @__PURE__ */ React.createElement(Button, {
|
|
39
|
+
onClick: handleCreate
|
|
40
|
+
}, /* @__PURE__ */ React.createElement(Icon, {
|
|
41
|
+
icon: "ph--plus--regular"
|
|
42
|
+
}))));
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
// packages/plugins/experimental/plugin-automation/src/components/Chain.tsx
|
|
46
|
+
import React2 from "react";
|
|
47
|
+
import { getSpace } from "@dxos/react-client/echo";
|
|
48
|
+
import { Select, useTranslation } from "@dxos/react-ui";
|
|
49
|
+
import { nonNullable } from "@dxos/util";
|
|
50
|
+
|
|
51
|
+
// packages/plugins/experimental/plugin-automation/src/presets.ts
|
|
52
|
+
import { create } from "@dxos/echo-schema";
|
|
53
|
+
var str = (...text) => text.filter((value) => value !== void 0 && value !== false).flat().join("\n");
|
|
54
|
+
var chainPresets = [
|
|
55
|
+
{
|
|
56
|
+
id: "dxos.org/prompt/translate",
|
|
57
|
+
title: "Translate",
|
|
58
|
+
createPrompt: () => create(ChainPromptType, {
|
|
59
|
+
command: "say",
|
|
60
|
+
template: str(
|
|
61
|
+
// prettier-ignore
|
|
62
|
+
"Translate the following into {language}:",
|
|
63
|
+
"",
|
|
64
|
+
"---",
|
|
65
|
+
"",
|
|
66
|
+
"{input}"
|
|
67
|
+
),
|
|
68
|
+
inputs: [
|
|
69
|
+
{
|
|
70
|
+
type: ChainInputType.VALUE,
|
|
71
|
+
name: "language",
|
|
72
|
+
value: "japanese"
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
type: ChainInputType.PASS_THROUGH,
|
|
76
|
+
name: "input"
|
|
77
|
+
}
|
|
78
|
+
]
|
|
79
|
+
})
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
id: "dxos.org/prompt/chess",
|
|
83
|
+
title: "Chess",
|
|
84
|
+
createPrompt: () => create(ChainPromptType, {
|
|
85
|
+
command: "hint",
|
|
86
|
+
template: str(
|
|
87
|
+
// prettier-ignore
|
|
88
|
+
"You are a machine that is an expert chess player.",
|
|
89
|
+
"",
|
|
90
|
+
"The move history of the current game is: {history}",
|
|
91
|
+
"",
|
|
92
|
+
"Suggest the next move and very briefly explain your strategy in a couple of sentences."
|
|
93
|
+
),
|
|
94
|
+
inputs: [
|
|
95
|
+
{
|
|
96
|
+
type: ChainInputType.CONTEXT,
|
|
97
|
+
name: "history",
|
|
98
|
+
value: "object.pgn"
|
|
99
|
+
}
|
|
100
|
+
]
|
|
101
|
+
})
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
id: "dxos.org/prompt/mermaid",
|
|
105
|
+
title: "Mermaid",
|
|
106
|
+
createPrompt: () => create(ChainPromptType, {
|
|
107
|
+
command: "draw",
|
|
108
|
+
template: str(
|
|
109
|
+
// prettier-ignore
|
|
110
|
+
"Create a simplified mermaid graph representing the text below.",
|
|
111
|
+
"Do not explain anything.",
|
|
112
|
+
"",
|
|
113
|
+
"---",
|
|
114
|
+
"",
|
|
115
|
+
"{input}"
|
|
116
|
+
),
|
|
117
|
+
inputs: [
|
|
118
|
+
{
|
|
119
|
+
type: ChainInputType.PASS_THROUGH,
|
|
120
|
+
name: "input"
|
|
121
|
+
}
|
|
122
|
+
]
|
|
123
|
+
})
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
id: "dxos.org/prompt/list",
|
|
127
|
+
title: "List",
|
|
128
|
+
createPrompt: () => create(ChainPromptType, {
|
|
129
|
+
command: "list",
|
|
130
|
+
template: str(
|
|
131
|
+
// prettier-ignore
|
|
132
|
+
"You are a machine that only replies with valid, iterable RFC8259 compliant JSON in your responses.",
|
|
133
|
+
"Your entire response should be a single array of JSON objects.",
|
|
134
|
+
"",
|
|
135
|
+
"Your entire response should be a map where the key is the type and the value is a single array of JSON objects conforming to the following types:",
|
|
136
|
+
"",
|
|
137
|
+
"{schema}",
|
|
138
|
+
"",
|
|
139
|
+
"---",
|
|
140
|
+
"",
|
|
141
|
+
"{question}"
|
|
142
|
+
),
|
|
143
|
+
inputs: [
|
|
144
|
+
{
|
|
145
|
+
type: ChainInputType.SCHEMA,
|
|
146
|
+
name: "schema",
|
|
147
|
+
value: "example.com/type/project"
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
type: ChainInputType.PASS_THROUGH,
|
|
151
|
+
name: "question"
|
|
152
|
+
}
|
|
153
|
+
]
|
|
154
|
+
})
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
id: "dxos.org/prompt/base",
|
|
158
|
+
title: "RAG",
|
|
159
|
+
createPrompt: () => create(ChainPromptType, {
|
|
160
|
+
command: "rag",
|
|
161
|
+
template: str(
|
|
162
|
+
// prettier-ignore
|
|
163
|
+
"Very briefly answer the question based only on the following context and say if you don't know the answer.",
|
|
164
|
+
// 'answer the question using the following context as well as your training data:',
|
|
165
|
+
"",
|
|
166
|
+
"{context}",
|
|
167
|
+
"",
|
|
168
|
+
"---",
|
|
169
|
+
"",
|
|
170
|
+
"question: {question}"
|
|
171
|
+
),
|
|
172
|
+
inputs: [
|
|
173
|
+
{
|
|
174
|
+
type: ChainInputType.RETRIEVER,
|
|
175
|
+
name: "context"
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
type: ChainInputType.CONTEXT,
|
|
179
|
+
name: "question",
|
|
180
|
+
value: "object.text"
|
|
181
|
+
}
|
|
182
|
+
]
|
|
183
|
+
})
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
id: "dxos.org/prompt/lookup",
|
|
187
|
+
title: "Lookup",
|
|
188
|
+
createPrompt: () => create(ChainPromptType, {
|
|
189
|
+
command: "lookup",
|
|
190
|
+
template: str(
|
|
191
|
+
// prettier-ignore
|
|
192
|
+
"Lookup and very briefly summarize the following topic in one or two sentences:",
|
|
193
|
+
"",
|
|
194
|
+
"---",
|
|
195
|
+
"",
|
|
196
|
+
"{input}"
|
|
197
|
+
),
|
|
198
|
+
inputs: [
|
|
199
|
+
{
|
|
200
|
+
type: ChainInputType.CONTEXT,
|
|
201
|
+
name: "input",
|
|
202
|
+
value: "text"
|
|
203
|
+
}
|
|
204
|
+
]
|
|
205
|
+
})
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
id: "dxos.org/prompt/extract",
|
|
209
|
+
title: "Extract",
|
|
210
|
+
createPrompt: () => create(ChainPromptType, {
|
|
211
|
+
command: "extract",
|
|
212
|
+
template: str(
|
|
213
|
+
// prettier-ignore
|
|
214
|
+
"List all people and companies mentioned in the text below.",
|
|
215
|
+
"",
|
|
216
|
+
"You are a machine that only replies with valid, iterable RFC8259 compliant JSON in your responses.",
|
|
217
|
+
"Your entire response should be a map where the key is the type and the value is a single array of JSON objects conforming to the following types:",
|
|
218
|
+
"",
|
|
219
|
+
"{contact}",
|
|
220
|
+
"{company}",
|
|
221
|
+
"",
|
|
222
|
+
"---",
|
|
223
|
+
"",
|
|
224
|
+
"{input}"
|
|
225
|
+
),
|
|
226
|
+
inputs: [
|
|
227
|
+
{
|
|
228
|
+
type: ChainInputType.SCHEMA,
|
|
229
|
+
name: "contact",
|
|
230
|
+
value: "example.com/type/contact"
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
type: ChainInputType.SCHEMA,
|
|
234
|
+
name: "company",
|
|
235
|
+
value: "example.com/type/organization"
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
type: ChainInputType.CONTEXT,
|
|
239
|
+
name: "input",
|
|
240
|
+
value: "text"
|
|
241
|
+
}
|
|
242
|
+
]
|
|
243
|
+
})
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
id: "dxos.org/prompt/discord",
|
|
247
|
+
title: "Summarize",
|
|
248
|
+
createPrompt: () => create(ChainPromptType, {
|
|
249
|
+
command: "summarize",
|
|
250
|
+
template: str(
|
|
251
|
+
// prettier-ignore
|
|
252
|
+
"Summarize what the team is working on and format it as a markdown table without any explanation.",
|
|
253
|
+
"",
|
|
254
|
+
"---",
|
|
255
|
+
"",
|
|
256
|
+
"{context}"
|
|
257
|
+
),
|
|
258
|
+
inputs: [
|
|
259
|
+
{
|
|
260
|
+
type: ChainInputType.RESOLVER,
|
|
261
|
+
name: "context",
|
|
262
|
+
value: "discord.messages.recent"
|
|
263
|
+
}
|
|
264
|
+
]
|
|
265
|
+
})
|
|
266
|
+
}
|
|
267
|
+
];
|
|
268
|
+
|
|
269
|
+
// packages/plugins/experimental/plugin-automation/src/components/Chain.tsx
|
|
270
|
+
var Chain = ({ chain }) => {
|
|
271
|
+
const space = getSpace(chain);
|
|
272
|
+
if (!space) {
|
|
273
|
+
return null;
|
|
274
|
+
}
|
|
275
|
+
const handleSelectPreset = (preset) => {
|
|
276
|
+
chain.name = preset.title;
|
|
277
|
+
chain.prompts?.filter(nonNullable).forEach((prompt) => space.db.remove(prompt));
|
|
278
|
+
chain.prompts = [
|
|
279
|
+
preset.createPrompt()
|
|
280
|
+
];
|
|
281
|
+
};
|
|
282
|
+
return /* @__PURE__ */ React2.createElement("div", {
|
|
283
|
+
className: "flex flex-col my-2 gap-4"
|
|
284
|
+
}, chain.prompts?.filter(nonNullable).map((prompt, i) => /* @__PURE__ */ React2.createElement(PromptEditor, {
|
|
285
|
+
key: i,
|
|
286
|
+
prompt
|
|
287
|
+
})), /* @__PURE__ */ React2.createElement("div", {
|
|
288
|
+
className: "p-2"
|
|
289
|
+
}, /* @__PURE__ */ React2.createElement(ChainPresets, {
|
|
290
|
+
presets: chainPresets,
|
|
291
|
+
onSelect: handleSelectPreset
|
|
292
|
+
})));
|
|
293
|
+
};
|
|
294
|
+
var ChainPresets = ({ presets, onSelect }) => {
|
|
295
|
+
const { t } = useTranslation(AUTOMATION_PLUGIN);
|
|
296
|
+
return /* @__PURE__ */ React2.createElement(Select.Root, {
|
|
297
|
+
onValueChange: (value) => {
|
|
298
|
+
onSelect(presets.find(({ id }) => id === value));
|
|
299
|
+
}
|
|
300
|
+
}, /* @__PURE__ */ React2.createElement(Select.TriggerButton, {
|
|
301
|
+
classNames: "w-full",
|
|
302
|
+
placeholder: t("select preset template placeholder")
|
|
303
|
+
}), /* @__PURE__ */ React2.createElement(Select.Portal, null, /* @__PURE__ */ React2.createElement(Select.Content, null, /* @__PURE__ */ React2.createElement(Select.Viewport, null, presets.map(({ id, title }) => /* @__PURE__ */ React2.createElement(Select.Option, {
|
|
304
|
+
key: id,
|
|
305
|
+
value: id
|
|
306
|
+
}, title))))));
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
// packages/plugins/experimental/plugin-automation/src/components/TriggerEditor/TriggerEditor.tsx
|
|
310
|
+
import React5, { useEffect, useMemo, useState } from "react";
|
|
311
|
+
import { Mutex } from "@dxos/async";
|
|
312
|
+
import { Context } from "@dxos/context";
|
|
313
|
+
import { createSubscriptionTrigger, createWebsocketTrigger } from "@dxos/functions";
|
|
314
|
+
import { FunctionTrigger } from "@dxos/functions/types";
|
|
315
|
+
import { log as log3 } from "@dxos/log";
|
|
316
|
+
import { ScriptType } from "@dxos/plugin-script/types";
|
|
317
|
+
import { useClient } from "@dxos/react-client";
|
|
318
|
+
import { Filter as Filter2, useQuery } from "@dxos/react-client/echo";
|
|
319
|
+
import { Input as Input3, Select as Select2 } from "@dxos/react-ui";
|
|
320
|
+
import { distinctBy } from "@dxos/util";
|
|
321
|
+
|
|
322
|
+
// packages/plugins/experimental/plugin-automation/src/components/TriggerEditor/Form.tsx
|
|
323
|
+
import React3 from "react";
|
|
324
|
+
import { Input } from "@dxos/react-ui";
|
|
325
|
+
var InputRow = ({ label, children }) => /* @__PURE__ */ React3.createElement(Input.Root, null, /* @__PURE__ */ React3.createElement("tr", null, /* @__PURE__ */ React3.createElement("td", {
|
|
326
|
+
className: "w-[80px] px-2 text-right align-top pt-3 overflow-hidden"
|
|
327
|
+
}, /* @__PURE__ */ React3.createElement(Input.Label, {
|
|
328
|
+
classNames: "truncate text-xs"
|
|
329
|
+
}, label)), /* @__PURE__ */ React3.createElement("td", {
|
|
330
|
+
className: "p-1 pr-2"
|
|
331
|
+
}, children)));
|
|
332
|
+
|
|
333
|
+
// packages/plugins/experimental/plugin-automation/src/components/TriggerEditor/invokation-handler.ts
|
|
334
|
+
import { sleep } from "@dxos/async";
|
|
335
|
+
import { getObjectCore } from "@dxos/echo-db";
|
|
336
|
+
import { invariant } from "@dxos/invariant";
|
|
337
|
+
import { DXN, LOCAL_SPACE_TAG } from "@dxos/keys";
|
|
338
|
+
import { log as log2 } from "@dxos/log";
|
|
339
|
+
import { FunctionType } from "@dxos/plugin-script";
|
|
340
|
+
|
|
341
|
+
// packages/plugins/experimental/plugin-automation/src/components/TriggerEditor/email.ts
|
|
342
|
+
import { findObjectWithForeignKey } from "@dxos/echo-db";
|
|
343
|
+
import { create as create2, foreignKey } from "@dxos/echo-schema";
|
|
344
|
+
import { log } from "@dxos/log";
|
|
345
|
+
import { MailboxType } from "@dxos/plugin-inbox/types";
|
|
346
|
+
import { MessageType } from "@dxos/plugin-space/types";
|
|
347
|
+
import { Filter } from "@dxos/react-client/echo";
|
|
348
|
+
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/plugins/experimental/plugin-automation/src/components/TriggerEditor/email.ts";
|
|
349
|
+
var SOURCE_ID = "hub.dxos.network/api/mailbox";
|
|
350
|
+
var handleEmail = async (space, data) => {
|
|
351
|
+
const { messages } = data;
|
|
352
|
+
const { objects: mailboxes } = await space.db.query(Filter.schema(MailboxType)).run();
|
|
353
|
+
const mailbox = mailboxes[0] ?? space.db.add(create2(MailboxType, {
|
|
354
|
+
messages: []
|
|
355
|
+
}));
|
|
356
|
+
log.info("messages", {
|
|
357
|
+
count: messages.length,
|
|
358
|
+
existingMailbox: mailboxes.length > 0
|
|
359
|
+
}, {
|
|
360
|
+
F: __dxlog_file,
|
|
361
|
+
L: 21,
|
|
362
|
+
S: void 0,
|
|
363
|
+
C: (f, a) => f(...a)
|
|
364
|
+
});
|
|
365
|
+
const { objects } = await space.db.query(Filter.schema(MessageType)).run();
|
|
366
|
+
for (const message of messages) {
|
|
367
|
+
let object = findObjectWithForeignKey(objects, {
|
|
368
|
+
source: SOURCE_ID,
|
|
369
|
+
id: String(message.id)
|
|
370
|
+
});
|
|
371
|
+
if (!object) {
|
|
372
|
+
object = space.db.add(create2(MessageType, {
|
|
373
|
+
sender: {
|
|
374
|
+
email: message.from
|
|
375
|
+
},
|
|
376
|
+
timestamp: new Date(message.created).toISOString(),
|
|
377
|
+
text: message.body,
|
|
378
|
+
properties: {
|
|
379
|
+
subject: message.subject,
|
|
380
|
+
to: [
|
|
381
|
+
{
|
|
382
|
+
email: message.to
|
|
383
|
+
}
|
|
384
|
+
]
|
|
385
|
+
}
|
|
386
|
+
}, {
|
|
387
|
+
keys: [
|
|
388
|
+
foreignKey(SOURCE_ID, String(message.id))
|
|
389
|
+
]
|
|
390
|
+
}));
|
|
391
|
+
mailbox.messages?.push(object);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
return 200;
|
|
395
|
+
};
|
|
396
|
+
|
|
397
|
+
// packages/plugins/experimental/plugin-automation/src/components/TriggerEditor/invokation-handler.ts
|
|
398
|
+
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/plugins/experimental/plugin-automation/src/components/TriggerEditor/invokation-handler.ts";
|
|
399
|
+
var MAX_RETRIES = 3;
|
|
400
|
+
var RETRY_DELAY = 1e3;
|
|
401
|
+
var callFunction = async (funcUrl, trigger, data) => {
|
|
402
|
+
const body = {
|
|
403
|
+
event: "trigger",
|
|
404
|
+
trigger,
|
|
405
|
+
data
|
|
406
|
+
};
|
|
407
|
+
let retryCount = 0;
|
|
408
|
+
while (retryCount < MAX_RETRIES) {
|
|
409
|
+
log2.info("exec", {
|
|
410
|
+
funcUrl,
|
|
411
|
+
body,
|
|
412
|
+
retryCount
|
|
413
|
+
}, {
|
|
414
|
+
F: __dxlog_file2,
|
|
415
|
+
L: 26,
|
|
416
|
+
S: void 0,
|
|
417
|
+
C: (f, a) => f(...a)
|
|
418
|
+
});
|
|
419
|
+
const response = await fetch(funcUrl, {
|
|
420
|
+
method: "POST",
|
|
421
|
+
headers: {
|
|
422
|
+
"Content-Type": "application/json"
|
|
423
|
+
},
|
|
424
|
+
body: JSON.stringify(body)
|
|
425
|
+
});
|
|
426
|
+
const data2 = await response.text();
|
|
427
|
+
log2.info("response", {
|
|
428
|
+
status: response.status,
|
|
429
|
+
body: data2
|
|
430
|
+
}, {
|
|
431
|
+
F: __dxlog_file2,
|
|
432
|
+
L: 36,
|
|
433
|
+
S: void 0,
|
|
434
|
+
C: (f, a) => f(...a)
|
|
435
|
+
});
|
|
436
|
+
if (response.status === 409) {
|
|
437
|
+
retryCount++;
|
|
438
|
+
await sleep(RETRY_DELAY * Math.min(retryCount, 2));
|
|
439
|
+
continue;
|
|
440
|
+
}
|
|
441
|
+
return {
|
|
442
|
+
status: response.status,
|
|
443
|
+
data: data2
|
|
444
|
+
};
|
|
445
|
+
}
|
|
446
|
+
return {
|
|
447
|
+
status: 500
|
|
448
|
+
};
|
|
449
|
+
};
|
|
450
|
+
var invokeFunction = async (client, space, trigger, data) => {
|
|
451
|
+
try {
|
|
452
|
+
if (trigger.spec.type === "websocket") {
|
|
453
|
+
return handleEmail(space, data.data);
|
|
454
|
+
}
|
|
455
|
+
const script = await space.crud.query({
|
|
456
|
+
id: trigger.function
|
|
457
|
+
}).first();
|
|
458
|
+
const { objects: functions } = await space.crud.query({
|
|
459
|
+
__typename: FunctionType.typename
|
|
460
|
+
}).run();
|
|
461
|
+
const func = functions.find((fn) => referenceEquals(fn.source, trigger.function));
|
|
462
|
+
const funcSlug = func?.__meta.keys.find((key) => key.source === USERFUNCTIONS_META_KEY)?.id;
|
|
463
|
+
if (!funcSlug) {
|
|
464
|
+
log2.warn("function not deployed", {
|
|
465
|
+
scriptId: script.id,
|
|
466
|
+
name: script.name
|
|
467
|
+
}, {
|
|
468
|
+
F: __dxlog_file2,
|
|
469
|
+
L: 59,
|
|
470
|
+
S: void 0,
|
|
471
|
+
C: (f, a) => f(...a)
|
|
472
|
+
});
|
|
473
|
+
return 404;
|
|
474
|
+
}
|
|
475
|
+
const funcUrl = getFunctionUrl(client.config, funcSlug, space.id);
|
|
476
|
+
const triggerData = {
|
|
477
|
+
...getObjectCore(trigger).toPlainObject(),
|
|
478
|
+
// TODO: Remove when functions can query by DXN.
|
|
479
|
+
promptId: trigger.meta?.prompt?.id
|
|
480
|
+
};
|
|
481
|
+
return (await callFunction(funcUrl, triggerData, data)).status;
|
|
482
|
+
} catch (err) {
|
|
483
|
+
return 400;
|
|
484
|
+
}
|
|
485
|
+
};
|
|
486
|
+
var USERFUNCTIONS_META_KEY = "dxos.org/service/function";
|
|
487
|
+
var getFunctionUrl = (config, slug, spaceId) => {
|
|
488
|
+
const baseUrl = new URL("functions/", config.values.runtime?.services?.edge?.url);
|
|
489
|
+
const relativeUrl = slug.replace(/^\//, "");
|
|
490
|
+
const url = new URL(`./${relativeUrl}`, baseUrl.toString());
|
|
491
|
+
spaceId && url.searchParams.set("spaceId", spaceId);
|
|
492
|
+
url.protocol = "https";
|
|
493
|
+
return url.toString();
|
|
494
|
+
};
|
|
495
|
+
var referenceEquals = (a, b) => {
|
|
496
|
+
const aDXN = toDXN(a);
|
|
497
|
+
const bDXN = toDXN(b);
|
|
498
|
+
return aDXN.toString() === bDXN.toString();
|
|
499
|
+
};
|
|
500
|
+
var toDXN = (ref) => {
|
|
501
|
+
if (typeof ref === "string") {
|
|
502
|
+
if (ref.startsWith("dxn:")) {
|
|
503
|
+
return DXN.parse(ref);
|
|
504
|
+
} else {
|
|
505
|
+
return new DXN(DXN.kind.ECHO, [
|
|
506
|
+
LOCAL_SPACE_TAG,
|
|
507
|
+
ref
|
|
508
|
+
]);
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
invariant(typeof ref["/"] === "string", void 0, {
|
|
512
|
+
F: __dxlog_file2,
|
|
513
|
+
L: 108,
|
|
514
|
+
S: void 0,
|
|
515
|
+
A: [
|
|
516
|
+
"typeof ref['/'] === 'string'",
|
|
517
|
+
""
|
|
518
|
+
]
|
|
519
|
+
});
|
|
520
|
+
return DXN.parse(ref["/"]);
|
|
521
|
+
};
|
|
522
|
+
|
|
523
|
+
// packages/plugins/experimental/plugin-automation/src/components/TriggerEditor/meta.tsx
|
|
524
|
+
import React4 from "react";
|
|
525
|
+
import { create as create3, getMeta as getEchoMeta } from "@dxos/echo-schema";
|
|
526
|
+
import { GameType } from "@dxos/plugin-chess/types";
|
|
527
|
+
import { FileType } from "@dxos/plugin-ipfs/types";
|
|
528
|
+
import { DocumentType } from "@dxos/plugin-markdown";
|
|
529
|
+
import { DiagramType } from "@dxos/plugin-sketch/types";
|
|
530
|
+
import { CollectionType, MessageType as MessageType2 } from "@dxos/plugin-space";
|
|
531
|
+
import { Input as Input2 } from "@dxos/react-ui";
|
|
532
|
+
import { safeParseInt } from "@dxos/util";
|
|
533
|
+
var stateInitialValues = {
|
|
534
|
+
schemas: [
|
|
535
|
+
// TODO(burdon): Get all schema from API.
|
|
536
|
+
DocumentType,
|
|
537
|
+
FileType,
|
|
538
|
+
GameType,
|
|
539
|
+
MessageType2,
|
|
540
|
+
DiagramType,
|
|
541
|
+
CollectionType
|
|
542
|
+
],
|
|
543
|
+
selectedSchema: {}
|
|
544
|
+
};
|
|
545
|
+
var state = create3(stateInitialValues);
|
|
546
|
+
var USERFUNCTIONS_PRESET_META_KEY = "dxos.org/service/function-preset";
|
|
547
|
+
var getFunctionMetaExtension = (trigger, script) => {
|
|
548
|
+
if (script) {
|
|
549
|
+
const meta = getEchoMeta(script).keys.find((key) => key.source === USERFUNCTIONS_PRESET_META_KEY);
|
|
550
|
+
const extension = meta && metaExtensions[meta.id];
|
|
551
|
+
if (extension) {
|
|
552
|
+
return extension;
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
return trigger?.function ? metaExtensions[trigger.function] : metaExtensions["dxos.org/function/gpt"];
|
|
556
|
+
};
|
|
557
|
+
var DefaultMetaProps = ({ meta }) => {
|
|
558
|
+
return /* @__PURE__ */ React4.createElement(React4.Fragment, null);
|
|
559
|
+
};
|
|
560
|
+
var ChessMetaProps = ({ meta }) => {
|
|
561
|
+
if (!meta) {
|
|
562
|
+
return null;
|
|
563
|
+
}
|
|
564
|
+
return /* @__PURE__ */ React4.createElement(React4.Fragment, null, /* @__PURE__ */ React4.createElement(InputRow, {
|
|
565
|
+
label: "Level"
|
|
566
|
+
}, /* @__PURE__ */ React4.createElement(Input2.TextInput, {
|
|
567
|
+
type: "number",
|
|
568
|
+
value: meta.level ?? 1,
|
|
569
|
+
onChange: (event) => meta.level = safeParseInt(event.target.value),
|
|
570
|
+
placeholder: "Engine strength."
|
|
571
|
+
})));
|
|
572
|
+
};
|
|
573
|
+
var EmailWorkerMetaProps = ({ meta }) => {
|
|
574
|
+
if (!meta) {
|
|
575
|
+
return null;
|
|
576
|
+
}
|
|
577
|
+
return /* @__PURE__ */ React4.createElement(React4.Fragment, null, /* @__PURE__ */ React4.createElement(InputRow, {
|
|
578
|
+
label: "Account"
|
|
579
|
+
}, /* @__PURE__ */ React4.createElement(Input2.TextInput, {
|
|
580
|
+
value: meta.account ?? "",
|
|
581
|
+
onChange: (event) => meta.account = event.target.value,
|
|
582
|
+
placeholder: "https://"
|
|
583
|
+
})));
|
|
584
|
+
};
|
|
585
|
+
var ChainPromptMetaProps = ({ meta, triggerId }) => {
|
|
586
|
+
const schema = triggerId ? state.selectedSchema[triggerId] : void 0;
|
|
587
|
+
if (!meta) {
|
|
588
|
+
return null;
|
|
589
|
+
}
|
|
590
|
+
return /* @__PURE__ */ React4.createElement(React4.Fragment, null, /* @__PURE__ */ React4.createElement(InputRow, {
|
|
591
|
+
label: "Model"
|
|
592
|
+
}, /* @__PURE__ */ React4.createElement(Input2.TextInput, {
|
|
593
|
+
value: meta.model ?? "",
|
|
594
|
+
onChange: (event) => meta.model = event.target.value,
|
|
595
|
+
placeholder: "llama2"
|
|
596
|
+
})), /* @__PURE__ */ React4.createElement(InputRow, {
|
|
597
|
+
label: "Presets"
|
|
598
|
+
}, /* @__PURE__ */ React4.createElement(ChainPresets, {
|
|
599
|
+
presets: chainPresets,
|
|
600
|
+
onSelect: (preset) => {
|
|
601
|
+
meta.prompt = preset.createPrompt();
|
|
602
|
+
}
|
|
603
|
+
})), meta.prompt && /* @__PURE__ */ React4.createElement(InputRow, {
|
|
604
|
+
label: "Prompt"
|
|
605
|
+
}, /* @__PURE__ */ React4.createElement(PromptEditor, {
|
|
606
|
+
prompt: meta.prompt,
|
|
607
|
+
schema
|
|
608
|
+
})));
|
|
609
|
+
};
|
|
610
|
+
var EmbeddingMetaProps = ({ meta }) => {
|
|
611
|
+
if (!meta) {
|
|
612
|
+
return null;
|
|
613
|
+
}
|
|
614
|
+
return /* @__PURE__ */ React4.createElement(React4.Fragment, null, /* @__PURE__ */ React4.createElement(InputRow, {
|
|
615
|
+
label: "Model"
|
|
616
|
+
}, /* @__PURE__ */ React4.createElement(Input2.TextInput, {
|
|
617
|
+
value: meta.model ?? "",
|
|
618
|
+
onChange: (event) => meta.model = event.target.value,
|
|
619
|
+
placeholder: "llama2"
|
|
620
|
+
})));
|
|
621
|
+
};
|
|
622
|
+
var metaExtensions = {
|
|
623
|
+
__DEFAULT__: {
|
|
624
|
+
initialValue: () => ({}),
|
|
625
|
+
component: DefaultMetaProps
|
|
626
|
+
},
|
|
627
|
+
"dxos.org/function/chess": {
|
|
628
|
+
initialValue: () => ({
|
|
629
|
+
level: 2
|
|
630
|
+
}),
|
|
631
|
+
component: ChessMetaProps
|
|
632
|
+
},
|
|
633
|
+
"dxos.org/function/email-worker": {
|
|
634
|
+
initialValue: () => ({
|
|
635
|
+
account: "hello@dxos.network"
|
|
636
|
+
}),
|
|
637
|
+
component: EmailWorkerMetaProps
|
|
638
|
+
},
|
|
639
|
+
"dxos.org/function/gpt": {
|
|
640
|
+
initialValue: () => ({
|
|
641
|
+
model: "llama2"
|
|
642
|
+
}),
|
|
643
|
+
component: ChainPromptMetaProps
|
|
644
|
+
},
|
|
645
|
+
"dxos.org/function/embedding": {
|
|
646
|
+
initialValue: () => ({
|
|
647
|
+
model: "llama2"
|
|
648
|
+
}),
|
|
649
|
+
component: EmbeddingMetaProps
|
|
650
|
+
}
|
|
651
|
+
};
|
|
652
|
+
|
|
653
|
+
// packages/plugins/experimental/plugin-automation/src/components/TriggerEditor/TriggerEditor.tsx
|
|
654
|
+
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/plugins/experimental/plugin-automation/src/components/TriggerEditor/TriggerEditor.tsx";
|
|
655
|
+
var triggerTypes = [
|
|
656
|
+
"subscription",
|
|
657
|
+
"timer",
|
|
658
|
+
"webhook",
|
|
659
|
+
"websocket"
|
|
660
|
+
];
|
|
661
|
+
var registerTriggersMutex = new Mutex();
|
|
662
|
+
var TriggerEditor = ({ space, trigger }) => {
|
|
663
|
+
const client = useClient();
|
|
664
|
+
const scripts = useQuery(space, Filter2.schema(ScriptType));
|
|
665
|
+
const script = useMemo(() => scripts.find((script2) => script2.id === trigger.function), [
|
|
666
|
+
trigger.function,
|
|
667
|
+
scripts
|
|
668
|
+
]);
|
|
669
|
+
const [registry] = useState(/* @__PURE__ */ new Map());
|
|
670
|
+
const triggers = useQuery(space, Filter2.schema(FunctionTrigger));
|
|
671
|
+
useEffect(() => {
|
|
672
|
+
setTimeout(async () => {
|
|
673
|
+
await registerTriggersMutex.executeSynchronized(async () => {
|
|
674
|
+
const deprecated = new Set(Array.from(registry.keys()));
|
|
675
|
+
log3.info("triggers", {
|
|
676
|
+
deprecated,
|
|
677
|
+
all: triggers.map((t) => t.id),
|
|
678
|
+
enabled: triggers.filter((t) => t.enabled).map((t) => t.id)
|
|
679
|
+
}, {
|
|
680
|
+
F: __dxlog_file3,
|
|
681
|
+
L: 47,
|
|
682
|
+
S: void 0,
|
|
683
|
+
C: (f, a) => f(...a)
|
|
684
|
+
});
|
|
685
|
+
for (const trigger2 of triggers) {
|
|
686
|
+
if (trigger2.enabled) {
|
|
687
|
+
if (registry.has(trigger2.id)) {
|
|
688
|
+
deprecated.delete(trigger2.id);
|
|
689
|
+
continue;
|
|
690
|
+
}
|
|
691
|
+
log3.info("activating trigger", trigger2.id, {
|
|
692
|
+
F: __dxlog_file3,
|
|
693
|
+
L: 59,
|
|
694
|
+
S: void 0,
|
|
695
|
+
C: (f, a) => f(...a)
|
|
696
|
+
});
|
|
697
|
+
const ctx = new Context(void 0, {
|
|
698
|
+
F: __dxlog_file3,
|
|
699
|
+
L: 61
|
|
700
|
+
});
|
|
701
|
+
registry.set(trigger2.id, ctx);
|
|
702
|
+
const triggerSpec = trigger2.spec;
|
|
703
|
+
let triggerFactory;
|
|
704
|
+
if (triggerSpec.type === "subscription") {
|
|
705
|
+
triggerFactory = createSubscriptionTrigger;
|
|
706
|
+
} else if (triggerSpec.type === "websocket") {
|
|
707
|
+
triggerFactory = createWebsocketTrigger;
|
|
708
|
+
} else {
|
|
709
|
+
log3.info("unsupported trigger", {
|
|
710
|
+
type: triggerSpec.type
|
|
711
|
+
}, {
|
|
712
|
+
F: __dxlog_file3,
|
|
713
|
+
L: 71,
|
|
714
|
+
S: void 0,
|
|
715
|
+
C: (f, a) => f(...a)
|
|
716
|
+
});
|
|
717
|
+
continue;
|
|
718
|
+
}
|
|
719
|
+
await triggerFactory(ctx, space, trigger2.spec, (data) => {
|
|
720
|
+
return invokeFunction(client, space, trigger2, data);
|
|
721
|
+
});
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
for (const id of deprecated) {
|
|
725
|
+
const ctx = registry.get(id);
|
|
726
|
+
if (ctx) {
|
|
727
|
+
await ctx.dispose();
|
|
728
|
+
registry.delete(id);
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
});
|
|
732
|
+
});
|
|
733
|
+
}, [
|
|
734
|
+
JSON.stringify(triggers)
|
|
735
|
+
]);
|
|
736
|
+
useEffect(() => {
|
|
737
|
+
return () => {
|
|
738
|
+
for (const ctx of registry.values()) {
|
|
739
|
+
void ctx.dispose();
|
|
740
|
+
}
|
|
741
|
+
};
|
|
742
|
+
}, []);
|
|
743
|
+
useEffect(() => {
|
|
744
|
+
void space.db.schema.list().then((schemas) => {
|
|
745
|
+
state.schemas = distinctBy([
|
|
746
|
+
...state.schemas,
|
|
747
|
+
...schemas
|
|
748
|
+
], (schema) => schema.typename).sort((a, b) => a.typename < b.typename ? -1 : 1);
|
|
749
|
+
}).catch(() => {
|
|
750
|
+
});
|
|
751
|
+
}, [
|
|
752
|
+
space
|
|
753
|
+
]);
|
|
754
|
+
useEffect(() => {
|
|
755
|
+
const spec = trigger.spec;
|
|
756
|
+
if (spec.type === "subscription") {
|
|
757
|
+
if (spec.filter && spec.filter.length > 0) {
|
|
758
|
+
const type = spec.filter[0].type;
|
|
759
|
+
const foundSchema = state.schemas.find((schema) => schema.typename === type);
|
|
760
|
+
if (foundSchema) {
|
|
761
|
+
state.selectedSchema[trigger.id] = foundSchema;
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
}, [
|
|
766
|
+
JSON.stringify(trigger.spec),
|
|
767
|
+
state.schemas
|
|
768
|
+
]);
|
|
769
|
+
useEffect(() => {
|
|
770
|
+
if (!trigger.meta) {
|
|
771
|
+
const extension = getFunctionMetaExtension(trigger, script);
|
|
772
|
+
trigger.meta = extension?.initialValue?.();
|
|
773
|
+
}
|
|
774
|
+
}, [
|
|
775
|
+
trigger.function,
|
|
776
|
+
trigger.meta
|
|
777
|
+
]);
|
|
778
|
+
const handleSelectFunction = (value) => {
|
|
779
|
+
const match = scripts.find((fn) => fn.id === value);
|
|
780
|
+
if (match) {
|
|
781
|
+
trigger.function = match.id;
|
|
782
|
+
}
|
|
783
|
+
};
|
|
784
|
+
const handleSelectTriggerType = (triggerType) => {
|
|
785
|
+
switch (triggerType) {
|
|
786
|
+
case "subscription": {
|
|
787
|
+
trigger.spec = {
|
|
788
|
+
type: "subscription",
|
|
789
|
+
filter: []
|
|
790
|
+
};
|
|
791
|
+
break;
|
|
792
|
+
}
|
|
793
|
+
case "timer": {
|
|
794
|
+
trigger.spec = {
|
|
795
|
+
type: "timer",
|
|
796
|
+
cron: "0 0 * * *"
|
|
797
|
+
};
|
|
798
|
+
break;
|
|
799
|
+
}
|
|
800
|
+
case "webhook": {
|
|
801
|
+
trigger.spec = {
|
|
802
|
+
type: "webhook",
|
|
803
|
+
method: "GET"
|
|
804
|
+
};
|
|
805
|
+
break;
|
|
806
|
+
}
|
|
807
|
+
case "websocket": {
|
|
808
|
+
trigger.spec = {
|
|
809
|
+
type: "websocket",
|
|
810
|
+
url: "",
|
|
811
|
+
init: {
|
|
812
|
+
type: "sync"
|
|
813
|
+
}
|
|
814
|
+
};
|
|
815
|
+
break;
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
};
|
|
819
|
+
const TriggerMeta = getFunctionMetaExtension(trigger, script)?.component;
|
|
820
|
+
return /* @__PURE__ */ React5.createElement("div", {
|
|
821
|
+
className: "flex flex-col py-1"
|
|
822
|
+
}, /* @__PURE__ */ React5.createElement("table", {
|
|
823
|
+
className: "is-full table-fixed"
|
|
824
|
+
}, /* @__PURE__ */ React5.createElement("tbody", null, /* @__PURE__ */ React5.createElement(InputRow, {
|
|
825
|
+
label: "Function"
|
|
826
|
+
}, /* @__PURE__ */ React5.createElement(Select2.Root, {
|
|
827
|
+
value: script?.id,
|
|
828
|
+
onValueChange: handleSelectFunction
|
|
829
|
+
}, /* @__PURE__ */ React5.createElement(Select2.TriggerButton, {
|
|
830
|
+
placeholder: "Select function"
|
|
831
|
+
}), /* @__PURE__ */ React5.createElement(Select2.Portal, null, /* @__PURE__ */ React5.createElement(Select2.Content, null, /* @__PURE__ */ React5.createElement(Select2.Viewport, null, scripts.map(({ id, name }) => /* @__PURE__ */ React5.createElement(Select2.Option, {
|
|
832
|
+
key: id,
|
|
833
|
+
value: id
|
|
834
|
+
}, name ?? "Unnamed"))))))), script?.description?.length && /* @__PURE__ */ React5.createElement(InputRow, null, /* @__PURE__ */ React5.createElement("div", {
|
|
835
|
+
className: "px-2"
|
|
836
|
+
}, /* @__PURE__ */ React5.createElement("p", {
|
|
837
|
+
className: "text-sm text-description"
|
|
838
|
+
}, script?.description?.length))), /* @__PURE__ */ React5.createElement(InputRow, {
|
|
839
|
+
label: "Type"
|
|
840
|
+
}, /* @__PURE__ */ React5.createElement(Select2.Root, {
|
|
841
|
+
value: trigger.spec?.type,
|
|
842
|
+
onValueChange: handleSelectTriggerType
|
|
843
|
+
}, /* @__PURE__ */ React5.createElement(Select2.TriggerButton, {
|
|
844
|
+
placeholder: "Select trigger"
|
|
845
|
+
}), /* @__PURE__ */ React5.createElement(Select2.Portal, null, /* @__PURE__ */ React5.createElement(Select2.Content, null, /* @__PURE__ */ React5.createElement(Select2.Viewport, null, triggerTypes.map((trigger2) => /* @__PURE__ */ React5.createElement(Select2.Option, {
|
|
846
|
+
key: trigger2,
|
|
847
|
+
value: trigger2
|
|
848
|
+
}, trigger2)))))))), /* @__PURE__ */ React5.createElement("tbody", null, trigger.spec && /* @__PURE__ */ React5.createElement(TriggerSpec, {
|
|
849
|
+
space,
|
|
850
|
+
spec: trigger.spec
|
|
851
|
+
}), /* @__PURE__ */ React5.createElement(InputRow, {
|
|
852
|
+
label: "Enabled"
|
|
853
|
+
}, /* @__PURE__ */ React5.createElement("div", {
|
|
854
|
+
className: "flex items-center h-8"
|
|
855
|
+
}, /* @__PURE__ */ React5.createElement(Input3.Switch, {
|
|
856
|
+
checked: trigger.enabled,
|
|
857
|
+
onCheckedChange: (checked) => trigger.enabled = !!checked
|
|
858
|
+
})))), TriggerMeta && /* @__PURE__ */ React5.createElement("tbody", null, /* @__PURE__ */ React5.createElement("tr", null, /* @__PURE__ */ React5.createElement("td", null), /* @__PURE__ */ React5.createElement("td", {
|
|
859
|
+
className: "py-2"
|
|
860
|
+
}, /* @__PURE__ */ React5.createElement("div", {
|
|
861
|
+
className: "border-b border-separator"
|
|
862
|
+
}))), /* @__PURE__ */ React5.createElement(TriggerMeta, {
|
|
863
|
+
meta: trigger.meta
|
|
864
|
+
}))));
|
|
865
|
+
};
|
|
866
|
+
var TriggerSpecSubscription = ({ spec }) => {
|
|
867
|
+
if (!spec.filter) {
|
|
868
|
+
return null;
|
|
869
|
+
}
|
|
870
|
+
const handleSelectSchema = (typename) => {
|
|
871
|
+
spec.filter = [
|
|
872
|
+
{
|
|
873
|
+
type: typename
|
|
874
|
+
}
|
|
875
|
+
];
|
|
876
|
+
};
|
|
877
|
+
return /* @__PURE__ */ React5.createElement(React5.Fragment, null, /* @__PURE__ */ React5.createElement(InputRow, {
|
|
878
|
+
label: "Filter"
|
|
879
|
+
}, /* @__PURE__ */ React5.createElement(Select2.Root, {
|
|
880
|
+
value: spec.filter.length > 0 ? spec.filter[0].type : void 0,
|
|
881
|
+
onValueChange: handleSelectSchema
|
|
882
|
+
}, /* @__PURE__ */ React5.createElement(Select2.TriggerButton, {
|
|
883
|
+
classNames: "w-full",
|
|
884
|
+
placeholder: "Select type"
|
|
885
|
+
}), /* @__PURE__ */ React5.createElement(Select2.Portal, null, /* @__PURE__ */ React5.createElement(Select2.Content, null, /* @__PURE__ */ React5.createElement(Select2.Viewport, null, state.schemas.map(({ typename }) => /* @__PURE__ */ React5.createElement(Select2.Option, {
|
|
886
|
+
key: typename,
|
|
887
|
+
value: typename
|
|
888
|
+
}, typename))))))));
|
|
889
|
+
};
|
|
890
|
+
var TriggerSpecTimer = ({ spec }) => /* @__PURE__ */ React5.createElement(React5.Fragment, null, /* @__PURE__ */ React5.createElement(InputRow, {
|
|
891
|
+
label: "Cron"
|
|
892
|
+
}, /* @__PURE__ */ React5.createElement(Input3.TextInput, {
|
|
893
|
+
value: spec.cron,
|
|
894
|
+
onChange: (event) => spec.cron = event.target.value
|
|
895
|
+
})));
|
|
896
|
+
var methods = [
|
|
897
|
+
"GET",
|
|
898
|
+
"POST"
|
|
899
|
+
];
|
|
900
|
+
var TriggerSpecWebhook = ({ spec }) => /* @__PURE__ */ React5.createElement(React5.Fragment, null, /* @__PURE__ */ React5.createElement(InputRow, {
|
|
901
|
+
label: "Method"
|
|
902
|
+
}, /* @__PURE__ */ React5.createElement(Select2.Root, {
|
|
903
|
+
value: spec.method,
|
|
904
|
+
onValueChange: (value) => spec.method = value
|
|
905
|
+
}, /* @__PURE__ */ React5.createElement(Select2.TriggerButton, {
|
|
906
|
+
placeholder: "type"
|
|
907
|
+
}), /* @__PURE__ */ React5.createElement(Select2.Portal, null, /* @__PURE__ */ React5.createElement(Select2.Content, null, /* @__PURE__ */ React5.createElement(Select2.Viewport, null, methods.map((method) => /* @__PURE__ */ React5.createElement(Select2.Option, {
|
|
908
|
+
key: method,
|
|
909
|
+
value: method
|
|
910
|
+
}, method))))))));
|
|
911
|
+
var TriggerSpecWebsocket = ({ spec }) => {
|
|
912
|
+
const handleChangeInit = (event) => {
|
|
913
|
+
try {
|
|
914
|
+
spec.init = JSON.parse(event.target.value);
|
|
915
|
+
} catch (err) {
|
|
916
|
+
}
|
|
917
|
+
};
|
|
918
|
+
return /* @__PURE__ */ React5.createElement(React5.Fragment, null, /* @__PURE__ */ React5.createElement(InputRow, {
|
|
919
|
+
label: "Endpoint"
|
|
920
|
+
}, /* @__PURE__ */ React5.createElement(Input3.TextInput, {
|
|
921
|
+
value: spec.url,
|
|
922
|
+
onChange: (event) => spec.url = event.target.value,
|
|
923
|
+
placeholder: "https://"
|
|
924
|
+
})), /* @__PURE__ */ React5.createElement(InputRow, {
|
|
925
|
+
label: "Init"
|
|
926
|
+
}, /* @__PURE__ */ React5.createElement(Input3.TextInput, {
|
|
927
|
+
value: JSON.stringify(spec.init),
|
|
928
|
+
onChange: handleChangeInit,
|
|
929
|
+
placeholder: "Initial message."
|
|
930
|
+
})));
|
|
931
|
+
};
|
|
932
|
+
var triggerRenderers = {
|
|
933
|
+
subscription: TriggerSpecSubscription,
|
|
934
|
+
timer: TriggerSpecTimer,
|
|
935
|
+
webhook: TriggerSpecWebhook,
|
|
936
|
+
websocket: TriggerSpecWebsocket
|
|
937
|
+
};
|
|
938
|
+
var TriggerSpec = ({ space, spec }) => {
|
|
939
|
+
const Component = triggerRenderers[spec.type];
|
|
940
|
+
return Component ? /* @__PURE__ */ React5.createElement(Component, {
|
|
941
|
+
space,
|
|
942
|
+
spec
|
|
943
|
+
}) : null;
|
|
944
|
+
};
|
|
945
|
+
|
|
946
|
+
// packages/plugins/experimental/plugin-automation/src/components/index.ts
|
|
947
|
+
var PromptContainer = lazy(() => import("./PromptContainer-RFMJXMUA.mjs"));
|
|
948
|
+
|
|
949
|
+
// packages/plugins/experimental/plugin-automation/src/translations.ts
|
|
950
|
+
var translations_default = [
|
|
951
|
+
{
|
|
952
|
+
"en-US": {
|
|
953
|
+
[AUTOMATION_PLUGIN]: {
|
|
954
|
+
"plugin name": "Automation",
|
|
955
|
+
"object placeholder": "New prompt",
|
|
956
|
+
"create object label": "Create prompt",
|
|
957
|
+
"create trigger label": "Create trigger",
|
|
958
|
+
"create stack section label": "Create prompt",
|
|
959
|
+
"command placeholder": "Enter slash command...",
|
|
960
|
+
"template placeholder": "Enter template...",
|
|
961
|
+
"value placeholder": "Enter value...",
|
|
962
|
+
"select preset template placeholder": "Select preset"
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
];
|
|
967
|
+
|
|
968
|
+
// packages/plugins/experimental/plugin-automation/src/AutomationPlugin.tsx
|
|
969
|
+
var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/plugins/experimental/plugin-automation/src/AutomationPlugin.tsx";
|
|
970
|
+
var AutomationPlugin = () => {
|
|
971
|
+
return {
|
|
972
|
+
meta: meta_default,
|
|
973
|
+
provides: {
|
|
974
|
+
metadata: {
|
|
975
|
+
records: {
|
|
976
|
+
[ChainType.typename]: {
|
|
977
|
+
placeholder: [
|
|
978
|
+
"object placeholder",
|
|
979
|
+
{
|
|
980
|
+
ns: AUTOMATION_PLUGIN
|
|
981
|
+
}
|
|
982
|
+
],
|
|
983
|
+
icon: "ph--magic-wand--regular",
|
|
984
|
+
// TODO(wittjosiah): Move out of metadata.
|
|
985
|
+
loadReferences: (chain) => loadObjectReferences(chain, (chain2) => chain2.prompts)
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
},
|
|
989
|
+
translations: translations_default,
|
|
990
|
+
echo: {
|
|
991
|
+
schema: [
|
|
992
|
+
ChainType,
|
|
993
|
+
ChainPromptType,
|
|
994
|
+
FunctionDef,
|
|
995
|
+
FunctionTrigger2
|
|
996
|
+
]
|
|
997
|
+
},
|
|
998
|
+
graph: {
|
|
999
|
+
builder: (plugins) => {
|
|
1000
|
+
const clientPlugin = resolvePlugin(plugins, parseClientPlugin);
|
|
1001
|
+
const metadataPlugin = resolvePlugin(plugins, parseMetadataResolverPlugin);
|
|
1002
|
+
const resolve = metadataPlugin?.provides.metadata.resolver;
|
|
1003
|
+
const client = clientPlugin?.provides.client;
|
|
1004
|
+
invariant2(resolve, void 0, {
|
|
1005
|
+
F: __dxlog_file4,
|
|
1006
|
+
L: 46,
|
|
1007
|
+
S: void 0,
|
|
1008
|
+
A: [
|
|
1009
|
+
"resolve",
|
|
1010
|
+
""
|
|
1011
|
+
]
|
|
1012
|
+
});
|
|
1013
|
+
invariant2(client, void 0, {
|
|
1014
|
+
F: __dxlog_file4,
|
|
1015
|
+
L: 47,
|
|
1016
|
+
S: void 0,
|
|
1017
|
+
A: [
|
|
1018
|
+
"client",
|
|
1019
|
+
""
|
|
1020
|
+
]
|
|
1021
|
+
});
|
|
1022
|
+
return [
|
|
1023
|
+
// Create nodes for object settings.
|
|
1024
|
+
createExtension({
|
|
1025
|
+
id: `${AUTOMATION_PLUGIN}/automation-for-subject`,
|
|
1026
|
+
resolver: ({ id }) => {
|
|
1027
|
+
if (!id.endsWith("~automation")) {
|
|
1028
|
+
return;
|
|
1029
|
+
}
|
|
1030
|
+
const type = "orphan-settings-for-subject";
|
|
1031
|
+
const icon = "ph--magic-wand--regular";
|
|
1032
|
+
const [subjectId] = id.split("~");
|
|
1033
|
+
const { spaceId, objectId } = parseId(subjectId);
|
|
1034
|
+
const space = client.spaces.get().find((space2) => space2.id === spaceId);
|
|
1035
|
+
if (!objectId) {
|
|
1036
|
+
const label2 = space ? space.properties.name || [
|
|
1037
|
+
"unnamed space label",
|
|
1038
|
+
{
|
|
1039
|
+
ns: AUTOMATION_PLUGIN
|
|
1040
|
+
}
|
|
1041
|
+
] : [
|
|
1042
|
+
"unnamed object settings label",
|
|
1043
|
+
{
|
|
1044
|
+
ns: AUTOMATION_PLUGIN
|
|
1045
|
+
}
|
|
1046
|
+
];
|
|
1047
|
+
return {
|
|
1048
|
+
id,
|
|
1049
|
+
type,
|
|
1050
|
+
data: null,
|
|
1051
|
+
properties: {
|
|
1052
|
+
icon,
|
|
1053
|
+
label: label2,
|
|
1054
|
+
showResolvedThreads: false,
|
|
1055
|
+
object: null,
|
|
1056
|
+
space
|
|
1057
|
+
}
|
|
1058
|
+
};
|
|
1059
|
+
}
|
|
1060
|
+
const object = toSignal((onChange) => {
|
|
1061
|
+
const timeout = setTimeout(async () => {
|
|
1062
|
+
await space?.db.loadObjectById(objectId);
|
|
1063
|
+
onChange();
|
|
1064
|
+
});
|
|
1065
|
+
return () => clearTimeout(timeout);
|
|
1066
|
+
}, () => space?.db.getObjectById(objectId), subjectId);
|
|
1067
|
+
if (!object || !subjectId) {
|
|
1068
|
+
return;
|
|
1069
|
+
}
|
|
1070
|
+
const meta = resolve(getTypename(object) ?? "");
|
|
1071
|
+
const label = meta.label?.(object) || object.name || meta.placeholder || [
|
|
1072
|
+
"unnamed object settings label",
|
|
1073
|
+
{
|
|
1074
|
+
ns: AUTOMATION_PLUGIN
|
|
1075
|
+
}
|
|
1076
|
+
];
|
|
1077
|
+
return {
|
|
1078
|
+
id,
|
|
1079
|
+
type,
|
|
1080
|
+
data: null,
|
|
1081
|
+
properties: {
|
|
1082
|
+
icon,
|
|
1083
|
+
label,
|
|
1084
|
+
object
|
|
1085
|
+
}
|
|
1086
|
+
};
|
|
1087
|
+
}
|
|
1088
|
+
})
|
|
1089
|
+
];
|
|
1090
|
+
}
|
|
1091
|
+
},
|
|
1092
|
+
surface: {
|
|
1093
|
+
component: ({ data, role }) => {
|
|
1094
|
+
switch (role) {
|
|
1095
|
+
// case 'article':
|
|
1096
|
+
// return data.object instanceof ChainType ? <ChainArticle chain={data.object} /> : null;
|
|
1097
|
+
case "complementary--automation":
|
|
1098
|
+
return /* @__PURE__ */ React6.createElement(AutomationPanel, null);
|
|
1099
|
+
}
|
|
1100
|
+
return null;
|
|
1101
|
+
}
|
|
1102
|
+
},
|
|
1103
|
+
intent: {
|
|
1104
|
+
resolver: (intent) => {
|
|
1105
|
+
switch (intent.action) {
|
|
1106
|
+
case AutomationAction.CREATE: {
|
|
1107
|
+
return {};
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
};
|
|
1114
|
+
};
|
|
1115
|
+
|
|
1116
|
+
// packages/plugins/experimental/plugin-automation/src/index.ts
|
|
1117
|
+
var src_default = AutomationPlugin;
|
|
1118
|
+
export {
|
|
1119
|
+
AutomationAction,
|
|
1120
|
+
AutomationPanel,
|
|
1121
|
+
AutomationPlugin,
|
|
1122
|
+
Chain,
|
|
1123
|
+
ChainInputSchema,
|
|
1124
|
+
ChainInputType,
|
|
1125
|
+
ChainPresets,
|
|
1126
|
+
ChainPromptType,
|
|
1127
|
+
ChainType,
|
|
1128
|
+
PromptContainer,
|
|
1129
|
+
PromptEditor,
|
|
1130
|
+
TriggerEditor,
|
|
1131
|
+
chainPresets,
|
|
1132
|
+
src_default as default,
|
|
1133
|
+
str
|
|
1134
|
+
};
|
|
1135
|
+
//# sourceMappingURL=index.mjs.map
|