@loopbacktools/protocol 0.0.0-stage → 0.4.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.
@@ -0,0 +1,1903 @@
1
+ {
2
+ "openapi": "3.1.0",
3
+ "info": {
4
+ "title": "Loopback",
5
+ "description": "Loopback puts what an agent needs from a person in front of them and hands the reply back.\n\nAn agent asks over MCP; a person answers through this API, usually from the web inbox. Live updates\narrive over the WebSocket at `/api/v1/events`, which sends a `SnapshotEvent` and then `AskEvent`s.\n\nEvery response names the code that answered: `Loopback-Revision`, the revision of this contract the\nserver writes, and `Loopback-Build`, when the deploy it is from was made. A client that names the\nrevision it writes in `Loopback-Revision` on its requests learns when the server is newer than\nitself, and is refused with `409` and the code `reload` when it is the newer, as after a rollback.",
6
+ "version": "1"
7
+ },
8
+ "tags": [],
9
+ "paths": {
10
+ "/asks": {
11
+ "get": {
12
+ "operationId": "Asks_list",
13
+ "description": "Closed asks, newest first, for paging back through history.",
14
+ "parameters": [
15
+ {
16
+ "name": "before",
17
+ "in": "query",
18
+ "required": false,
19
+ "description": "Only asks closed before this moment.",
20
+ "schema": {
21
+ "type": "string",
22
+ "format": "date-time"
23
+ },
24
+ "explode": false
25
+ },
26
+ {
27
+ "name": "limit",
28
+ "in": "query",
29
+ "required": false,
30
+ "schema": {
31
+ "type": "integer",
32
+ "format": "int32",
33
+ "minimum": 1,
34
+ "maximum": 100
35
+ },
36
+ "explode": false
37
+ }
38
+ ],
39
+ "responses": {
40
+ "200": {
41
+ "description": "The request has succeeded.",
42
+ "content": {
43
+ "application/json": {
44
+ "schema": {
45
+ "$ref": "#/components/schemas/AskPage"
46
+ }
47
+ }
48
+ }
49
+ },
50
+ "401": {
51
+ "description": "Access is unauthorized.",
52
+ "content": {
53
+ "application/json": {
54
+ "schema": {
55
+ "$ref": "#/components/schemas/Problem"
56
+ }
57
+ }
58
+ }
59
+ }
60
+ },
61
+ "security": [
62
+ {
63
+ "BearerAuth": []
64
+ }
65
+ ]
66
+ }
67
+ },
68
+ "/asks/{id}": {
69
+ "get": {
70
+ "operationId": "Asks_read",
71
+ "parameters": [
72
+ {
73
+ "name": "id",
74
+ "in": "path",
75
+ "required": true,
76
+ "schema": {
77
+ "type": "string"
78
+ }
79
+ }
80
+ ],
81
+ "responses": {
82
+ "200": {
83
+ "description": "The request has succeeded.",
84
+ "content": {
85
+ "application/json": {
86
+ "schema": {
87
+ "$ref": "#/components/schemas/Ask"
88
+ }
89
+ }
90
+ }
91
+ },
92
+ "401": {
93
+ "description": "Access is unauthorized.",
94
+ "content": {
95
+ "application/json": {
96
+ "schema": {
97
+ "$ref": "#/components/schemas/Problem"
98
+ }
99
+ }
100
+ }
101
+ },
102
+ "404": {
103
+ "description": "The server cannot find the requested resource.",
104
+ "content": {
105
+ "application/json": {
106
+ "schema": {
107
+ "$ref": "#/components/schemas/Problem"
108
+ }
109
+ }
110
+ }
111
+ }
112
+ },
113
+ "security": [
114
+ {
115
+ "BearerAuth": []
116
+ }
117
+ ]
118
+ }
119
+ },
120
+ "/asks/{id}/reply": {
121
+ "post": {
122
+ "operationId": "Asks_reply",
123
+ "description": "Reply to an ask. Refused with 409 when the ask is closed or it is the agent's turn, except that\na briefing may be dismissed during the agent's turn. Refused with 422 when the reply does not\nfit: `answered` is for questions and needs a choice or text, with choices among those offered\nand only one unless several are allowed; `approved` and `changes_requested` are for reviews;\n`responded` is for briefings, names each of their points at most once with words or resolved,\nand either resolves every point or leaves the agent a point to answer. A briefing takes no\n`follow_up`.",
124
+ "parameters": [
125
+ {
126
+ "name": "id",
127
+ "in": "path",
128
+ "required": true,
129
+ "schema": {
130
+ "type": "string"
131
+ }
132
+ }
133
+ ],
134
+ "responses": {
135
+ "200": {
136
+ "description": "The request has succeeded.",
137
+ "content": {
138
+ "application/json": {
139
+ "schema": {
140
+ "$ref": "#/components/schemas/Ask"
141
+ }
142
+ }
143
+ }
144
+ },
145
+ "401": {
146
+ "description": "Access is unauthorized.",
147
+ "content": {
148
+ "application/json": {
149
+ "schema": {
150
+ "$ref": "#/components/schemas/Problem"
151
+ }
152
+ }
153
+ }
154
+ },
155
+ "404": {
156
+ "description": "The server cannot find the requested resource.",
157
+ "content": {
158
+ "application/json": {
159
+ "schema": {
160
+ "$ref": "#/components/schemas/Problem"
161
+ }
162
+ }
163
+ }
164
+ },
165
+ "409": {
166
+ "description": "The request conflicts with the current state of the server.",
167
+ "content": {
168
+ "application/json": {
169
+ "schema": {
170
+ "$ref": "#/components/schemas/Problem"
171
+ }
172
+ }
173
+ }
174
+ },
175
+ "422": {
176
+ "description": "Client error",
177
+ "content": {
178
+ "application/json": {
179
+ "schema": {
180
+ "$ref": "#/components/schemas/Problem"
181
+ }
182
+ }
183
+ }
184
+ }
185
+ },
186
+ "requestBody": {
187
+ "required": true,
188
+ "content": {
189
+ "application/json": {
190
+ "schema": {
191
+ "$ref": "#/components/schemas/Reply"
192
+ }
193
+ }
194
+ }
195
+ },
196
+ "security": [
197
+ {
198
+ "BearerAuth": []
199
+ }
200
+ ]
201
+ }
202
+ },
203
+ "/events/tickets": {
204
+ "post": {
205
+ "operationId": "EventTickets_issue",
206
+ "description": "A one-time pass onto the event socket, `/api/v1/events`.",
207
+ "parameters": [],
208
+ "responses": {
209
+ "201": {
210
+ "description": "The request has succeeded and a new resource has been created as a result.",
211
+ "content": {
212
+ "application/json": {
213
+ "schema": {
214
+ "$ref": "#/components/schemas/EventTicket"
215
+ }
216
+ }
217
+ }
218
+ },
219
+ "401": {
220
+ "description": "Access is unauthorized.",
221
+ "content": {
222
+ "application/json": {
223
+ "schema": {
224
+ "$ref": "#/components/schemas/Problem"
225
+ }
226
+ }
227
+ }
228
+ }
229
+ },
230
+ "security": [
231
+ {
232
+ "BearerAuth": []
233
+ }
234
+ ]
235
+ }
236
+ },
237
+ "/files/{uploadId}": {
238
+ "get": {
239
+ "operationId": "Files_read",
240
+ "description": "An uploaded image.",
241
+ "parameters": [
242
+ {
243
+ "name": "uploadId",
244
+ "in": "path",
245
+ "required": true,
246
+ "schema": {
247
+ "type": "string"
248
+ }
249
+ }
250
+ ],
251
+ "responses": {
252
+ "200": {
253
+ "description": "The request has succeeded.",
254
+ "content": {
255
+ "image/png": {
256
+ "schema": {
257
+ "contentMediaType": "image/png"
258
+ }
259
+ },
260
+ "image/jpeg": {
261
+ "schema": {
262
+ "contentMediaType": "image/jpeg"
263
+ }
264
+ },
265
+ "image/webp": {
266
+ "schema": {
267
+ "contentMediaType": "image/webp"
268
+ }
269
+ },
270
+ "image/gif": {
271
+ "schema": {
272
+ "contentMediaType": "image/gif"
273
+ }
274
+ }
275
+ }
276
+ },
277
+ "401": {
278
+ "description": "Access is unauthorized.",
279
+ "content": {
280
+ "application/json": {
281
+ "schema": {
282
+ "$ref": "#/components/schemas/Problem"
283
+ }
284
+ }
285
+ }
286
+ },
287
+ "404": {
288
+ "description": "The server cannot find the requested resource.",
289
+ "content": {
290
+ "application/json": {
291
+ "schema": {
292
+ "$ref": "#/components/schemas/Problem"
293
+ }
294
+ }
295
+ }
296
+ }
297
+ },
298
+ "security": [
299
+ {
300
+ "BearerAuth": []
301
+ }
302
+ ]
303
+ }
304
+ },
305
+ "/snapshot": {
306
+ "get": {
307
+ "operationId": "Snapshots_read",
308
+ "description": "Every open ask and the fifty most recently closed: what an inbox starts from.",
309
+ "parameters": [],
310
+ "responses": {
311
+ "200": {
312
+ "description": "The request has succeeded.",
313
+ "content": {
314
+ "application/json": {
315
+ "schema": {
316
+ "$ref": "#/components/schemas/Snapshot"
317
+ }
318
+ }
319
+ }
320
+ },
321
+ "401": {
322
+ "description": "Access is unauthorized.",
323
+ "content": {
324
+ "application/json": {
325
+ "schema": {
326
+ "$ref": "#/components/schemas/Problem"
327
+ }
328
+ }
329
+ }
330
+ }
331
+ },
332
+ "security": [
333
+ {
334
+ "BearerAuth": []
335
+ }
336
+ ]
337
+ }
338
+ },
339
+ "/uploads/{spaceId}/{token}": {
340
+ "put": {
341
+ "operationId": "Uploads_store",
342
+ "description": "Store an image against an upload ticket. The URL is the credential: it works once, for\nfifteen minutes, for the declared content type, up to the ticket's `maxBytes`.",
343
+ "parameters": [
344
+ {
345
+ "name": "spaceId",
346
+ "in": "path",
347
+ "required": true,
348
+ "schema": {
349
+ "type": "string"
350
+ }
351
+ },
352
+ {
353
+ "name": "token",
354
+ "in": "path",
355
+ "required": true,
356
+ "schema": {
357
+ "type": "string"
358
+ }
359
+ }
360
+ ],
361
+ "responses": {
362
+ "201": {
363
+ "description": "The request has succeeded and a new resource has been created as a result.",
364
+ "content": {
365
+ "application/json": {
366
+ "schema": {
367
+ "$ref": "#/components/schemas/UploadReceipt"
368
+ }
369
+ }
370
+ }
371
+ },
372
+ "404": {
373
+ "description": "The server cannot find the requested resource.",
374
+ "content": {
375
+ "application/json": {
376
+ "schema": {
377
+ "$ref": "#/components/schemas/Problem"
378
+ }
379
+ }
380
+ }
381
+ },
382
+ "410": {
383
+ "description": "Client error",
384
+ "content": {
385
+ "application/json": {
386
+ "schema": {
387
+ "$ref": "#/components/schemas/Problem"
388
+ }
389
+ }
390
+ }
391
+ },
392
+ "413": {
393
+ "description": "Client error",
394
+ "content": {
395
+ "application/json": {
396
+ "schema": {
397
+ "$ref": "#/components/schemas/Problem"
398
+ }
399
+ }
400
+ }
401
+ },
402
+ "422": {
403
+ "description": "Client error",
404
+ "content": {
405
+ "application/json": {
406
+ "schema": {
407
+ "$ref": "#/components/schemas/Problem"
408
+ }
409
+ }
410
+ }
411
+ }
412
+ },
413
+ "requestBody": {
414
+ "required": true,
415
+ "content": {
416
+ "*/*": {
417
+ "schema": {
418
+ "contentMediaType": "*/*"
419
+ }
420
+ }
421
+ }
422
+ },
423
+ "security": [
424
+ {}
425
+ ]
426
+ }
427
+ },
428
+ "/whoami": {
429
+ "get": {
430
+ "operationId": "Session_whoami",
431
+ "description": "The space the credentials open.",
432
+ "parameters": [],
433
+ "responses": {
434
+ "200": {
435
+ "description": "The request has succeeded.",
436
+ "content": {
437
+ "application/json": {
438
+ "schema": {
439
+ "$ref": "#/components/schemas/Whoami"
440
+ }
441
+ }
442
+ }
443
+ },
444
+ "401": {
445
+ "description": "Access is unauthorized.",
446
+ "content": {
447
+ "application/json": {
448
+ "schema": {
449
+ "$ref": "#/components/schemas/Problem"
450
+ }
451
+ }
452
+ }
453
+ }
454
+ },
455
+ "security": [
456
+ {
457
+ "BearerAuth": []
458
+ }
459
+ ]
460
+ }
461
+ }
462
+ },
463
+ "components": {
464
+ "schemas": {
465
+ "Actor": {
466
+ "type": "object",
467
+ "required": [
468
+ "id"
469
+ ],
470
+ "properties": {
471
+ "id": {
472
+ "type": "string",
473
+ "description": "Stable within the deployment, as its gate names them."
474
+ },
475
+ "name": {
476
+ "type": "string",
477
+ "description": "How to show them, when the gate knows."
478
+ }
479
+ },
480
+ "unevaluatedProperties": {
481
+ "not": {}
482
+ },
483
+ "description": "Someone a deployment's gate recognised: a person, or the agent they authorised."
484
+ },
485
+ "AgentEntry": {
486
+ "type": "object",
487
+ "required": [
488
+ "author",
489
+ "answer",
490
+ "at"
491
+ ],
492
+ "properties": {
493
+ "author": {
494
+ "type": "string",
495
+ "enum": [
496
+ "agent"
497
+ ]
498
+ },
499
+ "answer": {
500
+ "type": "string"
501
+ },
502
+ "content": {
503
+ "type": "array",
504
+ "items": {
505
+ "$ref": "#/components/schemas/Block"
506
+ }
507
+ },
508
+ "point": {
509
+ "type": "string",
510
+ "description": "The briefing point this answers."
511
+ },
512
+ "points": {
513
+ "type": "array",
514
+ "items": {
515
+ "$ref": "#/components/schemas/Point"
516
+ },
517
+ "description": "Sub-points the answer broke the point into, with their ids."
518
+ },
519
+ "at": {
520
+ "type": "string",
521
+ "format": "date-time"
522
+ }
523
+ },
524
+ "unevaluatedProperties": {
525
+ "not": {}
526
+ },
527
+ "description": "An answer the agent gave: to a question asked back, or on one point of a briefing."
528
+ },
529
+ "Answered": {
530
+ "type": "object",
531
+ "required": [
532
+ "outcome",
533
+ "selected"
534
+ ],
535
+ "properties": {
536
+ "outcome": {
537
+ "type": "string",
538
+ "enum": [
539
+ "answered"
540
+ ]
541
+ },
542
+ "selected": {
543
+ "type": "array",
544
+ "items": {
545
+ "type": "string"
546
+ }
547
+ },
548
+ "text": {
549
+ "type": "string"
550
+ }
551
+ },
552
+ "unevaluatedProperties": {
553
+ "not": {}
554
+ },
555
+ "description": "An answer to a question: the choices picked, words of their own, or both."
556
+ },
557
+ "Approved": {
558
+ "type": "object",
559
+ "required": [
560
+ "outcome"
561
+ ],
562
+ "properties": {
563
+ "outcome": {
564
+ "type": "string",
565
+ "enum": [
566
+ "approved"
567
+ ]
568
+ },
569
+ "note": {
570
+ "type": "string"
571
+ }
572
+ },
573
+ "unevaluatedProperties": {
574
+ "not": {}
575
+ },
576
+ "description": "A review approved, with an optional note."
577
+ },
578
+ "Ask": {
579
+ "anyOf": [
580
+ {
581
+ "$ref": "#/components/schemas/QuestionAsk"
582
+ },
583
+ {
584
+ "$ref": "#/components/schemas/ReviewAsk"
585
+ },
586
+ {
587
+ "$ref": "#/components/schemas/BriefingAsk"
588
+ }
589
+ ],
590
+ "description": "Something an agent needs from a person: a short thread that ends with a reply."
591
+ },
592
+ "AskCommon": {
593
+ "type": "object",
594
+ "required": [
595
+ "id",
596
+ "status",
597
+ "waiting",
598
+ "thread",
599
+ "createdAt",
600
+ "updatedAt"
601
+ ],
602
+ "properties": {
603
+ "id": {
604
+ "type": "string"
605
+ },
606
+ "status": {
607
+ "$ref": "#/components/schemas/AskStatus"
608
+ },
609
+ "waiting": {
610
+ "type": "boolean",
611
+ "description": "Whether an agent is following this ask right now: waiting on its call, or polling it as a background task."
612
+ },
613
+ "project": {
614
+ "type": "string"
615
+ },
616
+ "client": {
617
+ "type": "string",
618
+ "description": "The MCP client that asked, such as `claude-code 2.1.0`."
619
+ },
620
+ "raisedBy": {
621
+ "$ref": "#/components/schemas/Actor",
622
+ "description": "Whose agent asked: the person its credential belongs to, when the deployment knows."
623
+ },
624
+ "thread": {
625
+ "type": "array",
626
+ "items": {
627
+ "$ref": "#/components/schemas/Entry"
628
+ },
629
+ "description": "Every turn after the ask was opened, oldest first."
630
+ },
631
+ "createdAt": {
632
+ "type": "string",
633
+ "format": "date-time"
634
+ },
635
+ "updatedAt": {
636
+ "type": "string",
637
+ "format": "date-time"
638
+ },
639
+ "closedAt": {
640
+ "type": "string",
641
+ "format": "date-time"
642
+ }
643
+ },
644
+ "unevaluatedProperties": {
645
+ "not": {}
646
+ },
647
+ "description": "What every ask carries, whatever its kind."
648
+ },
649
+ "AskEvent": {
650
+ "type": "object",
651
+ "required": [
652
+ "type",
653
+ "ask"
654
+ ],
655
+ "properties": {
656
+ "type": {
657
+ "type": "string",
658
+ "enum": [
659
+ "ask.opened",
660
+ "ask.updated"
661
+ ]
662
+ },
663
+ "ask": {
664
+ "$ref": "#/components/schemas/Ask"
665
+ }
666
+ },
667
+ "unevaluatedProperties": {
668
+ "not": {}
669
+ },
670
+ "description": "An ask was opened, or changed: a new turn, a close, or an agent starting or stopping following it."
671
+ },
672
+ "AskKind": {
673
+ "type": "string",
674
+ "enum": [
675
+ "question",
676
+ "review",
677
+ "briefing"
678
+ ],
679
+ "description": "What an agent is asking for: an answer to a question, a verdict on something it produced, or the\nperson's word on each point of something it explained."
680
+ },
681
+ "AskPage": {
682
+ "type": "object",
683
+ "required": [
684
+ "items"
685
+ ],
686
+ "properties": {
687
+ "items": {
688
+ "type": "array",
689
+ "items": {
690
+ "$ref": "#/components/schemas/Ask"
691
+ }
692
+ },
693
+ "nextBefore": {
694
+ "type": "string",
695
+ "format": "date-time",
696
+ "description": "Pass as `before` for the next page. Absent on the last page."
697
+ }
698
+ },
699
+ "unevaluatedProperties": {
700
+ "not": {}
701
+ },
702
+ "description": "A page of closed asks, newest first."
703
+ },
704
+ "AskStatus": {
705
+ "type": "string",
706
+ "enum": [
707
+ "awaiting_human",
708
+ "awaiting_agent",
709
+ "closed"
710
+ ],
711
+ "description": "Where an ask stands. While it is open, it is either the person's move or the agent's."
712
+ },
713
+ "Block": {
714
+ "anyOf": [
715
+ {
716
+ "$ref": "#/components/schemas/MarkdownBlock"
717
+ },
718
+ {
719
+ "$ref": "#/components/schemas/CodeBlock"
720
+ },
721
+ {
722
+ "$ref": "#/components/schemas/DiffBlock"
723
+ },
724
+ {
725
+ "$ref": "#/components/schemas/ImageBlock"
726
+ }
727
+ ],
728
+ "description": "One piece of what is shown to the person."
729
+ },
730
+ "BriefingAnswerInput": {
731
+ "type": "object",
732
+ "required": [
733
+ "askId",
734
+ "answers"
735
+ ],
736
+ "properties": {
737
+ "askId": {
738
+ "type": "string",
739
+ "minLength": 1
740
+ },
741
+ "answers": {
742
+ "type": "array",
743
+ "items": {
744
+ "$ref": "#/components/schemas/PointAnswer"
745
+ },
746
+ "minItems": 1
747
+ }
748
+ },
749
+ "unevaluatedProperties": {
750
+ "not": {}
751
+ },
752
+ "description": "Your answers on a briefing, one per point: every point the person wrote on without resolving it,\nand any other open point you have more to say on. All of it together may be at most 256 KiB."
753
+ },
754
+ "BriefingAsk": {
755
+ "type": "object",
756
+ "required": [
757
+ "kind",
758
+ "prompt",
759
+ "id",
760
+ "status",
761
+ "waiting",
762
+ "thread",
763
+ "createdAt",
764
+ "updatedAt"
765
+ ],
766
+ "properties": {
767
+ "kind": {
768
+ "type": "string",
769
+ "enum": [
770
+ "briefing"
771
+ ]
772
+ },
773
+ "prompt": {
774
+ "$ref": "#/components/schemas/BriefingPrompt"
775
+ },
776
+ "id": {
777
+ "type": "string"
778
+ },
779
+ "status": {
780
+ "$ref": "#/components/schemas/AskStatus"
781
+ },
782
+ "waiting": {
783
+ "type": "boolean",
784
+ "description": "Whether an agent is following this ask right now: waiting on its call, or polling it as a background task."
785
+ },
786
+ "project": {
787
+ "type": "string"
788
+ },
789
+ "client": {
790
+ "type": "string",
791
+ "description": "The MCP client that asked, such as `claude-code 2.1.0`."
792
+ },
793
+ "raisedBy": {
794
+ "$ref": "#/components/schemas/Actor",
795
+ "description": "Whose agent asked: the person its credential belongs to, when the deployment knows."
796
+ },
797
+ "thread": {
798
+ "type": "array",
799
+ "items": {
800
+ "$ref": "#/components/schemas/Entry"
801
+ },
802
+ "description": "Every turn after the ask was opened, oldest first."
803
+ },
804
+ "createdAt": {
805
+ "type": "string",
806
+ "format": "date-time"
807
+ },
808
+ "updatedAt": {
809
+ "type": "string",
810
+ "format": "date-time"
811
+ },
812
+ "closedAt": {
813
+ "type": "string",
814
+ "format": "date-time"
815
+ }
816
+ },
817
+ "unevaluatedProperties": {
818
+ "not": {}
819
+ },
820
+ "description": "Points an agent explained, for the person to reply on one at a time."
821
+ },
822
+ "BriefingInput": {
823
+ "type": "object",
824
+ "required": [
825
+ "title",
826
+ "sections",
827
+ "project"
828
+ ],
829
+ "properties": {
830
+ "title": {
831
+ "type": "string",
832
+ "minLength": 1,
833
+ "maxLength": 200
834
+ },
835
+ "summary": {
836
+ "type": "string",
837
+ "description": "What this explains, and why, as markdown."
838
+ },
839
+ "sections": {
840
+ "type": "array",
841
+ "items": {
842
+ "$ref": "#/components/schemas/BriefingSection"
843
+ },
844
+ "minItems": 1,
845
+ "description": "The points, in lists under optional headings."
846
+ },
847
+ "project": {
848
+ "type": "string",
849
+ "minLength": 1,
850
+ "description": "The project you are working in: the name of the folder at the root of its repository (the\nlast part of `git rev-parse --show-toplevel`), or of the working directory outside one. The\nperson works on many projects at once from one inbox; this is how they know who is asking."
851
+ }
852
+ },
853
+ "unevaluatedProperties": {
854
+ "not": {}
855
+ },
856
+ "description": "Something explained as points the person can reply on one at a time: findings, options, steps, a\nlist of changes. They may write on any point, or mark it resolved, and you answer on each point\nthey wrote on until every point is resolved. Points are numbered for you, straight through every\nsection: at most fifty. All of it together may be at most 256 KiB."
857
+ },
858
+ "BriefingPoint": {
859
+ "type": "object",
860
+ "required": [
861
+ "title"
862
+ ],
863
+ "properties": {
864
+ "title": {
865
+ "type": "string",
866
+ "minLength": 1,
867
+ "maxLength": 200,
868
+ "description": "The point in one line, shown while it is folded."
869
+ },
870
+ "detail": {
871
+ "type": "string",
872
+ "description": "The point explained, as markdown, shown when the person opens it."
873
+ },
874
+ "content": {
875
+ "type": "array",
876
+ "items": {
877
+ "$ref": "#/components/schemas/Block"
878
+ },
879
+ "description": "Anything to look at with it: code, a diff or an image."
880
+ }
881
+ },
882
+ "unevaluatedProperties": {
883
+ "not": {}
884
+ },
885
+ "description": "One point of a briefing: a line the person sees folded, and what opens beneath it."
886
+ },
887
+ "BriefingPrompt": {
888
+ "type": "object",
889
+ "required": [
890
+ "title",
891
+ "sections"
892
+ ],
893
+ "properties": {
894
+ "title": {
895
+ "type": "string"
896
+ },
897
+ "summary": {
898
+ "type": "string"
899
+ },
900
+ "sections": {
901
+ "type": "array",
902
+ "items": {
903
+ "$ref": "#/components/schemas/BriefingPromptSection"
904
+ }
905
+ }
906
+ },
907
+ "unevaluatedProperties": {
908
+ "not": {}
909
+ },
910
+ "description": "A briefing as it is shown to the person, before any sub-points the agent adds while answering."
911
+ },
912
+ "BriefingPromptSection": {
913
+ "type": "object",
914
+ "required": [
915
+ "points"
916
+ ],
917
+ "properties": {
918
+ "title": {
919
+ "type": "string"
920
+ },
921
+ "points": {
922
+ "type": "array",
923
+ "items": {
924
+ "$ref": "#/components/schemas/Point"
925
+ }
926
+ }
927
+ },
928
+ "unevaluatedProperties": {
929
+ "not": {}
930
+ },
931
+ "description": "A list of a briefing's points as it is shown."
932
+ },
933
+ "BriefingSection": {
934
+ "type": "object",
935
+ "required": [
936
+ "points"
937
+ ],
938
+ "properties": {
939
+ "title": {
940
+ "type": "string"
941
+ },
942
+ "points": {
943
+ "type": "array",
944
+ "items": {
945
+ "$ref": "#/components/schemas/BriefingPoint"
946
+ },
947
+ "minItems": 1
948
+ }
949
+ },
950
+ "unevaluatedProperties": {
951
+ "not": {}
952
+ },
953
+ "description": "A list of points under an optional heading."
954
+ },
955
+ "ChangesRequested": {
956
+ "type": "object",
957
+ "required": [
958
+ "outcome",
959
+ "feedback"
960
+ ],
961
+ "properties": {
962
+ "outcome": {
963
+ "type": "string",
964
+ "enum": [
965
+ "changes_requested"
966
+ ]
967
+ },
968
+ "feedback": {
969
+ "type": "string",
970
+ "minLength": 1
971
+ }
972
+ },
973
+ "unevaluatedProperties": {
974
+ "not": {}
975
+ },
976
+ "description": "A review sent back with feedback."
977
+ },
978
+ "Choice": {
979
+ "type": "object",
980
+ "required": [
981
+ "label"
982
+ ],
983
+ "properties": {
984
+ "label": {
985
+ "type": "string",
986
+ "minLength": 1,
987
+ "maxLength": 80
988
+ },
989
+ "description": {
990
+ "type": "string"
991
+ }
992
+ },
993
+ "unevaluatedProperties": {
994
+ "not": {}
995
+ },
996
+ "description": "A choice offered with a question."
997
+ },
998
+ "CodeBlock": {
999
+ "type": "object",
1000
+ "required": [
1001
+ "type",
1002
+ "code"
1003
+ ],
1004
+ "properties": {
1005
+ "type": {
1006
+ "type": "string",
1007
+ "enum": [
1008
+ "code"
1009
+ ]
1010
+ },
1011
+ "code": {
1012
+ "type": "string",
1013
+ "minLength": 1
1014
+ },
1015
+ "language": {
1016
+ "type": "string",
1017
+ "description": "A language name the highlighter knows, such as `ts` or `python`."
1018
+ },
1019
+ "filename": {
1020
+ "type": "string"
1021
+ }
1022
+ },
1023
+ "unevaluatedProperties": {
1024
+ "not": {}
1025
+ },
1026
+ "description": "Source code, shown highlighted."
1027
+ },
1028
+ "DiffBlock": {
1029
+ "type": "object",
1030
+ "required": [
1031
+ "type",
1032
+ "diff"
1033
+ ],
1034
+ "properties": {
1035
+ "type": {
1036
+ "type": "string",
1037
+ "enum": [
1038
+ "diff"
1039
+ ]
1040
+ },
1041
+ "diff": {
1042
+ "type": "string",
1043
+ "minLength": 1
1044
+ },
1045
+ "filename": {
1046
+ "type": "string"
1047
+ }
1048
+ },
1049
+ "unevaluatedProperties": {
1050
+ "not": {}
1051
+ },
1052
+ "description": "A unified diff, as `git diff` prints it."
1053
+ },
1054
+ "Dismissed": {
1055
+ "type": "object",
1056
+ "required": [
1057
+ "outcome"
1058
+ ],
1059
+ "properties": {
1060
+ "outcome": {
1061
+ "type": "string",
1062
+ "enum": [
1063
+ "dismissed"
1064
+ ]
1065
+ }
1066
+ },
1067
+ "unevaluatedProperties": {
1068
+ "not": {}
1069
+ },
1070
+ "description": "Declined without an answer."
1071
+ },
1072
+ "Entry": {
1073
+ "anyOf": [
1074
+ {
1075
+ "$ref": "#/components/schemas/HumanEntry"
1076
+ },
1077
+ {
1078
+ "$ref": "#/components/schemas/AgentEntry"
1079
+ }
1080
+ ],
1081
+ "description": "One turn in an ask's thread after it was opened."
1082
+ },
1083
+ "EventTicket": {
1084
+ "type": "object",
1085
+ "required": [
1086
+ "ticket",
1087
+ "expiresAt"
1088
+ ],
1089
+ "properties": {
1090
+ "ticket": {
1091
+ "type": "string"
1092
+ },
1093
+ "expiresAt": {
1094
+ "type": "string",
1095
+ "format": "date-time"
1096
+ }
1097
+ },
1098
+ "unevaluatedProperties": {
1099
+ "not": {}
1100
+ },
1101
+ "description": "A one-time pass onto the event socket, for a client that cannot send headers there, as a browser\ncannot. Offer it as the subprotocol `loopback.ticket.<ticket>` alongside `loopback.v1`. It works\nonce, within a minute, so a copy that turns up in a log is of no use to anyone."
1102
+ },
1103
+ "FollowUp": {
1104
+ "type": "object",
1105
+ "required": [
1106
+ "outcome",
1107
+ "question"
1108
+ ],
1109
+ "properties": {
1110
+ "outcome": {
1111
+ "type": "string",
1112
+ "enum": [
1113
+ "follow_up"
1114
+ ]
1115
+ },
1116
+ "question": {
1117
+ "type": "string",
1118
+ "minLength": 1
1119
+ }
1120
+ },
1121
+ "unevaluatedProperties": {
1122
+ "not": {}
1123
+ },
1124
+ "description": "A question asked back before deciding. The ask stays open until the agent answers."
1125
+ },
1126
+ "FollowUpInput": {
1127
+ "type": "object",
1128
+ "required": [
1129
+ "askId",
1130
+ "answer"
1131
+ ],
1132
+ "properties": {
1133
+ "askId": {
1134
+ "type": "string",
1135
+ "minLength": 1
1136
+ },
1137
+ "answer": {
1138
+ "type": "string",
1139
+ "minLength": 1,
1140
+ "description": "The answer, as markdown."
1141
+ },
1142
+ "content": {
1143
+ "type": "array",
1144
+ "items": {
1145
+ "$ref": "#/components/schemas/Block"
1146
+ },
1147
+ "description": "Anything new to look at alongside the answer."
1148
+ }
1149
+ },
1150
+ "unevaluatedProperties": {
1151
+ "not": {}
1152
+ },
1153
+ "description": "The agent's answer to a question the person asked back, with its content at most 256 KiB."
1154
+ },
1155
+ "HumanEntry": {
1156
+ "type": "object",
1157
+ "required": [
1158
+ "author",
1159
+ "reply",
1160
+ "at"
1161
+ ],
1162
+ "properties": {
1163
+ "author": {
1164
+ "type": "string",
1165
+ "enum": [
1166
+ "human"
1167
+ ]
1168
+ },
1169
+ "reply": {
1170
+ "$ref": "#/components/schemas/Reply"
1171
+ },
1172
+ "by": {
1173
+ "$ref": "#/components/schemas/Actor",
1174
+ "description": "Who replied, when the deployment knows."
1175
+ },
1176
+ "at": {
1177
+ "type": "string",
1178
+ "format": "date-time"
1179
+ }
1180
+ },
1181
+ "unevaluatedProperties": {
1182
+ "not": {}
1183
+ },
1184
+ "description": "A reply the person gave."
1185
+ },
1186
+ "ImageBlock": {
1187
+ "type": "object",
1188
+ "required": [
1189
+ "type",
1190
+ "uploadId"
1191
+ ],
1192
+ "properties": {
1193
+ "type": {
1194
+ "type": "string",
1195
+ "enum": [
1196
+ "image"
1197
+ ]
1198
+ },
1199
+ "uploadId": {
1200
+ "type": "string",
1201
+ "minLength": 1
1202
+ },
1203
+ "caption": {
1204
+ "type": "string"
1205
+ }
1206
+ },
1207
+ "unevaluatedProperties": {
1208
+ "not": {}
1209
+ },
1210
+ "description": "An image uploaded beforehand through an upload ticket."
1211
+ },
1212
+ "ImageType": {
1213
+ "type": "string",
1214
+ "enum": [
1215
+ "image/png",
1216
+ "image/jpeg",
1217
+ "image/webp",
1218
+ "image/gif"
1219
+ ],
1220
+ "description": "Image formats an agent may upload for a review."
1221
+ },
1222
+ "InboxLink": {
1223
+ "type": "object",
1224
+ "required": [
1225
+ "url"
1226
+ ],
1227
+ "properties": {
1228
+ "url": {
1229
+ "type": "string"
1230
+ }
1231
+ },
1232
+ "unevaluatedProperties": {
1233
+ "not": {}
1234
+ },
1235
+ "description": "Where the person reads and answers everything agents ask."
1236
+ },
1237
+ "InboxRequest": {
1238
+ "type": "object",
1239
+ "properties": {
1240
+ "askId": {
1241
+ "type": "string",
1242
+ "description": "An ask to open directly. Leave it out for the inbox itself."
1243
+ }
1244
+ },
1245
+ "unevaluatedProperties": {
1246
+ "not": {}
1247
+ },
1248
+ "description": "A request for the address of the person's inbox."
1249
+ },
1250
+ "MarkdownBlock": {
1251
+ "type": "object",
1252
+ "required": [
1253
+ "type",
1254
+ "text"
1255
+ ],
1256
+ "properties": {
1257
+ "type": {
1258
+ "type": "string",
1259
+ "enum": [
1260
+ "markdown"
1261
+ ]
1262
+ },
1263
+ "text": {
1264
+ "type": "string",
1265
+ "minLength": 1
1266
+ }
1267
+ },
1268
+ "unevaluatedProperties": {
1269
+ "not": {}
1270
+ },
1271
+ "description": "Prose, copy or a plan, as GitHub-flavoured markdown."
1272
+ },
1273
+ "Point": {
1274
+ "type": "object",
1275
+ "required": [
1276
+ "id",
1277
+ "title"
1278
+ ],
1279
+ "properties": {
1280
+ "id": {
1281
+ "type": "string",
1282
+ "description": "`3` for the third point of the briefing, `3.1` for the first beneath it."
1283
+ },
1284
+ "title": {
1285
+ "type": "string",
1286
+ "minLength": 1,
1287
+ "maxLength": 200,
1288
+ "description": "The point in one line, shown while it is folded."
1289
+ },
1290
+ "detail": {
1291
+ "type": "string",
1292
+ "description": "The point explained, as markdown, shown when the person opens it."
1293
+ },
1294
+ "content": {
1295
+ "type": "array",
1296
+ "items": {
1297
+ "$ref": "#/components/schemas/Block"
1298
+ },
1299
+ "description": "Anything to look at with it: code, a diff or an image."
1300
+ }
1301
+ },
1302
+ "unevaluatedProperties": {
1303
+ "not": {}
1304
+ },
1305
+ "description": "A point of a briefing as it is shown, with the id replies name it by."
1306
+ },
1307
+ "PointAnswer": {
1308
+ "type": "object",
1309
+ "required": [
1310
+ "point",
1311
+ "answer"
1312
+ ],
1313
+ "properties": {
1314
+ "point": {
1315
+ "type": "string",
1316
+ "minLength": 1,
1317
+ "description": "The point's id, such as `3` or `3.1`."
1318
+ },
1319
+ "answer": {
1320
+ "type": "string",
1321
+ "minLength": 1,
1322
+ "description": "The answer, as markdown."
1323
+ },
1324
+ "content": {
1325
+ "type": "array",
1326
+ "items": {
1327
+ "$ref": "#/components/schemas/Block"
1328
+ },
1329
+ "description": "Anything new to look at alongside the answer."
1330
+ },
1331
+ "points": {
1332
+ "type": "array",
1333
+ "items": {
1334
+ "$ref": "#/components/schemas/BriefingPoint"
1335
+ },
1336
+ "description": "Sub-points this point breaks into, numbered beneath it (`3.1`, `3.2`, …), each of which the\nperson can reply on in turn. Points go at most three levels deep."
1337
+ }
1338
+ },
1339
+ "unevaluatedProperties": {
1340
+ "not": {}
1341
+ },
1342
+ "description": "Your answer on one point of a briefing."
1343
+ },
1344
+ "PointReply": {
1345
+ "type": "object",
1346
+ "required": [
1347
+ "point"
1348
+ ],
1349
+ "properties": {
1350
+ "point": {
1351
+ "type": "string",
1352
+ "minLength": 1
1353
+ },
1354
+ "text": {
1355
+ "type": "string",
1356
+ "description": "What they said: a question, a push-back or a comment."
1357
+ },
1358
+ "resolved": {
1359
+ "type": "boolean",
1360
+ "description": "Whether they are done with the point, and everything beneath it."
1361
+ }
1362
+ },
1363
+ "unevaluatedProperties": {
1364
+ "not": {}
1365
+ },
1366
+ "description": "The person on one point of a briefing: words, resolved, or both."
1367
+ },
1368
+ "Problem": {
1369
+ "type": "object",
1370
+ "required": [
1371
+ "code",
1372
+ "message"
1373
+ ],
1374
+ "properties": {
1375
+ "code": {
1376
+ "type": "string",
1377
+ "description": "A stable, machine-readable reason, such as `ask.closed`."
1378
+ },
1379
+ "message": {
1380
+ "type": "string"
1381
+ }
1382
+ },
1383
+ "unevaluatedProperties": {
1384
+ "not": {}
1385
+ },
1386
+ "description": "Why a request was refused."
1387
+ },
1388
+ "QuestionAsk": {
1389
+ "type": "object",
1390
+ "required": [
1391
+ "kind",
1392
+ "prompt",
1393
+ "id",
1394
+ "status",
1395
+ "waiting",
1396
+ "thread",
1397
+ "createdAt",
1398
+ "updatedAt"
1399
+ ],
1400
+ "properties": {
1401
+ "kind": {
1402
+ "type": "string",
1403
+ "enum": [
1404
+ "question"
1405
+ ]
1406
+ },
1407
+ "prompt": {
1408
+ "$ref": "#/components/schemas/QuestionPrompt"
1409
+ },
1410
+ "id": {
1411
+ "type": "string"
1412
+ },
1413
+ "status": {
1414
+ "$ref": "#/components/schemas/AskStatus"
1415
+ },
1416
+ "waiting": {
1417
+ "type": "boolean",
1418
+ "description": "Whether an agent is following this ask right now: waiting on its call, or polling it as a background task."
1419
+ },
1420
+ "project": {
1421
+ "type": "string"
1422
+ },
1423
+ "client": {
1424
+ "type": "string",
1425
+ "description": "The MCP client that asked, such as `claude-code 2.1.0`."
1426
+ },
1427
+ "raisedBy": {
1428
+ "$ref": "#/components/schemas/Actor",
1429
+ "description": "Whose agent asked: the person its credential belongs to, when the deployment knows."
1430
+ },
1431
+ "thread": {
1432
+ "type": "array",
1433
+ "items": {
1434
+ "$ref": "#/components/schemas/Entry"
1435
+ },
1436
+ "description": "Every turn after the ask was opened, oldest first."
1437
+ },
1438
+ "createdAt": {
1439
+ "type": "string",
1440
+ "format": "date-time"
1441
+ },
1442
+ "updatedAt": {
1443
+ "type": "string",
1444
+ "format": "date-time"
1445
+ },
1446
+ "closedAt": {
1447
+ "type": "string",
1448
+ "format": "date-time"
1449
+ }
1450
+ },
1451
+ "unevaluatedProperties": {
1452
+ "not": {}
1453
+ },
1454
+ "description": "A question an agent asked."
1455
+ },
1456
+ "QuestionInput": {
1457
+ "type": "object",
1458
+ "required": [
1459
+ "question",
1460
+ "project"
1461
+ ],
1462
+ "properties": {
1463
+ "question": {
1464
+ "type": "string",
1465
+ "minLength": 1,
1466
+ "description": "The question, as markdown."
1467
+ },
1468
+ "options": {
1469
+ "type": "array",
1470
+ "items": {
1471
+ "$ref": "#/components/schemas/Choice"
1472
+ },
1473
+ "minItems": 2,
1474
+ "maxItems": 6,
1475
+ "description": "Between two and six choices, offered as buttons."
1476
+ },
1477
+ "multiple": {
1478
+ "type": "boolean",
1479
+ "description": "Whether the person may pick more than one choice."
1480
+ },
1481
+ "context": {
1482
+ "type": "string",
1483
+ "description": "Background the person needs to answer, as markdown."
1484
+ },
1485
+ "project": {
1486
+ "type": "string",
1487
+ "minLength": 1,
1488
+ "description": "The project you are working in: the name of the folder at the root of its repository (the\nlast part of `git rev-parse --show-toplevel`), or of the working directory outside one. The\nperson works on many projects at once from one inbox; this is how they know who is asking."
1489
+ }
1490
+ },
1491
+ "unevaluatedProperties": {
1492
+ "not": {}
1493
+ },
1494
+ "description": "A question for the person, with optional choices. They may always answer in their own words. All\nof it together may be at most 256 KiB."
1495
+ },
1496
+ "QuestionPrompt": {
1497
+ "type": "object",
1498
+ "required": [
1499
+ "question",
1500
+ "options",
1501
+ "multiple"
1502
+ ],
1503
+ "properties": {
1504
+ "question": {
1505
+ "type": "string"
1506
+ },
1507
+ "options": {
1508
+ "type": "array",
1509
+ "items": {
1510
+ "$ref": "#/components/schemas/Choice"
1511
+ }
1512
+ },
1513
+ "multiple": {
1514
+ "type": "boolean"
1515
+ },
1516
+ "context": {
1517
+ "type": "string"
1518
+ }
1519
+ },
1520
+ "unevaluatedProperties": {
1521
+ "not": {}
1522
+ },
1523
+ "description": "A question as it is shown to the person."
1524
+ },
1525
+ "Reply": {
1526
+ "anyOf": [
1527
+ {
1528
+ "$ref": "#/components/schemas/Answered"
1529
+ },
1530
+ {
1531
+ "$ref": "#/components/schemas/Approved"
1532
+ },
1533
+ {
1534
+ "$ref": "#/components/schemas/ChangesRequested"
1535
+ },
1536
+ {
1537
+ "$ref": "#/components/schemas/FollowUp"
1538
+ },
1539
+ {
1540
+ "$ref": "#/components/schemas/Dismissed"
1541
+ },
1542
+ {
1543
+ "$ref": "#/components/schemas/Responded"
1544
+ }
1545
+ ],
1546
+ "description": "What a person replies. A `follow_up` hands the move to the agent; so does a `responded` that\nleaves any point unresolved. Every other reply closes the ask."
1547
+ },
1548
+ "Responded": {
1549
+ "type": "object",
1550
+ "required": [
1551
+ "outcome",
1552
+ "points"
1553
+ ],
1554
+ "properties": {
1555
+ "outcome": {
1556
+ "type": "string",
1557
+ "enum": [
1558
+ "responded"
1559
+ ]
1560
+ },
1561
+ "points": {
1562
+ "type": "array",
1563
+ "items": {
1564
+ "$ref": "#/components/schemas/PointReply"
1565
+ },
1566
+ "minItems": 1
1567
+ }
1568
+ },
1569
+ "unevaluatedProperties": {
1570
+ "not": {}
1571
+ },
1572
+ "description": "Replies on the points of a briefing. The agent answers every point written on and left unresolved;\nthe briefing closes once every point is resolved."
1573
+ },
1574
+ "ReviewAsk": {
1575
+ "type": "object",
1576
+ "required": [
1577
+ "kind",
1578
+ "prompt",
1579
+ "id",
1580
+ "status",
1581
+ "waiting",
1582
+ "thread",
1583
+ "createdAt",
1584
+ "updatedAt"
1585
+ ],
1586
+ "properties": {
1587
+ "kind": {
1588
+ "type": "string",
1589
+ "enum": [
1590
+ "review"
1591
+ ]
1592
+ },
1593
+ "prompt": {
1594
+ "$ref": "#/components/schemas/ReviewPrompt"
1595
+ },
1596
+ "revises": {
1597
+ "type": "string",
1598
+ "description": "The id of the review this one revises."
1599
+ },
1600
+ "id": {
1601
+ "type": "string"
1602
+ },
1603
+ "status": {
1604
+ "$ref": "#/components/schemas/AskStatus"
1605
+ },
1606
+ "waiting": {
1607
+ "type": "boolean",
1608
+ "description": "Whether an agent is following this ask right now: waiting on its call, or polling it as a background task."
1609
+ },
1610
+ "project": {
1611
+ "type": "string"
1612
+ },
1613
+ "client": {
1614
+ "type": "string",
1615
+ "description": "The MCP client that asked, such as `claude-code 2.1.0`."
1616
+ },
1617
+ "raisedBy": {
1618
+ "$ref": "#/components/schemas/Actor",
1619
+ "description": "Whose agent asked: the person its credential belongs to, when the deployment knows."
1620
+ },
1621
+ "thread": {
1622
+ "type": "array",
1623
+ "items": {
1624
+ "$ref": "#/components/schemas/Entry"
1625
+ },
1626
+ "description": "Every turn after the ask was opened, oldest first."
1627
+ },
1628
+ "createdAt": {
1629
+ "type": "string",
1630
+ "format": "date-time"
1631
+ },
1632
+ "updatedAt": {
1633
+ "type": "string",
1634
+ "format": "date-time"
1635
+ },
1636
+ "closedAt": {
1637
+ "type": "string",
1638
+ "format": "date-time"
1639
+ }
1640
+ },
1641
+ "unevaluatedProperties": {
1642
+ "not": {}
1643
+ },
1644
+ "description": "Work an agent put up for review."
1645
+ },
1646
+ "ReviewInput": {
1647
+ "type": "object",
1648
+ "required": [
1649
+ "title",
1650
+ "content",
1651
+ "project"
1652
+ ],
1653
+ "properties": {
1654
+ "title": {
1655
+ "type": "string",
1656
+ "minLength": 1,
1657
+ "maxLength": 200
1658
+ },
1659
+ "content": {
1660
+ "type": "array",
1661
+ "items": {
1662
+ "$ref": "#/components/schemas/Block"
1663
+ },
1664
+ "minItems": 1,
1665
+ "description": "What is being reviewed, in order."
1666
+ },
1667
+ "summary": {
1668
+ "type": "string",
1669
+ "description": "What changed, or what to look at."
1670
+ },
1671
+ "revises": {
1672
+ "type": "string",
1673
+ "description": "The id of the review this one revises, after changes were requested."
1674
+ },
1675
+ "project": {
1676
+ "type": "string",
1677
+ "minLength": 1,
1678
+ "description": "The project you are working in: the name of the folder at the root of its repository (the\nlast part of `git rev-parse --show-toplevel`), or of the working directory outside one. The\nperson works on many projects at once from one inbox; this is how they know who is asking."
1679
+ }
1680
+ },
1681
+ "unevaluatedProperties": {
1682
+ "not": {}
1683
+ },
1684
+ "description": "Work put in front of the person for approval or feedback. All of it together may be at most\n256 KiB: show the part that matters, or split it into several reviews."
1685
+ },
1686
+ "ReviewPrompt": {
1687
+ "type": "object",
1688
+ "required": [
1689
+ "title",
1690
+ "content"
1691
+ ],
1692
+ "properties": {
1693
+ "title": {
1694
+ "type": "string"
1695
+ },
1696
+ "content": {
1697
+ "type": "array",
1698
+ "items": {
1699
+ "$ref": "#/components/schemas/Block"
1700
+ }
1701
+ },
1702
+ "summary": {
1703
+ "type": "string"
1704
+ }
1705
+ },
1706
+ "unevaluatedProperties": {
1707
+ "not": {}
1708
+ },
1709
+ "description": "A review as it is shown to the person."
1710
+ },
1711
+ "Revisions": {
1712
+ "type": "string",
1713
+ "enum": [
1714
+ "1"
1715
+ ],
1716
+ "description": "The contract's revisions, oldest first. Change the shape of any message and declare it here as a\nnew revision, marking what changed with `@added`, `@removed`, `@renamedFrom` or `@typeChangedFrom`:\nevery part of a deployment names the revision it writes, and newer code upgrades older messages.\nNever edit a revision that has shipped; `revisions/` holds each one frozen, and a test fails when\nthe contract no longer emits it unchanged. See docs/design/versioned-messages.md."
1717
+ },
1718
+ "ServerEvent": {
1719
+ "anyOf": [
1720
+ {
1721
+ "$ref": "#/components/schemas/SnapshotEvent"
1722
+ },
1723
+ {
1724
+ "$ref": "#/components/schemas/AskEvent"
1725
+ }
1726
+ ],
1727
+ "description": "A frame on the event socket."
1728
+ },
1729
+ "Snapshot": {
1730
+ "type": "object",
1731
+ "required": [
1732
+ "open",
1733
+ "recent"
1734
+ ],
1735
+ "properties": {
1736
+ "open": {
1737
+ "type": "array",
1738
+ "items": {
1739
+ "$ref": "#/components/schemas/Ask"
1740
+ }
1741
+ },
1742
+ "recent": {
1743
+ "type": "array",
1744
+ "items": {
1745
+ "$ref": "#/components/schemas/Ask"
1746
+ }
1747
+ }
1748
+ },
1749
+ "unevaluatedProperties": {
1750
+ "not": {}
1751
+ },
1752
+ "description": "Open asks, newest first, and the most recently closed."
1753
+ },
1754
+ "SnapshotEvent": {
1755
+ "type": "object",
1756
+ "required": [
1757
+ "type",
1758
+ "snapshot"
1759
+ ],
1760
+ "properties": {
1761
+ "type": {
1762
+ "type": "string",
1763
+ "enum": [
1764
+ "snapshot"
1765
+ ]
1766
+ },
1767
+ "snapshot": {
1768
+ "$ref": "#/components/schemas/Snapshot"
1769
+ }
1770
+ },
1771
+ "unevaluatedProperties": {
1772
+ "not": {}
1773
+ },
1774
+ "description": "The first frame on the event socket, and the state to start from."
1775
+ },
1776
+ "ToolReply": {
1777
+ "type": "object",
1778
+ "required": [
1779
+ "askId",
1780
+ "reply"
1781
+ ],
1782
+ "properties": {
1783
+ "askId": {
1784
+ "type": "string"
1785
+ },
1786
+ "reply": {
1787
+ "$ref": "#/components/schemas/Reply"
1788
+ }
1789
+ },
1790
+ "unevaluatedProperties": {
1791
+ "not": {}
1792
+ },
1793
+ "description": "What a blocking MCP tool returns: the reply that ended its wait."
1794
+ },
1795
+ "UploadReceipt": {
1796
+ "type": "object",
1797
+ "required": [
1798
+ "uploadId",
1799
+ "contentType",
1800
+ "size"
1801
+ ],
1802
+ "properties": {
1803
+ "uploadId": {
1804
+ "type": "string"
1805
+ },
1806
+ "contentType": {
1807
+ "$ref": "#/components/schemas/ImageType"
1808
+ },
1809
+ "size": {
1810
+ "type": "integer",
1811
+ "format": "int32"
1812
+ }
1813
+ },
1814
+ "unevaluatedProperties": {
1815
+ "not": {}
1816
+ },
1817
+ "description": "A stored upload."
1818
+ },
1819
+ "UploadRequest": {
1820
+ "type": "object",
1821
+ "required": [
1822
+ "contentType"
1823
+ ],
1824
+ "properties": {
1825
+ "contentType": {
1826
+ "$ref": "#/components/schemas/ImageType"
1827
+ }
1828
+ },
1829
+ "unevaluatedProperties": {
1830
+ "not": {}
1831
+ },
1832
+ "description": "A request for somewhere to upload an image."
1833
+ },
1834
+ "UploadTicket": {
1835
+ "type": "object",
1836
+ "required": [
1837
+ "uploadId",
1838
+ "uploadUrl",
1839
+ "expiresAt",
1840
+ "maxBytes",
1841
+ "command"
1842
+ ],
1843
+ "properties": {
1844
+ "uploadId": {
1845
+ "type": "string"
1846
+ },
1847
+ "uploadUrl": {
1848
+ "type": "string",
1849
+ "description": "Send the image here with `PUT` and its `Content-Type`. No credentials needed."
1850
+ },
1851
+ "expiresAt": {
1852
+ "type": "string",
1853
+ "format": "date-time"
1854
+ },
1855
+ "maxBytes": {
1856
+ "type": "integer",
1857
+ "format": "int32"
1858
+ },
1859
+ "command": {
1860
+ "type": "string",
1861
+ "description": "A ready-to-run command that performs the upload; replace `FILE` with the image's path."
1862
+ }
1863
+ },
1864
+ "unevaluatedProperties": {
1865
+ "not": {}
1866
+ },
1867
+ "description": "Where to upload an image, once, before it expires."
1868
+ },
1869
+ "Whoami": {
1870
+ "type": "object",
1871
+ "required": [
1872
+ "space",
1873
+ "actor"
1874
+ ],
1875
+ "properties": {
1876
+ "space": {
1877
+ "type": "string"
1878
+ },
1879
+ "actor": {
1880
+ "$ref": "#/components/schemas/Actor"
1881
+ }
1882
+ },
1883
+ "unevaluatedProperties": {
1884
+ "not": {}
1885
+ },
1886
+ "description": "Who the caller is."
1887
+ }
1888
+ },
1889
+ "securitySchemes": {
1890
+ "BearerAuth": {
1891
+ "type": "http",
1892
+ "scheme": "Bearer"
1893
+ }
1894
+ }
1895
+ },
1896
+ "servers": [
1897
+ {
1898
+ "url": "/api/v1",
1899
+ "description": "Loopback API",
1900
+ "variables": {}
1901
+ }
1902
+ ]
1903
+ }