@datalayer/agent-runtimes 1.3.96 → 1.3.97

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.
@@ -62,7 +62,7 @@ export function SandboxSelector(_props) {
62
62
  // Held here: drawn, said why on hover, not taken. `aria-disabled`
63
63
  // rather than `disabled`: a disabled button takes no pointer, and
64
64
  // its reason would never be read.
65
- const held = heldTargetReason(entry);
65
+ const held = heldTargetReason(entry, service?.serverUrl ?? '');
66
66
  return (_jsx(SegmentedControl.Button, { selected: position === index, "aria-disabled": held ? true : undefined, "data-sandbox-target": entry, "data-sandbox-target-held": held ? '' : undefined, sx: {
67
67
  listStyle: 'none',
68
68
  ...(held
@@ -15,7 +15,7 @@ import { createTeamSelection } from './team';
15
15
  import { createSwitchableSandboxService, heldTargetReason, TARGET_SPECS, targetHasAgent, } from './switchable';
16
16
  export const AGENTS_PLUGIN_NAME = '@datalayer/loop-plugin-agents';
17
17
  /** The target asked for, or the page itself when this page holds it. */
18
- const offeredTarget = (target) => heldTargetReason(target) ? 'browser' : target;
18
+ const offeredTarget = (target, serverUrl) => (heldTargetReason(target, serverUrl) ? 'browser' : target);
19
19
  export const AgentsPlugin = definePlugin({
20
20
  name: AGENTS_PLUGIN_NAME,
21
21
  displayName: 'Agents',
@@ -51,7 +51,7 @@ export const AgentsPlugin = definePlugin({
51
51
  // A host that names no target gets the service's own default, Local —
52
52
  // read here, so that it is held on the web like any other.
53
53
  initialTarget: offeredTarget((showVariants || config.targetFixed ? config.target : 'browser') ??
54
- 'local'),
54
+ 'local', config.serverUrl),
55
55
  kernelSource: config.kernelSource,
56
56
  localAgent: config.localAgent,
57
57
  // The capacity plugins' say, read at switch time — lazily, because a
@@ -66,7 +66,7 @@ export declare const SANDBOX_TARGETS: readonly SandboxTarget[];
66
66
  * JupyterLab it is offered as before — the same line the code-sandbox picker
67
67
  * draws for a Jupyter Server's kernels (`codeSandboxProviders`).
68
68
  */
69
- export declare function heldTargetReason(target: SandboxTarget): string | undefined;
69
+ export declare function heldTargetReason(target: SandboxTarget, serverUrl: string): string | undefined;
70
70
  export declare const TARGET_SPECS: Record<SandboxTarget, SandboxTargetSpec>;
71
71
  /** Whether an agent runs on this target — the question the chat asks. */
72
72
  export declare function targetHasAgent(target: SandboxTarget): boolean;
@@ -52,8 +52,13 @@ export const SANDBOX_TARGETS = [
52
52
  * JupyterLab it is offered as before — the same line the code-sandbox picker
53
53
  * draws for a Jupyter Server's kernels (`codeSandboxProviders`).
54
54
  */
55
- export function heldTargetReason(target) {
56
- if (target === 'local' && !insideJupyterLab()) {
55
+ export function heldTargetReason(target, serverUrl) {
56
+ // A host that names its own agent-runtimes server — `app.mount`, `loop apps
57
+ // run --web` (LOOP P-08, P-25) — is not asking for the reader's machine:
58
+ // Local is that server, and it is offered. Held, every message of a page
59
+ // served by its own server went to the visitors' runtime instead
60
+ // (seen 2026-10-10 on 1.3.96).
61
+ if (target === 'local' && !serverUrl && !insideJupyterLab()) {
57
62
  return 'Not offered on the web for now: a local agent and the Jupyter server it starts run beside JupyterLab, not in a page.';
58
63
  }
59
64
  return undefined;
@@ -317,7 +322,7 @@ export function createSwitchableSandboxService({ serverUrl, initialTarget = 'loc
317
322
  return;
318
323
  }
319
324
  // Held here: refused whoever asks, not only by the switch's button.
320
- const held = heldTargetReason(next);
325
+ const held = heldTargetReason(next, serverUrl);
321
326
  if (held) {
322
327
  throw new Error(held);
323
328
  }
@@ -8,7 +8,8 @@
8
8
  * started_at, ended_at}` — which the AG-UI adapter hands on as an
9
9
  * `activity`. A step is drawn as the chat draws a tool call: one row,
10
10
  * collapsed, its input and output inside, running until it ends; a nested
11
- * step says the step it is in.
11
+ * step says the step it is in. A step that streams its output (LOOP P-31)
12
+ * is said again as it writes, its output so far, and drawn in place.
12
13
  */
13
14
  import type { DisplayItem, ToolCallMessage } from '../../types/chat';
14
15
  /** The `CUSTOM` event's name. */
@@ -43,9 +43,8 @@ export function stepItem(step, inside) {
43
43
  kind: step.kind,
44
44
  ...(step.input !== null ? { input: step.input } : {}),
45
45
  },
46
- ...(step.ended && !step.error && step.output !== null
47
- ? { result: step.output }
48
- : {}),
46
+ // Running, what it wrote so far — a step that streams (LOOP P-31).
47
+ ...(!step.error && step.output !== null ? { result: step.output } : {}),
49
48
  status: !step.ended ? 'executing' : step.error ? 'error' : 'complete',
50
49
  ...(step.error ? { error: step.error } : {}),
51
50
  summary: inside ? `${kind}, inside ${inside}` : kind,
@@ -208,7 +208,8 @@ export function ToolCallDisplay({ toolCallId, toolName, args, result, status, er
208
208
  wordBreak: 'break-word',
209
209
  }, children: Object.keys(args).length > 0
210
210
  ? JSON.stringify(args, null, 2)
211
- : `(${chatText.noParameters})` }) })] }), status === 'complete' && result !== undefined && (_jsxs(Box, { children: [_jsx(Text, { sx: {
211
+ : `(${chatText.noParameters})` }) })] }), (status === 'complete' || status === 'executing') &&
212
+ result !== undefined && (_jsxs(Box, { children: [_jsx(Text, { sx: {
212
213
  display: 'block',
213
214
  fontSize: 0,
214
215
  fontWeight: 'semibold',
@@ -20,6 +20,7 @@ export declare const EXAMPLE_AI_EXPLAINS_NOTEBOOK_OUTPUT_AGENTSPEC_0_0_1: Agents
20
20
  export declare const EXAMPLE_AI_WRITES_PANDAS_CODE_AGENTSPEC_0_0_1: Agentspec;
21
21
  export declare const EXAMPLE_ANALYZE_EXCEL_SPREADSHEET_AGENTSPEC_0_0_1: Agentspec;
22
22
  export declare const EXAMPLE_BACKEND_TOOL_RENDERING_AGENTSPEC_0_0_1: Agentspec;
23
+ export declare const EXAMPLE_BLANK_AGENTSPEC_0_0_1: Agentspec;
23
24
  export declare const EXAMPLE_BUILD_NOTEBOOK_WITH_ONE_PROMPT_AGENTSPEC_0_0_1: Agentspec;
24
25
  export declare const EXAMPLE_CHECKPOINTS_AGENTSPEC_0_0_1: Agentspec;
25
26
  export declare const EXAMPLE_CLOUDFLARE_AGENTSPEC_0_0_1: Agentspec;
@@ -1086,6 +1086,54 @@ Use the \`get_weather\` tool to fetch current weather data.
1086
1086
  parameters: undefined,
1087
1087
  subagents: undefined,
1088
1088
  };
1089
+ export const EXAMPLE_BLANK_AGENTSPEC_0_0_1 = {
1090
+ id: 'example-blank',
1091
+ version: '0.0.1',
1092
+ name: 'A Blank Agent',
1093
+ description: `A model and nothing else: no prompt of its own, no MCP servers, no skills, no tools. The application that runs it says who it is in its instructions, and gives it its tools — so an app.py runs it in its own process, as on a runtime.`,
1094
+ tags: ['workflow'],
1095
+ domain: undefined,
1096
+ enabled: true,
1097
+ model: 'bedrock:us.anthropic.claude-sonnet-4-6',
1098
+ modelAdditionals: ['alibaba:qwen-max'],
1099
+ mcpServers: [],
1100
+ skills: [].filter(Boolean),
1101
+ backendTools: [],
1102
+ frontendTools: [],
1103
+ environmentName: 'ai-agents-env',
1104
+ icon: 'agent',
1105
+ emoji: '⬜',
1106
+ color: '#6B7280',
1107
+ suggestions: [],
1108
+ welcomeMessage: undefined,
1109
+ welcomeNotebook: undefined,
1110
+ welcomeDocument: undefined,
1111
+ sandboxVariant: 'jupyter-server',
1112
+ harness: 'pydantic-ai',
1113
+ systemPrompt: undefined,
1114
+ systemPromptCodemodeAddons: undefined,
1115
+ goal: undefined,
1116
+ delegable: [],
1117
+ protocol: undefined,
1118
+ uiPlugin: undefined,
1119
+ trigger: undefined,
1120
+ modelConfig: undefined,
1121
+ mcpServerTools: undefined,
1122
+ guardrails: undefined,
1123
+ evals: undefined,
1124
+ codemode: undefined,
1125
+ output: undefined,
1126
+ advanced: undefined,
1127
+ checkpoints: undefined,
1128
+ authorizationPolicy: undefined,
1129
+ notifications: undefined,
1130
+ memory: 'ephemeral',
1131
+ preHooks: undefined,
1132
+ postHooks: undefined,
1133
+ toolHooks: undefined,
1134
+ parameters: undefined,
1135
+ subagents: undefined,
1136
+ };
1089
1137
  export const EXAMPLE_BUILD_NOTEBOOK_WITH_ONE_PROMPT_AGENTSPEC_0_0_1 = {
1090
1138
  id: 'example-build-notebook-with-one-prompt',
1091
1139
  version: '0.0.1',
@@ -13276,6 +13324,7 @@ export const AGENTSPECS = {
13276
13324
  'example-ai-writes-pandas-code': EXAMPLE_AI_WRITES_PANDAS_CODE_AGENTSPEC_0_0_1,
13277
13325
  'example-analyze-excel-spreadsheet': EXAMPLE_ANALYZE_EXCEL_SPREADSHEET_AGENTSPEC_0_0_1,
13278
13326
  'example-backend-tool-rendering': EXAMPLE_BACKEND_TOOL_RENDERING_AGENTSPEC_0_0_1,
13327
+ 'example-blank': EXAMPLE_BLANK_AGENTSPEC_0_0_1,
13279
13328
  'example-build-notebook-with-one-prompt': EXAMPLE_BUILD_NOTEBOOK_WITH_ONE_PROMPT_AGENTSPEC_0_0_1,
13280
13329
  'example-checkpoints': EXAMPLE_CHECKPOINTS_AGENTSPEC_0_0_1,
13281
13330
  'example-cloudflare': EXAMPLE_CLOUDFLARE_AGENTSPEC_0_0_1,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datalayer/agent-runtimes",
3
- "version": "1.3.96",
3
+ "version": "1.3.97",
4
4
  "type": "module",
5
5
  "workspaces": [
6
6
  ".",
@@ -54,7 +54,7 @@
54
54
  },
55
55
  "scripts": {
56
56
  "apply:patches": "bash scripts/apply-patches.sh",
57
- "build": "npm run clean && gulp resources-to-lib && tsc -b && cross-env NODE_OPTIONS=--max-old-space-size=8192 vite build",
57
+ "build": "npm run clean && gulp resources-to-lib && tsc -b && cross-env NODE_OPTIONS=--max-old-space-size=8192 vite build && npm run build:embed",
58
58
  "build-storybook": "storybook build",
59
59
  "build:all": "npm run build && npm run build:examples",
60
60
  "build:embed": "cross-env NODE_OPTIONS=--max-old-space-size=8192 vite build --config vite.embed.config.ts",
@@ -1,4 +1,9 @@
1
1
  #!/usr/bin/env node
2
+ /*
3
+ * Copyright (c) 2025-2026 Datalayer, Inc.
4
+ * Distributed under the terms of the Modified BSD License.
5
+ */
6
+
2
7
  /**
3
8
  * Put `dist-embed/` in a checkout: the embed element's own bundle.
4
9
  *