@datalayer/core 1.2.10 → 1.2.13
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.
- package/README.md +5 -5
- package/lib/api/iam/authentication.js +6 -4
- package/lib/api/iam/healthz.js +2 -2
- package/lib/api/iam/oauth2.js +18 -12
- package/lib/api/iam/secrets.js +1 -2
- package/lib/api/mcp/observability.d.ts +9 -2
- package/lib/api/mcp/observability.js +40 -15
- package/lib/client/auth/strategies.js +1 -1
- package/lib/client/mixins/IAMMixin.js +2 -2
- package/lib/components/checkout/StripeCheckout.d.ts +1 -1
- package/lib/components/checkout/StripeCheckout.js +1 -1
- package/lib/components/display/VisuallyHidden.d.ts +1 -2
- package/lib/components/sharing/sandboxSharing.js +7 -1
- package/lib/config/Configuration.d.ts +4 -4
- package/lib/config/Configuration.js +7 -7
- package/lib/config/index.d.ts +1 -0
- package/lib/config/index.js +1 -0
- package/lib/config/planes.d.ts +45 -0
- package/lib/config/planes.js +53 -0
- package/lib/hooks/useBackdrop.d.ts +4 -5
- package/lib/hooks/useCache.d.ts +52 -19
- package/lib/hooks/useCache.js +310 -198
- package/lib/hooks/useContents.js +3 -0
- package/lib/hooks/useMcp.js +1 -1
- package/lib/hooks/useNavigate.js +10 -0
- package/lib/hooks/useWindowSize.js +1 -1
- package/lib/models/IAMProvidersSpecs.d.ts +10 -5
- package/lib/models/IAMProvidersSpecs.js +0 -23
- package/lib/models/URN.d.ts +37 -0
- package/lib/models/URN.js +59 -1
- package/lib/navigation/adapters/react-router.d.ts +1 -1
- package/lib/navigation/adapters/react-router.js +3 -0
- package/lib/state/sessionEnd.js +1 -1
- package/lib/state/substates/CoreState.js +3 -16
- package/lib/state/substates/IAMState.d.ts +3 -3
- package/lib/state/substates/NavigationState.d.ts +92 -0
- package/lib/state/substates/NavigationState.js +304 -0
- package/lib/state/substates/index.d.ts +1 -0
- package/lib/state/substates/index.js +1 -0
- package/lib/utils/Handles.js +1 -1
- package/lib/utils/Screencapture.d.ts +15 -0
- package/lib/utils/Screencapture.js +26 -23
- package/lib/views/mcp/McpDashboard.js +15 -10
- package/lib/views/mcp/McpHome.js +13 -6
- package/lib/views/mcp/types.d.ts +4 -0
- package/package.json +9 -7
- package/scripts/generate-mcp-types.py +15 -9
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://github.com/sponsors/datalayer)
|
|
4
4
|
|
|
5
|
-
# ☰
|
|
5
|
+
# ☰ 🌀 Datalayer Core
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
8
|
<strong>Python and Typescript libraries for Datalayer</strong>
|
|
@@ -13,12 +13,12 @@
|
|
|
13
13
|
<a href="https://pypi.org/project/datalayer-core/"><img src="https://img.shields.io/pypi/pyversions/datalayer-core.svg" alt="Python versions"></img></a>
|
|
14
14
|
<a href="https://github.com/datalayer/core/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-BSD%203--Clause-blue.svg" alt="License"></img></a>
|
|
15
15
|
<a href="https://datalayer.ai/docs/"><img src="https://img.shields.io/badge/docs-datalayer.app-blue" alt="Documentation"></img></a>
|
|
16
|
-
<a href="https://github.com/datalayer/core/actions/workflows/py-tests.
|
|
16
|
+
<a href="https://github.com/datalayer/core/actions/workflows/py-tests.yaml"><img src="https://github.com/datalayer/core/actions/workflows/py-tests.yaml/badge.svg" alt="Units Tests"></img></a><a href="https://github.com/datalayer/core/actions/workflows/ts-tests.yaml"><img src="https://github.com/datalayer/core/actions/workflows/ts-tests.yaml/badge.svg" alt="Units Tests"></img></a>
|
|
17
17
|
</p>
|
|
18
18
|
|
|
19
19
|
## Overview
|
|
20
20
|
|
|
21
|
-
Datalayer Core is the foundational package that powers the [Datalayer AI Platform](https://datalayer.
|
|
21
|
+
Datalayer Core is the foundational package that powers the [Datalayer AI Platform](https://datalayer.ai/). It provides a TypesScript and Python packages as a Command Line Interface (CLI) for AI engineers, data scientists, and researchers to seamlessly integrate scalable compute runtimes into their workflows.
|
|
22
22
|
|
|
23
23
|
This package serves as the base foundation used by many other Datalayer packages, containing core application classes, configuration, and unified APIs for authentication, runtime management, and code execution in cloud-based environments.
|
|
24
24
|
|
|
@@ -219,7 +219,7 @@ This project is licensed under the [BSD 3-Clause License](https://github.com/dat
|
|
|
219
219
|
|
|
220
220
|
- **Documentation**: [Datalayer Platform Documentation](https://datalayer.ai/docs/)
|
|
221
221
|
- **Issues**: [GitHub Issues](https://github.com/datalayer/core/issues)
|
|
222
|
-
- **Community**: [Datalayer Platform](https://datalayer.
|
|
222
|
+
- **Community**: [Datalayer Platform](https://datalayer.ai/)
|
|
223
223
|
|
|
224
224
|
---
|
|
225
225
|
|
|
@@ -229,5 +229,5 @@ This project is licensed under the [BSD 3-Clause License](https://github.com/dat
|
|
|
229
229
|
|
|
230
230
|
<p align="center">
|
|
231
231
|
<strong>🚀 AI Agents for Data Analysis</strong><br></br>
|
|
232
|
-
<a href="https://datalayer.
|
|
232
|
+
<a href="https://datalayer.ai/">Get started with Datalayer today!</a>
|
|
233
233
|
</p>
|
|
@@ -60,10 +60,12 @@ export const login = async (data, baseUrl = DEFAULT_SERVICE_URLS.IAM) => {
|
|
|
60
60
|
const status = error.response.status;
|
|
61
61
|
// Expected error: 401 for invalid credentials
|
|
62
62
|
if (status === 401) {
|
|
63
|
-
throw new Error(`Login failed: Invalid credentials (${status})
|
|
63
|
+
throw new Error(`Login failed: Invalid credentials (${status})`, {
|
|
64
|
+
cause: error,
|
|
65
|
+
});
|
|
64
66
|
}
|
|
65
67
|
// Unexpected status codes
|
|
66
|
-
throw new Error(`Login failed: Unexpected status code ${status} - ${error.message}
|
|
68
|
+
throw new Error(`Login failed: Unexpected status code ${status} - ${error.message}`, { cause: error });
|
|
67
69
|
}
|
|
68
70
|
// Re-throw other errors (network errors, etc.)
|
|
69
71
|
throw error;
|
|
@@ -116,10 +118,10 @@ export const checkAuth = async (token, baseUrl = DEFAULT_SERVICE_URLS.IAM) => {
|
|
|
116
118
|
const status = error.response.status;
|
|
117
119
|
// Expected errors
|
|
118
120
|
if (status === 401) {
|
|
119
|
-
throw new Error(`Authentication check failed: Unauthorized (${status})
|
|
121
|
+
throw new Error(`Authentication check failed: Unauthorized (${status})`, { cause: error });
|
|
120
122
|
}
|
|
121
123
|
// Unexpected status codes
|
|
122
|
-
throw new Error(`Authentication check failed: Unexpected status code ${status} - ${error.message}
|
|
124
|
+
throw new Error(`Authentication check failed: Unexpected status code ${status} - ${error.message}`, { cause: error });
|
|
123
125
|
}
|
|
124
126
|
// Re-throw other errors (network errors, etc.)
|
|
125
127
|
throw error;
|
package/lib/api/iam/healthz.js
CHANGED
|
@@ -37,9 +37,9 @@ export const ping = async (baseUrl = DEFAULT_SERVICE_URLS.IAM) => {
|
|
|
37
37
|
// Check if it's a response error with status code information
|
|
38
38
|
if (error.response) {
|
|
39
39
|
const status = error.response.status;
|
|
40
|
-
throw new Error(`Health check failed: Service unhealthy (status ${status}) - ${error.message}
|
|
40
|
+
throw new Error(`Health check failed: Service unhealthy (status ${status}) - ${error.message}`, { cause: error });
|
|
41
41
|
}
|
|
42
42
|
// Re-throw other errors (network errors, etc.)
|
|
43
|
-
throw new Error(`Health check failed: ${error.message}
|
|
43
|
+
throw new Error(`Health check failed: ${error.message}`, { cause: error });
|
|
44
44
|
}
|
|
45
45
|
};
|
package/lib/api/iam/oauth2.js
CHANGED
|
@@ -57,13 +57,15 @@ export const getOAuth2AuthzUrl = async (provider, callbackUri, nonce, baseUrl =
|
|
|
57
57
|
const status = error.response.status;
|
|
58
58
|
// Expected errors
|
|
59
59
|
if (status === 400) {
|
|
60
|
-
throw new Error(`Invalid OAuth2 parameters: ${error.message}
|
|
60
|
+
throw new Error(`Invalid OAuth2 parameters: ${error.message}`, {
|
|
61
|
+
cause: error,
|
|
62
|
+
});
|
|
61
63
|
}
|
|
62
64
|
if (status === 404) {
|
|
63
|
-
throw new Error(`OAuth2 provider '${provider}' not found or not configured
|
|
65
|
+
throw new Error(`OAuth2 provider '${provider}' not found or not configured`, { cause: error });
|
|
64
66
|
}
|
|
65
67
|
// Unexpected status codes
|
|
66
|
-
throw new Error(`Failed to get OAuth2 authorization URL: ${status} - ${error.message}
|
|
68
|
+
throw new Error(`Failed to get OAuth2 authorization URL: ${status} - ${error.message}`, { cause: error });
|
|
67
69
|
}
|
|
68
70
|
// Re-throw other errors (network errors, etc.)
|
|
69
71
|
throw error;
|
|
@@ -112,13 +114,15 @@ export const getOAuth2AuthzUrlForLink = async (provider, callbackUri, baseUrl =
|
|
|
112
114
|
const status = error.response.status;
|
|
113
115
|
// Expected errors
|
|
114
116
|
if (status === 400) {
|
|
115
|
-
throw new Error(`Invalid OAuth2 link parameters: ${error.message}
|
|
117
|
+
throw new Error(`Invalid OAuth2 link parameters: ${error.message}`, {
|
|
118
|
+
cause: error,
|
|
119
|
+
});
|
|
116
120
|
}
|
|
117
121
|
if (status === 404) {
|
|
118
|
-
throw new Error(`OAuth2 provider '${provider}' not found or not configured for linking
|
|
122
|
+
throw new Error(`OAuth2 provider '${provider}' not found or not configured for linking`, { cause: error });
|
|
119
123
|
}
|
|
120
124
|
// Unexpected status codes
|
|
121
|
-
throw new Error(`Failed to get OAuth2 link authorization URL: ${status} - ${error.message}
|
|
125
|
+
throw new Error(`Failed to get OAuth2 link authorization URL: ${status} - ${error.message}`, { cause: error });
|
|
122
126
|
}
|
|
123
127
|
// Re-throw other errors (network errors, etc.)
|
|
124
128
|
throw error;
|
|
@@ -176,10 +180,10 @@ export const handleGitHubOAuth2Callback = async (params, baseUrl = DEFAULT_SERVI
|
|
|
176
180
|
const status = error.response.status;
|
|
177
181
|
// Expected errors
|
|
178
182
|
if (status === 403) {
|
|
179
|
-
throw new Error(`GitHub OAuth2 callback unauthorized: ${error.message}
|
|
183
|
+
throw new Error(`GitHub OAuth2 callback unauthorized: ${error.message}`, { cause: error });
|
|
180
184
|
}
|
|
181
185
|
// Unexpected status codes
|
|
182
|
-
throw new Error(`GitHub OAuth2 callback failed: ${status} - ${error.message}
|
|
186
|
+
throw new Error(`GitHub OAuth2 callback failed: ${status} - ${error.message}`, { cause: error });
|
|
183
187
|
}
|
|
184
188
|
// Re-throw other errors (network errors, etc.)
|
|
185
189
|
throw error;
|
|
@@ -237,10 +241,10 @@ export const handleLinkedInOAuth2Callback = async (params, baseUrl = DEFAULT_SER
|
|
|
237
241
|
const status = error.response.status;
|
|
238
242
|
// Expected errors
|
|
239
243
|
if (status === 403) {
|
|
240
|
-
throw new Error(`LinkedIn OAuth2 callback unauthorized: ${error.message}
|
|
244
|
+
throw new Error(`LinkedIn OAuth2 callback unauthorized: ${error.message}`, { cause: error });
|
|
241
245
|
}
|
|
242
246
|
// Unexpected status codes
|
|
243
|
-
throw new Error(`LinkedIn OAuth2 callback failed: ${status} - ${error.message}
|
|
247
|
+
throw new Error(`LinkedIn OAuth2 callback failed: ${status} - ${error.message}`, { cause: error });
|
|
244
248
|
}
|
|
245
249
|
// Re-throw other errors (network errors, etc.)
|
|
246
250
|
throw error;
|
|
@@ -298,10 +302,12 @@ export const handleOktaOAuth2Callback = async (params, baseUrl = DEFAULT_SERVICE
|
|
|
298
302
|
const status = error.response.status;
|
|
299
303
|
// Expected errors
|
|
300
304
|
if (status === 403) {
|
|
301
|
-
throw new Error(`Okta OAuth2 callback unauthorized: ${error.message}
|
|
305
|
+
throw new Error(`Okta OAuth2 callback unauthorized: ${error.message}`, {
|
|
306
|
+
cause: error,
|
|
307
|
+
});
|
|
302
308
|
}
|
|
303
309
|
// Unexpected status codes
|
|
304
|
-
throw new Error(`Okta OAuth2 callback failed: ${status} - ${error.message}
|
|
310
|
+
throw new Error(`Okta OAuth2 callback failed: ${status} - ${error.message}`, { cause: error });
|
|
305
311
|
}
|
|
306
312
|
// Re-throw other errors (network errors, etc.)
|
|
307
313
|
throw error;
|
package/lib/api/iam/secrets.js
CHANGED
|
@@ -32,7 +32,6 @@ export const createSecret = async (token, data, baseUrl = DEFAULT_SERVICE_URLS.I
|
|
|
32
32
|
validateToken(token);
|
|
33
33
|
validateRequiredString(data.name, 'Secret name');
|
|
34
34
|
validateRequiredString(data.value, 'Secret value');
|
|
35
|
-
// Base64 encode the value before sending to API
|
|
36
35
|
const requestBody = {
|
|
37
36
|
variant: data.variant || 'generic',
|
|
38
37
|
name: data.name,
|
|
@@ -132,7 +131,7 @@ export const getSecret = async (token, secretId, baseUrl = DEFAULT_SERVICE_URLS.
|
|
|
132
131
|
export const updateSecret = async (token, secretId, data, baseUrl = DEFAULT_SERVICE_URLS.IAM) => {
|
|
133
132
|
validateToken(token);
|
|
134
133
|
validateRequiredString(secretId, 'Secret ID');
|
|
135
|
-
//
|
|
134
|
+
// Secret values are opaque. Send exactly what the owner supplied.
|
|
136
135
|
const requestBody = { ...data };
|
|
137
136
|
if (data.value) {
|
|
138
137
|
requestBody.value = data.value;
|
|
@@ -10,8 +10,15 @@ import type { McpTask } from '../../models/McpTask';
|
|
|
10
10
|
* queryable after the process is gone.
|
|
11
11
|
*/
|
|
12
12
|
export declare const MCP_GATEWAY_SERVICE_NAME = "jupyter-mcp-server";
|
|
13
|
-
/**
|
|
14
|
-
|
|
13
|
+
/**
|
|
14
|
+
* The `service.name` a worker's relayed output is filed under.
|
|
15
|
+
*
|
|
16
|
+
* `mcp-worker` since the service was renamed to `datalayer-mcp-server`: the
|
|
17
|
+
* gateway names its workers, and a name carrying `jupyter` said the wrong
|
|
18
|
+
* thing about a process that serves Datalayer sandboxes as readily as a
|
|
19
|
+
* Jupyter server.
|
|
20
|
+
*/
|
|
21
|
+
export declare const MCP_WORKER_SERVICE_NAME = "mcp-worker";
|
|
15
22
|
/**
|
|
16
23
|
* The `service.name` the durable execution service exports under.
|
|
17
24
|
*
|
|
@@ -37,8 +37,15 @@ import { getDashboardData } from '../otel/dashboards.js';
|
|
|
37
37
|
* queryable after the process is gone.
|
|
38
38
|
*/
|
|
39
39
|
export const MCP_GATEWAY_SERVICE_NAME = 'jupyter-mcp-server';
|
|
40
|
-
/**
|
|
41
|
-
|
|
40
|
+
/**
|
|
41
|
+
* The `service.name` a worker's relayed output is filed under.
|
|
42
|
+
*
|
|
43
|
+
* `mcp-worker` since the service was renamed to `datalayer-mcp-server`: the
|
|
44
|
+
* gateway names its workers, and a name carrying `jupyter` said the wrong
|
|
45
|
+
* thing about a process that serves Datalayer sandboxes as readily as a
|
|
46
|
+
* Jupyter server.
|
|
47
|
+
*/
|
|
48
|
+
export const MCP_WORKER_SERVICE_NAME = 'mcp-worker';
|
|
42
49
|
/**
|
|
43
50
|
* The `service.name` the durable execution service exports under.
|
|
44
51
|
*
|
|
@@ -126,8 +133,10 @@ const attribute = (holder, name) => String(holder.attributes?.[name] ?? '');
|
|
|
126
133
|
const notBefore = (timestamp, since) => !since || !timestamp || timestamp >= since;
|
|
127
134
|
/** Whether an `mcp.request` span is a failed call in the availability sense. */
|
|
128
135
|
const isUnavailable = (span) => {
|
|
129
|
-
const status = attribute(span, 'http.response.status_code') ||
|
|
130
|
-
|
|
136
|
+
const status = attribute(span, 'http.response.status_code') ||
|
|
137
|
+
attribute(span, 'http.status_code');
|
|
138
|
+
const rpc = attribute(span, 'rpc.jsonrpc.error_code') ||
|
|
139
|
+
attribute(span, 'mcp.error.code');
|
|
131
140
|
return status.startsWith('5') || rpc === '-32001';
|
|
132
141
|
};
|
|
133
142
|
/**
|
|
@@ -150,10 +159,7 @@ export const summarizeServiceLevels = (data) => {
|
|
|
150
159
|
const tasks = byLabel(MCP_SERVICE_LEVEL_PANELS.tasksByStatus);
|
|
151
160
|
const terminal = TERMINAL_STATUSES.reduce((sum, status) => sum + (tasks[status] ?? 0), 0);
|
|
152
161
|
const p95Seconds = byLabel(MCP_SERVICE_LEVEL_PANELS.callDurationP95)[''];
|
|
153
|
-
const p95SandboxLaunchSeconds = Object.fromEntries(Object.entries(byLabel(MCP_SERVICE_LEVEL_PANELS.sandboxLaunchP95)).map(([provider, seconds]) => [
|
|
154
|
-
provider || 'unknown',
|
|
155
|
-
seconds,
|
|
156
|
-
]));
|
|
162
|
+
const p95SandboxLaunchSeconds = Object.fromEntries(Object.entries(byLabel(MCP_SERVICE_LEVEL_PANELS.sandboxLaunchP95)).map(([provider, seconds]) => [provider || 'unknown', seconds]));
|
|
157
163
|
return {
|
|
158
164
|
availability: totalCalls > 0 ? (totalCalls - failedCalls) / totalCalls : null,
|
|
159
165
|
p95CallDurationMs: p95Seconds === undefined ? null : p95Seconds * 1000,
|
|
@@ -186,8 +192,12 @@ export const summarizeRequestSpans = (spans, filters = {}) => {
|
|
|
186
192
|
const terminal = [...tasks.values()].filter(status => ['completed', 'failed', 'cancelled'].includes(status));
|
|
187
193
|
const completed = terminal.filter(status => status === 'completed').length;
|
|
188
194
|
return {
|
|
189
|
-
availability: selected.length > 0
|
|
190
|
-
|
|
195
|
+
availability: selected.length > 0
|
|
196
|
+
? (selected.length - unavailable) / selected.length
|
|
197
|
+
: null,
|
|
198
|
+
p95CallDurationMs: percentile(selected
|
|
199
|
+
.filter(span => !attribute(span, 'mcp.task.id'))
|
|
200
|
+
.map(span => span.duration_ms), 0.95),
|
|
191
201
|
taskSuccessRate: terminal.length > 0 ? completed / terminal.length : null,
|
|
192
202
|
p95SandboxLaunchSeconds: {},
|
|
193
203
|
samples: { calls: selected.length, tasks: terminal.length, launches: 0 },
|
|
@@ -202,7 +212,9 @@ export const fetchMcpMetrics = async (token, filters = {}, otelUrl = DEFAULT_SER
|
|
|
202
212
|
? undefined
|
|
203
213
|
: getDashboardData(token, MCP_SERVICE_LEVELS_DASHBOARD, { since: filters.since ? new Date(filters.since) : undefined }, otelUrl),
|
|
204
214
|
listMetricNames(token, otelUrl),
|
|
205
|
-
scoped
|
|
215
|
+
scoped
|
|
216
|
+
? listTraces(token, { serviceName: MCP_GATEWAY_SERVICE_NAME, limit }, otelUrl)
|
|
217
|
+
: undefined,
|
|
206
218
|
]);
|
|
207
219
|
const reported = new Set((names.data ?? []).map(row => row.metric_name));
|
|
208
220
|
const spans = traces?.data ?? [];
|
|
@@ -210,7 +222,9 @@ export const fetchMcpMetrics = async (token, filters = {}, otelUrl = DEFAULT_SER
|
|
|
210
222
|
filters,
|
|
211
223
|
reporting: MCP_METRIC_CATALOG.filter(name => reported.has(name)),
|
|
212
224
|
spans,
|
|
213
|
-
slis: levels
|
|
225
|
+
slis: levels
|
|
226
|
+
? summarizeServiceLevels(levels)
|
|
227
|
+
: summarizeRequestSpans(spans, filters),
|
|
214
228
|
readAt: new Date().toISOString(),
|
|
215
229
|
};
|
|
216
230
|
};
|
|
@@ -222,7 +236,9 @@ export const spanTree = (spans) => {
|
|
|
222
236
|
}
|
|
223
237
|
const roots = [];
|
|
224
238
|
for (const node of nodes.values()) {
|
|
225
|
-
const parent = node.span.parent_span_id
|
|
239
|
+
const parent = node.span.parent_span_id
|
|
240
|
+
? nodes.get(node.span.parent_span_id)
|
|
241
|
+
: undefined;
|
|
226
242
|
(parent ? parent.children : roots).push(node);
|
|
227
243
|
}
|
|
228
244
|
const byStart = (a, b) => a.span.start_time.localeCompare(b.span.start_time);
|
|
@@ -240,7 +256,12 @@ export const fetchRunTrace = async (token, task, otelUrl = DEFAULT_SERVICE_URLS.
|
|
|
240
256
|
}
|
|
241
257
|
const trace = await getTrace(token, task.traceId, otelUrl);
|
|
242
258
|
const spans = trace.data ?? [];
|
|
243
|
-
return {
|
|
259
|
+
return {
|
|
260
|
+
taskUid: task.uid,
|
|
261
|
+
traceId: task.traceId,
|
|
262
|
+
spans,
|
|
263
|
+
tree: spanTree(spans),
|
|
264
|
+
};
|
|
244
265
|
};
|
|
245
266
|
/**
|
|
246
267
|
* The spans of one trace, named directly.
|
|
@@ -262,6 +283,10 @@ export const fetchMcpLogs = async (token, task, options = {}, otelUrl = DEFAULT_
|
|
|
262
283
|
if (!task.traceId) {
|
|
263
284
|
return { taskUid: task.uid, traceId: '', records: [] };
|
|
264
285
|
}
|
|
265
|
-
const page = await queryLogs(token, {
|
|
286
|
+
const page = await queryLogs(token, {
|
|
287
|
+
traceId: task.traceId,
|
|
288
|
+
limit: options.limit ?? 200,
|
|
289
|
+
severity: options.severity,
|
|
290
|
+
}, otelUrl);
|
|
266
291
|
return { taskUid: task.uid, traceId: task.traceId, records: page.data ?? [] };
|
|
267
292
|
};
|
|
@@ -191,7 +191,7 @@ export class BrowserOAuthStrategy extends BaseAuthStrategy {
|
|
|
191
191
|
}
|
|
192
192
|
}
|
|
193
193
|
catch (error) {
|
|
194
|
-
throw new Error(`OAuth authentication failed: ${error instanceof Error ? error.message : String(error)}
|
|
194
|
+
throw new Error(`OAuth authentication failed: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
195
195
|
}
|
|
196
196
|
}
|
|
197
197
|
/**
|
|
@@ -75,7 +75,7 @@ export function IAMMixin(Base) {
|
|
|
75
75
|
catch (error) {
|
|
76
76
|
// Clear the invalid token
|
|
77
77
|
await this.setToken('');
|
|
78
|
-
throw new Error(`Invalid token: ${error instanceof Error ? error.message : 'Unknown error'}
|
|
78
|
+
throw new Error(`Invalid token: ${error instanceof Error ? error.message : 'Unknown error'}`, { cause: error });
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
81
|
/** Log out the current user. */
|
|
@@ -144,7 +144,7 @@ export function IAMMixin(Base) {
|
|
|
144
144
|
async checkIAMHealth() {
|
|
145
145
|
const startTime = Date.now();
|
|
146
146
|
const errors = [];
|
|
147
|
-
let status
|
|
147
|
+
let status;
|
|
148
148
|
let healthy = false;
|
|
149
149
|
try {
|
|
150
150
|
// Test basic connectivity and authentication by getting user profile
|
|
@@ -50,4 +50,4 @@ export type StripeCheckoutProps = {
|
|
|
50
50
|
/**
|
|
51
51
|
* Stripe checkout.
|
|
52
52
|
*/
|
|
53
|
-
export declare function StripeCheckout({ checkoutPortal, appearance, accountUid, showStatusUsageSummary, onCheckoutSuccess, }: StripeCheckoutProps): import("react").
|
|
53
|
+
export declare function StripeCheckout({ checkoutPortal, appearance, accountUid, showStatusUsageSummary, onCheckoutSuccess, }: StripeCheckoutProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
@@ -1067,7 +1067,7 @@ export function StripeCheckout({ checkoutPortal, appearance, accountUid, showSta
|
|
|
1067
1067
|
}, children: [_jsx(Button, { variant: "danger", onClick: () => void onConfirmCancelSubscription(), disabled: isCancelActionPending, leadingVisual: () => isCancelActionPending ? _jsx(Spinner, { size: "small" }) : undefined, children: isCancelActionPending
|
|
1068
1068
|
? 'Waiting for confirmation...'
|
|
1069
1069
|
: 'Confirm downgrade' }), _jsx(Button, { variant: "default", onClick: onAbortCancelView, disabled: isCancelActionPending, children: "Keep current plan" })] })] }))] }) })) : null;
|
|
1070
|
-
let view
|
|
1070
|
+
let view;
|
|
1071
1071
|
// While the Stripe payment form is shown, disable interaction with the
|
|
1072
1072
|
// status / plan picker cards behind it so the only available action is the
|
|
1073
1073
|
// "Cancel" button next to the form.
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { SxProp } from '@primer/react';
|
|
2
1
|
export interface IVisuallyHiddenProps {
|
|
3
2
|
isVisible?: boolean;
|
|
4
3
|
}
|
|
5
|
-
export declare const VisuallyHidden:
|
|
4
|
+
export declare const VisuallyHidden: any;
|
|
@@ -36,6 +36,12 @@ export const sandboxSharingUrl = (runtimesUrl, runtimeName) => {
|
|
|
36
36
|
if (!base || !name) {
|
|
37
37
|
return undefined;
|
|
38
38
|
}
|
|
39
|
-
|
|
39
|
+
// Trailing slashes trimmed by hand: a `/\/+$/` replace backtracks
|
|
40
|
+
// quadratically on a string of many slashes.
|
|
41
|
+
let end = base.length;
|
|
42
|
+
while (end > 0 && base[end - 1] === '/') {
|
|
43
|
+
end -= 1;
|
|
44
|
+
}
|
|
45
|
+
return `${base.slice(0, end)}/api/runtimes/v1/runtimes/${encodeURIComponent(name)}/sharing`;
|
|
40
46
|
};
|
|
41
47
|
export default sandboxSharingUrl;
|
|
@@ -76,7 +76,7 @@ export type IDatalayerCoreConfig = {
|
|
|
76
76
|
/**
|
|
77
77
|
* Jupyter MCP Server URL.
|
|
78
78
|
*/
|
|
79
|
-
|
|
79
|
+
datalayerMcpServerUrl: string;
|
|
80
80
|
/**
|
|
81
81
|
* OTEL (OpenTelemetry) API URL.
|
|
82
82
|
*
|
|
@@ -170,10 +170,10 @@ export declare class DatalayerConfiguration {
|
|
|
170
170
|
* Default configuration values for Datalayer
|
|
171
171
|
*/
|
|
172
172
|
/**
|
|
173
|
-
* Where a service lives when nothing says otherwise.
|
|
173
|
+
* Where a service lives when nothing says otherwise: the control plane.
|
|
174
174
|
*
|
|
175
|
-
*
|
|
176
|
-
*
|
|
175
|
+
* Kept under its old name for the callers that have it; the table every
|
|
176
|
+
* service is read from is `DEFAULT_PLANE_URLS` in `config/planes`.
|
|
177
177
|
*/
|
|
178
178
|
export declare const DEFAULT_DATALAYER_SERVICE_URL = "https://prod1.datalayer.run";
|
|
179
179
|
/**
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { Signal } from '@lumino/signaling';
|
|
6
6
|
import { coreStore } from '../state/index.js';
|
|
7
|
+
import { CONTROL_PLANE_URL, DEFAULT_PLANE_URLS, RUNTIMES_PLANE_URL, } from './planes.js';
|
|
7
8
|
export const FORCE_ACTIVATE_RUNTIMES_PLUGINS = false;
|
|
8
9
|
export class DatalayerConfiguration {
|
|
9
10
|
_configuration = coreStore.getState().configuration;
|
|
@@ -26,21 +27,20 @@ export class DatalayerConfiguration {
|
|
|
26
27
|
* Default configuration values for Datalayer
|
|
27
28
|
*/
|
|
28
29
|
/**
|
|
29
|
-
* Where a service lives when nothing says otherwise.
|
|
30
|
+
* Where a service lives when nothing says otherwise: the control plane.
|
|
30
31
|
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
32
|
+
* Kept under its old name for the callers that have it; the table every
|
|
33
|
+
* service is read from is `DEFAULT_PLANE_URLS` in `config/planes`.
|
|
33
34
|
*/
|
|
34
|
-
export const DEFAULT_DATALAYER_SERVICE_URL =
|
|
35
|
+
export const DEFAULT_DATALAYER_SERVICE_URL = CONTROL_PLANE_URL;
|
|
35
36
|
/**
|
|
36
37
|
* Where the Contents service lives when nothing says otherwise.
|
|
37
38
|
*
|
|
38
39
|
* Not the generic default: Contents runs on the runtimes plane, where the NFS that backs the Home Folder and Volumes lives.
|
|
39
40
|
*/
|
|
40
|
-
export const DEFAULT_DATALAYER_CONTENTS_URL =
|
|
41
|
+
export const DEFAULT_DATALAYER_CONTENTS_URL = RUNTIMES_PLANE_URL;
|
|
41
42
|
export const DEFAULT_DATALAYER_CONFIG = {
|
|
42
|
-
|
|
43
|
-
contentsUrl: DEFAULT_DATALAYER_CONTENTS_URL,
|
|
43
|
+
...DEFAULT_PLANE_URLS,
|
|
44
44
|
credits: 100,
|
|
45
45
|
cpuEnvironment: 'ai-agents-env',
|
|
46
46
|
gpuEnvironment: 'ai-env',
|
package/lib/config/index.d.ts
CHANGED
package/lib/config/index.js
CHANGED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where each Datalayer service lives when nothing says otherwise.
|
|
3
|
+
*
|
|
4
|
+
* Two planes. The control plane (`prod1`) holds identity, the library, the
|
|
5
|
+
* spaces and the platform's own services. The runtimes plane (`r1`) holds
|
|
6
|
+
* what runs close to compute: the runtimes, the scheduler, the agents, the
|
|
7
|
+
* contents that back the Home Folder — and inference, which moved there
|
|
8
|
+
* with the agents that call it.
|
|
9
|
+
*
|
|
10
|
+
* One table, imported by everything that needs a default host: the core
|
|
11
|
+
* store's initial configuration, the configuration helpers, and any host
|
|
12
|
+
* that wants to know where to point. It used to be a literal in each of
|
|
13
|
+
* those, and the examples' Makefile besides, so a service that changed plane
|
|
14
|
+
* was corrected in some places and not others — inference was still pinned
|
|
15
|
+
* to the control plane by the examples after it moved, and every in-page
|
|
16
|
+
* agent there failed to reach it.
|
|
17
|
+
*
|
|
18
|
+
* No imports, so anything may import it without a cycle.
|
|
19
|
+
*
|
|
20
|
+
* @module config/planes
|
|
21
|
+
*/
|
|
22
|
+
/** The control plane. */
|
|
23
|
+
export declare const CONTROL_PLANE_URL = "https://prod1.datalayer.run";
|
|
24
|
+
/** The runtimes plane. */
|
|
25
|
+
export declare const RUNTIMES_PLANE_URL = "https://r1.datalayer.run";
|
|
26
|
+
/** The MCP gateway, on its own host. */
|
|
27
|
+
export declare const MCP_SERVER_URL = "https://mcp.datalayer.run/mcp";
|
|
28
|
+
/** Every service's default host, by the configuration key that names it. */
|
|
29
|
+
export declare const DEFAULT_PLANE_URLS: {
|
|
30
|
+
readonly iamUrl: "https://prod1.datalayer.run";
|
|
31
|
+
readonly managerUrl: "https://prod1.datalayer.run";
|
|
32
|
+
readonly libraryUrl: "https://prod1.datalayer.run";
|
|
33
|
+
readonly spacerUrl: "https://prod1.datalayer.run";
|
|
34
|
+
readonly otelUrl: "https://prod1.datalayer.run";
|
|
35
|
+
readonly growthUrl: "https://prod1.datalayer.run";
|
|
36
|
+
readonly inboundsUrl: "https://prod1.datalayer.run";
|
|
37
|
+
readonly successUrl: "https://prod1.datalayer.run";
|
|
38
|
+
readonly supportUrl: "https://prod1.datalayer.run";
|
|
39
|
+
readonly contentsUrl: "https://r1.datalayer.run";
|
|
40
|
+
readonly runtimesUrl: "https://r1.datalayer.run";
|
|
41
|
+
readonly schedulerUrl: "https://r1.datalayer.run";
|
|
42
|
+
readonly aiAgentsUrl: "https://r1.datalayer.run";
|
|
43
|
+
readonly aiInferenceUrl: "https://r1.datalayer.run";
|
|
44
|
+
readonly datalayerMcpServerUrl: "https://mcp.datalayer.run/mcp";
|
|
45
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023-2025 Datalayer, Inc.
|
|
3
|
+
* Distributed under the terms of the Modified BSD License.
|
|
4
|
+
*/
|
|
5
|
+
/*
|
|
6
|
+
* Copyright (c) 2023-2026 Datalayer, Inc.
|
|
7
|
+
* Distributed under the terms of the Modified BSD License.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Where each Datalayer service lives when nothing says otherwise.
|
|
11
|
+
*
|
|
12
|
+
* Two planes. The control plane (`prod1`) holds identity, the library, the
|
|
13
|
+
* spaces and the platform's own services. The runtimes plane (`r1`) holds
|
|
14
|
+
* what runs close to compute: the runtimes, the scheduler, the agents, the
|
|
15
|
+
* contents that back the Home Folder — and inference, which moved there
|
|
16
|
+
* with the agents that call it.
|
|
17
|
+
*
|
|
18
|
+
* One table, imported by everything that needs a default host: the core
|
|
19
|
+
* store's initial configuration, the configuration helpers, and any host
|
|
20
|
+
* that wants to know where to point. It used to be a literal in each of
|
|
21
|
+
* those, and the examples' Makefile besides, so a service that changed plane
|
|
22
|
+
* was corrected in some places and not others — inference was still pinned
|
|
23
|
+
* to the control plane by the examples after it moved, and every in-page
|
|
24
|
+
* agent there failed to reach it.
|
|
25
|
+
*
|
|
26
|
+
* No imports, so anything may import it without a cycle.
|
|
27
|
+
*
|
|
28
|
+
* @module config/planes
|
|
29
|
+
*/
|
|
30
|
+
/** The control plane. */
|
|
31
|
+
export const CONTROL_PLANE_URL = 'https://prod1.datalayer.run';
|
|
32
|
+
/** The runtimes plane. */
|
|
33
|
+
export const RUNTIMES_PLANE_URL = 'https://r1.datalayer.run';
|
|
34
|
+
/** The MCP gateway, on its own host. */
|
|
35
|
+
export const MCP_SERVER_URL = 'https://mcp.datalayer.run/mcp';
|
|
36
|
+
/** Every service's default host, by the configuration key that names it. */
|
|
37
|
+
export const DEFAULT_PLANE_URLS = {
|
|
38
|
+
iamUrl: CONTROL_PLANE_URL,
|
|
39
|
+
managerUrl: CONTROL_PLANE_URL,
|
|
40
|
+
libraryUrl: CONTROL_PLANE_URL,
|
|
41
|
+
spacerUrl: CONTROL_PLANE_URL,
|
|
42
|
+
otelUrl: CONTROL_PLANE_URL,
|
|
43
|
+
growthUrl: CONTROL_PLANE_URL,
|
|
44
|
+
inboundsUrl: CONTROL_PLANE_URL,
|
|
45
|
+
successUrl: CONTROL_PLANE_URL,
|
|
46
|
+
supportUrl: CONTROL_PLANE_URL,
|
|
47
|
+
contentsUrl: RUNTIMES_PLANE_URL,
|
|
48
|
+
runtimesUrl: RUNTIMES_PLANE_URL,
|
|
49
|
+
schedulerUrl: RUNTIMES_PLANE_URL,
|
|
50
|
+
aiAgentsUrl: RUNTIMES_PLANE_URL,
|
|
51
|
+
aiInferenceUrl: RUNTIMES_PLANE_URL,
|
|
52
|
+
datalayerMcpServerUrl: MCP_SERVER_URL,
|
|
53
|
+
};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
3
2
|
export type BackdropContextType = {
|
|
4
3
|
closeBackdrop: () => void;
|
|
5
4
|
displayBackdrop: (nextBackdrop: any) => void;
|
|
@@ -19,9 +18,9 @@ export type IBackdropProviderProps = {
|
|
|
19
18
|
export declare function BackdropProvider({ children, zIndex, disableDarken, backdropSurface, }: IBackdropProviderProps): import("react").JSX.Element;
|
|
20
19
|
export declare namespace BackdropProvider {
|
|
21
20
|
var propTypes: {
|
|
22
|
-
children:
|
|
23
|
-
zIndex:
|
|
24
|
-
disableDarken:
|
|
25
|
-
backdropSurface:
|
|
21
|
+
children: any;
|
|
22
|
+
zIndex: any;
|
|
23
|
+
disableDarken: any;
|
|
24
|
+
backdropSurface: any;
|
|
26
25
|
};
|
|
27
26
|
}
|