@maudecode/talaria-web-contracts 1.16.1 → 1.18.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/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/openapi.js +5 -1
- package/dist/openapi.js.map +1 -1
- package/dist/router.d.ts +4169 -1107
- package/dist/routes/automation.d.ts +173 -10
- package/dist/routes/automation.js +17 -9
- package/dist/routes/automation.js.map +1 -1
- package/dist/routes/chat.d.ts +1215 -16
- package/dist/routes/chat.js +5 -3
- package/dist/routes/chat.js.map +1 -1
- package/dist/routes/core.d.ts +11 -0
- package/dist/routes/core.js +3 -0
- package/dist/routes/core.js.map +1 -1
- package/dist/routes/git.d.ts +98 -2
- package/dist/routes/git.js +20 -6
- package/dist/routes/git.js.map +1 -1
- package/dist/routes/raw.d.ts +3 -1
- package/dist/routes/raw.js +31 -7
- package/dist/routes/raw.js.map +1 -1
- package/dist/routes/sessions.d.ts +3080 -539
- package/dist/routes/sessions.js +68 -1
- package/dist/routes/sessions.js.map +1 -1
- package/dist/routes/settings.d.ts +132 -2
- package/dist/routes/settings.js +4 -4
- package/dist/routes/settings.js.map +1 -1
- package/dist/routes/tools.d.ts +425 -19
- package/dist/routes/tools.js +23 -4
- package/dist/routes/tools.js.map +1 -1
- package/dist/routes/workspaces.d.ts +96 -0
- package/dist/routes/workspaces.js +18 -1
- package/dist/routes/workspaces.js.map +1 -1
- package/dist/sidecar/methods.d.ts +253 -0
- package/dist/sidecar/methods.js +2 -1
- package/dist/sidecar/methods.js.map +1 -1
- package/dist/sidecar/namespaces.d.ts +381 -1
- package/dist/sidecar/namespaces.js +89 -10
- package/dist/sidecar/namespaces.js.map +1 -1
- package/dist/sidecar/version.d.ts +1 -1
- package/dist/sidecar/version.js +1 -1
- package/dist/sidecar/version.js.map +1 -1
- package/dist/sse.d.ts +79 -14
- package/dist/sse.js +13 -6
- package/dist/sse.js.map +1 -1
- package/dist/theme.d.ts +10 -0
- package/dist/theme.js +10 -0
- package/dist/theme.js.map +1 -0
- package/dist/views.d.ts +1419 -39
- package/dist/views.js +215 -25
- package/dist/views.js.map +1 -1
- package/fixtures/sidecar/checkpoints.json +50 -0
- package/fixtures/sidecar/commands.json +250 -96
- package/fixtures/sidecar/cron.json +38 -55
- package/fixtures/sidecar/goals.json +6 -6
- package/fixtures/sidecar/kanban.json +84 -67
- package/fixtures/sidecar/plugins.json +171 -172
- package/fixtures/sidecar/process.json +25 -0
- package/fixtures/sidecar/profiles.json +10 -2
- package/fixtures/sidecar/providers.json +25 -12
- package/fixtures/sidecar/rpc.json +17 -0
- package/fixtures/sidecar/runtime.json +22 -29
- package/fixtures/sidecar/state_db.json +15 -0
- package/fixtures/sidecar/text.json +2 -2
- package/fixtures/sidecar/usage.json +38 -0
- package/package.json +1 -1
package/dist/views.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* that must survive a round trip (documented passthrough).
|
|
6
6
|
*/
|
|
7
7
|
import { z } from 'zod';
|
|
8
|
+
import { CanonicalBotChatSchema } from './sidecar/namespaces.js';
|
|
8
9
|
const Json = z.unknown();
|
|
9
10
|
export const NullableString = z.string().nullable();
|
|
10
11
|
export const NullableNumber = z.number().nullable();
|
|
@@ -17,8 +18,28 @@ export const AttachmentSchema = z.looseObject({
|
|
|
17
18
|
});
|
|
18
19
|
/** The server's display class for a tool call: clients map it to an icon and localized verb, and never classify names themselves. */
|
|
19
20
|
export const ToolKindSchema = z.enum(['shell', 'read', 'list', 'search', 'web', 'write', 'skill', 'memory', 'delegate', 'unknown']);
|
|
20
|
-
/**
|
|
21
|
-
|
|
21
|
+
/**
|
|
22
|
+
* TAL-604: one row of a unified diff hunk as the server parsed it. `text` is the raw line, its `+` / `-` / space prefix kept;
|
|
23
|
+
* `old_line` / `new_line` number it on each side (null on the side it is absent from, and on a `\ No newline` marker).
|
|
24
|
+
*/
|
|
25
|
+
export const DiffLineSchema = z.object({ kind: z.enum(['addition', 'deletion', 'context']), old_line: z.number().int().nullable(), new_line: z.number().int().nullable(), text: z.string() });
|
|
26
|
+
/**
|
|
27
|
+
* TAL-604: one hunk of a unified diff: its `@@` `header`, the first old and new line numbers, the last new line it covers
|
|
28
|
+
* (`new_end`, at least `new_start`), its added and removed line counts, and its lines. A diff without `@@` headers yields
|
|
29
|
+
* one hunk per file with an empty `header` and null numbers.
|
|
30
|
+
*/
|
|
31
|
+
export const DiffHunkSchema = z.object({
|
|
32
|
+
header: z.string(), old_start: z.number().int().nullable(), new_start: z.number().int().nullable(), new_end: z.number().int().nullable(),
|
|
33
|
+
additions: z.number().int(), deletions: z.number().int(), lines: z.array(DiffLineSchema),
|
|
34
|
+
});
|
|
35
|
+
/**
|
|
36
|
+
* TAL-448: a completed file-edit call's change, from its result's unified diff: `added` / `removed` count the whole diff's
|
|
37
|
+
* lines (file headers excluded); `diff` is the redacted diff, capped at 400 lines, with `truncated` when cut, and `hunks`
|
|
38
|
+
* that diff parsed (TAL-604). Absent on a call whose result has no diff.
|
|
39
|
+
*/
|
|
40
|
+
export const ToolEditDiffSchema = z.object({ added: z.number().int(), removed: z.number().int(), diff: z.string(), truncated: z.boolean(), hunks: z.array(DiffHunkSchema) });
|
|
41
|
+
/** Server-derived display fields every tool call carries: the kind, and the redacted first-line label of its main argument (`''` when none; omitted on a live frame with none, which keeps its start frame's target), and a file edit's `edit_diff`. */
|
|
42
|
+
export const ToolDisplayFields = { kind: ToolKindSchema.optional(), target: z.string().optional(), edit_diff: ToolEditDiffSchema.optional() };
|
|
22
43
|
/**
|
|
23
44
|
* TAL-315: a tool result's display sections, decided by the server's one rule for live, replayed and persisted results
|
|
24
45
|
* alike. Clients show `stdout`, `stderr`, a labelled `error` and a labelled `exit_code` (sent only when worth showing), or
|
|
@@ -109,6 +130,14 @@ export const MessageSchema = z.looseObject({
|
|
|
109
130
|
provider_details: Json.optional(), provider_details_label: z.string().optional(), recovery_control: Json.optional(), _anchor_activity_scene: ActivitySceneSchema.optional(),
|
|
110
131
|
/** The turn this row belongs to; the server stamps every row it sends, so clients group turns by equality alone. */
|
|
111
132
|
_turn_id: z.string().optional(),
|
|
133
|
+
/** On a turn's last assistant row: seconds the turn ran. */
|
|
134
|
+
_turnDuration: z.number().optional(),
|
|
135
|
+
/** On a turn's last assistant row: output tokens per second, when the turn reported usage. */
|
|
136
|
+
_turnTps: z.number().optional(),
|
|
137
|
+
/** Epoch seconds the row was written; `timestamp` when absent. */
|
|
138
|
+
_ts: z.number().optional(),
|
|
139
|
+
/** Reasoning titles an older Web stored on the row, in order. */
|
|
140
|
+
reasoning_titles: z.array(z.string()).optional(),
|
|
112
141
|
/** The running turn's prompt, which the turn's settlement replaces with its persisted row. */
|
|
113
142
|
_active_turn_user: z.boolean().optional(),
|
|
114
143
|
/** A consumed steer at its causal place in the turn: display-only, never model history. A steer only the Agent recorded has no timing. */
|
|
@@ -118,6 +147,11 @@ export const MessageSchema = z.looseObject({
|
|
|
118
147
|
/** A settled body too long to lay out whole: clients render `_display_excerpt` collapsed, with a local "Show more" for `content`. */
|
|
119
148
|
_display_truncated: z.boolean().optional(),
|
|
120
149
|
_display_excerpt: z.string().optional(),
|
|
150
|
+
/**
|
|
151
|
+
* TAL-452: a typed user message (never a steer, background update or marker) longer than 20 lines or 2,000
|
|
152
|
+
* characters. Clients show it folded to a few lines with a local "Show more"; copy and edit use the whole `content`.
|
|
153
|
+
*/
|
|
154
|
+
_collapsible: z.boolean().optional(),
|
|
121
155
|
/**
|
|
122
156
|
* TAL-186: an assistant row's text with each media reference the server serves rewritten to standard Markdown: an
|
|
123
157
|
* image to ``, any other file to `[name](url)`. Clients render it in place of `content` as one Markdown
|
|
@@ -151,6 +185,12 @@ export const MessageSchema = z.looseObject({
|
|
|
151
185
|
_background_reply: z.boolean().optional(),
|
|
152
186
|
/** TAL-460: that reply is only a silence marker; clients show the update's lines and nothing of this turn's reply. */
|
|
153
187
|
_background_silent: z.boolean().optional(),
|
|
188
|
+
/**
|
|
189
|
+
* TAL-600: how clients show the row, on every row the server sends: `row` on its own, `in_scene` only inside its turn's
|
|
190
|
+
* activity scene (a tool result or a consumed steer), `hidden` not at all (a silent background reply, or a row with
|
|
191
|
+
* nothing to show).
|
|
192
|
+
*/
|
|
193
|
+
_display: z.enum(['row', 'hidden', 'in_scene']).optional(),
|
|
154
194
|
});
|
|
155
195
|
export const ComposerDraftSchema = z.looseObject({ text: z.string().optional(), files: z.array(Json).optional() });
|
|
156
196
|
/**
|
|
@@ -179,6 +219,7 @@ const ReadOnlySchema = z.boolean().describe('The session cannot be modified from
|
|
|
179
219
|
const CanBranchSchema = z.boolean().describe('Web may branch this session: never a subagent child, and a read-only session only when it is a cron run.');
|
|
180
220
|
const CanPinSchema = z.boolean().describe('Web may pin or unpin this session: never a subagent child.');
|
|
181
221
|
const CanArchiveSchema = z.boolean().describe('Web may archive or unarchive this session: never a subagent child.');
|
|
222
|
+
const CanDeleteSchema = z.boolean().describe('Web may delete this session: never a read-only session (a read-only import, a view-only subagent child, or a foreign session whose owner refuses claiming).');
|
|
182
223
|
const CanDuplicateSchema = z.boolean().describe('Web may duplicate this session: it has a WebUI copy and is not a subagent child.');
|
|
183
224
|
// TAL-310: the server classifies every session's source once; clients file rows by it and never scan source markers.
|
|
184
225
|
export const SourceKindSchema = z.enum(['webui', 'cli', 'messaging', 'cron', 'webhook', 'subagent', 'claude_code', 'kanban', 'api', 'other'])
|
|
@@ -191,6 +232,17 @@ const IsMessagingSessionSchema = z.boolean().describe('`source_kind` is `messagi
|
|
|
191
232
|
* the folder name (TAL-303). Null without a workspace; absent from an older server, where clients show no label.
|
|
192
233
|
*/
|
|
193
234
|
const WorkspaceNameSchema = NullableString.optional();
|
|
235
|
+
/**
|
|
236
|
+
* TAL-560: the "Context compaction · Reference only" card, on payloads that carry `messages`. Clients render `text` after
|
|
237
|
+
* the row at full-transcript index `after_message_index` (row `after_message_index - _messages_offset` of `messages`), or
|
|
238
|
+
* above the loaded rows when it is null or before them. Null: no card.
|
|
239
|
+
*/
|
|
240
|
+
export const CompressionReferenceSchema = z.object({
|
|
241
|
+
text: z.string(),
|
|
242
|
+
after_message_index: z.number().int().nonnegative().nullable().describe('The full-transcript index of the row the card follows; null puts it above the transcript.'),
|
|
243
|
+
});
|
|
244
|
+
/** TAL-454: the chat a `/branch` copied, with its redacted title. */
|
|
245
|
+
export const BranchedFromSchema = z.object({ session_id: SessionIdSchema, title: z.string() });
|
|
194
246
|
/** Full session record from `GET /api/session` and mutations returning `session`. */
|
|
195
247
|
export const SessionSchema = z.looseObject({
|
|
196
248
|
session_id: SessionIdSchema, title: z.string(), workspace: z.string().optional(), created_workspace: z.string().nullable().optional(), model: NullableString.optional(), model_provider: NullableString.optional(),
|
|
@@ -201,9 +253,10 @@ export const SessionSchema = z.looseObject({
|
|
|
201
253
|
cache_hit_percent: NullableNumber.optional(), estimated_cost: NullableNumber.optional(), active_stream_id: ActiveStreamIdSchema, is_streaming: IsStreamingSchema, active_turn_origin: ActiveTurnOriginSchema, pending_steers: z.array(PendingSteerSchema).optional().describe('TAL-424: the active stream\'s pending steers, oldest first.'), has_pending_user_message: z.boolean().optional(),
|
|
202
254
|
pending_user_message: NullableString.optional(), pending_attachments: z.array(AttachmentSchema).optional(), pending_started_at: NullableNumber.optional(), pending_user_source: NullableString.optional(),
|
|
203
255
|
context_length: NullableNumber.optional(), threshold_tokens: NullableNumber.optional(), last_prompt_tokens: NullableNumber.optional(), post_compression_context_tokens_estimate: NullableNumber.optional(), ...ContextUsageFields,
|
|
204
|
-
enabled_toolsets: z.array(z.string()).nullable().optional(), composer_draft: ComposerDraftSchema.optional(), is_cli_session: z.boolean().optional(), source_kind: SourceKindSchema, is_messaging_session: IsMessagingSessionSchema, sort_ts: SortTsSchema, read_only: ReadOnlySchema, can_branch: CanBranchSchema, can_pin: CanPinSchema, can_archive: CanArchiveSchema, can_duplicate: CanDuplicateSchema, source_tag: NullableString.optional(),
|
|
256
|
+
enabled_toolsets: z.array(z.string()).nullable().optional(), composer_draft: ComposerDraftSchema.optional(), is_cli_session: z.boolean().optional(), source_kind: SourceKindSchema, is_messaging_session: IsMessagingSessionSchema, sort_ts: SortTsSchema, read_only: ReadOnlySchema, can_branch: CanBranchSchema, can_pin: CanPinSchema, can_archive: CanArchiveSchema, can_delete: CanDeleteSchema, can_duplicate: CanDuplicateSchema, source_tag: NullableString.optional(),
|
|
257
|
+
can_compress: z.boolean().optional().describe('TAL-614: a manual compression would start now: writable, no running turn, and at least four model-history messages. Only the full session detail carries it; absent means no.'),
|
|
205
258
|
source_label: NullableString.optional(), session_source: NullableString.optional(), raw_source: NullableString.optional(), parent_session_id: NullableString.optional(), worktree_path: NullableString.optional(),
|
|
206
|
-
worktree_branch: NullableString.optional(), worktree_repo_root: NullableString.optional(), share_token: NullableString.optional(), share_created_at: NullableNumber.optional(), manual_title: z.boolean().optional(),
|
|
259
|
+
worktree_branch: NullableString.optional(), worktree_repo_root: NullableString.optional(), share_token: NullableString.optional(), share_url: NullableString.optional(), share_created_at: NullableNumber.optional(), manual_title: z.boolean().optional(),
|
|
207
260
|
compression_anchor_summary: NullableString.optional(), compression_recovery: z.record(z.string(), Json).optional(), recommended_recovery_action: NullableString.optional(), compression_recovery_action: NullableString.optional(),
|
|
208
261
|
compression_recovery_source_session_id: NullableString.optional(), gateway_routing: Json.optional(), _messages_offset: z.number().optional(), _messages_truncated: z.boolean().optional(), _msg_limit_max: z.number().optional(), _load_revision: z.string().optional(),
|
|
209
262
|
/**
|
|
@@ -215,15 +268,17 @@ export const SessionSchema = z.looseObject({
|
|
|
215
268
|
/** The agent's display name: a named profile's own name, else the `bot_name` setting (TAL-458). */
|
|
216
269
|
assistant_name: z.string().optional(),
|
|
217
270
|
workspace_name: WorkspaceNameSchema,
|
|
271
|
+
compression_reference: CompressionReferenceSchema.nullable().optional(),
|
|
272
|
+
branched_from: BranchedFromSchema.nullable().optional().describe('TAL-454: the chat this one was branched from while it still loads (archived included); null for a compression continuation, a deleted or missing parent, and every other chat.'),
|
|
218
273
|
});
|
|
219
274
|
export const SessionEnvelopeSchema = z.looseObject({ session: SessionSchema });
|
|
220
275
|
/** Sidebar row from `GET /api/sessions`. */
|
|
221
276
|
export const SessionRowSchema = z.looseObject({
|
|
222
277
|
session_id: SessionIdSchema, title: z.string(), workspace: z.string().optional(), model: NullableString.optional(), created_at: UnixSeconds.optional(), updated_at: UnixSeconds.optional(), last_message_at: NullableNumber.optional(),
|
|
223
278
|
message_count: z.number().optional(), pinned: z.boolean().optional(), archived: z.boolean().optional(), project_id: NullableString.optional(), profile: NullableString.optional(), is_streaming: IsStreamingSchema,
|
|
224
|
-
is_cli_session: z.boolean().optional(), source_kind: SourceKindSchema, is_messaging_session: IsMessagingSessionSchema, sort_ts: SortTsSchema, cron_running: z.boolean().optional(), read_only: ReadOnlySchema, can_branch: CanBranchSchema, can_pin: CanPinSchema, can_archive: CanArchiveSchema, can_duplicate: CanDuplicateSchema, attention: z.looseObject({ kind: z.string().optional(), count: z.number().optional() }).nullable().optional(),
|
|
279
|
+
is_cli_session: z.boolean().optional(), source_kind: SourceKindSchema, is_messaging_session: IsMessagingSessionSchema, sort_ts: SortTsSchema, cron_running: z.boolean().optional(), read_only: ReadOnlySchema, can_branch: CanBranchSchema, can_pin: CanPinSchema, can_archive: CanArchiveSchema, can_delete: CanDeleteSchema, can_duplicate: CanDuplicateSchema, attention: z.looseObject({ kind: z.string().optional(), count: z.number().optional() }).nullable().optional(),
|
|
225
280
|
source_tag: NullableString.optional(), source_label: NullableString.optional(), session_source: NullableString.optional(), raw_source: NullableString.optional(), parent_session_id: NullableString.optional(),
|
|
226
|
-
active_stream_id: ActiveStreamIdSchema, share_token: NullableString.optional(), worktree_branch: NullableString.optional(), match_type: z.enum(['title', 'metadata', 'content']).optional(), match_preview: NullableString.optional(),
|
|
281
|
+
active_stream_id: ActiveStreamIdSchema, share_token: NullableString.optional(), share_url: NullableString.optional(), worktree_branch: NullableString.optional(), match_type: z.enum(['title', 'metadata', 'content']).optional(), match_preview: NullableString.optional(),
|
|
227
282
|
workspace_name: WorkspaceNameSchema,
|
|
228
283
|
...ContextUsageFields,
|
|
229
284
|
});
|
|
@@ -254,7 +309,12 @@ export const ChatStartResponseSchema = z.looseObject({
|
|
|
254
309
|
stream_id: z.string().optional(), session_id: SessionIdSchema.optional(), turn_id: z.string().optional(), user_message_id: z.union([z.string(), z.number()]).nullable().optional(), pending_started_at: z.number().nullable().optional(),
|
|
255
310
|
title: z.string().optional(), effective_model: z.string().optional(), effective_model_provider: z.string().optional(), queued: z.boolean().optional(), ok: z.boolean().optional(), status: z.string().optional(), reason: z.string().optional(), session: SessionSchema.optional(),
|
|
256
311
|
});
|
|
257
|
-
|
|
312
|
+
/**
|
|
313
|
+
* `active` is whether this stream's channel is still live. `blocking_stream_id` (TAL-622) is the run that still holds the
|
|
314
|
+
* stream's session: this run while it unwinds after a Stop, or a successor such as a goal continuation. A session delete
|
|
315
|
+
* answers 409 while it is set, so a client draining a session before deleting it waits until it is null.
|
|
316
|
+
*/
|
|
317
|
+
export const StreamStatusSchema = z.looseObject({ active: z.boolean(), stream_id: z.string(), replay_available: z.boolean().optional(), journal: Json.optional(), blocking_stream_id: z.string().nullable() });
|
|
258
318
|
/**
|
|
259
319
|
* TAL-424: a pending steer is no longer pending without the Agent taking it: Edit and Cancel by the user, `stopped` by a
|
|
260
320
|
* Stop (`text` goes back to the composer), or `followup` when the server sends it as the next turn. `steer_id` is null
|
|
@@ -301,11 +361,11 @@ export const ClarifyRespondRequestSchema = z.looseObject({ session_id: SessionId
|
|
|
301
361
|
export const ClarifyRespondResponseSchema = z.looseObject({ ok: z.boolean(), response: z.string().optional(), error: z.string().optional(), stale: z.boolean().optional() });
|
|
302
362
|
export const DraftSchema = z.looseObject({ text: z.string(), files: z.array(Json) });
|
|
303
363
|
export const DraftResponseSchema = z.looseObject({ ok: z.literal(true), draft: DraftSchema, draft_version: z.string().nullable(), unchanged: z.boolean().optional() });
|
|
304
|
-
|
|
364
|
+
/** At most this many attachments ride one chat message; the server names each in the prompt (TAL-276, TAL-635). */
|
|
365
|
+
export const MAX_CHAT_ATTACHMENTS = 20;
|
|
366
|
+
export const UploadResponseSchema = z.looseObject({ filename: z.string(), path: z.string(), size: z.number(), mime: z.string(), is_image: z.boolean().optional(), rollback_token: z.string().optional(), named_in_prompt: z.boolean().optional(), max_attachments_per_message: z.number().int().positive().optional() });
|
|
305
367
|
export const GoalViewSchema = z.looseObject({ text: z.string().optional(), state: z.string().optional(), status: z.string().optional(), turns: z.number().optional(), max_turns: z.number().optional(), reason: z.string().optional() });
|
|
306
368
|
export const GoalResponseSchema = z.looseObject({ ok: z.boolean().optional(), action: z.string().optional(), goal: GoalViewSchema.nullable().optional(), message: z.string().optional(), message_key: z.string().optional(), stream_id: z.string().optional(), status: z.string().optional(), reason: z.string().optional() });
|
|
307
|
-
export const BackgroundResultSchema = z.looseObject({ id: z.string().optional(), task_id: z.string().optional(), status: z.string().optional(), title: z.string().optional(), summary: z.string().optional(), prompt: z.string().optional(), answer: NullableString.optional(), error: z.string().optional(), completed_at: z.number().nullable().optional() });
|
|
308
|
-
export const BackgroundStatusSchema = z.looseObject({ results: z.array(BackgroundResultSchema) });
|
|
309
369
|
/**
|
|
310
370
|
* TAL-372: one piece of background work a session owns, the same record for every client, reload and restart.
|
|
311
371
|
* - `task_id` is stable: the delegation unit's id, the process id, or the `/background` task id.
|
|
@@ -352,6 +412,11 @@ export const SessionNewRequestSchema = z.looseObject({
|
|
|
352
412
|
});
|
|
353
413
|
export const TranscribeCapabilitySchema = z.looseObject({ ok: z.literal(true), available: z.boolean(), provider: z.string() });
|
|
354
414
|
// ── settings, profiles, models, providers ───────────────────────────────
|
|
415
|
+
/** TAL-411: the request profile's quota urgency thresholds. A save patches valid fields and clamps critical to at most warning. */
|
|
416
|
+
export const QuotaThresholdsSchema = z.object({
|
|
417
|
+
warning_remaining_percent: z.number().int().min(1).max(99), critical_remaining_percent: z.number().int().min(0).max(99), pace_tolerance_percent: z.number().int().min(0).max(25),
|
|
418
|
+
pace_warning_burn_rate_percent: z.number().int().min(100).max(300), pace_critical_burn_rate_percent: z.number().int().min(100).max(400), pace_minimum_elapsed_hours: z.number().int().min(0).max(72),
|
|
419
|
+
});
|
|
355
420
|
export const LoginResponseSchema = z.looseObject({ ok: z.literal(true), message: z.string().optional() });
|
|
356
421
|
export const SettingsSchema = z.looseObject({
|
|
357
422
|
bot_name: z.string().optional(), default_model: z.string().optional(), default_workspace: z.string().optional(), language: z.string().optional(), send_key: z.string().optional(), font_size: z.string().optional(),
|
|
@@ -364,10 +429,15 @@ export const SettingsSchema = z.looseObject({
|
|
|
364
429
|
dictation_append: z.boolean().optional(), persisted_speech_keys: z.array(z.string()).optional(),
|
|
365
430
|
/** TAL-279: ask before opening external chat links; `trusted_link_hosts` are exact, server-normalized hostnames that skip the ask. */
|
|
366
431
|
confirm_external_links: z.boolean().optional(), trusted_link_hosts: z.array(z.string()).optional(),
|
|
432
|
+
provider_quota_thresholds: QuotaThresholdsSchema.optional(),
|
|
367
433
|
});
|
|
368
434
|
export const ProfileSchema = z.looseObject({
|
|
369
435
|
name: z.string(), path: z.string().optional(), is_active: z.boolean().optional(), is_default: z.boolean().optional(), model: NullableString.optional(), provider: NullableString.optional(), skill_count: z.number().optional(),
|
|
370
436
|
total_skills: z.number().optional(), enabled_skills: z.number().optional(), gateway_running: z.boolean().optional(), has_env: z.boolean().optional(), visible: z.boolean().optional(),
|
|
437
|
+
/** TAL-213: Bot Mode identity from `profile.yaml` (the bot's roster title, else the profile's display name), one bounded printable line each. */
|
|
438
|
+
display_name: z.string().optional(), description: z.string().optional(), has_avatar: z.boolean().optional(),
|
|
439
|
+
/** TAL-213: present only when the profile has a canonical Bot Chat; clients open `tip_session_id` after switching to the profile. */
|
|
440
|
+
canonical_session: CanonicalBotChatSchema.nullable().optional(),
|
|
371
441
|
});
|
|
372
442
|
export const ProfilesSchema = z.looseObject({ profiles: z.array(ProfileSchema), active: z.string(), single_profile_mode: z.boolean().optional() });
|
|
373
443
|
export const ActiveProfileSchema = z.looseObject({ name: z.string(), path: z.string().optional(), is_default: z.boolean().optional(), default_workspace: NullableString.optional() });
|
|
@@ -378,16 +448,29 @@ export const ReasoningStatusSchema = z.looseObject({ show_reasoning: z.boolean()
|
|
|
378
448
|
export const ModelEntrySchema = z.looseObject({ id: z.string(), label: z.string().optional(), provider: z.string().optional(), provider_id: z.string().optional(), bare_id: z.string().optional(), supports_fast_tier: z.boolean().optional() });
|
|
379
449
|
export const ModelGroupSchema = z.looseObject({ provider: z.string(), provider_id: z.string().optional(), models: z.array(ModelEntrySchema), extra_models: z.array(ModelEntrySchema).optional() });
|
|
380
450
|
export const ModelsSchema = z.looseObject({ active_provider: NullableString.optional(), default_model: z.string().optional(), default_provider_id: NullableString.optional(), default_bare_id: z.string().optional(), default_option_id: NullableString.optional(), groups: z.array(ModelGroupSchema), aliases: z.record(z.string(), Json).optional(), configured_model_badges: z.record(z.string(), Json).optional() });
|
|
451
|
+
/** TAL-603: where a card's credential comes from; `other` is a source the server cannot name, shown as its raw `key_source`. */
|
|
452
|
+
export const KeySourceKindSchema = z.enum(['env', 'oauth', 'config', 'pool', 'plugin', 'other']);
|
|
453
|
+
/**
|
|
454
|
+
* `has_key` reports a credential; `configured` (TAL-570) is the row's setup status, which a keyless Ollama or LM Studio endpoint also meets.
|
|
455
|
+
* TAL-603: `is_active` marks the active provider's card; `key_source_kind` is the key badge (`null` without a credential);
|
|
456
|
+
* `models_total` is the catalog size, never below `models.length`. `is_active` and `key_source_kind` are absent from older servers.
|
|
457
|
+
* TAL-641: `removable` marks a key Remove would clear: a built-in, not self-hosted, provider whose only key is its own profile `.env` variable.
|
|
458
|
+
*/
|
|
381
459
|
export const ProviderSchema = z.looseObject({
|
|
382
|
-
id: z.string(), display_name: z.string().optional(), has_key: z.boolean().optional(), configurable: z.boolean().optional(), is_oauth: z.boolean().optional(), is_plugin_provider: z.boolean().optional(), is_self_hosted: z.boolean().optional(),
|
|
460
|
+
id: z.string(), display_name: z.string().optional(), has_key: z.boolean().optional(), configured: z.boolean().optional(), configurable: z.boolean().optional(), is_oauth: z.boolean().optional(), is_plugin_provider: z.boolean().optional(), is_self_hosted: z.boolean().optional(),
|
|
383
461
|
is_custom: z.boolean().optional(), key_source: z.string().optional(), base_url: NullableString.optional(), auth_error: NullableString.optional(), env_var: NullableString.optional(), models: z.array(ModelEntrySchema).optional(), models_total: z.number().optional(),
|
|
462
|
+
is_active: z.boolean().optional(), key_source_kind: KeySourceKindSchema.nullable().optional(), removable: z.boolean().optional(),
|
|
384
463
|
});
|
|
385
464
|
export const ProvidersSchema = z.looseObject({ providers: z.array(ProviderSchema), active_provider: NullableString.optional() });
|
|
465
|
+
export const QuotaLevelSchema = z.enum(['healthy', 'warning', 'critical', 'stale', 'unavailable']);
|
|
466
|
+
/** TAL-411: the server's classification per colour basis; `/api/provider/quotas` only, at the profile's thresholds. */
|
|
467
|
+
export const QuotaUrgencySchema = z.looseObject({ remaining: QuotaLevelSchema, pace: QuotaLevelSchema.describe('Burn rate and pace tolerance; the remaining classification when the window has no pace.') });
|
|
386
468
|
/** TAL-409: a window's pace as of the envelope's `computed_at`. Stale once `valid_until` (the window's reset) passes. */
|
|
387
469
|
export const QuotaPaceSchema = z.looseObject({
|
|
388
470
|
expected_remaining_percent: z.number(), pace_delta_percent: z.number(), burn_rate: z.number(), minutes_to_reset: z.number(),
|
|
389
471
|
projected_minutes_to_empty: NullableNumber.describe('Minutes until the window empties at the current burn; null when nothing has been used.'),
|
|
390
472
|
elapsed_minutes: z.number(), valid_until: z.string(),
|
|
473
|
+
status: z.enum(['over', 'on', 'under']).optional().describe('TAL-411, `/api/provider/quotas` only: over when behind pace by at least the tolerance, under when more than 1 point ahead.'),
|
|
391
474
|
});
|
|
392
475
|
export const QuotaForecastSchema = z.looseObject({
|
|
393
476
|
outcome: z.enum(['safe', 'warning']).describe('`warning` when the projection empties the window before it resets.'),
|
|
@@ -399,6 +482,8 @@ export const QuotaWindowSchema = z.looseObject({
|
|
|
399
482
|
window_seconds: NullableNumber.describe('The provider value, else 5h or weekly from the label; null when unknown.'),
|
|
400
483
|
pace: QuotaPaceSchema.nullable().describe('Null for a window without a future reset, a usage value, or a 5h/weekly length.'),
|
|
401
484
|
forecast: QuotaForecastSchema.nullable(),
|
|
485
|
+
projection_eligible: z.boolean().optional().describe('TAL-411, `/api/provider/quotas` only: the burn-rate breakpoints apply (enough elapsed time and use, and the projection empties the window before reset).'),
|
|
486
|
+
urgency: QuotaUrgencySchema.optional(),
|
|
402
487
|
});
|
|
403
488
|
const QuotaWindowIndex = z.number().int().nullable().optional();
|
|
404
489
|
export const QuotaSourceSchema = z.looseObject({
|
|
@@ -406,6 +491,7 @@ export const QuotaSourceSchema = z.looseObject({
|
|
|
406
491
|
is_active_provider: z.boolean().optional(), quota: Json.optional(), windows: z.array(QuotaWindowSchema).optional(), balances: Json.optional(), plan: Json.optional(), details: Json.optional(), unavailable_reason: Json.optional(), retry_after: Json.optional(), fetched_at: Json.optional(),
|
|
407
492
|
pace_window_index: QuotaWindowIndex.describe('The window a pace-coloured widget shows: the weekly one, else the first 5h/session window.'),
|
|
408
493
|
session_window_index: QuotaWindowIndex.describe('The session (else 5h) window.'), weekly_window_index: QuotaWindowIndex.describe('The weekly window.'),
|
|
494
|
+
urgency: QuotaUrgencySchema.optional().describe('TAL-411: `remaining` of the first window, `pace` of the pace window; alerts and the source colour follow it.'),
|
|
409
495
|
});
|
|
410
496
|
/** An account-usage provider's normalised snapshot on `/api/provider/quota` (the same windows and indexes as a quotas source). */
|
|
411
497
|
export const QuotaAccountLimitsSchema = z.looseObject({
|
|
@@ -426,6 +512,22 @@ export const ProviderQuotasSchema = z.looseObject({
|
|
|
426
512
|
missing_source: z.boolean().describe('True when `?source=` names a source id this scope no longer has; `sources` is then empty.'),
|
|
427
513
|
sources: z.array(QuotaSourceSchema).describe('Each live source id exactly once, ordered by `provider_id`, then `account_label`, then `source_id`. Clients render this list as-is; a `?source=` read returns that one row.'),
|
|
428
514
|
});
|
|
515
|
+
/** One day of OpenRouter spend on `/api/provider/cost-history` (TAL-412). */
|
|
516
|
+
export const CostSnapshotSchema = z.looseObject({
|
|
517
|
+
date: z.string().describe('UTC day, `YYYY-MM-DD`.'), used: NullableNumber.describe('Cumulative OpenRouter usage in USD that day.'),
|
|
518
|
+
delta: NullableNumber.describe("Spend since the previous day; the day's `used` after a credit reset; null for the first day or a missing `used`."),
|
|
519
|
+
bar_percent: z.number().describe('Bar height: `delta` as a percent of the window\'s largest delta, at least 2 for any positive delta, 0 for a null delta.'),
|
|
520
|
+
});
|
|
521
|
+
/** Python `get_provider_cost_history`: OpenRouter daily spend with the server-computed monthly pace and budget standing. */
|
|
522
|
+
export const ProviderCostHistorySchema = z.looseObject({
|
|
523
|
+
ok: z.boolean(), provider: NullableString, display_name: z.string().optional(), supported: z.boolean().optional(), status: z.string().describe('`available`, `unavailable` (the snapshots are the last known data), `no_key`, `unsupported`, or `missing_provider`.'), message: z.string(),
|
|
524
|
+
window_days: z.number().int().optional(), snapshots: z.array(CostSnapshotSchema).optional(), limit: NullableNumber.optional(), label: NullableString.optional(),
|
|
525
|
+
monthly_budget: NullableNumber.optional().describe('Settings `provider_cost_budget`.'),
|
|
526
|
+
monthly_pace: NullableNumber.optional().describe('Mean of the non-null deltas × 30, in USD rounded to cents; null without a delta.'),
|
|
527
|
+
has_enough_data: z.boolean().optional().describe('At least one non-null delta (two daily snapshots).'),
|
|
528
|
+
budget_percent: NullableNumber.optional().describe('round(pace / budget × 100); null without a positive pace and a budget.'),
|
|
529
|
+
budget_level: z.enum(['ok', 'warn', 'over']).nullable().optional().describe('`warn` from 80%, `over` from 100%; null without `budget_percent`.'),
|
|
530
|
+
});
|
|
429
531
|
export const PersonalitiesSchema = z.looseObject({ personalities: z.array(z.looseObject({ name: z.string(), description: z.string().optional() })) });
|
|
430
532
|
/** One auxiliary task slot in server order (TAL-388). The server owns ordering, normalization, and catalog matching. */
|
|
431
533
|
export const AuxiliaryTaskSchema = z.looseObject({
|
|
@@ -453,12 +555,25 @@ export const FileEntrySchema = z.looseObject({
|
|
|
453
555
|
birthtime_ns: z.union([z.number(), z.string()]).nullable().optional(), hidden: z.boolean().optional(), workspace_sort_rank: z.number().int().optional(), target: z.string().optional(), target_outside_workspace: z.boolean().optional(),
|
|
454
556
|
});
|
|
455
557
|
export const DirListingSchema = z.looseObject({ path: z.string().optional(), entries: z.array(FileEntrySchema), signature: z.string().optional(), workspace: z.string().optional(), workspace_recovered: z.boolean().optional(), is_git: z.boolean().optional() });
|
|
456
|
-
|
|
457
|
-
export const
|
|
558
|
+
/** How a workspace file renders (TAL-566): media streams from `/api/file/raw`; text kinds carry `content`. */
|
|
559
|
+
export const FilePreviewKindSchema = z.enum(['text', 'markdown', 'csv', 'html', 'image', 'pdf', 'audio', 'video', 'binary']);
|
|
560
|
+
/** `table` is a `csv` preview's leading rows (header first); `table_truncated` says the file has more. `preview_url` is an
|
|
561
|
+
* `html` preview's app-relative frame URL, under which the page's relative assets also resolve. */
|
|
562
|
+
export const FileContentSchema = z.looseObject({
|
|
563
|
+
path: z.string().optional(), content: z.string().optional(), lines: z.number().optional(), size: z.number().optional(), truncated: z.boolean().optional(), binary: z.boolean().optional(), mime: z.string().optional(),
|
|
564
|
+
preview: FilePreviewKindSchema.optional(), table: z.array(z.array(z.string())).optional(), table_truncated: z.boolean().optional(),
|
|
565
|
+
preview_url: z.string().optional(),
|
|
566
|
+
});
|
|
567
|
+
const GitBadgeSchema = z.looseObject({ is_git: z.boolean().optional(), branch: NullableString.optional(), dirty: z.number().optional(), modified: z.number().optional(), untracked: z.number().optional(), ahead: z.number().optional(), behind: z.number().optional() });
|
|
568
|
+
export const GitInfoSchema = z.looseObject({ git: GitBadgeSchema.nullable().optional() });
|
|
458
569
|
// ── tools ────────────────────────────────────────────────────────────────
|
|
459
570
|
export const SkillSchema = z.looseObject({ name: z.string(), description: NullableString.optional(), category: NullableString.optional(), disabled: z.boolean().optional() });
|
|
460
571
|
export const SkillsSchema = z.looseObject({ skills: z.array(SkillSchema), categories: z.array(Json).optional() });
|
|
461
|
-
|
|
572
|
+
/**
|
|
573
|
+
* `linked_files` groups the skill directory's files by folder (`references`, `templates`, ...); open one with `?file=`.
|
|
574
|
+
* A linked file that is not UTF-8 text carries `binary: true` and its `size` instead of `content`.
|
|
575
|
+
*/
|
|
576
|
+
export const SkillContentSchema = z.looseObject({ name: z.string().optional(), content: z.string().optional(), path: z.string().optional(), linked_files: z.record(z.string(), z.array(z.string())).optional(), binary: z.literal(true).optional(), size: z.number().optional(), success: z.boolean().optional(), message: z.string().optional(), ok: z.boolean().optional() });
|
|
462
577
|
export const SkillsUsageSchema = z.looseObject({ usage: z.record(z.string(), z.looseObject({ use_count: z.number().optional(), view_count: z.number().optional(), patch_count: z.number().optional() })), skill_names: z.array(z.string()).optional(), total_invocations: z.number().optional(), unique_skills_used: z.number().optional() });
|
|
463
578
|
export const MemorySchema = z.looseObject({
|
|
464
579
|
memory: z.string(), user: z.string(), soul: z.string(), project_context: z.string().optional(), memory_path: z.string().optional(), user_path: z.string().optional(), soul_path: z.string().optional(), project_context_path: z.string().optional(),
|
|
@@ -472,13 +587,14 @@ export const PromptsSchema = z.looseObject({ prompts: z.array(PromptSchema) });
|
|
|
472
587
|
* first, then the Agent registry, in display order; each name appears once. `handler` says who runs it, `clients` which
|
|
473
588
|
* clients can run it, and `unsupported_message` is the English text a client outside `clients` shows when it is typed.
|
|
474
589
|
* Clients suggest the entries listing them whose name or any alias starts with the typed text (case-insensitive), and
|
|
475
|
-
* resolve a typed alias to the entry's `name`.
|
|
590
|
+
* resolve a typed alias to the entry's `name`. `exec` marks an Agent entry `POST /api/commands/exec` runs: the client
|
|
591
|
+
* posts the typed text there and shows the returned output instead of starting a chat turn (TAL-561).
|
|
476
592
|
*/
|
|
477
593
|
export const CommandClientSchema = z.enum(['web', 'ios']);
|
|
478
594
|
export const CommandRowSchema = z.looseObject({
|
|
479
595
|
name: z.string(), description: z.string().optional(), aliases: z.array(z.string()), args_hint: z.string().optional(), category: z.string().optional(),
|
|
480
596
|
handler: z.enum(['client', 'agent']), clients: z.array(CommandClientSchema), unsupported_message: z.string().optional(),
|
|
481
|
-
cli_only: z.boolean().optional(), gateway_only: z.boolean().optional(), subcommands: z.array(Json).optional(),
|
|
597
|
+
cli_only: z.boolean().optional(), gateway_only: z.boolean().optional(), subcommands: z.array(Json).optional(), exec: z.boolean().optional(),
|
|
482
598
|
});
|
|
483
599
|
export const CommandsSchema = z.looseObject({ commands: z.array(CommandRowSchema) });
|
|
484
600
|
export const LogsSchema = z.looseObject({ file: z.string(), tail: z.number().optional(), lines: z.array(z.string()), truncated: z.boolean().optional(), total_bytes: z.number().optional(), mtime: NullableNumber.optional(), hint: z.string().optional() });
|
|
@@ -489,14 +605,52 @@ export const InsightsSchema = z.looseObject({
|
|
|
489
605
|
models: z.array(z.looseObject({ model: z.string().optional(), sessions: z.number().optional(), tokens: z.number().optional(), cost: z.number().optional() })).optional(),
|
|
490
606
|
});
|
|
491
607
|
export const DashboardStatusSchema = z.looseObject({ running: z.boolean(), enabled: z.string().optional(), url: z.string().optional(), browser_url: z.string().optional(), host: z.string().optional(), port: z.number().int().optional(), version: z.string().optional(), error: z.string().optional() });
|
|
608
|
+
/**
|
|
609
|
+
* Gateway status for the Settings banner (TAL-266). `running` and `configured` come from the Agent health probe; when it
|
|
610
|
+
* is inconclusive, stale running metadata or known gateway sessions mark the gateway configured. `platforms` are the
|
|
611
|
+
* messaging platforms of known gateway sessions; `last_active` is the gateway session index's ISO mtime while running, else "".
|
|
612
|
+
*/
|
|
613
|
+
export const GatewayStatusSchema = z.object({
|
|
614
|
+
running: z.boolean(), configured: z.boolean(), platforms: z.array(z.object({ name: z.string(), label: z.string() })), last_active: z.string(), session_count: z.number().int(),
|
|
615
|
+
health: z.object({ state: NullableString, reason: NullableString, gateway_state: NullableString }),
|
|
616
|
+
});
|
|
617
|
+
export const GatewayActionSchema = z.object({ ok: z.literal(true), action: z.enum(['start', 'stop', 'restart']), message: z.string(), status: GatewayStatusSchema });
|
|
618
|
+
export const DashboardConfigSchema = z.object({ enabled: z.enum(['auto', 'always', 'never']), url: z.string() });
|
|
619
|
+
/**
|
|
620
|
+
* Project OS dashboard for a repo found from the last workspace or the `board`'s default workdir (TAL-266). Every field is
|
|
621
|
+
* null or empty when the profile has no local workspace I/O or no repo is found. `onboarding.active` means the docs came
|
|
622
|
+
* from the repo root's `PROJECT.md`/`PLAN.md`/`STATUS.md` instead of `docs/project-os/`.
|
|
623
|
+
*/
|
|
624
|
+
export const ProjectOsDashboardSchema = z.object({
|
|
625
|
+
workspace: NullableString, repo_root: NullableString, selected_board_slug: NullableString.optional(), git: GitBadgeSchema.nullable(),
|
|
626
|
+
docs: z.object({ project: FileContentSchema.nullable(), plan: FileContentSchema.nullable(), status: FileContentSchema.nullable(), blocker_resolver: FileContentSchema.nullable() }).partial(),
|
|
627
|
+
handoff: z.record(z.string(), Json).nullable(), active: z.record(z.string(), Json).nullable(), heartbeat: z.record(z.string(), Json).nullable(),
|
|
628
|
+
onboarding: z.looseObject({ active: z.boolean(), doc_source: z.enum(['project-os', 'root']) }).optional(), goal_summary: z.string(),
|
|
629
|
+
});
|
|
492
630
|
export const AgentHealthSchema = z.looseObject({ alive: z.boolean().nullable().optional(), checked_at: z.string().optional(), details: z.looseObject({ state: z.string().optional(), reason: z.string().optional() }).optional(), gateway_chat: z.looseObject({ enabled: z.boolean().optional(), backend: z.string().optional(), base_url_configured: z.boolean().optional(), api_key_configured: z.boolean().optional() }).optional(), error: z.string().optional() });
|
|
493
631
|
export const SystemHealthSchema = z.looseObject({
|
|
494
632
|
available: z.boolean().optional(), status: z.string().optional(), checked_at: z.string().optional(), cpu: Json.nullable().optional(), memory: Json.nullable().optional(), disk: z.looseObject({ percent: z.number().optional(), total_bytes: z.number().optional(), used_bytes: z.number().optional() }).nullable().optional(),
|
|
495
633
|
errors: z.array(z.looseObject({ code: z.string().optional(), metric: z.string().optional() })).optional(), webui_runtime: Json.optional(),
|
|
496
634
|
});
|
|
497
|
-
export const
|
|
635
|
+
export const UpdateStateSchema = z.enum(['up_to_date', 'release_ready', 'commits_behind', 'local_changes', 'finish', 'manual', 'check_failed', 'off', 'unknown']);
|
|
636
|
+
export const UpdateTargetSchema = z.looseObject({ name: z.string().optional(), channel: z.enum(['stable', 'experimental']).optional(), unsupported: z.boolean().optional(), supported_revision: z.string().optional(), supported_version: z.string().optional(), candidate_revision: z.string().optional(), behind: z.number().nullable().optional(), current_sha: z.string().nullable().optional(), latest_sha: z.string().nullable().optional(), compare_url: z.string().optional(), repo_url: z.string().optional(), error: z.string().optional(), ok: z.boolean().optional(), manual_update: z.boolean().optional(), no_git: z.boolean().optional(), install_kind: z.literal('npm').optional(), npm: z.string().optional(), channel_switch: z.boolean().optional(), dirty: z.boolean().optional(), metadata_repair: z.boolean().optional(), release_url: z.string().optional(), ignored: z.boolean().optional(), stale_check: z.boolean().optional(), current_version: z.string().optional(),
|
|
637
|
+
state: UpdateStateSchema.describe('TAL-559: the status clients word; `off` when checks are disabled or Agent updates are ignored.'),
|
|
638
|
+
can_apply: z.boolean().describe('The apply action is available for this target.'),
|
|
639
|
+
installed_unverified: z.boolean().describe('`release_ready` only: the installed revision sits on no release tag.'),
|
|
640
|
+
manual_link: z.boolean().describe('Show the manual-install (releases) link.'),
|
|
641
|
+
target_version: z.string().nullable().describe('The version the update path leads to, when one is shown.'),
|
|
642
|
+
summary_available: z.boolean().describe('TAL-759: offer "Summarize with AI" for this target (`release_ready` or `commits_behind`).'),
|
|
643
|
+
});
|
|
498
644
|
export const UpdatesCheckSchema = z.looseObject({ disabled: z.boolean().optional(), cached: z.boolean().optional(), channel: z.string().optional(), agent_channel: z.enum(['stable', 'experimental']).optional(), checked_at: z.number().optional(), include_agent: z.boolean().optional(), webui: UpdateTargetSchema.nullable().optional(), agent: UpdateTargetSchema.nullable().optional() });
|
|
499
|
-
export const UpdatesSummarySchema = z.
|
|
645
|
+
export const UpdatesSummarySchema = z.object({
|
|
646
|
+
ok: z.boolean(), target: z.enum(['webui', 'agent']), summary: z.string(),
|
|
647
|
+
current_version: z.string().nullable().describe('The installed version this summary starts from.'),
|
|
648
|
+
target_version: z.string().nullable().describe('The version this summary leads to, when the update names one.'),
|
|
649
|
+
summary_sections: z.array(z.object({ title: z.string(), items: z.array(z.string()) })).describe('Display-ready headed bullet lists; empty when nothing is pending.'),
|
|
650
|
+
generated_by: z.enum(['llm', 'fallback', 'none']).describe('`fallback` when no model answered; `none` when the target has no pending update to summarize.'),
|
|
651
|
+
source: z.enum(['release_notes', 'commits', 'none']).describe('Stable targets summarize the release notes they install; commit-tracking targets, or unreadable notes, use commit subjects.'),
|
|
652
|
+
cached: z.boolean(),
|
|
653
|
+
});
|
|
500
654
|
export const UpdateApplySchema = z.looseObject({ ok: z.boolean().optional(), status: z.string().optional(), error: z.string().optional(), message: z.string().optional(), lock: Json.optional(), confirmation_required: z.boolean().optional(), candidate_revision: z.string().optional(), supported_revision: z.string().optional(), supported_version: z.string().optional(), agent_channel: z.enum(['stable', 'experimental']).optional(), notification_id: z.uuid().optional(), channel_switch: z.boolean().optional(), backup_dir: z.string().nullable().optional(), backup_failed: z.boolean().optional(), stash_conflict: z.boolean().optional() });
|
|
501
655
|
export const UpdateNotificationPhaseSchema = z.enum(['applying', 'awaiting_confirmation', 'restarting', 'succeeded', 'blocked', 'failed', 'unknown']);
|
|
502
656
|
export const UpdateNotificationActionSchema = z.object({
|
|
@@ -558,12 +712,24 @@ export const UpdateNotificationsSchema = z.object({
|
|
|
558
712
|
});
|
|
559
713
|
export const PluginSchema = z.looseObject({ key: z.string(), name: z.string().optional(), kind: z.string().optional(), enabled: z.boolean().optional(), description: z.string().optional(), version: z.string().optional(), activation: z.string().optional(), is_active_provider: z.boolean().optional(), hooks: z.array(Json).optional() });
|
|
560
714
|
export const PluginsSchema = z.looseObject({ plugins: z.array(PluginSchema), empty: z.boolean().optional(), read_only: z.boolean().optional(), supported_hooks: z.array(z.string()).optional(), unavailable: z.boolean().optional() });
|
|
561
|
-
export const McpServerSchema = z.looseObject({ name: z.string(), id: z.string().optional(), transport: z.string().optional(), enabled: z.boolean().optional(), active: z.boolean().optional(), status: z.string().optional(), tools: z.number().optional(), tool_count: z.number().int().nullable().optional(), health: z.string().optional(), health_detail: z.string().optional(), health_checked_at: Json.optional(), health_pending: z.boolean().optional() });
|
|
715
|
+
export const McpServerSchema = z.looseObject({ name: z.string(), id: z.string().optional(), transport: z.string().optional(), enabled: z.boolean().optional(), can_toggle: z.boolean().optional().describe('Whether PATCH can enable or disable this server; false for invalid config.'), active: z.boolean().optional(), status: z.string().optional(), tools: z.number().optional(), tool_count: z.number().int().nullable().optional(), health: z.string().optional(), health_detail: z.string().optional(), health_checked_at: Json.optional(), health_pending: z.boolean().optional() });
|
|
562
716
|
export const McpServersSchema = z.looseObject({ servers: z.array(McpServerSchema), health_pending: z.boolean().optional(), reload_required: z.boolean().optional(), toggle_supported: z.boolean().optional() });
|
|
563
717
|
export const McpToolsSchema = z.looseObject({ tools: z.array(z.looseObject({ name: z.string().optional(), server: z.string().optional(), description: z.string().optional() })), total: z.number().int().optional(), source: z.string().optional(), inventory_scope: z.string().optional(), unavailable_servers: z.array(z.string()).optional() });
|
|
564
718
|
export const NotesSourcesSchema = z.looseObject({ enabled: z.boolean().optional(), sources: z.array(Json).optional(), source: z.string().optional(), inventory_scope: z.string().optional(), recent_ai_notes: z.array(Json).optional(), attach_supported: z.boolean().optional(), automatic_recall_unchanged: z.boolean().optional() });
|
|
719
|
+
/** Joplin search hit: bounded, redacted display text and a snippet around the query; `updated_time` is Joplin's raw value. */
|
|
720
|
+
export const NoteSearchResultSchema = z.object({ id: z.string(), title: z.string(), snippet: z.string(), parent_id: z.string(), updated_time: Json, source: z.literal('joplin') });
|
|
721
|
+
export const NotesSearchSchema = z.object({ source: z.literal('joplin'), query: z.string(), results: z.array(NoteSearchResultSchema) });
|
|
722
|
+
/** One Joplin note for preview: `body` is cut at 50,000 characters (with a notice) and redacted. */
|
|
723
|
+
export const NoteItemSchema = z.object({ source: z.literal('joplin'), note: z.object({ id: z.string(), title: z.string(), body: z.string(), parent_id: z.string(), updated_time: Json, created_time: Json, source: z.literal('joplin') }) });
|
|
724
|
+
/** LLM wiki summary: counts and timestamps only, never page bodies or the wiki path. `error` names the exception type when `status` is `error`. */
|
|
725
|
+
export const WikiStatusSchema = z.object({
|
|
726
|
+
available: z.boolean(), enabled: z.boolean(), status: z.enum(['missing', 'not_directory', 'ready', 'empty', 'error']), entry_count: z.number().int(), page_count: z.number().int(), raw_source_count: z.number().int(),
|
|
727
|
+
last_updated: z.string().nullable(), last_writer: z.string(), path_configured: z.boolean(), path_source: z.string(), toggle_available: z.literal(false), toggle_reason: z.string(), docs_url: z.string(), error: z.string().optional(),
|
|
728
|
+
});
|
|
729
|
+
export const WikiBrowseSchema = z.object({ pages: z.array(z.object({ name: z.string(), path: z.string(), size: z.number().int(), mtime: z.number().int() })) });
|
|
730
|
+
export const WikiPageSchema = z.object({ content: z.string(), path: z.string() });
|
|
565
731
|
export const TodoItemSchema = z.looseObject({ id: z.union([z.string(), z.number()]).optional(), text: z.string().optional(), content: z.string().optional(), title: z.string().optional(), status: z.string().optional(), done: z.boolean().optional(), completed: z.boolean().optional() });
|
|
566
|
-
export const TodoStateSchema = z.looseObject({ session_id: z.string().optional(), todos: z.array(TodoItemSchema).optional(), version: z.number().optional(), ts: z.number().optional(), source: z.string().optional(), description: z.string().optional(), pending_count: z.number().optional() });
|
|
732
|
+
export const TodoStateSchema = z.looseObject({ session_id: z.string().optional(), todos: z.array(TodoItemSchema).optional(), summary: z.record(z.string(), z.unknown()).optional(), version: z.number().optional(), ts: z.number().optional(), source: z.string().optional(), description: z.string().optional(), pending_count: z.number().optional() });
|
|
567
733
|
// ── onboarding ───────────────────────────────────────────────────────────
|
|
568
734
|
/** `oauth_flow` (TAL-398): `device_code` when the provider signs in through `/api/onboarding/oauth/*` instead of taking an API key; `oauth_label` then names the account to sign in with, and `signed_in` says whether the profile already holds its credential. */
|
|
569
735
|
export const OnboardingProviderSchema = z.looseObject({ id: z.string(), name: z.string().optional(), label: z.string().optional(), kind: z.string().optional(), oauth: z.boolean().optional(), needs_key: z.boolean().optional(), base_url: NullableString.optional(), models: z.array(Json).optional(), category: z.string().optional(), default_model: z.string().optional(), oauth_flow: z.literal('device_code').nullable().optional(), oauth_label: z.string().optional(), signed_in: z.boolean().optional() });
|
|
@@ -599,8 +765,15 @@ export const CronJobViewSchema = z.looseObject({
|
|
|
599
765
|
context_from: z.union([z.array(z.string()), z.string(), z.null()]).optional(), reasoning_effort: NullableString.optional(), toast_notifications: z.boolean().optional(), running: z.boolean().optional(),
|
|
600
766
|
/** Server-derived (TAL-296): the job's status, whether it needs attention, and whether its primary action is Resume. Live runs overlay it. */
|
|
601
767
|
derived_state: CronDerivedStateSchema.optional(), needs_attention: z.boolean().optional(), resumable: z.boolean().optional(),
|
|
768
|
+
/** Server-derived (TAL-599): a known cause clients explain in the needs-attention banner. */
|
|
769
|
+
attention_hint: z.enum(['croniter_missing']).nullable(),
|
|
770
|
+
});
|
|
771
|
+
export const CronsSchema = z.looseObject({
|
|
772
|
+
jobs: z.array(CronJobViewSchema),
|
|
773
|
+
/** TAL-601: `jobs` arrive in display order (running first, then soonest next run, none last, then name); clients keep it. Absent from older servers. */
|
|
774
|
+
ordered: z.boolean().optional(),
|
|
775
|
+
active_profile: z.string().optional(), all_profiles: z.boolean().optional(), other_profile_count: z.number().optional(), cron_unavailable: z.boolean().optional(),
|
|
602
776
|
});
|
|
603
|
-
export const CronsSchema = z.looseObject({ jobs: z.array(CronJobViewSchema), active_profile: z.string().optional(), all_profiles: z.boolean().optional(), other_profile_count: z.number().optional(), cron_unavailable: z.boolean().optional() });
|
|
604
777
|
export const CronContextSourcesSchema = z.object({ profile: z.string(), sources: z.array(z.object({ job_id: z.string(), label: z.string(), selectable: z.boolean() })) });
|
|
605
778
|
/** `GET /api/crons/recent` row: one job's latest completion, ordered and classified by the server. */
|
|
606
779
|
export const CronRecentCompletionSchema = z.object({
|
|
@@ -612,12 +785,29 @@ export const CronMutationSchema = z.looseObject({ ok: z.boolean().optional(), jo
|
|
|
612
785
|
export const CronRunUsageSchema = z.looseObject({ input_tokens: NullableNumber.optional(), output_tokens: NullableNumber.optional(), total_tokens: NullableNumber.optional(), estimated_cost_usd: NullableNumber.optional(), duration_seconds: NullableNumber.optional(), model: z.string().optional(), provider: z.string().optional() });
|
|
613
786
|
export const CronRunSummarySchema = z.looseObject({ filename: z.string(), size: z.number(), modified: z.number(), usage: CronRunUsageSchema.optional() });
|
|
614
787
|
export const CronHistorySchema = z.looseObject({ job_id: z.string().optional(), runs: z.array(CronRunSummarySchema), total: z.number().optional(), offset: z.number().optional() });
|
|
615
|
-
|
|
788
|
+
/** `response` is server-extracted (TAL-599): the agent's reply after the run file's `## Response` heading, else the whole text. */
|
|
789
|
+
export const CronRunSchema = z.looseObject({ content: z.string().optional(), snippet: z.string().optional(), response: z.string().optional(), usage: CronRunUsageSchema.optional(), error: z.string().optional() });
|
|
616
790
|
export const CronStatusSchema = z.looseObject({ running: z.union([z.boolean(), z.record(z.string(), z.number())]).optional() });
|
|
617
|
-
|
|
791
|
+
/** Card actions the server offers for a task's current status (TAL-557); clients show exactly these. `move_to` lists the statuses a Move may target, in display order. */
|
|
792
|
+
export const KanbanTaskActionsSchema = z.object({ block: z.boolean(), unblock: z.boolean(), complete: z.boolean(), archive: z.boolean(), move_to: z.array(z.string()) });
|
|
793
|
+
/** Server-computed card policy on every task the Kanban routes return (TAL-557). `requires_running_exit_confirmation`: any action takes the task out of a live run, so clients confirm first. */
|
|
794
|
+
export const KanbanTaskPolicyShape = { available_actions: KanbanTaskActionsSchema, requires_running_exit_confirmation: z.boolean() };
|
|
795
|
+
export const KanbanTaskViewSchema = z.looseObject({ id: z.union([z.string(), z.number()]), title: z.string().optional(), status: z.string().optional(), assignee: NullableString.optional(), priority: z.union([z.string(), z.number()]).nullable().optional(), description: z.string().optional(), tags: z.array(z.string()).optional(), session_id: NullableString.optional(), archived: z.boolean().optional(), created_at: Json.optional(), updated_at: Json.optional(), ...KanbanTaskPolicyShape });
|
|
618
796
|
export const KanbanColumnSchema = z.looseObject({ name: z.string(), tasks: z.array(KanbanTaskViewSchema) });
|
|
619
|
-
|
|
620
|
-
export const
|
|
797
|
+
/** One profile lane (TAL-567): an assignee's tasks (`null` = unassigned) across every board column, with its task count. */
|
|
798
|
+
export const KanbanLaneSchema = z.object({ assignee: z.string().nullable(), count: z.number().int(), columns: z.array(KanbanColumnSchema) });
|
|
799
|
+
export const KanbanBoardViewSchema = z.looseObject({ columns: z.array(KanbanColumnSchema).optional(), assignees: z.array(Json).optional(), filters: Json.optional(), latest_event_id: z.number().optional(), read_only: z.boolean().optional(), tenants: z.array(Json).optional(), changed: z.boolean().optional(),
|
|
800
|
+
/** Statuses a bulk status change may target (TAL-557). */
|
|
801
|
+
bulk_move_targets: z.array(z.string()),
|
|
802
|
+
/** The saved board view (TAL-567): `true` groups the board into `lanes` by assignee. */
|
|
803
|
+
lane_by_profile: z.boolean(),
|
|
804
|
+
/** Present when `lane_by_profile`: the columns split into profile lanes, assignees in name order, unassigned last. */
|
|
805
|
+
lanes: z.array(KanbanLaneSchema).optional() });
|
|
806
|
+
export const KanbanBoardsViewSchema = z.looseObject({ boards: z.array(z.looseObject({ slug: z.string(), name: z.string().nullable().optional(), is_current: z.boolean().optional(), total: z.number().optional(), archived: z.boolean().optional(), color: z.string().optional(), icon: z.string().optional(), description: z.string().optional(),
|
|
807
|
+
/** Whether the board can be archived or deleted; the default board cannot (TAL-567). */
|
|
808
|
+
removable: z.boolean() })), current: z.string().optional(), read_only: z.boolean().optional() });
|
|
809
|
+
/** Board-wide task counts (TAL-567): `status_counts` in board-column order, unknown statuses after; `total` excludes archived tasks. */
|
|
810
|
+
export const KanbanStatsViewSchema = z.looseObject({ by_status: z.record(z.string(), z.number()), total: z.number().int(), status_counts: z.array(z.object({ status: z.string(), count: z.number().int() })) });
|
|
621
811
|
export const ExtensionStatusSchema = z.looseObject({
|
|
622
812
|
enabled: z.boolean(), extension_dir_configured: z.boolean().optional(), extension_dir_valid: z.boolean().optional(), script_urls: z.array(z.string()).optional(), stylesheet_urls: z.array(z.string()).optional(), sidecars: z.array(Json).optional(),
|
|
623
813
|
extensions: z.array(z.looseObject({ id: z.string(), enabled: z.boolean().optional(), name: z.string().optional(), version: z.string().optional() })).optional(), warnings: z.array(Json).optional(),
|