@maudecode/talaria-web-contracts 1.18.0 → 1.19.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/gateway-session.d.ts +229 -0
- package/dist/gateway-session.js +46 -0
- package/dist/gateway-session.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/openapi.js +4 -0
- package/dist/openapi.js.map +1 -1
- package/dist/router.d.ts +4265 -220
- package/dist/routes/automation.d.ts +104 -24
- package/dist/routes/automation.js +6 -3
- package/dist/routes/automation.js.map +1 -1
- package/dist/routes/chat.d.ts +1338 -43
- package/dist/routes/chat.js +5 -1
- package/dist/routes/chat.js.map +1 -1
- package/dist/routes/core.d.ts +17 -6
- package/dist/routes/core.js +2 -2
- package/dist/routes/core.js.map +1 -1
- package/dist/routes/raw.js +1 -1
- package/dist/routes/raw.js.map +1 -1
- package/dist/routes/sessions.d.ts +2367 -156
- package/dist/routes/sessions.js +18 -7
- package/dist/routes/sessions.js.map +1 -1
- package/dist/routes/settings.d.ts +427 -9
- package/dist/routes/settings.js +2 -2
- package/dist/routes/settings.js.map +1 -1
- package/dist/routes/tools.d.ts +645 -18
- package/dist/routes/tools.js +65 -8
- package/dist/routes/tools.js.map +1 -1
- package/dist/run-status.d.ts +39 -0
- package/dist/run-status.js +13 -0
- package/dist/run-status.js.map +1 -0
- package/dist/sidecar/methods.d.ts +1074 -17
- package/dist/sidecar/methods.js +9 -2
- package/dist/sidecar/methods.js.map +1 -1
- package/dist/sidecar/namespaces.d.ts +1469 -33
- package/dist/sidecar/namespaces.js +298 -31
- package/dist/sidecar/namespaces.js.map +1 -1
- package/dist/sidecar/runtime.d.ts +61 -0
- package/dist/sidecar/runtime.js +20 -0
- package/dist/sidecar/runtime.js.map +1 -1
- package/dist/sidecar/version.d.ts +1 -1
- package/dist/sidecar/version.js +1 -1
- package/dist/speed.d.ts +14 -0
- package/dist/speed.js +6 -0
- package/dist/speed.js.map +1 -0
- package/dist/sse.d.ts +797 -5
- package/dist/sse.js +24 -7
- package/dist/sse.js.map +1 -1
- package/dist/transcribe-stream.d.ts +34 -0
- package/dist/transcribe-stream.js +23 -0
- package/dist/transcribe-stream.js.map +1 -0
- package/dist/views.d.ts +2097 -127
- package/dist/views.js +273 -47
- package/dist/views.js.map +1 -1
- package/fixtures/sidecar/aux.json +134 -0
- package/fixtures/sidecar/chat.json +14 -0
- package/fixtures/sidecar/checkpoints.json +6 -6
- package/fixtures/sidecar/commands.json +216 -108
- package/fixtures/sidecar/config.json +15 -0
- package/fixtures/sidecar/connectors.json +218 -0
- package/fixtures/sidecar/cron.json +1001 -31
- package/fixtures/sidecar/gateway.json +39 -0
- package/fixtures/sidecar/goals.json +5 -3
- package/fixtures/sidecar/kanban.json +139 -49
- package/fixtures/sidecar/memory.json +50 -0
- package/fixtures/sidecar/models.json +122 -0
- package/fixtures/sidecar/personalities.json +92 -0
- package/fixtures/sidecar/plugins.json +116 -27
- package/fixtures/sidecar/process.json +31 -0
- package/fixtures/sidecar/profiles.json +2 -0
- package/fixtures/sidecar/providers.json +14 -1
- package/fixtures/sidecar/rpc.json +35 -1
- package/fixtures/sidecar/runtime.json +130 -14
- package/fixtures/sidecar/skills.json +256 -13
- package/fixtures/sidecar/state_db.json +19 -2
- package/fixtures/sidecar/stt.json +62 -1
- package/fixtures/sidecar/text.json +20 -2
- package/fixtures/sidecar/toolsets.json +468 -0
- package/fixtures/sidecar/usage.json +22 -2
- package/fixtures/sidecar/write_approval.json +98 -0
- package/package.json +1 -1
package/dist/views.js
CHANGED
|
@@ -5,7 +5,12 @@
|
|
|
5
5
|
* that must survive a round trip (documented passthrough).
|
|
6
6
|
*/
|
|
7
7
|
import { z } from 'zod';
|
|
8
|
-
import {
|
|
8
|
+
import { RunStatusSchema } from './run-status.js';
|
|
9
|
+
import { AgentRefreshConfirmationSchema } from './sidecar/runtime.js';
|
|
10
|
+
import { SpeedTierSchema } from './speed.js';
|
|
11
|
+
import { OwnerAttachmentSchema } from './gateway-session.js';
|
|
12
|
+
import { CanonicalBotChatSchema, GatewayModeSchema, PluginSettingFieldSchema, SkillCatalogIdentitySchema } from './sidecar/namespaces.js';
|
|
13
|
+
export { SpeedTierSchema } from './speed.js';
|
|
9
14
|
const Json = z.unknown();
|
|
10
15
|
export const NullableString = z.string().nullable();
|
|
11
16
|
export const NullableNumber = z.number().nullable();
|
|
@@ -100,8 +105,8 @@ export const TurnFileChangeSchema = z.looseObject({ path: z.string(), action: z.
|
|
|
100
105
|
export const TurnTerminalStateSchema = z.enum(['completed', 'no_response', 'cancelled', 'interrupted', 'tool_limit_reached', 'compression_exhausted', 'error']);
|
|
101
106
|
export const ActivitySceneSchema = z.looseObject({
|
|
102
107
|
version: z.literal('activity_scene_v1'), activity_rows: z.array(ActivitySceneRowSchema), final_answer: z.string().optional(),
|
|
103
|
-
/** TAL-456:
|
|
104
|
-
final_answer_excerpt: z.string().optional(), turn_duration: z.number().nullable().optional(),
|
|
108
|
+
/** TAL-456: an older settled final answer too long to lay out whole. Absent on the session-global newest settled visible reply and throughout the next running turn. Clients render the excerpt with a local "Show more". */
|
|
109
|
+
final_answer_excerpt: z.string().optional().describe("Collapsed preview of an older settled final answer. Absent on the session-global newest visible reply; its exemption transfers only when a newer visible reply settles."), turn_duration: z.number().nullable().optional(),
|
|
105
110
|
/** TAL-186: `final_answer` with its media references rewritten for display (see `_display_content`), and its media. */
|
|
106
111
|
final_answer_display: z.string().optional(), final_answer_media: z.array(DisplayMediaSchema).optional(),
|
|
107
112
|
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.'),
|
|
@@ -115,8 +120,13 @@ export const ActivitySceneSchema = z.looseObject({
|
|
|
115
120
|
file_changes: z.array(TurnFileChangeSchema).optional(),
|
|
116
121
|
activity_rows_total: z.number().int().optional(), activity_rows_offset: z.number().int().optional(), activity_rows_complete: z.boolean().optional(), activity_rows_omitted: z.number().int().optional(), activity_scene_ref: z.string().optional(),
|
|
117
122
|
});
|
|
118
|
-
/**
|
|
119
|
-
export const
|
|
123
|
+
/** The server-owned result-review lifecycle (TAL-1022). */
|
|
124
|
+
export const BackgroundReviewStateSchema = z.enum(['waiting', 'reviewing', 'reviewed', 'failed', 'unknown']);
|
|
125
|
+
/** One finished background item (see `_background_update.lines`). */
|
|
126
|
+
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(),
|
|
127
|
+
/** Server-composed worker and parent outcome. Failure/unknown worker outcomes take precedence. */
|
|
128
|
+
review_state: BackgroundReviewStateSchema.optional(),
|
|
129
|
+
});
|
|
120
130
|
export const MessageSchema = z.looseObject({
|
|
121
131
|
role: z.string(), content: MessageContentSchema.optional(), id: MessageIdSchema.optional(), message_id: MessageIdSchema.optional(), timestamp: z.number().nullable().optional(),
|
|
122
132
|
attachments: z.array(AttachmentSchema).optional(), tool_calls: z.array(ToolCallSchema).optional(),
|
|
@@ -144,9 +154,9 @@ export const MessageSchema = z.looseObject({
|
|
|
144
154
|
_steer: z.looseObject({ steer_id: z.string(), submitted_at: z.number().nullable().optional(), consumed_at: z.number().optional(), phase_duration: z.number().optional() }).optional(),
|
|
145
155
|
/** On a steered turn's last reply: seconds from the last consumed steer to the turn's end. */
|
|
146
156
|
_final_phase_duration: z.number().optional(),
|
|
147
|
-
/** A settled body too long to lay out whole
|
|
148
|
-
_display_truncated: z.boolean().optional(),
|
|
149
|
-
_display_excerpt: z.string().optional(),
|
|
157
|
+
/** A settled body too long to lay out whole. The session-global newest settled visible assistant reply and running output carry no excerpt. Only a newer visible terminal answer transfers that exemption. Clients render `_display_excerpt` with a local "Show more" for full `content`. */
|
|
158
|
+
_display_truncated: z.boolean().optional().describe("Whether this settled body has a collapsed preview. The newest settled visible assistant reply and active-turn output remain full."),
|
|
159
|
+
_display_excerpt: z.string().optional().describe("Collapsed preview with full content retained. The newest settled visible assistant reply remains exempt throughout the next running turn, until a newer visible reply settles."),
|
|
150
160
|
/**
|
|
151
161
|
* TAL-452: a typed user message (never a steer, background update or marker) longer than 20 lines or 2,000
|
|
152
162
|
* characters. Clients show it folded to a few lines with a local "Show more"; copy and edit use the whole `content`.
|
|
@@ -168,11 +178,13 @@ export const MessageSchema = z.looseObject({
|
|
|
168
178
|
_background_update: z.object({
|
|
169
179
|
kind: z.enum(['delegation', 'process', 'mixed', 'other']), attention: z.boolean(), count: z.number().int().positive(), summary: z.string(),
|
|
170
180
|
/**
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
* `
|
|
181
|
+
* One completion line per finished item. Clients show its label and exactly one leading icon from `review_state`,
|
|
182
|
+
* with localized accessible/help wording. Parent review never overrides failed/unknown worker outcomes.
|
|
183
|
+
* `content` stays available in full on expansion.
|
|
174
184
|
*/
|
|
175
185
|
lines: z.array(BackgroundLineSchema),
|
|
186
|
+
/** Parent review only, established from admission, the live run, and terminal evidence. */
|
|
187
|
+
review_state: BackgroundReviewStateSchema.optional(),
|
|
176
188
|
}).optional(),
|
|
177
189
|
/**
|
|
178
190
|
* TAL-305: a marker the Agent wrote around context compaction, not a message anyone typed. Clients render a collapsed
|
|
@@ -181,6 +193,19 @@ export const MessageSchema = z.looseObject({
|
|
|
181
193
|
_marker_kind: z.enum(['context_compaction', 'preserved_task_list']).optional(),
|
|
182
194
|
/** TAL-305: a preserved task list's card body, without its marker line. */
|
|
183
195
|
_marker_body: z.string().optional(),
|
|
196
|
+
/**
|
|
197
|
+
* TAL-815: an assistant row the Agent wrote as a notice, not the model's reply. `failed_turn`: the boundary closing a
|
|
198
|
+
* turn that failed, with its copy in `content`. Clients show it as a notice in its place, never as a reply bubble or
|
|
199
|
+
* part of a turn's reply; it is absent when Web's own error row already reports that turn. `session_finalize` is
|
|
200
|
+
* a plugin's closing text after clear, with role `local_notice`, display-only and excluded from model history.
|
|
201
|
+
*/
|
|
202
|
+
_notice_kind: z.enum(['failed_turn', 'session_finalize']).optional(),
|
|
203
|
+
/**
|
|
204
|
+
* TAL-816: a user row of a messaging session that the Agent's gateway mirrored after a webhook route's or cron job's
|
|
205
|
+
* delivery to the chat, not a message the user sent. Clients show it as a delivery notice titled by a localized label
|
|
206
|
+
* per `kind` with `name`, and `body` (the delivered text, without its label line) beneath, never as a user bubble.
|
|
207
|
+
*/
|
|
208
|
+
_delivery: z.object({ kind: z.enum(['webhook', 'cron']), name: z.string(), body: z.string() }).optional(),
|
|
184
209
|
/** TAL-460: part of the Agent's reply to the background update just before it in the same turn. */
|
|
185
210
|
_background_reply: z.boolean().optional(),
|
|
186
211
|
/** TAL-460: that reply is only a silence marker; clients show the update's lines and nothing of this turn's reply. */
|
|
@@ -201,6 +226,23 @@ export const PendingSteerSchema = z.object({
|
|
|
201
226
|
steer_id: z.string(), text: z.string(), submitted_at: z.number(), state: z.enum(['pending', 'sending_now']),
|
|
202
227
|
actions: z.object({ edit: z.boolean(), cancel: z.boolean(), send_now: z.boolean() }),
|
|
203
228
|
});
|
|
229
|
+
/**
|
|
230
|
+
* TAL-803: an out-of-band notice the Agent raised for the session (a memory provider that failed to load, credit and
|
|
231
|
+
* usage warnings), one per `key`. The server keeps it until the Agent clears that key, `expires_at` passes, or a new agent
|
|
232
|
+
* replaces the one that raised it.
|
|
233
|
+
*/
|
|
234
|
+
export const SessionNoticeSchema = z.object({
|
|
235
|
+
key: z.string(), level: z.enum(['info', 'warn', 'error', 'success']), text: z.string(),
|
|
236
|
+
expires_at: NullableNumber.describe('Unix seconds when the server drops it; null when only the Agent clears it.'),
|
|
237
|
+
});
|
|
238
|
+
/**
|
|
239
|
+
* TAL-808: the session's standing `/goal` while it runs, from the Agent's goal state. `parked` is an active goal waiting on
|
|
240
|
+
* a process or a timer; `reason` is why it is paused or what it waits on. A done, cleared or absent goal is null.
|
|
241
|
+
*/
|
|
242
|
+
export const SessionGoalSchema = z.object({
|
|
243
|
+
text: z.string(), status: z.enum(['active', 'paused', 'parked']), turns_used: z.number().int().nonnegative(), max_turns: z.number().int().nonnegative(),
|
|
244
|
+
reason: NullableString, parked_until: NullableNumber.describe('Unix seconds a timed park ends; null otherwise.'),
|
|
245
|
+
});
|
|
204
246
|
/**
|
|
205
247
|
* TAL-299: the context ring, computed by the server. `context_used_tokens` is the post-compression estimate, else the last
|
|
206
248
|
* prompt (never the cumulative `input_tokens`); `context_window_tokens` is the model's window. The percents are rounded
|
|
@@ -215,12 +257,13 @@ export const ContextUsageFields = {
|
|
|
215
257
|
const ActiveTurnOriginSchema = z.enum(['user', 'background']).nullable().optional().describe('Who started the running turn; null while idle.');
|
|
216
258
|
const IsStreamingSchema = z.boolean().describe('True only while the session\'s run is a live stream on this server.');
|
|
217
259
|
const ActiveStreamIdSchema = NullableString.optional().describe('The live stream id; non-null only while `is_streaming` is true.');
|
|
260
|
+
const ReadOnlyReasonSchema = NullableString.optional().describe('Server-owned reason this session is display-only or its ownership cannot be verified.');
|
|
218
261
|
const ReadOnlySchema = z.boolean().describe('The session cannot be modified from Web: a read-only import, a view-only subagent child, or a foreign session whose owner refuses claiming.');
|
|
219
|
-
const CanBranchSchema = z.boolean().describe('Web may branch this session: never a subagent child
|
|
220
|
-
const CanPinSchema = z.boolean().describe('Web may pin or unpin this session: never a subagent child.');
|
|
221
|
-
const CanArchiveSchema = z.boolean().describe('Web may archive or unarchive this session: never a subagent child.');
|
|
262
|
+
const CanBranchSchema = z.boolean().describe('Web may branch this session: never a subagent child or an ownership-locked session; other read-only sessions only when they are cron runs.');
|
|
263
|
+
const CanPinSchema = z.boolean().describe('Web may pin or unpin this session: never a subagent child or a session locked by canonical ownership or unreadable ownership storage.');
|
|
264
|
+
const CanArchiveSchema = z.boolean().describe('Web may archive or unarchive this session: never a subagent child or a session locked by canonical ownership or unreadable ownership storage.');
|
|
222
265
|
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).');
|
|
223
|
-
const CanDuplicateSchema = z.boolean().describe('Web may duplicate this session: it has a WebUI copy
|
|
266
|
+
const CanDuplicateSchema = z.boolean().describe('Web may duplicate this session: it has a WebUI copy, is not a subagent child, and is not locked by canonical ownership or unreadable ownership storage.');
|
|
224
267
|
// TAL-310: the server classifies every session's source once; clients file rows by it and never scan source markers.
|
|
225
268
|
export const SourceKindSchema = z.enum(['webui', 'cli', 'messaging', 'cron', 'webhook', 'subagent', 'claude_code', 'kanban', 'api', 'other'])
|
|
226
269
|
.describe('The session\'s source family. `is_cli_session` is true only for `cli` and `claude_code`.');
|
|
@@ -245,16 +288,23 @@ export const CompressionReferenceSchema = z.object({
|
|
|
245
288
|
export const BranchedFromSchema = z.object({ session_id: SessionIdSchema, title: z.string() });
|
|
246
289
|
/** Full session record from `GET /api/session` and mutations returning `session`. */
|
|
247
290
|
export const SessionSchema = z.looseObject({
|
|
291
|
+
composer_state_key: z.string().optional().describe('Opaque profile-home and owner identity for device-local composer state; never an API session id.'),
|
|
248
292
|
session_id: SessionIdSchema, title: z.string(), workspace: z.string().optional(), created_workspace: z.string().nullable().optional(), model: NullableString.optional(), model_provider: NullableString.optional(),
|
|
249
293
|
model_option_id: NullableString.optional().describe('TAL-301: the catalog entry id the stored model/provider selects; null when none.'),
|
|
250
294
|
messages: z.array(MessageSchema).optional(), tool_calls: z.array(ToolCallSchema).optional(), created_at: UnixSeconds.optional(), updated_at: UnixSeconds.optional(), last_message_at: NullableNumber.optional(),
|
|
251
295
|
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(),
|
|
252
296
|
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(),
|
|
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.'),
|
|
297
|
+
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.'),
|
|
298
|
+
run_status: RunStatusSchema.nullable().optional().describe('Current server-selected run presentation; null when no turn runs. Older servers omit it.'),
|
|
299
|
+
compression_started_at: NullableNumber.optional().describe('TAL-1006: when the compression clients show started (epoch seconds): the running manual job\'s, else the live run\'s open span; null when none runs.'),
|
|
300
|
+
notices: z.array(SessionNoticeSchema).optional().describe('TAL-803: the Agent\'s active notices for the session, oldest first.'),
|
|
301
|
+
goal: SessionGoalSchema.nullable().optional().describe('TAL-808: the standing /goal; null when none runs.'),
|
|
302
|
+
automatic_turns_held: z.boolean().optional().describe('TAL-899: the user pressed Stop, so no automatic turn (background wakeup or goal continuation) starts until their next message.'), has_pending_user_message: z.boolean().optional(),
|
|
254
303
|
pending_user_message: NullableString.optional(), pending_attachments: z.array(AttachmentSchema).optional(), pending_started_at: NullableNumber.optional(), pending_user_source: NullableString.optional(),
|
|
255
304
|
context_length: NullableNumber.optional(), threshold_tokens: NullableNumber.optional(), last_prompt_tokens: NullableNumber.optional(), post_compression_context_tokens_estimate: NullableNumber.optional(), ...ContextUsageFields,
|
|
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(),
|
|
305
|
+
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, read_only_reason: ReadOnlyReasonSchema, owner_attachment: OwnerAttachmentSchema.optional(), can_branch: CanBranchSchema, can_pin: CanPinSchema, can_archive: CanArchiveSchema, can_delete: CanDeleteSchema, can_duplicate: CanDuplicateSchema, source_tag: NullableString.optional(),
|
|
257
306
|
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.'),
|
|
307
|
+
confirms_deep_truncate: z.boolean().optional().describe('TAL-929: this server holds a `session.truncate` that discards more than one user turn until it is confirmed; absent on older servers, which cut at once.'),
|
|
258
308
|
source_label: NullableString.optional(), session_source: NullableString.optional(), raw_source: NullableString.optional(), parent_session_id: NullableString.optional(), worktree_path: NullableString.optional(),
|
|
259
309
|
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(),
|
|
260
310
|
compression_anchor_summary: NullableString.optional(), compression_recovery: z.record(z.string(), Json).optional(), recommended_recovery_action: NullableString.optional(), compression_recovery_action: NullableString.optional(),
|
|
@@ -276,12 +326,18 @@ export const SessionEnvelopeSchema = z.looseObject({ session: SessionSchema });
|
|
|
276
326
|
export const SessionRowSchema = z.looseObject({
|
|
277
327
|
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(),
|
|
278
328
|
message_count: z.number().optional(), pinned: z.boolean().optional(), archived: z.boolean().optional(), project_id: NullableString.optional(), profile: NullableString.optional(), is_streaming: IsStreamingSchema,
|
|
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(),
|
|
329
|
+
is_cli_session: z.boolean().optional(), source_kind: SourceKindSchema, is_messaging_session: IsMessagingSessionSchema, sort_ts: SortTsSchema, cron_running: z.boolean().optional(), read_only: ReadOnlySchema, read_only_reason: ReadOnlyReasonSchema, owner_attachment: OwnerAttachmentSchema.optional(), 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(),
|
|
280
330
|
source_tag: NullableString.optional(), source_label: NullableString.optional(), session_source: NullableString.optional(), raw_source: NullableString.optional(), parent_session_id: NullableString.optional(),
|
|
281
331
|
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(),
|
|
282
332
|
workspace_name: WorkspaceNameSchema,
|
|
283
333
|
...ContextUsageFields,
|
|
284
334
|
});
|
|
335
|
+
/**
|
|
336
|
+
* TAL-785: whether the Agent's `state.db` could serve the Agent session rows. `corrupt`: SQLite reports the file
|
|
337
|
+
* damaged; `unavailable`: it could not be read for another reason (permissions, a lock, an I/O error); `outdated`: a
|
|
338
|
+
* readable database from an older hermes-agent. `reason` explains a degraded state.
|
|
339
|
+
*/
|
|
340
|
+
export const AgentStorageSchema = z.object({ state: z.enum(['ok', 'corrupt', 'unavailable', 'outdated']), reason: z.string().nullable() });
|
|
285
341
|
export const SessionsListSchema = z.looseObject({
|
|
286
342
|
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(),
|
|
287
343
|
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(),
|
|
@@ -289,10 +345,11 @@ export const SessionsListSchema = z.looseObject({
|
|
|
289
345
|
// TAL-482: sidebar counts for the "Scheduled sessions" / "Webhook sessions" groups; `_truncated` means more exist than are listed.
|
|
290
346
|
scheduled_session_count: z.number().int().nonnegative(), scheduled_sessions_truncated: z.boolean(),
|
|
291
347
|
webhook_session_count: z.number().int().nonnegative(), webhook_sessions_truncated: z.boolean(),
|
|
348
|
+
agent_storage: AgentStorageSchema.describe('Agent session storage health; a degraded state explains an empty or missing Agent session list.'),
|
|
292
349
|
archived_limit: z.number().int().nullable().optional(), archived_offset: z.number().int().optional(),
|
|
293
350
|
});
|
|
294
351
|
export const SessionStatusSchema = z.looseObject({
|
|
295
|
-
session_id: SessionIdSchema, title: z.string().optional(), active_stream_id: ActiveStreamIdSchema, active_turn_origin: ActiveTurnOriginSchema, agent_running: IsStreamingSchema, is_streaming: IsStreamingSchema, read_only: ReadOnlySchema, message_count: z.number().optional(), model: NullableString.optional(),
|
|
352
|
+
session_id: SessionIdSchema, title: z.string().optional(), active_stream_id: ActiveStreamIdSchema, active_turn_origin: ActiveTurnOriginSchema, agent_running: IsStreamingSchema, is_streaming: IsStreamingSchema, read_only: ReadOnlySchema, read_only_reason: ReadOnlyReasonSchema, owner_attachment: OwnerAttachmentSchema.optional(), message_count: z.number().optional(), model: NullableString.optional(),
|
|
296
353
|
profile: NullableString.optional(), workspace: z.string().optional(), input_tokens: z.number().optional(), output_tokens: z.number().optional(), total_tokens: z.number().optional(), estimated_cost: NullableNumber.optional(), updated_at: UnixSeconds.optional(),
|
|
297
354
|
});
|
|
298
355
|
export const SessionUsageSchema = z.looseObject({ input_tokens: z.number().optional(), output_tokens: z.number().optional(), total_tokens: z.number().optional(), estimated_cost: NullableNumber.optional(), model: NullableString.optional() });
|
|
@@ -300,12 +357,20 @@ export const ProjectSchema = z.looseObject({ project_id: z.string(), name: z.str
|
|
|
300
357
|
export const ProjectsSchema = z.looseObject({ projects: z.array(ProjectSchema), active_profile: z.string(), all_profiles: z.boolean(), other_profile_count: z.number().int() });
|
|
301
358
|
export const SessionDeleteResultSchema = z.looseObject({ ok: z.literal(true), state_db_cleanup_failed: z.boolean().optional() });
|
|
302
359
|
// ── chat ─────────────────────────────────────────────────────────────────
|
|
360
|
+
/** `voice_turn` (TAL-801): the turn was spoken (an App voice note), so the Agent runs it on `auxiliary.voice_chat`. */
|
|
303
361
|
export const ChatStartRequestSchema = z.looseObject({
|
|
362
|
+
submission_id: z.string().min(1).max(128).optional().describe('Stable native-owner admission identity. Reuse only for an exact retry of the same submission.'),
|
|
304
363
|
session_id: SessionIdSchema, message: z.string().optional(), model: z.string().nullable().optional(), model_provider: z.string().nullable().optional(), workspace: z.string().nullable().optional(), profile: z.string().nullable().optional(),
|
|
305
364
|
explicit_model_pick: z.boolean().optional(), attachments: z.array(z.union([AttachmentSchema, z.string()])).optional(), moa_config: z.boolean().optional(), regenerate: z.boolean().optional(), regeneration_revision: z.string().optional(),
|
|
365
|
+
voice_turn: z.boolean().optional(),
|
|
366
|
+
/** TAL-818: this client renders `connect_card`, so a `manage_connections` call waits on the card; without it the Agent answers with plain links. */
|
|
367
|
+
connect_card: z.boolean().optional(),
|
|
368
|
+
/** The starting client renders the masked `skill_secret` prompt; omitted by older and native clients. */
|
|
369
|
+
skill_secret: z.boolean().optional(),
|
|
306
370
|
});
|
|
307
371
|
/** Accepted turn. `stream_id` is the owner identity for the SSE connection. */
|
|
308
372
|
export const ChatStartResponseSchema = z.looseObject({
|
|
373
|
+
owner_attachment: OwnerAttachmentSchema.optional(), admission_id: z.string().optional(),
|
|
309
374
|
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(),
|
|
310
375
|
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(),
|
|
311
376
|
});
|
|
@@ -330,14 +395,15 @@ export const SteerWithdrawRequestSchema = z.object({ session_id: SessionIdSchema
|
|
|
330
395
|
/** `withdrawn: false` when the steer is unknown, already taken by the Agent (it then settles as consumed), or being sent. */
|
|
331
396
|
export const SteerWithdrawResponseSchema = z.object({ withdrawn: z.boolean(), text: z.string().optional() });
|
|
332
397
|
export const SteerSendNowRequestSchema = z.object({ session_id: SessionIdSchema, steer_id: z.string().min(1) });
|
|
333
|
-
/**
|
|
334
|
-
export const SteerSendNowResponseSchema = z.object({ redirected: z.boolean() });
|
|
398
|
+
/** The server decides why Send now did or did not deliver. `redirected` remains for older clients. */
|
|
399
|
+
export const SteerSendNowResponseSchema = z.object({ redirected: z.boolean(), outcome: z.enum(['delivered', 'next_step', 'not_running', 'taken', 'failed']) });
|
|
335
400
|
/** `text` is delivered to the running agent; `display_text` is what the transcript shows. */
|
|
336
401
|
export const SteerRequestSchema = z.looseObject({ session_id: SessionIdSchema, text: z.string().min(1), display_text: z.string().optional(), steer_id: z.string().optional() });
|
|
337
402
|
/** `accepted: false` with a `fallback` reason means the message was not delivered; the caller keeps the draft. */
|
|
338
403
|
/** TAL-460: a steer sent while a background turn runs starts the user's own turn instead; `started_turn` is its start response. */
|
|
339
404
|
export const SteerResponseSchema = z.looseObject({ accepted: z.boolean(), fallback: NullableString.optional(), stream_id: NullableString.optional(), steer_id: z.string().optional(), started_turn: ChatStartResponseSchema.optional() });
|
|
340
405
|
export const ApprovalPendingSchema = z.looseObject({
|
|
406
|
+
allowed_choices: z.array(z.enum(['once', 'session', 'always', 'deny'])).optional(), can_enable_yolo: z.boolean().optional(),
|
|
341
407
|
approval_id: z.string().optional(), session_id: z.string().optional(), command: z.string().optional(), description: z.string().optional(), title: z.string().optional(), name: z.string().optional(), kind: z.string().optional(),
|
|
342
408
|
reason: z.string().optional(), action: z.string().optional(), question: z.string().optional(), status: z.string().optional(), pending_count: z.number().optional(), run_id: z.string().optional(), mirror_token: z.string().optional(),
|
|
343
409
|
});
|
|
@@ -350,14 +416,34 @@ export const ClarifyChoiceSchema = z.union([z.string(), z.looseObject({ label: z
|
|
|
350
416
|
export const ClarifyStepSchema = z.looseObject({ qid: z.string(), question: z.string(), choices: z.array(z.string()), multi_select: z.boolean() });
|
|
351
417
|
/** Keyed step answers; a multi-select step takes a list. The server shapes them into the Agent's reply. */
|
|
352
418
|
export const ClarifyAnswersSchema = z.record(z.string(), z.union([z.string(), z.array(z.string())]));
|
|
419
|
+
/** TAL-887: one input of a password-manager prompt, answered under its `key`; a `secure` input is masked. */
|
|
420
|
+
export const VaultPromptFieldSchema = z.object({ key: z.enum(['master_password', 'identifier', 'password', 'code', 'secret']), secure: z.boolean() });
|
|
421
|
+
/**
|
|
422
|
+
* TAL-887: the Agent asks for a password manager's master password (`vault_unlock`), a login to save for the page it is
|
|
423
|
+
* on (`vault_save_login`), a one-time code (`vault_code`), or a skill environment secret (`skill_secret`). Clients answer through
|
|
424
|
+
* `/api/clarify/respond` with keyed `answers`, or `decline`; an empty answer, a decline, a cancel and `timeout_at` all
|
|
425
|
+
* resolve it unanswered. Answers never enter chat, logs, streams, or responses. Skill secrets are saved only to the invoking profile.
|
|
426
|
+
*/
|
|
427
|
+
export const VaultPromptSchema = z.object({
|
|
428
|
+
kind: z.enum(['vault_unlock', 'vault_save_login', 'vault_code', 'skill_secret']),
|
|
429
|
+
backend: z.string().nullable().describe('The password manager (`vault_unlock`).'),
|
|
430
|
+
display_name: z.string().nullable().describe('Its display name (`vault_unlock`).'),
|
|
431
|
+
origin: z.string().nullable().describe('The page origin the login is saved for (`vault_save_login`).'),
|
|
432
|
+
site: z.string().nullable().describe('The site, by host (`vault_save_login`, `vault_code`).'),
|
|
433
|
+
hint: z.string().nullable().describe('Where the code was sent, when the Agent says (`vault_code`).'),
|
|
434
|
+
skill: z.object({ env_var: z.string(), skill_name: z.string(), help: z.string().nullable(), required_for: z.string().nullable() }).optional().describe('Profile-local environment setup metadata (`skill_secret`).'),
|
|
435
|
+
fields: z.array(VaultPromptFieldSchema),
|
|
436
|
+
timeout_at: z.number().describe('Unix seconds when the Agent stops waiting.'),
|
|
437
|
+
});
|
|
353
438
|
export const ClarifyPendingSchema = z.looseObject({
|
|
354
439
|
steps: z.array(ClarifyStepSchema).optional(),
|
|
440
|
+
vault: VaultPromptSchema.optional(),
|
|
355
441
|
clarify_id: z.string().optional(), session_id: z.string().optional(), question: z.string().optional(), description: z.string().optional(), choices: z.array(ClarifyChoiceSchema).optional(), title: z.string().optional(),
|
|
356
442
|
name: z.string().optional(), kind: z.string().optional(), reason: z.string().optional(), action: z.string().optional(), status: z.string().optional(), raw_preview: z.string().optional(), timeout_at: z.number().optional(),
|
|
357
443
|
timeout_seconds: z.number().optional(), pending_count: z.number().optional(), index: z.number().optional(), total: z.number().optional(),
|
|
358
444
|
});
|
|
359
445
|
export const ClarifyPendingEnvelopeSchema = z.looseObject({ pending: ClarifyPendingSchema.nullable(), pending_count: z.number().int() });
|
|
360
|
-
export const ClarifyRespondRequestSchema = z.looseObject({ session_id: SessionIdSchema, answers: ClarifyAnswersSchema.optional(), response: z.string().optional(), answer: z.string().optional(), choice: z.string().optional(), clarify_id: z.string().optional() });
|
|
446
|
+
export const ClarifyRespondRequestSchema = z.looseObject({ session_id: SessionIdSchema, answers: ClarifyAnswersSchema.optional(), response: z.string().optional(), answer: z.string().optional(), choice: z.string().optional(), clarify_id: z.string().optional(), decline: z.boolean().optional() });
|
|
361
447
|
export const ClarifyRespondResponseSchema = z.looseObject({ ok: z.boolean(), response: z.string().optional(), error: z.string().optional(), stale: z.boolean().optional() });
|
|
362
448
|
export const DraftSchema = z.looseObject({ text: z.string(), files: z.array(Json) });
|
|
363
449
|
export const DraftResponseSchema = z.looseObject({ ok: z.literal(true), draft: DraftSchema, draft_version: z.string().nullable(), unchanged: z.boolean().optional() });
|
|
@@ -410,7 +496,15 @@ export const SessionNewRequestSchema = z.looseObject({
|
|
|
410
496
|
title: z.string().optional(), workspace: z.string().optional(), workspace_inherited_from_prev_session: z.boolean().optional(), model: z.string().nullable().optional(), model_provider: z.string().nullable().optional(),
|
|
411
497
|
profile: z.string().nullable().optional(), prev_session_id: z.string().optional(), project_id: z.string().nullable().optional(), worktree: Json.optional(), enabled_toolsets: z.array(z.string()).nullable().optional(), parent_session_id: z.string().optional(),
|
|
412
498
|
});
|
|
413
|
-
|
|
499
|
+
/**
|
|
500
|
+
* `streaming` (TAL-802): live dictation over `TRANSCRIBE_STREAM_PATH` would open for this profile (`stt.streaming` on, a live provider wire).
|
|
501
|
+
* `warm_supported` (TAL-916): a client starting a recording should `POST /api/transcribe/warm` so the engine loads while the user speaks.
|
|
502
|
+
*/
|
|
503
|
+
export const TranscribeCapabilitySchema = z.looseObject({ ok: z.literal(true), available: z.boolean(), provider: z.string(), streaming: z.boolean(), warm_supported: z.boolean() });
|
|
504
|
+
/** TAL-906: what read-aloud speaks for a message; clients play it as is. */
|
|
505
|
+
export const SpeechPrepareSchema = z.object({ spoken_text: z.string() });
|
|
506
|
+
/** `POST /api/transcribe`: the recording's transcript; `filtered` (TAL-917) when the server emptied a phrase Whisper invents on silent audio. */
|
|
507
|
+
export const TranscribeResponseSchema = z.looseObject({ ok: z.literal(true), transcript: z.string(), filtered: z.boolean() });
|
|
414
508
|
// ── settings, profiles, models, providers ───────────────────────────────
|
|
415
509
|
/** TAL-411: the request profile's quota urgency thresholds. A save patches valid fields and clamps critical to at most warning. */
|
|
416
510
|
export const QuotaThresholdsSchema = z.object({
|
|
@@ -422,7 +516,7 @@ export const SettingsSchema = z.looseObject({
|
|
|
422
516
|
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(),
|
|
423
517
|
full_width_chat: z.boolean().optional(), chat_width: z.enum(['comfortable', 'wide', 'full']).optional(), auto_scroll_follow: z.boolean().optional(), render_user_markdown: z.boolean().optional(), chat_activity_display_mode: z.string().optional(), default_message_mode: z.string().optional(),
|
|
424
518
|
fade_text_effect: z.boolean().optional(), hidden_tabs: z.array(z.string()).optional(), composer_control_order: z.array(z.string()).optional(), show_cli_sessions: z.boolean().optional(), show_claude_code_sessions: z.boolean().optional(),
|
|
425
|
-
show_cron_sessions: z.boolean().optional(), show_webhook_sessions: z.boolean().optional(), show_kanban_sessions: z.boolean().optional(), check_for_updates: z.boolean().optional(), ignore_agent_updates: z.boolean().optional(),
|
|
519
|
+
show_cron_sessions: z.boolean().optional(), show_webhook_sessions: z.boolean().optional(), show_kanban_sessions: z.boolean().optional(), check_for_updates: z.boolean().optional(), summarize_updates_automatically: z.boolean().optional(), ignore_agent_updates: z.boolean().optional(),
|
|
426
520
|
auth_enabled: z.boolean().optional(), password_auth_enabled: z.boolean().optional(), password_env_var: z.boolean().optional(), passkeys_enabled: z.boolean().optional(), passwordless_enabled: z.boolean().optional(),
|
|
427
521
|
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(),
|
|
428
522
|
max_tokens: NullableNumber.optional(), max_tokens_effective: NullableNumber.optional(), max_tokens_fallback: NullableNumber.optional(), tts_engine: z.string().optional(), tts_voice: z.string().optional(),
|
|
@@ -434,20 +528,47 @@ export const SettingsSchema = z.looseObject({
|
|
|
434
528
|
export const ProfileSchema = z.looseObject({
|
|
435
529
|
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(),
|
|
436
530
|
total_skills: z.number().optional(), enabled_skills: z.number().optional(), gateway_running: z.boolean().optional(), has_env: z.boolean().optional(), visible: z.boolean().optional(),
|
|
531
|
+
/** TAL-805: the profile's gateway mode; `gateway_running` is true exactly for `own` and `served`. */
|
|
532
|
+
gateway_mode: GatewayModeSchema.optional(),
|
|
437
533
|
/** 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
534
|
display_name: z.string().optional(), description: z.string().optional(), has_avatar: z.boolean().optional(),
|
|
439
535
|
/** TAL-213: present only when the profile has a canonical Bot Chat; clients open `tip_session_id` after switching to the profile. */
|
|
440
536
|
canonical_session: CanonicalBotChatSchema.nullable().optional(),
|
|
537
|
+
/** TAL-819: skill and memory writes the Agent staged for approval, reviewed on the Skills and Memory pages. */
|
|
538
|
+
pending_writes: z.number().int().optional(),
|
|
441
539
|
});
|
|
442
540
|
export const ProfilesSchema = z.looseObject({ profiles: z.array(ProfileSchema), active: z.string(), single_profile_mode: z.boolean().optional() });
|
|
443
541
|
export const ActiveProfileSchema = z.looseObject({ name: z.string(), path: z.string().optional(), is_default: z.boolean().optional(), default_workspace: NullableString.optional() });
|
|
444
542
|
export const ProfileSwitchSchema = ProfilesSchema.extend({ is_default: z.boolean(), default_model: Json, default_model_provider: Json, default_workspace: z.string().nullable() });
|
|
445
543
|
/** `/api/reasoning`: config.yaml agent.reasoning_effort / display.show_reasoning, resolved for a model. */
|
|
446
544
|
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() });
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
545
|
+
export const QuotaLevelSchema = z.enum(['healthy', 'warning', 'critical', 'stale', 'unavailable']);
|
|
546
|
+
/**
|
|
547
|
+
* 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.
|
|
548
|
+
* TAL-807: `limit` is present while the provider's credential pool cannot serve this model until `resets_at` (ISO-8601 UTC).
|
|
549
|
+
*/
|
|
550
|
+
export const ModelEntrySchema = z.looseObject({
|
|
551
|
+
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(), supported_speed_tiers: z.array(SpeedTierSchema).optional(),
|
|
552
|
+
limit: z.object({ scope: z.literal('model'), resets_at: z.string() }).optional(),
|
|
553
|
+
});
|
|
554
|
+
/** TAL-807: a group's rate limit: every pool account benched until `resets_at`, else the entry ids (`models`) cooling down until their reset. */
|
|
555
|
+
export const ModelGroupLimitSchema = z.discriminatedUnion('scope', [
|
|
556
|
+
z.object({ scope: z.literal('account'), resets_at: z.string() }),
|
|
557
|
+
z.object({ scope: z.literal('models'), models: z.record(z.string(), z.string()) }),
|
|
558
|
+
]);
|
|
559
|
+
/**
|
|
560
|
+
* TAL-807: `limit` is the provider's live pool rate limit; `quota_level` is the TAL-411 `remaining` level of the tightest
|
|
561
|
+
* account-scope window in the provider's last account-usage read (a model-family window never counts), absent without one
|
|
562
|
+
* and while the group is account-limited.
|
|
563
|
+
*/
|
|
564
|
+
export const CatalogAvailabilitySchema = z.object({ status: z.enum(['available', 'stale', 'unavailable']), authoritative: z.boolean(), unavailable_reason: NullableString, generation: z.string().min(1).describe('Opaque source generation; cached data from another generation must never be merged.') });
|
|
565
|
+
export const ModelGroupSchema = z.looseObject({
|
|
566
|
+
availability: CatalogAvailabilitySchema.optional(),
|
|
567
|
+
provider: z.string(), provider_id: z.string().optional(), models: z.array(ModelEntrySchema), extra_models: z.array(ModelEntrySchema).optional(),
|
|
568
|
+
limit: ModelGroupLimitSchema.optional(), quota_level: QuotaLevelSchema.optional(),
|
|
569
|
+
});
|
|
570
|
+
export const ModelsSchema = z.looseObject({ availability: CatalogAvailabilitySchema.optional(), 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() });
|
|
571
|
+
export const ModelsLiveSchema = z.looseObject({ availability: CatalogAvailabilitySchema.optional(), provider: z.string().optional(), source: z.string().optional(), models: z.array(ModelEntrySchema), count: z.number().optional(), error: z.string().optional() });
|
|
451
572
|
/** TAL-603: where a card's credential comes from; `other` is a source the server cannot name, shown as its raw `key_source`. */
|
|
452
573
|
export const KeySourceKindSchema = z.enum(['env', 'oauth', 'config', 'pool', 'plugin', 'other']);
|
|
453
574
|
/**
|
|
@@ -461,8 +582,7 @@ export const ProviderSchema = z.looseObject({
|
|
|
461
582
|
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
583
|
is_active: z.boolean().optional(), key_source_kind: KeySourceKindSchema.nullable().optional(), removable: z.boolean().optional(),
|
|
463
584
|
});
|
|
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']);
|
|
585
|
+
export const ProvidersSchema = z.looseObject({ availability: CatalogAvailabilitySchema.optional(), providers: z.array(ProviderSchema), active_provider: NullableString.optional() });
|
|
466
586
|
/** TAL-411: the server's classification per colour basis; `/api/provider/quotas` only, at the profile's thresholds. */
|
|
467
587
|
export const QuotaUrgencySchema = z.looseObject({ remaining: QuotaLevelSchema, pace: QuotaLevelSchema.describe('Burn rate and pace tolerance; the remaining classification when the window has no pace.') });
|
|
468
588
|
/** TAL-409: a window's pace as of the envelope's `computed_at`. Stale once `valid_until` (the window's reset) passes. */
|
|
@@ -487,6 +607,7 @@ export const QuotaWindowSchema = z.looseObject({
|
|
|
487
607
|
});
|
|
488
608
|
const QuotaWindowIndex = z.number().int().nullable().optional();
|
|
489
609
|
export const QuotaSourceSchema = z.looseObject({
|
|
610
|
+
computed_at: z.string().optional().describe('Original reference time of this source, retained with stale windows.'),
|
|
490
611
|
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(),
|
|
491
612
|
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(),
|
|
492
613
|
pace_window_index: QuotaWindowIndex.describe('The window a pace-coloured widget shows: the weekly one, else the first 5h/session window.'),
|
|
@@ -507,8 +628,8 @@ export const ProviderQuotaSchema = z.looseObject({
|
|
|
507
628
|
account_limits: QuotaAccountLimitsSchema.nullable().optional(),
|
|
508
629
|
});
|
|
509
630
|
/** Python `get_provider_quotas`: the stable identity envelope the iOS quota widget persists (`scope_id`/`profile_id`). */
|
|
510
|
-
export const ProviderQuotasSchema = z.looseObject({
|
|
511
|
-
version: z.number(), computed_at: z.string().describe('ISO-8601 UTC reference time
|
|
631
|
+
export const ProviderQuotasSchema = z.looseObject({ availability: CatalogAvailabilitySchema.optional(),
|
|
632
|
+
version: z.number(), computed_at: z.string().describe('ISO-8601 UTC request reference time; coalesced or stale sources retain their own computed_at.'), scope_id: z.string(), profile_id: z.string(), active_provider: NullableString, requested_source_id: NullableString,
|
|
512
633
|
missing_source: z.boolean().describe('True when `?source=` names a source id this scope no longer has; `sources` is then empty.'),
|
|
513
634
|
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.'),
|
|
514
635
|
});
|
|
@@ -543,8 +664,12 @@ export const AuxiliaryTaskSchema = z.looseObject({
|
|
|
543
664
|
selected_option_id: z.string().nullable(),
|
|
544
665
|
/** False only for a pinned model the current catalog does not list; it stays visible and editable. */
|
|
545
666
|
in_catalog: z.boolean(),
|
|
667
|
+
/** TAL-800: the slot a plugin task inherits its route from; while the task is Auto, `value_label` names that slot's model. */
|
|
668
|
+
inherit_from: z.string().nullable(),
|
|
669
|
+
/** TAL-800: the reasoning effort the slot runs with (the Agent's default until one is saved; `''` = provider default); null when the Agent does not report its slots. */
|
|
670
|
+
reasoning_effort: z.string().nullable(),
|
|
546
671
|
});
|
|
547
|
-
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) });
|
|
672
|
+
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(), service_tier: z.enum(['', 'default', 'priority', 'ultrafast']).optional().describe('Empty string is the Standard value returned by older servers.'), supported_speed_tiers: z.array(SpeedTierSchema).optional() }), tasks: z.array(AuxiliaryTaskSchema) });
|
|
548
673
|
export const MaxTokensSchema = z.looseObject({ max_tokens: NullableNumber, max_tokens_effective: NullableNumber, max_tokens_fallback: NullableNumber });
|
|
549
674
|
// ── workspaces, files, git ───────────────────────────────────────────────
|
|
550
675
|
/** 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). */
|
|
@@ -567,18 +692,20 @@ export const FileContentSchema = z.looseObject({
|
|
|
567
692
|
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
693
|
export const GitInfoSchema = z.looseObject({ git: GitBadgeSchema.nullable().optional() });
|
|
569
694
|
// ── tools ────────────────────────────────────────────────────────────────
|
|
570
|
-
export const SkillSchema = z.looseObject({ name: z.string(), description: NullableString.optional(), category: NullableString.optional(), disabled: z.boolean().optional() });
|
|
695
|
+
export const SkillSchema = z.looseObject({ ...SkillCatalogIdentitySchema.shape, name: z.string(), description: NullableString.optional(), category: NullableString.optional(), disabled: z.boolean().optional() });
|
|
571
696
|
export const SkillsSchema = z.looseObject({ skills: z.array(SkillSchema), categories: z.array(Json).optional() });
|
|
572
697
|
/**
|
|
573
698
|
* `linked_files` groups the skill directory's files by folder (`references`, `templates`, ...); open one with `?file=`.
|
|
574
699
|
* A linked file that is not UTF-8 text carries `binary: true` and its `size` instead of `content`.
|
|
575
700
|
*/
|
|
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() });
|
|
701
|
+
export const SkillContentSchema = z.looseObject({ editable: z.boolean().optional(), 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() });
|
|
577
702
|
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() });
|
|
578
703
|
export const MemorySchema = z.looseObject({
|
|
579
704
|
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(),
|
|
580
705
|
project_context_name: z.string().optional(), project_context_workspace: z.string().optional(), memory_mtime: NullableNumber.optional(), user_mtime: NullableNumber.optional(), soul_mtime: NullableNumber.optional(), project_context_mtime: NullableNumber.optional(),
|
|
581
706
|
project_context_shadowed: z.array(Json).optional(), external_notes_enabled: z.boolean().optional(),
|
|
707
|
+
/** TAL-784: the revision of each file as this read found it. A save sends the revision its edit started from. */
|
|
708
|
+
memory_revision: z.string(), user_revision: z.string(), soul_revision: z.string(),
|
|
582
709
|
});
|
|
583
710
|
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() });
|
|
584
711
|
export const PromptsSchema = z.looseObject({ prompts: z.array(PromptSchema) });
|
|
@@ -588,12 +715,15 @@ export const PromptsSchema = z.looseObject({ prompts: z.array(PromptSchema) });
|
|
|
588
715
|
* clients can run it, and `unsupported_message` is the English text a client outside `clients` shows when it is typed.
|
|
589
716
|
* Clients suggest the entries listing them whose name or any alias starts with the typed text (case-insensitive), and
|
|
590
717
|
* 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
|
|
718
|
+
* posts the typed text there with the open chat's `session_id` and shows the returned output instead of starting a chat turn
|
|
719
|
+
* (TAL-561); `/refine` reviews that chat (TAL-902).
|
|
720
|
+
* `handler: 'prompt'` marks an Agent prompt built-in: the client sends the typed text as a chat turn and the server starts the
|
|
721
|
+
* turn with the Agent's expansion of it (TAL-817).
|
|
592
722
|
*/
|
|
593
723
|
export const CommandClientSchema = z.enum(['web', 'ios']);
|
|
594
724
|
export const CommandRowSchema = z.looseObject({
|
|
595
725
|
name: z.string(), description: z.string().optional(), aliases: z.array(z.string()), args_hint: z.string().optional(), category: z.string().optional(),
|
|
596
|
-
handler: z.enum(['client', 'agent']), clients: z.array(CommandClientSchema), unsupported_message: z.string().optional(),
|
|
726
|
+
handler: z.enum(['client', 'agent', 'prompt']), clients: z.array(CommandClientSchema), unsupported_message: z.string().optional(),
|
|
597
727
|
cli_only: z.boolean().optional(), gateway_only: z.boolean().optional(), subcommands: z.array(Json).optional(), exec: z.boolean().optional(),
|
|
598
728
|
});
|
|
599
729
|
export const CommandsSchema = z.looseObject({ commands: z.array(CommandRowSchema) });
|
|
@@ -609,9 +739,11 @@ export const DashboardStatusSchema = z.looseObject({ running: z.boolean(), enabl
|
|
|
609
739
|
* Gateway status for the Settings banner (TAL-266). `running` and `configured` come from the Agent health probe; when it
|
|
610
740
|
* is inconclusive, stale running metadata or known gateway sessions mark the gateway configured. `platforms` are the
|
|
611
741
|
* messaging platforms of known gateway sessions; `last_active` is the gateway session index's ISO mtime while running, else "".
|
|
742
|
+
* TAL-805: `gateway_mode` is the active profile's mode and decides `running` when it is not null. It is null for a remote
|
|
743
|
+
* gateway, or for the root profile when the sidecar cannot answer; a named profile whose mode is unconfirmed reads `stopped`.
|
|
612
744
|
*/
|
|
613
745
|
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(),
|
|
746
|
+
running: z.boolean(), configured: z.boolean(), gateway_mode: GatewayModeSchema.nullable(), platforms: z.array(z.object({ name: z.string(), label: z.string() })), last_active: z.string(), session_count: z.number().int(),
|
|
615
747
|
health: z.object({ state: NullableString, reason: NullableString, gateway_state: NullableString }),
|
|
616
748
|
});
|
|
617
749
|
export const GatewayActionSchema = z.object({ ok: z.literal(true), action: z.enum(['start', 'stop', 'restart']), message: z.string(), status: GatewayStatusSchema });
|
|
@@ -627,21 +759,55 @@ export const ProjectOsDashboardSchema = z.object({
|
|
|
627
759
|
handoff: z.record(z.string(), Json).nullable(), active: z.record(z.string(), Json).nullable(), heartbeat: z.record(z.string(), Json).nullable(),
|
|
628
760
|
onboarding: z.looseObject({ active: z.boolean(), doc_source: z.enum(['project-os', 'root']) }).optional(), goal_summary: z.string(),
|
|
629
761
|
});
|
|
630
|
-
|
|
762
|
+
/** One server projection used by chat readiness, HTTP refusals, and persisted stream errors. */
|
|
763
|
+
export const AgentRuntimeMetadataSchema = z.object({
|
|
764
|
+
agent_runtime_reason: z.enum(['update_active', 'recovery_incomplete', 'source_changed', 'unknown']).optional(),
|
|
765
|
+
agent_update_state: z.string().optional(),
|
|
766
|
+
retryable: z.boolean().optional(),
|
|
767
|
+
restart_scheduled: z.boolean().optional(),
|
|
768
|
+
});
|
|
769
|
+
/** TAL-951: whether Web chat can run, from the Agent sidecar's status; `condition` says why not, null when available. */
|
|
770
|
+
export const ChatReadinessSchema = z.discriminatedUnion('available', [
|
|
771
|
+
z.object({ available: z.literal(true), condition: z.null() }),
|
|
772
|
+
z.object({ available: z.literal(false), condition: z.enum(['sidecar_unavailable', 'agent_incompatible', 'agent_runtime_stale']), ...AgentRuntimeMetadataSchema.shape }),
|
|
773
|
+
]);
|
|
774
|
+
/** Messaging-gateway liveness (`alive`, `details`, `gateway_chat`) for Settings → System, plus Web chat readiness in `chat`. */
|
|
775
|
+
export const AgentHealthSchema = z.looseObject({ chat: ChatReadinessSchema.optional().describe('Always sent since TAL-951; absent from older servers.'), 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() });
|
|
631
776
|
export const SystemHealthSchema = z.looseObject({
|
|
632
777
|
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(),
|
|
633
778
|
errors: z.array(z.looseObject({ code: z.string().optional(), metric: z.string().optional() })).optional(), webui_runtime: Json.optional(),
|
|
634
779
|
});
|
|
635
780
|
export const UpdateStateSchema = z.enum(['up_to_date', 'release_ready', 'commits_behind', 'local_changes', 'finish', 'manual', 'check_failed', 'off', 'unknown']);
|
|
636
|
-
|
|
781
|
+
const AgentSupportSchema = z.enum(['supported', 'unchecked']);
|
|
782
|
+
export const UpdateVersionSchema = z.object({
|
|
783
|
+
version: z.string().describe('The release as shown: the Agent tag or the Web release tag.'),
|
|
784
|
+
ref: z.string().describe('What `updates.apply`/`updates.force` accept back as `version`: the Agent tag or the Web semver.'),
|
|
785
|
+
sha: z.string().optional().describe('Agent only: the commit the tag peels to.'),
|
|
786
|
+
release_url: z.string().nullable(),
|
|
787
|
+
latest: z.boolean().describe('The channel\'s newest release, the one an update without `version` installs.'),
|
|
788
|
+
folded: z.boolean().describe('Shown behind the folded "more versions" node: every entry except the newest.'),
|
|
789
|
+
support: AgentSupportSchema.optional().describe('Agent only: this release\'s classification against the verified Agent window.'),
|
|
790
|
+
support_label: z.string().optional().describe('Agent only: `support` worded to fit one phone line.'),
|
|
791
|
+
}).describe('TAL-946: one installable Stable release newer than the installed one.');
|
|
792
|
+
export const UpdateTargetSchema = z.looseObject({
|
|
793
|
+
failed_update: z.object({ version: z.string(), restored_version: z.string() }).optional().describe('Web only: the update that failed before HTTP readiness and the restored package version. Manual retry remains available.'),
|
|
794
|
+
name: z.string().optional(), channel: z.enum(['stable', 'experimental']).optional(),
|
|
795
|
+
unsupported: z.boolean().optional().describe('Deprecated (TAL-350): `support === \'unchecked\'`, kept for older clients.'),
|
|
796
|
+
support: AgentSupportSchema.optional().describe('Agent target only (TAL-350): `supported` when the target revision is exactly a release in the verified Agent window, else `unchecked`; an `unchecked` apply requires `confirmed_agent_revision`.'),
|
|
797
|
+
support_label: z.string().optional().describe('Agent target only (TAL-946): `support` worded to fit one phone line.'),
|
|
798
|
+
current_support: AgentSupportSchema.optional().describe('Agent target only: the same classification for the installed Agent revision.'),
|
|
799
|
+
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
800
|
state: UpdateStateSchema.describe('TAL-559: the status clients word; `off` when checks are disabled or Agent updates are ignored.'),
|
|
638
801
|
can_apply: z.boolean().describe('The apply action is available for this target.'),
|
|
639
802
|
installed_unverified: z.boolean().describe('`release_ready` only: the installed revision sits on no release tag.'),
|
|
640
803
|
manual_link: z.boolean().describe('Show the manual-install (releases) link.'),
|
|
641
804
|
target_version: z.string().nullable().describe('The version the update path leads to, when one is shown.'),
|
|
642
805
|
summary_available: z.boolean().describe('TAL-759: offer "Summarize with AI" for this target (`release_ready` or `commits_behind`).'),
|
|
806
|
+
versions: z.array(UpdateVersionSchema).describe('TAL-946: every installable Stable release newer than the installed one, newest first; empty unless `release_ready` can apply.'),
|
|
807
|
+
folded_count: z.number().int().nonnegative().describe('How many `versions` are `folded`.'),
|
|
643
808
|
});
|
|
644
|
-
export const
|
|
809
|
+
export const AgentRecoveryStateSchema = z.object({ phase: z.enum(['idle', 'running', 'waiting', 'complete', 'blocked']), attempt: z.number().int().nonnegative(), detail: z.string(), retry_at: z.string().nullable() });
|
|
810
|
+
export const UpdatesCheckSchema = z.looseObject({ agent_recovery: AgentRecoveryStateSchema.optional(), 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() });
|
|
645
811
|
export const UpdatesSummarySchema = z.object({
|
|
646
812
|
ok: z.boolean(), target: z.enum(['webui', 'agent']), summary: z.string(),
|
|
647
813
|
current_version: z.string().nullable().describe('The installed version this summary starts from.'),
|
|
@@ -651,8 +817,12 @@ export const UpdatesSummarySchema = z.object({
|
|
|
651
817
|
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
818
|
cached: z.boolean(),
|
|
653
819
|
});
|
|
654
|
-
export const UpdateApplySchema = z.looseObject({
|
|
655
|
-
|
|
820
|
+
export const UpdateApplySchema = z.looseObject({
|
|
821
|
+
recovery_compatibility: z.object({ manual_execution: z.boolean(), bot_chat_delivery: z.boolean() }).optional()
|
|
822
|
+
.describe('Whether the target Agent can reconcile retained manual execution and pending Bot Chat records. A false value blocks the update before any source or repair-intent change.'),
|
|
823
|
+
ok: z.boolean().optional(), status: z.string().optional(), error: z.string().optional(), message: z.string().optional(), lock: Json.optional(), confirmation_required: z.boolean().optional(), refresh_confirmation: AgentRefreshConfirmationSchema.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(), gateway_restart: z.string().optional().describe('TAL-953: `waiting_for_idle` when an Agent update left the gateway restart to wait for the gateway\'s running work; the update notification reports its outcome.')
|
|
824
|
+
});
|
|
825
|
+
export const UpdateNotificationPhaseSchema = z.enum(['applying', 'awaiting_confirmation', 'waiting_for_idle', 'restarting', 'succeeded', 'blocked', 'failed', 'unknown']);
|
|
656
826
|
export const UpdateNotificationActionSchema = z.object({
|
|
657
827
|
id: z.string().min(1).max(64).regex(/^[a-z0-9][a-z0-9_-]*$/),
|
|
658
828
|
label: z.string().min(1).max(80),
|
|
@@ -710,10 +880,58 @@ export const UpdateNotificationsSchema = z.object({
|
|
|
710
880
|
clearable_count: z.number().int().nonnegative(),
|
|
711
881
|
can_clear: z.boolean(),
|
|
712
882
|
});
|
|
713
|
-
|
|
714
|
-
export const
|
|
883
|
+
/** TAL-806: a plugin setting as Settings shows it; `locked` marks a secret the server's launch environment supplies, so an edit would not take effect. */
|
|
884
|
+
export const PluginSettingViewSchema = PluginSettingFieldSchema.extend({ locked: z.boolean().optional() });
|
|
885
|
+
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(),
|
|
886
|
+
/** TAL-806: the manifest's `config_schema` fields with current values; absent when the plugin declares none. */
|
|
887
|
+
settings: z.array(PluginSettingViewSchema).optional() });
|
|
888
|
+
/**
|
|
889
|
+
* `read_only` (TAL-806): this session may not save plugin `settings` (not the server owner, or no sidecar).
|
|
890
|
+
* `plugin_isolation_advisory` (TAL-820): more than one profile has third-party plugins installed and one of those runs them
|
|
891
|
+
* `in_process`, so Settings recommends `plugins.isolation: host`; Talaria never sets the mode.
|
|
892
|
+
*/
|
|
893
|
+
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(), plugin_isolation_advisory: z.boolean().optional() });
|
|
715
894
|
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() });
|
|
716
895
|
export const McpServersSchema = z.looseObject({ servers: z.array(McpServerSchema), health_pending: z.boolean().optional(), reload_required: z.boolean().optional(), toggle_supported: z.boolean().optional() });
|
|
896
|
+
/** TAL-818: one connected account of a Nous tool-gateway app; `name` is its alias, else the vendor label. `problem` is its gateway status while it is not active, else null. */
|
|
897
|
+
export const ConnectorAccountViewSchema = z.object({ connection_id: z.string(), name: z.string(), problem: z.enum(['pending', 'failed', 'expired', 'revoked', 'inactive']).nullable(), status_reason: z.string().nullable(), active: z.boolean(), created_at: z.string() });
|
|
898
|
+
/**
|
|
899
|
+
* TAL-818: one app on the Connectors page. `accounts` are its live accounts, active first. `enabled`: Hermes may use it (the
|
|
900
|
+
* member rule allows it and no other layer locks it). `org_locked` means an organization or role rule keeps it off whatever the member rule says. `rules_editable`: the switch
|
|
901
|
+
* may change the member rule (readable rules and no lock). `tools_off` counts the tools the member rules turn off.
|
|
902
|
+
*/
|
|
903
|
+
export const ConnectorViewSchema = z.object({
|
|
904
|
+
slug: z.string(), name: z.string(), description: z.string(), category: z.string(), logo_url: z.string().nullable(),
|
|
905
|
+
connected: z.boolean(), accounts: z.array(ConnectorAccountViewSchema), enabled: z.boolean(), org_locked: z.boolean(), rules_editable: z.boolean(), tools_off: z.number().int(),
|
|
906
|
+
});
|
|
907
|
+
/**
|
|
908
|
+
* TAL-818: the Connectors page. `available` is the Agent's connectors gate; false hides the page. `policy_revision` is the
|
|
909
|
+
* member rules' revision every rule change sends back; null when the rules are read-only (no member layer, or unreadable),
|
|
910
|
+
* so no switch changes them. `rules_error`: why the rules could not be read; every app then reads off (fails closed).
|
|
911
|
+
*/
|
|
912
|
+
export const ConnectorsPageSchema = z.object({ available: z.boolean(), connectors: z.array(ConnectorViewSchema), policy_revision: z.string().nullable(), rules_error: z.string().nullable() });
|
|
913
|
+
/**
|
|
914
|
+
* TAL-818: one app's tools: `enabled`: Hermes may use it (the member rules leave it on and nothing locks it); `locked`: an
|
|
915
|
+
* organization or role rule (by name or tag) keeps it off. `editable`: its switch may change the member rule (readable rules, the app on in them, and no lock).
|
|
916
|
+
*/
|
|
917
|
+
export const ConnectorToolsViewSchema = z.object({
|
|
918
|
+
connector: z.string(), policy_revision: z.string().nullable(),
|
|
919
|
+
tools: z.array(z.object({ slug: z.string(), name: z.string(), description: z.string(), facet: z.enum(['read', 'write', 'destructive', 'unclassified']), deprecated: z.boolean(), enabled: z.boolean(), locked: z.boolean(), editable: z.boolean() })),
|
|
920
|
+
});
|
|
921
|
+
/**
|
|
922
|
+
* TAL-818: a connection operation, from the Connectors page's Connect or a chat's `manage_connections` card. Each target's
|
|
923
|
+
* `connect_url` is the authorization link while it waits on one; `actions` are the moves the user may make on it now, and
|
|
924
|
+
* `env_fields` the credentials an `approve` sends, each with its `label`. `can_continue`: the card may end the wait for the
|
|
925
|
+
* rest (chat only). `outcome` is null while the operation is open, then `connected` when every target connected.
|
|
926
|
+
*/
|
|
927
|
+
export const ConnectorOperationViewSchema = z.object({
|
|
928
|
+
op_id: z.string(), settled: z.boolean(), outcome: z.enum(['connected', 'not_connected']).nullable(), can_continue: z.boolean(), tool_call_id: z.string().nullable(),
|
|
929
|
+
targets: z.array(z.object({
|
|
930
|
+
name: z.string(), title: z.string(), kind: z.string(), state: z.enum(['pending', 'initiated', 'connected', 'skipped', 'failed', 'expired', 'not_connected']),
|
|
931
|
+
detail: z.string(), connect_url: z.string().nullable(), actions: z.array(z.enum(['skip', 'retry', 'approve'])),
|
|
932
|
+
env_fields: z.array(z.object({ name: z.string(), label: z.string(), required: z.boolean(), secret: z.boolean() })),
|
|
933
|
+
})),
|
|
934
|
+
});
|
|
717
935
|
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() });
|
|
718
936
|
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
937
|
/** Joplin search hit: bounded, redacted display text and a snippet around the query; `updated_time` is Joplin's raw value. */
|
|
@@ -767,12 +985,17 @@ export const CronJobViewSchema = z.looseObject({
|
|
|
767
985
|
derived_state: CronDerivedStateSchema.optional(), needs_attention: z.boolean().optional(), resumable: z.boolean().optional(),
|
|
768
986
|
/** Server-derived (TAL-599): a known cause clients explain in the needs-attention banner. */
|
|
769
987
|
attention_hint: z.enum(['croniter_missing']).nullable(),
|
|
988
|
+
/** Server-normalized (TAL-810): the job's latest failed run, kept after later successes; `at` is epoch seconds, null when unparseable. */
|
|
989
|
+
last_failure: z.object({ at: z.number().nullable(), detail: z.string() }).nullable(),
|
|
770
990
|
});
|
|
991
|
+
/** TAL-810: a listed profile's cron store whose writes fail (full disk, read-only mount, permissions), so its scheduler skips every run. `error` and `fix` are the Agent's text; `since` is the last write that landed (epoch seconds), null when unknown. */
|
|
992
|
+
export const CronStoreHealthSchema = z.object({ profile: z.string(), store: z.string(), error: z.string(), fix: z.string(), since: z.number().nullable() });
|
|
771
993
|
export const CronsSchema = z.looseObject({
|
|
772
994
|
jobs: z.array(CronJobViewSchema),
|
|
773
995
|
/** 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
996
|
ordered: z.boolean().optional(),
|
|
775
997
|
active_profile: z.string().optional(), all_profiles: z.boolean().optional(), other_profile_count: z.number().optional(), cron_unavailable: z.boolean().optional(),
|
|
998
|
+
unwritable_stores: z.array(CronStoreHealthSchema),
|
|
776
999
|
});
|
|
777
1000
|
export const CronContextSourcesSchema = z.object({ profile: z.string(), sources: z.array(z.object({ job_id: z.string(), label: z.string(), selectable: z.boolean() })) });
|
|
778
1001
|
/** `GET /api/crons/recent` row: one job's latest completion, ordered and classified by the server. */
|
|
@@ -793,18 +1016,21 @@ export const KanbanTaskActionsSchema = z.object({ block: z.boolean(), unblock: z
|
|
|
793
1016
|
/** 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
1017
|
export const KanbanTaskPolicyShape = { available_actions: KanbanTaskActionsSchema, requires_running_exit_confirmation: z.boolean() };
|
|
795
1018
|
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 });
|
|
796
|
-
|
|
1019
|
+
/** A board column in the Agent workflow's order (TAL-796): `name` is the status key, `label` the Agent's English label. */
|
|
1020
|
+
export const KanbanColumnSchema = z.looseObject({ name: z.string(), label: z.string(), tasks: z.array(KanbanTaskViewSchema) });
|
|
797
1021
|
/** One profile lane (TAL-567): an assignee's tasks (`null` = unassigned) across every board column, with its task count. */
|
|
798
1022
|
export const KanbanLaneSchema = z.object({ assignee: z.string().nullable(), count: z.number().int(), columns: z.array(KanbanColumnSchema) });
|
|
799
1023
|
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
1024
|
/** Statuses a bulk status change may target (TAL-557). */
|
|
801
1025
|
bulk_move_targets: z.array(z.string()),
|
|
1026
|
+
/** Statuses a new task may start in (TAL-796). */
|
|
1027
|
+
create_statuses: z.array(z.string()),
|
|
802
1028
|
/** The saved board view (TAL-567): `true` groups the board into `lanes` by assignee. */
|
|
803
1029
|
lane_by_profile: z.boolean(),
|
|
804
1030
|
/** Present when `lane_by_profile`: the columns split into profile lanes, assignees in name order, unassigned last. */
|
|
805
1031
|
lanes: z.array(KanbanLaneSchema).optional() });
|
|
806
1032
|
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
|
|
1033
|
+
/** Whether the board can be archived or deleted; the default board (TAL-567) and an archived board (TAL-795) cannot. */
|
|
808
1034
|
removable: z.boolean() })), current: z.string().optional(), read_only: z.boolean().optional() });
|
|
809
1035
|
/** Board-wide task counts (TAL-567): `status_counts` in board-column order, unknown statuses after; `total` excludes archived tasks. */
|
|
810
1036
|
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() })) });
|