@otto-code/protocol 0.8.6 → 0.8.8

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/messages.js CHANGED
@@ -462,6 +462,12 @@ export const MutableBrainConfigSchema = z
462
462
  .passthrough()
463
463
  .default({ host: "127.0.0.1", port: 1234 }),
464
464
  defaultModel: z.string().nullable().default(null),
465
+ runtime: z
466
+ .object({
467
+ source: z.enum(["auto", "managed", "lmstudio"]).default("auto"),
468
+ path: z.string().nullable().default(null),
469
+ })
470
+ .default({ source: "auto", path: null }),
465
471
  // Pin the host to one model: serve only the default/resident model and
466
472
  // refuse completion requests that ask for a different one.
467
473
  lockModel: z.boolean().default(false),
@@ -533,6 +539,9 @@ export const MutableBrainConfigPatchSchema = z
533
539
  remote: MutableBrainRemotePatchSchema,
534
540
  listen: MutableBrainListenPatchSchema,
535
541
  defaultModel: z.string().nullable(),
542
+ runtime: z
543
+ .object({ source: z.enum(["auto", "managed", "lmstudio"]), path: z.string().nullable() })
544
+ .partial(),
536
545
  lockModel: z.boolean(),
537
546
  allowRemoteConfig: z.boolean(),
538
547
  allowInsecureBind: z.boolean(),
@@ -549,6 +558,7 @@ export const DEFAULT_MUTABLE_BRAIN_CONFIG = {
549
558
  remote: { host: "", port: 1234, secure: false, authToken: null, certFingerprint: null },
550
559
  listen: { host: "127.0.0.1", port: 1234 },
551
560
  defaultModel: null,
561
+ runtime: { source: "auto", path: null },
552
562
  lockModel: false,
553
563
  allowRemoteConfig: false,
554
564
  allowInsecureBind: false,
@@ -1337,6 +1347,9 @@ export const AgentSnapshotPayloadSchema = z.object({
1337
1347
  attentionReason: z.enum(["finished", "error", "permission"]).nullable().optional(),
1338
1348
  attentionTimestamp: z.string().nullable().optional(),
1339
1349
  archivedAt: z.string().nullable().optional(),
1350
+ // Bytes in Otto's record captured at archive time. This is a projection,
1351
+ // never a transcript rescan during rendering.
1352
+ archiveBytes: z.number().int().nonnegative().optional(),
1340
1353
  providerUnavailable: z.boolean().optional(),
1341
1354
  // Attendability. "observed" marks a provider-managed subagent (Claude Task /
1342
1355
  // ultracode fan-out) that the user can watch but not prompt or reconfigure -
@@ -1444,12 +1457,8 @@ export const CloseItemsRequestMessageSchema = z.object({
1444
1457
  // to be server-side because the history list is cursor-paginated across hosts,
1445
1458
  // so the client never holds the whole archived set.
1446
1459
  //
1447
- // Deleting a chat removes OTTO's record only. The provider's own on-disk
1448
- // transcript (Claude's `~/.claude/projects/**/<sessionId>.jsonl`, Codex threads,
1449
- // OpenCode sessions) is deliberately left in place: Otto never created it,
1450
- // another tool still reads it, and silently deleting another tool's state is not
1451
- // ours to do. There is intentionally **no** opt-in flag for provider data on the
1452
- // wire - the UI discloses what stays behind instead. See docs/chat-lifecycle.md.
1460
+ // Deleting a chat removes Otto's record only. Provider-owned session data is
1461
+ // deliberately left in place. See docs/chat-lifecycle.md.
1453
1462
  // Gated by server_info.features.historyDelete.
1454
1463
  export const HistoryAgentsClearArchivedRequestSchema = z.object({
1455
1464
  type: z.literal("history.agents.clear_archived.request"),
@@ -1475,6 +1484,21 @@ export const HistoryAgentsClearArchivedResponseSchema = z.object({
1475
1484
  dryRun: z.boolean(),
1476
1485
  error: z.string().nullable(),
1477
1486
  requestId: z.string(),
1487
+ ottoBytes: z.number().int().nonnegative().optional(),
1488
+ reclaimedBytes: z.number().int().nonnegative().optional(),
1489
+ }),
1490
+ });
1491
+ export const HistoryAgentsStorageStatsRequestSchema = z.object({
1492
+ type: z.literal("history.agents.get_storage_stats.request"),
1493
+ requestId: z.string(),
1494
+ });
1495
+ export const HistoryAgentsStorageStatsResponseSchema = z.object({
1496
+ type: z.literal("history.agents.get_storage_stats.response"),
1497
+ payload: z.object({
1498
+ archivedCount: z.number().int().nonnegative(),
1499
+ totalBytes: z.number().nonnegative(),
1500
+ error: z.string().nullable(),
1501
+ requestId: z.string(),
1478
1502
  }),
1479
1503
  });
1480
1504
  export const UpdateAgentRequestMessageSchema = z.object({
@@ -1897,12 +1921,30 @@ export const BrainCatalogModelSchema = z
1897
1921
  tier: z.string().default(""),
1898
1922
  useCases: z.array(z.string()).default([]),
1899
1923
  why: z.string().default(""),
1924
+ components: z
1925
+ .array(z.object({
1926
+ id: z.string(),
1927
+ label: z.string().default(""),
1928
+ description: z.string().default(""),
1929
+ role: z.string().default(""),
1930
+ hfRepo: z.string().optional(),
1931
+ file: z.string().default(""),
1932
+ bytes: z.number().nullable().optional(),
1933
+ required: z.boolean().default(false),
1934
+ defaultDownload: z.boolean().default(false),
1935
+ defaultLoad: z.boolean().default(false),
1936
+ minRuntimeBuild: z.number().optional(),
1937
+ }))
1938
+ .optional(),
1900
1939
  })
1901
1940
  .passthrough();
1902
1941
  // An installed llama.cpp runtime, from `otto-brain runtime list`.
1903
1942
  export const BrainRuntimeSchema = z
1904
1943
  .object({
1905
1944
  label: z.string().default(""),
1945
+ // A human-readable runtime identity. The filesystem-safe `label` remains
1946
+ // for older hosts and destructive operations, not for UI presentation.
1947
+ displayName: z.string().default(""),
1906
1948
  version: z.string().default(""),
1907
1949
  source: z.string().default(""),
1908
1950
  dir: z.string().default(""),
@@ -1915,6 +1957,7 @@ export const BrainRuntimeSchema = z
1915
1957
  export const BrainJobKindSchema = z.enum([
1916
1958
  "pull",
1917
1959
  "runtime-install",
1960
+ "runtime-remove",
1918
1961
  "calibrate",
1919
1962
  "sweep",
1920
1963
  "bench",
@@ -1993,6 +2036,9 @@ export const BrainModelsPullRequestSchema = z.object({
1993
2036
  type: z.literal("brain.models.pull.request"),
1994
2037
  // Catalog id or name fragment.
1995
2038
  model: z.string(),
2039
+ quant: z.string().optional(),
2040
+ // COMPAT(brainModelBundles): added in v0.8.7, drop the gate when floor >= v0.8.7.
2041
+ components: z.array(z.string()).optional(),
1996
2042
  requestId: z.string(),
1997
2043
  });
1998
2044
  export const BrainModelsPullResponseSchema = z.object({
@@ -2010,6 +2056,15 @@ export const BrainRuntimeInstallResponseSchema = z.object({
2010
2056
  type: z.literal("brain.runtime.install.response"),
2011
2057
  payload: BrainJobResultSchema,
2012
2058
  });
2059
+ export const BrainRuntimeRemoveRequestSchema = z.object({
2060
+ type: z.literal("brain.runtime.remove.request"),
2061
+ name: z.string(),
2062
+ requestId: z.string(),
2063
+ });
2064
+ export const BrainRuntimeRemoveResponseSchema = z.object({
2065
+ type: z.literal("brain.runtime.remove.response"),
2066
+ payload: BrainJobResultSchema,
2067
+ });
2013
2068
  // Measure real KV bytes/token for a model - starts a `calibrate` job. Needs a
2014
2069
  // runtime + GPU; refused with a helpful error otherwise.
2015
2070
  export const BrainCalibrateRequestSchema = z.object({
@@ -2074,6 +2129,8 @@ export const BrainHfSearchResultSchema = z
2074
2129
  downloads: z.number().default(0),
2075
2130
  likes: z.number().default(0),
2076
2131
  gated: z.boolean().default(false),
2132
+ // A short, source-authored excerpt extracted from the repository's model card.
2133
+ summary: z.string().nullable().optional(),
2077
2134
  // True when any quant of this repo is already on disk.
2078
2135
  installed: z.boolean().default(false),
2079
2136
  })
@@ -2085,8 +2142,23 @@ export const BrainRepoQuantSchema = z
2085
2142
  size: z.string().default(""),
2086
2143
  sizeBytes: z.number().default(0),
2087
2144
  files: z.number().default(0),
2145
+ fileNames: z.array(z.string()).optional(),
2088
2146
  // True when this specific quant is already on disk.
2089
2147
  installed: z.boolean().default(false),
2148
+ // The installed model's stable id, when this quant is already on disk.
2149
+ // Optional so daemons predating quant deletion remain compatible.
2150
+ modelId: z.string().nullable().optional(),
2151
+ // The shared projector detected in this repository. It is repeated on
2152
+ // each quant row because the quant picker is the unit that discovers and
2153
+ // presents a downloadable Hugging Face bundle.
2154
+ projector: z
2155
+ .object({
2156
+ file: z.string(),
2157
+ sizeBytes: z.number(),
2158
+ // COMPAT(brainDiscoveredProjectorState): added in v0.8.7, remove after 2027-02-11.
2159
+ installed: z.boolean().optional(),
2160
+ })
2161
+ .optional(),
2090
2162
  })
2091
2163
  .passthrough();
2092
2164
  // Search Hugging Face for GGUF models - `otto-brain search <query>`.
@@ -2123,6 +2195,8 @@ export const BrainModelsAddRequestSchema = z.object({
2123
2195
  type: z.literal("brain.models.add.request"),
2124
2196
  repo: z.string(),
2125
2197
  quant: z.string(),
2198
+ // COMPAT(brainDiscoveredBundleComponents): added in v0.8.7, remove after 2027-02-11.
2199
+ components: z.array(z.string()).optional(),
2126
2200
  requestId: z.string(),
2127
2201
  });
2128
2202
  export const BrainModelsAddResponseSchema = z.object({
@@ -2153,6 +2227,7 @@ export const BrainProfileSchema = z
2153
2227
  flashAttention: z.boolean().default(true),
2154
2228
  gpuLayers: z.number().default(0),
2155
2229
  vision: z.boolean().default(false),
2230
+ enabledComponents: z.array(z.string()).optional(),
2156
2231
  reasoningBudget: z.number().default(0),
2157
2232
  parallelSlots: z.number().default(1),
2158
2233
  })
@@ -2199,6 +2274,9 @@ export const BrainBudgetSchema = z
2199
2274
  .object({
2200
2275
  weightsBytes: z.number().default(0),
2201
2276
  mmprojBytes: z.number().default(0),
2277
+ componentBytes: z.number().optional(),
2278
+ drafterKvBytes: z.number().optional(),
2279
+ imageProcessingBytes: z.number().optional(),
2202
2280
  kvBytes: z.number().default(0),
2203
2281
  overheadBytes: z.number().default(0),
2204
2282
  totalBytes: z.number().default(0),
@@ -2244,6 +2322,22 @@ export const BrainInventoryModelSchema = z
2244
2322
  blockCount: z.number().nullable().default(null),
2245
2323
  headCountKv: z.number().nullable().default(null),
2246
2324
  hasProjector: z.boolean().default(false),
2325
+ components: z
2326
+ .array(z.object({
2327
+ id: z.string(),
2328
+ label: z.string().default(""),
2329
+ description: z.string().default(""),
2330
+ role: z.string().default(""),
2331
+ bytes: z.number().default(0),
2332
+ available: z.boolean().default(false),
2333
+ unavailableReason: z.string().optional(),
2334
+ required: z.boolean().default(false),
2335
+ defaultDownload: z.boolean().default(false),
2336
+ defaultLoad: z.boolean().default(false),
2337
+ minRuntimeBuild: z.number().optional(),
2338
+ }))
2339
+ .nullable()
2340
+ .optional(),
2247
2341
  reasoning: z.boolean().default(false),
2248
2342
  mtp: z.boolean().default(false),
2249
2343
  distilled: z.boolean().default(false),
@@ -2389,6 +2483,21 @@ export const BrainModelDeleteResponseSchema = z.object({
2389
2483
  requestId: z.string(),
2390
2484
  }),
2391
2485
  });
2486
+ export const BrainModelComponentDeleteRequestSchema = z.object({
2487
+ type: z.literal("brain.model.component.delete.request"),
2488
+ modelId: z.string(),
2489
+ componentId: z.string(),
2490
+ requestId: z.string(),
2491
+ });
2492
+ export const BrainModelComponentDeleteResponseSchema = z.object({
2493
+ type: z.literal("brain.model.component.delete.response"),
2494
+ payload: z.object({
2495
+ deleted: z.array(z.string()).default([]),
2496
+ freedBytes: z.number().default(0),
2497
+ error: z.string().nullable(),
2498
+ requestId: z.string(),
2499
+ }),
2500
+ });
2392
2501
  // Rename a model's display name. The brain rejects a collision with another
2393
2502
  // model's current id/displayName: /v1/models keys its id on displayName, and
2394
2503
  // both the completion path and defaultModel/switchTo resolve a model by
@@ -3807,6 +3916,7 @@ export const ProjectKnowledgeKindSchema = z.enum([
3807
3916
  "constraint",
3808
3917
  "requirement",
3809
3918
  "architecture",
3919
+ "finding",
3810
3920
  "project",
3811
3921
  "reference",
3812
3922
  ]);
@@ -3859,10 +3969,13 @@ export const ProjectKnowledgeRecordSchema = z.object({
3859
3969
  .optional(),
3860
3970
  path: z.string().optional(),
3861
3971
  });
3862
- export const ProjectKnowledgeFindingSchema = z.object({
3972
+ /** Review health, not a persisted project-knowledge finding record. */
3973
+ export const ProjectKnowledgeHealthSchema = z.object({
3863
3974
  kind: z.enum(["stale", "overlapping_tags", "overlapping_statement"]),
3864
3975
  recordId: z.string(),
3865
3976
  relatedRecordId: z.string().optional(),
3977
+ tagOverlap: z.enum(["complete", "partial"]).optional(),
3978
+ sharedTags: z.array(z.string()).optional(),
3866
3979
  message: z.string(),
3867
3980
  });
3868
3981
  export const ProjectKnowledgeRootPageSchema = z.object({
@@ -3882,7 +3995,7 @@ export const ProjectKnowledgeListResponseMessageSchema = z.object({
3882
3995
  requestId: z.string(),
3883
3996
  records: z.array(ProjectKnowledgeRecordSchema),
3884
3997
  rootPages: z.array(ProjectKnowledgeRootPageSchema).optional(),
3885
- findings: z.array(ProjectKnowledgeFindingSchema),
3998
+ findings: z.array(ProjectKnowledgeHealthSchema),
3886
3999
  brief: z.string(),
3887
4000
  briefTokens: z.number(),
3888
4001
  includedIds: z.array(z.string()),
@@ -6159,6 +6272,7 @@ export const SessionInboundMessageSchema = z.discriminatedUnion("type", [
6159
6272
  ArchiveAgentRequestMessageSchema,
6160
6273
  CloseItemsRequestMessageSchema,
6161
6274
  HistoryAgentsClearArchivedRequestSchema,
6275
+ HistoryAgentsStorageStatsRequestSchema,
6162
6276
  AttachmentsImagesStatsRequestSchema,
6163
6277
  AttachmentsImagesClearRequestSchema,
6164
6278
  BrainHostStatusRequestSchema,
@@ -6175,6 +6289,7 @@ export const SessionInboundMessageSchema = z.discriminatedUnion("type", [
6175
6289
  BrainRuntimeListRequestSchema,
6176
6290
  BrainModelsPullRequestSchema,
6177
6291
  BrainRuntimeInstallRequestSchema,
6292
+ BrainRuntimeRemoveRequestSchema,
6178
6293
  BrainCalibrateRequestSchema,
6179
6294
  BrainSweepRequestSchema,
6180
6295
  BrainBenchRequestSchema,
@@ -6190,6 +6305,7 @@ export const SessionInboundMessageSchema = z.discriminatedUnion("type", [
6190
6305
  BrainModelLoadRequestSchema,
6191
6306
  BrainModelUnloadRequestSchema,
6192
6307
  BrainModelDeleteRequestSchema,
6308
+ BrainModelComponentDeleteRequestSchema,
6193
6309
  BrainModelRenameRequestSchema,
6194
6310
  BrainModelRenameResetRequestSchema,
6195
6311
  BrainLogsTailRequestSchema,
@@ -6987,6 +7103,8 @@ export const ServerInfoStatusPayloadSchema = z
6987
7103
  // the daemon half of the Storage section; the app-side preview cache row
6988
7104
  // is local and always shown.
6989
7105
  attachmentStorage: z.boolean().optional(),
7106
+ // COMPAT(historyStorage): added in v0.7.2, drop the gate when daemon floor >= v0.7.2.
7107
+ historyStorage: z.boolean().optional(),
6990
7108
  // COMPAT(agentWorkspaceTransfer): added in v0.7.4, drop the gate when
6991
7109
  // daemon floor >= v0.7.4. Set when the daemon serves
6992
7110
  // `agent.workspace.transfer` - moving a chat to another workspace over
@@ -7327,6 +7445,9 @@ const WorkspaceGitRuntimePayloadSchema = z
7327
7445
  remoteUrl: z.string().nullable().optional(),
7328
7446
  isOttoOwnedWorktree: z.boolean().optional(),
7329
7447
  isDirty: z.boolean().nullable().optional(),
7448
+ // COMPAT(workspaceGitBaseRef): added in v0.8.7, remove after 2027-02-10.
7449
+ // The branch-history label is useful only when its comparison base is explicit.
7450
+ baseRef: z.string().nullable().optional(),
7330
7451
  aheadBehind: z
7331
7452
  .object({
7332
7453
  ahead: z.number(),
@@ -7424,6 +7545,16 @@ export const WorkspaceDescriptorPayloadSchema = z
7424
7545
  })
7425
7546
  .nullable()
7426
7547
  .optional(),
7548
+ // COMPAT(workspaceWorkingTreeDiffStat): added in v0.8.7, remove after 2027-02-10.
7549
+ // `diffStat` is retained for older clients and means branch-versus-base.
7550
+ // This field is only the working tree relative to HEAD, so it clears on commit.
7551
+ workingTreeDiffStat: z
7552
+ .object({
7553
+ additions: z.number(),
7554
+ deletions: z.number(),
7555
+ })
7556
+ .nullable()
7557
+ .optional(),
7427
7558
  scripts: z.array(WorkspaceScriptPayloadSchema).default([]),
7428
7559
  gitRuntime: WorkspaceGitRuntimePayloadSchema,
7429
7560
  githubRuntime: WorkspaceGitHubRuntimePayloadSchema,
@@ -10774,6 +10905,7 @@ export const SessionOutboundMessageSchema = z.discriminatedUnion("type", [
10774
10905
  AgentPermissionResolvedMessageSchema,
10775
10906
  AgentDeletedMessageSchema,
10776
10907
  HistoryAgentsClearArchivedResponseSchema,
10908
+ HistoryAgentsStorageStatsResponseSchema,
10777
10909
  AttachmentsImagesStatsResponseSchema,
10778
10910
  AttachmentsImagesClearResponseSchema,
10779
10911
  BrainHostStatusResponseSchema,
@@ -10790,6 +10922,7 @@ export const SessionOutboundMessageSchema = z.discriminatedUnion("type", [
10790
10922
  BrainRuntimeListResponseSchema,
10791
10923
  BrainModelsPullResponseSchema,
10792
10924
  BrainRuntimeInstallResponseSchema,
10925
+ BrainRuntimeRemoveResponseSchema,
10793
10926
  BrainCalibrateResponseSchema,
10794
10927
  BrainSweepResponseSchema,
10795
10928
  BrainBenchResponseSchema,
@@ -10805,6 +10938,7 @@ export const SessionOutboundMessageSchema = z.discriminatedUnion("type", [
10805
10938
  BrainModelLoadResponseSchema,
10806
10939
  BrainModelUnloadResponseSchema,
10807
10940
  BrainModelDeleteResponseSchema,
10941
+ BrainModelComponentDeleteResponseSchema,
10808
10942
  BrainModelRenameResponseSchema,
10809
10943
  BrainModelRenameResetResponseSchema,
10810
10944
  BrainLogsTailResponseSchema,