@prismshadow/penguin-server 0.2.3 → 0.2.5

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.
@@ -1,5 +1,6 @@
1
1
  import { OmniMessage, ToolCallPayload, CompactionMode } from '@prismshadow/penguin-core/omnimessage';
2
2
  import { ThinkingLevelName, ToolDefinitionConfig, MCPServerConfig } from '@prismshadow/penguin-core/interfaces';
3
+ import { VersionReport } from '@prismshadow/penguin-core';
3
4
 
4
5
  /**
5
6
  * Web API DTO contract — request/response types shared between server routes and the
@@ -69,9 +70,10 @@ interface MeResponse {
69
70
  * How THIS session was established. Distinct from desktopMode: a browser signed into a
70
71
  * desktop-mode server holds a "password" session and must still provide the old
71
72
  * password when changing it — only "desktop" sessions (opened by the shell's one-shot
72
- * token) may omit it.
73
+ * token) may omit it. "token" marks a request authenticated by the local API token's
74
+ * Bearer header (the CLI and agent-driven calls).
73
75
  */
74
- sessionVia: "password" | "desktop";
76
+ sessionVia: "password" | "desktop" | "token";
75
77
  /**
76
78
  * The upload limits currently in force, so the composer can refuse an oversize pick before
77
79
  * reading it and can name the real number in the message. They are admin-settable and ride
@@ -198,20 +200,33 @@ interface ServerSettingsUpdateRequest {
198
200
  */
199
201
  attachmentTotalMb?: number;
200
202
  }
203
+ /**
204
+ * One draft-screen shortcut: a prompt the user wrote, filed under a name they chose. Clicking it
205
+ * fills the composer exactly like a built-in example does, and sends nothing. Deliberately holds
206
+ * no Skill list — a saved prompt is not authored against a known Skill catalog the way a shipped
207
+ * example is, and the Agent it will run under is picked after the click.
208
+ */
209
+ interface DraftShortcut {
210
+ /** Stable client-generated id: what an edit or a delete addresses the row by. Unique per user. */
211
+ id: string;
212
+ title: string;
213
+ prompt: string;
214
+ }
201
215
  /** User UI preferences (SQLite ui_prefs, free-form JSON; known keys declared here). */
202
216
  interface UiPrefs {
203
217
  theme?: "light" | "dark";
204
218
  lastProjectId?: string;
205
219
  /** Whether the "no API key configured" guide has already been shown: once ever (on first visit to the chat page). */
206
220
  credentialGuideSeen?: boolean;
207
- /**
208
- * Also list CLI-created Sessions in the sidebar (`cli=1` on the sessions list). Default
209
- * off: the list then serves web rows straight from the DB, with no Trace-directory
210
- * scanning (#139).
211
- */
212
- showCliSessions?: boolean;
213
221
  /** The initial-password notice banner (app layout) was permanently dismissed by the user. */
214
222
  initialPasswordBannerDismissed?: boolean;
223
+ /**
224
+ * The draft screen's user-defined shortcuts, in display order. Replaced whole on every write
225
+ * (the merge is shallow, so the array is one field like any other) and bounded on write by
226
+ * services/draft-shortcuts.ts — count, title length and prompt length — because this is the one
227
+ * known key holding user-authored text rather than a flag or an id.
228
+ */
229
+ draftShortcuts?: DraftShortcut[];
215
230
  [key: string]: unknown;
216
231
  }
217
232
  interface PrefsResponse {
@@ -319,6 +334,14 @@ interface ModelInfo {
319
334
  pricing?: ModelPricingDto;
320
335
  /** Environment variable name to fall back to when api_key is empty (e.g. ANTHROPIC_API_KEY); unset if no known fallback. */
321
336
  envKey?: string;
337
+ /**
338
+ * Masked preview (same rule as `credential.apiKeyMasked`) of the value the server process
339
+ * currently holds for `envKey` — the plaintext is never serialized. Reported only for
340
+ * first-party official entries (vendor group, catalog shape unmodified); gateway, custom
341
+ * and user-defined groups never carry it. Absent = the variable is unset or empty, or the
342
+ * entry is not first-party.
343
+ */
344
+ envKeyMasked?: string;
322
345
  credential?: CredentialInfo;
323
346
  isDefault: boolean;
324
347
  }
@@ -501,6 +524,29 @@ interface ModelProtocolDetectResponse {
501
524
  detected?: string;
502
525
  probes: ModelProtocolProbeDto[];
503
526
  }
527
+ /**
528
+ * Endpoint model listing (POST /api/projects/:p/models/list, owner): given a base URL and
529
+ * the protocol `/detect` reported, returns every model id the endpoint serves (AgentHub's
530
+ * `listModels()` on the routed client). Used by the add-group dialog to import a provider's
531
+ * whole listing in one go; the ids come back in the endpoint's own order.
532
+ */
533
+ interface EndpointModelListRequest {
534
+ /** Endpoint base URL (as typed in the add-group dialog). */
535
+ baseUrl: string;
536
+ /** AgentHub client type to speak (normally a detected generic protocol; whole-endpoint listings need one). */
537
+ clientType: string;
538
+ /** Newly entered API key (plaintext); omitted = the SDK's environment fallback for the protocol. */
539
+ apiKey?: string;
540
+ }
541
+ /** Listing outcome: model ids on success, a truncated provider/SDK reason otherwise. */
542
+ interface EndpointModelListResponse {
543
+ ok: boolean;
544
+ /** The model ids the endpoint serves, in the order the endpoint returned them (ok only). */
545
+ models?: string[];
546
+ /** The routed client has no models endpoint (AgentHub UnsupportedOperationError) — callers offer the manual path. */
547
+ unsupported?: boolean;
548
+ message?: string;
549
+ }
504
550
  /**
505
551
  * PUT /api/projects/:p/models/default (owner): narrow default-model switch — flips the same
506
552
  * top-level `default_model` the models page's whole-table PUT writes, without resending the
@@ -515,6 +561,53 @@ interface DefaultModelUpdateRequest {
515
561
  interface DefaultModelResponse {
516
562
  defaultModel: ModelRefDto;
517
563
  }
564
+ /**
565
+ * How the authorization code travels back. `callback` sends the browser to a harness URL
566
+ * the provider redirects to; `manual` asks the provider for a one-time code the user copies
567
+ * back by hand, for the case where that redirect cannot reach the harness.
568
+ */
569
+ type ModelOAuthMode = "callback" | "manual";
570
+ /**
571
+ * POST /api/projects/:p/model-oauth/start (owner): opens a flow for one provider group.
572
+ * The group must declare an authorization flow in the built-in catalog — the endpoints it
573
+ * uses come from there, never from this request.
574
+ */
575
+ interface ModelOAuthStartRequest {
576
+ /** Provider group id (must be a catalog group that publishes a key-minting flow). */
577
+ provider: string;
578
+ /** Defaults to `callback`. */
579
+ mode?: ModelOAuthMode;
580
+ }
581
+ /** The opaque flow handle plus the page to send the user to. No secret of the flow's is included. */
582
+ interface ModelOAuthStartResponse {
583
+ flowId: string;
584
+ authorizeUrl: string;
585
+ }
586
+ /** Why a flow failed, as a code the frontend phrases; never carries a code, a verifier or a key. */
587
+ type ModelOAuthErrorCode = "invalid_request" | "code_rejected" | "upstream_failed" | "unreachable" | "apply_failed";
588
+ /**
589
+ * GET /api/projects/:p/model-oauth/:flowId (owner): where a flow stands. Unknown, expired,
590
+ * and other users' flows are all 404 alike.
591
+ */
592
+ interface ModelOAuthStatusResponse {
593
+ status: "pending" | "done" | "error";
594
+ /** The provider group the flow mints a key for. */
595
+ provider: string;
596
+ error?: ModelOAuthErrorCode;
597
+ }
598
+ /**
599
+ * POST /api/projects/:p/model-oauth/:flowId/code (owner): redeems a code the user pasted,
600
+ * the manual counterpart of the redirect callback. A flow is single-use either way.
601
+ */
602
+ interface ModelOAuthCodeRequest {
603
+ code: string;
604
+ }
605
+ /** Redemption outcome; `applied` counts the models the minted key was written to. */
606
+ interface ModelOAuthCodeResponse {
607
+ ok: boolean;
608
+ applied?: number;
609
+ error?: ModelOAuthErrorCode;
610
+ }
518
611
  /**
519
612
  * Per-Project new-chat defaults: prefill for the chat draft page. Every key is optional —
520
613
  * an absent key means "not set" (the pre-existing behavior). Serves as the GET response,
@@ -537,6 +630,36 @@ interface ChatDefaultsDto {
537
630
  */
538
631
  thinkingLevel?: Exclude<ThinkingLevelName, "none">;
539
632
  }
633
+ /**
634
+ * One deny rule of the sandbox command policy — plain project-editable data. The factory
635
+ * rules are seeded into new projects and carry no special status thereafter: every rule
636
+ * can be edited, disabled, or deleted.
637
+ */
638
+ interface CommandPolicyRuleDto {
639
+ name: string;
640
+ /** JavaScript regex source, matched against the whitespace-normalized command. */
641
+ pattern: string;
642
+ /** What the rule catches (free text). */
643
+ description?: string;
644
+ /** Per-rule switch, effective value (defaults on). */
645
+ enabled: boolean;
646
+ }
647
+ /**
648
+ * Per-Project sandbox command policy: deny rules for shell commands, evaluated ahead of
649
+ * the approval mode (a hit is denied even under allow-all). Serves as the GET response and
650
+ * the PUT response. The PUT request body carries `enabled?` plus the full `rules` list
651
+ * (required — a PUT always materializes the list into the config, model-presets style);
652
+ * per-rule `enabled` may be omitted there and defaults to on. Owner-only to write; any
653
+ * member may read.
654
+ */
655
+ interface CommandPolicyDto {
656
+ /** Effective master switch; an absent stored value reads as true (the policy defaults on). */
657
+ enabled: boolean;
658
+ /** The effective rule list — the factory set when the project predates seeding and has none stored. */
659
+ rules: CommandPolicyRuleDto[];
660
+ /** The factory set, served for the settings UI's "restore defaults". */
661
+ defaultRules: CommandPolicyRuleDto[];
662
+ }
540
663
  /** Read-only vault entry display: key name + masked value; plaintext is never sent. */
541
664
  interface VaultEntryInfo {
542
665
  key: string;
@@ -593,6 +716,28 @@ interface AgentCreateRequest {
593
716
  /** Display name; defaults to agentId. */
594
717
  name?: string;
595
718
  description?: string;
719
+ /**
720
+ * Library Skill names installed into the new Agent, seeding it at creation. Every name must
721
+ * exist in the library (404 `unknown_skill` otherwise, before anything is created); omitted or
722
+ * empty leaves the Agent with no Skills, which is what a plain Agent gets by default.
723
+ */
724
+ skills?: string[];
725
+ /**
726
+ * Skills imported from a directory on disk instead of the library. `skillsDirectory` is the
727
+ * absolute path the user picked and `directorySkills` are the names to install from it, read
728
+ * back from `.agents/skills` / `.claude/skills` at creation time. Both are required together,
729
+ * and every name must still be there (404 `unknown_skill` otherwise, before anything is
730
+ * created) — the client sends names, never Skill content.
731
+ */
732
+ skillsDirectory?: string;
733
+ directorySkills?: string[];
734
+ /**
735
+ * Base64 of an exported Agent State snapshot package (`.tar.gz`): the new Agent is
736
+ * initialized from the package instead of the default template. Mutually exclusive with
737
+ * skill seeding (`skills` / `skillsDirectory`) — the package carries its own skills.
738
+ * Explicit `name` / `description` override the package's values; absent ones keep them.
739
+ */
740
+ dataBase64?: string;
596
741
  }
597
742
  interface AgentCreateResponse {
598
743
  agent: AgentSummary;
@@ -685,13 +830,13 @@ interface AgentConfigResponse {
685
830
  }
686
831
  /**
687
832
  * POST …/config/kernel-update result: the smart merge's outcome (core's applyKernelUpdate).
688
- * Paths are dotted config leaves (`system_prompt`, `memory.prompt`, `tools.builtin.<name>`…)
689
- * in defaults-traversal order; the client maps them to display names.
833
+ * The entries are Agent settings **tabs** (`prompt`, `runtime`, `tools`, `skills`, `memory`,
834
+ * `vault`, `schedules`) in the settings page's tab order; the client maps them to tab labels.
690
835
  */
691
836
  interface AgentKernelUpdateResponse {
692
- /** Leaves advanced to the new default (previously missing, or an untouched old default). */
837
+ /** Tabs advanced to the current defaults (previously absent, or an untouched old default). */
693
838
  advanced: string[];
694
- /** Leaves kept because the stored value matches no recorded defaults generation (user customizations, kept conservatively). */
839
+ /** Tabs kept whole because they match no recorded default (customized, kept conservatively). */
695
840
  kept: string[];
696
841
  /** The kernel stamp written (the current defaults generation). */
697
842
  kernelVersion: string;
@@ -744,6 +889,8 @@ interface MemoryScopeInfo {
744
889
  workspacePath?: string;
745
890
  /** Number of Markdown topic files in the directory (the `MEMORY.md` index not counted). */
746
891
  fileCount: number;
892
+ /** Whether the directory holds a `MEMORY.md` index, so an import confirmation can say whether one would be replaced. */
893
+ hasIndex: boolean;
747
894
  /** Most recent topic-file mtime in the directory (ISO 8601); unset when the directory holds no topic file. */
748
895
  updatedAt?: string;
749
896
  }
@@ -783,6 +930,64 @@ interface MemoryFileResponse {
783
930
  file: MemoryFileInfo;
784
931
  content: string;
785
932
  }
933
+ /** One topic file inside a transfer document: the name it had in its scope, and its whole text. */
934
+ interface MemoryTransferFile {
935
+ /** File name inside the scope directory, e.g. `prefers-pnpm.md` — a name, never a path. */
936
+ name: string;
937
+ /** The file's full Markdown text, frontmatter included. */
938
+ content: string;
939
+ }
940
+ /**
941
+ * GET …/memory/scopes/:key/export, and the body a POST …/import carries back: everything one
942
+ * scope holds, as one JSON document — the topic files and the scope's own `MEMORY.md`.
943
+ */
944
+ interface MemoryScopeExport {
945
+ /** Format marker, so a foreign JSON file is refused with a clear reason rather than half-imported. */
946
+ format: "penguin-memory-scope";
947
+ /** Document version. A reader accepts exactly this; a later format bumps it and states its own compatibility. */
948
+ version: 1;
949
+ /** The scope this was exported from. Informational: an import writes into the scope its URL names. */
950
+ scopeKey: string;
951
+ kind: MemoryScopeInfo["kind"];
952
+ /** The Workspace the source scope stood for, when it had a `.workspace` marker. */
953
+ workspacePath?: string;
954
+ /** When the document was produced (ISO 8601). */
955
+ exportedAt: string;
956
+ /** The scope's `MEMORY.md`, or null when the scope has none. Only the index reaches the model's context. */
957
+ index: string | null;
958
+ files: MemoryTransferFile[];
959
+ }
960
+ /**
961
+ * What an import does with a name the target scope already holds:
962
+ * - `skip` — keep what is on disk, write only names the scope does not have (destroys nothing);
963
+ * - `overwrite` — replace a same-named file's content;
964
+ * - `replace` — additionally delete every topic file the document does not carry.
965
+ * The two destructive modes require `confirm`.
966
+ */
967
+ type MemoryImportMode = "skip" | "overwrite" | "replace";
968
+ /** POST …/memory/scopes/:key/import */
969
+ interface MemoryImportRequest {
970
+ /** Defaults to `skip`. */
971
+ mode?: MemoryImportMode;
972
+ /** Required by `overwrite` and `replace`; without it they are refused with 409 `memory_import_confirm_required`. */
973
+ confirm?: boolean;
974
+ payload: MemoryScopeExport;
975
+ }
976
+ /** What one import did, name by name, so the UI can report it rather than claim success. */
977
+ interface MemoryImportResponse {
978
+ scopeKey: string;
979
+ mode: MemoryImportMode;
980
+ /** Names written that the scope did not have. */
981
+ added: string[];
982
+ /** Names whose existing content was replaced. */
983
+ overwritten: string[];
984
+ /** Names left untouched because the scope already had them (`skip` only). */
985
+ skipped: string[];
986
+ /** Names deleted because `replace` dropped everything the document did not carry. */
987
+ removed: string[];
988
+ /** Whether the scope's `MEMORY.md` was written or extended. */
989
+ indexWritten: boolean;
990
+ }
786
991
  interface SessionInfo {
787
992
  sessionId: string;
788
993
  projectId: string;
@@ -839,6 +1044,8 @@ interface SessionInfo {
839
1044
  * history itself when it needs it.
840
1045
  */
841
1046
  tracePath?: string;
1047
+ /** Present when the Session has an ENABLED messaging binding: its channel (the sidebar row's per-channel indicator). */
1048
+ messagingChannel?: MessagingChannel;
842
1049
  }
843
1050
  /**
844
1051
  * Session list category, the sidebar's four-way split applied server-side: archived wins
@@ -874,6 +1081,17 @@ interface DirListResponse {
874
1081
  /** Subdirectory list (sorted by name, files excluded). */
875
1082
  entries: DirEntryInfo[];
876
1083
  }
1084
+ /** One Skill found in a picked directory: metadata plus which of the two layouts it came from. */
1085
+ interface DirectorySkillItem extends SkillMetadataItem {
1086
+ /** `.agents/skills` or `.claude/skills` — shown so the origin of an offered Skill is visible. */
1087
+ source: string;
1088
+ }
1089
+ interface DirectorySkillsResponse {
1090
+ /** Absolute path that was scanned (realpath). */
1091
+ path: string;
1092
+ /** Installable Skills found under the directory's Skill layouts; empty when it carries none. */
1093
+ skills: DirectorySkillItem[];
1094
+ }
877
1095
  interface SessionCreateRequest {
878
1096
  /** Upstream id of the session's model; always sent together with provider. Omit both for the Project's default Model. */
879
1097
  modelId?: string;
@@ -887,6 +1105,12 @@ interface SessionCreateRequest {
887
1105
  workspace?: string;
888
1106
  /** Defaults to allow-all. */
889
1107
  approvalMode?: ApprovalMode;
1108
+ /**
1109
+ * Creating-client hint stored on the Session row: "cli" when the CLI creates the
1110
+ * Session through the API; defaults to "web". Informational provenance only — lists
1111
+ * serve every row regardless of client.
1112
+ */
1113
+ client?: "web" | "cli";
890
1114
  }
891
1115
  interface SessionCreateResponse {
892
1116
  session: SessionInfo;
@@ -1144,6 +1368,30 @@ interface PendingFollowUpInfo {
1144
1368
  /** Number of file attachments in the queued input. */
1145
1369
  files: number;
1146
1370
  }
1371
+ /**
1372
+ * One live subagent child of a session's runtime, carried on `task_state` events and the SSE
1373
+ * subscribe snapshot: the child Session id (the origin hop the stream already correlates by),
1374
+ * its background registry handle (null while it only lives inside a foreground collect
1375
+ * window), and whether a round is currently running. Only an ACTIVE parent runtime reports
1376
+ * children — after a server restart the in-process children are gone, and the empty list is
1377
+ * the truth.
1378
+ */
1379
+ interface SubagentRuntimeInfo {
1380
+ sessionId: string;
1381
+ subagentId: string | null;
1382
+ running: boolean;
1383
+ }
1384
+ /**
1385
+ * Response of POST /api/sessions/:sessionId/subagents/:childSessionId/message — a user input
1386
+ * on the child, whatever its state: `steered` = queued as a mid-run interjection, `started` =
1387
+ * began a follow-up run on the idle child, `resumed` = the released child session was revived
1388
+ * (resume-session semantics) and the message began its next round. The failure shapes are
1389
+ * HTTP statuses instead: 404 when the child's session record does not exist or cannot be
1390
+ * revived, 409 when the child cannot take the message right now.
1391
+ */
1392
+ interface SubagentMessageResponse {
1393
+ outcome: "steered" | "started" | "resumed";
1394
+ }
1147
1395
  /**
1148
1396
  * Response of the two recall endpoints — DELETE /api/sessions/:id/steer/:steerId and
1149
1397
  * DELETE /api/sessions/:id/follow-ups/:followUpId: the withdrawn message's original content,
@@ -1190,10 +1438,165 @@ interface SessionProcessInfo {
1190
1438
  cwd: string;
1191
1439
  startedAt: string;
1192
1440
  running: boolean;
1441
+ /** The service the process serves, when detected: the last local URL its output printed, else an origin probed from its listening ports. */
1442
+ serviceUrl?: string;
1193
1443
  }
1194
1444
  interface SessionProcessesResponse {
1195
1445
  processes: SessionProcessInfo[];
1196
1446
  }
1447
+ /** Messaging channels a Session can bind to. */
1448
+ type MessagingChannel = "feishu" | "telegram";
1449
+ /** Event-connection runtime state of one binding (kept in memory, not persisted). */
1450
+ type MessagingRuntimeState = "disconnected" | "connecting" | "connected" | "error";
1451
+ interface MessagingRuntimeStatus {
1452
+ state: MessagingRuntimeState;
1453
+ /** Failure detail; present only in the `error` state. */
1454
+ lastError?: string;
1455
+ /** When the state last changed (ISO 8601); absent for a binding that never connected. */
1456
+ changedAt?: string;
1457
+ }
1458
+ /** The stored Feishu config, secret masked (plaintext never leaves the server). */
1459
+ interface FeishuBindingInfo {
1460
+ channel: "feishu";
1461
+ sessionId: string;
1462
+ appId: string;
1463
+ /**
1464
+ * Masked app secret (site-wide mask rule: `***`, or `first4…last4` for long values);
1465
+ * absent when no secret is stored (never entered, or cleared) — the binding cannot be
1466
+ * enabled until one is saved.
1467
+ */
1468
+ appSecretMasked?: string;
1469
+ baseDomain: string;
1470
+ /** Connection INTENT (the state toggle's value); new bindings start disabled, and at most one of a Session's channels is enabled. */
1471
+ enabled: boolean;
1472
+ /**
1473
+ * Whether an inbound Feishu chat is known (the bot has been messaged at least once).
1474
+ * Replies and test messages target that chat; until it exists nothing can be sent.
1475
+ */
1476
+ lastChatKnown: boolean;
1477
+ createdAt: string;
1478
+ updatedAt: string;
1479
+ }
1480
+ /** The stored Telegram config, token masked (plaintext never leaves the server). */
1481
+ interface TelegramBindingInfo {
1482
+ channel: "telegram";
1483
+ sessionId: string;
1484
+ /** The numeric bot id (the token's half before the colon) — the channel-scoped account identity, never secret. */
1485
+ botId: string;
1486
+ /**
1487
+ * Masked bot token (site-wide mask rule: `***`, or `first4…last4` for long values);
1488
+ * absent when no token is stored (cleared) — the binding cannot be enabled until one
1489
+ * is saved.
1490
+ */
1491
+ botTokenMasked?: string;
1492
+ /** Connection INTENT (the state toggle's value); new bindings start disabled, and at most one of a Session's channels is enabled. */
1493
+ enabled: boolean;
1494
+ /**
1495
+ * Whether an inbound Telegram chat is known (the bot has been messaged at least once).
1496
+ * Replies and test messages target that chat; until it exists nothing can be sent.
1497
+ */
1498
+ lastChatKnown: boolean;
1499
+ createdAt: string;
1500
+ updatedAt: string;
1501
+ }
1502
+ /** A Session's saved config for one messaging channel (`channel` is the discriminant). */
1503
+ type MessagingBindingInfo = FeishuBindingInfo | TelegramBindingInfo;
1504
+ /** One saved channel config with its event-connection runtime status. */
1505
+ interface MessagingChannelState {
1506
+ binding: MessagingBindingInfo;
1507
+ /** Only the enabled channel's connection is ever anything but disconnected. */
1508
+ status: MessagingRuntimeStatus;
1509
+ }
1510
+ /**
1511
+ * GET …/messaging response — the channel-agnostic read the channel-aware binding editor
1512
+ * loads: EVERY saved channel config (masked) with its runtime status. A Session may keep
1513
+ * both channels saved; at most one of them is enabled.
1514
+ */
1515
+ interface MessagingBindingsResponse {
1516
+ bindings: MessagingChannelState[];
1517
+ }
1518
+ /** GET / PUT …/messaging/feishu response: the Feishu config (null = not saved) plus its runtime status. */
1519
+ interface FeishuBindingResponse {
1520
+ binding: FeishuBindingInfo | null;
1521
+ status: MessagingRuntimeStatus;
1522
+ }
1523
+ /** GET / PUT …/messaging/telegram response (the Telegram narrowing of the same envelope). */
1524
+ interface TelegramBindingResponse {
1525
+ binding: TelegramBindingInfo | null;
1526
+ status: MessagingRuntimeStatus;
1527
+ }
1528
+ /**
1529
+ * PUT …/messaging/feishu — saves credentials/config ONLY, never flipping the connection
1530
+ * (exception: an enabled binding's connector restarts with the new credentials so stored
1531
+ * config and live connection never diverge). The connection toggle is POST …/state.
1532
+ */
1533
+ interface FeishuBindingPutRequest {
1534
+ appId: string;
1535
+ /** Omitted or blank keeps the stored secret (the masked value never round-trips). */
1536
+ appSecret?: string;
1537
+ /** Defaults to https://open.feishu.cn when omitted or blank. */
1538
+ baseDomain?: string;
1539
+ /**
1540
+ * Drops the STORED secret (the models-page clear idiom; a typed `appSecret` wins over
1541
+ * it). Refused with 409 `messaging_disable_before_clear` while the binding is enabled.
1542
+ */
1543
+ clearAppSecret?: boolean;
1544
+ }
1545
+ /**
1546
+ * PUT …/messaging/telegram — saves the credential ONLY, same contract as the Feishu PUT
1547
+ * (an enabled binding's connector restarts with the new token; the connection toggle is
1548
+ * POST …/state). 409 `telegram_bot_in_use` when the token's bot id is bound elsewhere.
1549
+ */
1550
+ interface TelegramBindingPutRequest {
1551
+ /** Omitted or blank keeps the stored token (the masked value never round-trips). */
1552
+ botToken?: string;
1553
+ /**
1554
+ * Drops the STORED token (the models-page clear idiom; a typed `botToken` wins over
1555
+ * it — and the row keeps its bot identity). Refused with 409
1556
+ * `messaging_disable_before_clear` while the binding is enabled.
1557
+ */
1558
+ clearBotToken?: boolean;
1559
+ }
1560
+ /**
1561
+ * POST …/messaging/<channel>/state — enable connects with the STORED credentials,
1562
+ * disable terminates. Enabling is mutually exclusive per Session: while another channel
1563
+ * is enabled it answers 409 `another_channel_enabled` (turn that one off first), and a
1564
+ * config whose secret is missing answers its channel's 400 `*_required`.
1565
+ */
1566
+ interface MessagingBindingStateRequest {
1567
+ enabled: boolean;
1568
+ }
1569
+ /** POST …/messaging/feishu/test — draft values; each omitted field falls back to the stored binding. */
1570
+ interface FeishuTestRequest {
1571
+ appId?: string;
1572
+ appSecret?: string;
1573
+ baseDomain?: string;
1574
+ }
1575
+ /** Credential-test outcome (an unreachable/rejected credential is `ok:false`, not an HTTP error). */
1576
+ interface FeishuTestResponse {
1577
+ ok: boolean;
1578
+ latencyMs?: number;
1579
+ error?: string;
1580
+ }
1581
+ /** POST …/messaging/telegram/test — a draft token, falling back to the stored binding when omitted. */
1582
+ interface TelegramTestRequest {
1583
+ botToken?: string;
1584
+ }
1585
+ /** Telegram credential-test outcome: success additionally names the bot the token signs in as. */
1586
+ interface TelegramTestResponse {
1587
+ ok: boolean;
1588
+ latencyMs?: number;
1589
+ /** The bot's `@username`, when the API reports one. */
1590
+ botUsername?: string;
1591
+ error?: string;
1592
+ }
1593
+ /**
1594
+ * POST …/messaging/<channel>/test-message — sent to the last known chat (409
1595
+ * `feishu_no_chat` / `telegram_no_chat` before one exists).
1596
+ */
1597
+ interface MessagingTestMessageResponse {
1598
+ ok: true;
1599
+ }
1197
1600
  /** Docs: /docs/server-api § "Streaming (SSE)". */
1198
1601
  type ServerEvent =
1199
1602
  /**
@@ -1214,6 +1617,12 @@ type ServerEvent =
1214
1617
  pendingSteering?: PendingSteeringInfo[];
1215
1618
  /** Queued follow-up tasks awaiting auto-start (absent = none): per-entry content + recall handle, alongside the `queued` count. */
1216
1619
  pendingFollowUps?: PendingFollowUpInfo[];
1620
+ /**
1621
+ * Live subagent children of this session's runtime (absent = none): the panel renders
1622
+ * child running marks from this structural liveness instead of parsing tool-output
1623
+ * text. Refreshed on every child run start/settle.
1624
+ */
1625
+ subagents?: SubagentRuntimeInfo[];
1217
1626
  }
1218
1627
  /** The model-generated title after the first turn has been persisted (for in-place list updates). */
1219
1628
  | {
@@ -1332,6 +1741,51 @@ interface TraceFileInfo {
1332
1741
  interface SessionTracesResponse {
1333
1742
  files: TraceFileInfo[];
1334
1743
  }
1744
+ /** One tool's share of the context: its calls plus their results. Its *definition* is counted in `toolDefs`, not here. */
1745
+ interface ContextToolShare {
1746
+ name: string;
1747
+ tokens: number;
1748
+ }
1749
+ /**
1750
+ * What the Session's current model context is made of — the part derived from its messages.
1751
+ *
1752
+ * Every token figure is an **estimate** from a character heuristic, not a tokenizer: the
1753
+ * authoritative occupancy is the last `token_usage`'s `request.total`, which says how large the
1754
+ * context is but not what fills it. Consumers should present these as shares of that measured
1755
+ * occupancy rather than as counts of their own.
1756
+ *
1757
+ * The six parts partition the context and sum to `total`; `topTools` is a ranking inside
1758
+ * `toolRequests + toolResults` and can sum to less than those two (a result whose call was not
1759
+ * recorded in the same Trace shard has no tool to be attributed to).
1760
+ */
1761
+ interface SessionContextParts {
1762
+ systemPrompt: number;
1763
+ toolDefs: number;
1764
+ userMessages: number;
1765
+ assistantMessages: number;
1766
+ toolRequests: number;
1767
+ toolResults: number;
1768
+ /** Sum of the six parts. */
1769
+ total: number;
1770
+ /** Tools ranked by the context their traffic occupies, descending; at most five. */
1771
+ topTools: ContextToolShare[];
1772
+ /**
1773
+ * A completed compaction closed the context these figures describe, and the next one has not
1774
+ * been written yet: the composition is of what was compacted away, not of what the model now
1775
+ * carries. The same state in which the chat page's context ring shows `—`.
1776
+ */
1777
+ contextClosed: boolean;
1778
+ }
1779
+ /** `GET /api/sessions/:id/context`: the message-derived composition plus where compaction will fire. */
1780
+ interface SessionContextResponse extends SessionContextParts {
1781
+ /**
1782
+ * Occupancy (tokens) at which this Session's next Request triggers context compaction: the
1783
+ * Agent's configured `compaction.max_context_length`, capped by what the model's context window
1784
+ * leaves room for. Null when compaction is disabled, when the Agent's config could not be read,
1785
+ * or when the derived threshold is not below the window — nothing to mark inside the gauge.
1786
+ */
1787
+ compactionThreshold: number | null;
1788
+ }
1335
1789
  interface TraceEventsResponse {
1336
1790
  events: OmniMessage[];
1337
1791
  offset: number;
@@ -1647,35 +2101,47 @@ interface UsageGroupRow {
1647
2101
  cost: number | null;
1648
2102
  hasUncosted: boolean;
1649
2103
  }
1650
- interface UsageTrendPoint {
1651
- date: string;
1652
- total: number;
1653
- cost: number | null;
1654
- /** Daily Token buckets (for the cost center's "Token Changes" stacked chart: cacheRead/cacheWrite/output). */
2104
+ /** Time-series precision for the usage series (`granularity` query parameter). `minute` requires the `fromTs`/`toTs` window bounds. */
2105
+ type UsageGranularity = "minute" | "hour" | "day" | "week" | "month";
2106
+ /**
2107
+ * One bucket of the usage time series (for the cost center's time-series charts).
2108
+ * Buckets are zero-filled across the whole requested range, so consecutive points
2109
+ * are always adjacent in time. Bucket keys by granularity: minute
2110
+ * `yyyy-mm-ddThh:mm` and hour `yyyy-mm-ddThh:00` (server-local clock), day
2111
+ * `yyyy-mm-dd`, week the ISO week's Monday `yyyy-mm-dd`, month `yyyy-mm`.
2112
+ */
2113
+ interface UsageSeriesPoint {
2114
+ bucket: string;
1655
2115
  cacheRead: number;
1656
2116
  cacheWrite: number;
1657
2117
  output: number;
2118
+ total: number;
2119
+ /** Cost converted at query time (USD); null when no priced Model contributed. */
2120
+ cost: number | null;
2121
+ requests: number;
2122
+ /** Successful requests in the bucket. */
2123
+ completed: number;
2124
+ /** Success-rate denominator: all requests minus aborted (a user interruption is not a model failure). */
2125
+ denominator: number;
2126
+ }
2127
+ /**
2128
+ * One entity's per-bucket request and success counts, aligned index-for-index
2129
+ * with `series` (the requests-and-success-rate chart draws one such entity —
2130
+ * or stacks them all). `denominator` excludes aborted, same as elsewhere.
2131
+ */
2132
+ interface UsageEntitySeriesCounts {
2133
+ requests: number[];
2134
+ completed: number[];
2135
+ denominator: number[];
1658
2136
  }
1659
- /** Invocation count per Agent (for the cost center's "Agent Invocation Count" chart). */
1660
- interface UsageAgentCount {
2137
+ /** Per-Agent counts per bucket. */
2138
+ interface UsageAgentSeries extends UsageEntitySeriesCounts {
1661
2139
  agentId: string;
1662
- requests: number;
1663
- total: number;
1664
2140
  }
1665
- /** Request success rate per Model (for the cost center's "Model Success Rate" chart; rows broken down by (provider, modelId)). */
1666
- interface UsageSuccessRate {
2141
+ /** Per-Model counts per bucket (entity identity is the (provider, modelId) pair). */
2142
+ interface UsageModelSeries extends UsageEntitySeriesCounts {
1667
2143
  provider: string;
1668
2144
  modelId: string;
1669
- /** Number of successful requests. */
1670
- completed: number;
1671
- /** Success rate denominator = all requests − aborted (user-initiated interruption isn't a model failure and shouldn't lower the success rate). */
1672
- total: number;
1673
- /** Count of user interruptions (excluded from success rate, shown separately). */
1674
- aborted: number;
1675
- /** Failure breakdown (shown on hover; unknown statuses count toward total but not these three). */
1676
- failed: number;
1677
- timeout: number;
1678
- malformed: number;
1679
2145
  }
1680
2146
  /** Occurrence count of an error for a given source · code (the "most common" metric in the stats center's error panel). */
1681
2147
  interface UsageErrorCount {
@@ -1728,12 +2194,27 @@ interface UsageResponse {
1728
2194
  };
1729
2195
  groupBy: UsageGroupBy;
1730
2196
  groups: UsageGroupRow[];
1731
- /** Daily trend for the last 30 days (includes Token buckets and cost; affected by agent/model filters). */
1732
- trend: UsageTrendPoint[];
1733
- /** Invocation count per Agent (affected by date/model filters). */
1734
- byAgent: UsageAgentCount[];
1735
- /** Raw success rate counts per Model (affected by date/agent filters). */
1736
- success: UsageSuccessRate[];
2197
+ /** Effective precision of `series` (the validated `granularity` query parameter; defaults to day). */
2198
+ granularity: UsageGranularity;
2199
+ /**
2200
+ * Usage time series over the requested from/to range (defaulting to the last 30
2201
+ * days), zero-filled at `granularity`; affected by agent/model filters. Carries
2202
+ * everything the time-series charts draw: Token buckets, cost, request count,
2203
+ * and per-bucket success counts.
2204
+ */
2205
+ series: UsageSeriesPoint[];
2206
+ /**
2207
+ * Per-Agent counts per bucket, aligned index-for-index with `series`, sorted
2208
+ * by total requests descending. Unaffected by the agent filter — the by-Agent
2209
+ * chart draws the whole breakdown — but affected by date/model filters.
2210
+ */
2211
+ byAgentSeries: UsageAgentSeries[];
2212
+ /**
2213
+ * Per-Model counts per bucket, aligned index-for-index with `series`, sorted
2214
+ * by total requests descending. Unaffected by the model filter — the by-Model
2215
+ * chart draws the whole breakdown — but affected by date/agent filters.
2216
+ */
2217
+ byModelSeries: UsageModelSeries[];
1737
2218
  /** Server-side error capture stats (affected by date/agent filters; unaffected by model filter). */
1738
2219
  errors: UsageErrors;
1739
2220
  /** List of Agent ids that have appeared in this Project (for the filter dropdown; unaffected by current filters). */
@@ -1884,7 +2365,7 @@ interface SkillMetadataItem {
1884
2365
  icon?: string;
1885
2366
  /** Version number (natural number, frontmatter version; falls back to 1 if invalid). */
1886
2367
  version: number;
1887
- /** Update date (YYYY-MM-DD, frontmatter updated; defaults to an empty string). */
2368
+ /** Update timestamp (frontmatter updated, ISO 8601 UTC by convention; defaults to an empty string). */
1888
2369
  updated: string;
1889
2370
  }
1890
2371
  interface SkillGroupItem {
@@ -1918,17 +2399,15 @@ interface SkillArchiveInstallRequest {
1918
2399
  /** Replace an already-installed Skill of the same name (deletes its directory first). */
1919
2400
  overwrite?: boolean;
1920
2401
  }
1921
- /** GET /api/version: the running server's release identity (from core's VERSION / BUILD_DATE). */
1922
- interface VersionResponse {
1923
- version: string;
1924
- /**
1925
- * The **running** version's release date (UTC yyyy-mm-dd), stamped into core's
1926
- * BUILD_DATE at build time by the release workflow — the web's "last updated" date
1927
- * needs no network. Null for a dev/source build and for releases that predate the
1928
- * stamping (v0.1.2 and earlier): the UI then shows the version alone.
1929
- */
1930
- buildDate: string | null;
1931
- }
2402
+ /**
2403
+ * GET /api/version: the running build's identity plus this root's pushed harness, verbatim
2404
+ * from `versionReport()` — the same record `penguin version --json` prints, so the two
2405
+ * cannot drift apart. Field meanings live on {@link VersionReport} and {@link HarnessInfo};
2406
+ * the ones the web reads are `version` and `buildDate` (the stamped release date behind the
2407
+ * sidebar's "last updated", needing no network, and null for a source build or a release
2408
+ * predating the stamping — v0.1.2 and earlier — where the UI shows the version alone).
2409
+ */
2410
+ type VersionResponse = VersionReport;
1932
2411
  /**
1933
2412
  * GET /api/version/update-check: newest published release vs the running version.
1934
2413
  * Always HTTP 200 (fail-soft): a lookup failure sets `error` and leaves `latestVersion`
@@ -1952,6 +2431,51 @@ interface UpdateCheckResponse {
1952
2431
  /** Why the lookup failed: unreachable network / GitHub rate limit / unusable response. */
1953
2432
  error?: "network" | "rate_limited" | "bad_response";
1954
2433
  }
2434
+ /**
2435
+ * The desktop shell's updater snapshot, pushed to the embedded server over the
2436
+ * utilityProcess message channel and served at GET /api/desktop/update. `state` is the
2437
+ * discriminator; the optional fields belong to the states named on them.
2438
+ *
2439
+ * A `downloaded` build stays the reported state until it is installed: a later periodic
2440
+ * check (or its failure) must not hide the actionable "restart to install" step.
2441
+ */
2442
+ interface DesktopUpdateStatus {
2443
+ /** Installed shell version (Electron app.getVersion()). */
2444
+ appVersion: string;
2445
+ /**
2446
+ * Bumped by the shell on every updater event it folds, whether or not the visible
2447
+ * state changed. A row-initiated check settles when the seq has moved past its
2448
+ * at-click value and the state is no longer `checking` — snapshot equality can't
2449
+ * carry that signal (a check that ends where it started is byte-identical).
2450
+ */
2451
+ seq?: number;
2452
+ state: "idle" | "checking" | "up-to-date" | "downloading" | "downloaded" | "error" | "unsupported";
2453
+ /** Newer release being fetched / ready to install (`downloading`, `downloaded`). */
2454
+ version?: string;
2455
+ /** Download progress 0–100 (`downloading`). */
2456
+ percent?: number;
2457
+ /** Updater failure text (`error`). */
2458
+ message?: string;
2459
+ /** Why this install form cannot update itself (`unsupported`): dev run, or a Linux install that is not an AppImage (e.g. .deb — the system package manager owns it). */
2460
+ reason?: "dev" | "linux-not-appimage";
2461
+ }
2462
+ /**
2463
+ * GET /api/desktop/update (desktop-shell sessions only): the latest shell snapshot.
2464
+ * `status` is null until the shell's first push lands (a beat after server start).
2465
+ */
2466
+ interface DesktopUpdateStatusResponse {
2467
+ status: DesktopUpdateStatus | null;
2468
+ }
2469
+ /** Shell → server push over the utilityProcess message channel. */
2470
+ interface DesktopUpdaterStatusMessage {
2471
+ type: "desktop-updater-status";
2472
+ status: DesktopUpdateStatus;
2473
+ }
2474
+ /** Server → shell command over the utilityProcess message channel (relayed from POST /api/desktop/update/check|install). */
2475
+ interface DesktopUpdaterCommandMessage {
2476
+ type: "desktop-updater-command";
2477
+ action: "check" | "install";
2478
+ }
1955
2479
  /**
1956
2480
  * POST /api/version/update (admin only): runs the CLI self-update (`penguin update --yes`)
1957
2481
  * on the server host. `unsupported` covers both a server not launched via the CLI and the
@@ -1967,4 +2491,4 @@ interface UpdateRunResponse {
1967
2491
  needsRestart: boolean;
1968
2492
  }
1969
2493
 
1970
- export type { AdminPasswordResetRequest, AdminUserCreateRequest, AdminUserCreateResponse, AdminUsersResponse, AgentCompactionConfigDto, AgentConfigDto, AgentConfigResponse, AgentConfigUpdateRequest, AgentCreateRequest, AgentCreateResponse, AgentImportRequest, AgentImportResponse, AgentKernelUpdateResponse, AgentMemoryConfigDto, AgentModelConfigDto, AgentSchedulesConfigDto, AgentSkillsConfigDto, AgentSkillsResponse, AgentSummary, AgentTraceDateGroup, AgentTraceFileRef, AgentTraceSessionEntry, AgentTraceSessionFile, AgentTraceSessionGroup, AgentTracesResponse, AgentVaultConfigDto, AgentsResponse, ApprovalDecisionRequest, ApprovalMode, AuthLoginRequest, AuthResponse, BenchmarkCaseScore, BenchmarkCaseSummary, BenchmarkCasesResponse, BenchmarkEvaluation, BenchmarkRunScore, BenchmarkSummary, BenchmarksResponse, CaseMaterial, ChatDefaultsDto, CredentialInfo, DefaultModelResponse, DefaultModelUpdateRequest, DirEntryInfo, DirListResponse, ErrorBody, FilesStatRequest, FilesStatResponse, GoalResponse, GoalServerEvent, GoalStateView, HistoryMessage, McpServerTestResponse, MeResponse, MemberAddRequest, MemberAddResponse, MemberInfo, MembersResponse, MemoryFileInfo, MemoryFileResponse, MemoryFilesResponse, MemoryOverviewResponse, MemoryScopeInfo, MessagesLiveTail, MessagesPageInfo, MessagesResponse, ModelInfo, ModelPricingDto, ModelProtocolDetectRequest, ModelProtocolDetectResponse, ModelProtocolProbeDto, ModelRefDto, ModelTestRequest, ModelTestResponse, ModelUpdateEntry, ModelVisionDetectRequest, ModelVisionDetectResponse, ModelVisionOutcome, ModelsResponse, ModelsUpdateRequest, PasswordChangeRequest, PendingFollowUpInfo, PendingSteeringInfo, PrefsResponse, ProjectCreateRequest, ProjectCreateResponse, ProjectRole, ProjectSummary, ProjectUpdateRequest, ProjectUpdateResponse, ProjectsResponse, ProtocolProbeOutcome, RecalledMessageResponse, RequestSpan, RetryNowResponse, ScheduleItem, ScheduleServerEvent, ScheduleStatus, ScheduleUpsertRequest, SchedulesResponse, ServerEvent, ServerSettings, ServerSettingsResponse, ServerSettingsUpdateRequest, SessionCategory, SessionCategoryCounts, SessionCreateRequest, SessionCreateResponse, SessionForkRequest, SessionForkResponse, SessionInfo, SessionPatchRequest, SessionProcessInfo, SessionProcessesResponse, SessionResponse, SessionSource, SessionStatus, SessionTracesResponse, SessionsResponse, SkillArchiveInstallRequest, SkillGroupItem, SkillInstallRequest, SkillLibraryResponse, SkillMetadataItem, SteerRequest, TaskCreateRequest, TaskCreateResponse, TaskInputPart, ToolCallSpan, TraceAnalysisResponse, TraceEventsResponse, TraceFileInfo, TraceImportRequest, TraceImportResponse, TraceModelSegment, TraceOtherSpan, TracePosition, TraceTaskStats, TraceToolSpan, UiPrefs, UpdateCheckResponse, UpdateRunResponse, UploadLimits, UsageAgentCount, UsageBucket, UsageErrorCount, UsageErrorItem, UsageErrors, UsageErrorsPage, UsageGroupBy, UsageGroupRow, UsageResponse, UsageSuccessRate, UsageTrendPoint, UsageTrendPointInTrace, UserInfo, VaultEntryInfo, VaultEntryUpdate, VaultResponse, VaultUpdateRequest, VersionResponse, WorkspaceFileEntry, WorkspaceFilesResponse };
2494
+ export type { AdminPasswordResetRequest, AdminUserCreateRequest, AdminUserCreateResponse, AdminUsersResponse, AgentCompactionConfigDto, AgentConfigDto, AgentConfigResponse, AgentConfigUpdateRequest, AgentCreateRequest, AgentCreateResponse, AgentImportRequest, AgentImportResponse, AgentKernelUpdateResponse, AgentMemoryConfigDto, AgentModelConfigDto, AgentSchedulesConfigDto, AgentSkillsConfigDto, AgentSkillsResponse, AgentSummary, AgentTraceDateGroup, AgentTraceFileRef, AgentTraceSessionEntry, AgentTraceSessionFile, AgentTraceSessionGroup, AgentTracesResponse, AgentVaultConfigDto, AgentsResponse, ApprovalDecisionRequest, ApprovalMode, AuthLoginRequest, AuthResponse, BenchmarkCaseScore, BenchmarkCaseSummary, BenchmarkCasesResponse, BenchmarkEvaluation, BenchmarkRunScore, BenchmarkSummary, BenchmarksResponse, CaseMaterial, ChatDefaultsDto, CommandPolicyDto, CommandPolicyRuleDto, ContextToolShare, CredentialInfo, DefaultModelResponse, DefaultModelUpdateRequest, DesktopUpdateStatus, DesktopUpdateStatusResponse, DesktopUpdaterCommandMessage, DesktopUpdaterStatusMessage, DirEntryInfo, DirListResponse, DirectorySkillItem, DirectorySkillsResponse, DraftShortcut, EndpointModelListRequest, EndpointModelListResponse, ErrorBody, FeishuBindingInfo, FeishuBindingPutRequest, FeishuBindingResponse, FeishuTestRequest, FeishuTestResponse, FilesStatRequest, FilesStatResponse, GoalResponse, GoalServerEvent, GoalStateView, HistoryMessage, McpServerTestResponse, MeResponse, MemberAddRequest, MemberAddResponse, MemberInfo, MembersResponse, MemoryFileInfo, MemoryFileResponse, MemoryFilesResponse, MemoryImportMode, MemoryImportRequest, MemoryImportResponse, MemoryOverviewResponse, MemoryScopeExport, MemoryScopeInfo, MemoryTransferFile, MessagesLiveTail, MessagesPageInfo, MessagesResponse, MessagingBindingInfo, MessagingBindingStateRequest, MessagingBindingsResponse, MessagingChannel, MessagingChannelState, MessagingRuntimeState, MessagingRuntimeStatus, MessagingTestMessageResponse, ModelInfo, ModelOAuthCodeRequest, ModelOAuthCodeResponse, ModelOAuthErrorCode, ModelOAuthMode, ModelOAuthStartRequest, ModelOAuthStartResponse, ModelOAuthStatusResponse, ModelPricingDto, ModelProtocolDetectRequest, ModelProtocolDetectResponse, ModelProtocolProbeDto, ModelRefDto, ModelTestRequest, ModelTestResponse, ModelUpdateEntry, ModelVisionDetectRequest, ModelVisionDetectResponse, ModelVisionOutcome, ModelsResponse, ModelsUpdateRequest, PasswordChangeRequest, PendingFollowUpInfo, PendingSteeringInfo, PrefsResponse, ProjectCreateRequest, ProjectCreateResponse, ProjectRole, ProjectSummary, ProjectUpdateRequest, ProjectUpdateResponse, ProjectsResponse, ProtocolProbeOutcome, RecalledMessageResponse, RequestSpan, RetryNowResponse, ScheduleItem, ScheduleServerEvent, ScheduleStatus, ScheduleUpsertRequest, SchedulesResponse, ServerEvent, ServerSettings, ServerSettingsResponse, ServerSettingsUpdateRequest, SessionCategory, SessionCategoryCounts, SessionContextParts, SessionContextResponse, SessionCreateRequest, SessionCreateResponse, SessionForkRequest, SessionForkResponse, SessionInfo, SessionPatchRequest, SessionProcessInfo, SessionProcessesResponse, SessionResponse, SessionSource, SessionStatus, SessionTracesResponse, SessionsResponse, SkillArchiveInstallRequest, SkillGroupItem, SkillInstallRequest, SkillLibraryResponse, SkillMetadataItem, SteerRequest, SubagentMessageResponse, SubagentRuntimeInfo, TaskCreateRequest, TaskCreateResponse, TaskInputPart, TelegramBindingInfo, TelegramBindingPutRequest, TelegramBindingResponse, TelegramTestRequest, TelegramTestResponse, ToolCallSpan, TraceAnalysisResponse, TraceEventsResponse, TraceFileInfo, TraceImportRequest, TraceImportResponse, TraceModelSegment, TraceOtherSpan, TracePosition, TraceTaskStats, TraceToolSpan, UiPrefs, UpdateCheckResponse, UpdateRunResponse, UploadLimits, UsageAgentSeries, UsageBucket, UsageEntitySeriesCounts, UsageErrorCount, UsageErrorItem, UsageErrors, UsageErrorsPage, UsageGranularity, UsageGroupBy, UsageGroupRow, UsageModelSeries, UsageResponse, UsageSeriesPoint, UsageTrendPointInTrace, UserInfo, VaultEntryInfo, VaultEntryUpdate, VaultResponse, VaultUpdateRequest, VersionResponse, WorkspaceFileEntry, WorkspaceFilesResponse };