@datalayer/agent-runtimes 1.3.15 → 1.3.17

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 (81) hide show
  1. package/README.md +1 -1
  2. package/lib/chat/base/ChatBase.js +3 -2
  3. package/lib/config/AgentConfiguration.d.ts +1 -1
  4. package/lib/loop/apps/AppRenderer.d.ts +24 -0
  5. package/lib/loop/apps/AppRenderer.js +101 -0
  6. package/lib/loop/apps/appspec.d.ts +69 -0
  7. package/lib/loop/apps/appspec.js +566 -0
  8. package/lib/loop/apps/checks.d.ts +21 -0
  9. package/lib/loop/apps/checks.js +556 -0
  10. package/lib/loop/apps/index.d.ts +10 -0
  11. package/lib/loop/apps/index.js +14 -0
  12. package/lib/loop/apps/rules.d.ts +64 -0
  13. package/lib/loop/apps/rules.js +289 -0
  14. package/lib/loop/apps/yaml.d.ts +17 -0
  15. package/lib/loop/apps/yaml.js +185 -0
  16. package/lib/loop/embed/LoopEmbed.d.ts +6 -1
  17. package/lib/loop/embed/LoopEmbed.js +3 -2
  18. package/lib/loop/index.d.ts +1 -0
  19. package/lib/loop/index.js +3 -0
  20. package/lib/loop/plugins/chat/ChatView.js +9 -4
  21. package/lib/loop/plugins/chat/index.d.ts +10 -0
  22. package/lib/loop/plugins/chat/index.js +1 -0
  23. package/lib/loop/presets.d.ts +6 -0
  24. package/lib/loop/presets.js +2 -1
  25. package/lib/loop/shell/LoopWorkspace.d.ts +14 -0
  26. package/lib/loop/shell/LoopWorkspace.js +20 -6
  27. package/lib/loop/shell/index.d.ts +1 -1
  28. package/lib/loop/shell/index.js +1 -1
  29. package/lib/loop/shell/useWorkspaceFullScreen.d.ts +17 -4
  30. package/lib/loop/shell/useWorkspaceFullScreen.js +23 -6
  31. package/lib/specs/actions.d.ts +30 -0
  32. package/lib/specs/actions.js +616 -0
  33. package/lib/specs/agents/agents.d.ts +1 -0
  34. package/lib/specs/agents/agents.js +338 -284
  35. package/lib/specs/apps.d.ts +25 -0
  36. package/lib/specs/apps.js +1064 -0
  37. package/lib/specs/cogs.d.ts +19 -0
  38. package/lib/specs/cogs.js +736 -0
  39. package/lib/specs/events.d.ts +6 -1
  40. package/lib/specs/events.js +144 -1
  41. package/lib/specs/frames.d.ts +19 -0
  42. package/lib/specs/frames.js +444 -0
  43. package/lib/specs/gates.d.ts +22 -0
  44. package/lib/specs/gates.js +177 -0
  45. package/lib/specs/guards.d.ts +26 -0
  46. package/lib/specs/guards.js +930 -0
  47. package/lib/specs/index.d.ts +10 -0
  48. package/lib/specs/index.js +10 -0
  49. package/lib/specs/mcpServers.js +2 -2
  50. package/lib/specs/memory.js +4 -0
  51. package/lib/specs/modelProviders.d.ts +22 -0
  52. package/lib/specs/modelProviders.js +102 -0
  53. package/lib/specs/models.d.ts +31 -0
  54. package/lib/specs/models.js +215 -0
  55. package/lib/specs/ops.d.ts +15 -0
  56. package/lib/specs/ops.js +1272 -0
  57. package/lib/specs/outputs.js +2 -2
  58. package/lib/specs/skills.js +1 -1
  59. package/lib/specs/teams/teams.js +18 -18
  60. package/lib/specs/tracks.d.ts +15 -0
  61. package/lib/specs/tracks.js +87 -0
  62. package/lib/specs/uiPlugins.d.ts +16 -0
  63. package/lib/specs/uiPlugins.js +40 -0
  64. package/lib/types/agentspecs.d.ts +453 -2
  65. package/lib/types/memory.d.ts +2 -0
  66. package/lib/types/models.d.ts +52 -0
  67. package/package.json +2 -1
  68. package/scripts/check-cloudflare-models.py +122 -0
  69. package/scripts/codegen/agentspecs_clone.py +53 -0
  70. package/scripts/codegen/compose.py +65 -0
  71. package/scripts/codegen/generate_agents.py +14 -4
  72. package/scripts/codegen/generate_apps.py +454 -0
  73. package/scripts/codegen/generate_cogs.py +308 -0
  74. package/scripts/codegen/generate_frames.py +278 -0
  75. package/scripts/codegen/generate_memory.py +2 -0
  76. package/scripts/codegen/generate_model_providers.py +246 -0
  77. package/scripts/codegen/generate_models.py +135 -4
  78. package/scripts/codegen/generate_ops.py +388 -0
  79. package/scripts/codegen/generate_sandbox_agents.py +1 -1
  80. package/scripts/codegen/generate_ui_plugins.py +226 -0
  81. package/scripts/gen_workers.py +2 -2
@@ -103,6 +103,20 @@ export type LoopWorkspaceProps = {
103
103
  * through `LoopSlots.header`.
104
104
  */
105
105
  headerActions?: ReactNode;
106
+ /**
107
+ * Where the header's controls go, when not in a row of their own.
108
+ *
109
+ * A host that already draws a bar above the workspace — a window's title
110
+ * bar, a frame with its own tabs — hands over an element in it, and the
111
+ * controls the header would have carried (the host's `headerActions`, every
112
+ * plugin's `LoopSlots.header` contribution, the view switcher) are rendered
113
+ * there instead, and the workspace draws no header row. They stay inside
114
+ * the workspace's React tree, so they keep their context and their state.
115
+ *
116
+ * `null` while the host's element is not mounted yet: nothing is rendered,
117
+ * and no row is drawn in its place.
118
+ */
119
+ headerContainer?: HTMLElement | null;
106
120
  };
107
121
  /** Build the platform for a set of plugins. */
108
122
  export declare function buildLoopReactor(extensions: PluginRef[]): ReactorPlatform;
@@ -1,5 +1,6 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
3
+ import { createPortal } from 'react-dom';
3
4
  import { Box } from '@primer/react';
4
5
  import { buildReactorFromPlugins, onView, } from '@datalayer/reactor';
5
6
  import { ReactorSlot, ReactorViewHost, useContributions, useReactorEvent, useSlotComponents, useReactor, } from '@datalayer/reactor/react';
@@ -11,21 +12,21 @@ export function buildLoopReactor(extensions) {
11
12
  return buildReactorFromPlugins(extensions);
12
13
  }
13
14
  export function LoopWorkspace(props) {
14
- const { serverUrl, agentId, conversationId, model, sandbox = { state: 'idle' }, extensions = [], reactor: providedReactor, manageReactor = true, initialViewType, onSend, layout = 'page', showViewSelector = true, showHeader = true, chatHeaderActions, headerActions, } = props;
15
+ const { serverUrl, agentId, conversationId, model, sandbox = { state: 'idle' }, extensions = [], reactor: providedReactor, manageReactor = true, initialViewType, onSend, layout = 'page', showViewSelector = true, showHeader = true, chatHeaderActions, headerActions, headerContainer, } = props;
15
16
  // Building the platform is a one-time act: rebuilding it on every render
16
17
  // would restart every plugin.
17
18
  const reactor = useMemo(() => providedReactor ?? buildLoopReactor(extensions),
18
19
  // eslint-disable-next-line react-hooks/exhaustive-deps
19
20
  [providedReactor]);
20
21
  useReactor(reactor, { autoStart: manageReactor });
21
- return (_jsx(WorkspaceBody, { serverUrl: serverUrl, agentId: agentId, conversationId: conversationId, model: model, initialSandbox: sandbox, initialViewType: initialViewType, onSend: onSend, layout: layout, showViewSelector: showViewSelector, showHeader: showHeader, chatHeaderActions: chatHeaderActions, headerActions: headerActions }));
22
+ return (_jsx(WorkspaceBody, { serverUrl: serverUrl, agentId: agentId, conversationId: conversationId, model: model, initialSandbox: sandbox, initialViewType: initialViewType, onSend: onSend, layout: layout, showViewSelector: showViewSelector, showHeader: showHeader, chatHeaderActions: chatHeaderActions, headerActions: headerActions, headerContainer: headerContainer }));
22
23
  }
23
24
  /**
24
25
  * Split from `LoopWorkspace` so the hooks below run with the platform already
25
26
  * registered — `useContributions` needs a reactor in the store, and `useReactor`
26
27
  * registers it during the parent's render.
27
28
  */
28
- function WorkspaceBody({ serverUrl, agentId: initialAgentId, conversationId, model, initialSandbox, initialViewType, onSend, layout = 'page', showViewSelector = true, showHeader = true, chatHeaderActions, headerActions, }) {
29
+ function WorkspaceBody({ serverUrl, agentId: initialAgentId, conversationId, model, initialSandbox, initialViewType, onSend, layout = 'page', showViewSelector = true, showHeader = true, chatHeaderActions, headerActions, headerContainer, }) {
29
30
  /*
30
31
  * Which agent the session is talking to.
31
32
  *
@@ -146,6 +147,12 @@ function WorkspaceBody({ serverUrl, agentId: initialAgentId, conversationId, mod
146
147
  // activates whatever was waiting for it. A plugin that declares neither is
147
148
  // untouched, so this costs nothing until somebody uses it.
148
149
  useReactorEvent(effectiveViewType ? onView(effectiveViewType) : undefined);
150
+ /*
151
+ * The header's controls: the host's first, then the plugins', then the
152
+ * view switcher on the trailing edge. Drawn in the header row, or in the
153
+ * host's own bar when it handed one over (`headerContainer`).
154
+ */
155
+ const headerControls = (_jsxs(_Fragment, { children: [headerActions, _jsx(ReactorSlot, { slot: LoopSlots.header, props: { workspace } }), showViewSelector ? (_jsx(ViewSwitcher, { views: views, workspace: workspace, compact: compact })) : null] }));
149
156
  return (_jsxs(Box
150
157
  /*
151
158
  Marked so a plugin inside can find the workspace it is part of.
@@ -169,7 +176,14 @@ function WorkspaceBody({ serverUrl, agentId: initialAgentId, conversationId, mod
169
176
  position: 'relative',
170
177
  bg: 'canvas.default',
171
178
  color: 'fg.default',
172
- }, children: [showHeader ? (_jsxs(Box, { as: "header", sx: {
179
+ }, children: [showHeader && headerContainer
180
+ ? createPortal(_jsx(Box, { sx: {
181
+ display: 'flex',
182
+ alignItems: 'center',
183
+ flexWrap: 'wrap',
184
+ gap: 2,
185
+ }, children: headerControls }), headerContainer)
186
+ : null, showHeader && headerContainer === undefined ? (_jsx(Box, { as: "header", sx: {
173
187
  display: 'flex',
174
188
  alignItems: 'center',
175
189
  // In a column there is no room for a row: the header wraps rather
@@ -191,7 +205,7 @@ function WorkspaceBody({ serverUrl, agentId: initialAgentId, conversationId, mod
191
205
  borderBottom: '1px solid',
192
206
  borderColor: 'border.default',
193
207
  flex: '0 0 auto',
194
- }, children: [headerActions, _jsx(ReactorSlot, { slot: LoopSlots.header, props: { workspace } }), showViewSelector ? (_jsx(ViewSwitcher, { views: views, workspace: workspace, compact: compact })) : null] })) : null, _jsxs(Box, { sx: { flex: '1 1 auto', minHeight: 0, display: 'flex' }, children: [_jsx(Box, { sx: {
208
+ }, children: headerControls })) : null, _jsxs(Box, { sx: { flex: '1 1 auto', minHeight: 0, display: 'flex' }, children: [_jsx(Box, { sx: {
195
209
  flex: '1 1 auto',
196
210
  minWidth: 0,
197
211
  minHeight: 0,
@@ -6,5 +6,5 @@
6
6
  export { LoopWorkspace, buildLoopReactor, type LoopWorkspaceProps, } from './LoopWorkspace';
7
7
  export { ViewSwitcher, type ViewSwitcherProps } from './ViewSwitcher';
8
8
  export { PluginToggles, type PluginTogglesProps } from './PluginToggles';
9
- export { useWorkspaceFullScreen, type WorkspaceFullScreen, } from './useWorkspaceFullScreen';
9
+ export { fullScreenNode, useWorkspaceFullScreen, type WorkspaceFullScreen, } from './useWorkspaceFullScreen';
10
10
  export { WorkspaceFullScreenAction } from './WorkspaceFullScreenAction';
@@ -10,5 +10,5 @@
10
10
  export { LoopWorkspace, buildLoopReactor, } from './LoopWorkspace';
11
11
  export { ViewSwitcher } from './ViewSwitcher';
12
12
  export { PluginToggles } from './PluginToggles';
13
- export { useWorkspaceFullScreen, } from './useWorkspaceFullScreen';
13
+ export { fullScreenNode, useWorkspaceFullScreen, } from './useWorkspaceFullScreen';
14
14
  export { WorkspaceFullScreenAction } from './WorkspaceFullScreenAction';
@@ -79,15 +79,28 @@ export type WorkspaceFullScreenOptions = {
79
79
  */
80
80
  topOffset?: number | string;
81
81
  };
82
+ /**
83
+ * What full screen promotes, found from the control that asked.
84
+ *
85
+ * The workspace (`[data-loop-workspace]`) — unless a host marked something
86
+ * around it with `data-loop-fullscreen-root`. A host that draws its own bar
87
+ * above the workspace and has the header's controls rendered in it
88
+ * (`LoopWorkspace`'s `headerContainer`) marks the element holding both: the
89
+ * controls are then outside the workspace, and promoting the workspace alone
90
+ * would leave them — the one that leaves full screen included — under the
91
+ * overlay. The anchor itself when there is neither.
92
+ */
93
+ export declare function fullScreenNode(anchor: HTMLElement | null): HTMLElement | null;
82
94
  /**
83
95
  * Full-screen state and the toggle, anchored by any element inside the
84
96
  * workspace.
85
97
  *
86
98
  * The element promoted is the whole workspace — the nearest
87
- * `[data-loop-workspace]` above the anchor — so the header's controls come
88
- * along instead of being left on the page underneath. With no workspace
89
- * around it, the anchor's own element is promoted, which is what a view
90
- * mounted without a shell would want.
99
+ * `[data-loop-workspace]` above the anchor, or the host's
100
+ * `[data-loop-fullscreen-root]` around it (see `fullScreenNode`) — so the
101
+ * header's controls come along instead of being left on the page underneath.
102
+ * With neither around it, the anchor's own element is promoted, which is what
103
+ * a view mounted without a shell would want.
91
104
  */
92
105
  export declare function useWorkspaceFullScreen(anchorRef: RefObject<HTMLElement | null>, options?: WorkspaceFullScreenOptions): WorkspaceFullScreen;
93
106
  export default useWorkspaceFullScreen;
@@ -21,15 +21,32 @@ export function resolveTopOffset(offset) {
21
21
  ? Math.max(0, Math.round(element.getBoundingClientRect().bottom))
22
22
  : 0;
23
23
  }
24
+ /**
25
+ * What full screen promotes, found from the control that asked.
26
+ *
27
+ * The workspace (`[data-loop-workspace]`) — unless a host marked something
28
+ * around it with `data-loop-fullscreen-root`. A host that draws its own bar
29
+ * above the workspace and has the header's controls rendered in it
30
+ * (`LoopWorkspace`'s `headerContainer`) marks the element holding both: the
31
+ * controls are then outside the workspace, and promoting the workspace alone
32
+ * would leave them — the one that leaves full screen included — under the
33
+ * overlay. The anchor itself when there is neither.
34
+ */
35
+ export function fullScreenNode(anchor) {
36
+ return (anchor?.closest('[data-loop-fullscreen-root]') ??
37
+ anchor?.closest('[data-loop-workspace]') ??
38
+ anchor);
39
+ }
24
40
  /**
25
41
  * Full-screen state and the toggle, anchored by any element inside the
26
42
  * workspace.
27
43
  *
28
44
  * The element promoted is the whole workspace — the nearest
29
- * `[data-loop-workspace]` above the anchor — so the header's controls come
30
- * along instead of being left on the page underneath. With no workspace
31
- * around it, the anchor's own element is promoted, which is what a view
32
- * mounted without a shell would want.
45
+ * `[data-loop-workspace]` above the anchor, or the host's
46
+ * `[data-loop-fullscreen-root]` around it (see `fullScreenNode`) — so the
47
+ * header's controls come along instead of being left on the page underneath.
48
+ * With neither around it, the anchor's own element is promoted, which is what
49
+ * a view mounted without a shell would want.
33
50
  */
34
51
  export function useWorkspaceFullScreen(anchorRef, options = {}) {
35
52
  const { forceOverlay = false, paintOverlay = false, topOffset = 0 } = options;
@@ -66,7 +83,7 @@ export function useWorkspaceFullScreen(anchorRef, options = {}) {
66
83
  * runs — so at full screen a reader would lose the two controls most
67
84
  * worth having room for.
68
85
  */
69
- const node = anchorRef.current?.closest('[data-loop-workspace]') ?? anchorRef.current;
86
+ const node = fullScreenNode(anchorRef.current);
70
87
  if (fullScreen) {
71
88
  if (usingApi.current && document.fullscreenElement) {
72
89
  void document.exitFullscreen();
@@ -116,7 +133,7 @@ export function useWorkspaceFullScreen(anchorRef, options = {}) {
116
133
  if (!paintOverlay || !fullScreen || usingApi.current) {
117
134
  return undefined;
118
135
  }
119
- const node = anchorRef.current?.closest('[data-loop-workspace]') ?? anchorRef.current;
136
+ const node = fullScreenNode(anchorRef.current);
120
137
  if (!node) {
121
138
  return undefined;
122
139
  }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Action Classes.
3
+ *
4
+ * What every tool does to the world: read, write, send, buy, delete, publish.
5
+ * A tool with no class is unknown, and unknown is the most restricted.
6
+ *
7
+ * This file is AUTO-GENERATED from YAML specifications.
8
+ * DO NOT EDIT MANUALLY - run 'make specs' to regenerate.
9
+ */
10
+ import type { ActionClass, AppBehaviour, AppEscalation, ServerActionsSpec } from '../types/agentspecs';
11
+ /** The classes of action, from the one that changes nothing. */
12
+ export declare const ACTION_CLASSES: ActionClass[];
13
+ /** What each tool of the tools catalogue does, by id. */
14
+ export declare const TOOL_ACTIONS: Record<string, ActionClass[]>;
15
+ /**
16
+ * What each MCP server's tools do, by server id. `checked` is the day the
17
+ * names were read off the running server; absent when nobody looked.
18
+ */
19
+ export declare const SERVER_ACTIONS: Record<string, ServerActionsSpec>;
20
+ /**
21
+ * What each application of the catalogue does about each classed tool of the
22
+ * servers it connects to, as agentspecs decides it. What the rules engine has
23
+ * to reproduce.
24
+ */
25
+ export declare const APP_BEHAVIOURS: Record<string, Record<string, AppBehaviour>>;
26
+ /**
27
+ * Where what a tool is asked changes what an application does about it: by
28
+ * application and tool, each condition and the behaviour when it holds.
29
+ */
30
+ export declare const APP_ESCALATIONS: Record<string, Record<string, AppEscalation[]>>;