@opengeni/react 0.1.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 +141 -0
- package/dist/index.d.ts +897 -0
- package/dist/index.js +3013 -0
- package/dist/index.js.map +1 -0
- package/package.json +64 -0
- package/src/approvals.ts +86 -0
- package/src/client.ts +52 -0
- package/src/commands/index.ts +17 -0
- package/src/commands/registry.ts +236 -0
- package/src/commands/types.ts +88 -0
- package/src/components/chat-composer.tsx +619 -0
- package/src/components/command-palette.tsx +94 -0
- package/src/components/fleet-tile.tsx +72 -0
- package/src/components/message-timeline.tsx +416 -0
- package/src/components/session-status.tsx +92 -0
- package/src/hooks/internal.ts +236 -0
- package/src/hooks/use-billing-usage.ts +51 -0
- package/src/hooks/use-composer.ts +213 -0
- package/src/hooks/use-environments.ts +118 -0
- package/src/hooks/use-file-attachments.ts +135 -0
- package/src/hooks/use-goal.ts +154 -0
- package/src/hooks/use-packs.ts +101 -0
- package/src/hooks/use-scheduled-tasks.ts +29 -0
- package/src/hooks/use-session-control.ts +85 -0
- package/src/hooks/use-session-events.ts +130 -0
- package/src/hooks/use-session.ts +33 -0
- package/src/hooks/use-slash-commands.ts +366 -0
- package/src/hooks/use-turn-queue.ts +229 -0
- package/src/hooks/use-workspace-sessions.ts +30 -0
- package/src/hooks/use-workspaces.ts +66 -0
- package/src/index.ts +115 -0
- package/src/lib/cn.ts +7 -0
- package/src/lib/format.ts +84 -0
- package/src/provider.tsx +57 -0
- package/src/timeline.ts +632 -0
- package/styles/index.css +157 -0
- package/styles/tokens.css +111 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,897 @@
|
|
|
1
|
+
import { OpenGeniClient, Session, ResourceRef, ToolRef, SessionStatus as SessionStatus$1, SessionEvent, StreamConnectionState, SendMessageInput, FileAsset, FileResourceRef, SessionTurn, UpdateSessionTurnRequest, SessionGoal, ScheduledTask, WorkspaceEnvironment, CreateWorkspaceEnvironmentRequest, UpdateWorkspaceEnvironmentRequest, WorkspaceEnvironmentVariableMetadata, CapabilityPack, PackInstallation, RegisterCapabilityPackRequest, WorkspaceRegisteredPack, EnablePackRequest, Workspace, CreateWorkspaceRequest, UpdateWorkspaceRequest, BillingBalance, UsageEvent, Permission } from '@opengeni/sdk';
|
|
2
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
|
+
import { ReactNode, KeyboardEvent, ClipboardEvent } from 'react';
|
|
4
|
+
import { ClassValue } from 'clsx';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The slice of `OpenGeniClient` the hooks depend on. Structural, so apps can
|
|
8
|
+
* pass the real SDK client, a proxy-backed client that routes through their
|
|
9
|
+
* own API, or a scripted client in tests/demos.
|
|
10
|
+
*/
|
|
11
|
+
type SessionClientLike = Pick<OpenGeniClient, "getSession" | "listSessions" | "sendMessage" | "steerMessage" | "interrupt" | "sendApprovalDecision" | "streamEvents" | "listTurns" | "updateQueuedTurn" | "reorderQueuedTurns" | "deleteQueuedTurn" | "getGoal" | "updateGoal" | "clearSessionContext" | "compactSessionContext" | "listScheduledTasks" | "uploadFile" | "getFile" | "createFileDownloadUrl" | "listEnvironments" | "createEnvironment" | "updateEnvironment" | "deleteEnvironment" | "setEnvironmentVariable" | "deleteEnvironmentVariable" | "listPacks" | "registerPack" | "enablePack" | "deletePack" | "listWorkspaces" | "createWorkspace" | "updateWorkspace" | "getBillingUsage">;
|
|
12
|
+
|
|
13
|
+
type OpenGeniContextValue = {
|
|
14
|
+
client: SessionClientLike;
|
|
15
|
+
workspaceId: string;
|
|
16
|
+
};
|
|
17
|
+
type OpenGeniProviderProps = {
|
|
18
|
+
client: SessionClientLike;
|
|
19
|
+
workspaceId: string;
|
|
20
|
+
children?: ReactNode;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Supplies the OpenGeni client + workspace to all hooks below it. Hooks also
|
|
24
|
+
* accept `{ client, workspaceId }` overrides per call for multi-workspace UIs.
|
|
25
|
+
*/
|
|
26
|
+
declare function OpenGeniProvider({ client, workspaceId, children }: OpenGeniProviderProps): react_jsx_runtime.JSX.Element;
|
|
27
|
+
type ClientOverride = {
|
|
28
|
+
client?: SessionClientLike | undefined;
|
|
29
|
+
workspaceId?: string | undefined;
|
|
30
|
+
};
|
|
31
|
+
/** Resolve client + workspace from explicit overrides or the provider. */
|
|
32
|
+
declare function useOpenGeni(override?: ClientOverride): OpenGeniContextValue;
|
|
33
|
+
/**
|
|
34
|
+
* Resolve the client only — for hooks that are not workspace-scoped
|
|
35
|
+
* (`useWorkspaces`, `useBillingUsage`).
|
|
36
|
+
*/
|
|
37
|
+
declare function useOpenGeniClient(override?: Pick<ClientOverride, "client">): SessionClientLike;
|
|
38
|
+
|
|
39
|
+
type UseSessionOptions = ClientOverride & {
|
|
40
|
+
/** Re-fetch on an interval (ms). Off by default — pair with `useSessionEvents` for live status. */
|
|
41
|
+
pollIntervalMs?: number | undefined;
|
|
42
|
+
enabled?: boolean | undefined;
|
|
43
|
+
};
|
|
44
|
+
type UseSessionResult = {
|
|
45
|
+
session: Session | null;
|
|
46
|
+
loading: boolean;
|
|
47
|
+
error: Error | null;
|
|
48
|
+
refresh: () => Promise<void>;
|
|
49
|
+
};
|
|
50
|
+
/** Fetch one session (with optional polling). */
|
|
51
|
+
declare function useSession(sessionId: string | null | undefined, options?: UseSessionOptions): UseSessionResult;
|
|
52
|
+
|
|
53
|
+
type UserMessageItem = {
|
|
54
|
+
kind: "user-message";
|
|
55
|
+
id: string;
|
|
56
|
+
text: string;
|
|
57
|
+
/** Resources attached to this message (file uploads, repositories). */
|
|
58
|
+
resources: ResourceRef[];
|
|
59
|
+
/** Tools requested for the turn this message starts. */
|
|
60
|
+
tools: ToolRef[];
|
|
61
|
+
occurredAt: string;
|
|
62
|
+
};
|
|
63
|
+
type AgentMessageItem = {
|
|
64
|
+
kind: "agent-message";
|
|
65
|
+
id: string;
|
|
66
|
+
turnId: string | null;
|
|
67
|
+
text: string;
|
|
68
|
+
/** Still receiving deltas (no completed/turn-end seen yet). */
|
|
69
|
+
streaming: boolean;
|
|
70
|
+
occurredAt: string;
|
|
71
|
+
};
|
|
72
|
+
type ReasoningItem = {
|
|
73
|
+
kind: "reasoning";
|
|
74
|
+
id: string;
|
|
75
|
+
turnId: string | null;
|
|
76
|
+
text: string;
|
|
77
|
+
streaming: boolean;
|
|
78
|
+
occurredAt: string;
|
|
79
|
+
};
|
|
80
|
+
type ToolCallItem = {
|
|
81
|
+
kind: "tool-call";
|
|
82
|
+
id: string;
|
|
83
|
+
turnId: string | null;
|
|
84
|
+
callId: string | null;
|
|
85
|
+
name: string;
|
|
86
|
+
arguments: unknown;
|
|
87
|
+
output: unknown;
|
|
88
|
+
status: "running" | "complete";
|
|
89
|
+
occurredAt: string;
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* An orchestration call against another session — the manager spawning or
|
|
93
|
+
* messaging a worker. Rendered as a first-class "worker" row, not a generic
|
|
94
|
+
* tool call.
|
|
95
|
+
*/
|
|
96
|
+
type WorkerItem = {
|
|
97
|
+
kind: "worker";
|
|
98
|
+
id: string;
|
|
99
|
+
turnId: string | null;
|
|
100
|
+
callId: string | null;
|
|
101
|
+
action: "spawn" | "message";
|
|
102
|
+
/** The worker's initial message / the message sent to it, when parseable. */
|
|
103
|
+
prompt: string | null;
|
|
104
|
+
/** The target/spawned worker session id, when parseable from args/output. */
|
|
105
|
+
workerSessionId: string | null;
|
|
106
|
+
status: "running" | "complete";
|
|
107
|
+
occurredAt: string;
|
|
108
|
+
};
|
|
109
|
+
type SandboxItem = {
|
|
110
|
+
kind: "sandbox";
|
|
111
|
+
id: string;
|
|
112
|
+
turnId: string | null;
|
|
113
|
+
name: string;
|
|
114
|
+
command: string | null;
|
|
115
|
+
output: string;
|
|
116
|
+
status: "running" | "complete" | "failed";
|
|
117
|
+
occurredAt: string;
|
|
118
|
+
};
|
|
119
|
+
type SessionStatusItem = {
|
|
120
|
+
kind: "session-status";
|
|
121
|
+
id: string;
|
|
122
|
+
status: SessionStatus$1;
|
|
123
|
+
occurredAt: string;
|
|
124
|
+
};
|
|
125
|
+
type GoalItem = {
|
|
126
|
+
kind: "goal";
|
|
127
|
+
id: string;
|
|
128
|
+
action: "set" | "updated" | "completed" | "paused" | "resumed" | "continuation";
|
|
129
|
+
text: string | null;
|
|
130
|
+
occurredAt: string;
|
|
131
|
+
};
|
|
132
|
+
type NoticeItem = {
|
|
133
|
+
kind: "notice";
|
|
134
|
+
id: string;
|
|
135
|
+
tone: "waiting" | "cancelled" | "failed";
|
|
136
|
+
text: string;
|
|
137
|
+
occurredAt: string;
|
|
138
|
+
};
|
|
139
|
+
type TimelineItem = UserMessageItem | AgentMessageItem | ReasoningItem | ToolCallItem | WorkerItem | SandboxItem | SessionStatusItem | GoalItem | NoticeItem;
|
|
140
|
+
declare function buildTimeline(events: SessionEvent[]): TimelineItem[];
|
|
141
|
+
/** The latest session status carried in the event log, if any. */
|
|
142
|
+
declare function sessionStatusFromEvents(events: SessionEvent[]): SessionStatus$1 | null;
|
|
143
|
+
type TimelineGroup = {
|
|
144
|
+
kind: "item";
|
|
145
|
+
item: TimelineItem;
|
|
146
|
+
} | {
|
|
147
|
+
kind: "activity";
|
|
148
|
+
id: string;
|
|
149
|
+
items: (ReasoningItem | ToolCallItem | WorkerItem | SandboxItem)[];
|
|
150
|
+
};
|
|
151
|
+
declare function groupTimeline(items: TimelineItem[]): TimelineGroup[];
|
|
152
|
+
/**
|
|
153
|
+
* Find a session id in orchestration tool arguments or output. Handles raw
|
|
154
|
+
* objects, JSON strings, and MCP tool results (`{ content: [{ type: "text",
|
|
155
|
+
* text: "{...}" }], structuredContent? }`).
|
|
156
|
+
*/
|
|
157
|
+
declare function extractSessionRef(value: unknown, depth?: number): string | null;
|
|
158
|
+
/** Readable label for a tool call ("session_create" -> "session create"). */
|
|
159
|
+
declare function toolDisplayName(name: string): string;
|
|
160
|
+
/** Compact, single-line preview of tool arguments/outputs for collapsed rows. */
|
|
161
|
+
declare function compactPayloadPreview(value: unknown, maxLength?: number): string;
|
|
162
|
+
|
|
163
|
+
type SessionEventsConnectionState = StreamConnectionState | "idle" | "ended" | "error";
|
|
164
|
+
type UseSessionEventsOptions = ClientOverride & {
|
|
165
|
+
/** Resume after this sequence (exclusive). Defaults to 0 = full replay. */
|
|
166
|
+
after?: number | undefined;
|
|
167
|
+
/** Pause the stream without unmounting (e.g. hidden tab). Defaults to true. */
|
|
168
|
+
enabled?: boolean | undefined;
|
|
169
|
+
};
|
|
170
|
+
type UseSessionEventsResult = {
|
|
171
|
+
/** Replayed + live events, ordered by sequence, no gaps, no duplicates. */
|
|
172
|
+
events: SessionEvent[];
|
|
173
|
+
/** Projected, renderable timeline (memoized over `events`). */
|
|
174
|
+
timeline: TimelineItem[];
|
|
175
|
+
/** Latest session status observed in the event log, if any. */
|
|
176
|
+
sessionStatus: SessionStatus$1 | null;
|
|
177
|
+
connectionState: SessionEventsConnectionState;
|
|
178
|
+
/** Highest sequence seen so far (0 before the first event). */
|
|
179
|
+
lastSequence: number;
|
|
180
|
+
error: Error | null;
|
|
181
|
+
};
|
|
182
|
+
/**
|
|
183
|
+
* Live-stream a session's event log with replay-by-sequence, reconnect, and
|
|
184
|
+
* batched React updates. The SDK guarantees ordered, gap-free, exactly-once
|
|
185
|
+
* delivery; this hook accumulates the log and projects it into a timeline.
|
|
186
|
+
*/
|
|
187
|
+
declare function useSessionEvents(sessionId: string | null | undefined, options?: UseSessionEventsOptions): UseSessionEventsResult;
|
|
188
|
+
|
|
189
|
+
type ComposerSendExtras = Omit<SendMessageInput, "text" | "clientEventId">;
|
|
190
|
+
/**
|
|
191
|
+
* Compose-time delivery choice. `queue` (the default) stacks the message
|
|
192
|
+
* behind the running turn — visible, editable, reorderable until claimed.
|
|
193
|
+
* `steer` interrupts the running turn and injects the message now.
|
|
194
|
+
*/
|
|
195
|
+
type ComposerMode = "queue" | "steer";
|
|
196
|
+
type UseComposerOptions = ClientOverride & {
|
|
197
|
+
/** Called with the accepted text after a successful send. */
|
|
198
|
+
onSent?: ((text: string) => void) | undefined;
|
|
199
|
+
/**
|
|
200
|
+
* Extra message fields (resources, tools, model, reasoningEffort) merged
|
|
201
|
+
* into every send. A function is evaluated at send time so it can read the
|
|
202
|
+
* surrounding UI state (attachment pickers, model selectors, ...).
|
|
203
|
+
*/
|
|
204
|
+
sendExtras?: ComposerSendExtras | (() => ComposerSendExtras) | undefined;
|
|
205
|
+
/** Initial delivery mode. Defaults to `"queue"`. */
|
|
206
|
+
defaultMode?: ComposerMode | undefined;
|
|
207
|
+
};
|
|
208
|
+
type ComposerState = {
|
|
209
|
+
value: string;
|
|
210
|
+
setValue: (value: string) => void;
|
|
211
|
+
/** Send the draft (or an explicit text) using the current mode. */
|
|
212
|
+
send: (text?: string) => Promise<boolean>;
|
|
213
|
+
sending: boolean;
|
|
214
|
+
canSend: boolean;
|
|
215
|
+
/** Queue (default) vs steer — the compose-time delivery choice. */
|
|
216
|
+
mode: ComposerMode;
|
|
217
|
+
setMode: (mode: ComposerMode) => void;
|
|
218
|
+
/** Ask the agent to stop the current turn. */
|
|
219
|
+
interrupt: (reason?: string) => Promise<void>;
|
|
220
|
+
interrupting: boolean;
|
|
221
|
+
error: Error | null;
|
|
222
|
+
clearError: () => void;
|
|
223
|
+
};
|
|
224
|
+
/**
|
|
225
|
+
* Draft + send + interrupt state for the chat composer — the only
|
|
226
|
+
* human-to-agent input surface. The draft survives a failed send (nothing is
|
|
227
|
+
* more hostile than losing a typed message); each send carries a generated
|
|
228
|
+
* `clientEventId` so retries stay idempotent server-side.
|
|
229
|
+
*/
|
|
230
|
+
declare function useComposer(sessionId: string | null | undefined, options?: UseComposerOptions): ComposerState;
|
|
231
|
+
/**
|
|
232
|
+
* Merge the draft text + idempotency key with caller-provided extras. The
|
|
233
|
+
* text and clientEventId always win over extras. Exported for tests.
|
|
234
|
+
*/
|
|
235
|
+
declare function composeSendInput(text: string, clientEventId: string, extras: ComposerSendExtras | (() => ComposerSendExtras) | undefined): SendMessageInput;
|
|
236
|
+
/** Submit on plain Enter; Shift+Enter inserts a newline. Exported for tests. */
|
|
237
|
+
declare function shouldSubmitOnKey(event: {
|
|
238
|
+
key: string;
|
|
239
|
+
shiftKey: boolean;
|
|
240
|
+
nativeEvent?: {
|
|
241
|
+
isComposing?: boolean;
|
|
242
|
+
};
|
|
243
|
+
}): boolean;
|
|
244
|
+
|
|
245
|
+
type UseFileAttachmentsOptions = ClientOverride & {
|
|
246
|
+
/**
|
|
247
|
+
* Only files matching this predicate are accepted by {@link
|
|
248
|
+
* UseFileAttachmentsResult.addFromPaste} (the clipboard path). Defaults to
|
|
249
|
+
* `image/*` — the console's historical paste filter. {@link
|
|
250
|
+
* UseFileAttachmentsResult.addFiles} (the explicit picker / drop path)
|
|
251
|
+
* bypasses it.
|
|
252
|
+
*/
|
|
253
|
+
pasteFilter?: ((file: File) => boolean) | undefined;
|
|
254
|
+
};
|
|
255
|
+
type FileAttachment = {
|
|
256
|
+
id: string;
|
|
257
|
+
name: string;
|
|
258
|
+
contentType: string;
|
|
259
|
+
sizeBytes: number;
|
|
260
|
+
status: "uploading" | "ready" | "failed";
|
|
261
|
+
/** The SDK `FileAsset` once the upload finishes. */
|
|
262
|
+
file?: FileAsset | undefined;
|
|
263
|
+
/** Object-URL for an inline preview; minted for `image/*` files only. */
|
|
264
|
+
previewUrl?: string | undefined;
|
|
265
|
+
error?: string | undefined;
|
|
266
|
+
};
|
|
267
|
+
type UseFileAttachmentsResult = {
|
|
268
|
+
attachments: FileAttachment[];
|
|
269
|
+
/**
|
|
270
|
+
* `FileResourceRef[]` for every attachment that finished uploading — feed
|
|
271
|
+
* straight into `useComposer`'s `sendExtras.resources`.
|
|
272
|
+
*/
|
|
273
|
+
readyResources: FileResourceRef[];
|
|
274
|
+
/** True while any attachment is still uploading (drives the send-gate). */
|
|
275
|
+
uploading: boolean;
|
|
276
|
+
/** Explicit picker / drop path — uploads every file, no filter. */
|
|
277
|
+
addFiles: (files: Iterable<File>) => void;
|
|
278
|
+
/** Clipboard path — applies `pasteFilter` (default `image/*`) then uploads. */
|
|
279
|
+
addFromPaste: (event: {
|
|
280
|
+
clipboardData: DataTransfer | null;
|
|
281
|
+
}) => void;
|
|
282
|
+
/** Remove one attachment; revokes its object-URL. */
|
|
283
|
+
remove: (id: string) => void;
|
|
284
|
+
/** Remove all; revokes every object-URL. Call from `useComposer`'s `onSent`. */
|
|
285
|
+
clear: () => void;
|
|
286
|
+
};
|
|
287
|
+
/**
|
|
288
|
+
* Upload-and-track state for files attached to the next message. Owns the
|
|
289
|
+
* full client-side upload layer: a per-file `uploading | ready | failed`
|
|
290
|
+
* status machine driven by the SDK's `client.uploadFile`, object-URL image
|
|
291
|
+
* previews with create/revoke lifecycle, the `image/*` clipboard paste filter,
|
|
292
|
+
* and a `FileResourceRef[]` projection that drops straight into a message's
|
|
293
|
+
* `resources`. Workspace-scoped, so it resolves both client and workspace from
|
|
294
|
+
* the {@link OpenGeniProvider} (or a per-call `{ client, workspaceId }`).
|
|
295
|
+
*/
|
|
296
|
+
declare function useFileAttachments(options?: UseFileAttachmentsOptions): UseFileAttachmentsResult;
|
|
297
|
+
|
|
298
|
+
type SessionEventFeedOptions = {
|
|
299
|
+
/**
|
|
300
|
+
* Share an existing event log (from `useSessionEvents`) instead of opening
|
|
301
|
+
* a second stream. When omitted the hook tails the session's event stream
|
|
302
|
+
* itself, starting at the current `lastSequence`.
|
|
303
|
+
*/
|
|
304
|
+
events?: SessionEvent[] | undefined;
|
|
305
|
+
enabled?: boolean | undefined;
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
/** Event types that change the turn queue (queue/edit/reorder/claim/finish). */
|
|
309
|
+
declare function isTurnQueueEvent(event: Pick<SessionEvent, "type">): boolean;
|
|
310
|
+
/** Queued turns in execution order (position, then creation time). */
|
|
311
|
+
declare function queueFromTurns(turns: SessionTurn[]): SessionTurn[];
|
|
312
|
+
/** The turn currently holding the session (running or awaiting approval). */
|
|
313
|
+
declare function activeTurnFromTurns(turns: SessionTurn[]): SessionTurn | null;
|
|
314
|
+
/** Optimistic projection of a queued-turn edit. */
|
|
315
|
+
declare function applyTurnEdit(turns: SessionTurn[], turnId: string, update: UpdateSessionTurnRequest): SessionTurn[];
|
|
316
|
+
/**
|
|
317
|
+
* Optimistic projection of a reorder, mirroring the server: the listed
|
|
318
|
+
* queued turns get positions 1..n in the given order; everything else keeps
|
|
319
|
+
* its position.
|
|
320
|
+
*/
|
|
321
|
+
declare function applyTurnReorder(turns: SessionTurn[], turnIds: string[]): SessionTurn[];
|
|
322
|
+
/** Optimistic projection of a queued-turn delete (server marks it cancelled). */
|
|
323
|
+
declare function applyTurnRemoval(turns: SessionTurn[], turnId: string): SessionTurn[];
|
|
324
|
+
type UseTurnQueueOptions = ClientOverride & SessionEventFeedOptions & {
|
|
325
|
+
/** Optional safety-net polling (ms). Off by default — turn.* events drive updates. */
|
|
326
|
+
pollIntervalMs?: number | undefined;
|
|
327
|
+
};
|
|
328
|
+
type UseTurnQueueResult = {
|
|
329
|
+
/** All turns the API returned (history + queue), newest server view. */
|
|
330
|
+
turns: SessionTurn[];
|
|
331
|
+
/** Queued turns in execution order — render this as the editable queue. */
|
|
332
|
+
queue: SessionTurn[];
|
|
333
|
+
/** The running / requires_action turn, if any. */
|
|
334
|
+
activeTurn: SessionTurn | null;
|
|
335
|
+
loading: boolean;
|
|
336
|
+
error: Error | null;
|
|
337
|
+
refresh: () => Promise<void>;
|
|
338
|
+
/** Edit a queued turn (optimistic; rolls back via refetch on failure). */
|
|
339
|
+
editTurn: (turnId: string, update: UpdateSessionTurnRequest) => Promise<SessionTurn | null>;
|
|
340
|
+
/** Reorder the queue to the given queued-turn id order (optimistic). */
|
|
341
|
+
reorderTurns: (turnIds: string[]) => Promise<SessionTurn[] | null>;
|
|
342
|
+
/** Delete (cancel) a queued turn before it is claimed (optimistic). */
|
|
343
|
+
removeTurn: (turnId: string) => Promise<SessionTurn | null>;
|
|
344
|
+
/** True while an edit/reorder/remove is in flight. */
|
|
345
|
+
mutating: boolean;
|
|
346
|
+
/** Last failed mutation, until the next mutation or clear. */
|
|
347
|
+
mutationError: Error | null;
|
|
348
|
+
clearMutationError: () => void;
|
|
349
|
+
};
|
|
350
|
+
/**
|
|
351
|
+
* The live turn queue — the heart of the queue-by-default interaction model.
|
|
352
|
+
* Messages sent mid-turn stack up here, visible and editable/reorderable/
|
|
353
|
+
* deletable until the worker claims them. Updates arrive over the session
|
|
354
|
+
* event stream (`turn.*`), either shared via `options.events` (pass the log
|
|
355
|
+
* from `useSessionEvents` to reuse its connection) or a dedicated tail
|
|
356
|
+
* stream. All mutations apply optimistically and reconcile with the server.
|
|
357
|
+
*/
|
|
358
|
+
declare function useTurnQueue(sessionId: string | null | undefined, options?: UseTurnQueueOptions): UseTurnQueueResult;
|
|
359
|
+
|
|
360
|
+
/** Event types that change the session goal (set/updated/completed/paused/...). */
|
|
361
|
+
declare function isGoalEvent(event: Pick<SessionEvent, "type">): boolean;
|
|
362
|
+
type UseGoalOptions = ClientOverride & SessionEventFeedOptions & {
|
|
363
|
+
/** Optional safety-net polling (ms). Off by default — goal.* events drive updates. */
|
|
364
|
+
pollIntervalMs?: number | undefined;
|
|
365
|
+
};
|
|
366
|
+
type UseGoalResult = {
|
|
367
|
+
/** The session goal, or null when the session has none. */
|
|
368
|
+
goal: SessionGoal | null;
|
|
369
|
+
/** Convenience flags over `goal.status`. */
|
|
370
|
+
isActive: boolean;
|
|
371
|
+
isPaused: boolean;
|
|
372
|
+
isCompleted: boolean;
|
|
373
|
+
loading: boolean;
|
|
374
|
+
error: Error | null;
|
|
375
|
+
refresh: () => Promise<void>;
|
|
376
|
+
/** Pause the goal loop (PATCH status=paused). */
|
|
377
|
+
pause: (rationale?: string) => Promise<SessionGoal | null>;
|
|
378
|
+
/** Resume a paused goal: resets counters and re-arms continuations. */
|
|
379
|
+
resume: () => Promise<SessionGoal | null>;
|
|
380
|
+
/** True while a pause/resume is in flight. */
|
|
381
|
+
updating: boolean;
|
|
382
|
+
mutationError: Error | null;
|
|
383
|
+
clearMutationError: () => void;
|
|
384
|
+
};
|
|
385
|
+
/**
|
|
386
|
+
* The session's goal: state, the autonomy counters (`autoContinuations`,
|
|
387
|
+
* `noProgressStreak`), and pause/resume control. A goal-less session yields
|
|
388
|
+
* `goal: null` (the 404 is absorbed). Live-updates on `goal.*` events —
|
|
389
|
+
* pass `options.events` from `useSessionEvents` to reuse its stream.
|
|
390
|
+
*/
|
|
391
|
+
declare function useGoal(sessionId: string | null | undefined, options?: UseGoalOptions): UseGoalResult;
|
|
392
|
+
|
|
393
|
+
type UseSessionControlOptions = ClientOverride;
|
|
394
|
+
type UseSessionControlResult = {
|
|
395
|
+
/** Interrupt the running turn (the explicit alternative to queueing). */
|
|
396
|
+
interrupt: (reason?: string) => Promise<SessionEvent | null>;
|
|
397
|
+
interrupting: boolean;
|
|
398
|
+
/** Approve a pending `requires_action` approval. */
|
|
399
|
+
approve: (approvalId: string, message?: string) => Promise<SessionEvent | null>;
|
|
400
|
+
/** Reject a pending `requires_action` approval. */
|
|
401
|
+
reject: (approvalId: string, message?: string) => Promise<SessionEvent | null>;
|
|
402
|
+
/** True while an approval decision is in flight. */
|
|
403
|
+
responding: boolean;
|
|
404
|
+
error: Error | null;
|
|
405
|
+
clearError: () => void;
|
|
406
|
+
};
|
|
407
|
+
/**
|
|
408
|
+
* Session control events: interrupt and approval decisions. Pair with
|
|
409
|
+
* `useSessionEvents` (for `session.requiresAction` payloads carrying the
|
|
410
|
+
* `approvalId`) to render an approval bar.
|
|
411
|
+
*/
|
|
412
|
+
declare function useSessionControl(sessionId: string | null | undefined, options?: UseSessionControlOptions): UseSessionControlResult;
|
|
413
|
+
|
|
414
|
+
type UseScheduledTasksOptions = ClientOverride & {
|
|
415
|
+
limit?: number | undefined;
|
|
416
|
+
pollIntervalMs?: number | undefined;
|
|
417
|
+
enabled?: boolean | undefined;
|
|
418
|
+
};
|
|
419
|
+
type UseScheduledTasksResult = {
|
|
420
|
+
tasks: ScheduledTask[];
|
|
421
|
+
loading: boolean;
|
|
422
|
+
error: Error | null;
|
|
423
|
+
refresh: () => Promise<void>;
|
|
424
|
+
};
|
|
425
|
+
/** List the workspace's scheduled tasks (drift checks, sentinels, reapers, ...). */
|
|
426
|
+
declare function useScheduledTasks(options?: UseScheduledTasksOptions): UseScheduledTasksResult;
|
|
427
|
+
|
|
428
|
+
type UseWorkspaceSessionsOptions = ClientOverride & {
|
|
429
|
+
limit?: number | undefined;
|
|
430
|
+
/** Refresh interval (ms) for fleet/manager views. Off by default. */
|
|
431
|
+
pollIntervalMs?: number | undefined;
|
|
432
|
+
enabled?: boolean | undefined;
|
|
433
|
+
};
|
|
434
|
+
type UseWorkspaceSessionsResult = {
|
|
435
|
+
sessions: Session[];
|
|
436
|
+
loading: boolean;
|
|
437
|
+
error: Error | null;
|
|
438
|
+
refresh: () => Promise<void>;
|
|
439
|
+
};
|
|
440
|
+
/** List the workspace's sessions — the data behind fleet and manager views. */
|
|
441
|
+
declare function useWorkspaceSessions(options?: UseWorkspaceSessionsOptions): UseWorkspaceSessionsResult;
|
|
442
|
+
|
|
443
|
+
type UseEnvironmentsOptions = ClientOverride & {
|
|
444
|
+
pollIntervalMs?: number | undefined;
|
|
445
|
+
enabled?: boolean | undefined;
|
|
446
|
+
};
|
|
447
|
+
type UseEnvironmentsResult = {
|
|
448
|
+
environments: WorkspaceEnvironment[];
|
|
449
|
+
loading: boolean;
|
|
450
|
+
error: Error | null;
|
|
451
|
+
refresh: () => Promise<void>;
|
|
452
|
+
create: (request: CreateWorkspaceEnvironmentRequest) => Promise<WorkspaceEnvironment | null>;
|
|
453
|
+
update: (environmentId: string, request: UpdateWorkspaceEnvironmentRequest) => Promise<WorkspaceEnvironment | null>;
|
|
454
|
+
remove: (environmentId: string) => Promise<boolean>;
|
|
455
|
+
/** Set/rotate a variable. Values are write-only — reads expose metadata only. */
|
|
456
|
+
setVariable: (environmentId: string, name: string, value: string) => Promise<WorkspaceEnvironmentVariableMetadata | null>;
|
|
457
|
+
deleteVariable: (environmentId: string, name: string) => Promise<boolean>;
|
|
458
|
+
mutating: boolean;
|
|
459
|
+
mutationError: Error | null;
|
|
460
|
+
clearMutationError: () => void;
|
|
461
|
+
};
|
|
462
|
+
/**
|
|
463
|
+
* Workspace environments (named, encrypted variable sets attached to sessions
|
|
464
|
+
* and scheduled tasks). Variable values are write-only end to end: this hook
|
|
465
|
+
* never sees a value after it is sent.
|
|
466
|
+
*/
|
|
467
|
+
declare function useEnvironments(options?: UseEnvironmentsOptions): UseEnvironmentsResult;
|
|
468
|
+
|
|
469
|
+
type UsePacksOptions = ClientOverride & {
|
|
470
|
+
pollIntervalMs?: number | undefined;
|
|
471
|
+
enabled?: boolean | undefined;
|
|
472
|
+
};
|
|
473
|
+
type UsePacksResult = {
|
|
474
|
+
/** Built-in + registered packs available to the workspace. */
|
|
475
|
+
packs: CapabilityPack[];
|
|
476
|
+
/** Enable/disable state per pack. */
|
|
477
|
+
installations: PackInstallation[];
|
|
478
|
+
/** The installation for a pack id, if any. */
|
|
479
|
+
installationFor: (packId: string) => PackInstallation | null;
|
|
480
|
+
loading: boolean;
|
|
481
|
+
error: Error | null;
|
|
482
|
+
refresh: () => Promise<void>;
|
|
483
|
+
/** Register (or replace) a workspace-scoped pack manifest. */
|
|
484
|
+
register: (manifest: RegisterCapabilityPackRequest) => Promise<WorkspaceRegisteredPack | null>;
|
|
485
|
+
enable: (packId: string, request?: EnablePackRequest) => Promise<PackInstallation | null>;
|
|
486
|
+
/** Unregister a workspace-scoped pack (built-ins cannot be removed). */
|
|
487
|
+
remove: (packId: string) => Promise<boolean>;
|
|
488
|
+
mutating: boolean;
|
|
489
|
+
mutationError: Error | null;
|
|
490
|
+
clearMutationError: () => void;
|
|
491
|
+
};
|
|
492
|
+
/** Capability packs: catalog + installations + register/enable/unregister. */
|
|
493
|
+
declare function usePacks(options?: UsePacksOptions): UsePacksResult;
|
|
494
|
+
|
|
495
|
+
type UseWorkspacesOptions = Pick<ClientOverride, "client"> & {
|
|
496
|
+
pollIntervalMs?: number | undefined;
|
|
497
|
+
enabled?: boolean | undefined;
|
|
498
|
+
};
|
|
499
|
+
type UseWorkspacesResult = {
|
|
500
|
+
workspaces: Workspace[];
|
|
501
|
+
loading: boolean;
|
|
502
|
+
error: Error | null;
|
|
503
|
+
refresh: () => Promise<void>;
|
|
504
|
+
create: (request: CreateWorkspaceRequest) => Promise<Workspace | null>;
|
|
505
|
+
update: (workspaceId: string, request: UpdateWorkspaceRequest) => Promise<Workspace | null>;
|
|
506
|
+
mutating: boolean;
|
|
507
|
+
mutationError: Error | null;
|
|
508
|
+
clearMutationError: () => void;
|
|
509
|
+
};
|
|
510
|
+
/**
|
|
511
|
+
* The caller's workspaces (workspace switchers, onboarding). Not scoped to
|
|
512
|
+
* the provider's workspace, so it only needs the client.
|
|
513
|
+
*/
|
|
514
|
+
declare function useWorkspaces(options?: UseWorkspacesOptions): UseWorkspacesResult;
|
|
515
|
+
|
|
516
|
+
type UseBillingUsageOptions = Pick<ClientOverride, "client"> & {
|
|
517
|
+
/** Account to read. Defaults to the caller's default account server-side. */
|
|
518
|
+
accountId?: string | undefined;
|
|
519
|
+
/** Filter usage to one workspace. */
|
|
520
|
+
workspaceId?: string | undefined;
|
|
521
|
+
/** Refresh interval (ms) for live billing meters. Off by default. */
|
|
522
|
+
pollIntervalMs?: number | undefined;
|
|
523
|
+
enabled?: boolean | undefined;
|
|
524
|
+
};
|
|
525
|
+
type UseBillingUsageResult = {
|
|
526
|
+
/** Prepaid credit balance (micro-USD), null until loaded. */
|
|
527
|
+
balance: BillingBalance | null;
|
|
528
|
+
/** Recent usage events (runs, tokens, cost, uploads, ...). */
|
|
529
|
+
usage: UsageEvent[];
|
|
530
|
+
loading: boolean;
|
|
531
|
+
error: Error | null;
|
|
532
|
+
refresh: () => Promise<void>;
|
|
533
|
+
};
|
|
534
|
+
/**
|
|
535
|
+
* Account billing usage: credit balance + recent usage events — the data
|
|
536
|
+
* behind per-call billing meters. Account-scoped, so it only needs the
|
|
537
|
+
* client; pass `workspaceId` to narrow usage to one workspace.
|
|
538
|
+
*/
|
|
539
|
+
declare function useBillingUsage(options?: UseBillingUsageOptions): UseBillingUsageResult;
|
|
540
|
+
|
|
541
|
+
type PendingApproval = {
|
|
542
|
+
/** The id to send back via `user.approvalDecision` (`approvalId`). */
|
|
543
|
+
id: string;
|
|
544
|
+
/** Tool/function name awaiting the decision. */
|
|
545
|
+
name: string;
|
|
546
|
+
arguments?: unknown;
|
|
547
|
+
/** The raw approval entry from the `session.requiresAction` payload. */
|
|
548
|
+
raw?: unknown;
|
|
549
|
+
};
|
|
550
|
+
/** The approvals carried by one `session.requiresAction` payload. */
|
|
551
|
+
declare function approvalsFromRequiresAction(payload: unknown): PendingApproval[];
|
|
552
|
+
/** The approvals still awaiting a decision after replaying `events` in order. */
|
|
553
|
+
declare function projectPendingApprovals(events: SessionEvent[]): PendingApproval[];
|
|
554
|
+
|
|
555
|
+
/**
|
|
556
|
+
* The slash-command registry. A command is a SESSION / OPERATOR control — an
|
|
557
|
+
* action on the session or the UI (clear, compact, pause the goal, show help) —
|
|
558
|
+
* NOT a structured way to talk to the agent. The human↔agent channel stays
|
|
559
|
+
* plain chat; the palette only recognizes a leading "/" and never sends a
|
|
560
|
+
* command to the model.
|
|
561
|
+
*
|
|
562
|
+
* Two kinds, modeled by where the handler does its work:
|
|
563
|
+
* - CLIENT commands touch only the local UI (e.g. /help, /clear-view).
|
|
564
|
+
* - SERVER commands call the API through the SDK (e.g. /clear, /compact,
|
|
565
|
+
* /goal).
|
|
566
|
+
* Both are just `run(args, ctx)`; `ctx` exposes the client for server commands
|
|
567
|
+
* and the UI affordances (notice, openHelp, clearView, confirm) for both.
|
|
568
|
+
*/
|
|
569
|
+
/** A positional argument a command accepts after its name. */
|
|
570
|
+
type SlashArg = {
|
|
571
|
+
name: string;
|
|
572
|
+
/** Enter runs only once every required arg is present; otherwise autocompletes. */
|
|
573
|
+
required?: boolean;
|
|
574
|
+
/** Closed value set (rendered as a hint; validated by the command itself). */
|
|
575
|
+
oneOf?: readonly string[];
|
|
576
|
+
description?: string;
|
|
577
|
+
};
|
|
578
|
+
/** Transient feedback surfaced in the composer (generalized error line). */
|
|
579
|
+
type Notice = {
|
|
580
|
+
tone: "ok" | "error";
|
|
581
|
+
message: string;
|
|
582
|
+
};
|
|
583
|
+
/** Everything a command handler can reach. Assembled by the composer. */
|
|
584
|
+
type CommandContext = {
|
|
585
|
+
/** SDK-shaped client for server commands. */
|
|
586
|
+
client: SessionClientLike;
|
|
587
|
+
workspaceId: string;
|
|
588
|
+
/** Null before a session exists (server commands should guard on this). */
|
|
589
|
+
sessionId: string | null;
|
|
590
|
+
status: SessionStatus$1 | null;
|
|
591
|
+
/** The operator's permissions on this workspace (gates command visibility). */
|
|
592
|
+
permissions: Permission[];
|
|
593
|
+
/** Surface a transient ok/error notice in the composer. */
|
|
594
|
+
notice: (notice: Notice) => void;
|
|
595
|
+
/** Open the in-composer /help panel (rendered from the registry). */
|
|
596
|
+
openHelp: () => void;
|
|
597
|
+
/**
|
|
598
|
+
* Reset only the LOCAL timeline view — no server call. Returns whether a
|
|
599
|
+
* view-reset affordance was actually wired (and thus had an effect): the host
|
|
600
|
+
* surface supplies one via the composer's `onClearView` prop, and consoles
|
|
601
|
+
* that don't (no resettable local timeline) get `false`. The /clear-view
|
|
602
|
+
* command uses this to avoid reporting a false "cleared" success on a no-op.
|
|
603
|
+
*/
|
|
604
|
+
clearView: () => boolean;
|
|
605
|
+
/** Show the danger confirm bar; resolves true once the operator confirms. */
|
|
606
|
+
confirm: () => Promise<boolean>;
|
|
607
|
+
};
|
|
608
|
+
type CommandResult = {
|
|
609
|
+
status: "ok" | "error";
|
|
610
|
+
message?: string;
|
|
611
|
+
/**
|
|
612
|
+
* Keep the composer draft instead of clearing it on an ok result. Used when a
|
|
613
|
+
* command resolves to a no-op the operator may want to retry — e.g. canceling
|
|
614
|
+
* the /clear confirm bar returns ok (no error) but must NOT wipe the typed
|
|
615
|
+
* "/clear" draft. Default false: a successful command clears the draft.
|
|
616
|
+
*/
|
|
617
|
+
keepDraft?: boolean;
|
|
618
|
+
};
|
|
619
|
+
type SlashCommand = {
|
|
620
|
+
/** Primary token after the slash (no leading "/"). */
|
|
621
|
+
name: string;
|
|
622
|
+
/** Alternate tokens that resolve to this command. */
|
|
623
|
+
aliases?: readonly string[];
|
|
624
|
+
description: string;
|
|
625
|
+
args?: readonly SlashArg[];
|
|
626
|
+
/** Required permission; the command is hidden from the palette without it. */
|
|
627
|
+
permission?: Permission;
|
|
628
|
+
/** Destructive — the palette shows a confirm bar before running. */
|
|
629
|
+
danger?: boolean;
|
|
630
|
+
/**
|
|
631
|
+
* Dynamic availability beyond the permission gate (e.g. hide a server command
|
|
632
|
+
* until a session exists). Returning false hides the command.
|
|
633
|
+
*/
|
|
634
|
+
available?: (ctx: Pick<CommandContext, "sessionId" | "status" | "permissions">) => boolean;
|
|
635
|
+
/** Execute the command. Throwing is caught and surfaced as an error notice. */
|
|
636
|
+
run: (args: string[], ctx: CommandContext) => Promise<CommandResult> | CommandResult;
|
|
637
|
+
};
|
|
638
|
+
|
|
639
|
+
/**
|
|
640
|
+
* Parse a composer value into a command name + the rest. A command is
|
|
641
|
+
* recognized ONLY when the value's first character is "/" (the start token);
|
|
642
|
+
* anything else is plain chat and returns null.
|
|
643
|
+
*
|
|
644
|
+
* "/cl" -> { name: "cl", rest: "", hasTrailingSpace: false }
|
|
645
|
+
* "/goal " -> { name: "goal", rest: "", hasTrailingSpace: true }
|
|
646
|
+
* "/goal pause"-> { name: "goal", rest: "pause", hasTrailingSpace: false }
|
|
647
|
+
*/
|
|
648
|
+
type ParsedCommandLine = {
|
|
649
|
+
name: string;
|
|
650
|
+
rest: string;
|
|
651
|
+
/** True when the name token is closed by a space — arg-hint mode. */
|
|
652
|
+
hasTrailingSpace: boolean;
|
|
653
|
+
args: string[];
|
|
654
|
+
};
|
|
655
|
+
declare function parseCommandLine(value: string): ParsedCommandLine | null;
|
|
656
|
+
/** Whether the operator's permission set satisfies a command's gate. */
|
|
657
|
+
declare function hasPermission(required: Permission | undefined, permissions: Permission[]): boolean;
|
|
658
|
+
/** Match a command (by name or alias) against the value. */
|
|
659
|
+
declare function matchCommand(commands: readonly SlashCommand[], value: string): SlashCommand | null;
|
|
660
|
+
type FilterCtx = Pick<CommandContext, "sessionId" | "status" | "permissions">;
|
|
661
|
+
/**
|
|
662
|
+
* The commands visible for the current token + context. Permission-absent and
|
|
663
|
+
* `available()===false` commands are dropped entirely (a gated command is never
|
|
664
|
+
* shown, not shown-disabled). Filtering is a prefix match on name/alias.
|
|
665
|
+
*/
|
|
666
|
+
declare function filterCommands(commands: readonly SlashCommand[], token: string, ctx: FilterCtx): SlashCommand[];
|
|
667
|
+
/** Render a command's arg hint for the palette footer / help, e.g. "<pause|resume>". */
|
|
668
|
+
declare function argHint(args: readonly SlashArg[] | undefined): string;
|
|
669
|
+
/** The first required arg that has not yet been supplied, if any. */
|
|
670
|
+
declare function firstMissingRequiredArg(command: SlashCommand, args: string[]): SlashArg | null;
|
|
671
|
+
/**
|
|
672
|
+
* The default command set. Adding a command is one object literal here; the
|
|
673
|
+
* palette list, filter, arg-hint footer, and /help all render from this array.
|
|
674
|
+
* Apps concat their own commands via the ChatComposer `commands` prop.
|
|
675
|
+
*/
|
|
676
|
+
declare const defaultCommands: readonly SlashCommand[];
|
|
677
|
+
|
|
678
|
+
/**
|
|
679
|
+
* Context the composer supplies for command execution and visibility. The
|
|
680
|
+
* composer owns the UI affordances (notice/openHelp/clearView/confirm), so they
|
|
681
|
+
* are NOT part of this slice — the hook closes over them via `handlers`.
|
|
682
|
+
*/
|
|
683
|
+
type SlashCommandContext = Pick<CommandContext, "client" | "workspaceId" | "sessionId" | "status" | "permissions">;
|
|
684
|
+
/**
|
|
685
|
+
* UI affordances the composer supplies. `confirm` differs from the registry-
|
|
686
|
+
* facing {@link CommandContext.confirm} (which takes no args): the composer's
|
|
687
|
+
* confirm receives the command being run so the confirm bar renders from that
|
|
688
|
+
* exact command's identity. The hook bridges the two in {@link buildContext}.
|
|
689
|
+
*/
|
|
690
|
+
type SlashCommandHandlers = Pick<CommandContext, "notice" | "openHelp" | "clearView"> & {
|
|
691
|
+
confirm: (command: SlashCommand) => Promise<boolean>;
|
|
692
|
+
};
|
|
693
|
+
type ConfirmState = {
|
|
694
|
+
command: SlashCommand;
|
|
695
|
+
/** Resolve the pending confirm() promise. */
|
|
696
|
+
resolve: (confirmed: boolean) => void;
|
|
697
|
+
} | null;
|
|
698
|
+
type UseSlashCommandsOptions = {
|
|
699
|
+
commands: readonly SlashCommand[];
|
|
700
|
+
context: SlashCommandContext | undefined;
|
|
701
|
+
handlers: SlashCommandHandlers;
|
|
702
|
+
/** The current composer draft. */
|
|
703
|
+
value: string;
|
|
704
|
+
/** Replace the composer draft (autocomplete writes through this). */
|
|
705
|
+
setValue: (value: string) => void;
|
|
706
|
+
};
|
|
707
|
+
type UseSlashCommandsResult = {
|
|
708
|
+
/** Whether the palette is open (a command token is being typed). */
|
|
709
|
+
open: boolean;
|
|
710
|
+
/**
|
|
711
|
+
* Whether the draft is a slash-command attempt (matches a registered command)
|
|
712
|
+
* — true even after Escape dismisses the popover. The composer blocks its send
|
|
713
|
+
* path while this holds so a command can't be delivered to the agent as chat.
|
|
714
|
+
*/
|
|
715
|
+
isCommandDraft: boolean;
|
|
716
|
+
/** Commands shown for the current token + context, in display order. */
|
|
717
|
+
items: SlashCommand[];
|
|
718
|
+
/** Index into `items` of the highlighted row. */
|
|
719
|
+
highlight: number;
|
|
720
|
+
setHighlight: (index: number) => void;
|
|
721
|
+
/** The matched command once the name is closed by a space (arg-hint mode). */
|
|
722
|
+
activeCommand: SlashCommand | null;
|
|
723
|
+
/** The arg hint string for the active command (footer), or "". */
|
|
724
|
+
activeArgHint: string;
|
|
725
|
+
/**
|
|
726
|
+
* Key handler for the textarea. Returns true when it consumed the event
|
|
727
|
+
* (the composer must then NOT run its send path). Only consumes while open.
|
|
728
|
+
*/
|
|
729
|
+
onKeyDown: (event: KeyboardEvent<HTMLTextAreaElement>) => boolean;
|
|
730
|
+
/** Run the highlighted command (or the active command in arg-hint mode). */
|
|
731
|
+
runHighlighted: () => Promise<void>;
|
|
732
|
+
/**
|
|
733
|
+
* Run the command at an explicitly chosen index (a pointer click on a row).
|
|
734
|
+
* Bypasses the exact-match token heuristic that runHighlighted uses for
|
|
735
|
+
* keyboard Enter, so an explicit click always runs the clicked command.
|
|
736
|
+
*/
|
|
737
|
+
runAt: (index: number) => Promise<void>;
|
|
738
|
+
/** Autocomplete the highlighted command name + a trailing space. */
|
|
739
|
+
autocompleteHighlighted: () => void;
|
|
740
|
+
};
|
|
741
|
+
declare function useSlashCommands(options: UseSlashCommandsOptions): UseSlashCommandsResult;
|
|
742
|
+
|
|
743
|
+
type CommandPaletteProps = {
|
|
744
|
+
open: boolean;
|
|
745
|
+
items: SlashCommand[];
|
|
746
|
+
highlight: number;
|
|
747
|
+
/** Hover/click selects a row. */
|
|
748
|
+
onHighlight: (index: number) => void;
|
|
749
|
+
/** Click runs the row (same path as Enter). */
|
|
750
|
+
onRun: (index: number) => void;
|
|
751
|
+
/** Footer arg hint shown in arg-hint mode (e.g. "<pause|resume>"). */
|
|
752
|
+
argHintText: string;
|
|
753
|
+
/** id used for aria-activedescendant wiring from the textarea. */
|
|
754
|
+
listboxId: string;
|
|
755
|
+
};
|
|
756
|
+
/**
|
|
757
|
+
* The slash-command palette: a popover anchored above the textarea, rendered
|
|
758
|
+
* entirely from the filtered registry. Dark-first, Linear/Vercel-calm, using
|
|
759
|
+
* the opengeni#46 design tokens. Full keyboard nav lives in useSlashCommands;
|
|
760
|
+
* this component is presentational + aria.
|
|
761
|
+
*/
|
|
762
|
+
declare function CommandPalette({ open, items, highlight, onHighlight, onRun, argHintText, listboxId }: CommandPaletteProps): react_jsx_runtime.JSX.Element;
|
|
763
|
+
|
|
764
|
+
type ChatComposerProps = {
|
|
765
|
+
composer: ComposerState;
|
|
766
|
+
/** Current session status; shows the stop control while a turn runs. */
|
|
767
|
+
status?: SessionStatus$1 | null | undefined;
|
|
768
|
+
placeholder?: string | undefined;
|
|
769
|
+
disabled?: boolean | undefined;
|
|
770
|
+
autoFocus?: boolean | undefined;
|
|
771
|
+
/** Replaces the default keyboard hint under the field. */
|
|
772
|
+
hint?: string | undefined;
|
|
773
|
+
/** App controls (model picker, attach button, ...) in the footer row, replacing the hint. */
|
|
774
|
+
controlsStart?: ReactNode | undefined;
|
|
775
|
+
/** Content rendered above the textarea, inside the field chrome (e.g. attachment chips). */
|
|
776
|
+
header?: ReactNode | undefined;
|
|
777
|
+
/** Paste hook on the textarea (e.g. paste-image-to-attach). */
|
|
778
|
+
onPaste?: ((event: ClipboardEvent<HTMLTextAreaElement>) => void) | undefined;
|
|
779
|
+
/**
|
|
780
|
+
* Opt-in file attachments. When supplied (e.g. from {@link useFileAttachments}),
|
|
781
|
+
* the composer renders a built-in attach button (prepended to `controlsStart`),
|
|
782
|
+
* an attachment-chips strip (above the textarea, before any host `header`),
|
|
783
|
+
* routes paste through `addFromPaste` (image/* filter lives in the hook), and
|
|
784
|
+
* gates send while `uploading` so a message never departs without its files.
|
|
785
|
+
* Absent → no attachment UI renders and the composer behaves exactly as before.
|
|
786
|
+
*/
|
|
787
|
+
attachments?: UseFileAttachmentsResult | undefined;
|
|
788
|
+
className?: string | undefined;
|
|
789
|
+
/**
|
|
790
|
+
* Slash-command palette. Defaults to the built-in {@link defaultCommands};
|
|
791
|
+
* apps concat their own. Backward-compatible: when `commandContext` is absent
|
|
792
|
+
* the palette is inert and behavior is identical to before.
|
|
793
|
+
*/
|
|
794
|
+
commands?: readonly SlashCommand[] | undefined;
|
|
795
|
+
/**
|
|
796
|
+
* Wiring the palette needs to run server commands and gate visibility. The
|
|
797
|
+
* composer supplies notice/openHelp/clearView/confirm internally.
|
|
798
|
+
*/
|
|
799
|
+
commandContext?: SlashCommandContext | undefined;
|
|
800
|
+
/** Reset the local timeline view (the /clear-view command target). */
|
|
801
|
+
onClearView?: (() => void) | undefined;
|
|
802
|
+
};
|
|
803
|
+
/**
|
|
804
|
+
* The chat composer — the only human-to-agent input surface. Plain chat in,
|
|
805
|
+
* everything else is the agent's job. Enter sends, Shift+Enter breaks the
|
|
806
|
+
* line, and the stop control appears while a turn is running (sending while
|
|
807
|
+
* running is legitimate steering, so send stays available too).
|
|
808
|
+
*
|
|
809
|
+
* Typing a leading "/" opens the slash-command palette — SESSION/OPERATOR
|
|
810
|
+
* controls (clear, compact, pause goal, help), never a structured channel to
|
|
811
|
+
* the agent. The palette is purely additive: with no `commandContext` it is
|
|
812
|
+
* inert and the composer behaves exactly as before.
|
|
813
|
+
*/
|
|
814
|
+
declare function ChatComposer({ composer, status, placeholder, disabled, autoFocus, hint, controlsStart, header, onPaste, attachments, className, commands, commandContext, onClearView, }: ChatComposerProps): react_jsx_runtime.JSX.Element;
|
|
815
|
+
|
|
816
|
+
type MessageTimelineProps = {
|
|
817
|
+
/** Raw session events (projected internally) … */
|
|
818
|
+
events?: SessionEvent[] | undefined;
|
|
819
|
+
/** … or pre-projected items (e.g. from `useSessionEvents().timeline`). */
|
|
820
|
+
items?: TimelineItem[] | undefined;
|
|
821
|
+
/** Current session status; drives the live "working" indicator. */
|
|
822
|
+
status?: SessionStatus$1 | null | undefined;
|
|
823
|
+
/** Plug a markdown renderer for message bodies (e.g. streamdown). */
|
|
824
|
+
renderMessageText?: ((text: string, item: AgentMessageItem | UserMessageItem) => ReactNode) | undefined;
|
|
825
|
+
/** Drill into a spawned worker session. */
|
|
826
|
+
onOpenSession?: ((sessionId: string) => void) | undefined;
|
|
827
|
+
/** Follow new events when pinned to the bottom. Defaults to true. */
|
|
828
|
+
autoFollow?: boolean | undefined;
|
|
829
|
+
emptyState?: ReactNode | undefined;
|
|
830
|
+
className?: string | undefined;
|
|
831
|
+
};
|
|
832
|
+
/**
|
|
833
|
+
* The session timeline: chat messages with streaming deltas, collapsed
|
|
834
|
+
* activity clusters (reasoning, tool calls, sandbox work), spawned-worker
|
|
835
|
+
* cards, goal markers, and status transitions. Owns stick-to-bottom scrolling
|
|
836
|
+
* with a "jump to latest" affordance when the reader scrolls back.
|
|
837
|
+
*/
|
|
838
|
+
declare function MessageTimeline({ events, items, status, renderMessageText, onOpenSession, autoFollow, emptyState, className, }: MessageTimelineProps): react_jsx_runtime.JSX.Element;
|
|
839
|
+
|
|
840
|
+
type SessionStatusMeta = {
|
|
841
|
+
label: string;
|
|
842
|
+
/** Token-backed color classes for the dot and tinted badge. */
|
|
843
|
+
dotClassName: string;
|
|
844
|
+
badgeClassName: string;
|
|
845
|
+
/** Live states breathe; terminal states hold still. */
|
|
846
|
+
pulse: boolean;
|
|
847
|
+
};
|
|
848
|
+
declare const SESSION_STATUS_META: Record<SessionStatus$1, SessionStatusMeta>;
|
|
849
|
+
type SessionStatusProps = {
|
|
850
|
+
status: SessionStatus$1;
|
|
851
|
+
/** Override the label ("Running" -> "Deploying", ...). */
|
|
852
|
+
label?: string | undefined;
|
|
853
|
+
size?: "sm" | "md" | undefined;
|
|
854
|
+
className?: string | undefined;
|
|
855
|
+
};
|
|
856
|
+
/** Status badge with a breathing dot for live states. */
|
|
857
|
+
declare function SessionStatus({ status, label, size, className }: SessionStatusProps): react_jsx_runtime.JSX.Element;
|
|
858
|
+
type StatusDotProps = {
|
|
859
|
+
status: SessionStatus$1;
|
|
860
|
+
className?: string | undefined;
|
|
861
|
+
};
|
|
862
|
+
/** Just the dot — for dense rows and tiles. */
|
|
863
|
+
declare function StatusDot({ status, className }: StatusDotProps): react_jsx_runtime.JSX.Element;
|
|
864
|
+
|
|
865
|
+
type FleetTileProps = {
|
|
866
|
+
session: Session;
|
|
867
|
+
/** Overrides the derived title (metadata.title/name, else the initial message). */
|
|
868
|
+
title?: string | undefined;
|
|
869
|
+
/** Extra line under the title — e.g. "drift check" or the worker's task. */
|
|
870
|
+
subtitle?: string | undefined;
|
|
871
|
+
onOpen?: ((session: Session) => void) | undefined;
|
|
872
|
+
className?: string | undefined;
|
|
873
|
+
};
|
|
874
|
+
/** Best-effort display title for a session. */
|
|
875
|
+
declare function sessionDisplayTitle(session: Session): string;
|
|
876
|
+
/**
|
|
877
|
+
* One session in the fleet/manager view: title, live status, model, and
|
|
878
|
+
* recency — dense but calm. Running sessions carry a breathing status dot
|
|
879
|
+
* and a faint accent edge so the live ones read at a glance.
|
|
880
|
+
*/
|
|
881
|
+
declare function FleetTile({ session, title, subtitle, onOpen, className }: FleetTileProps): react_jsx_runtime.JSX.Element;
|
|
882
|
+
|
|
883
|
+
/** Merge class names with Tailwind-aware conflict resolution. */
|
|
884
|
+
declare function cn(...inputs: ClassValue[]): string;
|
|
885
|
+
|
|
886
|
+
/** Compact relative time: "now", "42s", "7m", "3h", "2d", then a date. */
|
|
887
|
+
declare function formatRelativeTime(iso: string, now?: Date): string;
|
|
888
|
+
/** Human-readable byte size: "512 B", "8.0 KB", "1.4 MB", "3 GB". */
|
|
889
|
+
declare function formatBytes(bytes: number): string;
|
|
890
|
+
/** Single-line preview of arbitrary text, for tiles and collapsed rows. */
|
|
891
|
+
declare function truncate(text: string, maxLength: number): string;
|
|
892
|
+
/** Render an unknown payload as readable text (pretty JSON when possible). */
|
|
893
|
+
declare function stringifyPayload(value: unknown): string;
|
|
894
|
+
/** JSON.parse that returns `undefined` instead of throwing. */
|
|
895
|
+
declare function tryParseJson(text: string): unknown;
|
|
896
|
+
|
|
897
|
+
export { type AgentMessageItem, ChatComposer, type ChatComposerProps, type ClientOverride, type CommandContext, CommandPalette, type CommandPaletteProps, type CommandResult, type ComposerMode, type ComposerSendExtras, type ComposerState, type ConfirmState, type FileAttachment, FleetTile, type FleetTileProps, type GoalItem, MessageTimeline, type MessageTimelineProps, type Notice, type NoticeItem, type OpenGeniContextValue, OpenGeniProvider, type OpenGeniProviderProps, type ParsedCommandLine, type PendingApproval, type ReasoningItem, SESSION_STATUS_META, type SandboxItem, type SessionClientLike, type SessionEventsConnectionState, SessionStatus, type SessionStatusItem, type SessionStatusMeta, type SessionStatusProps, type SlashArg, type SlashCommand, type SlashCommandContext, type SlashCommandHandlers, StatusDot, type StatusDotProps, type TimelineGroup, type TimelineItem, type ToolCallItem, type UseBillingUsageOptions, type UseBillingUsageResult, type UseComposerOptions, type UseEnvironmentsOptions, type UseEnvironmentsResult, type UseFileAttachmentsOptions, type UseFileAttachmentsResult, type UseGoalOptions, type UseGoalResult, type UsePacksOptions, type UsePacksResult, type UseScheduledTasksOptions, type UseScheduledTasksResult, type UseSessionControlOptions, type UseSessionControlResult, type UseSessionEventsOptions, type UseSessionEventsResult, type UseSessionOptions, type UseSessionResult, type UseSlashCommandsOptions, type UseSlashCommandsResult, type UseTurnQueueOptions, type UseTurnQueueResult, type UseWorkspaceSessionsOptions, type UseWorkspaceSessionsResult, type UseWorkspacesOptions, type UseWorkspacesResult, type UserMessageItem, type WorkerItem, activeTurnFromTurns, applyTurnEdit, applyTurnRemoval, applyTurnReorder, approvalsFromRequiresAction, argHint, buildTimeline, cn, compactPayloadPreview, composeSendInput, defaultCommands, extractSessionRef, filterCommands, firstMissingRequiredArg, formatBytes, formatRelativeTime, groupTimeline, hasPermission, isGoalEvent, isTurnQueueEvent, matchCommand, parseCommandLine, projectPendingApprovals, queueFromTurns, sessionDisplayTitle, sessionStatusFromEvents, shouldSubmitOnKey, stringifyPayload, toolDisplayName, truncate, tryParseJson, useBillingUsage, useComposer, useEnvironments, useFileAttachments, useGoal, useOpenGeni, useOpenGeniClient, usePacks, useScheduledTasks, useSession, useSessionControl, useSessionEvents, useSlashCommands, useTurnQueue, useWorkspaceSessions, useWorkspaces };
|