@maudecode/talaria-web-contracts 1.15.0 → 1.17.2
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/router.d.ts +1681 -87
- package/dist/routes/automation.d.ts +168 -16
- package/dist/routes/automation.js +15 -8
- package/dist/routes/automation.js.map +1 -1
- package/dist/routes/chat.d.ts +193 -6
- package/dist/routes/core.d.ts +8 -4
- package/dist/routes/core.js +2 -0
- package/dist/routes/core.js.map +1 -1
- package/dist/routes/git.d.ts +22 -1
- package/dist/routes/git.js +7 -3
- package/dist/routes/git.js.map +1 -1
- package/dist/routes/raw.js +2 -2
- package/dist/routes/raw.js.map +1 -1
- package/dist/routes/sessions.d.ts +1187 -43
- package/dist/routes/sessions.js +22 -3
- package/dist/routes/sessions.js.map +1 -1
- package/dist/routes/settings.d.ts +254 -11
- package/dist/routes/settings.js +9 -8
- package/dist/routes/settings.js.map +1 -1
- package/dist/routes/tools.d.ts +86 -9
- package/dist/routes/tools.js +1 -1
- package/dist/routes/tools.js.map +1 -1
- package/dist/routes/workspaces.d.ts +19 -5
- package/dist/sidecar/methods.d.ts +192 -12
- package/dist/sidecar/methods.js +2 -1
- package/dist/sidecar/methods.js.map +1 -1
- package/dist/sidecar/namespaces.d.ts +315 -15
- package/dist/sidecar/namespaces.js +78 -9
- 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 +68 -9
- package/dist/sse.js +21 -7
- package/dist/sse.js.map +1 -1
- package/dist/views.d.ts +1392 -40
- package/dist/views.js +242 -37
- package/dist/views.js.map +1 -1
- package/fixtures/sidecar/commands.json +195 -92
- package/fixtures/sidecar/kanban.json +24 -8
- package/fixtures/sidecar/plugins.json +1 -403
- package/fixtures/sidecar/process.json +25 -0
- package/fixtures/sidecar/rpc.json +2 -1
- package/fixtures/sidecar/runtime.json +3 -3
- package/fixtures/sidecar/text.json +0 -10
- package/fixtures/sidecar/usage.json +51 -0
- package/package.json +1 -1
package/dist/views.js
CHANGED
|
@@ -17,19 +17,32 @@ export const AttachmentSchema = z.looseObject({
|
|
|
17
17
|
});
|
|
18
18
|
/** The server's display class for a tool call: clients map it to an icon and localized verb, and never classify names themselves. */
|
|
19
19
|
export const ToolKindSchema = z.enum(['shell', 'read', 'list', 'search', 'web', 'write', 'skill', 'memory', 'delegate', 'unknown']);
|
|
20
|
-
/**
|
|
21
|
-
|
|
20
|
+
/**
|
|
21
|
+
* TAL-448: a completed file-edit call's change, from its result's unified diff: `added` / `removed` count the whole diff's
|
|
22
|
+
* lines (file headers excluded); `diff` is the redacted diff, capped at 400 lines, with `truncated` when cut. Absent on a
|
|
23
|
+
* call whose result has no diff.
|
|
24
|
+
*/
|
|
25
|
+
export const ToolEditDiffSchema = z.object({ added: z.number().int(), removed: z.number().int(), diff: z.string(), truncated: z.boolean() });
|
|
26
|
+
/** 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`. */
|
|
27
|
+
export const ToolDisplayFields = { kind: ToolKindSchema.optional(), target: z.string().optional(), edit_diff: ToolEditDiffSchema.optional() };
|
|
28
|
+
/**
|
|
29
|
+
* TAL-315: a tool result's display sections, decided by the server's one rule for live, replayed and persisted results
|
|
30
|
+
* alike. Clients show `stdout`, `stderr`, a labelled `error` and a labelled `exit_code` (sent only when worth showing), or
|
|
31
|
+
* `text`, in that order, and never parse result text. Each string is capped server-side; a client without the field
|
|
32
|
+
* shows `preview`.
|
|
33
|
+
*/
|
|
34
|
+
export const ToolResultViewSchema = z.object({ text: z.string().optional(), stdout: z.string().optional(), stderr: z.string().optional(), error: z.string().optional(), exit_code: z.number().int().optional() });
|
|
22
35
|
/**
|
|
23
36
|
* Stored transcripts carry the OpenAI shape (`function.name` / `function.arguments` JSON string); live events carry `name` / `args`.
|
|
24
37
|
* On an assistant row the server resolves every call (TAL-313, `session-sse-contract-v1.md`): Anthropic `tool_use` parts and
|
|
25
38
|
* session-level-only calls join `tool_calls`; `done` is answered or outside the running turn; `is_error` is the server's
|
|
26
39
|
* outcome rule over the result; `duration` is the seconds the live stream measured, else `null`; `result` is the redacted
|
|
27
|
-
* result snippet, else `null`. Clients render these and pair nothing themselves.
|
|
40
|
+
* result snippet, else `null`; `result_view` its display sections, else `null`. Clients render these and pair nothing themselves.
|
|
28
41
|
*/
|
|
29
42
|
export const ToolCallSchema = z.looseObject({
|
|
30
43
|
...ToolDisplayFields,
|
|
31
44
|
name: z.string().optional(), args: Json.optional(), function: z.looseObject({ name: z.string().optional(), arguments: Json.optional() }).optional(), id: z.string().optional(), call_id: z.string().optional(), tool_call_id: z.string().optional(),
|
|
32
|
-
done: z.boolean().optional(), is_error: z.boolean().optional(), preview: z.string().nullable().optional(), result: Json.optional(), output: Json.optional(), duration: z.number().nullable().optional(), cost_usd: z.number().nullable().optional(),
|
|
45
|
+
done: z.boolean().optional(), is_error: z.boolean().optional(), preview: z.string().nullable().optional(), result: Json.optional(), result_view: ToolResultViewSchema.nullable().optional(), output: Json.optional(), duration: z.number().nullable().optional(), cost_usd: z.number().nullable().optional(),
|
|
33
46
|
timestamp: z.number().nullable().optional(), event_type: z.string().optional(),
|
|
34
47
|
});
|
|
35
48
|
export const ContentPartSchema = z.looseObject({ type: z.string(), text: z.string().optional() });
|
|
@@ -46,11 +59,23 @@ export const BackgroundLinkSchema = z.object({
|
|
|
46
59
|
status: z.enum(['running', 'attention', 'completed', 'failed', 'cancelled', 'unknown']),
|
|
47
60
|
agents: z.object({ total: z.number().int(), completed: z.number().int(), failed: z.number().int(), running: z.number().int() }),
|
|
48
61
|
});
|
|
62
|
+
/**
|
|
63
|
+
* TAL-186: one local or remote media reference the server recognized in a message's Markdown (a `MEDIA:` token, a bare
|
|
64
|
+
* `file://` URL or a local image destination), in content order. `url` is relative to the app root (`./api/media?path=…&session_id=…`)
|
|
65
|
+
* for a local file the `/api/media` allow-list serves, or the remote `http(s)` URL as written. Clients render `image`
|
|
66
|
+
* items inline from the display text and every other kind as a tile after it. A remote URL without a file
|
|
67
|
+
* extension has no known kind and is a `file`.
|
|
68
|
+
*/
|
|
69
|
+
export const DisplayMediaSchema = z.object({ url: z.string(), name: z.string(), mime: z.string(), kind: z.enum(['image', 'audio', 'video', 'pdf', 'file']) });
|
|
49
70
|
/** One normalized activity row: the server decides role, order, tool completion/error, and steering consumption. */
|
|
50
71
|
export const ActivitySceneRowSchema = z.looseObject({
|
|
51
72
|
row_id: z.string(), order_index: z.number().int(), role: z.enum(['prose', 'reasoning', 'tool', 'steering']), created_at: z.number().optional(),
|
|
52
73
|
text: z.string().optional(), titles: z.array(z.string()).optional(),
|
|
53
|
-
|
|
74
|
+
/** TAL-186: a prose row's `text` with its media references rewritten for display (see `_display_content`), and its media. */
|
|
75
|
+
display_text: z.string().optional(), media: z.array(DisplayMediaSchema).optional(),
|
|
76
|
+
tool: z.looseObject({ id: z.string(), name: z.string(), ...ToolDisplayFields, args: Json.optional(), preview: z.string().nullable(), result: Json.optional(), result_view: ToolResultViewSchema.nullable().optional(), done: z.boolean(), is_error: z.boolean(), duration: z.number().nullable(), cost_usd: z.number().nullable(), background: BackgroundLinkSchema.optional(),
|
|
77
|
+
/** TAL-331: a limited response clipped `result` (originally `result_chars` long); `GET /api/session/tool-result` serves it whole. */
|
|
78
|
+
result_truncated: z.literal(true).optional(), result_chars: z.number().int().nullable().optional() }).optional(),
|
|
54
79
|
steering: z.looseObject({ steer_id: z.string(), consumed: z.boolean(), submitted_at: z.number().nullable(), consumed_at: z.number().nullable(), phase_duration: z.number().nullable().optional() }).optional(),
|
|
55
80
|
});
|
|
56
81
|
/** One file a turn changed: its normalized path as the tool reported it, and the strongest action taken on it (`added` / `deleted` / `renamed` outrank a plain `edited`). */
|
|
@@ -62,9 +87,10 @@ export const ActivitySceneSchema = z.looseObject({
|
|
|
62
87
|
version: z.literal('activity_scene_v1'), activity_rows: z.array(ActivitySceneRowSchema), final_answer: z.string().optional(),
|
|
63
88
|
/** TAL-456: a settled final answer too long to lay out whole; clients render it collapsed, with a local "Show more". */
|
|
64
89
|
final_answer_excerpt: z.string().optional(), turn_duration: z.number().nullable().optional(),
|
|
65
|
-
/**
|
|
66
|
-
|
|
67
|
-
|
|
90
|
+
/** TAL-186: `final_answer` with its media references rewritten for display (see `_display_content`), and its media. */
|
|
91
|
+
final_answer_display: z.string().optional(), final_answer_media: z.array(DisplayMediaSchema).optional(),
|
|
92
|
+
terminal_state: z.string().optional().describe('The turn\'s outcome: a `TurnTerminalState` (`completed`, `no_response`, `error`, `cancelled`, `interrupted`, `tool_limit_reached`, ...), or `running` for the running turn of a run with no journal to replay (TAL-374). A running scene holds every persisted row (no final answer) and renders open, with no "Worked" fold or outcome; the live rows streamed after attach continue it, and the settled scene replaces both.'),
|
|
93
|
+
/** Whether the "Worked" disclosure opens by default: an unsuccessful outcome with work to read, or a running turn. */
|
|
68
94
|
expanded_by_default: z.boolean().optional(),
|
|
69
95
|
/** Seconds from the turn's last consumed steer to its end, when it has steers. */
|
|
70
96
|
final_phase_duration: z.number().optional(),
|
|
@@ -78,8 +104,14 @@ export const ActivitySceneSchema = z.looseObject({
|
|
|
78
104
|
export const BackgroundLineSchema = z.object({ kind: z.enum(['agent', 'command', 'other']), status: z.enum(['completed', 'failed', 'notice']), label: z.string(), exit_code: z.number().int().nullable().optional() });
|
|
79
105
|
export const MessageSchema = z.looseObject({
|
|
80
106
|
role: z.string(), content: MessageContentSchema.optional(), id: MessageIdSchema.optional(), message_id: MessageIdSchema.optional(), timestamp: z.number().nullable().optional(),
|
|
81
|
-
attachments: z.array(AttachmentSchema).optional(), tool_calls: z.array(ToolCallSchema).optional(),
|
|
82
|
-
|
|
107
|
+
attachments: z.array(AttachmentSchema).optional(), tool_calls: z.array(ToolCallSchema).optional(),
|
|
108
|
+
/**
|
|
109
|
+
* TAL-302: an assistant row's whole reasoning as one string (its reasoning fields, typed thinking parts and inline
|
|
110
|
+
* thinking blocks). Its `content` carries none of them and no leaked tool-call XML; `reasoning_content` and
|
|
111
|
+
* `thinking` are not sent. Clients render both as shipped.
|
|
112
|
+
*/
|
|
113
|
+
reasoning: z.string().optional(),
|
|
114
|
+
tool_call_id: z.string().optional(), tool_use_id: z.string().optional(), name: z.string().optional(), badge: z.string().optional(), label: z.string().optional(),
|
|
83
115
|
provider_details: Json.optional(), provider_details_label: z.string().optional(), recovery_control: Json.optional(), _anchor_activity_scene: ActivitySceneSchema.optional(),
|
|
84
116
|
/** The turn this row belongs to; the server stamps every row it sends, so clients group turns by equality alone. */
|
|
85
117
|
_turn_id: z.string().optional(),
|
|
@@ -92,6 +124,19 @@ export const MessageSchema = z.looseObject({
|
|
|
92
124
|
/** A settled body too long to lay out whole: clients render `_display_excerpt` collapsed, with a local "Show more" for `content`. */
|
|
93
125
|
_display_truncated: z.boolean().optional(),
|
|
94
126
|
_display_excerpt: z.string().optional(),
|
|
127
|
+
/**
|
|
128
|
+
* TAL-452: a typed user message (never a steer, background update or marker) longer than 20 lines or 2,000
|
|
129
|
+
* characters. Clients show it folded to a few lines with a local "Show more"; copy and edit use the whole `content`.
|
|
130
|
+
*/
|
|
131
|
+
_collapsible: z.boolean().optional(),
|
|
132
|
+
/**
|
|
133
|
+
* TAL-186: an assistant row's text with each media reference the server serves rewritten to standard Markdown: an
|
|
134
|
+
* image to ``, any other file to `[name](url)`. Clients render it in place of `content` as one Markdown
|
|
135
|
+
* document; `content` stays as stored for copy and edit. Absent when the text has no such reference.
|
|
136
|
+
*/
|
|
137
|
+
_display_content: z.string().optional(),
|
|
138
|
+
/** TAL-186: the media `_display_content` references, in content order. */
|
|
139
|
+
_media: z.array(DisplayMediaSchema).optional(),
|
|
95
140
|
/**
|
|
96
141
|
* TAL-371: an automatic background wakeup (delegation results, background process or watch notice), not a message the
|
|
97
142
|
* user sent. Clients render it as a "Background update" disclosure: a localized label per `kind` (with `count`), a
|
|
@@ -106,6 +151,13 @@ export const MessageSchema = z.looseObject({
|
|
|
106
151
|
*/
|
|
107
152
|
lines: z.array(BackgroundLineSchema),
|
|
108
153
|
}).optional(),
|
|
154
|
+
/**
|
|
155
|
+
* TAL-305: a marker the Agent wrote around context compaction, not a message anyone typed. Clients render a collapsed
|
|
156
|
+
* card with a localized title per kind and the body on expansion: `_marker_body` when sent, else `content`.
|
|
157
|
+
*/
|
|
158
|
+
_marker_kind: z.enum(['context_compaction', 'preserved_task_list']).optional(),
|
|
159
|
+
/** TAL-305: a preserved task list's card body, without its marker line. */
|
|
160
|
+
_marker_body: z.string().optional(),
|
|
109
161
|
/** TAL-460: part of the Agent's reply to the background update just before it in the same turn. */
|
|
110
162
|
_background_reply: z.boolean().optional(),
|
|
111
163
|
/** TAL-460: that reply is only a silence marker; clients show the update's lines and nothing of this turn's reply. */
|
|
@@ -138,23 +190,41 @@ const ReadOnlySchema = z.boolean().describe('The session cannot be modified from
|
|
|
138
190
|
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.');
|
|
139
191
|
const CanPinSchema = z.boolean().describe('Web may pin or unpin this session: never a subagent child.');
|
|
140
192
|
const CanArchiveSchema = z.boolean().describe('Web may archive or unarchive this session: never a subagent child.');
|
|
193
|
+
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).');
|
|
141
194
|
const CanDuplicateSchema = z.boolean().describe('Web may duplicate this session: it has a WebUI copy and is not a subagent child.');
|
|
142
195
|
// TAL-310: the server classifies every session's source once; clients file rows by it and never scan source markers.
|
|
143
196
|
export const SourceKindSchema = z.enum(['webui', 'cli', 'messaging', 'cron', 'webhook', 'subagent', 'claude_code', 'kanban', 'api', 'other'])
|
|
144
197
|
.describe('The session\'s source family. `is_cli_session` is true only for `cli` and `claude_code`.');
|
|
198
|
+
// TAL-306: clients keep the server's list order and date-bucket by this; they never sort or pick a timestamp themselves.
|
|
199
|
+
const SortTsSchema = z.number().describe('Epoch seconds the session sorts and date-buckets by: `last_message_at`, else `updated_at`, else `created_at`.');
|
|
145
200
|
const IsMessagingSessionSchema = z.boolean().describe('`source_kind` is `messaging`: a gateway chat (Telegram, Signal, WhatsApp, …) the server imports before Web continues it.');
|
|
201
|
+
/**
|
|
202
|
+
* The label every client shows for the session's workspace: its registered name in the session profile's registry, else
|
|
203
|
+
* the folder name (TAL-303). Null without a workspace; absent from an older server, where clients show no label.
|
|
204
|
+
*/
|
|
205
|
+
const WorkspaceNameSchema = NullableString.optional();
|
|
206
|
+
/**
|
|
207
|
+
* TAL-560: the "Context compaction · Reference only" card, on payloads that carry `messages`. Clients render `text` after
|
|
208
|
+
* the row at full-transcript index `after_message_index` (row `after_message_index - _messages_offset` of `messages`), or
|
|
209
|
+
* above the loaded rows when it is null or before them. Null: no card.
|
|
210
|
+
*/
|
|
211
|
+
export const CompressionReferenceSchema = z.object({
|
|
212
|
+
text: z.string(),
|
|
213
|
+
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.'),
|
|
214
|
+
});
|
|
146
215
|
/** Full session record from `GET /api/session` and mutations returning `session`. */
|
|
147
216
|
export const SessionSchema = z.looseObject({
|
|
148
217
|
session_id: SessionIdSchema, title: z.string(), workspace: z.string().optional(), created_workspace: z.string().nullable().optional(), model: NullableString.optional(), model_provider: NullableString.optional(),
|
|
218
|
+
model_option_id: NullableString.optional().describe('TAL-301: the catalog entry id the stored model/provider selects; null when none.'),
|
|
149
219
|
messages: z.array(MessageSchema).optional(), tool_calls: z.array(ToolCallSchema).optional(), created_at: UnixSeconds.optional(), updated_at: UnixSeconds.optional(), last_message_at: NullableNumber.optional(),
|
|
150
220
|
message_count: z.number().optional(), user_message_count: z.number().optional(), pinned: z.boolean().optional(), archived: z.boolean().optional(), project_id: NullableString.optional(), profile: NullableString.optional(),
|
|
151
221
|
personality: NullableString.optional(), input_tokens: z.number().optional(), output_tokens: z.number().optional(), cache_read_tokens: z.number().optional(), cache_write_tokens: z.number().optional(),
|
|
152
222
|
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(),
|
|
153
223
|
pending_user_message: NullableString.optional(), pending_attachments: z.array(AttachmentSchema).optional(), pending_started_at: NullableNumber.optional(), pending_user_source: NullableString.optional(),
|
|
154
224
|
context_length: NullableNumber.optional(), threshold_tokens: NullableNumber.optional(), last_prompt_tokens: NullableNumber.optional(), post_compression_context_tokens_estimate: NullableNumber.optional(), ...ContextUsageFields,
|
|
155
|
-
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, read_only: ReadOnlySchema, can_branch: CanBranchSchema, can_pin: CanPinSchema, can_archive: CanArchiveSchema, can_duplicate: CanDuplicateSchema, source_tag: NullableString.optional(),
|
|
225
|
+
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(),
|
|
156
226
|
source_label: NullableString.optional(), session_source: NullableString.optional(), raw_source: NullableString.optional(), parent_session_id: NullableString.optional(), worktree_path: NullableString.optional(),
|
|
157
|
-
worktree_branch: NullableString.optional(), worktree_repo_root: NullableString.optional(), share_token: NullableString.optional(), share_created_at: NullableNumber.optional(), manual_title: z.boolean().optional(),
|
|
227
|
+
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(),
|
|
158
228
|
compression_anchor_summary: NullableString.optional(), compression_recovery: z.record(z.string(), Json).optional(), recommended_recovery_action: NullableString.optional(), compression_recovery_action: NullableString.optional(),
|
|
159
229
|
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(),
|
|
160
230
|
/**
|
|
@@ -165,19 +235,22 @@ export const SessionSchema = z.looseObject({
|
|
|
165
235
|
transcript_seq: z.object({ stream_id: z.string(), seq: z.number().int().nonnegative() }).nullable().optional(),
|
|
166
236
|
/** The agent's display name: a named profile's own name, else the `bot_name` setting (TAL-458). */
|
|
167
237
|
assistant_name: z.string().optional(),
|
|
238
|
+
workspace_name: WorkspaceNameSchema,
|
|
239
|
+
compression_reference: CompressionReferenceSchema.nullable().optional(),
|
|
168
240
|
});
|
|
169
241
|
export const SessionEnvelopeSchema = z.looseObject({ session: SessionSchema });
|
|
170
242
|
/** Sidebar row from `GET /api/sessions`. */
|
|
171
243
|
export const SessionRowSchema = z.looseObject({
|
|
172
244
|
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(),
|
|
173
245
|
message_count: z.number().optional(), pinned: z.boolean().optional(), archived: z.boolean().optional(), project_id: NullableString.optional(), profile: NullableString.optional(), is_streaming: IsStreamingSchema,
|
|
174
|
-
is_cli_session: z.boolean().optional(), source_kind: SourceKindSchema, is_messaging_session: IsMessagingSessionSchema, 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(),
|
|
246
|
+
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(),
|
|
175
247
|
source_tag: NullableString.optional(), source_label: NullableString.optional(), session_source: NullableString.optional(), raw_source: NullableString.optional(), parent_session_id: NullableString.optional(),
|
|
176
|
-
active_stream_id: ActiveStreamIdSchema, share_token: NullableString.optional(), worktree_branch: NullableString.optional(), match_type: z.
|
|
248
|
+
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(),
|
|
249
|
+
workspace_name: WorkspaceNameSchema,
|
|
177
250
|
...ContextUsageFields,
|
|
178
251
|
});
|
|
179
252
|
export const SessionsListSchema = z.looseObject({
|
|
180
|
-
sessions: z.array(SessionRowSchema), sidebar_reference_sessions: z.array(SessionRowSchema), server_time: z.number(), server_tz: z.string(), active_profile: z.string(), all_profiles: z.boolean(), include_archived: z.boolean(),
|
|
253
|
+
sessions: z.array(SessionRowSchema).describe('Canonical display order (TAL-306): pinned first, then active (streaming or a pending prompt), then newest `sort_ts`, then `session_id`. Clients keep it.'), sidebar_reference_sessions: z.array(SessionRowSchema), server_time: z.number(), server_tz: z.string(), active_profile: z.string(), all_profiles: z.boolean(), include_archived: z.boolean(),
|
|
181
254
|
archived_count: z.number().int(), archived_webui_count: z.number().int(), archived_cli_count: z.number().int(), other_profile_count: z.number().int(), cli_count: z.number().int(), webui_session_count: z.number().int(),
|
|
182
255
|
cli_session_count: z.number().int(),
|
|
183
256
|
// TAL-482: sidebar counts for the "Scheduled sessions" / "Webhook sessions" groups; `_truncated` means more exist than are listed.
|
|
@@ -203,7 +276,12 @@ export const ChatStartResponseSchema = z.looseObject({
|
|
|
203
276
|
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(),
|
|
204
277
|
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(),
|
|
205
278
|
});
|
|
206
|
-
|
|
279
|
+
/**
|
|
280
|
+
* `active` is whether this stream's channel is still live. `blocking_stream_id` (TAL-622) is the run that still holds the
|
|
281
|
+
* stream's session: this run while it unwinds after a Stop, or a successor such as a goal continuation. A session delete
|
|
282
|
+
* answers 409 while it is set, so a client draining a session before deleting it waits until it is null.
|
|
283
|
+
*/
|
|
284
|
+
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() });
|
|
207
285
|
/**
|
|
208
286
|
* TAL-424: a pending steer is no longer pending without the Agent taking it: Edit and Cancel by the user, `stopped` by a
|
|
209
287
|
* Stop (`text` goes back to the composer), or `followup` when the server sends it as the next turn. `steer_id` is null
|
|
@@ -250,7 +328,9 @@ export const ClarifyRespondRequestSchema = z.looseObject({ session_id: SessionId
|
|
|
250
328
|
export const ClarifyRespondResponseSchema = z.looseObject({ ok: z.boolean(), response: z.string().optional(), error: z.string().optional(), stale: z.boolean().optional() });
|
|
251
329
|
export const DraftSchema = z.looseObject({ text: z.string(), files: z.array(Json) });
|
|
252
330
|
export const DraftResponseSchema = z.looseObject({ ok: z.literal(true), draft: DraftSchema, draft_version: z.string().nullable(), unchanged: z.boolean().optional() });
|
|
253
|
-
|
|
331
|
+
/** At most this many attachments ride one chat message; the server names each in the prompt (TAL-276, TAL-635). */
|
|
332
|
+
export const MAX_CHAT_ATTACHMENTS = 20;
|
|
333
|
+
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() });
|
|
254
334
|
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() });
|
|
255
335
|
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() });
|
|
256
336
|
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() });
|
|
@@ -301,6 +381,11 @@ export const SessionNewRequestSchema = z.looseObject({
|
|
|
301
381
|
});
|
|
302
382
|
export const TranscribeCapabilitySchema = z.looseObject({ ok: z.literal(true), available: z.boolean(), provider: z.string() });
|
|
303
383
|
// ── settings, profiles, models, providers ───────────────────────────────
|
|
384
|
+
/** TAL-411: the request profile's quota urgency thresholds. A save patches valid fields and clamps critical to at most warning. */
|
|
385
|
+
export const QuotaThresholdsSchema = z.object({
|
|
386
|
+
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),
|
|
387
|
+
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),
|
|
388
|
+
});
|
|
304
389
|
export const LoginResponseSchema = z.looseObject({ ok: z.literal(true), message: z.string().optional() });
|
|
305
390
|
export const SettingsSchema = z.looseObject({
|
|
306
391
|
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(),
|
|
@@ -311,6 +396,9 @@ export const SettingsSchema = z.looseObject({
|
|
|
311
396
|
auth_disabled_acknowledged: z.boolean().optional(), webui_version: z.string().optional(), agent_version: z.string().optional(), update_channel: z.string().optional(), agent_update_channel: z.enum(['stable', 'experimental']).optional(), update_channel_version: NullableString.optional(),
|
|
312
397
|
max_tokens: NullableNumber.optional(), max_tokens_effective: NullableNumber.optional(), max_tokens_fallback: NullableNumber.optional(), tts_engine: z.string().optional(), tts_voice: z.string().optional(),
|
|
313
398
|
dictation_append: z.boolean().optional(), persisted_speech_keys: z.array(z.string()).optional(),
|
|
399
|
+
/** TAL-279: ask before opening external chat links; `trusted_link_hosts` are exact, server-normalized hostnames that skip the ask. */
|
|
400
|
+
confirm_external_links: z.boolean().optional(), trusted_link_hosts: z.array(z.string()).optional(),
|
|
401
|
+
provider_quota_thresholds: QuotaThresholdsSchema.optional(),
|
|
314
402
|
});
|
|
315
403
|
export const ProfileSchema = z.looseObject({
|
|
316
404
|
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(),
|
|
@@ -321,20 +409,82 @@ export const ActiveProfileSchema = z.looseObject({ name: z.string(), path: z.str
|
|
|
321
409
|
export const ProfileSwitchSchema = ProfilesSchema.extend({ is_default: z.boolean(), default_model: Json, default_model_provider: Json, default_workspace: z.string().nullable() });
|
|
322
410
|
/** `/api/reasoning`: config.yaml agent.reasoning_effort / display.show_reasoning, resolved for a model. */
|
|
323
411
|
export const ReasoningStatusSchema = z.looseObject({ show_reasoning: z.boolean().optional(), reasoning_effort: z.string().nullable().optional(), supported_efforts: z.array(z.string()).optional(), supports_reasoning_effort: z.boolean().optional(), supports_thinking_toggle: z.boolean().optional() });
|
|
324
|
-
|
|
412
|
+
/** TAL-301: `provider_id`/`bare_id` are the server's split of `id`; clients match a stored `(model, provider)` against them and send `id` back. */
|
|
413
|
+
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() });
|
|
325
414
|
export const ModelGroupSchema = z.looseObject({ provider: z.string(), provider_id: z.string().optional(), models: z.array(ModelEntrySchema), extra_models: z.array(ModelEntrySchema).optional() });
|
|
326
|
-
export const ModelsSchema = z.looseObject({ active_provider: NullableString.optional(), default_model: z.string().optional(), groups: z.array(ModelGroupSchema), aliases: z.record(z.string(), Json).optional(), configured_model_badges: z.record(z.string(), Json).optional() });
|
|
415
|
+
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() });
|
|
416
|
+
/** `has_key` reports a credential; `configured` (TAL-570) is the row's setup status, which a keyless Ollama or LM Studio endpoint also meets. */
|
|
327
417
|
export const ProviderSchema = z.looseObject({
|
|
328
|
-
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(),
|
|
418
|
+
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(),
|
|
329
419
|
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(),
|
|
330
420
|
});
|
|
331
421
|
export const ProvidersSchema = z.looseObject({ providers: z.array(ProviderSchema), active_provider: NullableString.optional() });
|
|
422
|
+
export const QuotaLevelSchema = z.enum(['healthy', 'warning', 'critical', 'stale', 'unavailable']);
|
|
423
|
+
/** TAL-411: the server's classification per colour basis; `/api/provider/quotas` only, at the profile's thresholds. */
|
|
424
|
+
export const QuotaUrgencySchema = z.looseObject({ remaining: QuotaLevelSchema, pace: QuotaLevelSchema.describe('Burn rate and pace tolerance; the remaining classification when the window has no pace.') });
|
|
425
|
+
/** TAL-409: a window's pace as of the envelope's `computed_at`. Stale once `valid_until` (the window's reset) passes. */
|
|
426
|
+
export const QuotaPaceSchema = z.looseObject({
|
|
427
|
+
expected_remaining_percent: z.number(), pace_delta_percent: z.number(), burn_rate: z.number(), minutes_to_reset: z.number(),
|
|
428
|
+
projected_minutes_to_empty: NullableNumber.describe('Minutes until the window empties at the current burn; null when nothing has been used.'),
|
|
429
|
+
elapsed_minutes: z.number(), valid_until: z.string(),
|
|
430
|
+
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.'),
|
|
431
|
+
});
|
|
432
|
+
export const QuotaForecastSchema = z.looseObject({
|
|
433
|
+
outcome: z.enum(['safe', 'warning']).describe('`warning` when the projection empties the window before it resets.'),
|
|
434
|
+
budget_unit: z.enum(['hour', 'day']), budget_percent: NullableNumber.describe('Remaining percent per `budget_unit` until reset.'),
|
|
435
|
+
depletion_margin_minutes: NullableNumber.describe('Projected empty minus reset, in minutes; negative empties early, null when no depletion is projected.'),
|
|
436
|
+
});
|
|
437
|
+
export const QuotaWindowSchema = z.looseObject({
|
|
438
|
+
label: z.string(), used_percent: NullableNumber, remaining_percent: NullableNumber, reset_at: NullableString.describe('ISO-8601 UTC.'), detail: NullableString,
|
|
439
|
+
window_seconds: NullableNumber.describe('The provider value, else 5h or weekly from the label; null when unknown.'),
|
|
440
|
+
pace: QuotaPaceSchema.nullable().describe('Null for a window without a future reset, a usage value, or a 5h/weekly length.'),
|
|
441
|
+
forecast: QuotaForecastSchema.nullable(),
|
|
442
|
+
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).'),
|
|
443
|
+
urgency: QuotaUrgencySchema.optional(),
|
|
444
|
+
});
|
|
445
|
+
const QuotaWindowIndex = z.number().int().nullable().optional();
|
|
332
446
|
export const QuotaSourceSchema = z.looseObject({
|
|
333
447
|
source_id: z.string(), provider_id: z.string().optional(), provider_label: z.string().optional(), account_label: z.string().optional(), status: z.string().optional(), supported: z.boolean().optional(), message: z.string().nullable().optional(),
|
|
334
|
-
is_active_provider: z.boolean().optional(), quota: Json.optional(), windows:
|
|
448
|
+
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(),
|
|
449
|
+
pace_window_index: QuotaWindowIndex.describe('The window a pace-coloured widget shows: the weekly one, else the first 5h/session window.'),
|
|
450
|
+
session_window_index: QuotaWindowIndex.describe('The session (else 5h) window.'), weekly_window_index: QuotaWindowIndex.describe('The weekly window.'),
|
|
451
|
+
urgency: QuotaUrgencySchema.optional().describe('TAL-411: `remaining` of the first window, `pace` of the pace window; alerts and the source colour follow it.'),
|
|
452
|
+
});
|
|
453
|
+
/** An account-usage provider's normalised snapshot on `/api/provider/quota` (the same windows and indexes as a quotas source). */
|
|
454
|
+
export const QuotaAccountLimitsSchema = z.looseObject({
|
|
455
|
+
available: z.boolean().optional(), stale: z.boolean().optional(), title: z.string().optional(), plan: Json.optional(), unavailable_reason: NullableString.optional(),
|
|
456
|
+
windows: z.array(QuotaWindowSchema), details: Json.optional(), fetched_at: NullableString.describe('ISO-8601 UTC.'),
|
|
457
|
+
pace_window_index: QuotaWindowIndex, session_window_index: QuotaWindowIndex, weekly_window_index: QuotaWindowIndex,
|
|
458
|
+
});
|
|
459
|
+
/** Python `get_provider_quota`: one provider's quota status. */
|
|
460
|
+
export const ProviderQuotaSchema = z.looseObject({
|
|
461
|
+
computed_at: z.string().describe('ISO-8601 UTC reference time of every window `pace`.'),
|
|
462
|
+
ok: z.boolean(), provider: NullableString, display_name: NullableString, supported: z.boolean(), status: z.string(), label: z.string().optional(), message: z.string(),
|
|
463
|
+
quota: Json.describe('OpenRouter credits (`limit_remaining`, `usage`, `limit`), else null.'),
|
|
464
|
+
account_limits: QuotaAccountLimitsSchema.nullable().optional(),
|
|
335
465
|
});
|
|
336
466
|
/** Python `get_provider_quotas`: the stable identity envelope the iOS quota widget persists (`scope_id`/`profile_id`). */
|
|
337
|
-
export const ProviderQuotasSchema = z.looseObject({
|
|
467
|
+
export const ProviderQuotasSchema = z.looseObject({
|
|
468
|
+
version: z.number(), computed_at: z.string().describe('ISO-8601 UTC reference time of every window `pace`.'), scope_id: z.string(), profile_id: z.string(), active_provider: NullableString, requested_source_id: NullableString,
|
|
469
|
+
missing_source: z.boolean().describe('True when `?source=` names a source id this scope no longer has; `sources` is then empty.'),
|
|
470
|
+
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.'),
|
|
471
|
+
});
|
|
472
|
+
/** One day of OpenRouter spend on `/api/provider/cost-history` (TAL-412). */
|
|
473
|
+
export const CostSnapshotSchema = z.looseObject({
|
|
474
|
+
date: z.string().describe('UTC day, `YYYY-MM-DD`.'), used: NullableNumber.describe('Cumulative OpenRouter usage in USD that day.'),
|
|
475
|
+
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`."),
|
|
476
|
+
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.'),
|
|
477
|
+
});
|
|
478
|
+
/** Python `get_provider_cost_history`: OpenRouter daily spend with the server-computed monthly pace and budget standing. */
|
|
479
|
+
export const ProviderCostHistorySchema = z.looseObject({
|
|
480
|
+
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(),
|
|
481
|
+
window_days: z.number().int().optional(), snapshots: z.array(CostSnapshotSchema).optional(), limit: NullableNumber.optional(), label: NullableString.optional(),
|
|
482
|
+
monthly_budget: NullableNumber.optional().describe('Settings `provider_cost_budget`.'),
|
|
483
|
+
monthly_pace: NullableNumber.optional().describe('Mean of the non-null deltas × 30, in USD rounded to cents; null without a delta.'),
|
|
484
|
+
has_enough_data: z.boolean().optional().describe('At least one non-null delta (two daily snapshots).'),
|
|
485
|
+
budget_percent: NullableNumber.optional().describe('round(pace / budget × 100); null without a positive pace and a budget.'),
|
|
486
|
+
budget_level: z.enum(['ok', 'warn', 'over']).nullable().optional().describe('`warn` from 80%, `over` from 100%; null without `budget_percent`.'),
|
|
487
|
+
});
|
|
338
488
|
export const PersonalitiesSchema = z.looseObject({ personalities: z.array(z.looseObject({ name: z.string(), description: z.string().optional() })) });
|
|
339
489
|
/** One auxiliary task slot in server order (TAL-388). The server owns ordering, normalization, and catalog matching. */
|
|
340
490
|
export const AuxiliaryTaskSchema = z.looseObject({
|
|
@@ -354,14 +504,23 @@ export const AuxiliaryTaskSchema = z.looseObject({
|
|
|
354
504
|
export const AuxiliaryModelsSchema = z.looseObject({ main: z.looseObject({ model: z.string().optional(), provider: z.string().optional(), base_url: z.string().optional(), api_key_set: z.boolean().optional() }), tasks: z.array(AuxiliaryTaskSchema) });
|
|
355
505
|
export const MaxTokensSchema = z.looseObject({ max_tokens: NullableNumber, max_tokens_effective: NullableNumber, max_tokens_fallback: NullableNumber });
|
|
356
506
|
// ── workspaces, files, git ───────────────────────────────────────────────
|
|
357
|
-
|
|
507
|
+
/** A registry entry; `name` is never empty (the folder name when none is registered, `Home` for `default`), so pickers show it as-is (TAL-303). */
|
|
508
|
+
export const WorkspaceEntrySchema = z.looseObject({ name: z.string().min(1), path: z.string() });
|
|
358
509
|
export const WorkspacesSchema = z.looseObject({ workspaces: z.array(WorkspaceEntrySchema), last: NullableString.optional(), terminal_remote_backend: z.boolean().optional() });
|
|
359
510
|
export const FileEntrySchema = z.looseObject({
|
|
360
511
|
name: z.string(), path: z.string().optional(), is_dir: z.boolean().optional(), type: z.string().optional(), size: z.number().nullable().optional(), mtime: z.number().nullable().optional(), mtime_ns: z.union([z.number(), z.string()]).nullable().optional(),
|
|
361
512
|
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(),
|
|
362
513
|
});
|
|
363
514
|
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() });
|
|
364
|
-
|
|
515
|
+
/** How a workspace file renders (TAL-566): media streams from `/api/file/raw`; text kinds carry `content`. */
|
|
516
|
+
export const FilePreviewKindSchema = z.enum(['text', 'markdown', 'csv', 'html', 'image', 'pdf', 'audio', 'video', 'binary']);
|
|
517
|
+
/** `table` is a `csv` preview's leading rows (header first); `table_truncated` says the file has more. `preview_url` is an
|
|
518
|
+
* `html` preview's app-relative frame URL, under which the page's relative assets also resolve. */
|
|
519
|
+
export const FileContentSchema = z.looseObject({
|
|
520
|
+
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(),
|
|
521
|
+
preview: FilePreviewKindSchema.optional(), table: z.array(z.array(z.string())).optional(), table_truncated: z.boolean().optional(),
|
|
522
|
+
preview_url: z.string().optional(),
|
|
523
|
+
});
|
|
365
524
|
export const GitInfoSchema = z.looseObject({ git: 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() }).nullable().optional() });
|
|
366
525
|
// ── tools ────────────────────────────────────────────────────────────────
|
|
367
526
|
export const SkillSchema = z.looseObject({ name: z.string(), description: NullableString.optional(), category: NullableString.optional(), disabled: z.boolean().optional() });
|
|
@@ -375,7 +534,20 @@ export const MemorySchema = z.looseObject({
|
|
|
375
534
|
});
|
|
376
535
|
export const PromptSchema = z.looseObject({ id: z.string().optional(), name: z.string().optional(), title: z.string().optional(), label: z.string().optional(), text: z.string().optional(), content: z.string().optional(), created_at: z.number().optional() });
|
|
377
536
|
export const PromptsSchema = z.looseObject({ prompts: z.array(PromptSchema) });
|
|
378
|
-
|
|
537
|
+
/**
|
|
538
|
+
* One slash command in the server's canonical catalog (TAL-314). `GET /api/commands` lists the client-handled commands
|
|
539
|
+
* first, then the Agent registry, in display order; each name appears once. `handler` says who runs it, `clients` which
|
|
540
|
+
* clients can run it, and `unsupported_message` is the English text a client outside `clients` shows when it is typed.
|
|
541
|
+
* Clients suggest the entries listing them whose name or any alias starts with the typed text (case-insensitive), and
|
|
542
|
+
* resolve a typed alias to the entry's `name`. `exec` marks an Agent entry `POST /api/commands/exec` runs: the client
|
|
543
|
+
* posts the typed text there and shows the returned output instead of starting a chat turn (TAL-561).
|
|
544
|
+
*/
|
|
545
|
+
export const CommandClientSchema = z.enum(['web', 'ios']);
|
|
546
|
+
export const CommandRowSchema = z.looseObject({
|
|
547
|
+
name: z.string(), description: z.string().optional(), aliases: z.array(z.string()), args_hint: z.string().optional(), category: z.string().optional(),
|
|
548
|
+
handler: z.enum(['client', 'agent']), clients: z.array(CommandClientSchema), unsupported_message: z.string().optional(),
|
|
549
|
+
cli_only: z.boolean().optional(), gateway_only: z.boolean().optional(), subcommands: z.array(Json).optional(), exec: z.boolean().optional(),
|
|
550
|
+
});
|
|
379
551
|
export const CommandsSchema = z.looseObject({ commands: z.array(CommandRowSchema) });
|
|
380
552
|
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() });
|
|
381
553
|
export const InsightsSchema = z.looseObject({
|
|
@@ -390,10 +562,17 @@ export const SystemHealthSchema = z.looseObject({
|
|
|
390
562
|
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(),
|
|
391
563
|
errors: z.array(z.looseObject({ code: z.string().optional(), metric: z.string().optional() })).optional(), webui_runtime: Json.optional(),
|
|
392
564
|
});
|
|
393
|
-
export const
|
|
565
|
+
export const UpdateStateSchema = z.enum(['up_to_date', 'release_ready', 'commits_behind', 'local_changes', 'finish', 'manual', 'check_failed', 'off', 'unknown']);
|
|
566
|
+
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(),
|
|
567
|
+
state: UpdateStateSchema.describe('TAL-559: the status clients word; `off` when checks are disabled or Agent updates are ignored.'),
|
|
568
|
+
can_apply: z.boolean().describe('The apply action is available for this target.'),
|
|
569
|
+
installed_unverified: z.boolean().describe('`release_ready` only: the installed revision sits on no release tag.'),
|
|
570
|
+
manual_link: z.boolean().describe('Show the manual-install (releases) link.'),
|
|
571
|
+
target_version: z.string().nullable().describe('The version the update path leads to, when one is shown.'),
|
|
572
|
+
});
|
|
394
573
|
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() });
|
|
395
574
|
export const UpdatesSummarySchema = z.looseObject({ summary: z.string().optional(), text: z.string().optional(), ok: z.boolean().optional(), error: z.string().optional(), diff_links: z.array(Json).optional() });
|
|
396
|
-
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() });
|
|
575
|
+
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() });
|
|
397
576
|
export const UpdateNotificationPhaseSchema = z.enum(['applying', 'awaiting_confirmation', 'restarting', 'succeeded', 'blocked', 'failed', 'unknown']);
|
|
398
577
|
export const UpdateNotificationActionSchema = z.object({
|
|
399
578
|
id: z.string().min(1).max(64).regex(/^[a-z0-9][a-z0-9_-]*$/),
|
|
@@ -424,7 +603,7 @@ export const UpdateNotificationSchema = z.object({
|
|
|
424
603
|
acknowledged_action_id: z.string().nullable(),
|
|
425
604
|
verified_revision: z.string().regex(/^[a-f0-9]{40}$/).nullable(),
|
|
426
605
|
verified_version: z.string().min(1).max(80).nullable(),
|
|
427
|
-
/** The apply's own explanation of a failed or blocked attempt, line breaks kept; null
|
|
606
|
+
/** The apply's own explanation of a failed or blocked attempt, or of a success that needs attention (an Agent update that kept local edits in the git stash), line breaks kept; null otherwise. */
|
|
428
607
|
detail: z.string().max(2000).nullable(),
|
|
429
608
|
unread: z.boolean(),
|
|
430
609
|
active: z.boolean(),
|
|
@@ -454,14 +633,15 @@ export const UpdateNotificationsSchema = z.object({
|
|
|
454
633
|
});
|
|
455
634
|
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() });
|
|
456
635
|
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() });
|
|
457
|
-
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() });
|
|
636
|
+
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() });
|
|
458
637
|
export const McpServersSchema = z.looseObject({ servers: z.array(McpServerSchema), health_pending: z.boolean().optional(), reload_required: z.boolean().optional(), toggle_supported: z.boolean().optional() });
|
|
459
638
|
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() });
|
|
460
639
|
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() });
|
|
461
640
|
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() });
|
|
462
|
-
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() });
|
|
641
|
+
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() });
|
|
463
642
|
// ── onboarding ───────────────────────────────────────────────────────────
|
|
464
|
-
|
|
643
|
+
/** `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. */
|
|
644
|
+
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() });
|
|
465
645
|
export const OnboardingStatusSchema = z.looseObject({
|
|
466
646
|
completed: z.boolean(),
|
|
467
647
|
settings: z.looseObject({ bot_name: z.string().optional(), default_model: z.string().optional(), default_workspace: NullableString.optional(), password_enabled: z.boolean().optional() }).optional(),
|
|
@@ -471,16 +651,25 @@ export const OnboardingStatusSchema = z.looseObject({
|
|
|
471
651
|
models: ModelsSchema.optional(),
|
|
472
652
|
});
|
|
473
653
|
export const OnboardingProbeSchema = z.looseObject({ ok: z.boolean().optional(), success: z.boolean().optional(), error: z.string().optional(), message: z.string().optional(), models: z.array(Json).optional() });
|
|
474
|
-
|
|
654
|
+
/**
|
|
655
|
+
* One device-code sign-in (TAL-398). `status` is `pending` until the flow ends `approved`, `denied`, `expired`, `cancelled`
|
|
656
|
+
* or `error`; `ok` is false for every ending without a credential, and `error` then carries the Agent's reason.
|
|
657
|
+
* `user_code`, `verification_url`, `expires_in` and `interval` (seconds between polls) come with the start.
|
|
658
|
+
*/
|
|
659
|
+
export const OnboardingOAuthSchema = z.looseObject({
|
|
660
|
+
ok: z.boolean().optional(), status: z.string().optional(), url: z.string().optional(), verification_url: z.string().optional(), user_code: z.string().optional(), message: z.string().optional(),
|
|
661
|
+
error: z.string().nullable().optional(), flow_id: z.string().optional(), provider: z.string().optional(), expires_in: z.number().int().optional(), interval: z.number().int().optional(),
|
|
662
|
+
});
|
|
475
663
|
// ── automation ───────────────────────────────────────────────────────────
|
|
476
664
|
export const CronScheduleSchema = z.looseObject({ kind: z.string().optional(), expr: z.string().optional(), minutes: z.number().optional(), run_at: z.string().optional(), display: z.string().optional() });
|
|
477
665
|
export const CronRepeatSchema = z.looseObject({ times: NullableNumber.optional(), completed: z.number().optional() });
|
|
478
666
|
export const CronDerivedStateSchema = z.enum(['needs_attention', 'schedule_error', 'paused', 'off', 'error', 'active']);
|
|
479
667
|
export const CronJobViewSchema = z.looseObject({
|
|
480
668
|
read_only: z.boolean().optional(), owner_profile: NullableString.optional(), id: z.string().optional(), job_id: z.string().optional(), name: z.string().nullable().optional(), prompt: z.string().optional(), schedule: z.union([z.string(), CronScheduleSchema]).optional(),
|
|
481
|
-
|
|
669
|
+
/** Server-filled (TAL-298): `schedule_display` is the schedule text clients show; `schedule_input` is the editor prefill the scheduler accepts back. */
|
|
670
|
+
schedule_display: z.string(), schedule_input: z.string(), enabled: z.boolean().optional(), paused: z.boolean().optional(), paused_reason: NullableString.optional(), state: NullableString.optional(), last_status: NullableString.optional(), last_error: NullableString.optional(),
|
|
482
671
|
last_delivery_error: NullableString.optional(), next_run_at: z.union([z.string(), z.number(), z.null()]).optional(), last_run_at: z.union([z.string(), z.number(), z.null()]).optional(), repeat: z.union([CronRepeatSchema, z.number(), z.null()]).optional(),
|
|
483
|
-
status: z.string().optional(), last_run: Json.optional(), next_run: Json.optional(), profile: NullableString.optional(), session_id: NullableString.optional(), model: NullableString.optional(), provider: NullableString.optional(), workspace: NullableString.optional(),
|
|
672
|
+
status: z.string().optional(), last_run: Json.optional(), next_run: Json.optional(), profile: NullableString.optional(), session_id: NullableString.optional(), model: NullableString.optional(), provider: NullableString.optional(), model_option_id: NullableString.optional(), workspace: NullableString.optional(),
|
|
484
673
|
workdir: NullableString.optional(), deliver: NullableString.optional(), skills: z.array(z.string()).optional(), no_agent: z.boolean().optional(), script: NullableString.optional(), monitor: NullableString.optional(), continuity: z.boolean().optional(),
|
|
485
674
|
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(),
|
|
486
675
|
/** Server-derived (TAL-296): the job's status, whether it needs attention, and whether its primary action is Resume. Live runs overlay it. */
|
|
@@ -500,10 +689,26 @@ export const CronRunSummarySchema = z.looseObject({ filename: z.string(), size:
|
|
|
500
689
|
export const CronHistorySchema = z.looseObject({ job_id: z.string().optional(), runs: z.array(CronRunSummarySchema), total: z.number().optional(), offset: z.number().optional() });
|
|
501
690
|
export const CronRunSchema = z.looseObject({ content: z.string().optional(), snippet: z.string().optional(), usage: CronRunUsageSchema.optional(), error: z.string().optional() });
|
|
502
691
|
export const CronStatusSchema = z.looseObject({ running: z.union([z.boolean(), z.record(z.string(), z.number())]).optional() });
|
|
503
|
-
|
|
692
|
+
/** 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. */
|
|
693
|
+
export const KanbanTaskActionsSchema = z.object({ block: z.boolean(), unblock: z.boolean(), complete: z.boolean(), archive: z.boolean(), move_to: z.array(z.string()) });
|
|
694
|
+
/** 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. */
|
|
695
|
+
export const KanbanTaskPolicyShape = { available_actions: KanbanTaskActionsSchema, requires_running_exit_confirmation: z.boolean() };
|
|
696
|
+
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 });
|
|
504
697
|
export const KanbanColumnSchema = z.looseObject({ name: z.string(), tasks: z.array(KanbanTaskViewSchema) });
|
|
505
|
-
|
|
506
|
-
export const
|
|
698
|
+
/** One profile lane (TAL-567): an assignee's tasks (`null` = unassigned) across every board column, with its task count. */
|
|
699
|
+
export const KanbanLaneSchema = z.object({ assignee: z.string().nullable(), count: z.number().int(), columns: z.array(KanbanColumnSchema) });
|
|
700
|
+
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(),
|
|
701
|
+
/** Statuses a bulk status change may target (TAL-557). */
|
|
702
|
+
bulk_move_targets: z.array(z.string()),
|
|
703
|
+
/** The saved board view (TAL-567): `true` groups the board into `lanes` by assignee. */
|
|
704
|
+
lane_by_profile: z.boolean(),
|
|
705
|
+
/** Present when `lane_by_profile`: the columns split into profile lanes, assignees in name order, unassigned last. */
|
|
706
|
+
lanes: z.array(KanbanLaneSchema).optional() });
|
|
707
|
+
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(),
|
|
708
|
+
/** Whether the board can be archived or deleted; the default board cannot (TAL-567). */
|
|
709
|
+
removable: z.boolean() })), current: z.string().optional(), read_only: z.boolean().optional() });
|
|
710
|
+
/** Board-wide task counts (TAL-567): `status_counts` in board-column order, unknown statuses after; `total` excludes archived tasks. */
|
|
711
|
+
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() })) });
|
|
507
712
|
export const ExtensionStatusSchema = z.looseObject({
|
|
508
713
|
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(),
|
|
509
714
|
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(),
|