@alisio/sdk 0.1.0-alpha.9 → 0.1.1
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 +6 -0
- package/dist/index.d.ts +1565 -3
- package/dist/index.js +53 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -44,7 +44,233 @@ export type UiBlock = {
|
|
|
44
44
|
} | {
|
|
45
45
|
kind: "markdown";
|
|
46
46
|
text: string;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* A file change: a unified `patch`, or `before`/`after` contents when no patch is available.
|
|
50
|
+
* Producers bound the payload (about 200 KB).
|
|
51
|
+
*/
|
|
52
|
+
| {
|
|
53
|
+
kind: "diff";
|
|
54
|
+
path?: string;
|
|
55
|
+
patch?: string;
|
|
56
|
+
before?: string;
|
|
57
|
+
after?: string;
|
|
58
|
+
lang?: string;
|
|
59
|
+
caption?: string;
|
|
60
|
+
}
|
|
61
|
+
/** Output of a command. `output` may contain ANSI escapes; producers bound it (about 256 KB). */
|
|
62
|
+
| {
|
|
63
|
+
kind: "terminal";
|
|
64
|
+
command?: string;
|
|
65
|
+
cwd?: string;
|
|
66
|
+
output: string;
|
|
67
|
+
exitCode?: number;
|
|
68
|
+
durationMs?: number;
|
|
69
|
+
truncated?: boolean;
|
|
70
|
+
}
|
|
71
|
+
/** Mermaid diagram source; text surfaces show the source verbatim. */
|
|
72
|
+
| {
|
|
73
|
+
kind: "mermaid";
|
|
74
|
+
source: string;
|
|
75
|
+
title?: string;
|
|
76
|
+
}
|
|
77
|
+
/** A LaTeX formula; `display` requests block (not inline) layout. */
|
|
78
|
+
| {
|
|
79
|
+
kind: "math";
|
|
80
|
+
latex: string;
|
|
81
|
+
display?: boolean;
|
|
82
|
+
}
|
|
83
|
+
/** Any JSON value, shown as a collapsible tree by rich surfaces (bounded to about 256 KB). */
|
|
84
|
+
| {
|
|
85
|
+
kind: "json";
|
|
86
|
+
value: unknown;
|
|
87
|
+
collapsedDepth?: number;
|
|
88
|
+
caption?: string;
|
|
89
|
+
}
|
|
90
|
+
/** Test run results grouped by suite. */
|
|
91
|
+
| {
|
|
92
|
+
kind: "test-results";
|
|
93
|
+
framework?: string;
|
|
94
|
+
durationMs?: number;
|
|
95
|
+
suites: Array<{
|
|
96
|
+
name: string;
|
|
97
|
+
file?: string;
|
|
98
|
+
cases: TestCaseResult[];
|
|
99
|
+
}>;
|
|
100
|
+
}
|
|
101
|
+
/** A checklist of steps with their current status. */
|
|
102
|
+
| {
|
|
103
|
+
kind: "progress";
|
|
104
|
+
title?: string;
|
|
105
|
+
steps: ProgressStep[];
|
|
106
|
+
}
|
|
107
|
+
/** A published, downloadable artifact (`ToolContext.artifacts`). Text surfaces show one line. */
|
|
108
|
+
| {
|
|
109
|
+
kind: "artifact";
|
|
110
|
+
artifact: ArtifactRef;
|
|
47
111
|
};
|
|
112
|
+
/** Kind of a published artifact; decides the icon, the label and the renderer. */
|
|
113
|
+
export type ArtifactKind = "dashboard" | "document" | "spreadsheet" | "image" | "data" | "code" | "archive" | "file";
|
|
114
|
+
/** Public reference to a published artifact. Never carries absolute paths. */
|
|
115
|
+
export interface ArtifactRef {
|
|
116
|
+
/** `art_<ULID>`. */
|
|
117
|
+
id: string;
|
|
118
|
+
/** Root session that owns the artifact. */
|
|
119
|
+
sessionId: string;
|
|
120
|
+
title: string;
|
|
121
|
+
/** Download name, e.g. `report.md`, or `site.zip` for a multi-file artifact. */
|
|
122
|
+
fileName: string;
|
|
123
|
+
kind: ArtifactKind;
|
|
124
|
+
mimeType: string;
|
|
125
|
+
bytes: number;
|
|
126
|
+
/** More than 1 for multi-file dashboards. */
|
|
127
|
+
fileCount: number;
|
|
128
|
+
/** Decided by the host from the artifact kind and size. */
|
|
129
|
+
previewable: boolean;
|
|
130
|
+
createdAt: number;
|
|
131
|
+
/** Published from a failed execution (`publishOnError`). */
|
|
132
|
+
partial?: boolean;
|
|
133
|
+
status: "ready" | "deleted" | "expired";
|
|
134
|
+
}
|
|
135
|
+
/** Input of `ArtifactPublisher.publish`: files already written by the caller. */
|
|
136
|
+
export interface ArtifactPublishInput {
|
|
137
|
+
/** Absolute path of a file or a directory owned by the caller. */
|
|
138
|
+
source: string;
|
|
139
|
+
title?: string;
|
|
140
|
+
/** Entry file for a directory; defaults to `index.html` when present. */
|
|
141
|
+
entry?: string;
|
|
142
|
+
}
|
|
143
|
+
/** Publishes caller-owned files as downloadable artifacts of the current session. */
|
|
144
|
+
export interface ArtifactPublisher {
|
|
145
|
+
/** Validates, copies and registers; throws with a user-readable message on rejection. */
|
|
146
|
+
publish(input: ArtifactPublishInput): Promise<ArtifactRef>;
|
|
147
|
+
/** Creates a single-file artifact from text the tool already holds. */
|
|
148
|
+
publishText(input: {
|
|
149
|
+
fileName: string;
|
|
150
|
+
title?: string;
|
|
151
|
+
text: string;
|
|
152
|
+
}): Promise<ArtifactRef>;
|
|
153
|
+
}
|
|
154
|
+
/** Finer-grained permissions inside an effect (closed union; extended additively). */
|
|
155
|
+
export type AnalysisCapability = "analysis.run" | "analysis.install";
|
|
156
|
+
/**
|
|
157
|
+
* What an `analysis.install` approval shows (phase 4): the optional Python packages that would be
|
|
158
|
+
* installed, an estimate of the download and that it needs the network. Always asks, only `once`.
|
|
159
|
+
*/
|
|
160
|
+
export interface InstallPreview {
|
|
161
|
+
extras: "analysis" | "science";
|
|
162
|
+
/** Top-level packages, e.g. `pandas`, `numpy`. */
|
|
163
|
+
packages: string[];
|
|
164
|
+
/** Pinned distributions in the lockfile (the packages plus their dependencies). */
|
|
165
|
+
packageCount: number;
|
|
166
|
+
/** Rough download size (wheels only); an estimate, not a measurement. */
|
|
167
|
+
estimatedBytes: number;
|
|
168
|
+
network: true;
|
|
169
|
+
}
|
|
170
|
+
/** What a tool asks the host to approve before installing packages (capability `analysis.install`). */
|
|
171
|
+
export type InstallApprover = (request: InstallPreview) => Promise<"once" | "deny">;
|
|
172
|
+
/** A persisted capability decision as exposed by the web API. */
|
|
173
|
+
export interface CapabilityGrantWire {
|
|
174
|
+
id: string;
|
|
175
|
+
capability: AnalysisCapability;
|
|
176
|
+
sessionId: string;
|
|
177
|
+
scope: "once" | "session";
|
|
178
|
+
decision: "allow" | "deny";
|
|
179
|
+
source: "tui" | "web" | "flag" | "headless-grant";
|
|
180
|
+
createdAt: number;
|
|
181
|
+
revokedAt?: number;
|
|
182
|
+
}
|
|
183
|
+
/** Tabular formats the data tools ingest into one SQLite file per dataset. */
|
|
184
|
+
export type DatasetFormat = "csv" | "tsv" | "json" | "jsonl" | "xlsx";
|
|
185
|
+
/** A dataset (a CSV/TSV/JSON/JSONL/XLSX file ingested into SQLite). Never carries paths. */
|
|
186
|
+
export interface DatasetRef {
|
|
187
|
+
/** `ds_<ULID>`. */
|
|
188
|
+
id: string;
|
|
189
|
+
/** Original file name. */
|
|
190
|
+
name: string;
|
|
191
|
+
format: DatasetFormat;
|
|
192
|
+
bytes: number;
|
|
193
|
+
sha256: string;
|
|
194
|
+
sheets: Array<{
|
|
195
|
+
name: string;
|
|
196
|
+
table: string;
|
|
197
|
+
rows: number;
|
|
198
|
+
columns: number;
|
|
199
|
+
}>;
|
|
200
|
+
}
|
|
201
|
+
/** Column of a dataset table with the statistics computed at ingestion. */
|
|
202
|
+
export interface DatasetColumnWire {
|
|
203
|
+
name: string;
|
|
204
|
+
/** Original header text. */
|
|
205
|
+
label: string;
|
|
206
|
+
/** A hint (`integer`, `real`, `date`, `boolean`, `text`); values are stored without conversion. */
|
|
207
|
+
type: string;
|
|
208
|
+
nulls: number;
|
|
209
|
+
distinct: number;
|
|
210
|
+
distinctExact: boolean;
|
|
211
|
+
min?: string;
|
|
212
|
+
max?: string;
|
|
213
|
+
mean?: number;
|
|
214
|
+
textFallbacks: number;
|
|
215
|
+
top: Array<{
|
|
216
|
+
value: string;
|
|
217
|
+
count: number;
|
|
218
|
+
}>;
|
|
219
|
+
}
|
|
220
|
+
/** `GET /api/datasets/:did`: the dataset with the schema and statistics of every sheet. */
|
|
221
|
+
export interface DatasetDetailWire extends DatasetRef {
|
|
222
|
+
ingestVersion: number;
|
|
223
|
+
encoding?: string;
|
|
224
|
+
delimiter?: string;
|
|
225
|
+
sheetDetails: Array<{
|
|
226
|
+
name: string;
|
|
227
|
+
table: string;
|
|
228
|
+
rows: number;
|
|
229
|
+
columns: DatasetColumnWire[];
|
|
230
|
+
}>;
|
|
231
|
+
/** Sorting and filtering are disabled above this many rows (`analysis.data.maxInteractiveRows`). */
|
|
232
|
+
maxInteractiveRows: number;
|
|
233
|
+
}
|
|
234
|
+
/** `GET /api/datasets/:did/rows`: one page of a sheet (keyset-paginated). */
|
|
235
|
+
export interface DatasetRowsPage {
|
|
236
|
+
columns: Array<{
|
|
237
|
+
name: string;
|
|
238
|
+
label: string;
|
|
239
|
+
type: string;
|
|
240
|
+
}>;
|
|
241
|
+
/** Cell values as stored: numbers stay numbers, everything else is text, empty cells are null. */
|
|
242
|
+
rows: Array<Array<string | number | null>>;
|
|
243
|
+
/** 1-based position of the first row in the (unfiltered, unsorted) sheet, per row. */
|
|
244
|
+
rowids: number[];
|
|
245
|
+
/** Opaque cursor for the next page; absent on the last page. */
|
|
246
|
+
next?: string;
|
|
247
|
+
/** Rows in the sheet. */
|
|
248
|
+
total: number;
|
|
249
|
+
/** Rows matching the filter (first page only). */
|
|
250
|
+
matched?: number;
|
|
251
|
+
/** Sorting and filtering were ignored because the sheet exceeds `maxInteractiveRows`. */
|
|
252
|
+
interactive: boolean;
|
|
253
|
+
}
|
|
254
|
+
/** One case of a `{ kind: "test-results" }` UI block. */
|
|
255
|
+
export interface TestCaseResult {
|
|
256
|
+
name: string;
|
|
257
|
+
status: "passed" | "failed" | "skipped" | "todo";
|
|
258
|
+
durationMs?: number;
|
|
259
|
+
error?: string;
|
|
260
|
+
line?: number;
|
|
261
|
+
}
|
|
262
|
+
/** One step of a `{ kind: "progress" }` UI block. */
|
|
263
|
+
export interface ProgressStep {
|
|
264
|
+
label: string;
|
|
265
|
+
status: "pending" | "running" | "completed" | "failed" | "cancelled";
|
|
266
|
+
detail?: string;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Every `UiBlock` kind, for surfaces that dispatch on the kind at runtime (renderer registries,
|
|
270
|
+
* validators). Surfaces must still render an unknown kind as text: blocks persisted by a newer
|
|
271
|
+
* Alisio can be replayed by an older one.
|
|
272
|
+
*/
|
|
273
|
+
export declare const UI_BLOCK_KINDS: readonly ["table", "key-value", "tree", "code", "markdown", "diff", "terminal", "mermaid", "math", "json", "test-results", "progress", "artifact"];
|
|
48
274
|
export interface ToolResult {
|
|
49
275
|
content: Array<{
|
|
50
276
|
type: "text";
|
|
@@ -67,7 +293,11 @@ export interface ToolResult {
|
|
|
67
293
|
export interface Attachment {
|
|
68
294
|
kind: "image";
|
|
69
295
|
mimeType: string;
|
|
70
|
-
/**
|
|
296
|
+
/**
|
|
297
|
+
* Base64-encoded bytes, no `data:` prefix. Required: providers and plugins read it directly,
|
|
298
|
+
* and no runtime check yet guarantees an alternative source. Content-addressed uploads travel
|
|
299
|
+
* as `BlobRef` and are resolved to `data` by the host before they reach an `Attachment`.
|
|
300
|
+
*/
|
|
71
301
|
data: string;
|
|
72
302
|
bytes: number;
|
|
73
303
|
width?: number;
|
|
@@ -84,6 +314,8 @@ export type Message =
|
|
|
84
314
|
summary?: boolean;
|
|
85
315
|
display?: string;
|
|
86
316
|
attachments?: Attachment[];
|
|
317
|
+
/** Datasets attached to this prompt (UI chips); the model sees their text summary in `text`. */
|
|
318
|
+
datasets?: DatasetRef[];
|
|
87
319
|
} | {
|
|
88
320
|
role: "assistant";
|
|
89
321
|
text: string;
|
|
@@ -235,6 +467,28 @@ export interface ToolContext {
|
|
|
235
467
|
session?: string;
|
|
236
468
|
/** Who is asking, e.g. an agent path such as "general › explore" (child sessions only). */
|
|
237
469
|
label?: string;
|
|
470
|
+
/**
|
|
471
|
+
* Resolves a tool path under the session's mediated path policy (workspace plus declared extra
|
|
472
|
+
* directories). Out-of-root paths ask for directory approval when the host allows it; hosts that
|
|
473
|
+
* do not inject this fall back to the workspace-only `safePath` policy.
|
|
474
|
+
*/
|
|
475
|
+
resolvePath?: (path: string) => Promise<string>;
|
|
476
|
+
/** Run and tool call that issued this execution, when run by the agent loop. */
|
|
477
|
+
runId?: string;
|
|
478
|
+
callId?: string;
|
|
479
|
+
/**
|
|
480
|
+
* Emits a durable run event of the call's run. Only `exit_plan` receives it (`plan_proposed`,
|
|
481
|
+
* `plan_decided`); other tools, plugin tools included, never do.
|
|
482
|
+
*/
|
|
483
|
+
emitEvent?: <K extends "plan_proposed" | "plan_decided">(type: K, data: RunEventDataMap[K]) => void;
|
|
484
|
+
/** Present when the host has an artifact store for this session (built-in tools only in v1). */
|
|
485
|
+
artifacts?: ArtifactPublisher;
|
|
486
|
+
/**
|
|
487
|
+
* Asks the user to approve installing the optional Python packages (capability
|
|
488
|
+
* `analysis.install`; built-in tools only). Resolves `deny` where nobody can be asked
|
|
489
|
+
* (headless, `--read-only`), because no flag grants an installation.
|
|
490
|
+
*/
|
|
491
|
+
approveInstall?: InstallApprover;
|
|
238
492
|
}
|
|
239
493
|
export interface ToolDefinition {
|
|
240
494
|
name: string;
|
|
@@ -245,17 +499,286 @@ export interface ToolDefinition {
|
|
|
245
499
|
/** May run concurrently with other read/concurrent calls of the same turn (e.g. delegation). */
|
|
246
500
|
concurrent?: boolean;
|
|
247
501
|
paths?: (input: Record<string, unknown>) => string[];
|
|
502
|
+
/**
|
|
503
|
+
* Finer-grained permission inside `effect`: a broad grant of `effect` covers it, a grant of the
|
|
504
|
+
* capability never widens `effect`. Honored for built-in tools only (ignored for plugins in v1).
|
|
505
|
+
*/
|
|
506
|
+
capability?: AnalysisCapability;
|
|
248
507
|
execute(input: Record<string, unknown>, context: ToolContext): Promise<ToolResult>;
|
|
249
508
|
}
|
|
509
|
+
/**
|
|
510
|
+
* One event of an agent run, as delivered to `onEvent`, plugins and `alisio run --json` (JSONL).
|
|
511
|
+
* `schemaVersion` stays `1` while changes are additive (new optional fields, new event types);
|
|
512
|
+
* consumers must ignore unknown fields and unknown `type` values. See `KnownRunEvent` for the
|
|
513
|
+
* typed payloads of the events the core emits today.
|
|
514
|
+
*/
|
|
250
515
|
export interface RunEvent {
|
|
251
516
|
schemaVersion: 1;
|
|
252
517
|
runId: string;
|
|
253
518
|
sessionId: string;
|
|
519
|
+
/** Per-run counter starting at 1 (restarts on every run; not unique within a session). */
|
|
254
520
|
seq: number;
|
|
255
521
|
type: string;
|
|
256
522
|
timestamp: string;
|
|
257
523
|
data: unknown;
|
|
524
|
+
/**
|
|
525
|
+
* Stable id of a durable event: the persisted global `events.seq`, as a decimal string. Absent
|
|
526
|
+
* for ephemeral events (`EphemeralRunEventType`) and when the host store does not report it.
|
|
527
|
+
*/
|
|
528
|
+
eventId?: string;
|
|
529
|
+
/** Embedder-supplied correlation id (for example an HTTP `X-Request-Id`), when given. */
|
|
530
|
+
correlationId?: string;
|
|
258
531
|
}
|
|
532
|
+
/** What a `run_failed` event with `code: "timeout"` says about the limit that stopped the run. */
|
|
533
|
+
export interface RunTimeoutInfo {
|
|
534
|
+
/** `run`: the whole-run limit (`limits.timeoutMs`); `first_token`: a silent request (`limits.firstTokenTimeoutMs`). */
|
|
535
|
+
kind: "run" | "first_token";
|
|
536
|
+
/** The limit that was reached, in milliseconds. */
|
|
537
|
+
ms: number;
|
|
538
|
+
/** Model the run was using, when known. */
|
|
539
|
+
model?: string;
|
|
540
|
+
/** Short provider label (the host of an OpenAI-compatible endpoint), when known. */
|
|
541
|
+
provider?: string;
|
|
542
|
+
/** What the run was doing: waiting for the first token of a request, streaming, or running a tool. */
|
|
543
|
+
stage: "waiting_model" | "streaming" | "tool" | "other";
|
|
544
|
+
/** The tool that was running when `stage` is `tool`. */
|
|
545
|
+
tool?: string;
|
|
546
|
+
/** Nothing had been produced yet: the very first model request of the run got no answer. */
|
|
547
|
+
firstRequest?: boolean;
|
|
548
|
+
/**
|
|
549
|
+
* `first_token` only: how many times the same request was sent (the first try plus the silent
|
|
550
|
+
* retries of `limits.firstTokenRetries`); `1` when retrying is disabled.
|
|
551
|
+
*/
|
|
552
|
+
attempts?: number;
|
|
553
|
+
}
|
|
554
|
+
/** What a `run_failed` event with `code: "output_truncated"` says about the limit that cut it. */
|
|
555
|
+
export interface RunTruncationInfo {
|
|
556
|
+
/** How many responses were cut off (the first plus every recovery). */
|
|
557
|
+
attempts: number;
|
|
558
|
+
/** The output-token budget of the cut requests (the effective one, see `source`). */
|
|
559
|
+
maxOutputTokens: number;
|
|
560
|
+
/** Where that budget came from: the user, the model's catalog, or the default. */
|
|
561
|
+
source?: "user" | "model" | "default";
|
|
562
|
+
/** The model whose responses were cut. */
|
|
563
|
+
model?: string;
|
|
564
|
+
}
|
|
565
|
+
/**
|
|
566
|
+
* Payload of each event type the core emits today, keyed by `RunEvent.type`. Additive: new
|
|
567
|
+
* types and new optional fields may appear; existing fields keep their meaning.
|
|
568
|
+
*/
|
|
569
|
+
export interface RunEventDataMap {
|
|
570
|
+
run_started: {
|
|
571
|
+
model: string;
|
|
572
|
+
};
|
|
573
|
+
text_delta: {
|
|
574
|
+
delta: string;
|
|
575
|
+
};
|
|
576
|
+
/** Provider-visible reasoning text; display only, never persisted. */
|
|
577
|
+
reasoning_delta: {
|
|
578
|
+
delta: string;
|
|
579
|
+
};
|
|
580
|
+
turn_completed: {
|
|
581
|
+
/** 1-based turn number within the run. */
|
|
582
|
+
turn: number;
|
|
583
|
+
/** Cumulative input + output tokens of the run so far. */
|
|
584
|
+
tokens: number;
|
|
585
|
+
calls: number;
|
|
586
|
+
model: string;
|
|
587
|
+
usage?: Usage;
|
|
588
|
+
/** Milliseconds from sending the provider request to its completed response. */
|
|
589
|
+
durationMs?: number;
|
|
590
|
+
/** Milliseconds to the first streamed text/reasoning delta; absent when nothing streamed. */
|
|
591
|
+
ttftMs?: number;
|
|
592
|
+
};
|
|
593
|
+
tool_started: {
|
|
594
|
+
id: string;
|
|
595
|
+
name: string;
|
|
596
|
+
arguments: string;
|
|
597
|
+
effect: Effect;
|
|
598
|
+
};
|
|
599
|
+
/** `data` is whatever the tool passed to `ToolContext.emit`. */
|
|
600
|
+
tool_progress: {
|
|
601
|
+
id: string;
|
|
602
|
+
data: unknown;
|
|
603
|
+
};
|
|
604
|
+
tool_completed: {
|
|
605
|
+
id: string;
|
|
606
|
+
name: string;
|
|
607
|
+
isError: boolean;
|
|
608
|
+
durationMs: number;
|
|
609
|
+
/** Text projection of the result, capped at 2,000 characters. */
|
|
610
|
+
preview: string;
|
|
611
|
+
};
|
|
612
|
+
approval_requested: {
|
|
613
|
+
id: string;
|
|
614
|
+
name: string;
|
|
615
|
+
effect: "write" | "process" | "external";
|
|
616
|
+
label?: string;
|
|
617
|
+
/** The approval is for this capability (not the whole effect). */
|
|
618
|
+
capability?: AnalysisCapability;
|
|
619
|
+
/** `analysis.install` approvals: the packages, the size estimate and the network need. */
|
|
620
|
+
install?: InstallPreview;
|
|
621
|
+
};
|
|
622
|
+
approval_resolved: {
|
|
623
|
+
id: string;
|
|
624
|
+
name: string;
|
|
625
|
+
effect: "write" | "process" | "external";
|
|
626
|
+
decision: "once" | "session" | "deny";
|
|
627
|
+
capability?: AnalysisCapability;
|
|
628
|
+
/** A `session` capability decision was stored and survives restarts. */
|
|
629
|
+
persisted?: boolean;
|
|
630
|
+
};
|
|
631
|
+
/**
|
|
632
|
+
* A tool published an artifact. `path` is the absolute local path of the file (or the entry of a
|
|
633
|
+
* multi-file artifact) for local consumers (TUI, JSONL); web clients ignore it.
|
|
634
|
+
*/
|
|
635
|
+
artifact_published: {
|
|
636
|
+
artifact: ArtifactRef;
|
|
637
|
+
path: string;
|
|
638
|
+
callId?: string;
|
|
639
|
+
executionId?: string;
|
|
640
|
+
};
|
|
641
|
+
/** The plan agent proposed a plan with `exit_plan` and is waiting for the user's decision. */
|
|
642
|
+
plan_proposed: {
|
|
643
|
+
callId: string;
|
|
644
|
+
planId: string;
|
|
645
|
+
revision: number;
|
|
646
|
+
hash: string;
|
|
647
|
+
title: string;
|
|
648
|
+
/** The `plan.md` artifact (absent when publishing failed). */
|
|
649
|
+
artifactId?: string;
|
|
650
|
+
};
|
|
651
|
+
/** The user decided: approve (implementation follows), skip (stay in plan) or add context. */
|
|
652
|
+
plan_decided: {
|
|
653
|
+
callId: string;
|
|
654
|
+
planId: string;
|
|
655
|
+
hash: string;
|
|
656
|
+
decision: "approve" | "skip" | "context";
|
|
657
|
+
};
|
|
658
|
+
run_completed: {
|
|
659
|
+
tokens: number;
|
|
660
|
+
text: string;
|
|
661
|
+
truncated?: boolean;
|
|
662
|
+
};
|
|
663
|
+
/**
|
|
664
|
+
* `maxOutputTokens` is the effective budget of the cut request; `source` says whether it was
|
|
665
|
+
* set by the user, taken from the model's catalog, or the default.
|
|
666
|
+
*/
|
|
667
|
+
response_truncated: {
|
|
668
|
+
turn: number;
|
|
669
|
+
maxOutputTokens: number;
|
|
670
|
+
source?: "user" | "model" | "default";
|
|
671
|
+
};
|
|
672
|
+
/**
|
|
673
|
+
* A model request stayed completely silent for `limits.firstTokenTimeoutMs` and the same
|
|
674
|
+
* request is sent again (no new turn, nothing appended to the session). `attempt` is the
|
|
675
|
+
* retry about to start (1-based), `of` the retries allowed (`limits.firstTokenRetries`) and
|
|
676
|
+
* `afterMs` how long the aborted request had been silent.
|
|
677
|
+
*/
|
|
678
|
+
request_retry: {
|
|
679
|
+
attempt: number;
|
|
680
|
+
of: number;
|
|
681
|
+
reason: "first_token_timeout";
|
|
682
|
+
afterMs: number;
|
|
683
|
+
};
|
|
684
|
+
/**
|
|
685
|
+
* A model response was cut off by the output-token limit before it was usable (no text and no
|
|
686
|
+
* tool call, or a tool call whose arguments are incomplete) and the same turn is requested
|
|
687
|
+
* again with a short continuation notice. The truncated tool calls were discarded, never
|
|
688
|
+
* executed or persisted, and the retry is not a turn. `attempt` is the recovery about to start
|
|
689
|
+
* (1-based), `of` the recoveries allowed (`limits.truncationRecoveries`), `reason` what was
|
|
690
|
+
* lost, and `effort` the lowered reasoning effort of that request, when one was applied.
|
|
691
|
+
*/
|
|
692
|
+
truncation_recovery: {
|
|
693
|
+
attempt: number;
|
|
694
|
+
of: number;
|
|
695
|
+
reason: "tool_call_cut" | "empty_response";
|
|
696
|
+
maxOutputTokens: number;
|
|
697
|
+
effort?: string;
|
|
698
|
+
};
|
|
699
|
+
run_turns_exceeded: {
|
|
700
|
+
turns: number;
|
|
701
|
+
maxTurns: number;
|
|
702
|
+
};
|
|
703
|
+
/**
|
|
704
|
+
* The run failed. `error` is always a human-readable message. `code: "timeout"` (with `timeout`)
|
|
705
|
+
* marks a run stopped by a time limit instead of a provider or tool error;
|
|
706
|
+
* `code: "output_truncated"` (with `truncation`) a run whose responses kept being cut off by
|
|
707
|
+
* the output-token limit after the allowed recoveries. These fields are additive and absent
|
|
708
|
+
* for every other failure.
|
|
709
|
+
*/
|
|
710
|
+
run_failed: {
|
|
711
|
+
error: string;
|
|
712
|
+
code?: "timeout" | "output_truncated";
|
|
713
|
+
timeout?: RunTimeoutInfo;
|
|
714
|
+
truncation?: RunTruncationInfo;
|
|
715
|
+
};
|
|
716
|
+
run_cancelled: {
|
|
717
|
+
error: string;
|
|
718
|
+
};
|
|
719
|
+
model_changed: {
|
|
720
|
+
model: string;
|
|
721
|
+
previous: string;
|
|
722
|
+
};
|
|
723
|
+
compaction_started: {
|
|
724
|
+
reason: "manual" | "auto";
|
|
725
|
+
before: number;
|
|
726
|
+
messages: number;
|
|
727
|
+
};
|
|
728
|
+
compaction_completed: {
|
|
729
|
+
reason: "manual" | "auto";
|
|
730
|
+
before: number;
|
|
731
|
+
after: number;
|
|
732
|
+
replaced: number;
|
|
733
|
+
structured: boolean;
|
|
734
|
+
summarizedTokens: number;
|
|
735
|
+
checkpointTokens: number;
|
|
736
|
+
/** Per-plugin `CompactionOutcome.report`, keyed by plugin id. */
|
|
737
|
+
plugins: Record<string, Record<string, unknown>>;
|
|
738
|
+
/** The summary hit its output budget and was accepted as partial. */
|
|
739
|
+
partial?: true;
|
|
740
|
+
};
|
|
741
|
+
compaction_skipped: {
|
|
742
|
+
reason: "manual" | "auto";
|
|
743
|
+
before: number;
|
|
744
|
+
detail: string;
|
|
745
|
+
};
|
|
746
|
+
compaction_failed: {
|
|
747
|
+
reason: "manual" | "auto";
|
|
748
|
+
error: string;
|
|
749
|
+
};
|
|
750
|
+
/** Tool results clipped in place to fit the context budget. */
|
|
751
|
+
context_reduced: {
|
|
752
|
+
messages: number;
|
|
753
|
+
};
|
|
754
|
+
session_context_injected: {
|
|
755
|
+
tokens: number;
|
|
756
|
+
sources: string[];
|
|
757
|
+
};
|
|
758
|
+
plugin_hook_failed: {
|
|
759
|
+
source: string;
|
|
760
|
+
hook: string;
|
|
761
|
+
error: string;
|
|
762
|
+
continued: true;
|
|
763
|
+
};
|
|
764
|
+
}
|
|
765
|
+
/** Every `RunEvent.type` the core emits today. `RunEvent.type` itself stays `string`. */
|
|
766
|
+
export type RunEventType = keyof RunEventDataMap;
|
|
767
|
+
/** Event types never persisted to the session store (and therefore without `eventId`). */
|
|
768
|
+
export type EphemeralRunEventType = "text_delta" | "reasoning_delta" | "tool_progress";
|
|
769
|
+
export declare const EPHEMERAL_RUN_EVENT_TYPES: readonly EphemeralRunEventType[];
|
|
770
|
+
/** True for streaming-only event types that are never persisted. */
|
|
771
|
+
export declare function isEphemeralRunEventType(type: string): type is EphemeralRunEventType;
|
|
772
|
+
/**
|
|
773
|
+
* Discriminated view of `RunEvent` with typed `data`, for consumers that narrow on `type`.
|
|
774
|
+
* Every member is assignable to `RunEvent`; events of unknown types remain plain `RunEvent`s.
|
|
775
|
+
*/
|
|
776
|
+
export type KnownRunEvent = {
|
|
777
|
+
[K in RunEventType]: RunEvent & {
|
|
778
|
+
type: K;
|
|
779
|
+
data: RunEventDataMap[K];
|
|
780
|
+
};
|
|
781
|
+
}[RunEventType];
|
|
259
782
|
/** Generic structured checkpoint produced by core context compaction. */
|
|
260
783
|
export interface CompactionCheckpoint {
|
|
261
784
|
goal: string;
|
|
@@ -370,14 +893,33 @@ export interface MascotProvider {
|
|
|
370
893
|
id: string;
|
|
371
894
|
render(ctx: MascotContext): string | string[];
|
|
372
895
|
}
|
|
373
|
-
|
|
896
|
+
/**
|
|
897
|
+
* Catalog grouping a plugin declares in its manifest; the host derives `"model-provider"` from
|
|
898
|
+
* provider registrations. The TUI groups `/plugins` by the first declared category. Accepted
|
|
899
|
+
* values:
|
|
900
|
+
* - `"model-provider"` — registers model providers.
|
|
901
|
+
* - `"methodology-harness"` — bundles a development-methodology workflow.
|
|
902
|
+
* - `"memory"` — persistent memory, recollection and session summaries.
|
|
903
|
+
* - `"subagents"` — delegation, child sessions and agent management.
|
|
904
|
+
* - `"search"` — web or vector search providers.
|
|
905
|
+
* - `"tools"` — general-purpose tool collections.
|
|
906
|
+
* - `"security"` — audit, sandbox or permission tooling.
|
|
907
|
+
* - `"analytics"` — usage/metrics instrumentation (session stats, cost tracking).
|
|
908
|
+
* - `"mcp"` — MCP-server management or bundling helpers.
|
|
909
|
+
* - `"storage"` — durable storage backends beyond the default SQLite state.
|
|
910
|
+
* - `"ui"` — TUI presentation providers (startup screens, mascots, panels).
|
|
911
|
+
*/
|
|
912
|
+
export type PluginCategory = "model-provider" | "methodology-harness" | "memory" | "subagents" | "search" | "tools" | "security" | "analytics" | "mcp" | "storage" | "ui";
|
|
374
913
|
export interface PluginMetadata {
|
|
375
914
|
id: string;
|
|
376
915
|
version: string;
|
|
377
916
|
builtin: boolean;
|
|
378
917
|
name?: string;
|
|
379
918
|
description?: string;
|
|
380
|
-
/**
|
|
919
|
+
/**
|
|
920
|
+
* Categories declared by the plugin or derived by the host from its registrations; any value of
|
|
921
|
+
* the `PluginCategory` union.
|
|
922
|
+
*/
|
|
381
923
|
categories?: PluginCategory[];
|
|
382
924
|
}
|
|
383
925
|
export interface StartupFact {
|
|
@@ -537,6 +1079,124 @@ export interface QuestionOption {
|
|
|
537
1079
|
description?: string;
|
|
538
1080
|
/** At most one option per question should be marked recommended. A suggestion, never forced. */
|
|
539
1081
|
recommended?: boolean;
|
|
1082
|
+
/**
|
|
1083
|
+
* Choosing this option also asks for free text (for example "Add context"). The text travels
|
|
1084
|
+
* back as the extra answer key `"<questionId>:text"`; clients that do not know the field show
|
|
1085
|
+
* a plain option and the answer simply carries no text.
|
|
1086
|
+
*/
|
|
1087
|
+
textInput?: {
|
|
1088
|
+
placeholder?: string;
|
|
1089
|
+
};
|
|
1090
|
+
}
|
|
1091
|
+
/**
|
|
1092
|
+
* A plan waiting for the user's decision (`exit_plan`). Carried by `AskQuestionsRequest.plan` and
|
|
1093
|
+
* `PendingInteraction.request.plan`: clients that know it render the plan and the three decisions;
|
|
1094
|
+
* clients that do not still show the single question with its options.
|
|
1095
|
+
*/
|
|
1096
|
+
export interface PlanReview {
|
|
1097
|
+
/** Stable id of this proposal; one per `exit_plan` call. */
|
|
1098
|
+
planId: string;
|
|
1099
|
+
/** 1 for the first proposal of a session, then one more for every `exit_plan` call. */
|
|
1100
|
+
revision: number;
|
|
1101
|
+
/** `sha256` of the Markdown: the approved snapshot is the one with this hash. */
|
|
1102
|
+
hash: string;
|
|
1103
|
+
title: string;
|
|
1104
|
+
/** The whole plan in Markdown (the same text as the `plan.md` artifact). */
|
|
1105
|
+
markdown: string;
|
|
1106
|
+
/** The published `plan.md` artifact (absent when publishing failed). */
|
|
1107
|
+
artifact?: ArtifactRef;
|
|
1108
|
+
}
|
|
1109
|
+
/** Lifecycle of a background task (`bg_run`); a terminal state is never left. */
|
|
1110
|
+
export type BackgroundTaskStatus = "queued" | "running" | "stopping" | "succeeded" | "failed" | "cancelled" | "lost";
|
|
1111
|
+
/** `shell` is a `bg_run` command; `subagent` is a read-only mirror of a subagent task. */
|
|
1112
|
+
export type BackgroundTaskKind = "shell" | "subagent";
|
|
1113
|
+
/** Who aborted a task: the user (UI), the model (`bg_stop`), the watchdog or the shutdown. */
|
|
1114
|
+
export type BackgroundTaskAbortOrigin = "user" | "model" | "timeout" | "shutdown";
|
|
1115
|
+
/** A background task as shown by tools, routes and UIs (no secrets, no log path). */
|
|
1116
|
+
export interface BackgroundTaskInfo {
|
|
1117
|
+
id: string;
|
|
1118
|
+
kind: BackgroundTaskKind;
|
|
1119
|
+
label: string;
|
|
1120
|
+
status: BackgroundTaskStatus;
|
|
1121
|
+
/** Shell tasks: the command line and the directory it ran in. */
|
|
1122
|
+
command?: string;
|
|
1123
|
+
cwd?: string;
|
|
1124
|
+
exitCode?: number;
|
|
1125
|
+
signal?: string;
|
|
1126
|
+
/** `timeout` (watchdog) or `spawn_failed`. */
|
|
1127
|
+
errorCode?: string;
|
|
1128
|
+
abortOrigin?: BackgroundTaskAbortOrigin;
|
|
1129
|
+
/** Session that started it (a child session for delegated work). */
|
|
1130
|
+
sessionId: string;
|
|
1131
|
+
/** Subagent mirrors: the parent task or session. */
|
|
1132
|
+
parentId?: string;
|
|
1133
|
+
/** Operating-system process id (shell tasks, while known; useful to find a `lost` task). */
|
|
1134
|
+
pid?: number;
|
|
1135
|
+
/** Bytes of output stored so far. */
|
|
1136
|
+
bytes: number;
|
|
1137
|
+
/** The stored log was cut at its size limit. */
|
|
1138
|
+
truncated?: boolean;
|
|
1139
|
+
timeoutMs?: number;
|
|
1140
|
+
createdAt: number;
|
|
1141
|
+
startedAt?: number;
|
|
1142
|
+
endedAt?: number;
|
|
1143
|
+
/** The owner agent has been told about the end (or read the output after it). */
|
|
1144
|
+
delivered?: boolean;
|
|
1145
|
+
}
|
|
1146
|
+
/** One incremental read of a task log (`bg_output`, `GET …/tasks/:tid/output`). */
|
|
1147
|
+
export interface BackgroundTaskOutput {
|
|
1148
|
+
text: string;
|
|
1149
|
+
/** Pass it back as `offset` to continue; equals the input offset when nothing new arrived. */
|
|
1150
|
+
nextOffset: number;
|
|
1151
|
+
/** The task is over and everything has been read. */
|
|
1152
|
+
eof: boolean;
|
|
1153
|
+
status: BackgroundTaskStatus;
|
|
1154
|
+
exitCode?: number;
|
|
1155
|
+
truncated?: boolean;
|
|
1156
|
+
}
|
|
1157
|
+
/** The state of a session goal (`/goal`); `complete` and `budget_limited` are final unless re-armed. */
|
|
1158
|
+
export type GoalStatus = "active" | "paused" | "blocked" | "budget_limited" | "complete";
|
|
1159
|
+
/** Why a goal is in its state: a closed set of codes (the UIs translate them). */
|
|
1160
|
+
export type GoalReason = "created" | "resumed" | "edited" | "user_paused" | "user_interrupt" | "model_complete" | "model_blocked" | "policy_denied" | "run_error" | "token_budget" | "max_turns" | "max_wall" | "no_progress" | "restart";
|
|
1161
|
+
/** What an active goal is waiting for before its next continuation (never stored: computed). */
|
|
1162
|
+
export type GoalWaiting = "approval" | "question" | "user_input" | "plan_mode" | "background_tasks";
|
|
1163
|
+
/** What the user can do to a goal (the actions the UIs offer per state). */
|
|
1164
|
+
export type GoalAction = "pause" | "resume" | "edit" | "clear" | "budget";
|
|
1165
|
+
/** One piece of evidence the model gives with `update_goal` (`denied` = a permission denial). */
|
|
1166
|
+
export interface GoalEvidence {
|
|
1167
|
+
kind: "file" | "test" | "log" | "command" | "denied" | "other";
|
|
1168
|
+
detail: string;
|
|
1169
|
+
}
|
|
1170
|
+
/** A session goal as shown by routes and UIs. */
|
|
1171
|
+
export interface GoalInfo {
|
|
1172
|
+
sessionId: string;
|
|
1173
|
+
goalId: string;
|
|
1174
|
+
objective: string;
|
|
1175
|
+
status: GoalStatus;
|
|
1176
|
+
reason?: GoalReason;
|
|
1177
|
+
/** Short context of the reason (the error text of a failed run, which breaker paused it). */
|
|
1178
|
+
detail?: string;
|
|
1179
|
+
/** Compare-and-set counter: changes with every status, objective or budget change. */
|
|
1180
|
+
epoch: number;
|
|
1181
|
+
/** Tokens (input + output of every request) the goal may spend; absent = no token budget. */
|
|
1182
|
+
tokenBudget?: number;
|
|
1183
|
+
tokensUsed: number;
|
|
1184
|
+
/** Runs spent (a goal turn is one run: the kickoff, a continuation or a prompt of the user). */
|
|
1185
|
+
turnsUsed: number;
|
|
1186
|
+
maxTurns: number;
|
|
1187
|
+
/** Time spent in runs, in milliseconds, and its cap. */
|
|
1188
|
+
activeMs: number;
|
|
1189
|
+
maxWallMs: number;
|
|
1190
|
+
/** The model's last `update_goal` report. */
|
|
1191
|
+
summary?: string;
|
|
1192
|
+
evidence?: GoalEvidence[];
|
|
1193
|
+
/** What the next continuation waits for (set by the host: it knows the live state). */
|
|
1194
|
+
waiting?: GoalWaiting;
|
|
1195
|
+
/** The user actions allowed in this state. */
|
|
1196
|
+
actions: GoalAction[];
|
|
1197
|
+
createdAt: number;
|
|
1198
|
+
updatedAt: number;
|
|
1199
|
+
completedAt?: number;
|
|
540
1200
|
}
|
|
541
1201
|
export interface Question {
|
|
542
1202
|
id: string;
|
|
@@ -554,6 +1214,8 @@ export interface AskQuestionsRequest {
|
|
|
554
1214
|
session?: string;
|
|
555
1215
|
/** Who is asking, e.g. an agent path such as "general › explore". */
|
|
556
1216
|
label?: string;
|
|
1217
|
+
/** Set by `exit_plan`: the plan these questions decide on (see `PlanReview`). */
|
|
1218
|
+
plan?: PlanReview;
|
|
557
1219
|
signal?: AbortSignal;
|
|
558
1220
|
}
|
|
559
1221
|
/** Each question id maps to the chosen value(s), or undefined when the question was skipped. */
|
|
@@ -566,6 +1228,37 @@ export interface CommandOptions {
|
|
|
566
1228
|
description?: string;
|
|
567
1229
|
argumentHint?: string;
|
|
568
1230
|
}
|
|
1231
|
+
/** Where a data view runs: the session the web asked about (already validated by the host). */
|
|
1232
|
+
export interface ViewContext {
|
|
1233
|
+
sessionId: string;
|
|
1234
|
+
/** Workspace of that session. */
|
|
1235
|
+
workspace: string;
|
|
1236
|
+
/** Aborted when the host timeout for the view expires. */
|
|
1237
|
+
signal: AbortSignal;
|
|
1238
|
+
}
|
|
1239
|
+
/**
|
|
1240
|
+
* A named, read-only data view a plugin exposes to hosts (the web UI reads them through
|
|
1241
|
+
* `GET /api/sessions/:sid/views/:plugin/:view`). Read-only is a CONTRACT, not a sandbox: the host
|
|
1242
|
+
* only enforces the method, the validated parameters, a timeout and a response size cap.
|
|
1243
|
+
*/
|
|
1244
|
+
export interface ViewDefinition {
|
|
1245
|
+
/** Lowercase letters, digits and dashes, starting with a letter (max 40 characters). */
|
|
1246
|
+
id: string;
|
|
1247
|
+
description: string;
|
|
1248
|
+
/**
|
|
1249
|
+
* JSON Schema of the query parameters: `type: "object"` whose properties are primitives
|
|
1250
|
+
* (`string`, `integer`, `number`, `boolean`). Query strings are coerced to these types and
|
|
1251
|
+
* unknown keys are rejected. Omitted means "no parameters".
|
|
1252
|
+
*/
|
|
1253
|
+
params?: JsonSchema;
|
|
1254
|
+
/** Returns JSON-serializable data. Throw `ViewParamsError` for a parameter the schema cannot express. */
|
|
1255
|
+
handler(params: Record<string, unknown>, context: ViewContext): unknown | Promise<unknown>;
|
|
1256
|
+
}
|
|
1257
|
+
/** `ViewDefinition.handler` failure caused by the caller's parameters (becomes a 400). */
|
|
1258
|
+
export declare class ViewParamsError extends Error {
|
|
1259
|
+
readonly code = "view_invalid_params";
|
|
1260
|
+
constructor(message?: string);
|
|
1261
|
+
}
|
|
569
1262
|
export interface PluginAPI {
|
|
570
1263
|
tools: {
|
|
571
1264
|
register(tool: ToolDefinition): () => void;
|
|
@@ -621,6 +1314,13 @@ export interface PluginAPI {
|
|
|
621
1314
|
storage: {
|
|
622
1315
|
sqlite(path: string): SqlDatabase;
|
|
623
1316
|
};
|
|
1317
|
+
/**
|
|
1318
|
+
* Named read-only data views for hosts such as the web UI. Absent on a core that predates it:
|
|
1319
|
+
* feature-detect with `api.views?.register(...)` so the plugin keeps working there.
|
|
1320
|
+
*/
|
|
1321
|
+
views?: {
|
|
1322
|
+
register(view: ViewDefinition): () => void;
|
|
1323
|
+
};
|
|
624
1324
|
/** Provide an implementation for a named extension point (e.g. mascot, startup-screen). */
|
|
625
1325
|
extensions: {
|
|
626
1326
|
register<K extends keyof ExtensionPoints>(point: K, provider: ExtensionPoints[K], options?: ExtensionOptions): () => void;
|
|
@@ -683,6 +1383,7 @@ export interface Plugin {
|
|
|
683
1383
|
/** Provider-neutral catalog metadata. Hosts may derive additional categories from registrations. */
|
|
684
1384
|
name?: string;
|
|
685
1385
|
description?: string;
|
|
1386
|
+
/** Optional catalog categories; any value of the `PluginCategory` union. */
|
|
686
1387
|
categories?: PluginCategory[];
|
|
687
1388
|
/** Declarative sugar for `api.extensions.register(point, provider)` at priority 0. */
|
|
688
1389
|
extensions?: {
|
|
@@ -691,7 +1392,868 @@ export interface Plugin {
|
|
|
691
1392
|
setup(api: PluginAPI): void | Promise<void>;
|
|
692
1393
|
dispose?(): void | Promise<void>;
|
|
693
1394
|
}
|
|
1395
|
+
/** Derived status of a root session as shown by web clients (never persisted). */
|
|
1396
|
+
export type SessionUiStatus = "idle" | "queued" | "running" | "awaiting_input" | "locked" | "error";
|
|
1397
|
+
/** A content-addressed upload (for example an image attached from the web composer). */
|
|
1398
|
+
export interface BlobRef {
|
|
1399
|
+
/** Lowercase hex sha256 of the bytes. */
|
|
1400
|
+
hash: string;
|
|
1401
|
+
mimeType: string;
|
|
1402
|
+
bytes: number;
|
|
1403
|
+
width?: number;
|
|
1404
|
+
height?: number;
|
|
1405
|
+
}
|
|
1406
|
+
/** One entry of `GET /api/workspaces/:wid/tree` (paths are workspace-relative, `/`-separated). */
|
|
1407
|
+
export interface FileEntry {
|
|
1408
|
+
name: string;
|
|
1409
|
+
path: string;
|
|
1410
|
+
type: "file" | "dir" | "symlink" | "other";
|
|
1411
|
+
/** Bytes, for files. */
|
|
1412
|
+
size?: number;
|
|
1413
|
+
/** Last modification, ms epoch. */
|
|
1414
|
+
mtime?: number;
|
|
1415
|
+
}
|
|
1416
|
+
/** A page of a directory listing; `next` is an opaque cursor for the following page. */
|
|
1417
|
+
export interface FileTreePage {
|
|
1418
|
+
entries: FileEntry[];
|
|
1419
|
+
next?: string;
|
|
1420
|
+
}
|
|
1421
|
+
/** A file the session changed (write-effect tool calls), for the Changes dock. */
|
|
1422
|
+
export interface SessionChange {
|
|
1423
|
+
path: string;
|
|
1424
|
+
lastRunId?: string;
|
|
1425
|
+
effect: "write";
|
|
1426
|
+
/** `git status --porcelain` code when the workspace is a git repository (`M`, `A`, `D`, `??`…). */
|
|
1427
|
+
gitStatus?: string;
|
|
1428
|
+
}
|
|
1429
|
+
/** Session metadata carried by snapshot frames. */
|
|
1430
|
+
export interface SessionDetailWire {
|
|
1431
|
+
id: string;
|
|
1432
|
+
/** Opaque, stable workspace id (never a filesystem path in URLs). */
|
|
1433
|
+
workspaceId: string;
|
|
1434
|
+
/** Absolute workspace path, for display. */
|
|
1435
|
+
workspace: string;
|
|
1436
|
+
provider: string;
|
|
1437
|
+
model: string;
|
|
1438
|
+
status: SessionUiStatus;
|
|
1439
|
+
title?: string;
|
|
1440
|
+
parentId?: string;
|
|
1441
|
+
/** Persisted child-session status, shown verbatim for child sessions. */
|
|
1442
|
+
childStatus?: SessionStatus;
|
|
1443
|
+
createdAt?: number;
|
|
1444
|
+
updatedAt?: number;
|
|
1445
|
+
}
|
|
1446
|
+
/** In-flight state of a running run, rebuilt by the server for snapshots. */
|
|
1447
|
+
export interface InflightState {
|
|
1448
|
+
runId: string;
|
|
1449
|
+
status: "queued" | "running";
|
|
1450
|
+
/** Epoch milliseconds when the run started executing; lets a reloaded client show elapsed time. */
|
|
1451
|
+
startedAt?: number;
|
|
1452
|
+
/** Assistant text streamed since the last `turn_completed`. */
|
|
1453
|
+
text: string;
|
|
1454
|
+
/** Reasoning streamed since the last `turn_completed` (never persisted). */
|
|
1455
|
+
reasoning: string;
|
|
1456
|
+
tools: Array<{
|
|
1457
|
+
id: string;
|
|
1458
|
+
name: string;
|
|
1459
|
+
arguments: string;
|
|
1460
|
+
effect: Effect;
|
|
1461
|
+
startedAt: number;
|
|
1462
|
+
/** Latest progress output, bounded. */
|
|
1463
|
+
tail: string;
|
|
1464
|
+
}>;
|
|
1465
|
+
}
|
|
1466
|
+
/** An approval waiting for a decision from a web client. */
|
|
1467
|
+
export interface PendingApproval {
|
|
1468
|
+
/** `<sessionId>:<callId>` for tool effects; `<sessionId>:dir:<uuid>` for directories. */
|
|
1469
|
+
approvalId: string;
|
|
1470
|
+
sessionId: string;
|
|
1471
|
+
/** Root of `sessionId`, so child-session approvals show in the root session view. */
|
|
1472
|
+
rootSessionId: string;
|
|
1473
|
+
runId?: string;
|
|
1474
|
+
kind: "effect" | "directory";
|
|
1475
|
+
callId?: string;
|
|
1476
|
+
name?: string;
|
|
1477
|
+
effect?: "write" | "process" | "external";
|
|
1478
|
+
label?: string;
|
|
1479
|
+
directory?: string;
|
|
1480
|
+
/** Pretty-printed tool input, truncated to 4 KB. */
|
|
1481
|
+
input: string;
|
|
1482
|
+
expiresAt?: number;
|
|
1483
|
+
/** The approval is for this capability (for example running Python), not the whole effect. */
|
|
1484
|
+
capability?: AnalysisCapability;
|
|
1485
|
+
/** A short preview for capability approvals (the first 40 lines of the script). */
|
|
1486
|
+
preview?: string;
|
|
1487
|
+
/** Capability approvals: `managed` (not sandboxed) or `oci` (container). */
|
|
1488
|
+
runtime?: "managed" | "oci";
|
|
1489
|
+
/** `analysis.install` approvals: only `once` and `deny` are offered. */
|
|
1490
|
+
install?: InstallPreview;
|
|
1491
|
+
}
|
|
1492
|
+
/** A plugin UI request (`ui.select` / `ui.askQuestions`) waiting for a web client. */
|
|
1493
|
+
export interface PendingInteraction {
|
|
1494
|
+
interactionId: string;
|
|
1495
|
+
/** Present when the request names a session (`AskQuestionsRequest.session`). */
|
|
1496
|
+
sessionId?: string;
|
|
1497
|
+
workspaceId: string;
|
|
1498
|
+
request: {
|
|
1499
|
+
kind: "select";
|
|
1500
|
+
select: SelectRequest;
|
|
1501
|
+
} | {
|
|
1502
|
+
kind: "questions";
|
|
1503
|
+
questions: Question[];
|
|
1504
|
+
label?: string;
|
|
1505
|
+
plan?: PlanReview;
|
|
1506
|
+
};
|
|
1507
|
+
}
|
|
1508
|
+
/** One entry of the shared slash-command catalog. */
|
|
1509
|
+
export interface CommandDescriptor {
|
|
1510
|
+
name: string;
|
|
1511
|
+
description: string;
|
|
1512
|
+
aliases?: string[];
|
|
1513
|
+
argumentHint?: string;
|
|
1514
|
+
source: "builtin" | "plugin" | "prompt" | "skill" | "agent";
|
|
1515
|
+
/** Plugin id or resource owner, when not built in. */
|
|
1516
|
+
owner?: string;
|
|
1517
|
+
surfaces: Array<"tui" | "web" | "api">;
|
|
1518
|
+
/** `core` commands run through the catalog; `surface` commands are handled by each UI. */
|
|
1519
|
+
execution: "core" | "surface";
|
|
1520
|
+
}
|
|
1521
|
+
/** One JSON object per SSE `data:` line. Clients ignore unknown `t` values. */
|
|
1522
|
+
export type ServerFrame = {
|
|
1523
|
+
t: "hello";
|
|
1524
|
+
protocolVersion: 1;
|
|
1525
|
+
streamId: string;
|
|
1526
|
+
serverTime: number;
|
|
1527
|
+
} | {
|
|
1528
|
+
t: "snapshot";
|
|
1529
|
+
sessionId: string;
|
|
1530
|
+
/** `MAX(events.seq)` of the session when the snapshot was taken. */
|
|
1531
|
+
cursor: number;
|
|
1532
|
+
session: SessionDetailWire;
|
|
1533
|
+
messages: {
|
|
1534
|
+
items: Array<{
|
|
1535
|
+
seq: number;
|
|
1536
|
+
message: Message;
|
|
1537
|
+
compacted: boolean;
|
|
1538
|
+
}>;
|
|
1539
|
+
hasMore: boolean;
|
|
1540
|
+
};
|
|
1541
|
+
inflight?: InflightState;
|
|
1542
|
+
pending: {
|
|
1543
|
+
approvals: PendingApproval[];
|
|
1544
|
+
interactions: PendingInteraction[];
|
|
1545
|
+
};
|
|
1546
|
+
/** The session's goal, when it has one (so a reload shows the goal bar at once). */
|
|
1547
|
+
goal?: GoalInfo;
|
|
1548
|
+
}
|
|
1549
|
+
/** Durable event; its SSE `id` is `event.eventId`. */
|
|
1550
|
+
| {
|
|
1551
|
+
t: "event";
|
|
1552
|
+
sessionId: string;
|
|
1553
|
+
event: RunEvent;
|
|
1554
|
+
}
|
|
1555
|
+
/** Coalesced ephemeral output; carries no SSE `id`. */
|
|
1556
|
+
| {
|
|
1557
|
+
t: "delta";
|
|
1558
|
+
sessionId: string;
|
|
1559
|
+
runId: string;
|
|
1560
|
+
text?: string;
|
|
1561
|
+
reasoning?: string;
|
|
1562
|
+
progress?: Array<{
|
|
1563
|
+
toolId: string;
|
|
1564
|
+
chunk: string;
|
|
1565
|
+
}>;
|
|
1566
|
+
} | {
|
|
1567
|
+
t: "tool_result";
|
|
1568
|
+
sessionId: string;
|
|
1569
|
+
runId: string;
|
|
1570
|
+
callId: string;
|
|
1571
|
+
result: ToolResult;
|
|
1572
|
+
truncated?: boolean;
|
|
1573
|
+
} | {
|
|
1574
|
+
t: "message";
|
|
1575
|
+
sessionId: string;
|
|
1576
|
+
seq: number;
|
|
1577
|
+
message: Message;
|
|
1578
|
+
} | {
|
|
1579
|
+
t: "approval";
|
|
1580
|
+
approval: PendingApproval;
|
|
1581
|
+
} | {
|
|
1582
|
+
t: "approval_withdrawn";
|
|
1583
|
+
approvalId: string;
|
|
1584
|
+
reason: "cancelled" | "timeout" | "resolved_elsewhere";
|
|
1585
|
+
} | {
|
|
1586
|
+
t: "interaction";
|
|
1587
|
+
interaction: PendingInteraction;
|
|
1588
|
+
} | {
|
|
1589
|
+
t: "interaction_withdrawn";
|
|
1590
|
+
interactionId: string;
|
|
1591
|
+
} | {
|
|
1592
|
+
t: "session_status";
|
|
1593
|
+
sessionId: string;
|
|
1594
|
+
workspaceId: string;
|
|
1595
|
+
status: SessionUiStatus;
|
|
1596
|
+
title?: string;
|
|
1597
|
+
updatedAt?: number;
|
|
1598
|
+
} | {
|
|
1599
|
+
t: "catalog_changed";
|
|
1600
|
+
workspaceId: string;
|
|
1601
|
+
scope: "commands" | "plugins" | "skills" | "mcp" | "models" | "agents";
|
|
1602
|
+
} | {
|
|
1603
|
+
t: "resync";
|
|
1604
|
+
sessionId?: string;
|
|
1605
|
+
reason: "overflow" | "gap" | "server_restart";
|
|
1606
|
+
}
|
|
1607
|
+
/** A persisted capability grant of this root session was added or revoked. */
|
|
1608
|
+
| {
|
|
1609
|
+
t: "capabilities_changed";
|
|
1610
|
+
sessionId: string;
|
|
1611
|
+
}
|
|
1612
|
+
/** A dataset uploaded from the web finished ingesting (root session). */
|
|
1613
|
+
| {
|
|
1614
|
+
t: "dataset_ready";
|
|
1615
|
+
sessionId: string;
|
|
1616
|
+
dataset: DatasetRef;
|
|
1617
|
+
}
|
|
1618
|
+
/** A dataset upload could not be ingested. */
|
|
1619
|
+
| {
|
|
1620
|
+
t: "dataset_failed";
|
|
1621
|
+
sessionId: string;
|
|
1622
|
+
name: string;
|
|
1623
|
+
error: string;
|
|
1624
|
+
}
|
|
1625
|
+
/** A background task of this root session appeared or changed state (additive; `bg_run`). */
|
|
1626
|
+
| {
|
|
1627
|
+
t: "tasks_changed";
|
|
1628
|
+
sessionId: string;
|
|
1629
|
+
task: BackgroundTaskInfo;
|
|
1630
|
+
}
|
|
1631
|
+
/** The goal of this root session changed (`null` = cleared). Additive; `/goal`. */
|
|
1632
|
+
| {
|
|
1633
|
+
t: "goal_changed";
|
|
1634
|
+
sessionId: string;
|
|
1635
|
+
goal: GoalInfo | null;
|
|
1636
|
+
};
|
|
1637
|
+
export type ApiErrorCode = "unauthorized" | "forbidden_origin" | "forbidden_host" | "validation_failed" | "not_found" | "unknown_command" | "session_busy" | "session_locked" | "workspace_limit"
|
|
1638
|
+
/** A known workspace whose folder was deleted, moved or is no longer accessible (404). */
|
|
1639
|
+
| "workspace_missing" | "payload_too_large" | "unsupported_media_type" | "path_outside_workspace" | "not_a_git_repo" | "approval_resolved" | "capability_ceiling" | "not_manageable" | "mcp_not_permitted" | "runs_active" | "provider_unavailable" | "protocol_mismatch" | "shutting_down"
|
|
1640
|
+
/** Too many concurrent event streams (SSE) for this server. */
|
|
1641
|
+
| "stream_limit"
|
|
1642
|
+
/** The workspace is archived: unarchive it before starting new sessions (409). */
|
|
1643
|
+
| "workspace_archived"
|
|
1644
|
+
/** A native folder dialog is already open on the server machine (409). */
|
|
1645
|
+
| "picker_busy"
|
|
1646
|
+
/** No native folder dialog / folder browser on this server (remote bind, no desktop) (503). */
|
|
1647
|
+
| "picker_unavailable"
|
|
1648
|
+
/** The server user may not read that directory (403). */
|
|
1649
|
+
| "permission_denied"
|
|
1650
|
+
/** The request was cancelled before it finished, e.g. a `/btw` side question (409). */
|
|
1651
|
+
| "cancelled"
|
|
1652
|
+
/** The artifact does not exist or belongs to another session (404). */
|
|
1653
|
+
| "artifact_not_found"
|
|
1654
|
+
/** The artifact exceeds a size limit for this operation (413). */
|
|
1655
|
+
| "artifact_too_large"
|
|
1656
|
+
/** No usable Python runtime (503). */
|
|
1657
|
+
| "runtime_unavailable"
|
|
1658
|
+
/** The file is not a supported dataset, or needs a runtime that is missing (415/503 body code). */
|
|
1659
|
+
| "dataset_unsupported"
|
|
1660
|
+
/** A data query was rejected by the read-only guard (400). */
|
|
1661
|
+
| "query_rejected"
|
|
1662
|
+
/** A data query exceeded `analysis.data.queryTimeoutMs` (408). */
|
|
1663
|
+
| "query_timeout"
|
|
1664
|
+
/** A plugin data view threw while running (502; the message never carries its internals). */
|
|
1665
|
+
| "view_failed"
|
|
1666
|
+
/** A plugin data view exceeded the host timeout (504). */
|
|
1667
|
+
| "view_timeout"
|
|
1668
|
+
/** A plugin data view answered more than the host response cap (502). */
|
|
1669
|
+
| "view_too_large"
|
|
1670
|
+
/** The background task does not exist or belongs to another session (404). */
|
|
1671
|
+
| "task_not_found"
|
|
1672
|
+
/** The session has no goal (404). */
|
|
1673
|
+
| "goal_not_found"
|
|
1674
|
+
/** The goal changed since the client read it, or the action is not allowed in its state (409). */
|
|
1675
|
+
| "goal_conflict"
|
|
1676
|
+
/** Goals are turned off (`goal.enabled`) (409). */
|
|
1677
|
+
| "goal_disabled" | "internal";
|
|
1678
|
+
/** `GET /api/health` (the only unauthenticated API route). */
|
|
1679
|
+
export interface HealthInfo {
|
|
1680
|
+
name: "alisio";
|
|
1681
|
+
version: string;
|
|
1682
|
+
protocolVersion: 1;
|
|
1683
|
+
capabilities: {
|
|
1684
|
+
sse: boolean;
|
|
1685
|
+
websocket: boolean;
|
|
1686
|
+
multiWorkspace: boolean;
|
|
1687
|
+
attachments: boolean;
|
|
1688
|
+
uiBlocks: string[];
|
|
1689
|
+
mcpApps: boolean;
|
|
1690
|
+
automation: boolean;
|
|
1691
|
+
/** The server listens on a non-loopback address (`--allow-remote`). */
|
|
1692
|
+
remote: boolean;
|
|
1693
|
+
/**
|
|
1694
|
+
* `POST /api/workspaces/pick` can open a native folder dialog on this machine (loopback only,
|
|
1695
|
+
* with a desktop session and a dialog tool). Absent on older servers.
|
|
1696
|
+
*/
|
|
1697
|
+
nativePicker?: boolean;
|
|
1698
|
+
/** `GET /api/fs/dirs` lists directory names for the in-app folder browser (loopback only). */
|
|
1699
|
+
folderBrowser?: boolean;
|
|
1700
|
+
};
|
|
1701
|
+
}
|
|
1702
|
+
/** `POST /api/workspaces/pick`: the folder chosen in the native dialog, or a cancellation. */
|
|
1703
|
+
export type FolderPickResult = {
|
|
1704
|
+
path: string;
|
|
1705
|
+
} | {
|
|
1706
|
+
cancelled: true;
|
|
1707
|
+
};
|
|
1708
|
+
/** One page of the in-app folder browser (`GET /api/fs/dirs`): subdirectory names only. */
|
|
1709
|
+
export interface DirectoryListing {
|
|
1710
|
+
/** Absolute path listed (the server's own separators; `""` for the drive list on Windows). */
|
|
1711
|
+
path: string;
|
|
1712
|
+
/** Parent directory, absent at a filesystem root (and at the drive list). */
|
|
1713
|
+
parent?: string;
|
|
1714
|
+
/** Breadcrumbs from the root to `path`, built by the server (no separator assumptions). */
|
|
1715
|
+
segments: Array<{
|
|
1716
|
+
name: string;
|
|
1717
|
+
path: string;
|
|
1718
|
+
}>;
|
|
1719
|
+
/** Subdirectories (names and absolute paths; never files, never contents). */
|
|
1720
|
+
entries: Array<{
|
|
1721
|
+
name: string;
|
|
1722
|
+
path: string;
|
|
1723
|
+
hidden: boolean;
|
|
1724
|
+
}>;
|
|
1725
|
+
/** The server user's home directory (where browsing starts). */
|
|
1726
|
+
home: string;
|
|
1727
|
+
/** Path separator of the server platform. */
|
|
1728
|
+
separator: "/" | "\\";
|
|
1729
|
+
/** More than the listing cap: the rest is not shown. */
|
|
1730
|
+
truncated?: boolean;
|
|
1731
|
+
}
|
|
1732
|
+
/** A workspace known to the server (`GET /api/workspaces`). */
|
|
1733
|
+
export interface WorkspaceInfo {
|
|
1734
|
+
/** Opaque, stable id: a short sha256 of the canonical path. */
|
|
1735
|
+
id: string;
|
|
1736
|
+
/** Canonical absolute path (display only; URLs use `id`). */
|
|
1737
|
+
path: string;
|
|
1738
|
+
label?: string;
|
|
1739
|
+
pinned: boolean;
|
|
1740
|
+
/** An `Application` is open for it in the server right now. */
|
|
1741
|
+
open: boolean;
|
|
1742
|
+
/**
|
|
1743
|
+
* The folder is still an accessible directory. A workspace known from old sessions may have been
|
|
1744
|
+
* deleted or moved: its sessions stay readable, but it cannot be opened (`workspace_missing`).
|
|
1745
|
+
*/
|
|
1746
|
+
exists: boolean;
|
|
1747
|
+
/** Project resources load (trusted from the terminal or by a launch flag). */
|
|
1748
|
+
trusted: boolean;
|
|
1749
|
+
/** The directory has project resources that are not trusted (shown as "untrusted"). */
|
|
1750
|
+
untrustedResources: boolean;
|
|
1751
|
+
/** Archived: hidden from the default list; its sessions stay readable, new ones are refused. */
|
|
1752
|
+
archived: boolean;
|
|
1753
|
+
lastOpenedAt?: number;
|
|
1754
|
+
}
|
|
1755
|
+
/** Permission presets of the web composer (RF-08). */
|
|
1756
|
+
export type PermissionPresetId = "read-only" | "ask" | "workspace-write" | "full-access";
|
|
1757
|
+
/**
|
|
1758
|
+
* The permission mode shared by the TUI and the web presets: `ask` (every effect asks), `auto`
|
|
1759
|
+
* (workspace edits run without asking; commands, network and external directories still ask) and
|
|
1760
|
+
* `full` (nothing asks). A mode is NOT a sandbox.
|
|
1761
|
+
*/
|
|
1762
|
+
export type PermissionMode = "ask" | "auto" | "full";
|
|
1763
|
+
export interface PermissionPresetInfo {
|
|
1764
|
+
id: PermissionPresetId;
|
|
1765
|
+
/** The mode this preset implements (`read-only` has none). */
|
|
1766
|
+
mode?: PermissionMode;
|
|
1767
|
+
/** Selectable under the server's launch flags (its capability ceiling). */
|
|
1768
|
+
available: boolean;
|
|
1769
|
+
/** Why it is unavailable, or which effects still ask because of the ceiling. */
|
|
1770
|
+
reason?: string;
|
|
1771
|
+
/** Effects allowed without asking once the ceiling is applied. */
|
|
1772
|
+
policy: {
|
|
1773
|
+
write: boolean;
|
|
1774
|
+
process: boolean;
|
|
1775
|
+
external: boolean;
|
|
1776
|
+
};
|
|
1777
|
+
/** Whether non-allowed effects ask for approval (false: they are denied). */
|
|
1778
|
+
approvals: boolean;
|
|
1779
|
+
}
|
|
1780
|
+
/** One section (`Added`, `Changed`, `Fixed`…) of a changelog entry. */
|
|
1781
|
+
export interface ChangelogSection {
|
|
1782
|
+
title: string;
|
|
1783
|
+
items: string[];
|
|
1784
|
+
}
|
|
1785
|
+
/** One released (or `Unreleased`) version of `CHANGELOG.md`. */
|
|
1786
|
+
export interface ChangelogEntry {
|
|
1787
|
+
/** A semantic version such as `1.2.3-alpha.4`, or `Unreleased`. */
|
|
1788
|
+
version: string;
|
|
1789
|
+
date?: string;
|
|
1790
|
+
unreleased?: boolean;
|
|
1791
|
+
sections: ChangelogSection[];
|
|
1792
|
+
}
|
|
1793
|
+
/** `GET /api/changelog`: the entries asked for and whether there is news since `lastSeen`. */
|
|
1794
|
+
export interface ChangelogView {
|
|
1795
|
+
/** The running Alisio (CLI) version. */
|
|
1796
|
+
current: string;
|
|
1797
|
+
/** Newest first. */
|
|
1798
|
+
entries: ChangelogEntry[];
|
|
1799
|
+
/** `false` when a `version` was asked for and the changelog has no such entry. */
|
|
1800
|
+
found: boolean;
|
|
1801
|
+
/** Present when `lastSeen` is older than `current` and the changelog has entries in between. */
|
|
1802
|
+
news?: {
|
|
1803
|
+
latest: string;
|
|
1804
|
+
versions: string[];
|
|
1805
|
+
};
|
|
1806
|
+
}
|
|
1807
|
+
export type ReloadArea = "config" | "agents" | "skills" | "prompts" | "mcp" | "plugins";
|
|
1808
|
+
/** What `/reload` refreshed in one area: counts and the ids that appeared or disappeared. */
|
|
1809
|
+
export interface ReloadAreaReport {
|
|
1810
|
+
area: ReloadArea;
|
|
1811
|
+
before: number;
|
|
1812
|
+
after: number;
|
|
1813
|
+
added: string[];
|
|
1814
|
+
removed: string[];
|
|
1815
|
+
/** Items present in both whose definition changed (config: the changed sections). */
|
|
1816
|
+
changed?: string[];
|
|
1817
|
+
}
|
|
1818
|
+
/** Answer of `/reload` and `POST /api/workspaces/:wid/reload`. */
|
|
1819
|
+
export interface ReloadReport {
|
|
1820
|
+
refreshed: ReloadAreaReport[];
|
|
1821
|
+
/** What a reload cannot refresh (for example plugin code that was already imported). */
|
|
1822
|
+
restartRequired: string[];
|
|
1823
|
+
warnings: string[];
|
|
1824
|
+
}
|
|
1825
|
+
/** A row of the session list (`GET /api/sessions`). */
|
|
1826
|
+
export interface SessionSummary extends SessionDetailWire {
|
|
1827
|
+
pinned: boolean;
|
|
1828
|
+
archived: boolean;
|
|
1829
|
+
}
|
|
1830
|
+
/** `GET /api/sessions/:sid` and the result of creating or patching a session. */
|
|
1831
|
+
export interface SessionDetail extends SessionSummary {
|
|
1832
|
+
preset: PermissionPresetId;
|
|
1833
|
+
effort?: string;
|
|
1834
|
+
agent?: string;
|
|
1835
|
+
presets: PermissionPresetInfo[];
|
|
1836
|
+
children: SessionDetailWire[];
|
|
1837
|
+
}
|
|
1838
|
+
/** Answer of `POST /api/sessions/:sid/prompts`. */
|
|
1839
|
+
export type PromptAccepted = {
|
|
1840
|
+
runId: string;
|
|
1841
|
+
status: "queued" | "running";
|
|
1842
|
+
duplicate?: false;
|
|
1843
|
+
} | {
|
|
1844
|
+
runId: string;
|
|
1845
|
+
status: string;
|
|
1846
|
+
duplicate: true;
|
|
1847
|
+
} | {
|
|
1848
|
+
status: "enqueued";
|
|
1849
|
+
duplicate?: boolean;
|
|
1850
|
+
};
|
|
1851
|
+
/**
|
|
1852
|
+
* Answer of `POST /api/sessions/:sid/commands`. A command either reports (`output`, Markdown),
|
|
1853
|
+
* points the client at another session (`/clear`, `/resume`) or expands into a prompt the client
|
|
1854
|
+
* sends through `POST .../prompts` (prompt templates, skills, `/ask`). A repeated `requestId`
|
|
1855
|
+
* answers `{duplicate: true}` without running the command again.
|
|
1856
|
+
*/
|
|
1857
|
+
export interface CommandOutcome {
|
|
1858
|
+
output?: string;
|
|
1859
|
+
/** `notice` is a short status line; `info` (default) a report. */
|
|
1860
|
+
tone?: "info" | "notice";
|
|
1861
|
+
sessionId?: string;
|
|
1862
|
+
prompt?: {
|
|
1863
|
+
text: string;
|
|
1864
|
+
display: string;
|
|
1865
|
+
};
|
|
1866
|
+
/** What changed, e.g. `"model"` or `"effort"`, so clients refresh the session. */
|
|
1867
|
+
effects?: string[];
|
|
1868
|
+
duplicate?: boolean;
|
|
1869
|
+
}
|
|
1870
|
+
/**
|
|
1871
|
+
* One `/btw` side question: a tool-less question about a session answered outside its
|
|
1872
|
+
* conversation (never persisted as messages, events, runs or session usage). Answer of
|
|
1873
|
+
* `POST /api/sessions/:sid/btw`; `GET /api/sessions/:sid/btw` lists them, oldest first.
|
|
1874
|
+
*/
|
|
1875
|
+
export interface SideQuestionEntry {
|
|
1876
|
+
id: string;
|
|
1877
|
+
question: string;
|
|
1878
|
+
/** Markdown answer. */
|
|
1879
|
+
answer: string;
|
|
1880
|
+
/** Model that answered (the session's model at the time). */
|
|
1881
|
+
model: string;
|
|
1882
|
+
usage: {
|
|
1883
|
+
input: number;
|
|
1884
|
+
output: number;
|
|
1885
|
+
};
|
|
1886
|
+
/** Epoch milliseconds. */
|
|
1887
|
+
createdAt: number;
|
|
1888
|
+
/** The provider cut the answer at the output-token budget. */
|
|
1889
|
+
truncated?: boolean;
|
|
1890
|
+
}
|
|
1891
|
+
/** `GET /api/sessions/:sid/models`: models of the session's provider (credential-free). */
|
|
1892
|
+
export interface SessionModels {
|
|
1893
|
+
provider: string;
|
|
1894
|
+
model: string;
|
|
1895
|
+
/** Session reasoning effort, when set. */
|
|
1896
|
+
effort?: string;
|
|
1897
|
+
models: ModelInfo[];
|
|
1898
|
+
/** The provider could not list its models (the current model still works). */
|
|
1899
|
+
unavailable: boolean;
|
|
1900
|
+
}
|
|
1901
|
+
/** `GET /api/sessions/:sid/context`: estimated tokens of the next request and the budget. */
|
|
1902
|
+
export interface SessionContextUsage {
|
|
1903
|
+
estimated: number;
|
|
1904
|
+
/** Model context window, when known. */
|
|
1905
|
+
total?: number;
|
|
1906
|
+
basis: "window" | "unknown";
|
|
1907
|
+
/** Percentage of `total` at which auto-compaction triggers. */
|
|
1908
|
+
compactionAt: number;
|
|
1909
|
+
}
|
|
1910
|
+
/** `GET /api/plugins`: one plugin of a workspace (credential- and path-safe). */
|
|
1911
|
+
export interface PluginInfo {
|
|
1912
|
+
id: string;
|
|
1913
|
+
name: string;
|
|
1914
|
+
description: string;
|
|
1915
|
+
version?: string;
|
|
1916
|
+
categories: string[];
|
|
1917
|
+
builtin: boolean;
|
|
1918
|
+
source: string;
|
|
1919
|
+
status: "active" | "inactive" | "failed" | "restart-required";
|
|
1920
|
+
enabled: boolean;
|
|
1921
|
+
/** Whether the web may toggle it (else `diagnostic` says why). */
|
|
1922
|
+
manageable: boolean;
|
|
1923
|
+
diagnostic?: string;
|
|
1924
|
+
/** Tools it contributes, without the namespacing prefix. */
|
|
1925
|
+
tools: string[];
|
|
1926
|
+
/** Slash commands it contributes. */
|
|
1927
|
+
commands: string[];
|
|
1928
|
+
/** Prefix of its namespaced tool names (`p_<hash>`), to label tool calls. */
|
|
1929
|
+
toolPrefix: string;
|
|
1930
|
+
}
|
|
1931
|
+
/** `GET /api/skills`: one discovered skill (no file paths). */
|
|
1932
|
+
export interface SkillInfo {
|
|
1933
|
+
id: string;
|
|
1934
|
+
name: string;
|
|
1935
|
+
displayId: string;
|
|
1936
|
+
description: string;
|
|
1937
|
+
scope: "project" | "config" | "user" | "plugin";
|
|
1938
|
+
source: string;
|
|
1939
|
+
owner?: {
|
|
1940
|
+
id: string;
|
|
1941
|
+
name: string;
|
|
1942
|
+
};
|
|
1943
|
+
manageable: boolean;
|
|
1944
|
+
locked: boolean;
|
|
1945
|
+
enabled: boolean;
|
|
1946
|
+
effective: boolean;
|
|
1947
|
+
shadowedBy?: string;
|
|
1948
|
+
approximateTokens: number;
|
|
1949
|
+
}
|
|
1950
|
+
/** One MCP server of a workspace; commands, arguments and URLs are never sent. */
|
|
1951
|
+
export interface McpServerWire {
|
|
1952
|
+
name: string;
|
|
1953
|
+
displayName: string;
|
|
1954
|
+
/** Configuration layer that defines it (`global`, `project`, …). */
|
|
1955
|
+
source: string;
|
|
1956
|
+
status: string;
|
|
1957
|
+
enabled: boolean;
|
|
1958
|
+
transport: "stdio" | "http";
|
|
1959
|
+
capabilities: string[];
|
|
1960
|
+
counts: {
|
|
1961
|
+
tools: number;
|
|
1962
|
+
resources: number;
|
|
1963
|
+
prompts: number;
|
|
1964
|
+
};
|
|
1965
|
+
diagnostic?: string;
|
|
1966
|
+
}
|
|
1967
|
+
/**
|
|
1968
|
+
* `GET /api/analysis`: the state of the data-analysis runtime for Settings (read only). Never
|
|
1969
|
+
* carries a script or a repository path; interpreter paths are the user's own.
|
|
1970
|
+
*/
|
|
1971
|
+
export interface AnalysisStatus {
|
|
1972
|
+
/** `analysis.enabled` and not `--read-only`: python_run is registered. */
|
|
1973
|
+
enabled: boolean;
|
|
1974
|
+
readOnly: boolean;
|
|
1975
|
+
mode: "managed" | "oci";
|
|
1976
|
+
/** The discovered (or `--python`) interpreter and the extras environment. */
|
|
1977
|
+
python: {
|
|
1978
|
+
found: true;
|
|
1979
|
+
path: string;
|
|
1980
|
+
version: string;
|
|
1981
|
+
source: string;
|
|
1982
|
+
extras: string[];
|
|
1983
|
+
runtimeVersion?: string;
|
|
1984
|
+
} | {
|
|
1985
|
+
found: false;
|
|
1986
|
+
reason: string;
|
|
1987
|
+
/** Installation guidance for this system (commands are shown, never run). */
|
|
1988
|
+
hints: {
|
|
1989
|
+
system: string;
|
|
1990
|
+
heading?: string;
|
|
1991
|
+
primary: string;
|
|
1992
|
+
alternatives: string[];
|
|
1993
|
+
notes: string[];
|
|
1994
|
+
};
|
|
1995
|
+
};
|
|
1996
|
+
/** Container settings; `available` is probed only when the mode is `oci` or an image is set. */
|
|
1997
|
+
oci: {
|
|
1998
|
+
engine: "docker" | "podman";
|
|
1999
|
+
image?: string;
|
|
2000
|
+
memoryMb: number;
|
|
2001
|
+
cpus: number;
|
|
2002
|
+
available?: boolean;
|
|
2003
|
+
version?: string;
|
|
2004
|
+
reason?: string;
|
|
2005
|
+
};
|
|
2006
|
+
limits: {
|
|
2007
|
+
timeoutMs: number;
|
|
2008
|
+
};
|
|
2009
|
+
retention: {
|
|
2010
|
+
jobsDays: number;
|
|
2011
|
+
intermediateDays: number;
|
|
2012
|
+
artifactsDays: number;
|
|
2013
|
+
lastSweep?: number;
|
|
2014
|
+
};
|
|
2015
|
+
}
|
|
2016
|
+
/** `GET /api/mcp`: the workspace's MCP runtime permission and servers. */
|
|
2017
|
+
export interface McpOverview {
|
|
2018
|
+
permission: "granted" | "not-granted" | "read-only";
|
|
2019
|
+
/** Global consent (`mcp.allow`) is persisted for this user. */
|
|
2020
|
+
persisted: boolean;
|
|
2021
|
+
servers: McpServerWire[];
|
|
2022
|
+
}
|
|
2023
|
+
/** `GET /api/agents`: a selectable main-session agent. */
|
|
2024
|
+
export interface AgentInfo {
|
|
2025
|
+
id: string;
|
|
2026
|
+
name: string;
|
|
2027
|
+
description: string;
|
|
2028
|
+
instructions?: string;
|
|
2029
|
+
model?: string;
|
|
2030
|
+
readOnly?: boolean;
|
|
2031
|
+
source: "builtin" | "user" | "plugin";
|
|
2032
|
+
/** The workspace default (`agents.active`) used by sessions without their own agent. */
|
|
2033
|
+
default: boolean;
|
|
2034
|
+
}
|
|
2035
|
+
/** One user-facing setting (`SettableSettingKey`) and its effective value. */
|
|
2036
|
+
export interface SettingInfo {
|
|
2037
|
+
key: string;
|
|
2038
|
+
kind: "boolean" | "number" | "string" | "enum";
|
|
2039
|
+
options?: string[];
|
|
2040
|
+
value?: string | number | boolean;
|
|
2041
|
+
}
|
|
2042
|
+
/** `GET /api/settings`: effective settings and where configuration lives. */
|
|
2043
|
+
export interface SettingsOverview {
|
|
2044
|
+
/** Highest-priority configuration file of the workspace (it may not exist yet). */
|
|
2045
|
+
configPath: string;
|
|
2046
|
+
/** Global file that setting changes are written to. */
|
|
2047
|
+
settingsPath: string;
|
|
2048
|
+
/** Provider profiles (`providers.json`); credentials live apart, never shown. */
|
|
2049
|
+
providersPath: string;
|
|
2050
|
+
trusted: boolean;
|
|
2051
|
+
readOnly: boolean;
|
|
2052
|
+
settings: SettingInfo[];
|
|
2053
|
+
}
|
|
2054
|
+
/** A credential as the web sees it: never the value, at most a short masked tail. */
|
|
2055
|
+
export interface CredentialStatus {
|
|
2056
|
+
configured: boolean;
|
|
2057
|
+
source?: "file" | "env";
|
|
2058
|
+
/** Last characters behind an ellipsis (`…71B`), only for long stored secrets. */
|
|
2059
|
+
tail?: string;
|
|
2060
|
+
}
|
|
2061
|
+
/** One stored provider profile (non-secret values only). */
|
|
2062
|
+
export interface ProviderProfileInfo {
|
|
2063
|
+
name: string;
|
|
2064
|
+
provider: string;
|
|
2065
|
+
model: string;
|
|
2066
|
+
values: Record<string, ProviderConfigurationValue>;
|
|
2067
|
+
/** The globally active profile (`providers.json`). */
|
|
2068
|
+
active: boolean;
|
|
2069
|
+
credentials: Record<string, CredentialStatus>;
|
|
2070
|
+
}
|
|
2071
|
+
/** A provider type a profile can use, with its configuration fields. */
|
|
2072
|
+
export interface ProviderTypeInfo {
|
|
2073
|
+
id: string;
|
|
2074
|
+
name: string;
|
|
2075
|
+
description?: string;
|
|
2076
|
+
fields: ProviderConfigurationField[];
|
|
2077
|
+
}
|
|
2078
|
+
/** `GET /api/providers`. */
|
|
2079
|
+
export interface ProvidersOverview {
|
|
2080
|
+
active?: string;
|
|
2081
|
+
profiles: ProviderProfileInfo[];
|
|
2082
|
+
/** Provider types of the requested workspace (empty without `?workspace=`). */
|
|
2083
|
+
types: ProviderTypeInfo[];
|
|
2084
|
+
/** What the requested workspace's application currently runs. */
|
|
2085
|
+
current?: {
|
|
2086
|
+
provider: string;
|
|
2087
|
+
model: string;
|
|
2088
|
+
profile?: string;
|
|
2089
|
+
};
|
|
2090
|
+
}
|
|
2091
|
+
/** `GET /api/models`: models of every configured profile (credential-free). */
|
|
2092
|
+
export interface ProviderModelsInfo {
|
|
2093
|
+
profile: string;
|
|
2094
|
+
provider: string;
|
|
2095
|
+
title: string;
|
|
2096
|
+
configuredModel: string;
|
|
2097
|
+
models: ModelInfo[];
|
|
2098
|
+
unavailable: boolean;
|
|
2099
|
+
}
|
|
2100
|
+
/** Output format of an agent's answers (`text.format.type`). */
|
|
2101
|
+
export type AgentTextFormatType = "text" | "json_object" | "json_schema";
|
|
2102
|
+
/** Reasoning summary preference of an agent (`reasoning.summary`). */
|
|
2103
|
+
export type AgentReasoningSummary = "auto" | "none" | "concise" | "detailed";
|
|
2104
|
+
/** Answer verbosity preference of an agent (`text.verbosity`). */
|
|
2105
|
+
export type AgentVerbosity = "low" | "medium" | "high";
|
|
2106
|
+
/**
|
|
2107
|
+
* Where a user agent file lives: `project` is `<workspace>/.agents/agents/<id>.md`, `global` is
|
|
2108
|
+
* `~/.agents/agents/<id>.md`. A project agent overrides a global one with the same id.
|
|
2109
|
+
*/
|
|
2110
|
+
export type AgentScope = "project" | "global";
|
|
2111
|
+
/** Body of `POST /api/agents` and `PUT /api/agents/:id`: a user agent definition. */
|
|
2112
|
+
export interface AgentDefinitionInput {
|
|
2113
|
+
/** Display name; the stable id is derived from it once, on creation. */
|
|
2114
|
+
name: string;
|
|
2115
|
+
description?: string;
|
|
2116
|
+
/** System prompt appended to the session instructions when the agent is active. */
|
|
2117
|
+
instructions?: string;
|
|
2118
|
+
/** Model selector (`provider/model` or an unambiguous model id). */
|
|
2119
|
+
model: string;
|
|
2120
|
+
reasoning?: {
|
|
2121
|
+
effort?: string;
|
|
2122
|
+
summary?: AgentReasoningSummary;
|
|
2123
|
+
};
|
|
2124
|
+
text?: {
|
|
2125
|
+
format?: {
|
|
2126
|
+
type: AgentTextFormatType;
|
|
2127
|
+
};
|
|
2128
|
+
verbosity?: AgentVerbosity;
|
|
2129
|
+
};
|
|
2130
|
+
}
|
|
2131
|
+
/** A stored user agent definition (`GET /api/agents/definitions`). Times are epoch ms. */
|
|
2132
|
+
export interface AgentDefinitionInfo extends AgentDefinitionInput {
|
|
2133
|
+
/** File slug: the frontmatter `name` other harnesses use as the agent identifier. */
|
|
2134
|
+
id: string;
|
|
2135
|
+
scope: AgentScope;
|
|
2136
|
+
description: string;
|
|
2137
|
+
instructions: string;
|
|
2138
|
+
/** Absolute path of the Markdown file. */
|
|
2139
|
+
path: string;
|
|
2140
|
+
createdAt: number;
|
|
2141
|
+
updatedAt: number;
|
|
2142
|
+
/** A project agent that takes precedence over the global agent with the same id. */
|
|
2143
|
+
overridesGlobal?: boolean;
|
|
2144
|
+
/** A global agent hidden by the project agent with the same id. */
|
|
2145
|
+
overriddenByProject?: boolean;
|
|
2146
|
+
}
|
|
2147
|
+
/**
|
|
2148
|
+
* Answer of agent writes. `live`: the running Alisio already uses the change (its agent registry
|
|
2149
|
+
* reloaded and loaded the file); false means it is saved but needs a restart (or a trusted
|
|
2150
|
+
* workspace / the subagents plugin) before sessions can use it.
|
|
2151
|
+
*/
|
|
2152
|
+
export interface AgentSaveResult {
|
|
2153
|
+
agent: AgentDefinitionInfo;
|
|
2154
|
+
live: boolean;
|
|
2155
|
+
}
|
|
2156
|
+
/** `GET /api/agents/definitions`: both scopes merged, plus where new agents go by default. */
|
|
2157
|
+
export interface AgentDefinitionsOverview {
|
|
2158
|
+
agents: AgentDefinitionInfo[];
|
|
2159
|
+
scopes: AgentScope[];
|
|
2160
|
+
defaultScope: AgentScope;
|
|
2161
|
+
/** Directory of each available scope. */
|
|
2162
|
+
dirs: Partial<Record<AgentScope, string>>;
|
|
2163
|
+
/** Project agents load only in trusted workspaces. */
|
|
2164
|
+
trusted: boolean;
|
|
2165
|
+
}
|
|
2166
|
+
/** A predefined starting point for a new agent (`GET /api/agents/templates`). */
|
|
2167
|
+
export interface AgentTemplateInfo {
|
|
2168
|
+
id: string;
|
|
2169
|
+
name: string;
|
|
2170
|
+
description: string;
|
|
2171
|
+
instructions: string;
|
|
2172
|
+
reasoning?: {
|
|
2173
|
+
effort?: string;
|
|
2174
|
+
summary?: AgentReasoningSummary;
|
|
2175
|
+
};
|
|
2176
|
+
text?: {
|
|
2177
|
+
format?: {
|
|
2178
|
+
type: AgentTextFormatType;
|
|
2179
|
+
};
|
|
2180
|
+
verbosity?: AgentVerbosity;
|
|
2181
|
+
};
|
|
2182
|
+
}
|
|
2183
|
+
/** What a model supports for the agent editor, derived from its catalog metadata. */
|
|
2184
|
+
export interface AgentModelCapabilities {
|
|
2185
|
+
/** The catalog declared any capability metadata; otherwise every option is offered. */
|
|
2186
|
+
known: boolean;
|
|
2187
|
+
reasoning: boolean;
|
|
2188
|
+
/** Reasoning effort levels to offer (empty when reasoning is unsupported). */
|
|
2189
|
+
effortLevels: string[];
|
|
2190
|
+
defaultEffort?: string;
|
|
2191
|
+
summary: boolean;
|
|
2192
|
+
verbosity: boolean;
|
|
2193
|
+
textFormats: AgentTextFormatType[];
|
|
2194
|
+
/** Declared tool calling support; absent when unknown. */
|
|
2195
|
+
tools?: boolean;
|
|
2196
|
+
/** Declared image input support; absent when unknown. */
|
|
2197
|
+
vision?: boolean;
|
|
2198
|
+
}
|
|
2199
|
+
/** A configured model the agent editor can select (`GET /api/agents/models`). */
|
|
2200
|
+
export interface AgentModelOption {
|
|
2201
|
+
/** Canonical selector `<provider>/<model>`. */
|
|
2202
|
+
reference: string;
|
|
2203
|
+
provider: string;
|
|
2204
|
+
profile: string;
|
|
2205
|
+
providerName: string;
|
|
2206
|
+
id: string;
|
|
2207
|
+
name?: string;
|
|
2208
|
+
/** The workspace application runs this model right now. */
|
|
2209
|
+
active: boolean;
|
|
2210
|
+
capabilities: AgentModelCapabilities;
|
|
2211
|
+
/** Short capability labels such as "Reasoning", "Tools", "Vision". */
|
|
2212
|
+
labels: string[];
|
|
2213
|
+
}
|
|
2214
|
+
/** Answer of `POST /api/agents/draft`: a definition drafted by the active model. */
|
|
2215
|
+
export interface AgentDraft {
|
|
2216
|
+
name: string;
|
|
2217
|
+
description: string;
|
|
2218
|
+
instructions: string;
|
|
2219
|
+
reasoning?: {
|
|
2220
|
+
effort?: string;
|
|
2221
|
+
summary?: AgentReasoningSummary;
|
|
2222
|
+
};
|
|
2223
|
+
text?: {
|
|
2224
|
+
format?: {
|
|
2225
|
+
type: AgentTextFormatType;
|
|
2226
|
+
};
|
|
2227
|
+
verbosity?: AgentVerbosity;
|
|
2228
|
+
};
|
|
2229
|
+
/** The model that wrote the draft. */
|
|
2230
|
+
generatedBy: string;
|
|
2231
|
+
/** Authoring guidance used: `skill:<name>` (a discovered skill) or `bundled:create-agent`. */
|
|
2232
|
+
guidance: string;
|
|
2233
|
+
}
|
|
2234
|
+
/** Body of every non-2xx web API response. */
|
|
2235
|
+
export interface ApiError {
|
|
2236
|
+
error: {
|
|
2237
|
+
code: ApiErrorCode;
|
|
2238
|
+
message: string;
|
|
2239
|
+
details?: unknown;
|
|
2240
|
+
};
|
|
2241
|
+
correlationId: string;
|
|
2242
|
+
}
|
|
694
2243
|
export declare function definePlugin<T extends Plugin>(plugin: T): T;
|
|
2244
|
+
/** `OutputTruncatedError.code`: a provider's reply was cut off by the output-token limit. */
|
|
2245
|
+
export declare const OUTPUT_TRUNCATED_CODE = "output_truncated";
|
|
2246
|
+
/**
|
|
2247
|
+
* A provider that cannot yield a usable `completed` message because the output-token limit cut
|
|
2248
|
+
* the response before anything usable existed (no text and no complete tool call) throws this,
|
|
2249
|
+
* so the host can recover instead of failing the run. Hosts match on `code` (not `instanceof`),
|
|
2250
|
+
* because a plugin may bundle its own copy of this package. Prefer yielding `completed` with
|
|
2251
|
+
* `truncated: true` whenever the partial message is representable.
|
|
2252
|
+
*/
|
|
2253
|
+
export declare class OutputTruncatedError extends Error {
|
|
2254
|
+
readonly code = "output_truncated";
|
|
2255
|
+
constructor(message?: string);
|
|
2256
|
+
}
|
|
695
2257
|
export declare const textResult: (text: string, isError?: boolean) => ToolResult;
|
|
696
2258
|
/**
|
|
697
2259
|
* Text-only view of a tool result: the content filtered to its text parts, order preserved.
|