@opengeni/react 0.12.0 → 0.15.0
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 +20 -14
- package/dist/chunk-TOJR776I.js +2280 -0
- package/dist/chunk-TOJR776I.js.map +1 -0
- package/dist/index.d.ts +1040 -363
- package/dist/index.js +10938 -6281
- package/dist/index.js.map +1 -1
- package/dist/{machines-BeZ3bD3t.d.ts → machines-BpdwuQcD.d.ts} +134 -14
- package/dist/machines.d.ts +1 -1
- package/dist/machines.js +23 -1
- package/package.json +20 -12
- package/src/approvals.ts +16 -4
- package/src/client.ts +41 -5
- package/src/commands/index.ts +1 -7
- package/src/commands/registry.ts +46 -12
- package/src/components/chat-composer.tsx +417 -69
- package/src/components/code-editor.tsx +28 -36
- package/src/components/command-palette.tsx +26 -5
- package/src/components/desktop-viewer.tsx +29 -16
- package/src/components/diff-view.tsx +27 -189
- package/src/components/enrollment-consent.tsx +28 -10
- package/src/components/enrollment-device-flow.tsx +8 -5
- package/src/components/file-browser.tsx +190 -56
- package/src/components/fleet-tile.tsx +13 -4
- package/src/components/machine-card.tsx +93 -15
- package/src/components/machine-dock-bar.tsx +20 -8
- package/src/components/machine-health-pill.tsx +68 -0
- package/src/components/machine-metrics.tsx +28 -19
- package/src/components/machine-status-pill.tsx +26 -5
- package/src/components/machines/health.ts +146 -0
- package/src/components/machines/machine-detail.tsx +220 -0
- package/src/components/machines/metric-history-chart.tsx +298 -0
- package/src/components/machines/metric-sparkline.tsx +76 -0
- package/src/components/machines/series.ts +113 -0
- package/src/components/machines-dashboard.tsx +21 -3
- package/src/components/markdown.tsx +39 -9
- package/src/components/message-timeline.tsx +633 -109
- package/src/components/pierre-diff.tsx +83 -15
- package/src/components/pierre-file.tsx +10 -9
- package/src/components/queue-surface.tsx +578 -0
- package/src/components/sandbox-files.tsx +193 -225
- package/src/components/sandbox-terminal.tsx +256 -88
- package/src/components/sandbox-workspace.tsx +957 -0
- package/src/components/session-status.tsx +22 -2
- package/src/components/workbench-changes.tsx +585 -0
- package/src/components/workspace-dock.tsx +213 -59
- package/src/hooks/internal.ts +5 -2
- package/src/hooks/use-available-models.ts +7 -2
- package/src/hooks/use-billing-usage.ts +4 -1
- package/src/hooks/use-codex-accounts.ts +74 -44
- package/src/hooks/use-composer.ts +414 -63
- package/src/hooks/use-environments.ts +92 -47
- package/src/hooks/use-file-attachments.ts +101 -55
- package/src/hooks/use-goal.ts +52 -16
- package/src/hooks/use-machine-chip.ts +134 -0
- package/src/hooks/use-machines.ts +34 -16
- package/src/hooks/use-packs.ts +24 -19
- package/src/hooks/use-relay-frame-stream.ts +5 -2
- package/src/hooks/use-rigs.ts +335 -0
- package/src/hooks/use-sandbox-files.ts +213 -39
- package/src/hooks/use-sandbox-git.ts +188 -11
- package/src/hooks/use-sandbox-terminal.ts +18 -14
- package/src/hooks/use-scheduled-tasks.ts +10 -2
- package/src/hooks/use-session-capabilities.ts +77 -20
- package/src/hooks/use-session-control.ts +50 -23
- package/src/hooks/use-session-events.ts +50 -21
- package/src/hooks/use-session-lineage.ts +128 -0
- package/src/hooks/use-session.ts +53 -30
- package/src/hooks/use-slash-commands.ts +6 -4
- package/src/hooks/use-turn-queue.ts +202 -147
- package/src/hooks/use-windowed-sections.ts +204 -0
- package/src/hooks/use-workspace-capture.ts +233 -0
- package/src/hooks/use-workspace-edit.ts +231 -0
- package/src/hooks/use-workspace-sessions.ts +48 -5
- package/src/hooks/use-workspaces.ts +18 -15
- package/src/index.ts +133 -23
- package/src/lib/format.ts +3 -3
- package/src/lib/xterm-renderer.ts +65 -0
- package/src/lib/xterm-theme.ts +224 -18
- package/src/machines.ts +29 -3
- package/src/provider.tsx +195 -6
- package/src/timeline/activity-rail.tsx +213 -54
- package/src/timeline/disclosure-context.tsx +12 -2
- package/src/timeline/index.ts +21 -2
- package/src/timeline/parsers.ts +87 -16
- package/src/timeline/projection.ts +412 -87
- package/src/timeline/shared.tsx +111 -24
- package/src/timeline/tool-diff.tsx +24 -20
- package/src/timeline/tool-renderers.tsx +98 -21
- package/src/timeline/turn-summary.tsx +76 -23
- package/src/timeline/types.ts +96 -12
- package/styles/index.css +22 -0
- package/styles/tokens.css +2 -2
- package/dist/chunk-5TIXRCSI.js +0 -1291
- package/dist/chunk-5TIXRCSI.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { OpenGeniClient, MachineState, MetricSample, MachineView, MachineKind, MachinesResponse } from '@opengeni/sdk';
|
|
1
|
+
import { OpenGeniClient, WorkspaceControlEvent, StreamConnectionState, MachineState, MetricSample, MachineView, MachineKind, MachinesResponse } from '@opengeni/sdk';
|
|
2
2
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
3
|
import { ReactNode } from 'react';
|
|
4
4
|
|
|
@@ -7,22 +7,27 @@ import { ReactNode } from 'react';
|
|
|
7
7
|
* pass the real SDK client, a proxy-backed client that routes through their
|
|
8
8
|
* own API, or a scripted client in tests/demos.
|
|
9
9
|
*/
|
|
10
|
-
type SessionClientLike = Pick<OpenGeniClient, "getClientConfig" | "getSession" | "updateSession" | "listSessions" | "sendMessage" | "steerMessage" | "
|
|
10
|
+
type SessionClientLike = Pick<OpenGeniClient, "getClientConfig" | "getSession" | "getSessionLineage" | "updateSession" | "updateSessionPin" | "listSessions" | "listSessionPage" | "sendMessage" | "steerMessage" | "pauseSession" | "resumeSession" | "sendApprovalDecision" | "listEvents" | "streamEvents" | "getQueue" | "moveQueueItem" | "editQueueItem" | "steerQueueItem" | "deleteQueueItem" | "getComposerDraft" | "saveComposerDraft" | "listTurns" | "getGoal" | "updateGoal" | "deleteGoal" | "clearSessionContext" | "compactSessionContext" | "listScheduledTasks" | "uploadFile" | "getFile" | "createFileDownloadUrl" | "listVariableSets" | "createVariableSet" | "updateVariableSet" | "deleteVariableSet" | "setVariableSetVariable" | "deleteVariableSetVariable" | "listEnvironments" | "createEnvironment" | "updateEnvironment" | "deleteEnvironment" | "setEnvironmentVariable" | "deleteEnvironmentVariable" | "listRigs" | "createRig" | "getRig" | "updateRig" | "deleteRig" | "listRigVersions" | "activateRigVersion" | "listRigChanges" | "proposeRigChange" | "getRigChange" | "verifyRigChange" | "promoteRigChange" | "verifyRig" | "listPacks" | "registerPack" | "enablePack" | "deletePack" | "listWorkspaces" | "createWorkspace" | "updateWorkspace" | "setWorkspaceInferenceState" | "getWorkspace" | "listWorkspaceControlEvents" | "streamWorkspaceControlEvents" | "getBillingUsage" | "getClientConfig" | "getStreamCapabilities" | "acknowledgeStream" | "attachViewer" | "heartbeatViewer" | "detachViewer" | "fsList" | "fsRead" | "fsWrite" | "fsDelete" | "fsMove" | "fsMkdir" | "gitStatus" | "gitDiff" | "getWorkspaceCapture" | "getWorkspaceCaptureFile" | "terminalExec" | "terminalPtyOpen" | "terminalPtyWrite" | "terminalPtyResize" | "terminalPtyClose">;
|
|
11
11
|
|
|
12
12
|
type OpenGeniContextValue = {
|
|
13
13
|
client: SessionClientLike;
|
|
14
14
|
workspaceId: string;
|
|
15
|
+
workspaceControlEvent: WorkspaceControlEvent | null;
|
|
16
|
+
workspaceControlConnectionState: StreamConnectionState | "idle" | "error";
|
|
17
|
+
registerSessionReconciler: (sessionId: string, key: string, reconcile: () => Promise<void>) => () => void;
|
|
18
|
+
reconcileSession: (sessionId: string) => Promise<void>;
|
|
15
19
|
};
|
|
16
20
|
type OpenGeniProviderProps = {
|
|
17
21
|
client: SessionClientLike;
|
|
18
22
|
workspaceId: string;
|
|
23
|
+
onWorkspaceControlEvent?: ((event: WorkspaceControlEvent) => void) | undefined;
|
|
19
24
|
children?: ReactNode;
|
|
20
25
|
};
|
|
21
26
|
/**
|
|
22
27
|
* Supplies the OpenGeni client + workspace to all hooks below it. Hooks also
|
|
23
28
|
* accept `{ client, workspaceId }` overrides per call for multi-workspace UIs.
|
|
24
29
|
*/
|
|
25
|
-
declare function OpenGeniProvider({ client, workspaceId, children }: OpenGeniProviderProps): react_jsx_runtime.JSX.Element;
|
|
30
|
+
declare function OpenGeniProvider({ client, workspaceId, onWorkspaceControlEvent, children, }: OpenGeniProviderProps): react_jsx_runtime.JSX.Element;
|
|
26
31
|
type ClientOverride = {
|
|
27
32
|
client?: SessionClientLike | undefined;
|
|
28
33
|
workspaceId?: string | undefined;
|
|
@@ -76,7 +81,7 @@ type ConnectionStatusPillProps = {
|
|
|
76
81
|
* the Machines dashboard, the dock header, and the session timeline. Reconnecting
|
|
77
82
|
* breathes (the resiliency-as-headline blip), online/offline hold still.
|
|
78
83
|
*/
|
|
79
|
-
declare function ConnectionStatusPill({ status, label, size, className }: ConnectionStatusPillProps): react_jsx_runtime.JSX.Element;
|
|
84
|
+
declare function ConnectionStatusPill({ status, label, size, className, }: ConnectionStatusPillProps): react_jsx_runtime.JSX.Element;
|
|
80
85
|
type ConnectionDotProps = {
|
|
81
86
|
status: ConnectionStatus;
|
|
82
87
|
className?: string | undefined;
|
|
@@ -97,7 +102,7 @@ type MachineStatusPillProps = {
|
|
|
97
102
|
* dashboard row, the dock header, and the timeline all reuse so the status
|
|
98
103
|
* language is identical everywhere.
|
|
99
104
|
*/
|
|
100
|
-
declare function MachineStatusPill({ state, sharedSessionCount, size, className }: MachineStatusPillProps): react_jsx_runtime.JSX.Element;
|
|
105
|
+
declare function MachineStatusPill({ state, sharedSessionCount, size, className, }: MachineStatusPillProps): react_jsx_runtime.JSX.Element;
|
|
101
106
|
|
|
102
107
|
type MachineMetricsProps = {
|
|
103
108
|
/** The latest metric sample, or null when the machine hasn't reported yet. */
|
|
@@ -120,15 +125,124 @@ type MachineCardProps = {
|
|
|
120
125
|
onAttach?: ((machine: MachineView) => void) | undefined;
|
|
121
126
|
/** Whether an attach/swap is currently in flight (disables the affordance). */
|
|
122
127
|
attaching?: boolean | undefined;
|
|
128
|
+
/** Short recent history (e.g. 15m) — drives the card's CPU trend + preview. */
|
|
129
|
+
series?: MetricSample[] | undefined;
|
|
130
|
+
/** Open the full per-machine telemetry detail. Makes the whole card actionable. */
|
|
131
|
+
onOpenDetail?: ((machine: MachineView) => void) | undefined;
|
|
132
|
+
now?: number | undefined;
|
|
123
133
|
className?: string | undefined;
|
|
124
134
|
};
|
|
125
135
|
/**
|
|
126
|
-
* One machine in the Machines dashboard: name + kind + OS/arch, the
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
*
|
|
136
|
+
* One machine in the Machines dashboard: name + kind + OS/arch, the fused HEALTH
|
|
137
|
+
* verdict, latest resource meters, a CPU trend that previews the history, live
|
|
138
|
+
* freshness, and attach/swap. The whole card opens the telemetry detail when
|
|
139
|
+
* `onOpenDetail` is wired. The session's active sandbox carries an accent edge.
|
|
130
140
|
*/
|
|
131
|
-
declare function MachineCard({ machine, onAttach, attaching, className }: MachineCardProps): react_jsx_runtime.JSX.Element;
|
|
141
|
+
declare function MachineCard({ machine, onAttach, attaching, series, onOpenDetail, now, className, }: MachineCardProps): react_jsx_runtime.JSX.Element;
|
|
142
|
+
|
|
143
|
+
type MachineHealthPillProps = {
|
|
144
|
+
state: MachineState;
|
|
145
|
+
metrics: MetricSample | null;
|
|
146
|
+
now?: number | undefined;
|
|
147
|
+
size?: "sm" | "md" | undefined;
|
|
148
|
+
className?: string | undefined;
|
|
149
|
+
};
|
|
150
|
+
declare function MachineHealthPill({ state, metrics, now, size, className, }: MachineHealthPillProps): react_jsx_runtime.JSX.Element;
|
|
151
|
+
|
|
152
|
+
type HealthLevel = "healthy" | "degraded" | "critical" | "offline" | "unknown";
|
|
153
|
+
type HealthVerdict = {
|
|
154
|
+
level: HealthLevel;
|
|
155
|
+
/** Title-case label for the pill ("Healthy", "Under load", "Critical", …). */
|
|
156
|
+
label: string;
|
|
157
|
+
/** One short human clause naming the dominant cause ("Memory 94%", "No display"…). */
|
|
158
|
+
reason: string;
|
|
159
|
+
/** The latest sample is older than we'd expect from a live agent (~5s cadence). */
|
|
160
|
+
stale: boolean;
|
|
161
|
+
};
|
|
162
|
+
/** Fold a machine's reachability + latest sample + wall-clock into one verdict. */
|
|
163
|
+
declare function deriveHealth(state: MachineState, metrics: MetricSample | null, now?: number): HealthVerdict;
|
|
164
|
+
/**
|
|
165
|
+
* The token color ramp for a health level. Green/amber/red/grey is the
|
|
166
|
+
* universally-legible traffic model; we reserve it for the HEALTH verdict
|
|
167
|
+
* specifically (per-resource meters keep their own ramp in `machine-metrics`).
|
|
168
|
+
*/
|
|
169
|
+
declare const HEALTH_TOKEN: Record<HealthLevel, {
|
|
170
|
+
text: string;
|
|
171
|
+
dot: string;
|
|
172
|
+
soft: string;
|
|
173
|
+
}>;
|
|
174
|
+
/** Live/transient levels breathe; settled levels hold still. */
|
|
175
|
+
declare function healthPulses(level: HealthLevel): boolean;
|
|
176
|
+
|
|
177
|
+
type SeriesPoint = {
|
|
178
|
+
t: number;
|
|
179
|
+
v: number | null;
|
|
180
|
+
};
|
|
181
|
+
type MetricHistoryChartProps = {
|
|
182
|
+
points: SeriesPoint[];
|
|
183
|
+
/** Fixed ceiling (100 for %) or "auto" to fit the data with headroom. */
|
|
184
|
+
yMax?: number | "auto";
|
|
185
|
+
yMin?: number;
|
|
186
|
+
/** Format a value for the axis + readout (default: rounded + unit). */
|
|
187
|
+
format?: (v: number) => string;
|
|
188
|
+
unit?: string;
|
|
189
|
+
/** Stroke/fill hue — any CSS color; pass a token var to stay theme-safe. */
|
|
190
|
+
color?: string;
|
|
191
|
+
thresholds?: {
|
|
192
|
+
warn?: number | undefined;
|
|
193
|
+
crit?: number | undefined;
|
|
194
|
+
} | undefined;
|
|
195
|
+
height?: number;
|
|
196
|
+
/** Human range label for the empty state ("in the last hour"). */
|
|
197
|
+
rangeLabel?: string | undefined;
|
|
198
|
+
className?: string | undefined;
|
|
199
|
+
};
|
|
200
|
+
declare function MetricHistoryChart({ points, yMax, yMin, format, unit, color, thresholds, height, rangeLabel, className, }: MetricHistoryChartProps): react_jsx_runtime.JSX.Element;
|
|
201
|
+
|
|
202
|
+
type MetricSparklineProps = {
|
|
203
|
+
points: SeriesPoint[];
|
|
204
|
+
color?: string;
|
|
205
|
+
yMax?: number | "auto";
|
|
206
|
+
height?: number;
|
|
207
|
+
className?: string | undefined;
|
|
208
|
+
};
|
|
209
|
+
declare function MetricSparkline({ points, color, yMax, height, className, }: MetricSparklineProps): react_jsx_runtime.JSX.Element;
|
|
210
|
+
|
|
211
|
+
type MetricWindow = "15m" | "1h" | "6h" | "24h";
|
|
212
|
+
declare const METRIC_WINDOWS: MetricWindow[];
|
|
213
|
+
declare const WINDOW_LABEL: Record<MetricWindow, string>;
|
|
214
|
+
type MetricKey = "cpu" | "mem" | "disk" | "load" | "gpu";
|
|
215
|
+
type MetricDef = {
|
|
216
|
+
key: MetricKey;
|
|
217
|
+
title: string;
|
|
218
|
+
unit: string;
|
|
219
|
+
yMax: number | "auto";
|
|
220
|
+
color: string;
|
|
221
|
+
thresholds?: {
|
|
222
|
+
warn?: number;
|
|
223
|
+
crit?: number;
|
|
224
|
+
};
|
|
225
|
+
pick: (s: MetricSample) => number | null;
|
|
226
|
+
/** Big current-value string for tiles/badges. */
|
|
227
|
+
current: (s: MetricSample) => string;
|
|
228
|
+
/** Optional sub-line under the current value. */
|
|
229
|
+
sub?: (s: MetricSample) => string | null;
|
|
230
|
+
};
|
|
231
|
+
declare const METRICS: MetricDef[];
|
|
232
|
+
declare function pointsFor(def: MetricDef, samples: MetricSample[]): SeriesPoint[];
|
|
233
|
+
|
|
234
|
+
type MachineDetailProps = {
|
|
235
|
+
machine: MachineView;
|
|
236
|
+
/** Downsampled history for the active window (from `fetchSeries`). */
|
|
237
|
+
series: MetricSample[];
|
|
238
|
+
window: MetricWindow;
|
|
239
|
+
onWindowChange: (w: MetricWindow) => void;
|
|
240
|
+
loadingSeries?: boolean | undefined;
|
|
241
|
+
onBack?: (() => void) | undefined;
|
|
242
|
+
now?: number | undefined;
|
|
243
|
+
className?: string | undefined;
|
|
244
|
+
};
|
|
245
|
+
declare function MachineDetail({ machine, series, window, onWindowChange, loadingSeries, onBack, now, className, }: MachineDetailProps): react_jsx_runtime.JSX.Element;
|
|
132
246
|
|
|
133
247
|
type MachinesDashboardProps = {
|
|
134
248
|
machines: MachineView[];
|
|
@@ -140,6 +254,12 @@ type MachinesDashboardProps = {
|
|
|
140
254
|
onAttach?: ((machine: MachineView) => void) | undefined;
|
|
141
255
|
/** The sandbox id currently being attached/swapped to (disables that card). */
|
|
142
256
|
attachingSandboxId?: string | null | undefined;
|
|
257
|
+
/** Short recent history per machine (keyed by sandboxId) — drives card sparklines. */
|
|
258
|
+
seriesByMachine?: Record<string, MetricSample[]> | undefined;
|
|
259
|
+
/** Open the per-machine telemetry detail (makes each card actionable). */
|
|
260
|
+
onOpenDetail?: ((machine: MachineView) => void) | undefined;
|
|
261
|
+
/** Shared clock so freshness/relative times render consistently across cards. */
|
|
262
|
+
now?: number | undefined;
|
|
143
263
|
/** Open the enrollment flow (the "Enroll a machine" CTA). */
|
|
144
264
|
onEnroll?: (() => void) | undefined;
|
|
145
265
|
onRefresh?: (() => void) | undefined;
|
|
@@ -152,7 +272,7 @@ type MachinesDashboardProps = {
|
|
|
152
272
|
* machines → enroll CTA), a load error, and the populated grid. The component
|
|
153
273
|
* is purely presentational — feed it `MachinesResponse` data via `useMachines`.
|
|
154
274
|
*/
|
|
155
|
-
declare function MachinesDashboard({ machines, activeSandboxId, loading, error, onAttach, attachingSandboxId, onEnroll, onRefresh, className, }: MachinesDashboardProps): react_jsx_runtime.JSX.Element;
|
|
275
|
+
declare function MachinesDashboard({ machines, activeSandboxId, loading, error, onAttach, attachingSandboxId, seriesByMachine, onOpenDetail, now, onEnroll, onRefresh, className, }: MachinesDashboardProps): react_jsx_runtime.JSX.Element;
|
|
156
276
|
|
|
157
277
|
type MachineDockBarProps = {
|
|
158
278
|
/** The active machine's display name. */
|
|
@@ -171,7 +291,7 @@ type MachineDockBarProps = {
|
|
|
171
291
|
* render IDENTICALLY regardless of backend — this bar is the only backend-aware
|
|
172
292
|
* chrome (the dock-parity contract: selfhosted == Modal for the surfaces).
|
|
173
293
|
*/
|
|
174
|
-
declare function MachineDockBar({ name, kind, state,
|
|
294
|
+
declare function MachineDockBar({ name, kind, state, className }: MachineDockBarProps): react_jsx_runtime.JSX.Element;
|
|
175
295
|
type SharedMachineDisclosureProps = {
|
|
176
296
|
sharedSessionCount: number;
|
|
177
297
|
/** Compact (inline strip) vs full (a notice block). */
|
|
@@ -183,7 +303,7 @@ type SharedMachineDisclosureProps = {
|
|
|
183
303
|
* dock (and reused on the desktop take-control gate) so the user knows others are
|
|
184
304
|
* driving the same whole-machine lease. Render when `sharedSessionCount > 1`.
|
|
185
305
|
*/
|
|
186
|
-
declare function SharedMachineDisclosure({ sharedSessionCount, density, className }: SharedMachineDisclosureProps): react_jsx_runtime.JSX.Element;
|
|
306
|
+
declare function SharedMachineDisclosure({ sharedSessionCount, density, className, }: SharedMachineDisclosureProps): react_jsx_runtime.JSX.Element;
|
|
187
307
|
|
|
188
308
|
/** The poll state of an in-flight device-flow enrollment. */
|
|
189
309
|
type DeviceFlowPhase = "pending" | "authorized" | "denied" | "expired" | "disabled";
|
|
@@ -326,4 +446,4 @@ type UseMachinesResult = {
|
|
|
326
446
|
*/
|
|
327
447
|
declare function useMachines(options?: UseMachinesOptions): UseMachinesResult;
|
|
328
448
|
|
|
329
|
-
export {
|
|
449
|
+
export { WINDOW_LABEL as $, type MachineStateBadgeMeta as A, MachineStatusPill as B, type ClientOverride as C, type DeviceFlowPhase as D, EnrollmentConsent as E, type MachineStatusPillProps as F, type MachinesClientLike as G, HEALTH_TOKEN as H, MachinesDashboard as I, type MachinesDashboardProps as J, type MetricDef as K, MetricHistoryChart as L, MACHINE_STATE_BADGE_META as M, type MetricHistoryChartProps as N, type MetricKey as O, MetricSparkline as P, type MetricSparklineProps as Q, type MetricWindow as R, type SessionClientLike as S, type OpenGeniContextValue as T, OpenGeniProvider as U, type OpenGeniProviderProps as V, type SeriesPoint as W, SharedMachineDisclosure as X, type SharedMachineDisclosureProps as Y, type UseMachinesOptions as Z, type UseMachinesResult as _, CONNECTION_STATUS_META as a, connectionStatusForState as a0, deriveHealth as a1, healthPulses as a2, pointsFor as a3, useMachines as a4, useOpenGeni as a5, useOpenGeniClient as a6, ConnectionDot as b, type ConnectionDotProps as c, type ConnectionStatus as d, type ConnectionStatusMeta as e, ConnectionStatusPill as f, type ConnectionStatusPillProps as g, type EnrollmentConsentMachine as h, type EnrollmentConsentPhase as i, type EnrollmentConsentProps as j, EnrollmentDeviceFlow as k, type EnrollmentDeviceFlowProps as l, type HealthLevel as m, type HealthVerdict as n, METRICS as o, METRIC_WINDOWS as p, MachineCard as q, type MachineCardProps as r, MachineDetail as s, type MachineDetailProps as t, MachineDockBar as u, type MachineDockBarProps as v, MachineHealthPill as w, type MachineHealthPillProps as x, MachineMetrics as y, type MachineMetricsProps as z };
|
package/dist/machines.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { a as CONNECTION_STATUS_META, b as ConnectionDot, c as ConnectionDotProps, d as ConnectionStatus, e as ConnectionStatusMeta, f as ConnectionStatusPill, g as ConnectionStatusPillProps, D as DeviceFlowPhase, E as EnrollmentConsent, h as EnrollmentConsentMachine, i as EnrollmentConsentPhase, j as EnrollmentConsentProps, k as EnrollmentDeviceFlow, l as EnrollmentDeviceFlowProps, M as MACHINE_STATE_BADGE_META,
|
|
1
|
+
export { a as CONNECTION_STATUS_META, b as ConnectionDot, c as ConnectionDotProps, d as ConnectionStatus, e as ConnectionStatusMeta, f as ConnectionStatusPill, g as ConnectionStatusPillProps, D as DeviceFlowPhase, E as EnrollmentConsent, h as EnrollmentConsentMachine, i as EnrollmentConsentPhase, j as EnrollmentConsentProps, k as EnrollmentDeviceFlow, l as EnrollmentDeviceFlowProps, H as HEALTH_TOKEN, m as HealthLevel, n as HealthVerdict, M as MACHINE_STATE_BADGE_META, o as METRICS, p as METRIC_WINDOWS, q as MachineCard, r as MachineCardProps, s as MachineDetail, t as MachineDetailProps, u as MachineDockBar, v as MachineDockBarProps, w as MachineHealthPill, x as MachineHealthPillProps, y as MachineMetrics, z as MachineMetricsProps, A as MachineStateBadgeMeta, B as MachineStatusPill, F as MachineStatusPillProps, G as MachinesClientLike, I as MachinesDashboard, J as MachinesDashboardProps, K as MetricDef, L as MetricHistoryChart, N as MetricHistoryChartProps, O as MetricKey, P as MetricSparkline, Q as MetricSparklineProps, R as MetricWindow, W as SeriesPoint, X as SharedMachineDisclosure, Y as SharedMachineDisclosureProps, Z as UseMachinesOptions, _ as UseMachinesResult, $ as WINDOW_LABEL, a0 as connectionStatusForState, a1 as deriveHealth, a2 as healthPulses, a3 as pointsFor, a4 as useMachines } from './machines-BpdwuQcD.js';
|
|
2
2
|
export { MachineKind, MachineMetricsSeriesResponse, MachineState, MachineView, MachinesResponse, MetricSample } from '@opengeni/sdk';
|
|
3
3
|
import 'react/jsx-runtime';
|
|
4
4
|
import 'react';
|
package/dist/machines.js
CHANGED
|
@@ -4,30 +4,52 @@ import {
|
|
|
4
4
|
ConnectionStatusPill,
|
|
5
5
|
EnrollmentConsent,
|
|
6
6
|
EnrollmentDeviceFlow,
|
|
7
|
+
HEALTH_TOKEN,
|
|
7
8
|
MACHINE_STATE_BADGE_META,
|
|
9
|
+
METRICS,
|
|
10
|
+
METRIC_WINDOWS,
|
|
8
11
|
MachineCard,
|
|
12
|
+
MachineDetail,
|
|
9
13
|
MachineDockBar,
|
|
14
|
+
MachineHealthPill,
|
|
10
15
|
MachineMetrics,
|
|
11
16
|
MachineStatusPill,
|
|
12
17
|
MachinesDashboard,
|
|
18
|
+
MetricHistoryChart,
|
|
19
|
+
MetricSparkline,
|
|
13
20
|
SharedMachineDisclosure,
|
|
21
|
+
WINDOW_LABEL,
|
|
14
22
|
connectionStatusForState,
|
|
23
|
+
deriveHealth,
|
|
24
|
+
healthPulses,
|
|
25
|
+
pointsFor,
|
|
15
26
|
useMachines
|
|
16
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-TOJR776I.js";
|
|
17
28
|
export {
|
|
18
29
|
CONNECTION_STATUS_META,
|
|
19
30
|
ConnectionDot,
|
|
20
31
|
ConnectionStatusPill,
|
|
21
32
|
EnrollmentConsent,
|
|
22
33
|
EnrollmentDeviceFlow,
|
|
34
|
+
HEALTH_TOKEN,
|
|
23
35
|
MACHINE_STATE_BADGE_META,
|
|
36
|
+
METRICS,
|
|
37
|
+
METRIC_WINDOWS,
|
|
24
38
|
MachineCard,
|
|
39
|
+
MachineDetail,
|
|
25
40
|
MachineDockBar,
|
|
41
|
+
MachineHealthPill,
|
|
26
42
|
MachineMetrics,
|
|
27
43
|
MachineStatusPill,
|
|
28
44
|
MachinesDashboard,
|
|
45
|
+
MetricHistoryChart,
|
|
46
|
+
MetricSparkline,
|
|
29
47
|
SharedMachineDisclosure,
|
|
48
|
+
WINDOW_LABEL,
|
|
30
49
|
connectionStatusForState,
|
|
50
|
+
deriveHealth,
|
|
51
|
+
healthPulses,
|
|
52
|
+
pointsFor,
|
|
31
53
|
useMachines
|
|
32
54
|
};
|
|
33
55
|
//# sourceMappingURL=machines.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opengeni/react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "React hooks and styled components for OpenGeni: live session streaming, chat composer, message timeline, session status, and fleet views — token-themed (CSS variables), dark-first, built on Tailwind v4 + Radix + Motion.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -8,6 +8,11 @@
|
|
|
8
8
|
"url": "git+https://github.com/Cloudgeni-ai/opengeni.git",
|
|
9
9
|
"directory": "packages/react"
|
|
10
10
|
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist",
|
|
13
|
+
"src",
|
|
14
|
+
"styles"
|
|
15
|
+
],
|
|
11
16
|
"type": "module",
|
|
12
17
|
"sideEffects": false,
|
|
13
18
|
"main": "./dist/index.js",
|
|
@@ -25,20 +30,12 @@
|
|
|
25
30
|
"./styles.css": "./styles/index.css",
|
|
26
31
|
"./tokens.css": "./styles/tokens.css"
|
|
27
32
|
},
|
|
28
|
-
"files": [
|
|
29
|
-
"dist",
|
|
30
|
-
"src",
|
|
31
|
-
"styles"
|
|
32
|
-
],
|
|
33
|
-
"engines": {
|
|
34
|
-
"node": ">=18"
|
|
35
|
-
},
|
|
36
33
|
"publishConfig": {
|
|
37
34
|
"access": "public",
|
|
38
35
|
"provenance": true
|
|
39
36
|
},
|
|
40
37
|
"scripts": {
|
|
41
|
-
"typecheck": "
|
|
38
|
+
"typecheck": "tsgo --noEmit",
|
|
42
39
|
"build": "tsup",
|
|
43
40
|
"demo": "vite dev demo --port 3100",
|
|
44
41
|
"demo:build": "vite build demo",
|
|
@@ -46,7 +43,10 @@
|
|
|
46
43
|
},
|
|
47
44
|
"dependencies": {
|
|
48
45
|
"@bufbuild/protobuf": "^2.2.0",
|
|
49
|
-
"@
|
|
46
|
+
"@dnd-kit/core": "6.3.1",
|
|
47
|
+
"@dnd-kit/sortable": "10.0.0",
|
|
48
|
+
"@dnd-kit/utilities": "3.2.2",
|
|
49
|
+
"@opengeni/sdk": "^0.15.0",
|
|
50
50
|
"clsx": "^2.1.1",
|
|
51
51
|
"lucide-react": "^1.8.0",
|
|
52
52
|
"motion": "^12.0.0",
|
|
@@ -54,7 +54,8 @@
|
|
|
54
54
|
"react-markdown": "^10.1.0",
|
|
55
55
|
"react-resizable-panels": "^4.11.2",
|
|
56
56
|
"remark-gfm": "^4.0.1",
|
|
57
|
-
"tailwind-merge": "^3.5.0"
|
|
57
|
+
"tailwind-merge": "^3.5.0",
|
|
58
|
+
"virtua": "^0.49.2"
|
|
58
59
|
},
|
|
59
60
|
"peerDependencies": {
|
|
60
61
|
"@codemirror/lang-css": "^6.0.0",
|
|
@@ -68,6 +69,7 @@
|
|
|
68
69
|
"@uiw/react-codemirror": "^4.23.0",
|
|
69
70
|
"@xterm/addon-fit": "^0.11.0",
|
|
70
71
|
"@xterm/addon-web-links": "^0.12.0",
|
|
72
|
+
"@xterm/addon-webgl": "^0.19.0",
|
|
71
73
|
"@xterm/xterm": "^6.0.0",
|
|
72
74
|
"react": "^18.0.0 || ^19.0.0",
|
|
73
75
|
"react-dom": "^18.0.0 || ^19.0.0"
|
|
@@ -106,8 +108,14 @@
|
|
|
106
108
|
"@xterm/addon-web-links": {
|
|
107
109
|
"optional": true
|
|
108
110
|
},
|
|
111
|
+
"@xterm/addon-webgl": {
|
|
112
|
+
"optional": true
|
|
113
|
+
},
|
|
109
114
|
"@xterm/xterm": {
|
|
110
115
|
"optional": true
|
|
111
116
|
}
|
|
117
|
+
},
|
|
118
|
+
"engines": {
|
|
119
|
+
"node": ">=18"
|
|
112
120
|
}
|
|
113
121
|
}
|
package/src/approvals.ts
CHANGED
|
@@ -33,13 +33,22 @@ export type PendingApproval = {
|
|
|
33
33
|
|
|
34
34
|
/** The approvals carried by one `session.requiresAction` payload. */
|
|
35
35
|
export function approvalsFromRequiresAction(payload: unknown): PendingApproval[] {
|
|
36
|
-
const approvals =
|
|
36
|
+
const approvals =
|
|
37
|
+
payload && typeof payload === "object"
|
|
38
|
+
? (payload as { approvals?: unknown }).approvals
|
|
39
|
+
: undefined;
|
|
37
40
|
if (!Array.isArray(approvals)) {
|
|
38
41
|
return [];
|
|
39
42
|
}
|
|
40
43
|
return approvals.map((approval, index) => {
|
|
41
|
-
const raw = (approval && typeof approval === "object" ? approval : {}) as Record<
|
|
42
|
-
|
|
44
|
+
const raw = (approval && typeof approval === "object" ? approval : {}) as Record<
|
|
45
|
+
string,
|
|
46
|
+
unknown
|
|
47
|
+
>;
|
|
48
|
+
const rawItem =
|
|
49
|
+
raw.rawItem && typeof raw.rawItem === "object"
|
|
50
|
+
? (raw.rawItem as Record<string, unknown>)
|
|
51
|
+
: {};
|
|
43
52
|
return {
|
|
44
53
|
id: String(raw.id ?? raw.callId ?? rawItem.callId ?? index),
|
|
45
54
|
name: String(raw.name ?? "approval"),
|
|
@@ -61,7 +70,10 @@ export function projectPendingApprovals(events: SessionEvent[]): PendingApproval
|
|
|
61
70
|
break;
|
|
62
71
|
}
|
|
63
72
|
case "user.approvalDecision": {
|
|
64
|
-
const payload =
|
|
73
|
+
const payload =
|
|
74
|
+
event.payload && typeof event.payload === "object"
|
|
75
|
+
? (event.payload as { approvalId?: unknown })
|
|
76
|
+
: {};
|
|
65
77
|
if (typeof payload.approvalId === "string") {
|
|
66
78
|
pending = pending.filter((approval) => approval.id !== payload.approvalId);
|
|
67
79
|
}
|
package/src/client.ts
CHANGED
|
@@ -11,22 +11,31 @@ export type SessionClientLike = Pick<
|
|
|
11
11
|
| "getClientConfig"
|
|
12
12
|
// Sessions, events, composer
|
|
13
13
|
| "getSession"
|
|
14
|
+
| "getSessionLineage"
|
|
14
15
|
| "updateSession"
|
|
16
|
+
| "updateSessionPin"
|
|
15
17
|
| "listSessions"
|
|
18
|
+
| "listSessionPage"
|
|
16
19
|
| "sendMessage"
|
|
17
20
|
| "steerMessage"
|
|
18
|
-
| "
|
|
21
|
+
| "pauseSession"
|
|
22
|
+
| "resumeSession"
|
|
19
23
|
| "sendApprovalDecision"
|
|
20
24
|
| "listEvents"
|
|
21
25
|
| "streamEvents"
|
|
22
26
|
// Turn queue
|
|
27
|
+
| "getQueue"
|
|
28
|
+
| "moveQueueItem"
|
|
29
|
+
| "editQueueItem"
|
|
30
|
+
| "steerQueueItem"
|
|
31
|
+
| "deleteQueueItem"
|
|
32
|
+
| "getComposerDraft"
|
|
33
|
+
| "saveComposerDraft"
|
|
23
34
|
| "listTurns"
|
|
24
|
-
| "updateQueuedTurn"
|
|
25
|
-
| "reorderQueuedTurns"
|
|
26
|
-
| "deleteQueuedTurn"
|
|
27
35
|
// Goal
|
|
28
36
|
| "getGoal"
|
|
29
37
|
| "updateGoal"
|
|
38
|
+
| "deleteGoal"
|
|
30
39
|
// Operator context controls (/clear, /compact)
|
|
31
40
|
| "clearSessionContext"
|
|
32
41
|
| "compactSessionContext"
|
|
@@ -36,13 +45,33 @@ export type SessionClientLike = Pick<
|
|
|
36
45
|
| "uploadFile"
|
|
37
46
|
| "getFile"
|
|
38
47
|
| "createFileDownloadUrl"
|
|
39
|
-
//
|
|
48
|
+
// VariableSets
|
|
49
|
+
| "listVariableSets"
|
|
50
|
+
| "createVariableSet"
|
|
51
|
+
| "updateVariableSet"
|
|
52
|
+
| "deleteVariableSet"
|
|
53
|
+
| "setVariableSetVariable"
|
|
54
|
+
| "deleteVariableSetVariable"
|
|
40
55
|
| "listEnvironments"
|
|
41
56
|
| "createEnvironment"
|
|
42
57
|
| "updateEnvironment"
|
|
43
58
|
| "deleteEnvironment"
|
|
44
59
|
| "setEnvironmentVariable"
|
|
45
60
|
| "deleteEnvironmentVariable"
|
|
61
|
+
// Rigs
|
|
62
|
+
| "listRigs"
|
|
63
|
+
| "createRig"
|
|
64
|
+
| "getRig"
|
|
65
|
+
| "updateRig"
|
|
66
|
+
| "deleteRig"
|
|
67
|
+
| "listRigVersions"
|
|
68
|
+
| "activateRigVersion"
|
|
69
|
+
| "listRigChanges"
|
|
70
|
+
| "proposeRigChange"
|
|
71
|
+
| "getRigChange"
|
|
72
|
+
| "verifyRigChange"
|
|
73
|
+
| "promoteRigChange"
|
|
74
|
+
| "verifyRig"
|
|
46
75
|
// Packs
|
|
47
76
|
| "listPacks"
|
|
48
77
|
| "registerPack"
|
|
@@ -52,6 +81,10 @@ export type SessionClientLike = Pick<
|
|
|
52
81
|
| "listWorkspaces"
|
|
53
82
|
| "createWorkspace"
|
|
54
83
|
| "updateWorkspace"
|
|
84
|
+
| "setWorkspaceInferenceState"
|
|
85
|
+
| "getWorkspace"
|
|
86
|
+
| "listWorkspaceControlEvents"
|
|
87
|
+
| "streamWorkspaceControlEvents"
|
|
55
88
|
| "getBillingUsage"
|
|
56
89
|
// Stream surfacing (Phase 5): capability negotiation + viewer lifecycle
|
|
57
90
|
| "getClientConfig"
|
|
@@ -69,6 +102,9 @@ export type SessionClientLike = Pick<
|
|
|
69
102
|
| "fsMkdir"
|
|
70
103
|
| "gitStatus"
|
|
71
104
|
| "gitDiff"
|
|
105
|
+
// Workbench v2 turn-end capture reads (the cold-paint source; M3 consumes these)
|
|
106
|
+
| "getWorkspaceCapture"
|
|
107
|
+
| "getWorkspaceCaptureFile"
|
|
72
108
|
| "terminalExec"
|
|
73
109
|
| "terminalPtyOpen"
|
|
74
110
|
| "terminalPtyWrite"
|
package/src/commands/index.ts
CHANGED
package/src/commands/registry.ts
CHANGED
|
@@ -40,7 +40,10 @@ export function parseCommandLine(value: string): ParsedCommandLine | null {
|
|
|
40
40
|
const PERMISSION_SUPERUSER: Permission = "workspace:admin";
|
|
41
41
|
|
|
42
42
|
/** Whether the operator's permission set satisfies a command's gate. */
|
|
43
|
-
export function hasPermission(
|
|
43
|
+
export function hasPermission(
|
|
44
|
+
required: Permission | undefined,
|
|
45
|
+
permissions: Permission[],
|
|
46
|
+
): boolean {
|
|
44
47
|
if (!required) {
|
|
45
48
|
return true;
|
|
46
49
|
}
|
|
@@ -48,13 +51,18 @@ export function hasPermission(required: Permission | undefined, permissions: Per
|
|
|
48
51
|
}
|
|
49
52
|
|
|
50
53
|
/** Match a command (by name or alias) against the value. */
|
|
51
|
-
export function matchCommand(
|
|
54
|
+
export function matchCommand(
|
|
55
|
+
commands: readonly SlashCommand[],
|
|
56
|
+
value: string,
|
|
57
|
+
): SlashCommand | null {
|
|
52
58
|
const parsed = parseCommandLine(value);
|
|
53
59
|
if (!parsed) {
|
|
54
60
|
return null;
|
|
55
61
|
}
|
|
56
62
|
const token = parsed.name.toLowerCase();
|
|
57
|
-
return
|
|
63
|
+
return (
|
|
64
|
+
commands.find((command) => command.name === token || command.aliases?.includes(token)) ?? null
|
|
65
|
+
);
|
|
58
66
|
}
|
|
59
67
|
|
|
60
68
|
type FilterCtx = Pick<CommandContext, "sessionId" | "status" | "permissions">;
|
|
@@ -64,7 +72,11 @@ type FilterCtx = Pick<CommandContext, "sessionId" | "status" | "permissions">;
|
|
|
64
72
|
* `available()===false` commands are dropped entirely (a gated command is never
|
|
65
73
|
* shown, not shown-disabled). Filtering is a prefix match on name/alias.
|
|
66
74
|
*/
|
|
67
|
-
export function filterCommands(
|
|
75
|
+
export function filterCommands(
|
|
76
|
+
commands: readonly SlashCommand[],
|
|
77
|
+
token: string,
|
|
78
|
+
ctx: FilterCtx,
|
|
79
|
+
): SlashCommand[] {
|
|
68
80
|
const needle = token.toLowerCase();
|
|
69
81
|
return commands.filter((command) => {
|
|
70
82
|
if (!hasPermission(command.permission, ctx.permissions)) {
|
|
@@ -76,7 +88,10 @@ export function filterCommands(commands: readonly SlashCommand[], token: string,
|
|
|
76
88
|
if (needle.length === 0) {
|
|
77
89
|
return true;
|
|
78
90
|
}
|
|
79
|
-
return
|
|
91
|
+
return (
|
|
92
|
+
command.name.startsWith(needle) ||
|
|
93
|
+
(command.aliases?.some((alias) => alias.startsWith(needle)) ?? false)
|
|
94
|
+
);
|
|
80
95
|
});
|
|
81
96
|
}
|
|
82
97
|
|
|
@@ -139,7 +154,10 @@ export const defaultCommands: readonly SlashCommand[] = [
|
|
|
139
154
|
// instead so the operator isn't told something happened when nothing did.
|
|
140
155
|
const cleared = ctx.clearView();
|
|
141
156
|
if (!cleared) {
|
|
142
|
-
return {
|
|
157
|
+
return {
|
|
158
|
+
status: "error",
|
|
159
|
+
message: "This view can't be cleared here (no local timeline to reset).",
|
|
160
|
+
};
|
|
143
161
|
}
|
|
144
162
|
return { status: "ok", message: "Local view cleared." };
|
|
145
163
|
},
|
|
@@ -149,7 +167,9 @@ export const defaultCommands: readonly SlashCommand[] = [
|
|
|
149
167
|
description: "Pause or resume the session's goal loop.",
|
|
150
168
|
permission: "sessions:control",
|
|
151
169
|
available: hasSession,
|
|
152
|
-
args: [
|
|
170
|
+
args: [
|
|
171
|
+
{ name: "action", required: true, oneOf: ["pause", "resume"], description: "pause | resume" },
|
|
172
|
+
],
|
|
153
173
|
run: async (args, ctx) => {
|
|
154
174
|
const sessionId = requireSession(ctx);
|
|
155
175
|
const action = args[0];
|
|
@@ -157,7 +177,9 @@ export const defaultCommands: readonly SlashCommand[] = [
|
|
|
157
177
|
return { status: "error", message: "Usage: /goal pause | /goal resume" };
|
|
158
178
|
}
|
|
159
179
|
try {
|
|
160
|
-
await ctx.client.updateGoal(ctx.workspaceId, sessionId, {
|
|
180
|
+
await ctx.client.updateGoal(ctx.workspaceId, sessionId, {
|
|
181
|
+
status: action === "pause" ? "paused" : "active",
|
|
182
|
+
});
|
|
161
183
|
return { status: "ok", message: action === "pause" ? "Goal paused." : "Goal resumed." };
|
|
162
184
|
} catch (cause) {
|
|
163
185
|
return { status: "error", message: goalErrorMessage(cause, action) };
|
|
@@ -204,14 +226,24 @@ export const defaultCommands: readonly SlashCommand[] = [
|
|
|
204
226
|
];
|
|
205
227
|
|
|
206
228
|
function errorMessage(cause: unknown): string | undefined {
|
|
207
|
-
if (
|
|
229
|
+
if (
|
|
230
|
+
cause &&
|
|
231
|
+
typeof cause === "object" &&
|
|
232
|
+
"message" in cause &&
|
|
233
|
+
typeof (cause as { message?: unknown }).message === "string"
|
|
234
|
+
) {
|
|
208
235
|
return (cause as { message: string }).message;
|
|
209
236
|
}
|
|
210
237
|
return undefined;
|
|
211
238
|
}
|
|
212
239
|
|
|
213
240
|
function statusCode(cause: unknown): number | undefined {
|
|
214
|
-
if (
|
|
241
|
+
if (
|
|
242
|
+
cause &&
|
|
243
|
+
typeof cause === "object" &&
|
|
244
|
+
"status" in cause &&
|
|
245
|
+
typeof (cause as { status?: unknown }).status === "number"
|
|
246
|
+
) {
|
|
215
247
|
return (cause as { status: number }).status;
|
|
216
248
|
}
|
|
217
249
|
return undefined;
|
|
@@ -223,14 +255,16 @@ function goalErrorMessage(cause: unknown, action: "pause" | "resume"): string {
|
|
|
223
255
|
return "This session has no goal to control.";
|
|
224
256
|
}
|
|
225
257
|
if (code === 409) {
|
|
226
|
-
return action === "resume"
|
|
258
|
+
return action === "resume"
|
|
259
|
+
? "Only a paused goal can be resumed."
|
|
260
|
+
: "Goal is already in a terminal state.";
|
|
227
261
|
}
|
|
228
262
|
return errorMessage(cause) ?? `Could not ${action} the goal.`;
|
|
229
263
|
}
|
|
230
264
|
|
|
231
265
|
function clearErrorMessage(cause: unknown): string {
|
|
232
266
|
if (statusCode(cause) === 409) {
|
|
233
|
-
return "
|
|
267
|
+
return "Pause the session and wait for the current inference to settle, then clear context.";
|
|
234
268
|
}
|
|
235
269
|
return errorMessage(cause) ?? "Could not clear context.";
|
|
236
270
|
}
|