@sema-agent/client-core 0.89.0 → 0.91.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/CHANGELOG.md +297 -0
  2. package/README.md +35 -24
  3. package/dist/adapt/arms.js +9 -0
  4. package/dist/adapter/downstream/eventToSdkMessage.js +4 -2
  5. package/dist/adapter/downstream/wiringManifestView.d.ts +6 -0
  6. package/dist/adapter/downstream/wiringManifestView.js +16 -0
  7. package/dist/adapter/runStream.d.ts +2 -0
  8. package/dist/adapter/runStream.js +180 -38
  9. package/dist/askSurvivesStandingAnswer.d.ts +10 -0
  10. package/dist/askSurvivesStandingAnswer.js +40 -0
  11. package/dist/attachmentSeatCapability.d.ts +11 -0
  12. package/dist/attachmentSeatCapability.js +27 -0
  13. package/dist/attachmentsWireCaps.d.ts +22 -2
  14. package/dist/attachmentsWireCaps.js +95 -22
  15. package/dist/compensations.js +10 -14
  16. package/dist/controlRouter.d.ts +9 -2
  17. package/dist/controlRouter.js +66 -28
  18. package/dist/coreValuePorts.d.ts +1 -0
  19. package/dist/decideFailureNote.js +4 -2
  20. package/dist/disableSkillsWire.d.ts +1 -0
  21. package/dist/disableSkillsWire.js +8 -1
  22. package/dist/displayUntrusted.js +153 -4
  23. package/dist/engineCapReader.js +12 -1
  24. package/dist/engineCapsCache.d.ts +3 -1
  25. package/dist/engineCapsCache.js +56 -6
  26. package/dist/engineClosedSets.d.ts +2 -0
  27. package/dist/engineClosedSets.js +3 -0
  28. package/dist/engineErrorCodes.d.ts +3 -0
  29. package/dist/engineErrorCodes.js +10 -0
  30. package/dist/engineNoticeCodes.d.ts +2 -9
  31. package/dist/engineNoticeCodes.js +19 -27
  32. package/dist/fileHistoryLegNotice.d.ts +20 -0
  33. package/dist/fileHistoryLegNotice.js +122 -0
  34. package/dist/gateOutcome.d.ts +1 -1
  35. package/dist/gateOutcome.js +1 -0
  36. package/dist/generated/engineFactTables.d.ts +13 -0
  37. package/dist/generated/engineFactTables.js +50 -0
  38. package/dist/generated/engineNoticeTables.js +0 -3
  39. package/dist/hitl/askGateWire.d.ts +1 -1
  40. package/dist/hitl/askGateWire.js +1 -1
  41. package/dist/hitl/crashConverged.d.ts +7 -0
  42. package/dist/hitl/crashConverged.js +57 -0
  43. package/dist/hitl/crashConvergedNotice.d.ts +4 -0
  44. package/dist/hitl/crashConvergedNotice.js +57 -0
  45. package/dist/hitl/hitlBridge.d.ts +7 -4
  46. package/dist/hitl/parkResolver.d.ts +7 -2
  47. package/dist/hitl/parkResolver.js +19 -7
  48. package/dist/hitl/planReviewWire.d.ts +1 -1
  49. package/dist/hitl/planReviewWire.js +18 -4
  50. package/dist/hitl/sessionPolicyWire.d.ts +5 -0
  51. package/dist/hitl/sessionPolicyWire.js +63 -0
  52. package/dist/hitl/suspendedReopen.js +2 -2
  53. package/dist/hitl/toolApprovalWire.d.ts +4 -1
  54. package/dist/hitl/toolApprovalWire.js +20 -0
  55. package/dist/hookMatcherVerdict.d.ts +29 -0
  56. package/dist/hookMatcherVerdict.js +265 -0
  57. package/dist/hookToolAliases.d.ts +3 -0
  58. package/dist/hookToolAliases.js +10 -0
  59. package/dist/humanTurn.d.ts +91 -0
  60. package/dist/humanTurn.js +253 -0
  61. package/dist/humanTurnRead.d.ts +105 -0
  62. package/dist/humanTurnRead.js +331 -0
  63. package/dist/index.d.ts +30 -5
  64. package/dist/index.js +19 -4
  65. package/dist/inheritEnvWire.js +1 -1
  66. package/dist/liveModelCatalog.d.ts +2 -0
  67. package/dist/liveModelCatalog.js +51 -3
  68. package/dist/permissionRuleIssue.d.ts +1 -1
  69. package/dist/permissionRuleIssue.js +22 -3
  70. package/dist/permissionsAllowGrantCapability.d.ts +18 -0
  71. package/dist/permissionsAllowGrantCapability.js +84 -0
  72. package/dist/permissionsDeclaration.d.ts +48 -0
  73. package/dist/permissionsDeclaration.js +307 -0
  74. package/dist/promptDelivery.d.ts +16 -5
  75. package/dist/promptDelivery.js +172 -32
  76. package/dist/providerRejection.d.ts +3 -1
  77. package/dist/providerRejection.js +27 -1
  78. package/dist/readDenyTiers.d.ts +10 -0
  79. package/dist/readDenyTiers.js +29 -0
  80. package/dist/request/taskRequest.js +27 -1
  81. package/dist/resumeRefusalCopy.d.ts +11 -0
  82. package/dist/resumeRefusalCopy.js +61 -4
  83. package/dist/rewindArchiveCapability.js +4 -4
  84. package/dist/rewindWireCaps.d.ts +2 -1
  85. package/dist/rewindWireCaps.js +19 -2
  86. package/dist/sdkRegistryTransit.d.ts +1 -0
  87. package/dist/sdkRegistryTransit.js +1 -0
  88. package/dist/seam.d.ts +2 -0
  89. package/dist/supportFloor.d.ts +10 -0
  90. package/dist/supportFloor.js +42 -0
  91. package/dist/taskRequestWords.d.ts +7 -0
  92. package/dist/taskRequestWords.js +24 -0
  93. package/dist/toolHistoryBadTurn.d.ts +1 -0
  94. package/dist/toolHistoryBadTurn.js +89 -0
  95. package/dist/toolHistoryMismatch.d.ts +2 -1
  96. package/dist/toolHistoryMismatch.js +19 -6
  97. package/dist/userAttachmentEnvelope.d.ts +61 -0
  98. package/dist/userAttachmentEnvelope.js +204 -0
  99. package/dist/wireFailureShape.d.ts +1 -0
  100. package/dist/wireFailureShape.js +4 -0
  101. package/dist/wireRefusalCopy.d.ts +6 -0
  102. package/dist/wireRefusalCopy.js +26 -3
  103. package/docs/INTEGRATION-CLIENTS.md +1369 -18
  104. package/package.json +3 -3
@@ -0,0 +1,253 @@
1
+ import { mintEnvelopeOf, mintReferenceOf } from './userAttachmentEnvelope.js';
2
+ import { readEncodingShares, readHumanTurnInput } from './humanTurnRead.js';
3
+ const REQUEST_BODY_MAX_BYTES = 8 * 1024 * 1024;
4
+ const IMAGE_SEAT_MAX_COUNT = 20;
5
+ const IMAGE_MAX_BASE64_CHARS_EACH = 6 * 1024 * 1024;
6
+ const IMAGE_SEAT_MAX_BASE64_CHARS_TOTAL = 6 * 1024 * 1024;
7
+ const STEER_MAX_CHARS = 16000;
8
+ const STEER_REMINDER_TAG = /<\s*\/?\s*system-reminder(?:\s[^>]*)?>/i;
9
+ const STEER_CONTROL_CHARS = /[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f]/;
10
+ function utf8Length(s) {
11
+ let n = 0;
12
+ for (let i = 0; i < s.length; i += 1) {
13
+ const c = s.charCodeAt(i);
14
+ if (c < 0x80)
15
+ n += 1;
16
+ else if (c < 0x800)
17
+ n += 2;
18
+ else if (c >= 0xd800 && c <= 0xdbff && i + 1 < s.length) {
19
+ const d = s.charCodeAt(i + 1);
20
+ if (d >= 0xdc00 && d <= 0xdfff) {
21
+ n += 4;
22
+ i += 1;
23
+ }
24
+ else
25
+ n += 3;
26
+ }
27
+ else
28
+ n += 3;
29
+ }
30
+ return n;
31
+ }
32
+ const jsonBytes = (v) => utf8Length(JSON.stringify(v));
33
+ function bodyBytes(other, objective, images, ids) {
34
+ const keys = [jsonBytes('objective') + 1 + jsonBytes(objective)];
35
+ if (images.length > 0)
36
+ keys.push(jsonBytes('images') + 1 + jsonBytes(images));
37
+ if (ids.length > 0)
38
+ keys.push(jsonBytes('attachmentIds') + 1 + jsonBytes(ids));
39
+ const commas = other === 2 ? keys.length - 1 : keys.length;
40
+ return other + keys.reduce((a, b) => a + b, 0) + commas;
41
+ }
42
+ function steerRefusal(text) {
43
+ if (text.length === 0)
44
+ return 'no_text';
45
+ if (STEER_REMINDER_TAG.test(text))
46
+ return 'reminder_tag';
47
+ if (STEER_CONTROL_CHARS.test(text))
48
+ return 'control_char';
49
+ if (text.length > STEER_MAX_CHARS)
50
+ return 'too_long';
51
+ return undefined;
52
+ }
53
+ function textOf(p) {
54
+ if (p.form === 'reference')
55
+ return mintReferenceOf(p.a.d);
56
+ return mintEnvelopeOf(p.a.d, p.seated ? 'attached' : 'not-attached');
57
+ }
58
+ function compose(items, placements) {
59
+ const perItem = items.map((it, i) => [...placements.filter((p) => p.item === i).map(textOf), it.text].filter((s) => s.length > 0).join('\n\n'));
60
+ return perItem.filter((s) => s.length > 0).join('\n');
61
+ }
62
+ function seatedImages(items, pastedWhy, placements) {
63
+ const out = [];
64
+ items.forEach((it, i) => {
65
+ it.images.forEach((img, k) => {
66
+ if (pastedWhy[i]?.[k] === undefined)
67
+ out.push('url' in img ? { url: img.url } : { data: img.data, mimeType: img.mimeType });
68
+ });
69
+ for (const p of placements) {
70
+ if (p.item === i && p.form === 'content' && p.seated && p.a.pixels !== undefined)
71
+ out.push({ data: p.a.pixels.data, mimeType: p.a.pixels.mimeType });
72
+ }
73
+ });
74
+ return out;
75
+ }
76
+ const ENCODER_WHY_LIST = [
77
+ 'body_budget',
78
+ 'steer_admission',
79
+ 'vision_no',
80
+ 'vision_unknown',
81
+ 'image_too_large',
82
+ 'seat_count',
83
+ 'seat_total',
84
+ 'lane_has_no_image_seat',
85
+ 'lane_has_no_attachment_id_seat',
86
+ ];
87
+ const encoderWhysExhaustive = true;
88
+ void encoderWhysExhaustive;
89
+ const ENCODER_WHYS = new Set(ENCODER_WHY_LIST);
90
+ function records(lane, items, pastedWhy, placements) {
91
+ const recs = [];
92
+ const push = (item, part) => {
93
+ recs.push({ item, part });
94
+ };
95
+ items.forEach((it, i) => {
96
+ if (it.text.length > 0)
97
+ push(i, { kind: 'text', status: 'full' });
98
+ it.images.forEach((_, k) => {
99
+ const why = pastedWhy[i]?.[k];
100
+ push(i, lane !== 'objective' ? { kind: 'image', ref: k, status: 'none', why: 'lane_has_no_image_seat' } : why === undefined ? { kind: 'image', ref: k, status: 'full' } : { kind: 'image', ref: k, status: 'none', why });
101
+ });
102
+ for (const p of placements) {
103
+ if (p.item !== i)
104
+ continue;
105
+ push(i, p.form === 'content' ? { kind: 'attachment_ref', ref: p.a.uuid, status: 'full' } : { kind: 'attachment_ref', ref: p.a.uuid, status: 'none', why: lane === 'objective' ? 'body_budget' : 'steer_admission' });
106
+ if (p.a.pixels !== undefined) {
107
+ if (lane === 'steer')
108
+ push(i, { kind: 'image', ref: p.a.uuid, status: 'none', why: 'lane_has_no_image_seat' });
109
+ else if (p.seated && p.form === 'content')
110
+ push(i, { kind: 'image', ref: p.a.uuid, status: 'full' });
111
+ else
112
+ push(i, { kind: 'image', ref: p.a.uuid, status: 'none', why: p.seated ? 'body_budget' : p.seatWhy });
113
+ }
114
+ }
115
+ for (const id of it.attachmentIds) {
116
+ push(i, lane === 'objective' ? { kind: 'attachment_id', ref: id, status: 'full' } : { kind: 'attachment_id', ref: id, status: 'none', why: 'lane_has_no_attachment_id_seat' });
117
+ }
118
+ for (const r of it.riders) {
119
+ if (r.role === 'image_meta')
120
+ continue;
121
+ push(i, r.textIncluded ? { kind: 'rider_text', ref: r.uuid, status: 'full' } : { kind: 'rider_text', ref: r.uuid, status: 'none', why: 'text_not_included' });
122
+ }
123
+ for (const m of it.missing) {
124
+ push(i, m.ref === undefined ? { kind: m.kind, status: 'none', why: m.reason } : { kind: m.kind, ref: m.ref, status: 'none', why: m.reason });
125
+ }
126
+ });
127
+ return recs;
128
+ }
129
+ function sharesAndDegraded(items, recs) {
130
+ const shares = items.map((it, i) => {
131
+ const parts = recs.filter((r) => r.item === i).map((r) => r.part);
132
+ const full = parts.filter((p) => p.status === 'full').length;
133
+ const level = parts.length > 0 && full === parts.length ? 'full' : full === 0 ? 'none' : 'partial';
134
+ return { uuid: it.uuid, riderUuids: [...it.riders.map((r) => r.uuid), ...it.attachments.map((a) => a.uuid)], level, parts };
135
+ });
136
+ const degraded = [];
137
+ for (const r of recs) {
138
+ const w = r.part.why;
139
+ if (r.part.status === 'none' && w !== undefined && ENCODER_WHYS.has(w)) {
140
+ const uuid = items[r.item].uuid;
141
+ degraded.push(r.part.ref === undefined ? { uuid, kind: r.part.kind, why: w } : { uuid, kind: r.part.kind, ref: r.part.ref, why: w });
142
+ }
143
+ }
144
+ return { shares, degraded };
145
+ }
146
+ function encodeObjective(v) {
147
+ const { items } = v;
148
+ let count = 0;
149
+ let total = 0;
150
+ const seat = (len) => {
151
+ if (len > IMAGE_MAX_BASE64_CHARS_EACH)
152
+ return 'image_too_large';
153
+ if (count + 1 > IMAGE_SEAT_MAX_COUNT)
154
+ return 'seat_count';
155
+ if (total + len > IMAGE_SEAT_MAX_BASE64_CHARS_TOTAL)
156
+ return 'seat_total';
157
+ count += 1;
158
+ total += len;
159
+ return undefined;
160
+ };
161
+ const pastedWhy = items.map((it) => it.images.map((img) => seat('data' in img ? img.data.length : 0)));
162
+ const placements = [];
163
+ items.forEach((it, i) => {
164
+ for (const a of it.attachments) {
165
+ const p = { item: i, a, form: 'content', seated: false, seatWhy: undefined };
166
+ if (a.pixels !== undefined) {
167
+ if (v.vision !== 'yes')
168
+ p.seatWhy = v.vision === 'no' ? 'vision_no' : 'vision_unknown';
169
+ else {
170
+ p.seatWhy = seat(a.pixels.data.length);
171
+ p.seated = p.seatWhy === undefined;
172
+ }
173
+ }
174
+ placements.push(p);
175
+ }
176
+ });
177
+ const ids = items.flatMap((it) => it.attachmentIds);
178
+ for (;;) {
179
+ const text = compose(items, placements);
180
+ const images = seatedImages(items, pastedWhy, placements);
181
+ if (bodyBytes(v.otherBodyBytes, text, images, ids) <= REQUEST_BODY_MAX_BYTES) {
182
+ if (text.trim() === '')
183
+ return { ok: false, reason: 'empty' };
184
+ const { shares, degraded } = sharesAndDegraded(items, records('objective', items, pastedWhy, placements));
185
+ return { ok: true, lane: 'objective', text, images, attachmentIds: [...ids], shares, degraded };
186
+ }
187
+ let pick = -1;
188
+ let pickCost = -1;
189
+ placements.forEach((p, k) => {
190
+ if (p.form !== 'content')
191
+ return;
192
+ const cost = jsonBytes(textOf(p)) + (p.seated && p.a.pixels !== undefined ? jsonBytes({ data: p.a.pixels.data, mimeType: p.a.pixels.mimeType }) : 0);
193
+ if (cost >= pickCost) {
194
+ pick = k;
195
+ pickCost = cost;
196
+ }
197
+ });
198
+ if (pick < 0)
199
+ return { ok: false, reason: 'oversize' };
200
+ placements[pick].form = 'reference';
201
+ }
202
+ }
203
+ function encodeSteer(v) {
204
+ const { items } = v;
205
+ const placements = [];
206
+ items.forEach((it, i) => {
207
+ for (const a of it.attachments)
208
+ placements.push({ item: i, a, form: 'content', seated: false, seatWhy: undefined });
209
+ });
210
+ let text = compose(items, placements);
211
+ let refusal = steerRefusal(text);
212
+ if (refusal !== undefined && refusal !== 'no_text' && placements.length > 0) {
213
+ for (const p of placements)
214
+ p.form = 'reference';
215
+ text = compose(items, placements);
216
+ refusal = steerRefusal(text);
217
+ }
218
+ if (refusal !== undefined)
219
+ return { ok: false, reason: 'steer_hold', why: refusal };
220
+ const { shares, degraded } = sharesAndDegraded(items, records('steer', items, [], placements));
221
+ return { ok: true, lane: 'steer', text, shares, degraded };
222
+ }
223
+ export function encodeHumanTurn(input) {
224
+ let v;
225
+ try {
226
+ v = readHumanTurnInput(input);
227
+ }
228
+ catch {
229
+ return { ok: false, reason: 'malformed_input' };
230
+ }
231
+ if ('reject' in v)
232
+ return { ok: false, reason: v.reject };
233
+ try {
234
+ return v.lane === 'objective' ? encodeObjective(v) : encodeSteer(v);
235
+ }
236
+ catch {
237
+ return { ok: false, reason: 'malformed_input' };
238
+ }
239
+ }
240
+ export function deliveredUuidsOf(encoding) {
241
+ const shares = readEncodingShares(encoding);
242
+ const full = [];
243
+ const partial = [];
244
+ for (const s of shares ?? []) {
245
+ const into = s.level === 'full' ? full : s.level === 'partial' ? partial : undefined;
246
+ if (into === undefined)
247
+ continue;
248
+ into.push(s.uuid);
249
+ for (const r of s.riderUuids)
250
+ into.push(r);
251
+ }
252
+ return { full, partial };
253
+ }
@@ -0,0 +1,105 @@
1
+ import type { ImageInput } from './imagesWireCaps.js';
2
+ import type { UserAttachmentDescriptor, UserAttachmentNotIncludedReason, UserAttachmentSource } from './userAttachmentEnvelope.js';
3
+ import type { HumanTurnAttachment, HumanTurnEncoding, HumanTurnInput, HumanTurnMissing } from './humanTurn.js';
4
+ import type { ImageVision } from './liveModelCatalog.js';
5
+ export interface CellView {
6
+ cellType: string | undefined;
7
+ source: string | undefined;
8
+ cellId: string | undefined;
9
+ language: string | undefined;
10
+ outputs: {
11
+ text: string | undefined;
12
+ hasImage: boolean;
13
+ }[];
14
+ outputsTooLarge: boolean;
15
+ }
16
+ export type DescriptorView = {
17
+ kind: 'text';
18
+ source: UserAttachmentSource;
19
+ name: string;
20
+ path: string;
21
+ lines: string[];
22
+ startLine: number;
23
+ totalLines: number;
24
+ complete: boolean;
25
+ } | {
26
+ kind: 'notebook';
27
+ source: UserAttachmentSource;
28
+ name: string;
29
+ path: string;
30
+ cells: CellView[];
31
+ } | {
32
+ kind: 'image';
33
+ source: UserAttachmentSource;
34
+ name: string;
35
+ path: string;
36
+ sizeBytes: number | null;
37
+ delivery: 'attached' | 'not-attached' | undefined;
38
+ } | {
39
+ kind: 'pdf';
40
+ source: UserAttachmentSource;
41
+ name: string;
42
+ path: string;
43
+ sizeBytes: number | null;
44
+ pageCount: number | null;
45
+ } | {
46
+ kind: 'directory';
47
+ name: string;
48
+ path: string;
49
+ entries: string[];
50
+ totalEntries: number;
51
+ } | {
52
+ kind: 'not-included';
53
+ target: 'file' | 'directory' | 'path';
54
+ name: string;
55
+ path: string;
56
+ sizeBytes: number | null;
57
+ reason: UserAttachmentNotIncludedReason;
58
+ };
59
+ export declare function readDescriptor(x: UserAttachmentDescriptor | HumanTurnAttachment['descriptor'], imageDelivery: 'required' | 'ignored'): DescriptorView | undefined;
60
+ type Reason = Exclude<Extract<HumanTurnEncoding, {
61
+ ok: false;
62
+ }>['reason'], 'steer_hold' | 'oversize'>;
63
+ export interface AttachmentView {
64
+ uuid: string;
65
+ d: DescriptorView;
66
+ pixels: {
67
+ data: string;
68
+ mimeType: string;
69
+ } | undefined;
70
+ }
71
+ export interface RiderView {
72
+ uuid: string;
73
+ role: string;
74
+ textIncluded: boolean;
75
+ }
76
+ export interface MissingView {
77
+ kind: HumanTurnMissing['kind'];
78
+ ref: string | undefined;
79
+ reason: HumanTurnMissing['reason'];
80
+ }
81
+ export interface ItemView {
82
+ uuid: string;
83
+ text: string;
84
+ images: ImageInput[];
85
+ attachments: AttachmentView[];
86
+ attachmentIds: string[];
87
+ riders: RiderView[];
88
+ missing: MissingView[];
89
+ }
90
+ export interface InputView {
91
+ lane: 'objective' | 'steer';
92
+ vision: ImageVision;
93
+ otherBodyBytes: number;
94
+ items: ItemView[];
95
+ }
96
+ export declare function readHumanTurnInput(input: HumanTurnInput): InputView | {
97
+ readonly reject: Reason;
98
+ };
99
+ export interface ShareView {
100
+ uuid: string;
101
+ level: 'full' | 'partial' | 'none';
102
+ riderUuids: string[];
103
+ }
104
+ export declare function readEncodingShares(encoding: HumanTurnEncoding): ShareView[] | undefined;
105
+ export {};
@@ -0,0 +1,331 @@
1
+ const descriptorKindsAligned = true;
2
+ void descriptorKindsAligned;
3
+ const MALFORMED = Object.freeze({});
4
+ const bad = () => {
5
+ throw MALFORMED;
6
+ };
7
+ function isPlainObject(x) {
8
+ if (x === null || typeof x !== 'object' || Array.isArray(x))
9
+ return false;
10
+ const p = Object.getPrototypeOf(x);
11
+ return p === Object.prototype || p === null;
12
+ }
13
+ function ownData(o, key) {
14
+ const d = Object.getOwnPropertyDescriptor(o, key);
15
+ if (d === undefined)
16
+ return undefined;
17
+ if (!('value' in d))
18
+ bad();
19
+ return d.value;
20
+ }
21
+ function ownArray(x) {
22
+ if (!Array.isArray(x))
23
+ bad();
24
+ const arr = x;
25
+ const n = ownData(arr, 'length');
26
+ if (typeof n !== 'number' || !Number.isSafeInteger(n) || n < 0)
27
+ bad();
28
+ const out = [];
29
+ for (let i = 0; i < n; i += 1) {
30
+ const d = Object.getOwnPropertyDescriptor(arr, i);
31
+ if (d === undefined || !('value' in d))
32
+ bad();
33
+ out.push(d.value);
34
+ }
35
+ return out;
36
+ }
37
+ const str = (v) => (typeof v === 'string' ? v : bad());
38
+ const optStr = (v) => (v === undefined ? undefined : str(v));
39
+ const strArray = (v) => ownArray(v).map(str);
40
+ const sizeOf = (v) => (v === null ? null : typeof v === 'number' ? v : bad());
41
+ const posInt = (v) => (typeof v === 'number' && Number.isSafeInteger(v) && v >= 1 ? v : bad());
42
+ const natInt = (v) => (typeof v === 'number' && Number.isSafeInteger(v) && v >= 0 ? v : bad());
43
+ function sourceOf(v) {
44
+ return v === 'at-mention' || v === 'compact-restore' ? v : bad();
45
+ }
46
+ function readCell(x) {
47
+ if (!isPlainObject(x))
48
+ bad();
49
+ const c = x;
50
+ const outputsRaw = ownData(c, 'outputs');
51
+ const outputs = outputsRaw === undefined
52
+ ? []
53
+ : ownArray(outputsRaw).map((o) => {
54
+ if (!isPlainObject(o))
55
+ bad();
56
+ const hasImage = ownData(o, 'hasImage');
57
+ if (hasImage !== undefined && typeof hasImage !== 'boolean')
58
+ bad();
59
+ return { text: optStr(ownData(o, 'text')), hasImage: hasImage === true };
60
+ });
61
+ const tooLarge = ownData(c, 'outputsTooLarge');
62
+ if (tooLarge !== undefined && typeof tooLarge !== 'boolean')
63
+ bad();
64
+ return {
65
+ cellType: optStr(ownData(c, 'cellType')),
66
+ source: optStr(ownData(c, 'source')),
67
+ cellId: optStr(ownData(c, 'cellId')),
68
+ language: optStr(ownData(c, 'language')),
69
+ outputs,
70
+ outputsTooLarge: tooLarge === true,
71
+ };
72
+ }
73
+ function readDescriptorAny(x, imageDelivery) {
74
+ try {
75
+ if (!isPlainObject(x))
76
+ return undefined;
77
+ const o = x;
78
+ const kind = ownData(o, 'kind');
79
+ const name = () => str(ownData(o, 'name'));
80
+ const path = () => str(ownData(o, 'path'));
81
+ switch (kind) {
82
+ case 'text': {
83
+ const complete = ownData(o, 'complete');
84
+ if (typeof complete !== 'boolean')
85
+ bad();
86
+ return {
87
+ kind,
88
+ source: sourceOf(ownData(o, 'source')),
89
+ name: name(),
90
+ path: path(),
91
+ lines: strArray(ownData(o, 'lines')),
92
+ startLine: posInt(ownData(o, 'startLine')),
93
+ totalLines: natInt(ownData(o, 'totalLines')),
94
+ complete: complete,
95
+ };
96
+ }
97
+ case 'notebook':
98
+ return { kind, source: sourceOf(ownData(o, 'source')), name: name(), path: path(), cells: ownArray(ownData(o, 'cells')).map(readCell) };
99
+ case 'image': {
100
+ let delivery;
101
+ if (imageDelivery === 'required') {
102
+ const d = ownData(o, 'delivery');
103
+ delivery = d === 'attached' || d === 'not-attached' ? d : bad();
104
+ }
105
+ return { kind, source: sourceOf(ownData(o, 'source')), name: name(), path: path(), sizeBytes: sizeOf(ownData(o, 'sizeBytes')), delivery };
106
+ }
107
+ case 'pdf': {
108
+ const pc = ownData(o, 'pageCount');
109
+ return {
110
+ kind,
111
+ source: sourceOf(ownData(o, 'source')),
112
+ name: name(),
113
+ path: path(),
114
+ sizeBytes: sizeOf(ownData(o, 'sizeBytes')),
115
+ pageCount: pc === null ? null : typeof pc === 'number' ? pc : bad(),
116
+ };
117
+ }
118
+ case 'directory':
119
+ return { kind, name: name(), path: path(), entries: strArray(ownData(o, 'entries')), totalEntries: natInt(ownData(o, 'totalEntries')) };
120
+ case 'not-included': {
121
+ const target = ownData(o, 'target');
122
+ const reason = ownData(o, 'reason');
123
+ if (target !== 'file' && target !== 'directory' && target !== 'path')
124
+ bad();
125
+ if (reason !== 'too-large' && reason !== 'unreadable' && reason !== 'read-denied')
126
+ bad();
127
+ return {
128
+ kind,
129
+ target: target,
130
+ name: name(),
131
+ path: path(),
132
+ sizeBytes: sizeOf(ownData(o, 'sizeBytes')),
133
+ reason: reason,
134
+ };
135
+ }
136
+ default:
137
+ return undefined;
138
+ }
139
+ }
140
+ catch {
141
+ return undefined;
142
+ }
143
+ }
144
+ export function readDescriptor(x, imageDelivery) {
145
+ return readDescriptorAny(x, imageDelivery);
146
+ }
147
+ const REASON_LIST = ['empty', 'malformed_input', 'malformed_item', 'duplicate_uuid', 'rider_collides_primary'];
148
+ const reasonListExhaustive = true;
149
+ void reasonListExhaustive;
150
+ const REJECT_SENTINELS = new Map(REASON_LIST.map((r) => [Object.freeze({}), r]));
151
+ const sentinelOf = (reason) => {
152
+ for (const [s, r] of REJECT_SENTINELS)
153
+ if (r === reason)
154
+ return s;
155
+ return MALFORMED;
156
+ };
157
+ const reject = (reason) => {
158
+ throw sentinelOf(reason);
159
+ };
160
+ const rejectReasonOf = (e) => (typeof e === 'object' && e !== null ? REJECT_SENTINELS.get(e) : undefined);
161
+ const nonEmpty = (v) => (typeof v === 'string' && v.length > 0 ? v : reject('malformed_item'));
162
+ const optArray = (v) => (v === undefined ? [] : ownArray(v));
163
+ function readImage(x) {
164
+ if (!isPlainObject(x))
165
+ reject('malformed_item');
166
+ const o = x;
167
+ const data = ownData(o, 'data');
168
+ const mimeType = ownData(o, 'mimeType');
169
+ const url = ownData(o, 'url');
170
+ if (url === undefined && data !== undefined)
171
+ return { data: nonEmpty(data), mimeType: nonEmpty(mimeType) };
172
+ if (data === undefined && mimeType === undefined)
173
+ return { url: nonEmpty(url) };
174
+ return reject('malformed_item');
175
+ }
176
+ const MISSING_KIND_LIST = ['rider_text', 'image', 'attachment_ref', 'non_text'];
177
+ const MISSING_REASON_LIST = ['not_persisted', 'not_found', 'non_text_filtered', 'projection_failed'];
178
+ const missingListsExhaustive = true;
179
+ void missingListsExhaustive;
180
+ const MISSING_KINDS = new Set(MISSING_KIND_LIST);
181
+ const MISSING_REASONS = new Set(MISSING_REASON_LIST);
182
+ function readItem(x) {
183
+ if (!isPlainObject(x))
184
+ reject('malformed_item');
185
+ const o = x;
186
+ const text = ownData(o, 'text');
187
+ if (typeof text !== 'string')
188
+ reject('malformed_item');
189
+ const attachments = optArray(ownData(o, 'attachments')).map((a) => {
190
+ if (!isPlainObject(a))
191
+ reject('malformed_item');
192
+ const ao = a;
193
+ const d = readDescriptorAny(ownData(ao, 'descriptor'), 'ignored');
194
+ if (d === undefined)
195
+ reject('malformed_item');
196
+ const px = ownData(ao, 'pixels');
197
+ let pixels;
198
+ if (px !== undefined) {
199
+ if (d.kind !== 'image' || !isPlainObject(px))
200
+ reject('malformed_item');
201
+ pixels = { data: nonEmpty(ownData(px, 'data')), mimeType: nonEmpty(ownData(px, 'mimeType')) };
202
+ }
203
+ return { uuid: nonEmpty(ownData(ao, 'uuid')), d: d, pixels };
204
+ });
205
+ return {
206
+ uuid: nonEmpty(ownData(o, 'uuid')),
207
+ text: text,
208
+ images: optArray(ownData(o, 'images')).map(readImage),
209
+ attachments,
210
+ attachmentIds: optArray(ownData(o, 'attachmentIds')).map(nonEmpty),
211
+ riders: optArray(ownData(o, 'riders')).map((r) => {
212
+ if (!isPlainObject(r))
213
+ reject('malformed_item');
214
+ const ti = ownData(r, 'textIncluded');
215
+ if (typeof ti !== 'boolean')
216
+ reject('malformed_item');
217
+ return { uuid: nonEmpty(ownData(r, 'uuid')), role: nonEmpty(ownData(r, 'role')), textIncluded: ti };
218
+ }),
219
+ missing: optArray(ownData(o, 'missing')).map((m) => {
220
+ if (!isPlainObject(m))
221
+ reject('malformed_item');
222
+ const kind = ownData(m, 'kind');
223
+ const reason = ownData(m, 'reason');
224
+ const ref = ownData(m, 'ref');
225
+ if (typeof kind !== 'string' || !MISSING_KINDS.has(kind))
226
+ reject('malformed_item');
227
+ if (typeof reason !== 'string' || !MISSING_REASONS.has(reason))
228
+ reject('malformed_item');
229
+ if (ref !== undefined && typeof ref !== 'string')
230
+ reject('malformed_item');
231
+ return { kind: kind, ref: ref, reason: reason };
232
+ }),
233
+ };
234
+ }
235
+ function readInputAny(x) {
236
+ if (!isPlainObject(x))
237
+ reject('malformed_input');
238
+ const o = x;
239
+ const lane = ownData(o, 'lane');
240
+ if (lane !== 'objective' && lane !== 'steer')
241
+ reject('malformed_input');
242
+ const caps = ownData(o, 'caps');
243
+ if (!isPlainObject(caps))
244
+ reject('malformed_input');
245
+ const vision = ownData(caps, 'vision');
246
+ if (vision !== undefined && vision !== 'yes' && vision !== 'no' && vision !== 'unknown')
247
+ reject('malformed_input');
248
+ let otherBodyBytes = 0;
249
+ if (lane === 'objective') {
250
+ const ob = ownData(o, 'otherBodyBytes');
251
+ if (typeof ob !== 'number' || !Number.isSafeInteger(ob) || ob < 2)
252
+ reject('malformed_input');
253
+ otherBodyBytes = ob;
254
+ }
255
+ const raw = ownData(o, 'items');
256
+ if (!Array.isArray(raw))
257
+ reject('malformed_input');
258
+ let rawItems;
259
+ try {
260
+ rawItems = ownArray(raw);
261
+ }
262
+ catch {
263
+ return reject('malformed_input');
264
+ }
265
+ if (rawItems.length === 0)
266
+ reject('empty');
267
+ const items = rawItems.map((x) => {
268
+ try {
269
+ return readItem(x);
270
+ }
271
+ catch (e) {
272
+ return reject(rejectReasonOf(e) ?? 'malformed_item');
273
+ }
274
+ });
275
+ const primaries = new Set();
276
+ for (const it of items) {
277
+ if (primaries.has(it.uuid))
278
+ reject('duplicate_uuid');
279
+ primaries.add(it.uuid);
280
+ }
281
+ const secondaries = new Set();
282
+ for (const it of items) {
283
+ for (const u of [...it.riders.map((r) => r.uuid), ...it.attachments.map((a) => a.uuid)]) {
284
+ if (primaries.has(u))
285
+ reject('rider_collides_primary');
286
+ if (secondaries.has(u))
287
+ reject('malformed_item');
288
+ secondaries.add(u);
289
+ }
290
+ }
291
+ if (items.every((it) => it.text.length === 0 && it.images.length === 0 && it.attachments.length === 0 && it.attachmentIds.length === 0))
292
+ reject('empty');
293
+ return { lane: lane, vision: vision ?? 'unknown', otherBodyBytes, items };
294
+ }
295
+ export function readHumanTurnInput(input) {
296
+ try {
297
+ return readInputAny(input);
298
+ }
299
+ catch (e) {
300
+ return { reject: rejectReasonOf(e) ?? 'malformed_input' };
301
+ }
302
+ }
303
+ export function readEncodingShares(encoding) {
304
+ try {
305
+ if (!isPlainObject(encoding) || ownData(encoding, 'ok') !== true)
306
+ return undefined;
307
+ const out = [];
308
+ for (const s of ownArray(ownData(encoding, 'shares'))) {
309
+ if (!isPlainObject(s))
310
+ return undefined;
311
+ const level = ownData(s, 'level');
312
+ const uuid = ownData(s, 'uuid');
313
+ const riders = ownArray(ownData(s, 'riderUuids'));
314
+ if (typeof uuid !== 'string' || uuid.length === 0)
315
+ return undefined;
316
+ if (level !== 'full' && level !== 'partial' && level !== 'none')
317
+ return undefined;
318
+ const riderUuids = [];
319
+ for (const r of riders) {
320
+ if (typeof r !== 'string' || r.length === 0)
321
+ return undefined;
322
+ riderUuids.push(r);
323
+ }
324
+ out.push({ uuid, level, riderUuids });
325
+ }
326
+ return out;
327
+ }
328
+ catch {
329
+ return undefined;
330
+ }
331
+ }