@datalayer/core 1.2.19 → 1.2.21
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/lib/api/evals/client.d.ts +6 -6
- package/lib/api/evals/client.js +5 -5
- package/lib/api/evals/status.d.ts +3 -3
- package/lib/api/evals/status.js +3 -3
- package/lib/api/evals/types.d.ts +9 -9
- package/lib/api/iam/secrets.js +2 -2
- package/lib/api/iam/servicePrincipals.js +1 -1
- package/lib/api/iam/trials.js +1 -1
- package/lib/api/orchestration/generated.d.ts +12 -12
- package/lib/api/orchestration/generated.js +1 -1
- package/lib/api/orchestration/index.d.ts +2 -2
- package/lib/api/orchestration/index.js +2 -2
- package/lib/api/orchestration/lifecycle.d.ts +1 -1
- package/lib/api/orchestration/lifecycle.js +1 -1
- package/lib/api/scheduler/client.d.ts +1 -1
- package/lib/api/scheduler/client.js +1 -1
- package/lib/api/scheduler/types.d.ts +1 -1
- package/lib/api/spacer/comments.d.ts +1 -1
- package/lib/api/spacer/comments.js +1 -1
- package/lib/api/spacer/spaces.d.ts +1 -1
- package/lib/api/spacer/spaces.js +1 -1
- package/lib/components/avatars/UserAvatar.d.ts +10 -11
- package/lib/components/avatars/UserAvatar.js +23 -28
- package/lib/components/avatars/UserProfileAvatar.js +1 -1
- package/lib/components/avatars/avatarChoice.d.ts +42 -0
- package/lib/components/avatars/avatarChoice.js +65 -0
- package/lib/components/avatars/index.d.ts +1 -0
- package/lib/components/avatars/index.js +1 -0
- package/lib/components/collaboration/LiveEditorCollaborators.d.ts +3 -4
- package/lib/components/collaboration/LiveEditorCollaborators.js +7 -5
- package/lib/components/emoji/faceEmojis.js +48 -0
- package/lib/components/emoji/fluent/loaders.js +46 -0
- package/lib/components/emoji/fluent/svg/1f30a.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f30a.js +5 -0
- package/lib/components/emoji/fluent/svg/1f310.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f310.js +5 -0
- package/lib/components/emoji/fluent/svg/1f324.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f324.js +5 -0
- package/lib/components/emoji/fluent/svg/1f326.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f326.js +5 -0
- package/lib/components/emoji/fluent/svg/1f327.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f327.js +5 -0
- package/lib/components/emoji/fluent/svg/1f33e.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f33e.js +5 -0
- package/lib/components/emoji/fluent/svg/1f372.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f372.js +5 -0
- package/lib/components/emoji/fluent/svg/1f373.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f373.js +5 -0
- package/lib/components/emoji/fluent/svg/1f39b.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f39b.js +5 -0
- package/lib/components/emoji/fluent/svg/1f3ab.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f3ab.js +5 -0
- package/lib/components/emoji/fluent/svg/1f41b.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f41b.js +5 -0
- package/lib/components/emoji/fluent/svg/1f441.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f441.js +5 -0
- package/lib/components/emoji/fluent/svg/1f465.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f465.js +5 -0
- package/lib/components/emoji/fluent/svg/1f4b9.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f4b9.js +5 -0
- package/lib/components/emoji/fluent/svg/1f4be.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f4be.js +5 -0
- package/lib/components/emoji/fluent/svg/1f4c1.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f4c1.js +5 -0
- package/lib/components/emoji/fluent/svg/1f4c2.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f4c2.js +5 -0
- package/lib/components/emoji/fluent/svg/1f4c4.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f4c4.js +5 -0
- package/lib/components/emoji/fluent/svg/1f4d3.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f4d3.js +5 -0
- package/lib/components/emoji/fluent/svg/1f4d6.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f4d6.js +5 -0
- package/lib/components/emoji/fluent/svg/1f4dc.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f4dc.js +5 -0
- package/lib/components/emoji/fluent/svg/1f4e1.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f4e1.js +5 -0
- package/lib/components/emoji/fluent/svg/1f4e2.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f4e2.js +5 -0
- package/lib/components/emoji/fluent/svg/1f4e7.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f4e7.js +5 -0
- package/lib/components/emoji/fluent/svg/1f500.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f500.js +5 -0
- package/lib/components/emoji/fluent/svg/1f501.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f501.js +5 -0
- package/lib/components/emoji/fluent/svg/1f504.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f504.js +5 -0
- package/lib/components/emoji/fluent/svg/1f52d.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f52d.js +5 -0
- package/lib/components/emoji/fluent/svg/1f552.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f552.js +5 -0
- package/lib/components/emoji/fluent/svg/1f58b.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f58b.js +5 -0
- package/lib/components/emoji/fluent/svg/1f5b2.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f5b2.js +5 -0
- package/lib/components/emoji/fluent/svg/1f5c3.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f5c3.js +5 -0
- package/lib/components/emoji/fluent/svg/1f5d1.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f5d1.js +5 -0
- package/lib/components/emoji/fluent/svg/1f5dc.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f5dc.js +5 -0
- package/lib/components/emoji/fluent/svg/1f604.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f604.js +5 -0
- package/lib/components/emoji/fluent/svg/1f917.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f917.js +5 -0
- package/lib/components/emoji/fluent/svg/1f9d1-200d-2696.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1f9d1-200d-2696.js +5 -0
- package/lib/components/emoji/fluent/svg/1fa79.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1fa79.js +5 -0
- package/lib/components/emoji/fluent/svg/1fa9d.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1fa9d.js +5 -0
- package/lib/components/emoji/fluent/svg/1fa9f.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/1fa9f.js +5 -0
- package/lib/components/emoji/fluent/svg/23f3.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/23f3.js +5 -0
- package/lib/components/emoji/fluent/svg/2611.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/2611.js +5 -0
- package/lib/components/emoji/fluent/svg/2702.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/2702.js +5 -0
- package/lib/components/emoji/fluent/svg/270f.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/270f.js +5 -0
- package/lib/components/emoji/fluent/svg/2728.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/2728.js +5 -0
- package/lib/components/emoji/fluent/svg/2b1c.d.ts +2 -0
- package/lib/components/emoji/fluent/svg/2b1c.js +5 -0
- package/lib/components/principal/Principal.js +1 -1
- package/lib/components/principal/PrincipalAppearance.d.ts +24 -1
- package/lib/components/principal/PrincipalAppearance.js +105 -34
- package/lib/components/principal/PrincipalAvatar.d.ts +5 -7
- package/lib/components/principal/PrincipalAvatar.js +12 -18
- package/lib/components/principal/PrincipalDetailsOverlay.d.ts +4 -7
- package/lib/components/principal/PrincipalDetailsOverlay.js +2 -2
- package/lib/components/principal/PrincipalSwitcherMenu.js +1 -1
- package/lib/hooks/unlinkIAMProvider.d.ts +22 -0
- package/lib/hooks/unlinkIAMProvider.js +24 -0
- package/lib/hooks/useCache.d.ts +8 -1
- package/lib/hooks/useCache.js +37 -6
- package/lib/hooks/useNavigate.js +8 -2
- package/lib/models/IAMProviderLinked.d.ts +9 -0
- package/lib/models/IAMProviderLinked.js +34 -5
- package/lib/models/McpTask.d.ts +18 -1
- package/lib/models/McpTask.js +15 -0
- package/lib/models/Profile.d.ts +2 -2
- package/lib/models/Secret.d.ts +1 -1
- package/lib/models/Secret.js +1 -1
- package/lib/models/StartedBy.d.ts +1 -1
- package/lib/models/StartedBy.js +1 -1
- package/lib/models/User.js +5 -12
- package/lib/models/UserOnboarding.d.ts +9 -0
- package/lib/models/UserOnboarding.js +33 -0
- package/lib/portable/index.d.ts +3 -2
- package/lib/portable/index.js +4 -2
- package/lib/portable/states.d.ts +39 -0
- package/lib/portable/states.js +71 -0
- package/lib/state/substates/NavigationState.d.ts +5 -3
- package/lib/state/substates/NavigationState.js +12 -3
- package/lib/views/mcp/AlertDestinations.js +2 -2
- package/lib/views/mcp/ApprovalQueue.js +2 -2
- package/lib/views/mcp/EnterpriseConsole.js +2 -2
- package/lib/views/mcp/McpDashboard.js +2 -2
- package/lib/views/mcp/McpHome.js +4 -4
- package/lib/views/mcp/McpObservability.js +5 -5
- package/lib/views/mcp/NotebookRuns.js +2 -2
- package/lib/views/mcp/OrganizationUsage.js +2 -2
- package/lib/views/mcp/Policies.js +2 -2
- package/lib/views/mcp/RunDetail.d.ts +1 -1
- package/lib/views/mcp/RunDetail.js +4 -1
- package/lib/views/mcp/ScimProvisioning.js +2 -2
- package/lib/views/mcp/ToolAccess.js +2 -2
- package/lib/views/secrets/SecretNew.js +1 -1
- package/package.json +1 -1
- package/scripts/generate-orchestration-types.py +12 -12
|
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
2
2
|
import { useState } from 'react';
|
|
3
3
|
import { Button, Heading, Label, SegmentedControl, Spinner, Text, TextInput, } from '@primer/react';
|
|
4
4
|
import { Blankslate } from '@primer/react/experimental';
|
|
5
|
-
import { Box } from '@datalayer/primer-addons';
|
|
5
|
+
import { Box, Card } from '@datalayer/primer-addons';
|
|
6
6
|
import { SearchIcon, TelescopeIcon } from '@primer/octicons-react';
|
|
7
7
|
import { McpErrorBlankslate } from '../../components/mcp/index.js';
|
|
8
8
|
import { useMcpMetrics, useMcpTrace, useMcpWorkflowsHealth, useRunTrace, useTasks, } from '../../hooks/useMcp.js';
|
|
@@ -60,7 +60,7 @@ const SpanRow = ({ node, depth, }) => {
|
|
|
60
60
|
}, children: durationLabel(node.span.duration_ms) })] }), node.children.map(child => (_jsx(SpanRow, { node: child, depth: depth + 1 }, child.span.span_id)))] }));
|
|
61
61
|
};
|
|
62
62
|
/** A number the reader can act on, or a plain statement that it is not measured. */
|
|
63
|
-
const Sli = ({ label, value, note, }) => (_jsxs(
|
|
63
|
+
const Sli = ({ label, value, note, }) => (_jsxs(Card, { border: true, shadow: "none", display: "block", p: 3, minWidth: 0, children: [_jsx(Text, { sx: { display: 'block', fontSize: 3, fontWeight: 'bold' }, children: value }), _jsx(Text, { sx: { display: 'block', fontSize: 0, color: 'fg.muted' }, children: label }), note && (_jsx(Text, { sx: { display: 'block', fontSize: 0, color: 'fg.subtle' }, children: note }))] }));
|
|
64
64
|
/**
|
|
65
65
|
* What the durable engine's own report amounts to, in one line.
|
|
66
66
|
*
|
|
@@ -131,10 +131,10 @@ export const McpObservability = ({ errorState, routes, pane, onPaneChange, taskU
|
|
|
131
131
|
onSelect(/^[0-9a-f]{32}$/i.test(value)
|
|
132
132
|
? { trace: value }
|
|
133
133
|
: { task: value });
|
|
134
|
-
}, children: "Show the run" })] }), !taskUid && !traceId ? (_jsxs(Blankslate, { border: true, spacious: true, children: [_jsx(Blankslate.Visual, { children: _jsx(TelescopeIcon, { size: "medium" }) }), _jsx(Blankslate.Heading, { children: "Pick a run" }), _jsx(Blankslate.Description, { children: _jsx(Text, { sx: { textAlign: 'center' }, children: "Open a call from the audit log or the dashboard, or paste its task uid or trace id here, and its spans across the gateway, the policy check and the worker appear with the time each took." }) }), _jsx(Button, { size: "small", onClick: () => navigate(routes.audit), children: "Open the audit log" })] })) : run.isError ? (_jsx(McpErrorBlankslate, { state: errorState(run.error, 'This run'), onRetry: () => run.refetch() })) : run.isPending ? (_jsx(Box, { display: "flex", justifyContent: "center", py: 5, children: _jsx(Spinner, {}) })) : (run.data?.spans.length ?? 0) === 0 ? (_jsxs(Blankslate, { border: true, spacious: true, children: [_jsx(Blankslate.Visual, { children: _jsx(TelescopeIcon, { size: "medium" }) }), _jsx(Blankslate.Heading, { children: "No span for this call" }), _jsx(Blankslate.Description, { children: _jsx(Text, { sx: { textAlign: 'center' }, children: "Spans reach the collector a few seconds after the call and are kept for a short time. A call older than the retention window has an audit row but no trace." }) })] })) : (_jsxs(Box, { display: "grid", gap: 2, children: [_jsxs(Box, { display: "flex", gap: 3, alignItems: "center", flexWrap: "wrap", children: [_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', fontFamily: 'mono' }, children: run.data?.traceId }), _jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: [run.data?.spans.length, " spans"] }), _jsx(Button, { size: "small", onClick: () => navigate(`${routes.audit}?trace=${encodeURIComponent(run.data?.traceId ?? '')}`), children: "The audit row" })] }), _jsx(TraceTimeline, { tree: run.data?.tree ?? [] }), _jsx(
|
|
134
|
+
}, children: "Show the run" })] }), !taskUid && !traceId ? (_jsxs(Blankslate, { border: true, spacious: true, children: [_jsx(Blankslate.Visual, { children: _jsx(TelescopeIcon, { size: "medium" }) }), _jsx(Blankslate.Heading, { children: "Pick a run" }), _jsx(Blankslate.Description, { children: _jsx(Text, { sx: { textAlign: 'center' }, children: "Open a call from the audit log or the dashboard, or paste its task uid or trace id here, and its spans across the gateway, the policy check and the worker appear with the time each took." }) }), _jsx(Button, { size: "small", onClick: () => navigate(routes.audit), children: "Open the audit log" })] })) : run.isError ? (_jsx(McpErrorBlankslate, { state: errorState(run.error, 'This run'), onRetry: () => run.refetch() })) : run.isPending ? (_jsx(Box, { display: "flex", justifyContent: "center", py: 5, children: _jsx(Spinner, {}) })) : (run.data?.spans.length ?? 0) === 0 ? (_jsxs(Blankslate, { border: true, spacious: true, children: [_jsx(Blankslate.Visual, { children: _jsx(TelescopeIcon, { size: "medium" }) }), _jsx(Blankslate.Heading, { children: "No span for this call" }), _jsx(Blankslate.Description, { children: _jsx(Text, { sx: { textAlign: 'center' }, children: "Spans reach the collector a few seconds after the call and are kept for a short time. A call older than the retention window has an audit row but no trace." }) })] })) : (_jsxs(Box, { display: "grid", gap: 2, children: [_jsxs(Box, { display: "flex", gap: 3, alignItems: "center", flexWrap: "wrap", children: [_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', fontFamily: 'mono' }, children: run.data?.traceId }), _jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: [run.data?.spans.length, " spans"] }), _jsx(Button, { size: "small", onClick: () => navigate(`${routes.audit}?trace=${encodeURIComponent(run.data?.traceId ?? '')}`), children: "The audit row" })] }), _jsx(TraceTimeline, { tree: run.data?.tree ?? [] }), _jsx(Card, { border: true, shadow: "none", display: "block", overflowX: "auto", children: (run.data?.tree ?? []).map(node => (_jsx(SpanRow, { node: node, depth: 0 }, node.span.span_id))) })] }))] })), pane === 'live' && (_jsxs(Box, { display: "grid", gap: 3, children: [(() => {
|
|
135
135
|
const look = engineLook(engine.data, engine.isError);
|
|
136
136
|
const queues = engine.data?.queues ?? [];
|
|
137
|
-
return (_jsxs(
|
|
137
|
+
return (_jsxs(Card, { border: true, shadow: "none", p: 3, display: "grid", gap: 2, children: [_jsxs(Box, { display: "flex", gap: 2, alignItems: "center", flexWrap: "wrap", children: [_jsx(Heading, { as: "h3", sx: { fontSize: 1 }, children: "The durable engine" }), _jsx(Label, { size: "small", variant: look.variant, children: look.label }), engine.data?.engine && (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: engine.data.engine }))] }), look.note && (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: look.note })), queues.length > 0 && (_jsx(Box, { display: "grid", gap: 1, children: queues.map(queue => (_jsxs(Box, { display: "flex", gap: 2, alignItems: "center", fontSize: 0, children: [_jsx(Text, { sx: { fontFamily: 'mono' }, children: queue.name }), _jsxs(Text, { sx: { color: 'fg.muted' }, children: [queue.backlog, " waiting"] }), typeof queue.oldestWaitSeconds === 'number' && (_jsxs(Text, { sx: { color: 'fg.muted' }, children: ["oldest", ' ', durationLabel(queue.oldestWaitSeconds * 1000)] }))] }, queue.name))) }))] }));
|
|
138
138
|
})(), _jsxs(Box, { display: "grid", gap: 2, children: [_jsx(Heading, { as: "h3", sx: { fontSize: 1 }, children: "Running now" }), live.isError ? (_jsx(McpErrorBlankslate, { state: errorState(live.error, 'The running calls'), onRetry: () => live.refetch() })) : live.isPending ? (_jsx(Box, { display: "flex", justifyContent: "center", py: 4, children: _jsx(Spinner, {}) })) : (live.data?.items.length ?? 0) === 0 ? (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "Nothing of yours is running. A call that finishes inside its own request never appears here \u2014 it is over before this pane could draw it \u2014 and is found by its trace in Runs." })) : ((live.data?.items ?? []).map(task => (_jsxs(Box, { display: "flex", gap: 2, alignItems: "center", flexWrap: "wrap", py: 1, borderBottom: "1px solid", borderColor: "border.muted", children: [_jsx(Label, { size: "small", variant: "success", children: "Working" }), _jsx(Text, { sx: { fontSize: 0 }, children: task.tool || 'Run' }), _jsx(Text, { sx: {
|
|
139
139
|
fontSize: 0,
|
|
140
140
|
fontFamily: 'mono',
|
|
@@ -151,7 +151,7 @@ export const McpObservability = ({ errorState, routes, pane, onPaneChange, taskU
|
|
|
151
151
|
? 'Not measured'
|
|
152
152
|
: Object.entries(metrics.data?.slis.p95SandboxLaunchSeconds ?? {})
|
|
153
153
|
.map(([provider, seconds]) => `${provider} ${seconds.toFixed(1)}s`)
|
|
154
|
-
.join(' · '), note: `${metrics.data?.slis.samples.launches ?? 0} launches` })] }), _jsx(
|
|
154
|
+
.join(' · '), note: `${metrics.data?.slis.samples.launches ?? 0} launches` })] }), _jsx(Card, { border: true, shadow: "none", display: "block", overflowX: "auto", children: MCP_METRIC_CATALOG.map(name => {
|
|
155
155
|
const reporting = metrics.data?.reporting.includes(name) ?? false;
|
|
156
156
|
return (_jsxs(Box, { display: "flex", alignItems: "center", gap: 3, py: 1, px: 2, borderBottom: "1px solid", borderColor: "border.muted", children: [_jsx(Text, { sx: { fontSize: 0, fontFamily: 'mono', flex: 1 }, children: name }), _jsx(Text, { sx: {
|
|
157
157
|
fontSize: 0,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Heading, Label, Link, RelativeTime, Spinner, Text, } from '@primer/react';
|
|
3
|
-
import { Box } from '@datalayer/primer-addons';
|
|
3
|
+
import { Box, Card } from '@datalayer/primer-addons';
|
|
4
4
|
import { useNotebookTasks } from '../../hooks/useMcp.js';
|
|
5
5
|
import { RUN_STATUS_LOOK, isRunOver } from './RunDetail.js';
|
|
6
6
|
/**
|
|
@@ -29,7 +29,7 @@ export const NotebookRuns = ({ notebookUid, routes, limit = 20, }) => {
|
|
|
29
29
|
}
|
|
30
30
|
return (_jsxs(Box, { display: "grid", gap: 2, minWidth: 0, children: [_jsx(Heading, { as: "h3", sx: { fontSize: 1 }, children: "Runs" }), tasks.length === 0 ? (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "Nothing has run on this notebook yet. A tool call that outlives its request appears here while it runs." })) : (tasks.map(task => {
|
|
31
31
|
const look = RUN_STATUS_LOOK[task.status];
|
|
32
|
-
return (_jsxs(
|
|
32
|
+
return (_jsxs(Card, { border: true, shadow: "none", display: "grid", gap: 1, p: 2, borderColor: task.status === 'input_required'
|
|
33
33
|
? 'attention.emphasis'
|
|
34
34
|
: 'border.default', children: [_jsxs(Box, { display: "flex", gap: 2, alignItems: "center", children: [_jsx(Label, { size: "small", variant: look.variant, children: look.label }), _jsx(Text, { sx: { fontSize: 0 }, children: task.tool || 'Run' })] }), _jsxs(Box, { display: "flex", gap: 2, alignItems: "center", children: [_jsxs(Link, { href: `${routes.runs}/${encodeURIComponent(task.uid)}`, sx: { fontFamily: 'mono', fontSize: 0 }, children: [task.uid.slice(0, 16), "\u2026"] }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: _jsx(RelativeTime, { datetime: task.lastUpdatedAt }) })] })] }, task.uid));
|
|
35
35
|
}))] }));
|
|
@@ -2,7 +2,7 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
|
|
|
2
2
|
import { useMemo } from 'react';
|
|
3
3
|
import { Heading, Label, ProgressBar, Spinner, Text } from '@primer/react';
|
|
4
4
|
import { Blankslate, DataTable, Table } from '@primer/react/experimental';
|
|
5
|
-
import { Box } from '@datalayer/primer-addons';
|
|
5
|
+
import { Box, Card } from '@datalayer/primer-addons';
|
|
6
6
|
import { GraphIcon } from '@primer/octicons-react';
|
|
7
7
|
import { ClientBadge, McpErrorBlankslate } from '../../components/mcp/index.js';
|
|
8
8
|
import { useOrgMcpUsage } from '../../hooks/useMcp.js';
|
|
@@ -69,7 +69,7 @@ const QuotaCard = ({ label, hint, quota, }) => {
|
|
|
69
69
|
const limit = quota?.limit;
|
|
70
70
|
const used = quota?.used;
|
|
71
71
|
const fraction = quota?.fraction;
|
|
72
|
-
return (_jsxs(
|
|
72
|
+
return (_jsxs(Card, { border: true, shadow: "none", display: "block", p: 3, flex: "1 1 220px", minWidth: 0, children: [_jsx(Text, { sx: { fontWeight: 'bold', fontSize: 1 }, children: label }), _jsx(Box, { mt: 2, display: "flex", alignItems: "baseline", gap: 2, children: quota?.unknown ? (_jsx(Text, { sx: { fontSize: 2, color: 'fg.muted' }, children: "Not available" })) : (_jsxs(_Fragment, { children: [_jsx(Text, { sx: { fontSize: 4, fontWeight: 'bold' }, children: typeof used === 'number' ? amount(used) : '—' }), _jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: typeof limit === 'number'
|
|
73
73
|
? `of ${amount(limit)}`
|
|
74
74
|
: 'no limit set' })] })) }), typeof fraction === 'number' && (_jsx(Box, { mt: 2, children: _jsx(ProgressBar, { progress: Math.min(100, fraction * 100), barSize: "small", bg: `${quotaTone(fraction)}.emphasis`, "aria-label": `${label}: ${Math.round(fraction * 100)}% of the limit` }) })), _jsx(Text, { as: "p", sx: { mt: 2, mb: 0, fontSize: 0, color: 'fg.muted' }, children: quota?.unknown ? quota.unknown : hint })] }));
|
|
75
75
|
};
|
|
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
2
2
|
import { useMemo, useState } from 'react';
|
|
3
3
|
import { Heading, Label, Link, Select, Spinner, Text } from '@primer/react';
|
|
4
4
|
import { Blankslate, Table } from '@primer/react/experimental';
|
|
5
|
-
import { Box } from '@datalayer/primer-addons';
|
|
5
|
+
import { Box, Card } from '@datalayer/primer-addons';
|
|
6
6
|
import { ShieldCheckIcon } from '@primer/octicons-react';
|
|
7
7
|
import { McpErrorBlankslate } from '../../components/mcp/index.js';
|
|
8
8
|
import { useConnectedAgents, useEffectivePolicy } from '../../hooks/useMcp.js';
|
|
@@ -164,6 +164,6 @@ export const Policies = ({ errorState, routes, organizationName, showTitle = tru
|
|
|
164
164
|
color: 'fg.muted',
|
|
165
165
|
display: 'block',
|
|
166
166
|
mt: 1,
|
|
167
|
-
}, children: row.rule.reason }))] })] }, row.name))) })] })] }), _jsxs(Box, { display: "grid", gap: 3, children: [_jsx(ToolGroup, { title: "Read-only tools", description: "Tools that only look: listing, reading a cell, reading a source.", tools: readOnlyTools, organizationName: organizationName }), _jsx(ToolGroup, { title: "Tools that change things", description: "Tools that write to a notebook, a document or a source.", tools: writeTools, organizationName: organizationName }), _jsx(ToolGroup, { title: "Tools that launch or spend", description: "Tools that execute code, launch a sandbox or reserve compute.", tools: executeTools, organizationName: organizationName })] }), _jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: ["Your token carries ", policy.data?.scopes.length ?? 0, " scopes, which is the ceiling over every rule above:", ' ', (policy.data?.scopes ?? []).join(', ') || 'none', "."] })] })), _jsxs(
|
|
167
|
+
}, children: row.rule.reason }))] })] }, row.name))) })] })] }), _jsxs(Box, { display: "grid", gap: 3, children: [_jsx(ToolGroup, { title: "Read-only tools", description: "Tools that only look: listing, reading a cell, reading a source.", tools: readOnlyTools, organizationName: organizationName }), _jsx(ToolGroup, { title: "Tools that change things", description: "Tools that write to a notebook, a document or a source.", tools: writeTools, organizationName: organizationName }), _jsx(ToolGroup, { title: "Tools that launch or spend", description: "Tools that execute code, launch a sandbox or reserve compute.", tools: executeTools, organizationName: organizationName })] }), _jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: ["Your token carries ", policy.data?.scopes.length ?? 0, " scopes, which is the ceiling over every rule above:", ' ', (policy.data?.scopes ?? []).join(', ') || 'none', "."] })] })), _jsxs(Card, { border: true, shadow: "none", variant: "subtle", p: 3, display: "grid", gap: 1, children: [_jsx(Text, { sx: { fontSize: 1, fontWeight: 'semibold' }, children: "Your own rules" }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "Narrowing the defaults for your own agents \u2014 approval by tool, a daily credits cap, a denylist, the environments they may use \u2014 is edited here once the policy layers ship. When your agents act inside an organization, that organization's policy applies instead of yours." }), _jsx(Text, { sx: { fontSize: 1, fontWeight: 'semibold', mt: 2 }, children: "Organizations you own" }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "The policy form for each organization you own, with its history and a preview of what one agent would get, is the same form the organization's MCP tab carries. It joins this page with the layers." })] })] }));
|
|
168
168
|
};
|
|
169
169
|
export default Policies;
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
* @module views/mcp/RunDetail
|
|
27
27
|
*/
|
|
28
28
|
import type { JSX } from 'react';
|
|
29
|
-
import type
|
|
29
|
+
import { type McpTask, type McpTaskStatus } from '../../models/McpTask';
|
|
30
30
|
import type { McpSpanNode } from '../../api/mcp/observability';
|
|
31
31
|
import { type McpErrorStateFn, type McpRoutes } from './types';
|
|
32
32
|
/** How a run's status is drawn. Shared with the runs list. */
|
|
@@ -6,6 +6,7 @@ import { useNavigate } from 'react-router-dom';
|
|
|
6
6
|
import { McpErrorBlankslate } from '../../components/mcp/index.js';
|
|
7
7
|
import { useAnswerTask, useCancelTask, useRunTrace, useTask, useTaskEvents, } from '../../hooks/useMcp.js';
|
|
8
8
|
import { TraceTimelineSection } from './TraceTimeline.js';
|
|
9
|
+
import { taskFailureOf, } from '../../models/McpTask.js';
|
|
9
10
|
/** How a run's status is drawn. Shared with the runs list. */
|
|
10
11
|
export const RUN_STATUS_LOOK = {
|
|
11
12
|
working: { label: 'Working', variant: 'success' },
|
|
@@ -151,6 +152,8 @@ export const RunDetail = ({ taskUid, errorState, routes, mock = false, }) => {
|
|
|
151
152
|
return (_jsx(Box, { display: "flex", justifyContent: "center", p: 4, children: _jsx(Spinner, {}) }));
|
|
152
153
|
}
|
|
153
154
|
const task = mock ? SAMPLE_RUN : run.data;
|
|
155
|
+
// An empty object is no failure: the server sends `{}` while nothing failed.
|
|
156
|
+
const failure = taskFailureOf(task.error);
|
|
154
157
|
const look = RUN_STATUS_LOOK[task.status];
|
|
155
158
|
const over = isRunOver(task.status);
|
|
156
159
|
const output = outputTextOf(task);
|
|
@@ -159,6 +162,6 @@ export const RunDetail = ({ taskUid, errorState, routes, mock = false, }) => {
|
|
|
159
162
|
navigate(routes.runs);
|
|
160
163
|
}, sx: { fontSize: 0 }, children: "All runs" }), _jsx(Heading, { as: "h2", sx: { fontSize: 3, mt: 1, mb: 1 }, children: task.tool || 'Run' }), _jsxs(Box, { display: "flex", gap: 2, alignItems: "center", flexWrap: "wrap", children: [_jsx(Label, { size: "small", variant: look.variant, children: look.label }), _jsx(Text, { sx: { fontFamily: 'mono', fontSize: 0, color: 'fg.muted' }, children: task.uid }), _jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: ["updated ", _jsx(RelativeTime, { datetime: task.lastUpdatedAt })] })] }), task.statusMessage && (_jsx(Text, { as: "p", sx: { fontSize: 1, color: 'fg.muted', mt: 2 }, children: task.statusMessage }))] }), task.status === 'input_required' && (_jsxs(Box, { borderWidth: 1, borderStyle: "solid", borderColor: "attention.emphasis", borderRadius: 2, p: 3, display: "grid", gap: 2, children: [_jsx(Heading, { as: "h3", sx: { fontSize: 1 }, children: "This run is waiting on you" }), _jsx(Textarea, { "aria-label": "Your answer", value: reply, onChange: event => setReply(event.target.value), placeholder: "Your answer", rows: 3 }), _jsx(Box, { children: _jsx(Button, { variant: "primary", disabled: !reply.trim() || answer.isPending, onClick: () => answer.mutate({ taskUid: task.uid, input: { answer: reply } }, { onSuccess: () => setReply('') }), children: answer.isPending ? 'Answering…' : 'Answer' }) })] })), _jsxs(Box, { children: [_jsx(Heading, { as: "h3", sx: { fontSize: 1, mb: 2 }, children: "Output" }), output ? (_jsx(Box, { as: "pre", fontFamily: "mono", fontSize: 0, whiteSpace: "pre-wrap", overflowX: "auto", bg: "canvas.subtle", borderRadius: 2, p: 3, m: 0, children: output })) : (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: over
|
|
161
164
|
? 'This run printed nothing.'
|
|
162
|
-
: 'Nothing printed yet. Output appears here as it arrives.' }))] }),
|
|
165
|
+
: 'Nothing printed yet. Output appears here as it arrives.' }))] }), failure && (_jsxs(Box, { children: [_jsx(Heading, { as: "h3", sx: { fontSize: 1, mb: 2 }, children: "Why it failed" }), _jsx(Text, { sx: { fontFamily: 'mono', fontSize: 0, color: 'danger.fg' }, children: failure })] })), _jsx(TraceTimelineSection, { tree: mock ? SAMPLE_TRACE : (trace.data?.tree ?? []), traceId: mock ? SAMPLE_TRACE[0].span.trace_id : trace.data?.traceId, live: !over }), !over && (_jsxs(Box, { children: [_jsx(Button, { variant: "danger", disabled: cancel.isPending, onClick: () => cancel.mutate(task.uid), children: cancel.isPending ? 'Cancelling…' : 'Cancel this run' }), _jsx(Text, { as: "p", sx: { fontSize: 0, color: 'fg.muted', mt: 2 }, children: "Cancelling interrupts the work itself, so the sandbox stops being billed for it. What it has already printed is kept." })] }))] }));
|
|
163
166
|
};
|
|
164
167
|
export default RunDetail;
|
|
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
2
2
|
import { useMemo, useRef, useState } from 'react';
|
|
3
3
|
import { ActionList, ActionMenu, Button, Flash, FormControl, Heading, IconButton, Label, Spinner, Text, TextInput, } from '@primer/react';
|
|
4
4
|
import { Blankslate, DataTable, Dialog, Table, } from '@primer/react/experimental';
|
|
5
|
-
import { Box } from '@datalayer/primer-addons';
|
|
5
|
+
import { Box, Card } from '@datalayer/primer-addons';
|
|
6
6
|
import { KebabHorizontalIcon, PeopleIcon } from '@primer/octicons-react';
|
|
7
7
|
import { McpErrorBlankslate } from '../../components/mcp/index.js';
|
|
8
8
|
import { useCoreStore } from '../../state/index.js';
|
|
@@ -142,7 +142,7 @@ export const ScimProvisioning = ({ errorState, orgUid, readOnly = false, showTit
|
|
|
142
142
|
return (_jsx(McpErrorBlankslate, { state: errorState(tokens.error, 'SCIM provisioning'), onRetry: () => tokens.refetch() }));
|
|
143
143
|
}
|
|
144
144
|
const shown = SCIM_STATUS_MESSAGES[status.state];
|
|
145
|
-
return (_jsxs(Box, { display: "grid", gap: 3, minWidth: 0, children: [showTitle && (_jsxs(Box, { display: "flex", alignItems: "start", justifyContent: "space-between", gap: 3, children: [_jsxs(Box, { children: [_jsx(Heading, { as: "h2", sx: { fontSize: 3, mb: 1 }, children: "Directory provisioning" }), _jsx(Text, { as: "p", sx: { color: 'fg.muted', fontSize: 1, m: 0 }, children: "Over SCIM. Sign-in can only act on somebody who turns up; this is what removes the person who does not." })] }), !readOnly && (_jsx(Button, { variant: "primary", ref: returnFocusRef, onClick: openCreate, children: "New SCIM token" }))] })), tokens.isPending && !tokens.data ? (_jsx(Box, { display: "flex", justifyContent: "center", py: 5, children: _jsx(Spinner, {}) })) : (_jsxs(_Fragment, { children: [_jsxs(Flash, { variant: shown.variant, children: [_jsx(Text, { as: "p", sx: { fontWeight: 'semibold', m: 0 }, children: shown.heading }), _jsx(Text, { as: "p", sx: { fontSize: 1, mt: 1, mb: 0 }, children: shown.body }), status.lastUsedAt && (_jsxs(Text, { as: "p", sx: { fontSize: 1, mt: 1, mb: 0, color: 'fg.muted' }, children: ["Last provisioning call ", timeAgo(status.lastUsedAt), "."] }))] }), rows.length > 0 ? (_jsxs(_Fragment, { children: [_jsxs(Table.Container, { children: [_jsx(Table.Title, { as: "h3", id: "scim-tokens", children: "SCIM tokens" }), _jsx(Table.Subtitle, { as: "p", id: "scim-tokens-subtitle", children: "A revoked token is kept rather than deleted, so the provisioning it did stays attributable." }), _jsx(DataTable, { "aria-labelledby": "scim-tokens", "aria-describedby": "scim-tokens-subtitle", data: rows, columns: columns })] }), _jsxs(
|
|
145
|
+
return (_jsxs(Box, { display: "grid", gap: 3, minWidth: 0, children: [showTitle && (_jsxs(Box, { display: "flex", alignItems: "start", justifyContent: "space-between", gap: 3, children: [_jsxs(Box, { children: [_jsx(Heading, { as: "h2", sx: { fontSize: 3, mb: 1 }, children: "Directory provisioning" }), _jsx(Text, { as: "p", sx: { color: 'fg.muted', fontSize: 1, m: 0 }, children: "Over SCIM. Sign-in can only act on somebody who turns up; this is what removes the person who does not." })] }), !readOnly && (_jsx(Button, { variant: "primary", ref: returnFocusRef, onClick: openCreate, children: "New SCIM token" }))] })), tokens.isPending && !tokens.data ? (_jsx(Box, { display: "flex", justifyContent: "center", py: 5, children: _jsx(Spinner, {}) })) : (_jsxs(_Fragment, { children: [_jsxs(Flash, { variant: shown.variant, children: [_jsx(Text, { as: "p", sx: { fontWeight: 'semibold', m: 0 }, children: shown.heading }), _jsx(Text, { as: "p", sx: { fontSize: 1, mt: 1, mb: 0 }, children: shown.body }), status.lastUsedAt && (_jsxs(Text, { as: "p", sx: { fontSize: 1, mt: 1, mb: 0, color: 'fg.muted' }, children: ["Last provisioning call ", timeAgo(status.lastUsedAt), "."] }))] }), rows.length > 0 ? (_jsxs(_Fragment, { children: [_jsxs(Table.Container, { children: [_jsx(Table.Title, { as: "h3", id: "scim-tokens", children: "SCIM tokens" }), _jsx(Table.Subtitle, { as: "p", id: "scim-tokens-subtitle", children: "A revoked token is kept rather than deleted, so the provisioning it did stays attributable." }), _jsx(DataTable, { "aria-labelledby": "scim-tokens", "aria-describedby": "scim-tokens-subtitle", data: rows, columns: columns })] }), _jsxs(Card, { border: true, shadow: "none", p: 3, display: "grid", gap: 2, children: [_jsx(Text, { sx: { fontWeight: 'semibold', fontSize: 1 }, children: "What to give the directory" }), _jsxs(FormControl, { children: [_jsx(FormControl.Label, { children: "SCIM base URL" }), _jsx(TextInput, { block: true, readOnly: true, value: scimBaseUrl(iamUrl), "aria-describedby": "scim-base-url-note" }), _jsxs(FormControl.Caption, { id: "scim-base-url-note", children: ["Okta and Entra append ", _jsx("code", { children: "/Users" }), " themselves. Use the token as a bearer credential; the token is what says which organization is being provisioned, so nothing else names this one."] })] }), _jsxs(Text, { as: "p", sx: { fontSize: 0, color: 'fg.muted', m: 0 }, children: ["Groups are not provisioned over SCIM \u2014 this server answers them ", _jsx("code", { children: "501" }), " saying so. Roles come from the sign-in token\u2019s groups claim and the provider\u2019s role mappings, above; a second source of the same fact would eventually disagree with the first."] })] })] })) : (_jsxs(Blankslate, { border: true, spacious: true, children: [_jsx(Blankslate.Visual, { children: _jsx(PeopleIcon, { size: "medium" }) }), _jsx(Blankslate.Heading, { children: "No SCIM token" }), _jsx(Blankslate.Description, { children: _jsx(Text, { sx: { textAlign: 'center' }, children: "Issue one to let this organization\u2019s directory add people when they join and \u2014 the part sign-in cannot do \u2014 remove them when they leave." }) }), !readOnly && (_jsx(Button, { size: "small", onClick: openCreate, children: "New SCIM token" }))] }))] })), creating && (_jsx(Dialog, { title: "New SCIM token", onClose: () => setCreating(false), returnFocusRef: returnFocusRef, footerButtons: [
|
|
146
146
|
{
|
|
147
147
|
buttonType: 'default',
|
|
148
148
|
content: 'Cancel',
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useState } from 'react';
|
|
3
3
|
import { Button, Heading, Label, Spinner, Text, Truncate } from '@primer/react';
|
|
4
|
-
import { Box } from '@datalayer/primer-addons';
|
|
4
|
+
import { Box, Card } from '@datalayer/primer-addons';
|
|
5
5
|
import { McpErrorBlankslate } from '../../components/mcp/index.js';
|
|
6
6
|
import { useContentSources, useMcpSessions, useMcpTools, useRevokeMcpSession, } from '../../hooks/useContents.js';
|
|
7
7
|
/**
|
|
@@ -67,7 +67,7 @@ const SourceCard = ({ source, permissions, errorState, }) => {
|
|
|
67
67
|
const [revoking, setRevoking] = useState('');
|
|
68
68
|
const look = config ? APPROVAL_POLICY_LOOK[config.approvalPolicy] : undefined;
|
|
69
69
|
const offered = manifest.data?.tools?.length ?? 0;
|
|
70
|
-
return (_jsxs(
|
|
70
|
+
return (_jsxs(Card, { border: true, shadow: "none", p: 3, display: "grid", gap: 2, minWidth: 0, children: [_jsxs(Box, { display: "flex", gap: 2, alignItems: "center", flexWrap: "wrap", children: [_jsx(Heading, { as: "h3", sx: { fontSize: 1 }, children: source.name }), look && (_jsx(Label, { size: "small", variant: look.variant, children: look.label })), config?.transport && (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: config.transport }))] }), look && _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: look.note }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: sourceTools.length === 0
|
|
71
71
|
? 'No tool is allowed on this source, so an agent can call none of it.'
|
|
72
72
|
: `${sourceTools.length} of ${offered || sourceTools.length} tools allowed to agents.` }), sourceTools.length > 0 && (_jsx(Box, { display: "flex", gap: 1, flexWrap: "wrap", children: [...sourceTools].sort().map(tool => (_jsx(Label, { size: "small", variant: "accent", children: tool }, tool))) })), _jsxs(Box, { children: [_jsx(Heading, { as: "h4", sx: { fontSize: 0, color: 'fg.muted', mb: 1 }, children: "Open sessions" }), sessions.isError ? (_jsx(McpErrorBlankslate, { state: errorState(sessions.error, 'The sessions'), onRetry: () => sessions.refetch() })) : sessions.isPending ? (_jsx(Spinner, { size: "small" })) : (sessions.data?.items.length ?? 0) === 0 ? (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "No agent has opened this source." })) : ((sessions.data?.items ?? []).map(session => (_jsx(SessionRow, { session: session, sourceTools: sourceTools,
|
|
73
73
|
// Revoking a session withdraws an agent's access to this
|
|
@@ -77,7 +77,7 @@ export const SecretNew = ({ secretsListRoute = '/settings/secrets', } = {}) => {
|
|
|
77
77
|
name: formValues.name,
|
|
78
78
|
description: formValues.description,
|
|
79
79
|
// As it is: a secret has one representation end to end
|
|
80
|
-
// (
|
|
80
|
+
// (E3-05). This used to `btoa` and nothing on the read
|
|
81
81
|
// side undid it, so a build secret arrived at its build encoded and
|
|
82
82
|
// opened nothing.
|
|
83
83
|
value: formValues.value,
|
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
Generate deterministic TypeScript types from the canonical orchestration models.
|
|
7
7
|
|
|
8
8
|
The pydantic models in ``datalayer_core/orchestration`` are the source of
|
|
9
|
-
truth
|
|
9
|
+
truth and ``src/api/orchestration/generated.ts``
|
|
10
10
|
is what they say, in TypeScript, for the browser and the app. This is the
|
|
11
11
|
``generate-contents-types.py`` and ``generate-mcp-types.py`` pattern with two
|
|
12
12
|
documents rather than one:
|
|
@@ -24,19 +24,19 @@ documents rather than one:
|
|
|
24
24
|
What is written:
|
|
25
25
|
|
|
26
26
|
- one ``interface`` per model and one ``type`` per shared vocabulary, camel
|
|
27
|
-
case on the wire because the
|
|
27
|
+
case on the wire because the model is written that way
|
|
28
28
|
and because a browser that has to convert is a browser that can convert
|
|
29
29
|
wrongly;
|
|
30
30
|
- ``ORCHESTRATION_LIFECYCLE``: the states, the terminal states and the
|
|
31
|
-
transition table
|
|
31
|
+
transition table, so the TypeScript state machine (O0-02)
|
|
32
32
|
reads the same data the Python one does rather than a copy of it;
|
|
33
33
|
- ``ORCHESTRATION_COMMANDS``: the twelve commands and which of them mutate,
|
|
34
|
-
so that "every mutating command carries an idempotency key"
|
|
34
|
+
so that "every mutating command carries an idempotency key" is one
|
|
35
35
|
fact in one place;
|
|
36
|
-
- ``ORCHESTRATION_ACKNOWLEDGEMENT_ORDER``: the five milestones
|
|
36
|
+
- ``ORCHESTRATION_ACKNOWLEDGEMENT_ORDER``: the five milestones, in
|
|
37
37
|
order, because "has it reached acceptance yet" is a comparison;
|
|
38
|
-
- ``ORCHESTRATION_LIMITS``: the default depth, fan-out and retry limits
|
|
39
|
-
|
|
38
|
+
- ``ORCHESTRATION_LIMITS``: the default depth, fan-out and retry limits,
|
|
39
|
+
read from the models' own defaults;
|
|
40
40
|
- ``ORCHESTRATION_FIELDS``: which fields each model has, and which model
|
|
41
41
|
each nested one holds. TypeScript
|
|
42
42
|
types vanish at runtime and ``src/**/__tests__`` is outside the tsconfig,
|
|
@@ -630,7 +630,7 @@ def _api(paths: dict[str, Any]) -> list[str]:
|
|
|
630
630
|
|
|
631
631
|
def _lifecycle() -> list[str]:
|
|
632
632
|
"""
|
|
633
|
-
Render the lifecycle
|
|
633
|
+
Render the lifecycle as data (O0-02).
|
|
634
634
|
|
|
635
635
|
Returns
|
|
636
636
|
-------
|
|
@@ -651,7 +651,7 @@ def _lifecycle() -> list[str]:
|
|
|
651
651
|
"transitions": transitions,
|
|
652
652
|
}
|
|
653
653
|
return [
|
|
654
|
-
"/** The lifecycle
|
|
654
|
+
"/** The lifecycle: what a state accepts, and where it leads. */",
|
|
655
655
|
"export interface OrchestrationLifecycle {",
|
|
656
656
|
f"{INDENT}readonly initial: ExecutionState;",
|
|
657
657
|
f"{INDENT}readonly states: readonly ExecutionState[];",
|
|
@@ -693,7 +693,7 @@ def _commands() -> list[str]:
|
|
|
693
693
|
"ORCHESTRATION_COMMANDS", "readonly OrchestrationCommand[]", commands
|
|
694
694
|
),
|
|
695
695
|
"",
|
|
696
|
-
"/** The five milestones
|
|
696
|
+
"/** The five milestones, in the order they are reached. */",
|
|
697
697
|
*_declare(
|
|
698
698
|
"ORCHESTRATION_ACKNOWLEDGEMENT_ORDER",
|
|
699
699
|
"readonly AcknowledgementKind[]",
|
|
@@ -705,7 +705,7 @@ def _commands() -> list[str]:
|
|
|
705
705
|
|
|
706
706
|
def _limits() -> list[str]:
|
|
707
707
|
"""
|
|
708
|
-
Render the default delegation and retry limits
|
|
708
|
+
Render the default delegation and retry limits.
|
|
709
709
|
|
|
710
710
|
Returns
|
|
711
711
|
-------
|
|
@@ -717,7 +717,7 @@ def _limits() -> list[str]:
|
|
|
717
717
|
"retry": RetryPolicy().to_wire(),
|
|
718
718
|
}
|
|
719
719
|
return [
|
|
720
|
-
"/** The default limits
|
|
720
|
+
"/** The default limits, read from the models' own defaults. */",
|
|
721
721
|
"export interface OrchestrationLimits {",
|
|
722
722
|
f"{INDENT}readonly delegation: DelegationLimits;",
|
|
723
723
|
f"{INDENT}readonly retry: RetryPolicy;",
|