@dxos/plugin-automation 0.7.1 → 0.7.2-staging.6d26b2a

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