@dxos/plugin-script 0.7.5-labs.ff2ff30 → 0.7.5-main.5ae2ba8

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 (147) hide show
  1. package/dist/lib/browser/ScriptContainer-3RFMYKTV.mjs +258 -0
  2. package/dist/lib/browser/ScriptContainer-3RFMYKTV.mjs.map +7 -0
  3. package/dist/lib/browser/{artifact-UOESRBEZ.mjs → artifact-definition-4LWPD3DH.mjs} +27 -19
  4. package/dist/lib/browser/artifact-definition-4LWPD3DH.mjs.map +7 -0
  5. package/dist/lib/browser/{chunk-45LXDWNF.mjs → chunk-5SXOHNAK.mjs} +3 -3
  6. package/dist/lib/browser/chunk-5SXOHNAK.mjs.map +7 -0
  7. package/dist/lib/browser/{ScriptContainer-33XAJPQZ.mjs → chunk-G2FYNDU4.mjs} +16 -254
  8. package/dist/lib/browser/chunk-G2FYNDU4.mjs.map +7 -0
  9. package/dist/lib/browser/chunk-PZPYF7M4.mjs +69 -0
  10. package/dist/lib/browser/chunk-PZPYF7M4.mjs.map +7 -0
  11. package/dist/lib/browser/{chunk-BTZIBJJN.mjs → chunk-VTWBVFBK.mjs} +2 -4
  12. package/dist/lib/browser/{chunk-BTZIBJJN.mjs.map → chunk-VTWBVFBK.mjs.map} +3 -3
  13. package/dist/lib/browser/index.mjs +60 -29
  14. package/dist/lib/browser/index.mjs.map +4 -4
  15. package/dist/lib/browser/{intent-resolver-CMKQTLBG.mjs → intent-resolver-D6FPY5ZA.mjs} +2 -2
  16. package/dist/lib/browser/meta.json +1 -1
  17. package/dist/lib/browser/{react-surface-S5BSIXGB.mjs → react-surface-G4C2PZ2K.mjs} +23 -7
  18. package/dist/lib/browser/react-surface-G4C2PZ2K.mjs.map +7 -0
  19. package/dist/lib/node/ScriptContainer-G6FZU4AM.cjs +274 -0
  20. package/dist/lib/node/ScriptContainer-G6FZU4AM.cjs.map +7 -0
  21. package/dist/lib/node/{artifact-PDTB4LV4.cjs → artifact-definition-BXQCFPAH.cjs} +26 -21
  22. package/dist/lib/node/artifact-definition-BXQCFPAH.cjs.map +7 -0
  23. package/dist/lib/node/chunk-ITAJ3WRW.cjs +77 -0
  24. package/dist/lib/node/chunk-ITAJ3WRW.cjs.map +7 -0
  25. package/dist/lib/node/{chunk-IID7WUQS.cjs → chunk-K3ZZWVXS.cjs} +5 -5
  26. package/dist/lib/node/chunk-K3ZZWVXS.cjs.map +7 -0
  27. package/dist/lib/node/{chunk-2P7DKHIO.cjs → chunk-TOXBGIEI.cjs} +5 -8
  28. package/dist/lib/node/{chunk-2P7DKHIO.cjs.map → chunk-TOXBGIEI.cjs.map} +3 -3
  29. package/dist/lib/node/{ScriptContainer-YR6TIDY3.cjs → chunk-XKYJYY3T.cjs} +59 -280
  30. package/dist/lib/node/chunk-XKYJYY3T.cjs.map +7 -0
  31. package/dist/lib/node/index.cjs +58 -30
  32. package/dist/lib/node/index.cjs.map +4 -4
  33. package/dist/lib/node/{intent-resolver-V5ASU5DW.cjs → intent-resolver-NYJFPD5B.cjs} +6 -6
  34. package/dist/lib/node/meta.json +1 -1
  35. package/dist/lib/node/{react-surface-YNPH5JPY.cjs → react-surface-EGSE3FMN.cjs} +24 -12
  36. package/dist/lib/node/react-surface-EGSE3FMN.cjs.map +7 -0
  37. package/dist/lib/node-esm/ScriptContainer-7FTCFIF3.mjs +259 -0
  38. package/dist/lib/node-esm/ScriptContainer-7FTCFIF3.mjs.map +7 -0
  39. package/dist/lib/node-esm/{artifact-IX4ZCTUF.mjs → artifact-definition-KT4DK2LQ.mjs} +26 -19
  40. package/dist/lib/node-esm/artifact-definition-KT4DK2LQ.mjs.map +7 -0
  41. package/dist/lib/node-esm/{chunk-CGF7EOGD.mjs → chunk-2AFXX34U.mjs} +3 -3
  42. package/dist/lib/node-esm/chunk-2AFXX34U.mjs.map +7 -0
  43. package/dist/lib/node-esm/{ScriptContainer-ZQRQSVJA.mjs → chunk-NRICF4KE.mjs} +16 -254
  44. package/dist/lib/node-esm/chunk-NRICF4KE.mjs.map +7 -0
  45. package/dist/lib/node-esm/{chunk-YGA2AFHL.mjs → chunk-S64WSJQK.mjs} +2 -4
  46. package/dist/lib/node-esm/{chunk-YGA2AFHL.mjs.map → chunk-S64WSJQK.mjs.map} +3 -3
  47. package/dist/lib/node-esm/chunk-YIWRJ25J.mjs +71 -0
  48. package/dist/lib/node-esm/chunk-YIWRJ25J.mjs.map +7 -0
  49. package/dist/lib/node-esm/index.mjs +60 -29
  50. package/dist/lib/node-esm/index.mjs.map +4 -4
  51. package/dist/lib/node-esm/{intent-resolver-75BHFRUK.mjs → intent-resolver-KLBHSMW4.mjs} +2 -2
  52. package/dist/lib/node-esm/meta.json +1 -1
  53. package/dist/lib/node-esm/{react-surface-BNC2OM5X.mjs → react-surface-7YSGHZQM.mjs} +23 -7
  54. package/dist/lib/node-esm/react-surface-7YSGHZQM.mjs.map +7 -0
  55. package/dist/types/src/ScriptPlugin.d.ts.map +1 -1
  56. package/dist/types/src/capabilities/{artifact.d.ts → artifact-definition.d.ts} +1 -1
  57. package/dist/types/src/capabilities/artifact-definition.d.ts.map +1 -0
  58. package/dist/types/src/capabilities/index.d.ts +1 -1
  59. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  60. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  61. package/dist/types/src/components/DebugPanel/DebugPanel.d.ts +1 -2
  62. package/dist/types/src/components/DebugPanel/DebugPanel.d.ts.map +1 -1
  63. package/dist/types/src/components/FrameContainer/FrameContainer.d.ts +1 -2
  64. package/dist/types/src/components/FrameContainer/FrameContainer.d.ts.map +1 -1
  65. package/dist/types/src/components/ScriptContainer.d.ts +1 -2
  66. package/dist/types/src/components/ScriptContainer.d.ts.map +1 -1
  67. package/dist/types/src/components/ScriptSettings/ScriptSettings.d.ts +1 -2
  68. package/dist/types/src/components/ScriptSettings/ScriptSettings.d.ts.map +1 -1
  69. package/dist/types/src/components/ScriptSettingsPanel.d.ts +1 -2
  70. package/dist/types/src/components/ScriptSettingsPanel.d.ts.map +1 -1
  71. package/dist/types/src/components/ScriptToolbar/ScriptToolbar.d.ts +1 -2
  72. package/dist/types/src/components/ScriptToolbar/ScriptToolbar.d.ts.map +1 -1
  73. package/dist/types/src/components/TypescriptEditor/TypescriptEditor.d.ts +1 -2
  74. package/dist/types/src/components/TypescriptEditor/TypescriptEditor.d.ts.map +1 -1
  75. package/dist/types/src/components/index.d.ts +2 -2
  76. package/dist/types/src/components/index.d.ts.map +1 -1
  77. package/dist/types/src/events.d.ts +4 -0
  78. package/dist/types/src/events.d.ts.map +1 -0
  79. package/dist/types/src/hooks/deploy.d.ts.map +1 -1
  80. package/dist/types/src/hooks/template.d.ts +1 -1
  81. package/dist/types/src/hooks/view.d.ts +1 -1
  82. package/dist/types/src/hooks/view.d.ts.map +1 -1
  83. package/dist/types/src/templates/chess.d.ts +1 -4
  84. package/dist/types/src/templates/chess.d.ts.map +1 -1
  85. package/dist/types/src/templates/discord.d.ts +3 -0
  86. package/dist/types/src/templates/discord.d.ts.map +1 -0
  87. package/dist/types/src/templates/forex-effect.d.ts +0 -3
  88. package/dist/types/src/templates/forex-effect.d.ts.map +1 -1
  89. package/dist/types/src/templates/forex.d.ts +0 -3
  90. package/dist/types/src/templates/forex.d.ts.map +1 -1
  91. package/dist/types/src/templates/index.d.ts.map +1 -1
  92. package/dist/types/src/translations.d.ts +3 -0
  93. package/dist/types/src/translations.d.ts.map +1 -1
  94. package/dist/types/src/types.d.ts +1 -1
  95. package/package.json +43 -41
  96. package/src/ScriptPlugin.tsx +38 -18
  97. package/src/capabilities/{artifact.ts → artifact-definition.ts} +15 -10
  98. package/src/capabilities/index.ts +1 -1
  99. package/src/capabilities/react-surface.tsx +9 -3
  100. package/src/components/DebugPanel/DebugPanel.tsx +2 -2
  101. package/src/components/FrameContainer/FrameContainer.tsx +1 -1
  102. package/src/components/TypescriptEditor/TypescriptEditor.tsx +2 -2
  103. package/src/components/index.ts +1 -1
  104. package/src/events.ts +11 -0
  105. package/src/hooks/deploy.ts +1 -1
  106. package/src/hooks/view.ts +4 -1
  107. package/src/templates/chat.ts +4 -4
  108. package/src/templates/chess.ts +42 -35
  109. package/src/templates/discord.ts +103 -0
  110. package/src/templates/forex-effect.ts +16 -17
  111. package/src/templates/forex.ts +2 -3
  112. package/src/templates/index.ts +10 -2
  113. package/src/translations.ts +3 -0
  114. package/dist/lib/browser/AutomationPanel-J3SZ5L3Y.mjs +0 -78
  115. package/dist/lib/browser/AutomationPanel-J3SZ5L3Y.mjs.map +0 -7
  116. package/dist/lib/browser/ScriptContainer-33XAJPQZ.mjs.map +0 -7
  117. package/dist/lib/browser/artifact-UOESRBEZ.mjs.map +0 -7
  118. package/dist/lib/browser/chunk-45LXDWNF.mjs.map +0 -7
  119. package/dist/lib/browser/chunk-VIX22OMB.mjs +0 -60
  120. package/dist/lib/browser/chunk-VIX22OMB.mjs.map +0 -7
  121. package/dist/lib/browser/react-surface-S5BSIXGB.mjs.map +0 -7
  122. package/dist/lib/node/AutomationPanel-4M55FURO.cjs +0 -104
  123. package/dist/lib/node/AutomationPanel-4M55FURO.cjs.map +0 -7
  124. package/dist/lib/node/ScriptContainer-YR6TIDY3.cjs.map +0 -7
  125. package/dist/lib/node/artifact-PDTB4LV4.cjs.map +0 -7
  126. package/dist/lib/node/chunk-IID7WUQS.cjs.map +0 -7
  127. package/dist/lib/node/chunk-PKT5DD3O.cjs +0 -70
  128. package/dist/lib/node/chunk-PKT5DD3O.cjs.map +0 -7
  129. package/dist/lib/node/react-surface-YNPH5JPY.cjs.map +0 -7
  130. package/dist/lib/node-esm/AutomationPanel-W6SKG35R.mjs +0 -79
  131. package/dist/lib/node-esm/AutomationPanel-W6SKG35R.mjs.map +0 -7
  132. package/dist/lib/node-esm/ScriptContainer-ZQRQSVJA.mjs.map +0 -7
  133. package/dist/lib/node-esm/artifact-IX4ZCTUF.mjs.map +0 -7
  134. package/dist/lib/node-esm/chunk-CGF7EOGD.mjs.map +0 -7
  135. package/dist/lib/node-esm/chunk-NBAL5DXN.mjs +0 -62
  136. package/dist/lib/node-esm/chunk-NBAL5DXN.mjs.map +0 -7
  137. package/dist/lib/node-esm/react-surface-BNC2OM5X.mjs.map +0 -7
  138. package/dist/types/src/capabilities/artifact.d.ts.map +0 -1
  139. package/dist/types/src/components/AutomationPanel/AutomationPanel.d.ts +0 -17
  140. package/dist/types/src/components/AutomationPanel/AutomationPanel.d.ts.map +0 -1
  141. package/dist/types/src/components/AutomationPanel/index.d.ts +0 -4
  142. package/dist/types/src/components/AutomationPanel/index.d.ts.map +0 -1
  143. package/src/components/AutomationPanel/AutomationPanel.tsx +0 -104
  144. package/src/components/AutomationPanel/index.ts +0 -9
  145. /package/dist/lib/browser/{intent-resolver-CMKQTLBG.mjs.map → intent-resolver-D6FPY5ZA.mjs.map} +0 -0
  146. /package/dist/lib/node/{intent-resolver-V5ASU5DW.cjs.map → intent-resolver-NYJFPD5B.cjs.map} +0 -0
  147. /package/dist/lib/node-esm/{intent-resolver-75BHFRUK.mjs.map → intent-resolver-KLBHSMW4.mjs.map} +0 -0
@@ -8,10 +8,11 @@ import { createArtifactElement } from '@dxos/assistant';
8
8
  import { ObjectId, S } from '@dxos/echo-schema';
9
9
  import { ScriptType } from '@dxos/functions';
10
10
  import { invariant } from '@dxos/invariant';
11
+ import { SpaceAction } from '@dxos/plugin-space/types';
11
12
  import { create, makeRef, type Space } from '@dxos/react-client/echo';
12
13
  import { TextType } from '@dxos/schema';
13
- import { SpaceAction } from '@dxos/plugin-space/types';
14
14
 
15
+ import { meta } from '../meta';
15
16
  // TODO(burdon): Factor out.
16
17
  declare global {
17
18
  interface ToolContextExtensions {
@@ -22,10 +23,11 @@ declare global {
22
23
 
23
24
  export default () => {
24
25
  const definition = defineArtifact({
25
- id: 'plugin-script',
26
+ id: meta.id,
27
+ name: meta.name,
26
28
  // TODO(dmaretskyi): Since writing scripts requires a lot of domain knowledge,
27
- // we should offload the work of synthesizing the code to a separate model.
28
- // The main reasoning model will give it a concrete task and the script model will synthesize the code, knowing all the docs.
29
+ // we should offload the work of synthesizing the code to a separate model.
30
+ // The main reasoning model will give it a concrete task and the script model will synthesize the code, knowing all the docs.
29
31
  instructions: `
30
32
  If the user explicitly requests you to write a script, you can create one.
31
33
  If the user requests you to change one of the existing script, you can update it.
@@ -136,9 +138,10 @@ export default () => {
136
138
  `,
137
139
  schema: ScriptType,
138
140
  tools: [
139
- defineTool({
140
- name: 'script_new',
141
+ defineTool(meta.id, {
142
+ name: 'create',
141
143
  description: 'Create a new script. Returns the artifact definition for the script',
144
+ caption: 'Creating script...',
142
145
  schema: S.Struct({
143
146
  name: S.String.annotations({ description: 'The name of the script' }),
144
147
  code: S.String.annotations({
@@ -168,9 +171,10 @@ export default () => {
168
171
  return ToolResult.Success(createArtifactElement(script.id));
169
172
  },
170
173
  }),
171
- defineTool({
172
- name: 'script_inspect',
174
+ defineTool(meta.id, {
175
+ name: 'inspect',
173
176
  description: 'Inspect a script. Returns the artifact definition for the script',
177
+ caption: 'Inspecting script...',
174
178
  schema: S.Struct({
175
179
  id: ObjectId,
176
180
  }),
@@ -186,9 +190,10 @@ export default () => {
186
190
  });
187
191
  },
188
192
  }),
189
- defineTool({
190
- name: 'script_update',
193
+ defineTool(meta.id, {
194
+ name: 'update',
191
195
  description: 'Update a script. Returns the artifact definition for the script',
196
+ caption: 'Updating script...',
192
197
  schema: S.Struct({
193
198
  id: ObjectId,
194
199
  code: S.String.annotations({
@@ -8,6 +8,6 @@ export const Compiler = lazy(() => import('./compiler'));
8
8
  export const IntentResolver = lazy(() => import('./intent-resolver'));
9
9
  export const ReactSurface = lazy(() => import('./react-surface'));
10
10
  export const ScriptSettings = lazy(() => import('./settings'));
11
- export const Artifact = lazy(() => import('./artifact'));
11
+ export const ArtifactDefinition = lazy(() => import('./artifact-definition'));
12
12
 
13
13
  export * from './capabilities';
@@ -10,7 +10,8 @@ import { SettingsStore } from '@dxos/local-storage';
10
10
  import { Clipboard } from '@dxos/react-ui';
11
11
 
12
12
  import { ScriptCapabilities } from './capabilities';
13
- import { AutomationPanel, ScriptSettings, ScriptContainer, ScriptSettingsPanel } from '../components';
13
+ import { DebugPanel, ScriptSettings, ScriptContainer, ScriptSettingsPanel } from '../components';
14
+ import { useDeployState, useToolbarState } from '../hooks';
14
15
  import { SCRIPT_PLUGIN } from '../meta';
15
16
  import { type ScriptSettingsProps } from '../types';
16
17
 
@@ -36,10 +37,15 @@ export default () =>
36
37
  }),
37
38
  createSurface({
38
39
  id: `${SCRIPT_PLUGIN}/automation`,
39
- role: 'complementary--automation',
40
+ role: 'complementary--function',
40
41
  position: 'hoist',
41
42
  filter: (data): data is { subject: ScriptType } => data.subject instanceof ScriptType,
42
- component: ({ data }) => <AutomationPanel subject={data.subject} />,
43
+ component: ({ data }) => {
44
+ // TODO(wittjosiah): Decouple hooks from toolbar state.
45
+ const state = useToolbarState({ view: 'editor' });
46
+ useDeployState({ state, script: data.subject });
47
+ return <DebugPanel functionUrl={state.functionUrl} />;
48
+ },
43
49
  }),
44
50
  createSurface({
45
51
  id: `${SCRIPT_PLUGIN}/settings-panel`,
@@ -7,7 +7,7 @@ import React, { forwardRef, useEffect, useRef, useState } from 'react';
7
7
  import { log } from '@dxos/log';
8
8
  import { Avatar, Icon, Input, type ThemedClassName, Toolbar, useTranslation } from '@dxos/react-ui';
9
9
  import { SyntaxHighlighter } from '@dxos/react-ui-syntax-highlighter';
10
- import { mx } from '@dxos/react-ui-theme';
10
+ import { errorText, mx } from '@dxos/react-ui-theme';
11
11
 
12
12
  import { SCRIPT_PLUGIN } from '../../meta';
13
13
 
@@ -232,7 +232,7 @@ const MessageItem = ({ classNames, message }: ThemedClassName<{ message: Message
232
232
  const wrapper = 'p-1 px-2 rounded-lg bg-hoverSurface overflow-auto';
233
233
  return (
234
234
  <div className={mx('flex', type === 'request' ? 'ml-[1rem] justify-end' : 'mr-[1rem]', classNames)}>
235
- {error && <div className={mx(wrapper, 'whitespace-pre text-error')}>{String(error)}</div>}
235
+ {error && <div className={mx(wrapper, 'whitespace-pre', errorText)}>{String(error)}</div>}
236
236
 
237
237
  {text !== undefined && (
238
238
  <div className={mx(wrapper, type === 'request' && 'bg-primary-400 dark:bg-primary-600')}>
@@ -59,7 +59,7 @@ export const FrameContainer = ({ containerUrl, result, debug = true }: FrameCont
59
59
  <div
60
60
  className={mx(
61
61
  baseSurface,
62
- 'flex absolute right-2 bottom-2 w-[400px] h-[200px] ring rounded',
62
+ 'flex absolute right-2 bottom-2 w-[30rem] h-[200px] ring rounded',
63
63
  'z-20 overflow-x-hidden overflow-y-auto',
64
64
  )}
65
65
  >
@@ -27,7 +27,7 @@ import {
27
27
  useTextEditor,
28
28
  type UseTextEditorProps,
29
29
  } from '@dxos/react-ui-editor';
30
- import { nonNullable } from '@dxos/util';
30
+ import { isNonNullable } from '@dxos/util';
31
31
 
32
32
  export type TypescriptEditorProps = {
33
33
  id: string;
@@ -94,7 +94,7 @@ export const TypescriptEditor = ({
94
94
  ]
95
95
  : [],
96
96
  ],
97
- ].filter(nonNullable),
97
+ ].filter(isNonNullable),
98
98
  selection,
99
99
  scrollTo,
100
100
  }),
@@ -4,8 +4,8 @@
4
4
 
5
5
  import { lazy } from 'react';
6
6
 
7
+ export * from './DebugPanel';
7
8
  export * from './ScriptSettings';
8
9
  export * from './ScriptSettingsPanel';
9
10
 
10
- export const AutomationPanel = lazy(() => import('./AutomationPanel'));
11
11
  export const ScriptContainer = lazy(() => import('./ScriptContainer'));
package/src/events.ts ADDED
@@ -0,0 +1,11 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { defineEvent } from '@dxos/app-framework';
6
+
7
+ import { SCRIPT_PLUGIN } from './meta';
8
+
9
+ export namespace ScriptEvents {
10
+ export const SetupCompiler = defineEvent(`${SCRIPT_PLUGIN}/event/setup-compiler`);
11
+ }
@@ -6,10 +6,10 @@ import { useCallback, useEffect, useMemo } from 'react';
6
6
 
7
7
  import {
8
8
  FunctionType,
9
+ type ScriptType,
9
10
  getInvocationUrl,
10
11
  getUserFunctionUrlInMetadata,
11
12
  incrementSemverPatch,
12
- type ScriptType,
13
13
  setUserFunctionUrlInMetadata,
14
14
  uploadWorkerFunction,
15
15
  } from '@dxos/functions';
package/src/hooks/view.ts CHANGED
@@ -6,7 +6,8 @@ import { createMenuAction, createMenuItemGroup } from '@dxos/react-ui-menu';
6
6
 
7
7
  import { SCRIPT_PLUGIN } from '../meta';
8
8
 
9
- export type ViewType = 'editor' | 'split' | 'debug';
9
+ // TODO(wittjosiah): Replace debug with logs.
10
+ export type ViewType = 'editor' | 'split' | 'debug'; // 'logs';
10
11
 
11
12
  export type ViewState = { view: ViewType };
12
13
 
@@ -16,6 +17,8 @@ const views: Record<ViewType, string> = {
16
17
  editor: 'ph--code--regular',
17
18
  split: 'ph--square-split-vertical--regular',
18
19
  debug: 'ph--bug--regular',
20
+ // TODO(wittjosiah): Replace debug with logs.
21
+ // logs: 'ph--clock-counter-clockwise--regular',
19
22
  };
20
23
 
21
24
  const createViewGroupItem = (state: Partial<ViewState>) => {
@@ -57,11 +57,11 @@ export default async ({
57
57
  let prompt = promptObject.template;
58
58
  for (const input of promptObject.inputs) {
59
59
  let value: string | null = null;
60
- if (input.type === ChainInputType.VALUE) {
60
+ if (input.type === TemplateInputType.VALUE) {
61
61
  value = String(input.value);
62
- } else if (input.type === ChainInputType.RETRIEVER) {
62
+ } else if (input.type === TemplateInputType.RETRIEVER) {
63
63
  value = await getContext({ space });
64
- } else if (input.type === ChainInputType.PASS_THROUGH) {
64
+ } else if (input.type === TemplateInputType.PASS_THROUGH) {
65
65
  value = message.text;
66
66
  }
67
67
  if (value) {
@@ -90,7 +90,7 @@ const getContext = async ({ space }: any) => {
90
90
  return context;
91
91
  };
92
92
 
93
- enum ChainInputType {
93
+ enum TemplateInputType {
94
94
  VALUE = 0,
95
95
  PASS_THROUGH = 1,
96
96
  RETRIEVER = 2,
@@ -1,41 +1,48 @@
1
- //
2
- // Copyright 2024 DXOS.org
3
- //
4
-
1
+ // @ts-ignore
2
+ import { defineFunction, S } from 'dxos:functions';
5
3
  // @ts-ignore
6
4
  import { Chess } from 'https://esm.sh/chess.js@0.13.1';
7
5
 
8
- /**
9
- * Plays a random move in a chess game.
10
- */
11
- export default async ({
12
- event: {
13
- data: { request },
14
- },
15
- context: { space },
16
- }: any) => {
17
- const {
18
- data: {
19
- objects: [gameId],
20
- player = 'b',
21
- },
22
- } = await request.json();
6
+ export default defineFunction({
7
+ description: 'Plays a random move in a chess game.',
23
8
 
24
- const { pgn } = await space.crud.query({ id: gameId }).first();
25
- const game = new Chess();
26
- game.load_pgn(pgn);
27
- if (game.turn() !== player) {
28
- return new Response('Invalid turn', { status: 409 });
29
- }
9
+ inputSchema: S.Struct({
10
+ changedObjectId: S.String.annotations({
11
+ description: 'The objects to play the game on.',
12
+ }),
13
+ player: S.optional(S.Literal('w', 'b')).annotations({
14
+ description: 'The player to play the game as.',
15
+ }),
16
+ }),
30
17
 
31
- const moves = game.moves();
32
- const move = moves[Math.floor(Math.random() * moves.length)];
33
- if (!move) {
34
- return new Response('No legal moves', { status: 406 });
35
- }
18
+ outputSchema: S.Struct({
19
+ state: S.String.annotations({
20
+ description: 'The state of the game as an ASCII art board.',
21
+ }),
22
+ }),
36
23
 
37
- game.move(move);
38
- const newPgn = game.pgn();
39
- await space.crud.update({ id: gameId }, { pgn: newPgn });
40
- return new Response(game.ascii());
41
- };
24
+ handler: async ({
25
+ event: {
26
+ data: { changedObjectId, player = 'b' },
27
+ },
28
+ context: { space },
29
+ }: any) => {
30
+ const { pgn } = await space.db.query({ id: changedObjectId }).first();
31
+ const game = new Chess();
32
+ game.load_pgn(pgn);
33
+ if (game.turn() !== player) {
34
+ return new Response('Invalid turn', { status: 409 });
35
+ }
36
+
37
+ const moves = game.moves();
38
+ const move = moves[Math.floor(Math.random() * moves.length)];
39
+ if (!move) {
40
+ return new Response('No legal moves', { status: 406 });
41
+ }
42
+
43
+ game.move(move);
44
+ const newPgn = game.pgn();
45
+ await space.db.update({ id: changedObjectId }, { pgn: newPgn, fen: game.fen() });
46
+ return { state: game.ascii() };
47
+ },
48
+ });
@@ -0,0 +1,103 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ // @ts-ignore
6
+ import { createStatic, EchoObject, defineFunction, DXN, Filter, ObjectId, S } from 'dxos:functions';
7
+ import {
8
+ FetchHttpClient,
9
+ // @ts-ignore
10
+ } from 'https://esm.sh/@effect/platform@0.77.2?deps=effect@3.13.3';
11
+ // @ts-ignore
12
+ import { DiscordConfig, DiscordREST, DiscordRESTMemoryLive } from 'https://esm.sh/dfx@0.113.0?deps=effect@3.13.3';
13
+ // @ts-ignore
14
+ import { Effect, Config, Redacted, Ref } from 'https://esm.sh/effect@3.13.3';
15
+
16
+ const MessageSchema = S.Struct({
17
+ id: S.String,
18
+ foreignId: S.Any, // bigint?
19
+ from: S.String,
20
+ created: S.String,
21
+ content: S.String,
22
+ }).pipe(EchoObject('example.com/type/Message', '0.1.0'));
23
+
24
+ const DEFAULT_AFTER = 1704067200; // 2024-01-01
25
+
26
+ const generateSnowflake = (unixTimestamp: number): bigint => {
27
+ const discordEpoch = 1420070400000n; // Discord Epoch (ms)
28
+ return (BigInt(unixTimestamp * 1000) - discordEpoch) << 22n;
29
+ };
30
+
31
+ export default defineFunction({
32
+ inputSchema: S.Struct({
33
+ // TODO(wittjosiah): Remove. This is used to provide a terminal for a cron trigger.
34
+ tick: S.optional(S.String),
35
+ channelId: S.String,
36
+ after: S.optional(S.Number),
37
+ pageSize: S.optional(S.Number),
38
+ queueId: S.String,
39
+ }),
40
+
41
+ outputSchema: S.Struct({
42
+ newMessages: S.Number,
43
+ }),
44
+
45
+ handler: ({
46
+ event: {
47
+ data: { channelId, queueId, after = DEFAULT_AFTER, pageSize = 5 },
48
+ },
49
+ context: { space },
50
+ }: any) =>
51
+ Effect.gen(function* () {
52
+ const { token } = yield* Effect.tryPromise(() =>
53
+ space.db.query(Filter.typename('dxos.org/type/AccessToken', { source: 'discord.com' })).first(),
54
+ );
55
+ const { objects } = yield* Effect.tryPromise(() => space.queues.queryQueue(DXN.parse(queueId)));
56
+ const backfill = objects.length === 0;
57
+ const newMessages = yield* Ref.make(0);
58
+ const lastMessage = yield* Ref.make(objects.at(-1));
59
+
60
+ const enqueueMessages = Effect.gen(function* () {
61
+ const rest = yield* DiscordREST;
62
+
63
+ while (true) {
64
+ const last = yield* Ref.get(lastMessage);
65
+ const options = {
66
+ after: backfill && !last ? `${generateSnowflake(after)}` : last?.foreignId,
67
+ limit: pageSize,
68
+ };
69
+ const messages = yield* rest.getChannelMessages(channelId, options).pipe((res: any) => res.json);
70
+ const queueMessages = messages
71
+ .map((message: any) =>
72
+ createStatic(MessageSchema, {
73
+ id: ObjectId.random(),
74
+ foreignId: message.id,
75
+ from: message.author.username,
76
+ created: message.timestamp,
77
+ content: message.content,
78
+ }),
79
+ )
80
+ .toReversed();
81
+ if (queueMessages.length > 0) {
82
+ yield* Effect.tryPromise(() => space.queues.insertIntoQueue(DXN.parse(queueId), queueMessages));
83
+ yield* Ref.update(newMessages, (n: any) => n + queueMessages.length);
84
+ yield* Ref.update(lastMessage, (m: any) => queueMessages.at(-1));
85
+ }
86
+ if (messages.length < pageSize) {
87
+ break;
88
+ }
89
+ }
90
+ }).pipe(
91
+ Effect.provide(DiscordRESTMemoryLive),
92
+ Effect.provide(
93
+ DiscordConfig.layerConfig({
94
+ token: Config.succeed(Redacted.make(token)),
95
+ }),
96
+ ),
97
+ Effect.provide(FetchHttpClient.layer),
98
+ );
99
+
100
+ yield* enqueueMessages;
101
+ return { newMessages: yield* Ref.get(newMessages) };
102
+ }),
103
+ });
@@ -7,36 +7,35 @@ import { defineFunction, S } from 'dxos:functions';
7
7
  import {
8
8
  HttpClient,
9
9
  HttpClientRequest,
10
- HttpClientResponse,
11
- HttpClientError,
10
+ FetchHttpClient,
12
11
  // @ts-ignore
13
- } from 'https://esm.sh/@effect/platform@0.61.0?deps=effect@3.6.0';
12
+ } from 'https://esm.sh/@effect/platform@0.77.2?deps=effect@3.13.3';
14
13
  // @ts-ignore
15
- import type { Cause } from 'https://esm.sh/effect@3.6.0';
16
- // @ts-ignore
17
- import { Effect, Schedule } from 'https://esm.sh/effect@3.6.0';
14
+ import { Effect, Schedule } from 'https://esm.sh/effect@3.13.3';
18
15
 
19
- /**
20
- * Returns the exchange rate between two currencies.
21
- */
22
16
  export default defineFunction({
17
+ description: 'Returns the exchange rate between two currencies.',
18
+
23
19
  inputSchema: S.Struct({
24
20
  from: S.String.annotations({ description: 'The source currency' }),
25
21
  to: S.String.annotations({ description: 'The target currency' }),
26
22
  }),
27
23
 
28
- outputSchema: S.String,
24
+ outputSchema: S.String.annotations({ description: 'The exchange rate between the two currencies' }),
29
25
 
30
26
  handler: async ({
31
27
  event: {
32
28
  data: { from, to },
33
29
  },
34
30
  }: any) =>
35
- HttpClientRequest.get(`https://free.ratesdb.com/v1/rates?from=${from}&to=${to}`).pipe(
36
- HttpClient.fetchOk,
37
- HttpClientResponse.json,
38
- Effect.timeout('1 second'),
39
- Effect.retry(Schedule.exponential(1000).pipe(Schedule.compose(Schedule.recurs(3)))),
40
- Effect.map(({ data: { rates } }: any) => rates[to].toString()),
41
- ),
31
+ Effect.gen(function* () {
32
+ const res = yield* HttpClientRequest.get(`https://free.ratesdb.com/v1/rates?from=${from}&to=${to}`).pipe(
33
+ HttpClient.execute,
34
+ Effect.flatMap((res: any) => res.json),
35
+ Effect.timeout('1 second'),
36
+ Effect.retry(Schedule.exponential(1000).pipe(Schedule.compose(Schedule.recurs(3)))),
37
+ Effect.scoped,
38
+ );
39
+ return res.data.rates[to].toString();
40
+ }).pipe(Effect.provide(FetchHttpClient.layer)),
42
41
  });
@@ -5,10 +5,9 @@
5
5
  // @ts-ignore
6
6
  import { defineFunction, S } from 'dxos:functions';
7
7
 
8
- /**
9
- * Returns the exchange rate between two currencies.
10
- */
11
8
  export default defineFunction({
9
+ description: 'Returns the exchange rate between two currencies.',
10
+
12
11
  inputSchema: S.Struct({
13
12
  from: S.String.annotations({ description: 'The source currency' }),
14
13
  to: S.String.annotations({ description: 'The target currency' }),
@@ -7,13 +7,15 @@ import chat from './chat.ts?raw';
7
7
  // @ts-ignore
8
8
  import chess from './chess.ts?raw';
9
9
  // @ts-ignore
10
+ import discord from './discord.ts?raw';
11
+ // @ts-ignore
10
12
  import echo from './echo.ts?raw';
11
13
  // @ts-ignore
12
14
  import email from './email.ts?raw';
13
15
  // @ts-ignore
14
- import forex from './forex.ts?raw';
15
- // @ts-ignore
16
16
  import forexEffect from './forex-effect.ts?raw';
17
+ // @ts-ignore
18
+ import forex from './forex.ts?raw';
17
19
 
18
20
  const removeHeader = (str: string) => str.split('\n').slice(4).join('\n');
19
21
 
@@ -58,4 +60,10 @@ export const templates: Template[] = [
58
60
  source: removeHeader(email),
59
61
  presetId: 'dxos.org/function/email',
60
62
  },
63
+ {
64
+ id: 'dxos.org/script/discord',
65
+ name: 'Discord',
66
+ source: removeHeader(discord),
67
+ presetId: 'dxos.org/function/discord',
68
+ },
61
69
  ];
@@ -49,7 +49,10 @@ export default [
49
49
  'view editor label': 'Editor',
50
50
  'view split label': 'Split',
51
51
  'view debug label': 'Debug',
52
+ // TODO(wittjosiah): Replace debug with logs.
53
+ // 'view logs label': 'Logs',
52
54
  'template select group label': 'Select template',
55
+ 'function panel label': 'Debug Function',
53
56
  },
54
57
  },
55
58
  },
@@ -1,78 +0,0 @@
1
- import {
2
- DebugPanel
3
- } from "./chunk-45LXDWNF.mjs";
4
- import {
5
- SCRIPT_PLUGIN
6
- } from "./chunk-FVVCAWNP.mjs";
7
-
8
- // packages/plugins/experimental/plugin-script/src/components/AutomationPanel/AutomationPanel.tsx
9
- import React, { useMemo, useState } from "react";
10
- import { failUndefined } from "@dxos/debug";
11
- import { FunctionType, ScriptType, getInvocationUrl, getUserFunctionUrlInMetadata } from "@dxos/functions";
12
- import { useClient } from "@dxos/react-client";
13
- import { Filter, getMeta, getSpace, useQuery } from "@dxos/react-client/echo";
14
- import { Select, useTranslation } from "@dxos/react-ui";
15
- var AutomationPanel = ({ subject }) => {
16
- const { t } = useTranslation(SCRIPT_PLUGIN);
17
- const space = getSpace(subject);
18
- const functions = useQuery(space ?? void 0, subject instanceof ScriptType ? Filter.schema(FunctionType, {
19
- source: subject
20
- }) : Filter.schema(FunctionType, (fn) => fn.binding != null), {}, [
21
- subject
22
- ]);
23
- const [selectedFunction, setSelectedFunction] = useState(null);
24
- const chatFunction = subject instanceof ScriptType ? functions[0] : selectedFunction;
25
- return /* @__PURE__ */ React.createElement("div", {
26
- className: "h-full flex flex-col"
27
- }, !(subject instanceof ScriptType) && /* @__PURE__ */ React.createElement(BindingSelect, {
28
- selectedFunction,
29
- setSelectedFunction,
30
- functions
31
- }), chatFunction && /* @__PURE__ */ React.createElement(ChatPanel, {
32
- fn: chatFunction,
33
- subject
34
- }), subject instanceof ScriptType && functions.length === 0 && /* @__PURE__ */ React.createElement("div", {
35
- className: "p-1"
36
- }, t("not deployed")));
37
- };
38
- var ChatPanel = ({ fn, subject }) => {
39
- const client = useClient();
40
- const space = getSpace(fn);
41
- const existingFunctionUrl = getUserFunctionUrlInMetadata(getMeta(fn));
42
- const functionUrl = useMemo(() => {
43
- if (!existingFunctionUrl) {
44
- return;
45
- }
46
- return getInvocationUrl(existingFunctionUrl, client.config.values.runtime?.services?.edge?.url ?? "", {
47
- spaceId: space?.id,
48
- subjectId: subject?.id
49
- });
50
- }, [
51
- existingFunctionUrl,
52
- space,
53
- subject
54
- ]);
55
- return /* @__PURE__ */ React.createElement(DebugPanel, {
56
- functionUrl,
57
- classNames: "flex-1"
58
- });
59
- };
60
- var BindingSelect = ({ selectedFunction, setSelectedFunction, functions }) => {
61
- return /* @__PURE__ */ React.createElement(Select.Root, {
62
- value: selectedFunction?.id,
63
- onValueChange: (id) => setSelectedFunction(functions.find((fn) => fn.id === id) ?? failUndefined())
64
- }, /* @__PURE__ */ React.createElement(Select.TriggerButton, {
65
- placeholder: "Select value"
66
- }), /* @__PURE__ */ React.createElement(Select.Portal, null, /* @__PURE__ */ React.createElement(Select.Content, null, /* @__PURE__ */ React.createElement(Select.ScrollUpButton, null), /* @__PURE__ */ React.createElement(Select.Viewport, null, functions.map(({ id, binding }) => /* @__PURE__ */ React.createElement(Select.Option, {
67
- key: id,
68
- value: id
69
- }, binding))), /* @__PURE__ */ React.createElement(Select.ScrollDownButton, null), /* @__PURE__ */ React.createElement(Select.Arrow, null))));
70
- };
71
-
72
- // packages/plugins/experimental/plugin-script/src/components/AutomationPanel/index.ts
73
- var AutomationPanel_default = AutomationPanel;
74
- export {
75
- AutomationPanel,
76
- AutomationPanel_default as default
77
- };
78
- //# sourceMappingURL=AutomationPanel-J3SZ5L3Y.mjs.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/components/AutomationPanel/AutomationPanel.tsx", "../../../src/components/AutomationPanel/index.ts"],
4
- "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport React, { useMemo, useState } from 'react';\n\nimport { failUndefined } from '@dxos/debug';\nimport { FunctionType, ScriptType, getInvocationUrl, getUserFunctionUrlInMetadata } from '@dxos/functions';\nimport { useClient } from '@dxos/react-client';\nimport { Filter, getMeta, getSpace, type ReactiveEchoObject, useQuery } from '@dxos/react-client/echo';\nimport { Select, useTranslation } from '@dxos/react-ui';\n\nimport { SCRIPT_PLUGIN } from '../../meta';\nimport { DebugPanel } from '../DebugPanel';\n\nexport interface AutomationPanelProps {\n subject: ReactiveEchoObject<any>;\n}\n\nexport const AutomationPanel = ({ subject }: AutomationPanelProps) => {\n const { t } = useTranslation(SCRIPT_PLUGIN);\n const space = getSpace(subject);\n\n // TODO(dmaretskyi): Parametric query.\n const functions = useQuery(\n space ?? undefined,\n subject instanceof ScriptType\n ? Filter.schema(FunctionType, { source: subject })\n : Filter.schema(FunctionType, (fn) => fn.binding != null),\n {},\n [subject],\n );\n\n const [selectedFunction, setSelectedFunction] = useState<FunctionType | null>(null);\n const chatFunction = subject instanceof ScriptType ? functions[0] : selectedFunction;\n\n return (\n <div className='h-full flex flex-col'>\n {!(subject instanceof ScriptType) && (\n <BindingSelect\n selectedFunction={selectedFunction}\n setSelectedFunction={setSelectedFunction}\n functions={functions}\n />\n )}\n {chatFunction && <ChatPanel fn={chatFunction} subject={subject} />}\n {subject instanceof ScriptType && functions.length === 0 && <div className='p-1'>{t('not deployed')}</div>}\n </div>\n );\n};\n\nexport interface ChatPanelProps {\n fn: FunctionType;\n subject: ReactiveEchoObject<any>;\n}\n\nconst ChatPanel = ({ fn, subject }: ChatPanelProps) => {\n const client = useClient();\n const space = getSpace(fn);\n const existingFunctionUrl = getUserFunctionUrlInMetadata(getMeta(fn));\n const functionUrl = useMemo(() => {\n if (!existingFunctionUrl) {\n return;\n }\n\n return getInvocationUrl(existingFunctionUrl, client.config.values.runtime?.services?.edge?.url ?? '', {\n spaceId: space?.id,\n subjectId: subject?.id,\n });\n }, [existingFunctionUrl, space, subject]);\n\n return <DebugPanel functionUrl={functionUrl} classNames='flex-1' />;\n};\n\nexport interface BindingSelectProps {\n selectedFunction: FunctionType | null;\n setSelectedFunction: (fn: FunctionType) => void;\n functions: FunctionType[];\n}\n\nconst BindingSelect = ({ selectedFunction, setSelectedFunction, functions }: BindingSelectProps) => {\n return (\n <Select.Root\n value={selectedFunction?.id}\n onValueChange={(id) => setSelectedFunction(functions.find((fn) => fn.id === id) ?? failUndefined())}\n >\n <Select.TriggerButton placeholder='Select value' />\n <Select.Portal>\n <Select.Content>\n <Select.ScrollUpButton />\n <Select.Viewport>\n {functions.map(({ id, binding }) => (\n <Select.Option key={id} value={id}>\n {binding}\n </Select.Option>\n ))}\n </Select.Viewport>\n <Select.ScrollDownButton />\n <Select.Arrow />\n </Select.Content>\n </Select.Portal>\n </Select.Root>\n );\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { AutomationPanel } from './AutomationPanel';\n\nexport * from './AutomationPanel';\n\nexport default AutomationPanel;\n"],
5
- "mappings": ";;;;;;;;AAIA,OAAOA,SAASC,SAASC,gBAAgB;AAEzC,SAASC,qBAAqB;AAC9B,SAASC,cAAcC,YAAYC,kBAAkBC,oCAAoC;AACzF,SAASC,iBAAiB;AAC1B,SAASC,QAAQC,SAASC,UAAmCC,gBAAgB;AAC7E,SAASC,QAAQC,sBAAsB;AAShC,IAAMC,kBAAkB,CAAC,EAAEC,QAAO,MAAwB;AAC/D,QAAM,EAAEC,EAAC,IAAKC,eAAeC,aAAAA;AAC7B,QAAMC,QAAQC,SAASL,OAAAA;AAGvB,QAAMM,YAAYC,SAChBH,SAASI,QACTR,mBAAmBS,aACfC,OAAOC,OAAOC,cAAc;IAAEC,QAAQb;EAAQ,CAAA,IAC9CU,OAAOC,OAAOC,cAAc,CAACE,OAAOA,GAAGC,WAAW,IAAA,GACtD,CAAC,GACD;IAACf;GAAQ;AAGX,QAAM,CAACgB,kBAAkBC,mBAAAA,IAAuBC,SAA8B,IAAA;AAC9E,QAAMC,eAAenB,mBAAmBS,aAAaH,UAAU,CAAA,IAAKU;AAEpE,SACE,sBAAA,cAACI,OAAAA;IAAIC,WAAU;KACZ,EAAErB,mBAAmBS,eACpB,sBAAA,cAACa,eAAAA;IACCN;IACAC;IACAX;MAGHa,gBAAgB,sBAAA,cAACI,WAAAA;IAAUT,IAAIK;IAAcnB;MAC7CA,mBAAmBS,cAAcH,UAAUkB,WAAW,KAAK,sBAAA,cAACJ,OAAAA;IAAIC,WAAU;KAAOpB,EAAE,cAAA,CAAA,CAAA;AAG1F;AAOA,IAAMsB,YAAY,CAAC,EAAET,IAAId,QAAO,MAAkB;AAChD,QAAMyB,SAASC,UAAAA;AACf,QAAMtB,QAAQC,SAASS,EAAAA;AACvB,QAAMa,sBAAsBC,6BAA6BC,QAAQf,EAAAA,CAAAA;AACjE,QAAMgB,cAAcC,QAAQ,MAAA;AAC1B,QAAI,CAACJ,qBAAqB;AACxB;IACF;AAEA,WAAOK,iBAAiBL,qBAAqBF,OAAOQ,OAAOC,OAAOC,SAASC,UAAUC,MAAMC,OAAO,IAAI;MACpGC,SAASnC,OAAOoC;MAChBC,WAAWzC,SAASwC;IACtB,CAAA;EACF,GAAG;IAACb;IAAqBvB;IAAOJ;GAAQ;AAExC,SAAO,sBAAA,cAAC0C,YAAAA;IAAWZ;IAA0Ba,YAAW;;AAC1D;AAQA,IAAMrB,gBAAgB,CAAC,EAAEN,kBAAkBC,qBAAqBX,UAAS,MAAsB;AAC7F,SACE,sBAAA,cAACsC,OAAOC,MAAI;IACVC,OAAO9B,kBAAkBwB;IACzBO,eAAe,CAACP,OAAOvB,oBAAoBX,UAAU0C,KAAK,CAAClC,OAAOA,GAAG0B,OAAOA,EAAAA,KAAOS,cAAAA,CAAAA;KAEnF,sBAAA,cAACL,OAAOM,eAAa;IAACC,aAAY;MAClC,sBAAA,cAACP,OAAOQ,QAAM,MACZ,sBAAA,cAACR,OAAOS,SAAO,MACb,sBAAA,cAACT,OAAOU,gBAAc,IAAA,GACtB,sBAAA,cAACV,OAAOW,UAAQ,MACbjD,UAAUkD,IAAI,CAAC,EAAEhB,IAAIzB,QAAO,MAC3B,sBAAA,cAAC6B,OAAOa,QAAM;IAACC,KAAKlB;IAAIM,OAAON;KAC5BzB,OAAAA,CAAAA,CAAAA,GAIP,sBAAA,cAAC6B,OAAOe,kBAAgB,IAAA,GACxB,sBAAA,cAACf,OAAOgB,OAAK,IAAA,CAAA,CAAA,CAAA;AAKvB;;;AC/FA,IAAA,0BAAeC;",
6
- "names": ["React", "useMemo", "useState", "failUndefined", "FunctionType", "ScriptType", "getInvocationUrl", "getUserFunctionUrlInMetadata", "useClient", "Filter", "getMeta", "getSpace", "useQuery", "Select", "useTranslation", "AutomationPanel", "subject", "t", "useTranslation", "SCRIPT_PLUGIN", "space", "getSpace", "functions", "useQuery", "undefined", "ScriptType", "Filter", "schema", "FunctionType", "source", "fn", "binding", "selectedFunction", "setSelectedFunction", "useState", "chatFunction", "div", "className", "BindingSelect", "ChatPanel", "length", "client", "useClient", "existingFunctionUrl", "getUserFunctionUrlInMetadata", "getMeta", "functionUrl", "useMemo", "getInvocationUrl", "config", "values", "runtime", "services", "edge", "url", "spaceId", "id", "subjectId", "DebugPanel", "classNames", "Select", "Root", "value", "onValueChange", "find", "failUndefined", "TriggerButton", "placeholder", "Portal", "Content", "ScrollUpButton", "Viewport", "map", "Option", "key", "ScrollDownButton", "Arrow", "AutomationPanel"]
7
- }