@datalayer/agent-runtimes 1.0.19 → 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 (141) hide show
  1. package/README.md +11 -3
  2. package/lib/AgentNode.js +141 -40
  3. package/lib/App.js +2 -2
  4. package/lib/agent-node/AgentNodeGallery.js +188 -25
  5. package/lib/api/runtimes/runtimes.d.ts +57 -0
  6. package/lib/api/runtimes/runtimes.js +55 -1
  7. package/lib/chat/Chat.d.ts +1 -1
  8. package/lib/chat/Chat.js +2 -2
  9. package/lib/chat/base/ChatBase.js +50 -13
  10. package/lib/chat/document/EphemeralDocument.d.ts +5 -1
  11. package/lib/chat/document/EphemeralDocument.js +7 -5
  12. package/lib/chat/header/ChatHeaderBase.d.ts +3 -1
  13. package/lib/chat/header/ChatHeaderBase.js +5 -3
  14. package/lib/chat/messages/ChatMessageList.d.ts +19 -0
  15. package/lib/chat/messages/ChatMessageList.js +180 -9
  16. package/lib/chat/notebook/EphemeralNotebook.d.ts +5 -1
  17. package/lib/chat/notebook/EphemeralNotebook.js +9 -6
  18. package/lib/chat/prompt/InputPrompt.js +1 -1
  19. package/lib/chat/tools/SubagentActivity.d.ts +20 -0
  20. package/lib/chat/tools/SubagentActivity.js +154 -0
  21. package/lib/chat/tools/index.d.ts +1 -0
  22. package/lib/chat/tools/index.js +1 -0
  23. package/lib/chat/usage/TokenUsageBar.js +3 -3
  24. package/lib/client/AgentRuntimesClient.d.ts +5 -0
  25. package/lib/client/AgentsMixin.js +3 -1
  26. package/lib/client/mixins/RuntimesMixin.d.ts +12 -0
  27. package/lib/client/mixins/RuntimesMixin.js +24 -1
  28. package/lib/components/AgentSummary.d.ts +1 -0
  29. package/lib/components/AgentSummary.js +66 -10
  30. package/lib/components/runtimes/RuntimePickerBase.js +64 -29
  31. package/lib/components/runtimes/RuntimePickerCell.js +1 -1
  32. package/lib/components/runtimes/RuntimePickerNotebook.js +1 -1
  33. package/lib/components/runtimes/RuntimeSimplePicker.js +3 -2
  34. package/lib/components/runtimes/RuntimeUtils.js +2 -2
  35. package/lib/context/GraphFlowChart.js +1 -1
  36. package/lib/context/TokenUsageChart.js +1 -1
  37. package/lib/context/TurnGraphChart.js +2 -2
  38. package/lib/examples/A2UiAgentExample.js +4 -4
  39. package/lib/examples/A2UiComponentsGalleryExample.js +3 -3
  40. package/lib/examples/A2UiContactCardExample.js +3 -3
  41. package/lib/examples/A2UiRestaurantExample.js +2 -2
  42. package/lib/examples/A2UiViewerExample.js +3 -3
  43. package/lib/examples/AgUiAgenticExample.js +3 -3
  44. package/lib/examples/AgUiBackendToolRenderingExample.js +2 -2
  45. package/lib/examples/AgUiHaikuGenUiExample.js +3 -3
  46. package/lib/examples/AgUiHumanInTheLoopExample.js +5 -5
  47. package/lib/examples/AgUiSharedStateExample.js +3 -3
  48. package/lib/examples/AgUiToolsBasedGenUiExample.js +7 -5
  49. package/lib/examples/AgentCheckpointsExample.js +6 -5
  50. package/lib/examples/{AgentSandboxExample.d.ts → AgentCodeSandboxExample.d.ts} +4 -4
  51. package/lib/examples/{AgentSandboxExample.js → AgentCodeSandboxExample.js} +10 -9
  52. package/lib/examples/AgentCodeSandboxesExample.js +2 -2
  53. package/lib/examples/AgentCodemodeExample.js +3 -3
  54. package/lib/examples/AgentCompactionExample.d.ts +12 -0
  55. package/lib/examples/AgentCompactionExample.js +244 -0
  56. package/lib/examples/AgentEvalsExample.js +10 -20
  57. package/lib/examples/AgentGuardrailsExample.js +2 -2
  58. package/lib/examples/AgentHooksExample.js +1 -1
  59. package/lib/examples/AgentInferenceProviderExample.js +6 -8
  60. package/lib/examples/AgentLoopExample.js +3 -3
  61. package/lib/examples/AgentMCPExample.js +3 -3
  62. package/lib/examples/AgentMemoryExample.d.ts +4 -2
  63. package/lib/examples/AgentMemoryExample.js +93 -10
  64. package/lib/examples/AgentMonitoringExample.js +2 -2
  65. package/lib/examples/AgentNotificationsExample.js +1 -1
  66. package/lib/examples/AgentOtelExample.d.ts +2 -3
  67. package/lib/examples/AgentOtelExample.js +7 -12
  68. package/lib/examples/AgentOutputsExample.js +5 -5
  69. package/lib/examples/AgentParametersExample.js +3 -3
  70. package/lib/examples/AgentSkillsExample.js +4 -4
  71. package/lib/examples/AgentSubagentsExample.d.ts +2 -2
  72. package/lib/examples/AgentSubagentsExample.js +43 -34
  73. package/lib/examples/AgentToolApprovalsExample.js +1 -1
  74. package/lib/examples/AgentTriggersExample.js +9 -11
  75. package/lib/examples/AgentspecsExample.js +13 -5
  76. package/lib/examples/CellExample.d.ts +6 -0
  77. package/lib/examples/CellExample.js +84 -0
  78. package/lib/examples/ChatCustomExample.js +1 -1
  79. package/lib/examples/ChatExample.js +1 -1
  80. package/lib/examples/ChatStandaloneExample.js +2 -2
  81. package/lib/examples/HomeExample.js +29 -28
  82. package/lib/examples/Lexical2Example.js +2 -2
  83. package/lib/examples/LexicalAgentExample.js +1 -1
  84. package/lib/examples/LexicalAgentSidebarExample.js +2 -2
  85. package/lib/examples/NotebookAgentSidebarExample.d.ts +1 -1
  86. package/lib/examples/NotebookAgentSidebarExample.js +5 -4
  87. package/lib/examples/NotebookCollaborationExample.js +3 -3
  88. package/lib/examples/NotebookExample.js +2 -2
  89. package/lib/examples/components/ExampleWrapper.js +5 -0
  90. package/lib/examples/components/Header.js +2 -2
  91. package/lib/examples/components/HeaderControls.js +1 -1
  92. package/lib/examples/components/LexicalEditor.js +1 -1
  93. package/lib/examples/components/MainContent.js +1 -1
  94. package/lib/examples/components/MockFileBrowser.js +8 -8
  95. package/lib/examples/components/TimeTravel.js +1 -1
  96. package/lib/examples/components/haiku/HaikuDisplay.js +2 -2
  97. package/lib/examples/example-selector.js +4 -3
  98. package/lib/examples/hooks/useExampleAgentRuntime.js +11 -1
  99. package/lib/examples/hooks/useExampleAgentRuntimes.d.ts +7 -0
  100. package/lib/examples/hooks/useExampleAgentRuntimes.js +82 -0
  101. package/lib/examples/index.d.ts +2 -1
  102. package/lib/examples/index.js +2 -1
  103. package/lib/examples/main.js +359 -46
  104. package/lib/examples/utils/agentSummaryStore.d.ts +17 -0
  105. package/lib/examples/utils/themedProvider.js +32 -2
  106. package/lib/examples/utils/useExampleAgentRuntimesUrl.js +2 -1
  107. package/lib/examples2/NotebookMutationsKernel.js +6 -3
  108. package/lib/examples2/NotebookMutationsServiceManager.js +6 -3
  109. package/lib/examples2/ReactRouterExample.js +5 -5
  110. package/lib/examples2/main.js +38 -0
  111. package/lib/hooks/useAIAgentsWebSocket.js +35 -0
  112. package/lib/hooks/useAgentRuntimes.d.ts +22 -0
  113. package/lib/hooks/useAgentRuntimes.js +192 -5
  114. package/lib/hooks/useCheckpoints.js +2 -2
  115. package/lib/hooks/useToolApprovals.d.ts +10 -4
  116. package/lib/hooks/useToolApprovals.js +11 -5
  117. package/lib/models/Runtime.d.ts +10 -8
  118. package/lib/models/RuntimeDTO.d.ts +5 -3
  119. package/lib/models/RuntimeDTO.js +3 -3
  120. package/lib/runtimes/actions.js +3 -1
  121. package/lib/runtimes/apis.d.ts +7 -0
  122. package/lib/specs/agents/agents.d.ts +51 -0
  123. package/lib/specs/agents/agents.js +3389 -94
  124. package/lib/specs/models.d.ts +2 -0
  125. package/lib/specs/models.js +37 -0
  126. package/lib/stores/agentRuntimeStore.d.ts +32 -1
  127. package/lib/stores/agentRuntimeStore.js +65 -1
  128. package/lib/stores/index.d.ts +1 -1
  129. package/lib/stores/index.js +1 -1
  130. package/lib/types/agents.d.ts +9 -3
  131. package/lib/types/agentspecs.d.ts +2 -0
  132. package/lib/types/chat.d.ts +12 -0
  133. package/lib/types/models.d.ts +5 -0
  134. package/lib/types/stream.d.ts +58 -1
  135. package/package.json +4 -4
  136. package/scripts/codegen/__pycache__/versioning.cpython-313.pyc +0 -0
  137. package/scripts/codegen/generate_agents.py +7 -0
  138. package/scripts/codegen/generate_models.py +22 -9
  139. package/scripts/gen_workers.py +340 -0
  140. package/lib/examples/CellSimpleExample.d.ts +0 -6
  141. package/lib/examples/CellSimpleExample.js +0 -20
@@ -3,16 +3,15 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
3
3
  * Copyright (c) 2025-2026 Datalayer, Inc.
4
4
  * Distributed under the terms of the Modified BSD License.
5
5
  */
6
- import { createDatalayerServiceManager } from '../services/DatalayerServiceManager';
7
6
  /// <reference types="vite/client" />
8
7
  import { useCallback, useEffect, useMemo, useState } from 'react';
9
8
  import { createRoot } from 'react-dom/client';
10
9
  import { loadJupyterConfig, JupyterReactTheme, createServerSettings, setJupyterServerUrl, setJupyterServerToken, getJupyterServerUrl, getJupyterServerToken, } from '@datalayer/jupyter-react';
11
10
  import { ServiceManager } from '@jupyterlab/services';
12
- import { DatalayerThemeProvider, DatalayerLogoText, getLogoColors, themeConfigs, Box, } from '@datalayer/primer-addons';
11
+ import { DatalayerThemeProvider, DatalayerLogoText, getLogoColors, themeConfigs, Box, SlidingPanel, } from '@datalayer/primer-addons';
13
12
  import { AgentSummary } from '../components';
14
13
  import { HomeIcon, SignInIcon, SignOutIcon } from '@primer/octicons-react';
15
- import { Button, Spinner, Text } from '@primer/react';
14
+ import { Button, SegmentedControl, Spinner, Text } from '@primer/react';
16
15
  import { AppearanceControlsWithStore } from '@datalayer/primer-addons/lib/components/appearance';
17
16
  import { coreStore, iamStore } from '@datalayer/core';
18
17
  import { DATALAYER_IAM_TOKEN_KEY, DATALAYER_IAM_USER_KEY, } from '../state/substates';
@@ -29,9 +28,90 @@ import { useAgentSummaryStore } from './utils/agentSummaryStore';
29
28
  import { useExampleThemeStore } from './utils/themeStore';
30
29
  import { ExampleWrapper } from './components/ExampleWrapper';
31
30
  import { ExampleErrorBoundary } from './components/ExampleErrorBoundary';
31
+ import { createServiceManagerFromAgentSandbox } from '../hooks/useAgentRuntimes';
32
+ import { DEFAULT_MODEL } from '../specs/models';
32
33
  import nbformatExample from './utils/notebooks/NotebookExample1.ipynb.json';
33
34
  import '../../style/primer-primitives.css';
34
35
  const DEFAULT_RUNTIMES_URL = 'https://r1.datalayer.run';
36
+ const DEFAULT_LOCAL_JUPYTER_SERVER_URL = 'http://localhost:8888/api/jupyter-server';
37
+ const DEFAULT_LOCAL_JUPYTER_SERVER_TOKEN = '60c1661cc408f978c309d04157af55c9588ff9557c9380e4fb50785750703da6';
38
+ const DEFAULT_CLOUD_RUNTIME_ENVIRONMENT = 'ai-agents-env';
39
+ const isNotebookOrCellExample = (exampleId) => {
40
+ return ((exampleId.includes('Notebook') || exampleId.includes('Cell')) &&
41
+ !exampleId.includes('Agent'));
42
+ };
43
+ const wait = (ms) => new Promise(resolve => {
44
+ window.setTimeout(resolve, ms);
45
+ });
46
+ const safeExampleId = (value) => {
47
+ return value
48
+ .toLowerCase()
49
+ .replace(/[^a-z0-9-]+/g, '-')
50
+ .replace(/^-+|-+$/g, '')
51
+ .slice(0, 40);
52
+ };
53
+ const toAgentApiBaseUrl = (ingress) => {
54
+ const normalized = ingress.replace(/\/$/, '');
55
+ if (normalized.includes('/api/agent-runtimes')) {
56
+ return normalized;
57
+ }
58
+ if (normalized.includes('/api/jupyter-server')) {
59
+ return normalized.replace('/api/jupyter-server', '/api/agent-runtimes');
60
+ }
61
+ if (normalized.includes('/jupyter/server/')) {
62
+ return normalized.replace('/jupyter/server/', '/agent-runtimes/');
63
+ }
64
+ if (normalized.includes('/jupyter-server/')) {
65
+ return normalized.replace('/jupyter-server/', '/agent-runtimes/');
66
+ }
67
+ return normalized.replace('/jupyter/', '/agent-runtimes/');
68
+ };
69
+ const toSurfaceLabel = (exampleId) => {
70
+ if (exampleId.toLowerCase().includes('cell')) {
71
+ return 'cell';
72
+ }
73
+ return 'notebook';
74
+ };
75
+ const normalizeSandboxBaseUrl = (sandboxBaseUrl, agentBaseUrl) => {
76
+ const sandboxRaw = String(sandboxBaseUrl || '').trim();
77
+ const agentRaw = String(agentBaseUrl || '').trim();
78
+ if (!sandboxRaw) {
79
+ return agentRaw;
80
+ }
81
+ try {
82
+ const sandboxUrl = new URL(sandboxRaw);
83
+ const host = sandboxUrl.hostname;
84
+ const isInternalHost = host === '0.0.0.0' || host === '127.0.0.1' || host === 'localhost';
85
+ if (!isInternalHost) {
86
+ return sandboxRaw;
87
+ }
88
+ const agentUrl = new URL(agentRaw);
89
+ sandboxUrl.protocol = agentUrl.protocol;
90
+ sandboxUrl.host = agentUrl.host;
91
+ return sandboxUrl.toString();
92
+ }
93
+ catch {
94
+ return sandboxRaw;
95
+ }
96
+ };
97
+ const withTokenQueryParam = (rawUrl, token) => {
98
+ const normalizedUrl = String(rawUrl || '').trim();
99
+ const normalizedToken = String(token || '').trim();
100
+ if (!normalizedUrl || !normalizedToken) {
101
+ return normalizedUrl;
102
+ }
103
+ try {
104
+ const parsed = new URL(normalizedUrl);
105
+ if (!parsed.searchParams.get('token') &&
106
+ !parsed.searchParams.get('jupyter_token')) {
107
+ parsed.searchParams.set('token', normalizedToken);
108
+ }
109
+ return parsed.toString();
110
+ }
111
+ catch {
112
+ return normalizedUrl;
113
+ }
114
+ };
35
115
  const resolveRuntimesUrl = (configured) => {
36
116
  const envRuntimeUrl = import.meta.env.VITE_DATALAYER_RUNTIMES_URL;
37
117
  const envBaseUrl = import.meta.env.VITE_DATALAYER_URL;
@@ -54,6 +134,50 @@ const toAgentRuntimesBaseUrl = (value) => {
54
134
  }
55
135
  return normalized;
56
136
  };
137
+ const isProd1JupyterServerUrl = (value) => {
138
+ if (!value) {
139
+ return false;
140
+ }
141
+ try {
142
+ return new URL(value).hostname === 'prod1.datalayer.run';
143
+ }
144
+ catch {
145
+ return value.includes('prod1.datalayer.run');
146
+ }
147
+ };
148
+ const resolveLocalJupyterServerUrl = () => {
149
+ const normalizeLoopbackHost = (raw) => {
150
+ const trimmed = raw.trim().replace(/\/$/, '');
151
+ if (!trimmed) {
152
+ return DEFAULT_LOCAL_JUPYTER_SERVER_URL;
153
+ }
154
+ try {
155
+ const parsed = new URL(trimmed);
156
+ if (parsed.hostname === '0.0.0.0') {
157
+ parsed.hostname = 'localhost';
158
+ }
159
+ return parsed.toString().replace(/\/$/, '');
160
+ }
161
+ catch {
162
+ return trimmed.replace('://0.0.0.0', '://localhost');
163
+ }
164
+ };
165
+ const envLocalUrl = import.meta.env.VITE_JUPYTER_SERVER_URL?.trim();
166
+ if (envLocalUrl) {
167
+ return normalizeLoopbackHost(envLocalUrl);
168
+ }
169
+ const configured = getJupyterServerUrl();
170
+ if (configured && !isProd1JupyterServerUrl(configured)) {
171
+ return normalizeLoopbackHost(configured);
172
+ }
173
+ return normalizeLoopbackHost(DEFAULT_LOCAL_JUPYTER_SERVER_URL);
174
+ };
175
+ const ensureLocalJupyterToken = () => {
176
+ const token = (getJupyterServerToken() || '').trim();
177
+ if (!token) {
178
+ setJupyterServerToken(DEFAULT_LOCAL_JUPYTER_SERVER_TOKEN);
179
+ }
180
+ };
57
181
  // Load configurations from DOM
58
182
  const loadConfigurations = () => {
59
183
  // Load Datalayer configuration
@@ -360,12 +484,19 @@ const NotebookOnlyApp = () => {
360
484
  if (runtimeTargetStore.getState().target === 'cloud' &&
361
485
  configuration?.token) {
362
486
  try {
363
- const manager = await createDatalayerServiceManager(configuration.cpuEnvironment || 'python-3.11', configuration.credits || 100);
364
- await manager.ready;
487
+ const activeSummary = agentSummaryStore.getState().active;
488
+ if (!activeSummary || activeSummary.location !== 'cloud') {
489
+ throw new Error('No active cloud agent sandbox found for notebook-only mode.');
490
+ }
491
+ const manager = await createServiceManagerFromAgentSandbox({
492
+ baseUrl: activeSummary.sandboxBaseUrl || activeSummary.baseUrl,
493
+ agentId: activeSummary.agentId,
494
+ agentBaseUrl: activeSummary.baseUrl,
495
+ }, configuration.token);
365
496
  setServiceManager(manager);
366
497
  }
367
498
  catch (error) {
368
- console.error('Failed to create DatalayerServiceManager:', error);
499
+ console.error('Failed to connect to cloud sandbox:', error);
369
500
  const serverSettings = createServerSettings(getJupyterServerUrl(), getJupyterServerToken());
370
501
  const manager = new ServiceManager({ serverSettings });
371
502
  await manager.ready;
@@ -373,6 +504,8 @@ const NotebookOnlyApp = () => {
373
504
  }
374
505
  }
375
506
  else {
507
+ setJupyterServerUrl(resolveLocalJupyterServerUrl());
508
+ ensureLocalJupyterToken();
376
509
  const serverSettings = createServerSettings(getJupyterServerUrl(), getJupyterServerToken());
377
510
  const manager = new ServiceManager({ serverSettings });
378
511
  await manager.ready;
@@ -415,8 +548,18 @@ export const ExampleApp = () => {
415
548
  const [selectedExample, setSelectedExample] = useState(getDefaultExampleName());
416
549
  const [searchQuery, setSearchQuery] = useState(getInitialSearchQuery());
417
550
  const [isChangingExample, setIsChangingExample] = useState(false);
551
+ const [topNotice, setTopNotice] = useState(null);
418
552
  const runtimeTarget = useRuntimeTargetStore(state => state.target);
419
553
  const setRuntimeTarget = useRuntimeTargetStore(state => state.setTarget);
554
+ const showTopNotice = useCallback((message, tone = 'info', durationMs = 4500, details) => {
555
+ setTopNotice({
556
+ id: Date.now() + Math.floor(Math.random() * 1000),
557
+ message,
558
+ details,
559
+ tone,
560
+ durationMs,
561
+ });
562
+ }, []);
420
563
  const filteredExampleEntries = useMemo(() => {
421
564
  const normalized = searchQuery.trim().toLowerCase();
422
565
  const all = getExampleEntriesList();
@@ -449,11 +592,14 @@ export const ExampleApp = () => {
449
592
  }
450
593
  catch (e) {
451
594
  console.error('Failed to load example:', e);
595
+ showTopNotice(`Failed to load example: ${e instanceof Error ? e.message : String(e)}`, 'error', 6000);
452
596
  setError(`Failed to load example: ${e}`);
453
597
  setIsChangingExample(false);
454
598
  }
455
599
  };
456
600
  const createLocalServiceManager = async () => {
601
+ setJupyterServerUrl(resolveLocalJupyterServerUrl());
602
+ ensureLocalJupyterToken();
457
603
  const serverSettings = createServerSettings(getJupyterServerUrl(), getJupyterServerToken());
458
604
  const manager = new ServiceManager({ serverSettings });
459
605
  await manager.ready;
@@ -464,16 +610,182 @@ export const ExampleApp = () => {
464
610
  if (!configuration?.token) {
465
611
  throw new Error('Cloud runtime requires authentication. Please sign in.');
466
612
  }
613
+ const connectFromSummary = async (summary) => {
614
+ const connectOnce = async (candidate) => {
615
+ const resolvedSandboxBaseUrl = normalizeSandboxBaseUrl(candidate.sandboxBaseUrl, candidate.baseUrl);
616
+ const manager = await createServiceManagerFromAgentSandbox({
617
+ baseUrl: resolvedSandboxBaseUrl,
618
+ agentId: candidate.agentId,
619
+ agentBaseUrl: candidate.baseUrl,
620
+ runtimeEnvironment: candidate.runtimeEnvironment,
621
+ }, configuration.token);
622
+ const cloudBaseUrl = String(manager.serverSettings.baseUrl || '').trim();
623
+ const cloudToken = String(manager.serverSettings.token || '').trim();
624
+ if (cloudBaseUrl) {
625
+ setJupyterServerUrl(cloudBaseUrl.replace(/\/$/, ''));
626
+ }
627
+ if (cloudToken) {
628
+ setJupyterServerToken(cloudToken);
629
+ }
630
+ return manager;
631
+ };
632
+ let lastError;
633
+ for (let attempt = 1; attempt <= 8; attempt += 1) {
634
+ try {
635
+ return await connectOnce(summary);
636
+ }
637
+ catch (error) {
638
+ lastError = error;
639
+ if (attempt === 8) {
640
+ break;
641
+ }
642
+ await wait(700 * attempt);
643
+ }
644
+ }
645
+ throw lastError;
646
+ };
647
+ const bootstrapCloudSandbox = async () => {
648
+ const runtimesUrl = resolveRuntimesUrl(configuration.runtimesUrl);
649
+ const exampleSlug = safeExampleId(selectedExample || 'example');
650
+ const runtimeResp = await fetch(`${runtimesUrl}/api/runtimes/v1/runtimes`, {
651
+ method: 'POST',
652
+ headers: {
653
+ Authorization: `Bearer ${configuration.token}`,
654
+ 'Content-Type': 'application/json',
655
+ },
656
+ body: JSON.stringify({
657
+ environment: {
658
+ name: DEFAULT_CLOUD_RUNTIME_ENVIRONMENT,
659
+ },
660
+ given_name: `${exampleSlug}-sandbox`,
661
+ credits_limit: 5,
662
+ type: 'notebook',
663
+ editor_variant: 'none',
664
+ }),
665
+ });
666
+ if (!runtimeResp.ok) {
667
+ const failure = await runtimeResp.json().catch(() => ({}));
668
+ throw new Error(String(failure.detail ||
669
+ `Failed to launch cloud runtime (${runtimeResp.status}).`));
670
+ }
671
+ const runtimePayload = (await runtimeResp.json());
672
+ const ingress = String(runtimePayload.runtime?.ingress || runtimePayload.ingress || '').trim();
673
+ if (!ingress) {
674
+ throw new Error('Cloud runtime launched but did not expose a Jupyter ingress URL.');
675
+ }
676
+ const agentBaseUrl = toAgentApiBaseUrl(ingress);
677
+ const agentId = `${exampleSlug}-cloud-agent`;
678
+ const agentResp = await fetch(`${agentBaseUrl}/api/v1/agents`, {
679
+ method: 'POST',
680
+ headers: {
681
+ Authorization: `Bearer ${configuration.token}`,
682
+ 'Content-Type': 'application/json',
683
+ },
684
+ body: JSON.stringify({
685
+ name: agentId,
686
+ description: `Cloud sandbox agent for ${selectedExample}`,
687
+ agent_library: 'pydantic-ai',
688
+ transport: 'ag-ui',
689
+ model: DEFAULT_MODEL,
690
+ system_prompt: 'You are a helpful AI assistant.',
691
+ }),
692
+ });
693
+ if (!agentResp.ok &&
694
+ agentResp.status !== 400 &&
695
+ agentResp.status !== 409) {
696
+ const failure = await agentResp.json().catch(() => ({}));
697
+ throw new Error(String(failure.detail ||
698
+ `Cloud runtime launched but agent creation failed (${agentResp.status}).`));
699
+ }
700
+ const agentPayload = (await agentResp
701
+ .clone()
702
+ .json()
703
+ .catch(() => ({})));
704
+ const resolvedAgentId = String(agentPayload.agent_id ||
705
+ agentPayload.id ||
706
+ agentPayload.agent?.agent_id ||
707
+ agentPayload.agent?.id ||
708
+ '').trim() || agentId;
709
+ const resolvedJupyterToken = String(agentPayload.jupyter_token ||
710
+ agentPayload.token ||
711
+ runtimePayload.runtime?.jupyter_token ||
712
+ runtimePayload.runtime?.token ||
713
+ runtimePayload.jupyter_token ||
714
+ runtimePayload.token ||
715
+ '').trim();
716
+ const runtimeEnvironment = {
717
+ environmentName: String(runtimePayload.runtime?.environment?.name || '').trim() ||
718
+ undefined,
719
+ environmentTitle: String(runtimePayload.runtime?.environment?.title || '').trim() ||
720
+ undefined,
721
+ cpu: String(runtimePayload.runtime?.environment?.cpu ||
722
+ runtimePayload.runtime?.environment?.resources?.cpu ||
723
+ '').trim() || undefined,
724
+ memory: String(runtimePayload.runtime?.environment?.memory ||
725
+ runtimePayload.runtime?.environment?.resources?.memory ||
726
+ '').trim() || undefined,
727
+ gpu: [
728
+ runtimePayload.runtime?.environment?.gpu ||
729
+ runtimePayload.runtime?.environment?.resources?.gpu ||
730
+ runtimePayload.runtime?.environment?.resources?.gpu_count ||
731
+ runtimePayload.runtime?.environment?.resources?.['nvidia.com/gpu'] ||
732
+ '',
733
+ runtimePayload.runtime?.environment?.resources?.gpu_type || '',
734
+ runtimePayload.runtime?.environment?.resources?.gpu_memory ||
735
+ '',
736
+ ]
737
+ .map(value => String(value || '').trim())
738
+ .filter(Boolean)
739
+ .join(' ') || undefined,
740
+ };
741
+ return {
742
+ agentBaseUrl,
743
+ agentId: resolvedAgentId,
744
+ ingress: withTokenQueryParam(ingress, resolvedJupyterToken),
745
+ runtimeEnvironment,
746
+ };
747
+ };
467
748
  const activeSummary = agentSummaryStore.getState().active;
468
- const selectedEntry = getExampleEntriesList().find(entry => entry.id === selectedExample);
469
- const resolvedSpecId = activeSummary?.exampleId === selectedExample
470
- ? activeSummary.specId
471
- : undefined;
472
- const runtimeDescriptor = resolvedSpecId || selectedEntry?.title || selectedExample;
473
- const contextualRuntimeName = `Agent Runtime - ${runtimeDescriptor}`;
474
- const manager = await createDatalayerServiceManager(configuration.cpuEnvironment || 'python-3.11', configuration.credits || 100, contextualRuntimeName);
475
- await manager.ready;
476
- return manager;
749
+ if (activeSummary?.location === 'cloud' &&
750
+ (activeSummary.sandboxBaseUrl || activeSummary.baseUrl)) {
751
+ try {
752
+ return await connectFromSummary({
753
+ baseUrl: activeSummary.baseUrl,
754
+ sandboxBaseUrl: activeSummary.sandboxBaseUrl,
755
+ agentId: activeSummary.agentId,
756
+ runtimeEnvironment: activeSummary.runtimeEnvironment,
757
+ });
758
+ }
759
+ catch (error) {
760
+ if (!isNotebookOrCellExample(selectedExample)) {
761
+ throw error;
762
+ }
763
+ showTopNotice('Existing cloud sandbox is unavailable. Launching a fresh sandbox...', 'warning', 3500);
764
+ }
765
+ }
766
+ if (!isNotebookOrCellExample(selectedExample)) {
767
+ throw new Error('No active cloud agent sandbox found. Open an agent example and launch a cloud agent first.');
768
+ }
769
+ showTopNotice('Starting a cloud agent sandbox...', 'info', 2600);
770
+ const launched = await bootstrapCloudSandbox();
771
+ agentSummaryStore.getState().setActive({
772
+ exampleId: selectedExample,
773
+ agentName: launched.agentId,
774
+ agentId: launched.agentId,
775
+ location: 'cloud',
776
+ baseUrl: launched.agentBaseUrl,
777
+ sandboxBaseUrl: launched.ingress,
778
+ runtimeEnvironment: launched.runtimeEnvironment,
779
+ status: 'running',
780
+ isReady: true,
781
+ });
782
+ showTopNotice(`Cloud sandbox ready. Connecting ${toSurfaceLabel(selectedExample)} to it...`, 'success', 2600);
783
+ return connectFromSummary({
784
+ baseUrl: launched.agentBaseUrl,
785
+ sandboxBaseUrl: launched.ingress,
786
+ agentId: launched.agentId,
787
+ runtimeEnvironment: launched.runtimeEnvironment,
788
+ });
477
789
  };
478
790
  useEffect(() => {
479
791
  // Load configurations
@@ -488,14 +800,13 @@ export const ExampleApp = () => {
488
800
  try {
489
801
  const manager = await createCloudServiceManager();
490
802
  setServiceManager(manager);
803
+ showTopNotice('Code sandbox connected successfully (cloud).', 'success', 2600);
491
804
  // Load initial example
492
805
  await loadExample(selectedExample, manager);
493
806
  }
494
807
  catch (error) {
495
808
  console.error('Failed to create DatalayerServiceManager:', error);
496
- // Surface the failure in the UI, then fall back to local so the
497
- // app stays usable.
498
- setError(`Cloud runtime unavailable, using local instead: ${error instanceof Error ? error.message : String(error)}`);
809
+ showTopNotice(`Cloud runtime unavailable, using local instead: ${error instanceof Error ? error.message : String(error)}`, 'warning', 5500);
499
810
  const manager = await createLocalServiceManager();
500
811
  setServiceManager(manager);
501
812
  // Load initial example
@@ -513,6 +824,7 @@ export const ExampleApp = () => {
513
824
  }
514
825
  catch (e) {
515
826
  console.error('Failed to initialize app:', e);
827
+ showTopNotice(`Failed to initialize app: ${e instanceof Error ? e.message : String(e)}`, 'error', 6000);
516
828
  setError(`Failed to initialize app: ${e}`);
517
829
  setLoading(false);
518
830
  }
@@ -553,9 +865,9 @@ export const ExampleApp = () => {
553
865
  : await createLocalServiceManager();
554
866
  }
555
867
  catch (switchError) {
556
- setError(`Failed to switch to ${newTarget}: ${switchError instanceof Error
868
+ showTopNotice(`Failed to switch to ${newTarget}: ${switchError instanceof Error
557
869
  ? switchError.message
558
- : String(switchError)}`);
870
+ : String(switchError)}`, 'error', 6000);
559
871
  return;
560
872
  }
561
873
  // 1) Unmount the current example FIRST so its cleanup hooks run against the
@@ -576,6 +888,7 @@ export const ExampleApp = () => {
576
888
  setServiceManager(nextManager);
577
889
  setError(null);
578
890
  await loadExample(selectedExample, nextManager);
891
+ showTopNotice(`Code sandbox connected successfully (${newTarget}).`, 'success', 2600);
579
892
  };
580
893
  if (loading) {
581
894
  return (_jsxs("div", { style: { padding: '20px', textAlign: 'center' }, children: [_jsxs("h2", { children: ["Loading Example: ", selectedExample] }), _jsx("p", { children: "Please wait..." })] }));
@@ -598,16 +911,17 @@ export const ExampleApp = () => {
598
911
  exampleProps.onSelectExample = (name) => {
599
912
  void handleExampleChange(name);
600
913
  };
601
- return (_jsx(ExampleAppThemed, { selectedExample: selectedExample, isChangingExample: isChangingExample, error: error, ExampleComponent: ExampleComponent, exampleProps: exampleProps, serviceManager: serviceManager, onExampleChange: handleExampleChange, onRuntimeTargetChange: handleRuntimeTargetChange, availableExamples: getExampleEntriesList() }));
914
+ return (_jsx(ExampleAppThemed, { selectedExample: selectedExample, isChangingExample: isChangingExample, error: error, ExampleComponent: ExampleComponent, exampleProps: exampleProps, serviceManager: serviceManager, onExampleChange: handleExampleChange, onRuntimeTargetChange: handleRuntimeTargetChange, availableExamples: getExampleEntriesList(), topNotice: topNotice, onDismissTopNotice: () => setTopNotice(null) }));
602
915
  };
603
916
  /**
604
917
  * Inner shell that reads from the theme store and wires
605
918
  * DatalayerThemeProvider + the header bar with selectors.
606
919
  */
607
- const ExampleAppThemed = ({ selectedExample, isChangingExample, error, ExampleComponent, exampleProps, serviceManager, onExampleChange, onRuntimeTargetChange, availableExamples, }) => {
920
+ const ExampleAppThemed = ({ selectedExample, isChangingExample, error, ExampleComponent, exampleProps, serviceManager, onExampleChange, onRuntimeTargetChange, availableExamples, topNotice, onDismissTopNotice, }) => {
608
921
  const { colorMode, theme: themeVariant } = useExampleThemeStore();
609
922
  const runtimeTarget = useRuntimeTargetStore(state => state.target);
610
923
  const agentSummary = useAgentSummaryStore(state => state.active);
924
+ const isHome = selectedExample === 'HomeExample';
611
925
  const cfg = themeConfigs[themeVariant];
612
926
  const logoColors = getLogoColors(themeVariant, colorMode);
613
927
  const { token, setAuth, clearAuth } = useSimpleAuthStore();
@@ -619,8 +933,11 @@ const ExampleAppThemed = ({ selectedExample, isChangingExample, error, ExampleCo
619
933
  });
620
934
  }, []);
621
935
  useEffect(() => {
622
- const baseUrl = toAgentRuntimesBaseUrl(serviceManager?.serverSettings.baseUrl) ||
623
- resolveExampleAgentRuntimesUrl(runtimeTarget);
936
+ const jupyterSandboxBaseUrl = toAgentRuntimesBaseUrl(serviceManager?.serverSettings.baseUrl);
937
+ const agentApiBaseUrl = resolveExampleAgentRuntimesUrl(runtimeTarget);
938
+ const isSandboxOnlyExample = (selectedExample.includes('Notebook') ||
939
+ selectedExample.includes('Cell')) &&
940
+ !selectedExample.includes('Agent');
624
941
  // Seed a base summary for the selected example. Do NOT clobber a richer
625
942
  // summary that the mounted example already published (spec id, agent id,
626
943
  // readiness) for the same example + target — otherwise fast-settling local
@@ -639,7 +956,8 @@ const ExampleAppThemed = ({ selectedExample, isChangingExample, error, ExampleCo
639
956
  exampleId: selectedExample,
640
957
  agentName: selectedExample,
641
958
  location: runtimeTarget,
642
- baseUrl,
959
+ baseUrl: isSandboxOnlyExample ? '' : agentApiBaseUrl,
960
+ sandboxBaseUrl: isSandboxOnlyExample ? jupyterSandboxBaseUrl : undefined,
643
961
  status: isChangingExample ? 'switching' : 'selected',
644
962
  });
645
963
  }, [selectedExample, runtimeTarget, isChangingExample, serviceManager]);
@@ -686,7 +1004,7 @@ const ExampleAppThemed = ({ selectedExample, isChangingExample, error, ExampleCo
686
1004
  justifyContent: 'space-between',
687
1005
  gap: 3,
688
1006
  height: '60px',
689
- bg: 'canvas.subtle',
1007
+ bg: 'canvas.default',
690
1008
  borderBottom: '1px solid',
691
1009
  borderColor: 'border.default',
692
1010
  }, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Box, { as: "button", onClick: () => void onExampleChange('HomeExample'), title: "Home", "aria-label": "Go to examples home", sx: {
@@ -705,7 +1023,7 @@ const ExampleAppThemed = ({ selectedExample, isChangingExample, error, ExampleCo
705
1023
  px: 2,
706
1024
  py: '6px',
707
1025
  fontSize: 1,
708
- fontFamily: 'mono',
1026
+ fontFamily: 'inherit',
709
1027
  border: '1px solid',
710
1028
  borderColor: 'border.default',
711
1029
  borderRadius: 2,
@@ -715,7 +1033,7 @@ const ExampleAppThemed = ({ selectedExample, isChangingExample, error, ExampleCo
715
1033
  minWidth: '250px',
716
1034
  outline: 'none',
717
1035
  '&:focus-visible': {
718
- boxShadow: '0 0 0 2px var(--bgColor-accent-muted, rgba(9,105,218,0.3))',
1036
+ boxShadow: '0 0 0 2px var(--bgColor-accent-muted, rgba(26,188,156,0.3))',
719
1037
  },
720
1038
  }, children: (() => {
721
1039
  const home = availableExamples.find(e => e.id === 'HomeExample');
@@ -798,23 +1116,18 @@ const ExampleAppThemed = ({ selectedExample, isChangingExample, error, ExampleCo
798
1116
  }
799
1117
  }
800
1118
  return _jsx(_Fragment, { children: nodes });
801
- })() }), _jsxs(Box, { as: "select", value: runtimeTarget, onChange: (e) => void onRuntimeTargetChange(e.target.value), disabled: isChangingExample, "aria-label": "Runtime target", title: "Runtime target", sx: {
802
- px: 2,
803
- py: '6px',
804
- fontSize: 1,
805
- fontFamily: 'mono',
806
- border: '1px solid',
807
- borderColor: 'border.default',
808
- borderRadius: 2,
809
- bg: 'canvas.default',
810
- color: 'fg.default',
811
- cursor: isChangingExample ? 'not-allowed' : 'pointer',
812
- minWidth: '120px',
813
- outline: 'none',
814
- '&:focus-visible': {
815
- boxShadow: '0 0 0 2px var(--bgColor-accent-muted, rgba(9,105,218,0.3))',
816
- },
817
- }, children: [_jsx("option", { value: "local", children: "Local" }), _jsx("option", { value: "cloud", children: "Cloud" })] }), _jsx(AgentSummary, { summary: agentSummary }), isChangingExample && (_jsx(Box, { as: "span", sx: { color: 'fg.muted', fontSize: 0 }, children: "Loading\u2026" })), error && (_jsxs(Box, { as: "span", sx: { color: 'danger.fg', fontSize: 0 }, children: ["Error: ", error] }))] }), _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 3 }, children: [_jsx(AppearanceControlsWithStore, { useStore: useExampleThemeStore }), _jsx(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: token ? (_jsxs(_Fragment, { children: [_jsx(UserBadge, { token: token, variant: "small", onTokenExpired: () => {
1119
+ })() }), _jsx(Box, { "aria-label": "Runtime target", title: "Runtime target", sx: {
1120
+ minWidth: '160px',
1121
+ opacity: isHome || isChangingExample ? 0.6 : 1,
1122
+ }, children: _jsxs(SegmentedControl, { "aria-label": "Runtime target", fullWidth: true, children: [_jsx(SegmentedControl.Button, { selected: runtimeTarget === 'local', disabled: isHome, onClick: () => {
1123
+ if (!isHome && !isChangingExample) {
1124
+ void onRuntimeTargetChange('local');
1125
+ }
1126
+ }, children: "Local" }), _jsx(SegmentedControl.Button, { selected: runtimeTarget === 'cloud', disabled: isHome, onClick: () => {
1127
+ if (!isHome && !isChangingExample) {
1128
+ void onRuntimeTargetChange('cloud');
1129
+ }
1130
+ }, children: "Cloud" })] }) }), !isHome && _jsx(AgentSummary, { summary: agentSummary }), isChangingExample && (_jsx(Box, { as: "span", sx: { color: 'fg.muted', fontSize: 0 }, children: "Loading\u2026" }))] }), _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 3 }, children: [_jsx(AppearanceControlsWithStore, { useStore: useExampleThemeStore }), _jsx(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: token ? (_jsxs(_Fragment, { children: [_jsx(UserBadge, { token: token, variant: "small", onTokenExpired: () => {
818
1131
  handleHeaderLogout();
819
1132
  setShowSignIn(true);
820
1133
  } }), _jsx(Button, { size: "small", variant: "invisible", onClick: handleHeaderLogout, leadingVisual: SignOutIcon, sx: { color: 'fg.muted' }, children: "Sign out" })] })) : (_jsx(Button, { size: "small", variant: "invisible", onClick: () => setShowSignIn(true), leadingVisual: SignInIcon, sx: { color: 'fg.muted' }, children: "Sign in" })) }), _jsx(Box, { as: "a", href: "https://datalayer.ai", target: "_blank", rel: "noopener noreferrer", "aria-label": "Open Datalayer website", sx: { display: 'inline-flex', alignItems: 'center' }, children: _jsx(DatalayerLogoText, { size: 24, variant: themeVariant, colorMode: colorMode, primaryColor: logoColors.primary, secondaryColor: logoColors.secondary, textColor: logoColors.textColor, primaryGradient: logoColors.primaryGradient, secondaryGradient: logoColors.secondaryGradient, gradient: true }) })] })] }), _jsx(Box, { sx: {
@@ -827,7 +1140,7 @@ const ExampleAppThemed = ({ selectedExample, isChangingExample, error, ExampleCo
827
1140
  bg: 'canvas.backdrop',
828
1141
  p: 3,
829
1142
  overflow: 'auto',
830
- }, children: _jsx(Box, { sx: { maxWidth: 640, mx: 'auto' }, children: _jsx(SignInSimple, { onSignIn: handleHeaderSignIn, onApiKeySignIn: apiKey => handleHeaderSignIn(apiKey, 'api-key-user'), title: "Agent Runtimes Examples", description: "Sign in to run authenticated examples and tools.", leadingIcon: _jsx(HomeIcon, { size: 24 }) }) }) })) : isChangingExample ? (_jsxs(Box, { sx: { p: 5, textAlign: 'center', color: 'fg.muted' }, children: [_jsxs("h3", { children: ["Loading ", selectedExample, "\u2026"] }), _jsx("p", { children: "Please wait while the example loads." })] })) : ExampleComponent ? (_jsx(ExampleErrorBoundary, { children: _jsx(ExampleWrapper, { children: _jsx(ExampleComponent, { ...exampleProps }, `${selectedExample}:${runtimeTarget}`) }, `${selectedExample}:${runtimeTarget}`) }, `${selectedExample}:${runtimeTarget}`)) : null })] }) }));
1143
+ }, children: _jsx(Box, { sx: { maxWidth: 640, mx: 'auto' }, children: _jsx(SignInSimple, { onSignIn: handleHeaderSignIn, onApiKeySignIn: apiKey => handleHeaderSignIn(apiKey, 'api-key-user'), title: "Agent Runtimes Examples", description: "Sign in to run authenticated examples and tools.", leadingIcon: _jsx(HomeIcon, { size: 24 }) }) }) })) : isChangingExample ? (_jsxs(Box, { sx: { p: 5, textAlign: 'center', color: 'fg.muted' }, children: [_jsxs("h3", { children: ["Loading ", selectedExample, "\u2026"] }), _jsx("p", { children: "Please wait while the example loads." })] })) : ExampleComponent ? (_jsx(ExampleErrorBoundary, { children: _jsx(ExampleWrapper, { children: _jsx(ExampleComponent, { ...exampleProps }, `${selectedExample}:${runtimeTarget}`) }, `${selectedExample}:${runtimeTarget}`) }, `${selectedExample}:${runtimeTarget}`)) : null }), _jsx(SlidingPanel, { isOpen: Boolean(topNotice), onDismiss: onDismissTopNotice, position: "north", variant: topNotice?.tone ?? 'info', durationMs: topNotice?.durationMs ?? 0, fullWidth: true, offset: 60, zIndex: 160, message: topNotice?.message || '', details: topNotice?.details })] }) }));
831
1144
  };
832
1145
  // Mount the app - check route to determine which app to render
833
1146
  const root = document.getElementById('root');
@@ -5,7 +5,24 @@ export interface AgentSummary {
5
5
  agentId?: string;
6
6
  specId?: string;
7
7
  location: AgentSummaryLocation;
8
+ /**
9
+ * Base URL of the agent-runtimes API server. Hosts both the agent status
10
+ * endpoint (`/api/v1/runtime/status`) and the code sandbox status endpoint
11
+ * (`/api/v1/agents/sandbox/status`).
12
+ */
8
13
  baseUrl: string;
14
+ /**
15
+ * Base URL of the code sandbox (Jupyter for local runs). Shown for context;
16
+ * the sandbox status itself is reported by the agent-runtimes server.
17
+ */
18
+ sandboxBaseUrl?: string;
19
+ runtimeEnvironment?: {
20
+ environmentName?: string;
21
+ environmentTitle?: string;
22
+ cpu?: string;
23
+ memory?: string;
24
+ gpu?: string;
25
+ };
9
26
  status?: string;
10
27
  isReady?: boolean;
11
28
  error?: string;
@@ -1,5 +1,24 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { DatalayerThemeProvider, themeConfigs, } from '@datalayer/primer-addons';
2
+ /*
3
+ * Copyright (c) 2025-2026 Datalayer, Inc.
4
+ * Distributed under the terms of the Modified BSD License.
5
+ */
6
+ /**
7
+ * Theme-aware wrappers for example components.
8
+ *
9
+ * These are drop-in replacements for `DatalayerThemeProvider` and
10
+ * `JupyterReactTheme` that automatically read theme / color-mode
11
+ * from the shared `useExampleThemeStore`.
12
+ *
13
+ * Usage: replace
14
+ * import { DatalayerThemeProvider } from '@datalayer/primer-addons';
15
+ * with
16
+ * import { ThemedProvider } from './stores/themedProvider';
17
+ *
18
+ * and swap `<DatalayerThemeProvider>` → `<ThemedProvider>`.
19
+ */
20
+ import { useEffect } from 'react';
21
+ import { DatalayerThemeProvider, themeConfigs, useThemeStore as usePrimerThemeStore, } from '@datalayer/primer-addons';
3
22
  import { JupyterReactTheme } from '@datalayer/jupyter-react';
4
23
  import { useExampleThemeStore } from './themeStore';
5
24
  /**
@@ -11,6 +30,13 @@ import { useExampleThemeStore } from './themeStore';
11
30
  export const ThemedProvider = ({ children, ...rest }) => {
12
31
  const { colorMode, theme: themeVariant } = useExampleThemeStore();
13
32
  const cfg = themeConfigs[themeVariant];
33
+ // <Chat> and other components read the shared primer-addons singleton
34
+ // `useThemeStore` (key 'datalayer-theme', which defaults to matrix/dark),
35
+ // not the examples' `useExampleThemeStore`. Mirror the selected theme into
36
+ // the singleton so the chat main view follows the picker.
37
+ useEffect(() => {
38
+ usePrimerThemeStore.setState({ theme: themeVariant, colorMode });
39
+ }, [themeVariant, colorMode]);
14
40
  return (_jsx(DatalayerThemeProvider, { colorMode: rest.colorMode ?? colorMode, theme: rest.theme ?? cfg.primerTheme, themeStyles: rest.themeStyles ?? cfg.themeStyles, ...rest, children: children }));
15
41
  };
16
42
  /**
@@ -50,5 +76,9 @@ export const ThemedJupyterProvider = ({ children, useJupyterReactTheme = true })
50
76
  // Extract the canvas background from the theme's CSS-var overrides.
51
77
  const modeStyles = resolvedMode === 'dark' ? cfg.themeStyles.dark : cfg.themeStyles.light;
52
78
  const backgroundColor = modeStyles['--bgColor-default'];
53
- return (_jsx(ThemedProvider, { children: useJupyterReactTheme ? (_jsx(JupyterReactTheme, { colormode: colorMode, backgroundColor: backgroundColor, children: children })) : (children) }));
79
+ return (_jsx(ThemedProvider, { children: useJupyterReactTheme ? (
80
+ // `ThemedProvider` (DatalayerThemeProvider) already applies Primer
81
+ // BaseStyles with the branded theme font. Disable the inner BaseStyles
82
+ // so Jupyter examples inherit that font instead of Primer's default.
83
+ _jsx(JupyterReactTheme, { colormode: colorMode, backgroundColor: backgroundColor, useBaseStyles: false, children: children })) : (children) }));
54
84
  };