@sigrun/sigrun 0.0.0-stage → 0.1.1

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.
Files changed (130) hide show
  1. package/CHANGELOG.md +214 -0
  2. package/CONTEXT.md +163 -0
  3. package/LICENSE +21 -0
  4. package/README.md +691 -2
  5. package/THIRD_PARTY_NOTICES.md +28 -0
  6. package/dist/backup/marker.js +80 -0
  7. package/dist/backup/run-backup.js +339 -0
  8. package/dist/cli.js +952 -0
  9. package/dist/commands/expand.js +245 -0
  10. package/dist/commands/templates.js +272 -0
  11. package/dist/config.js +1146 -0
  12. package/dist/extension.d.ts +431 -0
  13. package/dist/harness/activity.js +42 -0
  14. package/dist/harness/ambient.js +261 -0
  15. package/dist/harness/auth.js +130 -0
  16. package/dist/harness/boot.js +865 -0
  17. package/dist/harness/builtins.js +191 -0
  18. package/dist/harness/event-bus.js +1203 -0
  19. package/dist/harness/health.js +30 -0
  20. package/dist/harness/identity/index.js +37 -0
  21. package/dist/harness/identity/invites.js +94 -0
  22. package/dist/harness/identity/json-store.js +108 -0
  23. package/dist/harness/identity/setup-code.js +81 -0
  24. package/dist/harness/identity/tokens.js +101 -0
  25. package/dist/harness/identity/users.js +93 -0
  26. package/dist/harness/interactions.js +283 -0
  27. package/dist/harness/loader.js +1236 -0
  28. package/dist/harness/memory-default.js +35 -0
  29. package/dist/harness/naming.js +193 -0
  30. package/dist/harness/packages.js +1002 -0
  31. package/dist/harness/providers/auth-bridge.js +60 -0
  32. package/dist/harness/providers/index.js +277 -0
  33. package/dist/harness/providers/models-store.js +105 -0
  34. package/dist/harness/providers/refresh.js +161 -0
  35. package/dist/harness/providers/scheduler.js +89 -0
  36. package/dist/harness/registry.js +9 -0
  37. package/dist/harness/reserved-sections.js +24 -0
  38. package/dist/harness/seam-host.js +239 -0
  39. package/dist/harness/sections/context-files.js +78 -0
  40. package/dist/harness/sections/model-guidance.js +77 -0
  41. package/dist/harness/settings.js +1053 -0
  42. package/dist/harness/stores.js +450 -0
  43. package/dist/harness/tools.js +500 -0
  44. package/dist/harness/workspace.js +73 -0
  45. package/dist/index.js +39 -0
  46. package/dist/jobs/docs.js +257 -0
  47. package/dist/jobs/fire.js +342 -0
  48. package/dist/jobs/index.js +228 -0
  49. package/dist/jobs/observe.js +165 -0
  50. package/dist/jobs/reconcile.js +245 -0
  51. package/dist/jobs/schedule.js +77 -0
  52. package/dist/jobs/spec.js +248 -0
  53. package/dist/jobs/task.js +190 -0
  54. package/dist/jobs/transfer.js +53 -0
  55. package/dist/serve.js +164 -0
  56. package/dist/server/auth/claim-lock.js +28 -0
  57. package/dist/server/auth/ip.js +51 -0
  58. package/dist/server/auth/login-limiter.js +52 -0
  59. package/dist/server/auth/loopback.js +47 -0
  60. package/dist/server/auth/pipeline.js +330 -0
  61. package/dist/server/auth/principal.js +26 -0
  62. package/dist/server/commands.js +198 -0
  63. package/dist/server/content-parts.js +142 -0
  64. package/dist/server/context.js +13 -0
  65. package/dist/server/conversation-handler.js +61 -0
  66. package/dist/server/conversation-ops.js +310 -0
  67. package/dist/server/events/hub.js +39 -0
  68. package/dist/server/events/types.js +8 -0
  69. package/dist/server/helpers.js +351 -0
  70. package/dist/server/host-bridge.js +131 -0
  71. package/dist/server/index.js +232 -0
  72. package/dist/server/notifications.js +185 -0
  73. package/dist/server/ownership.js +67 -0
  74. package/dist/server/readiness.js +36 -0
  75. package/dist/server/routes/auth.js +172 -0
  76. package/dist/server/routes/conversations.js +341 -0
  77. package/dist/server/routes/events.js +161 -0
  78. package/dist/server/routes/extension-routes.js +127 -0
  79. package/dist/server/routes/extensions.js +168 -0
  80. package/dist/server/routes/files.js +308 -0
  81. package/dist/server/routes/interactions.js +260 -0
  82. package/dist/server/routes/jobs.js +271 -0
  83. package/dist/server/routes/meta.js +146 -0
  84. package/dist/server/routes/metrics.js +219 -0
  85. package/dist/server/routes/onboarding.js +268 -0
  86. package/dist/server/routes/probes.js +53 -0
  87. package/dist/server/routes/providers.js +198 -0
  88. package/dist/server/routes/settings.js +48 -0
  89. package/dist/server/routes/stream.js +131 -0
  90. package/dist/server/routes/submissions.js +317 -0
  91. package/dist/server/routes/users.js +169 -0
  92. package/dist/server/schema-fixture.js +950 -0
  93. package/dist/server/session-meta.js +247 -0
  94. package/dist/server/static.js +169 -0
  95. package/dist/server/views.js +71 -0
  96. package/dist/skills/index.js +418 -0
  97. package/node_modules/@sigrun/shared/CHANGELOG.md +16 -0
  98. package/node_modules/@sigrun/shared/LICENSE +21 -0
  99. package/node_modules/@sigrun/shared/README.md +10 -0
  100. package/node_modules/@sigrun/shared/dist/access.d.ts +55 -0
  101. package/node_modules/@sigrun/shared/dist/access.js +72 -0
  102. package/node_modules/@sigrun/shared/dist/ambient.d.ts +111 -0
  103. package/node_modules/@sigrun/shared/dist/ambient.js +23 -0
  104. package/node_modules/@sigrun/shared/dist/commands.d.ts +75 -0
  105. package/node_modules/@sigrun/shared/dist/commands.js +25 -0
  106. package/node_modules/@sigrun/shared/dist/conversations.d.ts +31 -0
  107. package/node_modules/@sigrun/shared/dist/conversations.js +94 -0
  108. package/node_modules/@sigrun/shared/dist/interactions.d.ts +91 -0
  109. package/node_modules/@sigrun/shared/dist/interactions.js +21 -0
  110. package/node_modules/@sigrun/shared/dist/jobs.d.ts +100 -0
  111. package/node_modules/@sigrun/shared/dist/jobs.js +19 -0
  112. package/node_modules/@sigrun/shared/dist/json.d.ts +20 -0
  113. package/node_modules/@sigrun/shared/dist/json.js +13 -0
  114. package/node_modules/@sigrun/shared/dist/session-meta.d.ts +103 -0
  115. package/node_modules/@sigrun/shared/dist/session-meta.js +13 -0
  116. package/node_modules/@sigrun/shared/dist/settings.d.ts +401 -0
  117. package/node_modules/@sigrun/shared/dist/settings.js +19 -0
  118. package/node_modules/@sigrun/shared/dist/themes.d.ts +50 -0
  119. package/node_modules/@sigrun/shared/dist/themes.js +156 -0
  120. package/node_modules/@sigrun/shared/dist/turns.d.ts +102 -0
  121. package/node_modules/@sigrun/shared/dist/turns.js +166 -0
  122. package/node_modules/@sigrun/shared/dist/view-delta.d.ts +54 -0
  123. package/node_modules/@sigrun/shared/dist/view-delta.js +135 -0
  124. package/node_modules/@sigrun/shared/dist/views.d.ts +742 -0
  125. package/node_modules/@sigrun/shared/dist/views.js +38 -0
  126. package/node_modules/@sigrun/shared/package.json +83 -0
  127. package/package.json +89 -5
  128. package/webui/dist/assets/index-Rl0KhCLa.css +1 -0
  129. package/webui/dist/assets/index-rOiARZLF.js +50 -0
  130. package/webui/dist/index.html +37 -0
@@ -0,0 +1,950 @@
1
+ /**
2
+ * The captured-schema fixture (spec §5 "Captured schema", Task 9a Step 1).
3
+ *
4
+ * The §5 server serializes pi-durable's native `ConversationView` verbatim —
5
+ * there is no sigrun-side projection — so the wire contract sigrun's clients
6
+ * (webui) compile against is exactly upstream's view shape. Upstream churn
7
+ * must surface as a TEST FAILURE, not a runtime surprise: the shape of a real
8
+ * `ConversationView` (keys + value types, never literal values) is captured
9
+ * into {@link VIEW_SCHEMA} (mirrored into `test/fixtures/view-schema.json`;
10
+ * the drift test asserts the two are the same value) and
11
+ * `test/schema-drift.test.ts` re-captures a live hermetic view and asserts it
12
+ * still matches.
13
+ *
14
+ * `GET /v1/meta` serves {@link SCHEMA_VERSION} — the sha256 of the fixture's
15
+ * canonical JSON — so a webui can refuse to render on mismatch (fail loud).
16
+ * The hash is computed from {@link VIEW_SCHEMA} at module load, never stored:
17
+ * the constant and the hash cannot drift apart.
18
+ *
19
+ * The fixture is captured from ONE deterministic hermetic scenario (root
20
+ * conversation, one settled faux turn) with a fixed provider/model id
21
+ * (`faux/m`): shape keys that are dictionaries keyed by dynamic names
22
+ * (`docs["pi.usage"].models`) therefore appear literally. The drift test
23
+ * replays exactly that scenario. Shape variants that the scenario does not
24
+ * exercise (tool-call entries, compaction summaries, busy inboxes) are out of
25
+ * fixture scope; drift on the shared structures (EntryRecord base fields,
26
+ * Message, the built-in docs) still trips the wire.
27
+ */
28
+ import { createHash } from "node:crypto";
29
+ import { createRequire } from "node:module";
30
+ /**
31
+ * The pinned pi-durable package version, reported as `GET /v1/meta`
32
+ * `harnessVersion`. Read from the installed package's manifest through
33
+ * `createRequire` (a bundler-stable CJS require of the exported
34
+ * `./package.json` subpath), so a dependency bump moves it without a source
35
+ * edit — the fixture and this version both follow the pin.
36
+ */
37
+ export const HARNESS_VERSION = createRequire(import.meta.url)("@earendil-works/pi-durable/package.json").version;
38
+ const NULL = { kind: "null" };
39
+ const BOOLEAN = { kind: "boolean" };
40
+ const NUMBER = { kind: "number" };
41
+ const STRING = { kind: "string" };
42
+ /** Canonical JSON of a shape: object keys sorted at every depth. */
43
+ export function canonicalJson(shape) {
44
+ // The projection keeps the `kind` discriminators, so `JSON.parse` of the
45
+ // result is the same Shape again (round-trip safe — dedupe and hashing
46
+ // below rely on that).
47
+ const project = (value) => {
48
+ switch (value.kind) {
49
+ case "array":
50
+ // Variants are already canonically ordered (see mergeVariants).
51
+ return { kind: "array", variants: value.variants.map(project) };
52
+ case "object": {
53
+ const fields = {};
54
+ for (const key of Object.keys(value.fields).sort()) {
55
+ fields[key] = project(value.fields[key]);
56
+ }
57
+ return { kind: "object", fields };
58
+ }
59
+ default:
60
+ return value;
61
+ }
62
+ };
63
+ return JSON.stringify(project(shape));
64
+ }
65
+ function shapeOfValue(value) {
66
+ if (value === null)
67
+ return NULL;
68
+ switch (typeof value) {
69
+ case "boolean":
70
+ return BOOLEAN;
71
+ case "number":
72
+ return NUMBER;
73
+ case "string":
74
+ return STRING;
75
+ case "object":
76
+ if (Array.isArray(value)) {
77
+ return { kind: "array", variants: mergeVariants(value.map(shapeOfValue)) };
78
+ }
79
+ const fields = {};
80
+ for (const [key, entry] of Object.entries(value)) {
81
+ if (entry !== undefined)
82
+ fields[key] = shapeOfValue(entry);
83
+ }
84
+ return { kind: "object", fields };
85
+ default:
86
+ throw new Error(`ConversationView contains a non-JSON value of type ${typeof value}`);
87
+ }
88
+ }
89
+ /** Distinct shapes, deduped by canonical JSON and ordered by it. */
90
+ function mergeVariants(shapes) {
91
+ const distinct = new Map();
92
+ for (const shape of shapes) {
93
+ const key = canonicalJson(shape);
94
+ if (!distinct.has(key))
95
+ distinct.set(key, shape);
96
+ }
97
+ return [...distinct.entries()]
98
+ .sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0))
99
+ .map(([, shape]) => shape);
100
+ }
101
+ /**
102
+ * Serialize one live `ConversationView` into its structural shape.
103
+ *
104
+ * Arrays record the SET of distinct element shapes (not one merged shape), so
105
+ * heterogeneous arrays — `entries` (pi.user / pi.system / pi.assistant),
106
+ * `model` (user / system / assistant messages) — keep per-variant field
107
+ * presence, and a field moving between variants or appearing anew fails the
108
+ * fixture match instead of being averaged away.
109
+ */
110
+ export function captureViewShape(view) {
111
+ return shapeOfValue(view);
112
+ }
113
+ /** sha256 hex of a string. */
114
+ function sha256(text) {
115
+ return createHash("sha256").update(text).digest("hex");
116
+ }
117
+ /**
118
+ * The captured fixture: the shape of a real root-conversation `ConversationView`
119
+ * after one settled turn, captured from the pinned `@earendil-works/pi-durable`
120
+ * (see `test/fixtures/view-schema.json` — the same value as a committed file,
121
+ * and `test/schema-drift.test.ts` fails if the two ever diverge).
122
+ */
123
+ export const VIEW_SCHEMA = {
124
+ "kind": "object",
125
+ "fields": {
126
+ "conversation": {
127
+ "kind": "object",
128
+ "fields": {
129
+ "id": {
130
+ "kind": "number"
131
+ }
132
+ }
133
+ },
134
+ "entries": {
135
+ "kind": "array",
136
+ "variants": [
137
+ {
138
+ "kind": "object",
139
+ "fields": {
140
+ "model": {
141
+ "kind": "array",
142
+ "variants": [
143
+ {
144
+ "kind": "object",
145
+ "fields": {
146
+ "role": {
147
+ "kind": "string"
148
+ },
149
+ "content": {
150
+ "kind": "array",
151
+ "variants": [
152
+ {
153
+ "kind": "object",
154
+ "fields": {
155
+ "type": {
156
+ "kind": "string"
157
+ },
158
+ "text": {
159
+ "kind": "string"
160
+ }
161
+ }
162
+ }
163
+ ]
164
+ },
165
+ "api": {
166
+ "kind": "string"
167
+ },
168
+ "provider": {
169
+ "kind": "string"
170
+ },
171
+ "model": {
172
+ "kind": "string"
173
+ },
174
+ "usage": {
175
+ "kind": "object",
176
+ "fields": {
177
+ "input": {
178
+ "kind": "number"
179
+ },
180
+ "output": {
181
+ "kind": "number"
182
+ },
183
+ "cacheRead": {
184
+ "kind": "number"
185
+ },
186
+ "cacheWrite": {
187
+ "kind": "number"
188
+ },
189
+ "totalTokens": {
190
+ "kind": "number"
191
+ },
192
+ "cost": {
193
+ "kind": "object",
194
+ "fields": {
195
+ "input": {
196
+ "kind": "number"
197
+ },
198
+ "output": {
199
+ "kind": "number"
200
+ },
201
+ "cacheRead": {
202
+ "kind": "number"
203
+ },
204
+ "cacheWrite": {
205
+ "kind": "number"
206
+ },
207
+ "total": {
208
+ "kind": "number"
209
+ }
210
+ }
211
+ }
212
+ }
213
+ },
214
+ "stopReason": {
215
+ "kind": "string"
216
+ },
217
+ "timestamp": {
218
+ "kind": "number"
219
+ }
220
+ }
221
+ }
222
+ ]
223
+ },
224
+ "kind": {
225
+ "kind": "string"
226
+ },
227
+ "id": {
228
+ "kind": "number"
229
+ },
230
+ "conversationId": {
231
+ "kind": "number"
232
+ },
233
+ "byTaskId": {
234
+ "kind": "number"
235
+ }
236
+ }
237
+ },
238
+ {
239
+ "kind": "object",
240
+ "fields": {
241
+ "model": {
242
+ "kind": "array",
243
+ "variants": [
244
+ {
245
+ "kind": "object",
246
+ "fields": {
247
+ "role": {
248
+ "kind": "string"
249
+ },
250
+ "content": {
251
+ "kind": "string"
252
+ },
253
+ "sections": {
254
+ "kind": "object",
255
+ "fields": {
256
+ "identity": {
257
+ "kind": "string"
258
+ },
259
+ "persona": {
260
+ "kind": "string"
261
+ },
262
+ "codemode": {
263
+ "kind": "string"
264
+ },
265
+ "long-term-memory": {
266
+ "kind": "string"
267
+ }
268
+ }
269
+ },
270
+ "toolsAdded": {
271
+ "kind": "array",
272
+ "variants": [
273
+ {
274
+ "kind": "object",
275
+ "fields": {
276
+ "name": {
277
+ "kind": "string"
278
+ },
279
+ "description": {
280
+ "kind": "string"
281
+ },
282
+ "parameters": {
283
+ "kind": "object",
284
+ "fields": {
285
+ "type": {
286
+ "kind": "string"
287
+ },
288
+ "required": {
289
+ "kind": "array",
290
+ "variants": [
291
+ {
292
+ "kind": "string"
293
+ }
294
+ ]
295
+ },
296
+ "properties": {
297
+ "kind": "object",
298
+ "fields": {
299
+ "code": {
300
+ "kind": "object",
301
+ "fields": {
302
+ "type": {
303
+ "kind": "string"
304
+ },
305
+ "description": {
306
+ "kind": "string"
307
+ }
308
+ }
309
+ }
310
+ }
311
+ }
312
+ }
313
+ },
314
+ "constrainedSampling": {
315
+ "kind": "object",
316
+ "fields": {
317
+ "type": {
318
+ "kind": "string"
319
+ },
320
+ "variants": {
321
+ "kind": "object",
322
+ "fields": {
323
+ "openai_lark": {
324
+ "kind": "string"
325
+ }
326
+ }
327
+ }
328
+ }
329
+ }
330
+ }
331
+ },
332
+ {
333
+ "kind": "object",
334
+ "fields": {
335
+ "name": {
336
+ "kind": "string"
337
+ },
338
+ "description": {
339
+ "kind": "string"
340
+ },
341
+ "parameters": {
342
+ "kind": "object",
343
+ "fields": {
344
+ "type": {
345
+ "kind": "string"
346
+ },
347
+ "required": {
348
+ "kind": "array",
349
+ "variants": [
350
+ {
351
+ "kind": "string"
352
+ }
353
+ ]
354
+ },
355
+ "properties": {
356
+ "kind": "object",
357
+ "fields": {
358
+ "command": {
359
+ "kind": "object",
360
+ "fields": {
361
+ "type": {
362
+ "kind": "string"
363
+ },
364
+ "description": {
365
+ "kind": "string"
366
+ }
367
+ }
368
+ },
369
+ "timeout": {
370
+ "kind": "object",
371
+ "fields": {
372
+ "type": {
373
+ "kind": "string"
374
+ },
375
+ "description": {
376
+ "kind": "string"
377
+ }
378
+ }
379
+ }
380
+ }
381
+ }
382
+ }
383
+ }
384
+ }
385
+ },
386
+ {
387
+ "kind": "object",
388
+ "fields": {
389
+ "name": {
390
+ "kind": "string"
391
+ },
392
+ "description": {
393
+ "kind": "string"
394
+ },
395
+ "parameters": {
396
+ "kind": "object",
397
+ "fields": {
398
+ "type": {
399
+ "kind": "string"
400
+ },
401
+ "required": {
402
+ "kind": "array",
403
+ "variants": [
404
+ {
405
+ "kind": "string"
406
+ }
407
+ ]
408
+ },
409
+ "properties": {
410
+ "kind": "object",
411
+ "fields": {
412
+ "path": {
413
+ "kind": "object",
414
+ "fields": {
415
+ "type": {
416
+ "kind": "string"
417
+ },
418
+ "description": {
419
+ "kind": "string"
420
+ }
421
+ }
422
+ },
423
+ "content": {
424
+ "kind": "object",
425
+ "fields": {
426
+ "type": {
427
+ "kind": "string"
428
+ },
429
+ "description": {
430
+ "kind": "string"
431
+ }
432
+ }
433
+ }
434
+ }
435
+ }
436
+ }
437
+ }
438
+ }
439
+ },
440
+ {
441
+ "kind": "object",
442
+ "fields": {
443
+ "name": {
444
+ "kind": "string"
445
+ },
446
+ "description": {
447
+ "kind": "string"
448
+ },
449
+ "parameters": {
450
+ "kind": "object",
451
+ "fields": {
452
+ "type": {
453
+ "kind": "string"
454
+ },
455
+ "required": {
456
+ "kind": "array",
457
+ "variants": [
458
+ {
459
+ "kind": "string"
460
+ }
461
+ ]
462
+ },
463
+ "properties": {
464
+ "kind": "object",
465
+ "fields": {
466
+ "path": {
467
+ "kind": "object",
468
+ "fields": {
469
+ "type": {
470
+ "kind": "string"
471
+ },
472
+ "description": {
473
+ "kind": "string"
474
+ }
475
+ }
476
+ },
477
+ "edits": {
478
+ "kind": "object",
479
+ "fields": {
480
+ "type": {
481
+ "kind": "string"
482
+ },
483
+ "items": {
484
+ "kind": "object",
485
+ "fields": {
486
+ "type": {
487
+ "kind": "string"
488
+ },
489
+ "required": {
490
+ "kind": "array",
491
+ "variants": [
492
+ {
493
+ "kind": "string"
494
+ }
495
+ ]
496
+ },
497
+ "properties": {
498
+ "kind": "object",
499
+ "fields": {
500
+ "oldText": {
501
+ "kind": "object",
502
+ "fields": {
503
+ "type": {
504
+ "kind": "string"
505
+ },
506
+ "description": {
507
+ "kind": "string"
508
+ }
509
+ }
510
+ },
511
+ "newText": {
512
+ "kind": "object",
513
+ "fields": {
514
+ "type": {
515
+ "kind": "string"
516
+ },
517
+ "description": {
518
+ "kind": "string"
519
+ }
520
+ }
521
+ }
522
+ }
523
+ }
524
+ }
525
+ },
526
+ "description": {
527
+ "kind": "string"
528
+ }
529
+ }
530
+ }
531
+ }
532
+ }
533
+ }
534
+ }
535
+ }
536
+ },
537
+ {
538
+ "kind": "object",
539
+ "fields": {
540
+ "name": {
541
+ "kind": "string"
542
+ },
543
+ "description": {
544
+ "kind": "string"
545
+ },
546
+ "parameters": {
547
+ "kind": "object",
548
+ "fields": {
549
+ "type": {
550
+ "kind": "string"
551
+ },
552
+ "required": {
553
+ "kind": "array",
554
+ "variants": [
555
+ {
556
+ "kind": "string"
557
+ }
558
+ ]
559
+ },
560
+ "properties": {
561
+ "kind": "object",
562
+ "fields": {
563
+ "path": {
564
+ "kind": "object",
565
+ "fields": {
566
+ "type": {
567
+ "kind": "string"
568
+ },
569
+ "description": {
570
+ "kind": "string"
571
+ }
572
+ }
573
+ },
574
+ "offset": {
575
+ "kind": "object",
576
+ "fields": {
577
+ "type": {
578
+ "kind": "string"
579
+ },
580
+ "description": {
581
+ "kind": "string"
582
+ }
583
+ }
584
+ },
585
+ "limit": {
586
+ "kind": "object",
587
+ "fields": {
588
+ "type": {
589
+ "kind": "string"
590
+ },
591
+ "description": {
592
+ "kind": "string"
593
+ }
594
+ }
595
+ }
596
+ }
597
+ }
598
+ }
599
+ }
600
+ }
601
+ },
602
+ {
603
+ "kind": "object",
604
+ "fields": {
605
+ "name": {
606
+ "kind": "string"
607
+ },
608
+ "description": {
609
+ "kind": "string"
610
+ },
611
+ "parameters": {
612
+ "kind": "object",
613
+ "fields": {
614
+ "type": {
615
+ "kind": "string"
616
+ },
617
+ "required": {
618
+ "kind": "array",
619
+ "variants": [
620
+ {
621
+ "kind": "string"
622
+ }
623
+ ]
624
+ },
625
+ "properties": {
626
+ "kind": "object",
627
+ "fields": {
628
+ "query": {
629
+ "kind": "object",
630
+ "fields": {
631
+ "type": {
632
+ "kind": "string"
633
+ },
634
+ "description": {
635
+ "kind": "string"
636
+ }
637
+ }
638
+ },
639
+ "limit": {
640
+ "kind": "object",
641
+ "fields": {
642
+ "type": {
643
+ "kind": "string"
644
+ },
645
+ "description": {
646
+ "kind": "string"
647
+ }
648
+ }
649
+ }
650
+ }
651
+ }
652
+ }
653
+ }
654
+ }
655
+ },
656
+ {
657
+ "kind": "object",
658
+ "fields": {
659
+ "name": {
660
+ "kind": "string"
661
+ },
662
+ "description": {
663
+ "kind": "string"
664
+ },
665
+ "parameters": {
666
+ "kind": "object",
667
+ "fields": {
668
+ "type": {
669
+ "kind": "string"
670
+ },
671
+ "required": {
672
+ "kind": "array",
673
+ "variants": [
674
+ {
675
+ "kind": "string"
676
+ }
677
+ ]
678
+ },
679
+ "properties": {
680
+ "kind": "object",
681
+ "fields": {
682
+ "name": {
683
+ "kind": "object",
684
+ "fields": {
685
+ "type": {
686
+ "kind": "string"
687
+ },
688
+ "description": {
689
+ "kind": "string"
690
+ }
691
+ }
692
+ }
693
+ }
694
+ }
695
+ }
696
+ }
697
+ }
698
+ },
699
+ {
700
+ "kind": "object",
701
+ "fields": {
702
+ "name": {
703
+ "kind": "string"
704
+ },
705
+ "description": {
706
+ "kind": "string"
707
+ },
708
+ "parameters": {
709
+ "kind": "object",
710
+ "fields": {
711
+ "type": {
712
+ "kind": "string"
713
+ },
714
+ "required": {
715
+ "kind": "array",
716
+ "variants": [
717
+ {
718
+ "kind": "string"
719
+ }
720
+ ]
721
+ },
722
+ "properties": {
723
+ "kind": "object",
724
+ "fields": {
725
+ "pattern": {
726
+ "kind": "object",
727
+ "fields": {
728
+ "type": {
729
+ "kind": "string"
730
+ },
731
+ "description": {
732
+ "kind": "string"
733
+ }
734
+ }
735
+ },
736
+ "path": {
737
+ "kind": "object",
738
+ "fields": {
739
+ "type": {
740
+ "kind": "string"
741
+ },
742
+ "description": {
743
+ "kind": "string"
744
+ }
745
+ }
746
+ }
747
+ }
748
+ }
749
+ }
750
+ }
751
+ }
752
+ },
753
+ {
754
+ "kind": "object",
755
+ "fields": {
756
+ "name": {
757
+ "kind": "string"
758
+ },
759
+ "description": {
760
+ "kind": "string"
761
+ },
762
+ "parameters": {
763
+ "kind": "object",
764
+ "fields": {
765
+ "type": {
766
+ "kind": "string"
767
+ },
768
+ "properties": {
769
+ "kind": "object",
770
+ "fields": {
771
+ "path": {
772
+ "kind": "object",
773
+ "fields": {
774
+ "type": {
775
+ "kind": "string"
776
+ },
777
+ "description": {
778
+ "kind": "string"
779
+ }
780
+ }
781
+ }
782
+ }
783
+ }
784
+ }
785
+ }
786
+ }
787
+ }
788
+ ]
789
+ },
790
+ "timestamp": {
791
+ "kind": "number"
792
+ }
793
+ }
794
+ }
795
+ ]
796
+ },
797
+ "kind": {
798
+ "kind": "string"
799
+ },
800
+ "id": {
801
+ "kind": "number"
802
+ },
803
+ "conversationId": {
804
+ "kind": "number"
805
+ },
806
+ "byTaskId": {
807
+ "kind": "number"
808
+ }
809
+ }
810
+ },
811
+ {
812
+ "kind": "object",
813
+ "fields": {
814
+ "model": {
815
+ "kind": "array",
816
+ "variants": [
817
+ {
818
+ "kind": "object",
819
+ "fields": {
820
+ "role": {
821
+ "kind": "string"
822
+ },
823
+ "content": {
824
+ "kind": "string"
825
+ },
826
+ "timestamp": {
827
+ "kind": "number"
828
+ }
829
+ }
830
+ }
831
+ ]
832
+ },
833
+ "kind": {
834
+ "kind": "string"
835
+ },
836
+ "id": {
837
+ "kind": "number"
838
+ },
839
+ "conversationId": {
840
+ "kind": "number"
841
+ }
842
+ }
843
+ }
844
+ ]
845
+ },
846
+ "docs": {
847
+ "kind": "object",
848
+ "fields": {
849
+ "pi.agent": {
850
+ "kind": "object",
851
+ "fields": {
852
+ "model": {
853
+ "kind": "object",
854
+ "fields": {
855
+ "provider": {
856
+ "kind": "string"
857
+ },
858
+ "modelId": {
859
+ "kind": "string"
860
+ }
861
+ }
862
+ }
863
+ }
864
+ },
865
+ "pi.live": {
866
+ "kind": "object",
867
+ "fields": {}
868
+ },
869
+ "pi.inbox": {
870
+ "kind": "object",
871
+ "fields": {
872
+ "items": {
873
+ "kind": "array",
874
+ "variants": []
875
+ }
876
+ }
877
+ },
878
+ "pi.provider": {
879
+ "kind": "object",
880
+ "fields": {
881
+ "sessionId": {
882
+ "kind": "string"
883
+ }
884
+ }
885
+ },
886
+ "pi.usage": {
887
+ "kind": "object",
888
+ "fields": {
889
+ "models": {
890
+ "kind": "object",
891
+ "fields": {
892
+ "faux/m": {
893
+ "kind": "object",
894
+ "fields": {
895
+ "input": {
896
+ "kind": "number"
897
+ },
898
+ "output": {
899
+ "kind": "number"
900
+ },
901
+ "cacheRead": {
902
+ "kind": "number"
903
+ },
904
+ "cacheWrite": {
905
+ "kind": "number"
906
+ },
907
+ "totalTokens": {
908
+ "kind": "number"
909
+ },
910
+ "cost": {
911
+ "kind": "object",
912
+ "fields": {
913
+ "input": {
914
+ "kind": "number"
915
+ },
916
+ "output": {
917
+ "kind": "number"
918
+ },
919
+ "cacheRead": {
920
+ "kind": "number"
921
+ },
922
+ "cacheWrite": {
923
+ "kind": "number"
924
+ },
925
+ "total": {
926
+ "kind": "number"
927
+ }
928
+ }
929
+ }
930
+ }
931
+ }
932
+ }
933
+ },
934
+ "tools": {
935
+ "kind": "object",
936
+ "fields": {}
937
+ }
938
+ }
939
+ }
940
+ }
941
+ }
942
+ }
943
+ };
944
+ /**
945
+ * The fixture's schema version: sha256 of {@link VIEW_SCHEMA}'s canonical
946
+ * JSON. Upstream drift that changes any captured key or value type changes
947
+ * the fixture, which changes this hash — `GET /v1/meta` serves it and the
948
+ * webui refuses to render on string inequality (fail loud, spec §5).
949
+ */
950
+ export const SCHEMA_VERSION = sha256(canonicalJson(VIEW_SCHEMA));