@datalayer/agent-runtimes 1.0.18 → 1.0.20

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 (146) hide show
  1. package/README.md +14 -6
  2. package/lib/AgentNode.js +567 -67
  3. package/lib/App.js +2 -2
  4. package/lib/agent-node/AgentNodeGallery.d.ts +80 -0
  5. package/lib/agent-node/AgentNodeGallery.js +627 -0
  6. package/lib/agent-notebook-main.js +0 -1
  7. package/lib/api/runtimes/runtimes.d.ts +57 -0
  8. package/lib/api/runtimes/runtimes.js +55 -1
  9. package/lib/chat/Chat.d.ts +14 -1
  10. package/lib/chat/Chat.js +22 -7
  11. package/lib/chat/base/ChatBase.js +86 -23
  12. package/lib/chat/document/EphemeralDocument.d.ts +49 -1
  13. package/lib/chat/document/EphemeralDocument.js +141 -15
  14. package/lib/chat/header/ChatHeaderBase.d.ts +3 -1
  15. package/lib/chat/header/ChatHeaderBase.js +5 -3
  16. package/lib/chat/messages/ChatMessageList.d.ts +19 -0
  17. package/lib/chat/messages/ChatMessageList.js +180 -9
  18. package/lib/chat/notebook/EphemeralNotebook.d.ts +40 -1
  19. package/lib/chat/notebook/EphemeralNotebook.js +49 -13
  20. package/lib/chat/prompt/InputPrompt.js +1 -1
  21. package/lib/chat/tools/SubagentActivity.d.ts +20 -0
  22. package/lib/chat/tools/SubagentActivity.js +154 -0
  23. package/lib/chat/tools/index.d.ts +1 -0
  24. package/lib/chat/tools/index.js +1 -0
  25. package/lib/chat/usage/TokenUsageBar.js +3 -3
  26. package/lib/client/AgentRuntimesClient.d.ts +5 -0
  27. package/lib/client/AgentsMixin.js +3 -1
  28. package/lib/client/mixins/RuntimesMixin.d.ts +12 -0
  29. package/lib/client/mixins/RuntimesMixin.js +24 -1
  30. package/lib/components/AgentSummary.d.ts +1 -0
  31. package/lib/components/AgentSummary.js +66 -10
  32. package/lib/components/runtimes/RuntimePickerBase.js +64 -29
  33. package/lib/components/runtimes/RuntimePickerCell.js +1 -1
  34. package/lib/components/runtimes/RuntimePickerNotebook.js +1 -1
  35. package/lib/components/runtimes/RuntimeSimplePicker.js +3 -2
  36. package/lib/components/runtimes/RuntimeUtils.js +2 -2
  37. package/lib/context/GraphFlowChart.js +1 -1
  38. package/lib/context/TokenUsageChart.js +1 -1
  39. package/lib/context/TurnGraphChart.js +2 -2
  40. package/lib/examples/A2UiAgentExample.js +4 -4
  41. package/lib/examples/A2UiComponentsGalleryExample.js +3 -3
  42. package/lib/examples/A2UiContactCardExample.js +3 -3
  43. package/lib/examples/A2UiRestaurantExample.js +2 -2
  44. package/lib/examples/A2UiViewerExample.js +3 -3
  45. package/lib/examples/AgUiAgenticExample.js +3 -3
  46. package/lib/examples/AgUiBackendToolRenderingExample.js +2 -2
  47. package/lib/examples/AgUiHaikuGenUiExample.js +3 -3
  48. package/lib/examples/AgUiHumanInTheLoopExample.js +5 -5
  49. package/lib/examples/AgUiSharedStateExample.js +3 -3
  50. package/lib/examples/AgUiToolsBasedGenUiExample.js +7 -5
  51. package/lib/examples/AgentCheckpointsExample.js +6 -5
  52. package/lib/examples/{AgentSandboxExample.d.ts → AgentCodeSandboxExample.d.ts} +4 -4
  53. package/lib/examples/{AgentSandboxExample.js → AgentCodeSandboxExample.js} +10 -9
  54. package/lib/examples/AgentCodeSandboxesExample.js +2 -2
  55. package/lib/examples/AgentCodemodeExample.js +3 -3
  56. package/lib/examples/AgentCompactionExample.d.ts +12 -0
  57. package/lib/examples/AgentCompactionExample.js +244 -0
  58. package/lib/examples/AgentEvalsExample.js +10 -20
  59. package/lib/examples/AgentGuardrailsExample.js +2 -2
  60. package/lib/examples/AgentHooksExample.js +1 -1
  61. package/lib/examples/AgentInferenceProviderExample.js +6 -8
  62. package/lib/examples/AgentLoopExample.js +3 -3
  63. package/lib/examples/AgentMCPExample.js +3 -3
  64. package/lib/examples/AgentMemoryExample.d.ts +4 -2
  65. package/lib/examples/AgentMemoryExample.js +93 -10
  66. package/lib/examples/AgentMonitoringExample.js +2 -2
  67. package/lib/examples/AgentNotificationsExample.js +1 -1
  68. package/lib/examples/AgentOtelExample.d.ts +2 -3
  69. package/lib/examples/AgentOtelExample.js +7 -12
  70. package/lib/examples/AgentOutputsExample.js +5 -5
  71. package/lib/examples/AgentParametersExample.js +3 -3
  72. package/lib/examples/AgentSkillsExample.js +4 -4
  73. package/lib/examples/AgentSubagentsExample.d.ts +2 -2
  74. package/lib/examples/AgentSubagentsExample.js +43 -34
  75. package/lib/examples/AgentToolApprovalsExample.js +1 -1
  76. package/lib/examples/AgentTriggersExample.js +9 -11
  77. package/lib/examples/AgentspecsExample.js +13 -5
  78. package/lib/examples/CellExample.d.ts +6 -0
  79. package/lib/examples/CellExample.js +84 -0
  80. package/lib/examples/ChatCustomExample.js +1 -1
  81. package/lib/examples/ChatExample.js +1 -1
  82. package/lib/examples/ChatStandaloneExample.js +2 -2
  83. package/lib/examples/HomeExample.js +29 -28
  84. package/lib/examples/Lexical2Example.js +2 -2
  85. package/lib/examples/LexicalAgentExample.js +1 -1
  86. package/lib/examples/LexicalAgentSidebarExample.js +2 -2
  87. package/lib/examples/NotebookAgentSidebarExample.d.ts +1 -1
  88. package/lib/examples/NotebookAgentSidebarExample.js +5 -4
  89. package/lib/examples/NotebookCollaborationExample.js +3 -3
  90. package/lib/examples/NotebookExample.js +2 -2
  91. package/lib/examples/components/ExampleWrapper.js +5 -0
  92. package/lib/examples/components/Header.js +2 -2
  93. package/lib/examples/components/HeaderControls.js +1 -1
  94. package/lib/examples/components/LexicalEditor.js +1 -1
  95. package/lib/examples/components/MainContent.js +1 -1
  96. package/lib/examples/components/MockFileBrowser.js +8 -8
  97. package/lib/examples/components/TimeTravel.js +1 -1
  98. package/lib/examples/components/haiku/HaikuDisplay.js +2 -2
  99. package/lib/examples/example-selector.js +4 -3
  100. package/lib/examples/hooks/useExampleAgentRuntime.js +11 -1
  101. package/lib/examples/hooks/useExampleAgentRuntimes.d.ts +7 -0
  102. package/lib/examples/hooks/useExampleAgentRuntimes.js +82 -0
  103. package/lib/examples/index.d.ts +2 -1
  104. package/lib/examples/index.js +2 -1
  105. package/lib/examples/main.js +359 -46
  106. package/lib/examples/utils/agentSummaryStore.d.ts +17 -0
  107. package/lib/examples/utils/themedProvider.js +32 -2
  108. package/lib/examples/utils/useExampleAgentRuntimesUrl.js +2 -1
  109. package/lib/examples2/NotebookMutationsKernel.js +6 -3
  110. package/lib/examples2/NotebookMutationsServiceManager.js +6 -3
  111. package/lib/examples2/ReactRouterExample.js +5 -5
  112. package/lib/examples2/main.js +38 -0
  113. package/lib/hooks/useAIAgentsWebSocket.js +35 -0
  114. package/lib/hooks/useAgentRuntimes.d.ts +22 -0
  115. package/lib/hooks/useAgentRuntimes.js +192 -5
  116. package/lib/hooks/useCheckpoints.js +2 -2
  117. package/lib/hooks/useToolApprovals.d.ts +10 -4
  118. package/lib/hooks/useToolApprovals.js +11 -5
  119. package/lib/identity/AgentIdentity.js +1 -2
  120. package/lib/models/Runtime.d.ts +10 -8
  121. package/lib/models/RuntimeDTO.d.ts +5 -3
  122. package/lib/models/RuntimeDTO.js +3 -3
  123. package/lib/runtimes/actions.js +3 -1
  124. package/lib/runtimes/apis.d.ts +7 -0
  125. package/lib/shims/primerAddonsBox.d.ts +1 -0
  126. package/lib/shims/primerAddonsBox.js +7 -0
  127. package/lib/specs/agents/agents.d.ts +51 -0
  128. package/lib/specs/agents/agents.js +3389 -94
  129. package/lib/specs/models.d.ts +2 -0
  130. package/lib/specs/models.js +37 -0
  131. package/lib/stores/agentRuntimeStore.d.ts +32 -1
  132. package/lib/stores/agentRuntimeStore.js +65 -1
  133. package/lib/stores/index.d.ts +1 -1
  134. package/lib/stores/index.js +1 -1
  135. package/lib/types/agents.d.ts +9 -3
  136. package/lib/types/agentspecs.d.ts +2 -0
  137. package/lib/types/chat.d.ts +83 -0
  138. package/lib/types/models.d.ts +5 -0
  139. package/lib/types/stream.d.ts +58 -1
  140. package/package.json +6 -5
  141. package/scripts/codegen/generate_agents.py +7 -0
  142. package/scripts/codegen/generate_models.py +22 -9
  143. package/scripts/gen_workers.py +340 -0
  144. package/lib/examples/CellSimpleExample.d.ts +0 -6
  145. package/lib/examples/CellSimpleExample.js +0 -20
  146. package/scripts/codegen/__pycache__/generate_sandbox_agents.cpython-313.pyc +0 -0
@@ -1,5 +1,5 @@
1
1
  /**
2
- * AgentSandboxExample
2
+ * AgentCodeSandboxExample
3
3
  *
4
4
  * Demonstrates sandbox variant switching (eval / jupyter) with a live
5
5
  * sidebar that streams WebSocket messages to and from the
@@ -10,8 +10,8 @@
10
10
  * - Sidebar shows live sandbox status, WebSocket event log, and an
11
11
  * interrupt button
12
12
  *
13
- * @module examples/AgentSandboxExample
13
+ * @module examples/AgentCodeSandboxExample
14
14
  */
15
15
  import React from 'react';
16
- declare const AgentSandboxExample: React.FC;
17
- export default AgentSandboxExample;
16
+ declare const AgentCodeSandboxExample: React.FC;
17
+ export default AgentCodeSandboxExample;
@@ -4,7 +4,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
4
4
  * Distributed under the terms of the Modified BSD License.
5
5
  */
6
6
  /**
7
- * AgentSandboxExample
7
+ * AgentCodeSandboxExample
8
8
  *
9
9
  * Demonstrates sandbox variant switching (eval / jupyter) with a live
10
10
  * sidebar that streams WebSocket messages to and from the
@@ -15,7 +15,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
15
15
  * - Sidebar shows live sandbox status, WebSocket event log, and an
16
16
  * interrupt button
17
17
  *
18
- * @module examples/AgentSandboxExample
18
+ * @module examples/AgentCodeSandboxExample
19
19
  */
20
20
  /// <reference types="vite/client" />
21
21
  import { useCallback, useEffect, useMemo, useRef, useState, } from 'react';
@@ -59,7 +59,7 @@ function apiVariantFromUi(variant) {
59
59
  return variant;
60
60
  }
61
61
  // ─── Inner component (after auth) ──────────────────────────────────────────
62
- const AgentSandboxInner = ({ onLogout, }) => {
62
+ const AgentCodeSandboxInner = ({ onLogout, }) => {
63
63
  const { token } = useSimpleAuthStore();
64
64
  const agentName = useRef(uniqueAgentId(AGENT_NAME)).current;
65
65
  const chatAuthToken = token === null ? undefined : token;
@@ -377,9 +377,10 @@ const AgentSandboxInner = ({ onLogout, }) => {
377
377
  display: 'flex',
378
378
  flexDirection: 'column',
379
379
  minHeight: 0,
380
- bg: 'canvas.subtle',
380
+ bg: 'canvas.default',
381
381
  }, children: [_jsxs(Box, { sx: {
382
382
  p: 2,
383
+ bg: 'canvas.default',
383
384
  borderBottom: '1px solid',
384
385
  borderColor: 'border.default',
385
386
  }, children: [_jsx(Heading, { as: "h4", sx: { fontSize: 1, mb: 1 }, children: "Sandbox Details" }), _jsxs(Box, { sx: {
@@ -441,7 +442,7 @@ const AgentSandboxInner = ({ onLogout, }) => {
441
442
  py: '2px',
442
443
  color: entry.direction === 'sent' ? 'accent.fg' : 'fg.default',
443
444
  bg: entry.direction === 'sent'
444
- ? 'accent.subtle'
445
+ ? 'neutral.muted'
445
446
  : 'transparent',
446
447
  borderBottom: '1px solid',
447
448
  borderColor: 'border.subtle',
@@ -463,7 +464,7 @@ const AgentSandboxInner = ({ onLogout, }) => {
463
464
  py: 1,
464
465
  borderBottom: '1px solid',
465
466
  borderColor: 'border.default',
466
- }, children: _jsx(Text, { sx: { color: 'fg.muted', fontSize: 0 }, children: "Agent already running \u2014 reconnected." }) })), _jsxs(Box, { sx: { flex: 1, minHeight: 0, display: 'flex' }, children: [_jsx(Box, { sx: { flex: 1, minWidth: 0 }, children: _jsxs(Box, { sx: { position: 'relative', height: '100%' }, children: [_jsx(Chat, { protocol: "vercel-ai", baseUrl: agentBaseUrl, agentId: agentId, authToken: chatAuthToken, title: "Sandbox Agent", brandIcon: _jsx(TerminalIcon, { size: 16 }), placeholder: "Ask the agent to write and run code\u2026", showHeader: true, showNewChatButton: true, showClearButton: true, showTokenUsage: true, autoFocus: true, height: "100%", runtimeId: agentId, historyEndpoint: `${agentBaseUrl}/api/v1/history`, headerActions: _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsxs(SegmentedControl, { "aria-label": "Sandbox variant", size: "small", onChange: index => {
467
+ }, children: _jsx(Text, { sx: { color: 'fg.muted', fontSize: 0 }, children: "Agent already running \u2014 reconnected." }) })), _jsxs(Box, { sx: { flex: 1, minHeight: 0, display: 'flex' }, children: [_jsx(Box, { sx: { flex: 1, minWidth: 0 }, children: _jsxs(Box, { sx: { position: 'relative', height: '100%' }, children: [_jsx(Chat, { protocol: "vercel-ai", baseUrl: agentBaseUrl, agentId: agentId, authToken: chatAuthToken, title: "Sandbox Agent", brandIcon: _jsx(TerminalIcon, { size: 16 }), placeholder: "Ask the agent to write and run code\u2026", showHeader: true, kernelIndicatorPlacement: "right", showNewChatButton: true, showClearButton: true, showTokenUsage: true, autoFocus: true, height: "100%", runtimeId: agentId, historyEndpoint: `${agentBaseUrl}/api/v1/history`, headerActions: _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsxs(SegmentedControl, { "aria-label": "Sandbox variant", size: "small", onChange: index => {
467
468
  if (isTransitionLocked)
468
469
  return;
469
470
  void switchVariant(index === 0 ? 'eval' : 'jupyter');
@@ -495,7 +496,7 @@ const syncTokenToIamStore = (newToken) => {
495
496
  iamStore.setState({ token: newToken });
496
497
  });
497
498
  };
498
- const AgentSandboxExample = () => {
499
+ const AgentCodeSandboxExample = () => {
499
500
  const { token, clearAuth } = useSimpleAuthStore();
500
501
  const hasSynced = useRef(false);
501
502
  useEffect(() => {
@@ -514,6 +515,6 @@ const AgentSandboxExample = () => {
514
515
  if (!token) {
515
516
  return (_jsx(ThemedProvider, { children: _jsx(AuthRequiredView, {}) }));
516
517
  }
517
- return (_jsx(QueryClientProvider, { client: queryClient, children: _jsx(ThemedProvider, { children: _jsx(AgentSandboxInner, { onLogout: handleLogout }) }) }));
518
+ return (_jsx(QueryClientProvider, { client: queryClient, children: _jsx(ThemedProvider, { children: _jsx(AgentCodeSandboxInner, { onLogout: handleLogout }) }) }));
518
519
  };
519
- export default AgentSandboxExample;
520
+ export default AgentCodeSandboxExample;
@@ -149,7 +149,7 @@ const AgentCodeSandboxesInner = ({ onLogout, }) => {
149
149
  display: 'flex',
150
150
  flexDirection: 'column',
151
151
  gap: 3,
152
- bg: 'canvas.subtle',
152
+ bg: 'canvas.default',
153
153
  }, children: [_jsx(Text, { sx: { fontSize: 0, fontWeight: 'bold', color: 'fg.muted' }, children: "SANDBOX VARIANT DEMO" }), _jsx(Heading, { as: "h2", sx: { fontSize: 3 }, children: "Agent Code Sandboxes" }), _jsx(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: "Choose a sandbox variant-backed spec, launch the agent, then run code from chat to compare behavior across sandboxes." }), _jsxs(Box, { sx: { display: 'flex', gap: 2, flexWrap: 'wrap' }, children: [_jsxs(Label, { variant: "accent", children: ["Spec: ", selectedOption.specId] }), _jsxs(Label, { variant: "secondary", children: ["Variant: ", selectedOption.variant] }), _jsx(Label, { variant: "success", children: "Codemode: enabled" })] }), _jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 2 }, children: [_jsx(Text, { sx: { fontSize: 1, fontWeight: 600 }, children: "Sandbox Variant" }), _jsx("select", { value: selectedSpecId, onChange: event => {
154
154
  setSelectedSpecId(event.target.value);
155
155
  }, style: {
@@ -164,7 +164,7 @@ const AgentCodeSandboxesInner = ({ onLogout, }) => {
164
164
  void launchAgent();
165
165
  }, disabled: isLaunching, sx: { width: '100%', maxWidth: 420 }, children: isLaunching ? (_jsxs(_Fragment, { children: [_jsx(Spinner, { size: "small" }), " Launching..."] })) : (`Launch ${selectedOption.title}`) }), error && _jsx(ErrorView, { error: error, onLogout: onLogout })] }));
166
166
  }
167
- return (_jsx(Chat, { protocol: "vercel-ai", baseUrl: baseUrl, agentId: agentId, runtimeId: agentId, title: `Code Sandboxes: ${activeOption.title}`, description: `Spec ${activeOption.specId} (${activeOption.variant})`, brandIcon: _jsx(PackageIcon, { size: 16 }), showHeader: true, showModelSelector: true, showToolsMenu: true, showSkillsMenu: true, showTokenUsage: true, showInformation: true, autoFocus: true, height: "100vh", historyEndpoint: `${baseUrl}/api/v1/history`, suggestions: [
167
+ return (_jsx(Chat, { protocol: "vercel-ai", baseUrl: baseUrl, agentId: agentId, runtimeId: agentId, title: `Code Sandboxes: ${activeOption.title}`, description: `Spec ${activeOption.specId} (${activeOption.variant})`, brandIcon: _jsx(PackageIcon, { size: 16 }), showHeader: true, kernelIndicatorPlacement: "right", showModelSelector: true, showToolsMenu: true, showSkillsMenu: true, showTokenUsage: true, showInformation: true, autoFocus: true, height: "100vh", historyEndpoint: `${baseUrl}/api/v1/history`, suggestions: [
168
168
  {
169
169
  title: 'Identify sandbox variant',
170
170
  message: 'Use execute_code to print(os.getenv("DATALAYER_CODE_SANDBOX_VARIANT")) and summarize the result.',
@@ -46,7 +46,7 @@ const DEMO_AGENT_CONFIGS = [
46
46
  subtitle: 'Raw MCP tools without codemode conversion',
47
47
  suggestionMessage: NO_CODEMODE_SUGGESTION_MESSAGE,
48
48
  specId: 'example-no-codemode',
49
- color: '#0969DA',
49
+ color: '#16A085',
50
50
  baseUrl: NO_CODEMODE_BASE_URL,
51
51
  },
52
52
  {
@@ -374,7 +374,7 @@ const AgentRuntimePane = ({ config, token, onTokenConsumed, onAgentIdChange, onC
374
374
  minHeight: 560,
375
375
  display: 'flex',
376
376
  flexDirection: 'column',
377
- }, children: _jsx(Box, { sx: { flex: 1, minHeight: 0 }, children: _jsx(Chat, { protocol: "vercel-ai", baseUrl: config.baseUrl, agentId: agentId, authToken: token, title: config.title, brandIcon: _jsx(CodeIcon, { size: 16 }), subtitle: config.subtitle, placeholder: "Ask both agents the same request to compare behavior...", description: config.subtitle, showHeader: true, headerActions: isReconnectedAgent ? (_jsx(Label, { size: "small", variant: "attention", children: "Reconnected" })) : undefined, autoFocus: false, height: "100%", runtimeId: agentId, historyEndpoint: `${config.baseUrl}/api/v1/history`, mcpStatusData: mcpStatusData, codemodeStatusData: codemodeStatusData, codemodeEnabled: codemodeEnabled, onToggleCodemode: handleToggleCodemode, suggestions: [
377
+ }, children: _jsx(Box, { sx: { flex: 1, minHeight: 0 }, children: _jsx(Chat, { protocol: "vercel-ai", baseUrl: config.baseUrl, agentId: agentId, authToken: token, title: config.title, brandIcon: _jsx(CodeIcon, { size: 16 }), subtitle: config.subtitle, placeholder: "Ask both agents the same request to compare behavior...", description: config.subtitle, showHeader: true, kernelIndicatorPlacement: "right", headerActions: isReconnectedAgent ? (_jsx(Label, { size: "small", variant: "attention", children: "Reconnected" })) : undefined, autoFocus: false, height: "100%", runtimeId: agentId, historyEndpoint: `${config.baseUrl}/api/v1/history`, mcpStatusData: mcpStatusData, codemodeStatusData: codemodeStatusData, codemodeEnabled: codemodeEnabled, onToggleCodemode: handleToggleCodemode, suggestions: [
378
378
  {
379
379
  title: 'Datalayer extraction',
380
380
  message: config.suggestionMessage,
@@ -436,7 +436,7 @@ const AgentCodemodeInner = ({ onLogout, }) => {
436
436
  emoji: '🤝',
437
437
  title: 'Tie',
438
438
  message: 'Both agents are tied on token usage.',
439
- bg: 'canvas.subtle',
439
+ bg: 'canvas.default',
440
440
  borderColor: 'border.default',
441
441
  color: 'fg.default',
442
442
  };
@@ -0,0 +1,12 @@
1
+ /**
2
+ * AgentCompactionExample
3
+ *
4
+ * Demonstrates history compaction. Before launching, the user picks a context
5
+ * token ceiling (capped at the agentspec model's tokens_limit). A lower ceiling
6
+ * makes the agent summarize older messages sooner. When compaction runs, a
7
+ * live panel shows a spinner and the details (from/to tokens, from/to messages,
8
+ * and time taken).
9
+ */
10
+ import React from 'react';
11
+ declare const AgentCompactionExample: React.FC;
12
+ export default AgentCompactionExample;
@@ -0,0 +1,244 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /*
3
+ * Copyright (c) 2025-2026 Datalayer, Inc.
4
+ * Distributed under the terms of the Modified BSD License.
5
+ */
6
+ /**
7
+ * AgentCompactionExample
8
+ *
9
+ * Demonstrates history compaction. Before launching, the user picks a context
10
+ * token ceiling (capped at the agentspec model's tokens_limit). A lower ceiling
11
+ * makes the agent summarize older messages sooner. When compaction runs, a
12
+ * live panel shows a spinner and the details (from/to tokens, from/to messages,
13
+ * and time taken).
14
+ */
15
+ /// <reference types="vite/client" />
16
+ import { useEffect, useState, useCallback, useRef } from 'react';
17
+ import { Text, Spinner, Heading, Label, Button, FormControl, } from '@primer/react';
18
+ import { HistoryIcon, ClockIcon, ArrowRightIcon, CheckCircleIcon, StackIcon, } from '@primer/octicons-react';
19
+ import { Box } from '@datalayer/primer-addons';
20
+ import { AuthRequiredView, ErrorView } from './components';
21
+ import { ThemedProvider } from './utils/themedProvider';
22
+ import { uniqueAgentId } from './utils/agentId';
23
+ import { useSimpleAuthStore } from '@datalayer/core/lib/views/otel';
24
+ import { Chat } from '../chat';
25
+ import { useAgentRuntimeCompaction, agentRuntimeStore } from '../stores';
26
+ import { getAgentspecs } from '../specs/agents';
27
+ import { AI_MODEL_CATALOGUE } from '../specs';
28
+ import { useExampleAgentRuntimesUrl } from './utils/useExampleAgentRuntimesUrl';
29
+ import { useRuntimeTargetStore } from './utils/runtimeTargetStore';
30
+ const AGENT_NAME = 'compaction-example-agent';
31
+ const AGENTSPEC_ID = 'example-monitoring';
32
+ const MIN_MAX_TOKENS = 1000;
33
+ const DEFAULT_MAX_TOKENS = 4000;
34
+ /** Resolve the agentspec model's token limit as the upper bound the user can set. */
35
+ function resolveAgentspecTokenLimit() {
36
+ const spec = getAgentspecs(AGENTSPEC_ID);
37
+ const model = spec?.model;
38
+ const limit = model ? AI_MODEL_CATALOGUE[model]?.tokensLimit : undefined;
39
+ return typeof limit === 'number' && limit > 0 ? limit : 64000;
40
+ }
41
+ const numberFmt = new Intl.NumberFormat();
42
+ /** Live compaction status: spinner while running, details when complete. */
43
+ const CompactionPanel = ({ maxTokens }) => {
44
+ const compaction = useAgentRuntimeCompaction();
45
+ return (_jsxs(Box, { sx: {
46
+ p: 3,
47
+ borderBottom: '1px solid',
48
+ borderColor: 'border.default',
49
+ }, children: [_jsx(Heading, { as: "h4", sx: { fontSize: 1, mb: 2 }, children: "Compaction" }), _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2, mb: 2 }, children: [_jsx(StackIcon, { size: 14 }), _jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: ["Budget: ", numberFmt.format(maxTokens), " tokens"] })] }), !compaction && (_jsx(Text, { as: "p", sx: { fontSize: 0, color: 'fg.muted', m: 0 }, children: "No compaction yet. Keep chatting \u2014 once the history exceeds the token budget, older messages are summarized automatically." })), compaction?.phase === 'start' && (_jsxs(Box, { sx: {
50
+ display: 'flex',
51
+ alignItems: 'center',
52
+ gap: 2,
53
+ p: 2,
54
+ border: '1px solid',
55
+ borderColor: 'attention.emphasis',
56
+ borderRadius: 2,
57
+ bg: 'attention.subtle',
58
+ }, children: [_jsx(Spinner, { size: "small" }), _jsxs(Box, { children: [_jsx(Text, { sx: { fontSize: 1, fontWeight: 'bold' }, children: "Compacting\u2026" }), _jsxs(Text, { as: "p", sx: { fontSize: 0, color: 'fg.muted', m: 0 }, children: ["Summarizing ", numberFmt.format(compaction.beforeMessages), " messages (~", numberFmt.format(compaction.beforeTokens), " tokens)"] })] })] })), compaction?.phase === 'end' && (_jsxs(Box, { sx: {
59
+ p: 2,
60
+ border: '1px solid',
61
+ borderColor: compaction.reduced
62
+ ? 'success.emphasis'
63
+ : 'border.default',
64
+ borderRadius: 2,
65
+ bg: compaction.reduced ? 'success.subtle' : 'canvas.subtle',
66
+ }, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2, mb: 2 }, children: [_jsx(CheckCircleIcon, { size: 14 }), _jsx(Text, { sx: { fontSize: 1, fontWeight: 'bold' }, children: compaction.reduced ? 'Compacted' : 'History already minimal' })] }), _jsxs(Box, { sx: {
67
+ display: 'flex',
68
+ flexDirection: 'column',
69
+ gap: 1,
70
+ fontSize: 0,
71
+ }, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 1 }, children: [_jsx(Text, { sx: { color: 'fg.muted', minWidth: 64 }, children: "Tokens" }), _jsx(Text, { sx: { fontFamily: 'mono' }, children: numberFmt.format(compaction.beforeTokens) }), _jsx(ArrowRightIcon, { size: 12 }), _jsx(Text, { sx: { fontFamily: 'mono' }, children: numberFmt.format(compaction.afterTokens ?? compaction.beforeTokens) })] }), _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 1 }, children: [_jsx(Text, { sx: { color: 'fg.muted', minWidth: 64 }, children: "Messages" }), _jsx(Text, { sx: { fontFamily: 'mono' }, children: numberFmt.format(compaction.beforeMessages) }), _jsx(ArrowRightIcon, { size: 12 }), _jsx(Text, { sx: { fontFamily: 'mono' }, children: numberFmt.format(compaction.afterMessages ?? compaction.beforeMessages) })] }), _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 1 }, children: [_jsx(ClockIcon, { size: 12 }), _jsx(Text, { sx: { color: 'fg.muted', minWidth: 52 }, children: "Time" }), _jsxs(Text, { sx: { fontFamily: 'mono' }, children: [numberFmt.format(Math.round(compaction.durationMs ?? 0)), " ms"] })] }), typeof compaction.compactionCount === 'number' && (_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 1 }, children: [_jsx(Text, { sx: { color: 'fg.muted', minWidth: 64 }, children: "Total runs" }), _jsx(Text, { sx: { fontFamily: 'mono' }, children: numberFmt.format(compaction.compactionCount) })] }))] })] }))] }));
72
+ };
73
+ const AgentCompactionInner = ({ onLogout, }) => {
74
+ const { token } = useSimpleAuthStore();
75
+ const runtimeTarget = useRuntimeTargetStore(state => state.target);
76
+ const agentName = useRef(uniqueAgentId(AGENT_NAME)).current;
77
+ const tokenLimit = useRef(resolveAgentspecTokenLimit()).current;
78
+ const [maxTokensInput, setMaxTokensInput] = useState(Math.min(DEFAULT_MAX_TOKENS, tokenLimit));
79
+ const [launchedMaxTokens, setLaunchedMaxTokens] = useState(null);
80
+ const [runtimeStatus, setRuntimeStatus] = useState('idle');
81
+ const [isReady, setIsReady] = useState(false);
82
+ const [hookError, setHookError] = useState(null);
83
+ const [agentId, setAgentId] = useState(agentName);
84
+ const [isReconnectedAgent, setIsReconnectedAgent] = useState(false);
85
+ const agentBaseUrl = useExampleAgentRuntimesUrl();
86
+ const chatAuthToken = token === null ? undefined : token;
87
+ const authFetch = useCallback((url, opts = {}) => fetch(url, {
88
+ ...opts,
89
+ headers: {
90
+ 'Content-Type': 'application/json',
91
+ ...(token ? { Authorization: `Bearer ${token}` } : {}),
92
+ ...(opts.headers ?? {}),
93
+ },
94
+ }), [token]);
95
+ useEffect(() => {
96
+ if (launchedMaxTokens === null)
97
+ return;
98
+ let isCancelled = false;
99
+ const createAgentForTarget = async () => {
100
+ setRuntimeStatus('launching');
101
+ setIsReady(false);
102
+ setHookError(null);
103
+ setIsReconnectedAgent(false);
104
+ // Clear any prior compaction status from a previous stream.
105
+ agentRuntimeStore.getState().setCompaction(null);
106
+ try {
107
+ const response = await authFetch(`${agentBaseUrl}/api/v1/agents`, {
108
+ method: 'POST',
109
+ body: JSON.stringify({
110
+ name: agentName,
111
+ description: 'Compaction example – history summarization under a token budget',
112
+ agent_library: 'pydantic-ai',
113
+ transport: 'vercel-ai',
114
+ agent_spec_id: AGENTSPEC_ID,
115
+ memory: 'ephemeral',
116
+ enable_skills: true,
117
+ tools: [],
118
+ compactionMaxTokens: launchedMaxTokens,
119
+ }),
120
+ });
121
+ let resolvedAgentId = agentName;
122
+ let isAlreadyRunning = false;
123
+ if (response.ok) {
124
+ const data = await response.json();
125
+ resolvedAgentId = data?.id || agentName;
126
+ }
127
+ else {
128
+ const contentType = response.headers.get('content-type') || '';
129
+ let detail = '';
130
+ if (contentType.includes('application/json')) {
131
+ const data = await response.json().catch(() => null);
132
+ detail =
133
+ (typeof data?.detail === 'string' && data.detail) ||
134
+ (typeof data?.message === 'string' && data.message) ||
135
+ '';
136
+ }
137
+ else {
138
+ detail = await response.text();
139
+ }
140
+ if (response.status === 409 || /already exists/i.test(detail || '')) {
141
+ isAlreadyRunning = true;
142
+ }
143
+ else {
144
+ throw new Error(detail || `Failed to create local agent: ${response.status}`);
145
+ }
146
+ }
147
+ if (!isCancelled) {
148
+ setAgentId(resolvedAgentId);
149
+ setIsReconnectedAgent(isAlreadyRunning);
150
+ setIsReady(true);
151
+ setRuntimeStatus('ready');
152
+ }
153
+ }
154
+ catch (error) {
155
+ if (!isCancelled) {
156
+ setHookError(error instanceof Error ? error.message : 'Agent failed to start');
157
+ setRuntimeStatus('error');
158
+ }
159
+ }
160
+ };
161
+ void createAgentForTarget();
162
+ return () => {
163
+ isCancelled = true;
164
+ };
165
+ }, [agentBaseUrl, authFetch, runtimeTarget, launchedMaxTokens, agentName]);
166
+ // Setup phase: choose the compaction token budget before launching.
167
+ if (launchedMaxTokens === null) {
168
+ return (_jsx(Box, { sx: {
169
+ display: 'flex',
170
+ alignItems: 'center',
171
+ justifyContent: 'center',
172
+ height: '100%',
173
+ bg: 'canvas.default',
174
+ }, children: _jsxs(Box, { sx: {
175
+ width: 460,
176
+ maxWidth: '90%',
177
+ p: 4,
178
+ border: '1px solid',
179
+ borderColor: 'border.default',
180
+ borderRadius: 2,
181
+ bg: 'canvas.subtle',
182
+ }, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2, mb: 2 }, children: [_jsx(HistoryIcon, { size: 20 }), _jsx(Heading, { as: "h3", sx: { fontSize: 3 }, children: "History Compaction" })] }), _jsx(Text, { as: "p", sx: { fontSize: 1, color: 'fg.muted', mt: 0, mb: 3 }, children: "Set the context token budget before launching. When the conversation grows past this budget, older messages are summarized so the input stays within the limit. A lower budget triggers compaction sooner." }), _jsxs(FormControl, { children: [_jsxs(FormControl.Label, { children: ["Max context tokens: ", numberFmt.format(maxTokensInput)] }), _jsx(Box, { sx: { mt: 2 }, children: _jsx("input", { type: "range", min: MIN_MAX_TOKENS, max: tokenLimit, step: 500, value: maxTokensInput, onChange: e => setMaxTokensInput(Number(e.target.value)), style: { width: '100%' } }) }), _jsxs(FormControl.Caption, { children: ["Agentspec max: ", numberFmt.format(tokenLimit), " tokens (model limit)"] })] }), _jsx(Box, { sx: { display: 'flex', justifyContent: 'flex-end', mt: 3 }, children: _jsx(Button, { variant: "primary", leadingVisual: HistoryIcon, onClick: () => setLaunchedMaxTokens(maxTokensInput), children: "Launch agent" }) })] }) }));
183
+ }
184
+ if (!isReady && runtimeStatus !== 'error') {
185
+ return (_jsxs(Box, { sx: {
186
+ display: 'flex',
187
+ flexDirection: 'column',
188
+ alignItems: 'center',
189
+ justifyContent: 'center',
190
+ height: '100%',
191
+ gap: 3,
192
+ bg: 'canvas.default',
193
+ }, children: [_jsx(Spinner, { size: "large" }), _jsxs(Text, { sx: { color: 'fg.muted' }, children: ["Launching compaction example agent (", runtimeTarget, ")..."] })] }));
194
+ }
195
+ if (runtimeStatus === 'error' || hookError) {
196
+ return _jsx(ErrorView, { error: hookError, onLogout: onLogout });
197
+ }
198
+ return (_jsxs(Box, { sx: {
199
+ height: '100%',
200
+ display: 'flex',
201
+ flexDirection: 'column',
202
+ bg: 'canvas.default',
203
+ }, children: [_jsxs(Box, { sx: {
204
+ display: 'flex',
205
+ alignItems: 'center',
206
+ gap: 2,
207
+ px: 3,
208
+ py: 2,
209
+ borderBottom: '1px solid',
210
+ borderColor: 'border.default',
211
+ flexShrink: 0,
212
+ }, children: [_jsx(HistoryIcon, { size: 16 }), _jsx(Heading, { as: "h3", sx: { fontSize: 2, flex: 1 }, children: "Compaction Demo" }), isReconnectedAgent && (_jsx(Label, { variant: "secondary", size: "small", children: "Reconnected" })), _jsx(Label, { variant: "accent", children: runtimeTarget }), _jsxs(Label, { variant: "accent", children: [numberFmt.format(launchedMaxTokens), " tok budget"] })] }), _jsxs(Box, { sx: { flex: 1, minHeight: 0, display: 'flex' }, children: [_jsx(Box, { sx: { flex: 1, minWidth: 0 }, children: _jsx(Chat, { protocol: "vercel-ai", baseUrl: agentBaseUrl, agentId: agentId, authToken: chatAuthToken, title: "Compaction Agent", brandIcon: _jsx(HistoryIcon, { size: 16 }), placeholder: "Chat until the history exceeds the token budget...", description: "History summarization under a token budget", showHeader: true, kernelIndicatorPlacement: "right", autoFocus: true, height: "100%", runtimeId: agentId, historyEndpoint: `${agentBaseUrl}/api/v1/history`, suggestions: [
213
+ {
214
+ title: 'Fill the context',
215
+ message: 'Write a detailed, multi-paragraph essay on the history of computing, covering hardware, software, and networking eras.',
216
+ },
217
+ {
218
+ title: 'Keep going',
219
+ message: 'Now expand each section with more detail and concrete examples, adding at least three paragraphs per era.',
220
+ },
221
+ {
222
+ title: 'Recall earlier',
223
+ message: 'Summarize everything we have discussed so far in this conversation.',
224
+ },
225
+ ], submitOnSuggestionClick: true }) }), _jsxs(Box, { sx: {
226
+ width: 320,
227
+ borderLeft: '1px solid',
228
+ borderColor: 'border.default',
229
+ display: 'flex',
230
+ flexDirection: 'column',
231
+ overflow: 'auto',
232
+ }, children: [_jsx(CompactionPanel, { maxTokens: launchedMaxTokens }), _jsxs(Box, { sx: { p: 3 }, children: [_jsx(Heading, { as: "h4", sx: { fontSize: 1, mb: 2 }, children: "How It Works" }), _jsxs(Text, { as: "p", sx: { fontSize: 0, color: 'fg.muted', mb: 2 }, children: ["Before each model request, the compaction capability estimates the history size. When it exceeds a fraction of the", ' ', numberFmt.format(launchedMaxTokens), "-token budget, older messages are replaced by an LLM-generated summary while recent messages are preserved."] }), _jsxs(Text, { as: "p", sx: { fontSize: 0, color: 'fg.muted', mb: 0 }, children: ["The budget is capped at the agentspec model's token limit (", numberFmt.format(tokenLimit), "). Lower it to trigger compaction with a shorter conversation."] })] })] })] })] }));
233
+ };
234
+ const AgentCompactionExample = () => {
235
+ const { token, clearAuth } = useSimpleAuthStore();
236
+ const handleLogout = useCallback(() => {
237
+ clearAuth();
238
+ }, [clearAuth]);
239
+ if (!token) {
240
+ return (_jsx(ThemedProvider, { children: _jsx(AuthRequiredView, {}) }));
241
+ }
242
+ return (_jsx(ThemedProvider, { children: _jsx(AgentCompactionInner, { onLogout: handleLogout }) }));
243
+ };
244
+ export default AgentCompactionExample;
@@ -17,24 +17,22 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
17
17
  /// <reference types="vite/client" />
18
18
  import { useEffect, useState, useCallback, useRef, useMemo, } from 'react';
19
19
  import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
20
- import { Text, Button, Spinner, Heading, Label, Flash, ProgressBar, Select, FormControl, } from '@primer/react';
20
+ import { Text, Button, Spinner, Heading, Label, Flash, ProgressBar, } from '@primer/react';
21
21
  import { BeakerIcon, CheckCircleIcon, XCircleIcon, PlayIcon, } from '@primer/octicons-react';
22
22
  import { Box } from '@datalayer/primer-addons';
23
23
  import { AuthRequiredView, ErrorView } from './components';
24
24
  import { ThemedProvider } from './utils/themedProvider';
25
25
  import { uniqueAgentId } from './utils/agentId';
26
- import { useExampleAgentRuntimesUrl } from './utils/useExampleAgentRuntimesUrl';
26
+ import { resolveExampleAgentRuntimesUrl, useExampleAgentRuntimesUrl, } from './utils/useExampleAgentRuntimesUrl';
27
+ import { useRuntimeTargetStore, } from './utils/runtimeTargetStore';
27
28
  import { useSimpleAuthStore } from '@datalayer/core/lib/views/otel';
28
29
  import { useCoreStore } from '@datalayer/core';
29
30
  import { Chat } from '../chat';
30
- import { useAgentRuntimes } from '../hooks/useAgentRuntimes';
31
+ import { useExampleAgentRuntimes as useAgentRuntimes } from './hooks/useExampleAgentRuntimes';
31
32
  const queryClient = new QueryClient();
32
33
  // ─── Constants ─────────────────────────────────────────────────────────────
33
34
  const AGENT_NAME = 'eval-example-agent';
34
35
  const AGENTSPEC_ID = 'example-evals';
35
- const DEFAULT_EXECUTION_TARGET = (import.meta.env.VITE_AGENT_EVALS_TARGET || 'cloud').toLowerCase() === 'local'
36
- ? 'local'
37
- : 'cloud';
38
36
  const normalizeHttpUrl = (value) => {
39
37
  if (typeof value !== 'string') {
40
38
  return null;
@@ -72,25 +70,17 @@ const isLocalhostUrl = (value) => {
72
70
  }
73
71
  };
74
72
  // ─── Inner component (rendered after auth) ─────────────────────────────────
75
- const AgentEvalsInner = ({ onLogout, executionTarget, onExecutionTargetChange }) => {
73
+ const AgentEvalsInner = ({ onLogout, executionTarget }) => {
76
74
  const { token } = useSimpleAuthStore();
77
75
  const { configuration } = useCoreStore();
78
76
  const agentName = useRef(uniqueAgentId(AGENT_NAME)).current;
79
77
  const localRuntimeBaseUrl = useExampleAgentRuntimesUrl();
80
78
  const cloudRuntimeBaseUrl = useMemo(() => {
81
- const envRuntimesUrl = normalizeHttpUrl(import.meta.env.VITE_DATALAYER_RUNTIMES_URL);
82
- const envAgentRuntimesUrl = normalizeHttpUrl(import.meta.env.VITE_DATALAYER_AGENT_RUNTIMES_URL);
83
79
  const configuredRuntimesUrl = normalizeHttpUrl(configuration?.runtimesUrl);
84
- if (envRuntimesUrl && !isLocalhostUrl(envRuntimesUrl)) {
85
- return envRuntimesUrl;
86
- }
87
80
  if (configuredRuntimesUrl && !isLocalhostUrl(configuredRuntimesUrl)) {
88
81
  return configuredRuntimesUrl;
89
82
  }
90
- if (envAgentRuntimesUrl && !isLocalhostUrl(envAgentRuntimesUrl)) {
91
- return envAgentRuntimesUrl;
92
- }
93
- return 'https://r1.datalayer.run';
83
+ return resolveExampleAgentRuntimesUrl('cloud');
94
84
  }, [configuration?.runtimesUrl]);
95
85
  const { runtime, status: runtimeStatus, isReady, error: hookError, runtimeCreationBaseUrl, } = useAgentRuntimes({
96
86
  agentSpecId: AGENTSPEC_ID,
@@ -420,9 +410,9 @@ const AgentEvalsInner = ({ onLogout, executionTarget, onExecutionTargetChange })
420
410
  overflow: 'hidden',
421
411
  textOverflow: 'ellipsis',
422
412
  whiteSpace: 'nowrap',
423
- }, children: ["Runtime API: ", runtimeCreationBaseUrl, "/api/runtimes/v1/runtimes"] })] }), _jsxs(FormControl, { sx: { minWidth: 160 }, children: [_jsx(FormControl.Label, { sx: { fontSize: 0, mb: 1 }, children: "Target" }), _jsxs(Select, { size: "small", value: executionTarget, onChange: e => onExecutionTargetChange(e.target.value), disabled: isRunning, children: [_jsx(Select.Option, { value: "cloud", children: "Cloud" }), _jsx(Select.Option, { value: "local", children: "Local" })] })] })] }), _jsxs(Box, { sx: { flex: 1, minHeight: 0, display: 'flex' }, children: [_jsx(Box, { sx: { flex: 1, minWidth: 0 }, children: _jsx(Chat, { protocol: "vercel-ai", baseUrl: agentBaseUrl, agentId: agentId, title: "Eval Agent", brandIcon: _jsx(BeakerIcon, { size: 16 }), placeholder: "Chat with the agent, then run evaluations\u2026", description: latestScore != null
413
+ }, children: ["Runtime API: ", runtimeCreationBaseUrl, "/api/runtimes/v1/runtimes"] })] }), _jsxs(Label, { size: "small", variant: "accent", children: ["Target: ", executionTarget === 'cloud' ? 'Cloud' : 'Local'] })] }), _jsxs(Box, { sx: { flex: 1, minHeight: 0, display: 'flex' }, children: [_jsx(Box, { sx: { flex: 1, minWidth: 0 }, children: _jsx(Chat, { protocol: "vercel-ai", baseUrl: agentBaseUrl, agentId: agentId, title: "Eval Agent", brandIcon: _jsx(BeakerIcon, { size: 16 }), placeholder: "Chat with the agent, then run evaluations\u2026", description: latestScore != null
424
414
  ? `Last score: ${(latestScore * 100).toFixed(0)}%`
425
- : 'No evaluations run yet', showHeader: true, autoFocus: true, height: "100%", runtimeId: podName, historyEndpoint: `${agentBaseUrl}/api/v1/history`, suggestions: [
415
+ : 'No evaluations run yet', showHeader: true, kernelIndicatorPlacement: "right", autoFocus: true, height: "100%", runtimeId: podName, historyEndpoint: `${agentBaseUrl}/api/v1/history`, suggestions: [
426
416
  {
427
417
  title: 'Summarize KPIs',
428
418
  message: 'Summarize the latest KPI data',
@@ -474,7 +464,7 @@ const syncTokenToIamStore = (token) => {
474
464
  const AgentEvalsExample = () => {
475
465
  const { token, clearAuth } = useSimpleAuthStore();
476
466
  const hasSynced = useRef(false);
477
- const [executionTarget, setExecutionTarget] = useState(DEFAULT_EXECUTION_TARGET);
467
+ const executionTarget = useRuntimeTargetStore(state => state.target);
478
468
  useEffect(() => {
479
469
  if (token && !hasSynced.current) {
480
470
  hasSynced.current = true;
@@ -491,6 +481,6 @@ const AgentEvalsExample = () => {
491
481
  if (!token) {
492
482
  return (_jsx(ThemedProvider, { children: _jsx(AuthRequiredView, {}) }));
493
483
  }
494
- return (_jsx(QueryClientProvider, { client: queryClient, children: _jsx(ThemedProvider, { children: _jsx(AgentEvalsInner, { onLogout: handleLogout, executionTarget: executionTarget, onExecutionTargetChange: setExecutionTarget }, executionTarget) }) }));
484
+ return (_jsx(QueryClientProvider, { client: queryClient, children: _jsx(ThemedProvider, { children: _jsx(AgentEvalsInner, { onLogout: handleLogout, executionTarget: executionTarget }, executionTarget) }) }));
495
485
  };
496
486
  export default AgentEvalsExample;
@@ -227,7 +227,7 @@ const AgentGuardrailsInner = ({ onLogout, }) => {
227
227
  configuration?.datalayerUrl ||
228
228
  OTEL_BASE_URL_ENV ||
229
229
  DATALAYER_URL_ENV ||
230
- 'https://prod1.datalayer.run';
230
+ agentBaseUrl;
231
231
  const podName = agentId;
232
232
  const chatAuthToken = token === null ? undefined : token;
233
233
  // Authenticated fetch helper (for sidecar endpoints)
@@ -487,7 +487,7 @@ const AgentGuardrailsInner = ({ onLogout, }) => {
487
487
  ? ` (over by $${overBudgetAmountUsd.toFixed(4)}).`
488
488
  : '.', ' ', "Start a new run or increase the run budget before continuing."] }) })), approvals.map(req => (_jsx(Flash, { variant: "warning", sx: { mx: 3, mt: 2 }, children: _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsxs(Text, { sx: { flex: 1, fontSize: 1 }, children: [_jsx("strong", { children: req.tool_name }), " requests approval", req.tool_args
489
489
  ? ` — ${JSON.stringify(req.tool_args).slice(0, 120)}`
490
- : ''] }), _jsx(Button, { size: "small", variant: "primary", leadingVisual: CheckIcon, onClick: () => handleApprove(req.id), disabled: approvalLoading === req.id, children: "Approve" }), _jsx(Button, { size: "small", variant: "danger", leadingVisual: XIcon, onClick: () => handleReject(req.id), disabled: approvalLoading === req.id, children: "Reject" })] }) }, req.id))), _jsx(Box, { sx: { flex: 1, minHeight: 0 }, children: _jsx(Chat, { protocol: "vercel-ai", baseUrl: agentBaseUrl, agentId: agentId, authToken: chatAuthToken, title: "Guardrails Agent", brandIcon: _jsx(ShieldCheckIcon, { size: 16 }), placeholder: "Ask something that triggers tools\u2026", description: "Cost guardrail with OTEL-backed gauge and hook-aware approvals (before_tool_execute, after_tool_execute, on_tool_execute_error, deferred_tool_calls)", showHeader: true, showTokenUsage: true, errorBanner: overBudgetBanner, disableInputPrompt: isOverRunBudget, autoFocus: true, height: "100%", runtimeId: agentId, historyEndpoint: `${agentBaseUrl}/api/v1/history`, suggestions: [
490
+ : ''] }), _jsx(Button, { size: "small", variant: "primary", leadingVisual: CheckIcon, onClick: () => handleApprove(req.id), disabled: approvalLoading === req.id, children: "Approve" }), _jsx(Button, { size: "small", variant: "danger", leadingVisual: XIcon, onClick: () => handleReject(req.id), disabled: approvalLoading === req.id, children: "Reject" })] }) }, req.id))), _jsx(Box, { sx: { flex: 1, minHeight: 0 }, children: _jsx(Chat, { protocol: "vercel-ai", baseUrl: agentBaseUrl, agentId: agentId, authToken: chatAuthToken, title: "Guardrails Agent", brandIcon: _jsx(ShieldCheckIcon, { size: 16 }), placeholder: "Ask something that triggers tools\u2026", description: "Cost guardrail with OTEL-backed gauge and hook-aware approvals (before_tool_execute, after_tool_execute, on_tool_execute_error, deferred_tool_calls)", showHeader: true, kernelIndicatorPlacement: "right", showTokenUsage: true, errorBanner: overBudgetBanner, disableInputPrompt: isOverRunBudget, autoFocus: true, height: "100%", runtimeId: agentId, historyEndpoint: `${agentBaseUrl}/api/v1/history`, suggestions: [
491
491
  { title: 'Update CRM', message: 'Update the CRM records for Q3' },
492
492
  {
493
493
  title: 'Trigger before_tool_execute',
@@ -43,7 +43,7 @@ const AgentHooksExample = () => {
43
43
  if (error || !agentId) {
44
44
  return (_jsx(ThemedProvider, { children: _jsx(ErrorView, { error: "Failed to start hooks agent", detail: error || 'No agent ID returned' }) }));
45
45
  }
46
- return (_jsx(Chat, { protocol: "vercel-ai", baseUrl: baseUrl, agentId: agentId, title: "Hooks Agent", brandIcon: _jsx(SyncIcon, { size: 16 }), placeholder: "Ask about lifecycle hooks...", description: "Demonstrates lifecycle hooks and pydantic-style tool hooks: before_tool_execute, after_tool_execute, on_tool_execute_error, deferred_tool_calls", showHeader: true, showModelSelector: true, showToolsMenu: true, showSkillsMenu: true, showTokenUsage: true, showInformation: true, autoFocus: true, height: "100vh", runtimeId: agentId, historyEndpoint: `${baseUrl}/api/v1/history`, suggestions: [
46
+ return (_jsx(Chat, { protocol: "vercel-ai", baseUrl: baseUrl, agentId: agentId, title: "Hooks Agent", brandIcon: _jsx(SyncIcon, { size: 16 }), placeholder: "Ask about lifecycle hooks...", description: "Demonstrates lifecycle hooks and pydantic-style tool hooks: before_tool_execute, after_tool_execute, on_tool_execute_error, deferred_tool_calls", showHeader: true, kernelIndicatorPlacement: "right", showModelSelector: true, showToolsMenu: true, showSkillsMenu: true, showTokenUsage: true, showInformation: true, autoFocus: true, height: "100vh", runtimeId: agentId, historyEndpoint: `${baseUrl}/api/v1/history`, suggestions: [
47
47
  {
48
48
  title: 'Read the pre-hook marker file',
49
49
  message: 'Use execute_code to read /tmp/agent_runtimes_pre_hook_demo.txt and show its contents.',
@@ -37,7 +37,7 @@ const ProviderBadge = ({ provider, }) => (_jsx(Box, { sx: {
37
37
  borderColor: 'border.default',
38
38
  fontSize: 0,
39
39
  color: 'fg.muted',
40
- bg: 'canvas.inset',
40
+ bg: 'canvas.default',
41
41
  textTransform: 'uppercase',
42
42
  letterSpacing: '0.03em',
43
43
  }, children: provider }));
@@ -57,10 +57,8 @@ const AgentInferenceProviderExampleInner = () => {
57
57
  return 'local inference';
58
58
  }
59
59
  const env = import.meta.env ?? {};
60
- return (env.VITE_DATALAYER_AI_INFERENCE_URL ||
61
- env.VITE_DATALAYER_URL ||
62
- 'https://prod1.datalayer.run');
63
- }, [provider]);
60
+ return (env.VITE_DATALAYER_AI_INFERENCE_URL || env.VITE_DATALAYER_URL || baseUrl);
61
+ }, [provider, baseUrl]);
64
62
  const authFetch = useCallback((url, init = {}) => {
65
63
  return fetch(url, {
66
64
  ...init,
@@ -248,7 +246,7 @@ const AgentInferenceProviderExampleInner = () => {
248
246
  borderRadius: 2,
249
247
  overflow: 'hidden',
250
248
  bg: 'canvas.default',
251
- }, children: agentId && !isLaunching ? (_jsx(Chat, { protocol: "vercel-ai", baseUrl: baseUrl, agentId: agentId, authToken: token ?? undefined, title: "Agent Inference Provider Example", subtitle: `Spec: ${AGENTSPEC_ID}`, placeholder: "Ask the inference provider something...", showHeader: true, showNewChatButton: true, showClearButton: true, showModelSelector: true, showToolsMenu: true, showSkillsMenu: true, showTokenUsage: true, autoFocus: true, height: "100%", runtimeId: agentId, historyEndpoint: `${baseUrl}/api/v1/history`, onMessageSent: content => {
249
+ }, children: agentId && !isLaunching ? (_jsx(Chat, { protocol: "vercel-ai", baseUrl: baseUrl, agentId: agentId, authToken: token ?? undefined, title: "Agent Inference Provider Example", subtitle: `Spec: ${AGENTSPEC_ID}`, placeholder: "Ask the inference provider something...", showHeader: true, kernelIndicatorPlacement: "right", showNewChatButton: true, showClearButton: true, showModelSelector: true, showToolsMenu: true, showSkillsMenu: true, showTokenUsage: true, autoFocus: true, height: "100%", runtimeId: agentId, historyEndpoint: `${baseUrl}/api/v1/history`, onMessageSent: content => {
252
250
  appendProviderEvent('provider.request', `Sent message via ${provider}`, {
253
251
  provider,
254
252
  agentId,
@@ -275,7 +273,7 @@ const AgentInferenceProviderExampleInner = () => {
275
273
  gap: 2,
276
274
  minHeight: 0,
277
275
  overflow: 'hidden',
278
- bg: 'canvas.inset',
276
+ bg: 'canvas.default',
279
277
  }, children: [_jsx(Heading, { as: "h3", sx: { fontSize: 2 }, children: "Provider Event Stream" }), _jsx(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: "Low-level request/response events exchanged with the inference provider (newest first)." }), _jsx(Box, { sx: {
280
278
  flex: 1,
281
279
  minHeight: 0,
@@ -317,7 +315,7 @@ const AgentInferenceProviderExampleInner = () => {
317
315
  mb: 0,
318
316
  p: 2,
319
317
  borderRadius: 2,
320
- bg: 'canvas.subtle',
318
+ bg: 'canvas.default',
321
319
  fontSize: 0,
322
320
  whiteSpace: 'pre-wrap',
323
321
  fontFamily: 'mono',
@@ -135,8 +135,8 @@ function LoopSummary({ loop }) {
135
135
  px: 2,
136
136
  py: '2px',
137
137
  borderRadius: 6,
138
- bg: 'accent.subtle',
139
- color: 'accent.fg',
138
+ bg: 'neutral.muted',
139
+ color: 'fg.default',
140
140
  fontWeight: 'bold',
141
141
  }, children: [index + 1, ". ", phase] }, phase))) }), loop.objective && (_jsxs(Box, { sx: { color: 'fg.muted' }, children: [_jsx("strong", { children: "Objective:" }), " ", loop.objective] })), loop.termination && (_jsxs(Box, { sx: { color: 'fg.muted', mt: 1 }, children: [_jsx("strong", { children: "Max iterations:" }), " ", loop.termination.maxIterations, " \u00B7", ' ', _jsx("strong", { children: "On blocked:" }), " ", loop.termination.onBlocked] }))] }));
142
142
  }
@@ -241,7 +241,7 @@ export function AgentLoopExampleInner({ serviceManager, }) {
241
241
  p: 3,
242
242
  borderBottom: '1px solid',
243
243
  borderColor: 'border.default',
244
- bg: 'canvas.subtle',
244
+ bg: 'canvas.default',
245
245
  }, children: [_jsxs(Box, { sx: {
246
246
  display: 'flex',
247
247
  alignItems: 'center',