@or3/intern-client 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.
- package/README.md +76 -0
- package/dist/index.js +1362 -0
- package/package.json +34 -0
- package/src/client.ts +676 -0
- package/src/errors.ts +131 -0
- package/src/index.ts +6 -0
- package/src/protocol.ts +692 -0
- package/src/redaction.ts +114 -0
- package/src/sse.ts +151 -0
- package/src/transport.ts +915 -0
package/src/protocol.ts
ADDED
|
@@ -0,0 +1,692 @@
|
|
|
1
|
+
export type UnknownRecord = Record<string, unknown>;
|
|
2
|
+
|
|
3
|
+
export class InternProtocolError extends Error {
|
|
4
|
+
readonly code = 'protocol';
|
|
5
|
+
readonly path: string;
|
|
6
|
+
|
|
7
|
+
constructor(path: string, message: string) {
|
|
8
|
+
super(`${path}: ${message}`);
|
|
9
|
+
this.name = 'InternProtocolError';
|
|
10
|
+
this.path = path;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface InternHealth extends UnknownRecord {
|
|
15
|
+
status: string;
|
|
16
|
+
runtimeAvailable: boolean;
|
|
17
|
+
jobRegistryAvailable: boolean;
|
|
18
|
+
approvalBrokerAvailable: boolean;
|
|
19
|
+
processId: number;
|
|
20
|
+
startedAt: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface InternReadiness extends UnknownRecord {
|
|
24
|
+
status: string;
|
|
25
|
+
ready: boolean;
|
|
26
|
+
summary?: UnknownRecord;
|
|
27
|
+
findings?: unknown[];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface InternCapabilities extends UnknownRecord {
|
|
31
|
+
runtimeProfile: string;
|
|
32
|
+
hosted: boolean;
|
|
33
|
+
hostId: string;
|
|
34
|
+
approvalBroker: UnknownRecord;
|
|
35
|
+
approvals: Record<string, string>;
|
|
36
|
+
execAvailable: boolean;
|
|
37
|
+
sandboxEnabled: boolean;
|
|
38
|
+
sandboxRequired: boolean;
|
|
39
|
+
networkPolicy: UnknownRecord;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface InternRunner extends UnknownRecord {
|
|
43
|
+
id: string;
|
|
44
|
+
display_name: string;
|
|
45
|
+
status: string;
|
|
46
|
+
auth_status: string;
|
|
47
|
+
supports: UnknownRecord;
|
|
48
|
+
chat_capabilities?: UnknownRecord;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface InternRunnerList extends UnknownRecord {
|
|
52
|
+
runners: InternRunner[];
|
|
53
|
+
default_runner?: string;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface InternSession extends UnknownRecord {
|
|
57
|
+
id: string;
|
|
58
|
+
app_session_key: string;
|
|
59
|
+
runner_id: string;
|
|
60
|
+
continuation_mode: string;
|
|
61
|
+
created_at: number;
|
|
62
|
+
updated_at: number;
|
|
63
|
+
native_session_ref?: string;
|
|
64
|
+
model?: string;
|
|
65
|
+
mode?: string;
|
|
66
|
+
isolation?: string;
|
|
67
|
+
cwd?: string;
|
|
68
|
+
max_turns?: number;
|
|
69
|
+
meta?: unknown;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export interface InternSessionList extends UnknownRecord {
|
|
73
|
+
sessions: InternSession[];
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface InternTurn extends UnknownRecord {
|
|
77
|
+
id: string;
|
|
78
|
+
session_id: string;
|
|
79
|
+
sequence: number;
|
|
80
|
+
status: string;
|
|
81
|
+
continuation_mode: string;
|
|
82
|
+
requested_at: number;
|
|
83
|
+
started_at?: number;
|
|
84
|
+
completed_at?: number;
|
|
85
|
+
user_message?: string;
|
|
86
|
+
final_text?: string;
|
|
87
|
+
error?: string;
|
|
88
|
+
runner_run_id?: string;
|
|
89
|
+
runner_job_id?: string;
|
|
90
|
+
user_message_id?: number;
|
|
91
|
+
assistant_message_id?: number;
|
|
92
|
+
model?: string;
|
|
93
|
+
mode?: string;
|
|
94
|
+
isolation?: string;
|
|
95
|
+
cwd?: string;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export interface InternEvent extends UnknownRecord {
|
|
99
|
+
id: number;
|
|
100
|
+
turn_id: string;
|
|
101
|
+
seq: number;
|
|
102
|
+
ts: number;
|
|
103
|
+
type: string;
|
|
104
|
+
stream?: string;
|
|
105
|
+
text?: string;
|
|
106
|
+
job_id?: string;
|
|
107
|
+
payload?: unknown;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export interface InternApprovalDecision extends UnknownRecord {
|
|
111
|
+
request_id: number;
|
|
112
|
+
status?: string;
|
|
113
|
+
token?: string;
|
|
114
|
+
allowlist_id?: number;
|
|
115
|
+
session_key?: string;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export interface InternTurnList extends UnknownRecord {
|
|
119
|
+
turns: InternTurn[];
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export interface InternEventList extends UnknownRecord {
|
|
123
|
+
events: InternEvent[];
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export interface InternStartedTurn extends UnknownRecord {
|
|
127
|
+
session_id: string;
|
|
128
|
+
turn_id: string;
|
|
129
|
+
job_id: string;
|
|
130
|
+
status: string;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export interface InternActionAcknowledgement extends UnknownRecord {
|
|
134
|
+
status: string;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export interface InternTurnDecision extends UnknownRecord {
|
|
138
|
+
status: string;
|
|
139
|
+
decision: string;
|
|
140
|
+
route?: string;
|
|
141
|
+
approval_id?: number;
|
|
142
|
+
native_continued?: boolean;
|
|
143
|
+
fallback_to_token?: boolean;
|
|
144
|
+
allowlist_session?: boolean;
|
|
145
|
+
allowlist_id?: number;
|
|
146
|
+
token?: string;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export interface InternArtifact extends UnknownRecord {
|
|
150
|
+
id: string;
|
|
151
|
+
mime: string;
|
|
152
|
+
size_bytes: number;
|
|
153
|
+
offset: number;
|
|
154
|
+
read_bytes: number;
|
|
155
|
+
truncated: boolean;
|
|
156
|
+
content: string;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export interface InternApproval extends UnknownRecord {
|
|
160
|
+
id: string | number;
|
|
161
|
+
type: string;
|
|
162
|
+
status: string;
|
|
163
|
+
requested_at: number;
|
|
164
|
+
expires_at?: number;
|
|
165
|
+
resolved_at?: number;
|
|
166
|
+
preview?: string;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export interface InternApprovalList extends UnknownRecord {
|
|
170
|
+
items: InternApproval[];
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export interface InternPairResult extends UnknownRecord {
|
|
174
|
+
certificate: UnknownRecord;
|
|
175
|
+
certificate_hash: string;
|
|
176
|
+
device: UnknownRecord;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export interface CreateInternSessionInput {
|
|
180
|
+
app_session_key: string;
|
|
181
|
+
runner_id: string;
|
|
182
|
+
continuation_mode?: string;
|
|
183
|
+
model?: string;
|
|
184
|
+
mode?: string;
|
|
185
|
+
isolation?: string;
|
|
186
|
+
cwd?: string;
|
|
187
|
+
max_turns?: number;
|
|
188
|
+
approval_autopilot?: boolean;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
export interface StartInternTurnInput {
|
|
192
|
+
user_message: string;
|
|
193
|
+
attachments?: UnknownRecord[];
|
|
194
|
+
continuation_mode?: string;
|
|
195
|
+
model?: string;
|
|
196
|
+
mode?: string;
|
|
197
|
+
isolation?: string;
|
|
198
|
+
cwd?: string;
|
|
199
|
+
max_turns?: number;
|
|
200
|
+
timeout_seconds?: number;
|
|
201
|
+
meta?: UnknownRecord;
|
|
202
|
+
thinking_level?: string;
|
|
203
|
+
approval_token?: string;
|
|
204
|
+
approval_autopilot?: boolean;
|
|
205
|
+
runner_permission?: {
|
|
206
|
+
runner_id: string;
|
|
207
|
+
kind: string;
|
|
208
|
+
access: string;
|
|
209
|
+
target_path?: string;
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export interface InternApprovalInput {
|
|
214
|
+
note?: string;
|
|
215
|
+
allow_session?: boolean;
|
|
216
|
+
allowlist?: boolean;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
export interface InternPairInput {
|
|
220
|
+
rendezvous_id: string;
|
|
221
|
+
pairing_secret: string;
|
|
222
|
+
proposal: UnknownRecord;
|
|
223
|
+
trust_level: string;
|
|
224
|
+
expires_at?: number;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export type InternTurnDecisionAction = 'approve' | 'reject' | 'cancel';
|
|
228
|
+
export type InternApprovalDecisionAction = 'approve' | 'deny' | 'cancel';
|
|
229
|
+
|
|
230
|
+
function record(value: unknown, path: string): UnknownRecord {
|
|
231
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
232
|
+
throw new InternProtocolError(path, 'expected an object');
|
|
233
|
+
}
|
|
234
|
+
return value as UnknownRecord;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
function stringAt(
|
|
238
|
+
input: UnknownRecord,
|
|
239
|
+
key: string,
|
|
240
|
+
path: string
|
|
241
|
+
): string {
|
|
242
|
+
const value = input[key];
|
|
243
|
+
if (typeof value !== 'string') {
|
|
244
|
+
throw new InternProtocolError(`${path}.${key}`, 'expected a string');
|
|
245
|
+
}
|
|
246
|
+
return value;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
function numberAt(
|
|
250
|
+
input: UnknownRecord,
|
|
251
|
+
key: string,
|
|
252
|
+
path: string
|
|
253
|
+
): number {
|
|
254
|
+
const value = input[key];
|
|
255
|
+
if (typeof value !== 'number' || !Number.isFinite(value)) {
|
|
256
|
+
throw new InternProtocolError(`${path}.${key}`, 'expected a finite number');
|
|
257
|
+
}
|
|
258
|
+
return value;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
function booleanAt(
|
|
262
|
+
input: UnknownRecord,
|
|
263
|
+
key: string,
|
|
264
|
+
path: string
|
|
265
|
+
): boolean {
|
|
266
|
+
const value = input[key];
|
|
267
|
+
if (typeof value !== 'boolean') {
|
|
268
|
+
throw new InternProtocolError(`${path}.${key}`, 'expected a boolean');
|
|
269
|
+
}
|
|
270
|
+
return value;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
function optionalString(
|
|
274
|
+
input: UnknownRecord,
|
|
275
|
+
key: string,
|
|
276
|
+
path: string
|
|
277
|
+
): string | undefined {
|
|
278
|
+
const value = input[key];
|
|
279
|
+
if (value === undefined) return undefined;
|
|
280
|
+
if (typeof value !== 'string') {
|
|
281
|
+
throw new InternProtocolError(`${path}.${key}`, 'expected a string');
|
|
282
|
+
}
|
|
283
|
+
return value;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
function optionalNumber(
|
|
287
|
+
input: UnknownRecord,
|
|
288
|
+
key: string,
|
|
289
|
+
path: string
|
|
290
|
+
): number | undefined {
|
|
291
|
+
const value = input[key];
|
|
292
|
+
if (value === undefined) return undefined;
|
|
293
|
+
if (typeof value !== 'number' || !Number.isFinite(value)) {
|
|
294
|
+
throw new InternProtocolError(`${path}.${key}`, 'expected a finite number');
|
|
295
|
+
}
|
|
296
|
+
return value;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
function optionalBoolean(
|
|
300
|
+
input: UnknownRecord,
|
|
301
|
+
key: string,
|
|
302
|
+
path: string
|
|
303
|
+
): boolean | undefined {
|
|
304
|
+
const value = input[key];
|
|
305
|
+
if (value === undefined) return undefined;
|
|
306
|
+
if (typeof value !== 'boolean') {
|
|
307
|
+
throw new InternProtocolError(`${path}.${key}`, 'expected a boolean');
|
|
308
|
+
}
|
|
309
|
+
return value;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
export function parseInternRecord(
|
|
313
|
+
value: unknown,
|
|
314
|
+
path = 'response'
|
|
315
|
+
): UnknownRecord {
|
|
316
|
+
return { ...record(value, path) };
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
export function parseInternHealth(value: unknown): InternHealth {
|
|
320
|
+
const input = record(value, 'health');
|
|
321
|
+
return {
|
|
322
|
+
...input,
|
|
323
|
+
status: stringAt(input, 'status', 'health'),
|
|
324
|
+
runtimeAvailable: booleanAt(input, 'runtimeAvailable', 'health'),
|
|
325
|
+
jobRegistryAvailable: booleanAt(
|
|
326
|
+
input,
|
|
327
|
+
'jobRegistryAvailable',
|
|
328
|
+
'health'
|
|
329
|
+
),
|
|
330
|
+
approvalBrokerAvailable: booleanAt(
|
|
331
|
+
input,
|
|
332
|
+
'approvalBrokerAvailable',
|
|
333
|
+
'health'
|
|
334
|
+
),
|
|
335
|
+
processId: numberAt(input, 'processId', 'health'),
|
|
336
|
+
startedAt: stringAt(input, 'startedAt', 'health'),
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
export function parseInternReadiness(value: unknown): InternReadiness {
|
|
341
|
+
const input = record(value, 'readiness');
|
|
342
|
+
const findings = input.findings;
|
|
343
|
+
if (findings !== undefined && !Array.isArray(findings)) {
|
|
344
|
+
throw new InternProtocolError(
|
|
345
|
+
'readiness.findings',
|
|
346
|
+
'expected an array'
|
|
347
|
+
);
|
|
348
|
+
}
|
|
349
|
+
return {
|
|
350
|
+
...input,
|
|
351
|
+
status: stringAt(input, 'status', 'readiness'),
|
|
352
|
+
ready: booleanAt(input, 'ready', 'readiness'),
|
|
353
|
+
summary:
|
|
354
|
+
input.summary === undefined
|
|
355
|
+
? undefined
|
|
356
|
+
: record(input.summary, 'readiness.summary'),
|
|
357
|
+
findings,
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
export function parseInternCapabilities(
|
|
362
|
+
value: unknown
|
|
363
|
+
): InternCapabilities {
|
|
364
|
+
const input = record(value, 'capabilities');
|
|
365
|
+
const approvalInput = record(input.approvals, 'capabilities.approvals');
|
|
366
|
+
const approvals: Record<string, string> = {};
|
|
367
|
+
for (const [key, item] of Object.entries(approvalInput)) {
|
|
368
|
+
if (typeof item !== 'string') {
|
|
369
|
+
throw new InternProtocolError(
|
|
370
|
+
`capabilities.approvals.${key}`,
|
|
371
|
+
'expected a string'
|
|
372
|
+
);
|
|
373
|
+
}
|
|
374
|
+
approvals[key] = item;
|
|
375
|
+
}
|
|
376
|
+
return {
|
|
377
|
+
...input,
|
|
378
|
+
runtimeProfile: stringAt(input, 'runtimeProfile', 'capabilities'),
|
|
379
|
+
hosted: booleanAt(input, 'hosted', 'capabilities'),
|
|
380
|
+
hostId: stringAt(input, 'hostId', 'capabilities'),
|
|
381
|
+
approvalBroker: record(
|
|
382
|
+
input.approvalBroker,
|
|
383
|
+
'capabilities.approvalBroker'
|
|
384
|
+
),
|
|
385
|
+
approvals,
|
|
386
|
+
execAvailable: booleanAt(input, 'execAvailable', 'capabilities'),
|
|
387
|
+
sandboxEnabled: booleanAt(input, 'sandboxEnabled', 'capabilities'),
|
|
388
|
+
sandboxRequired: booleanAt(input, 'sandboxRequired', 'capabilities'),
|
|
389
|
+
networkPolicy: record(
|
|
390
|
+
input.networkPolicy,
|
|
391
|
+
'capabilities.networkPolicy'
|
|
392
|
+
),
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
export function parseInternRunnerList(value: unknown): InternRunnerList {
|
|
397
|
+
const input = record(value, 'runnerList');
|
|
398
|
+
if (!Array.isArray(input.runners)) {
|
|
399
|
+
throw new InternProtocolError('runnerList.runners', 'expected an array');
|
|
400
|
+
}
|
|
401
|
+
const runners = input.runners.map((item, index) => {
|
|
402
|
+
const runner = record(item, `runnerList.runners[${index}]`);
|
|
403
|
+
return {
|
|
404
|
+
...runner,
|
|
405
|
+
id: stringAt(runner, 'id', `runnerList.runners[${index}]`),
|
|
406
|
+
display_name: stringAt(
|
|
407
|
+
runner,
|
|
408
|
+
'display_name',
|
|
409
|
+
`runnerList.runners[${index}]`
|
|
410
|
+
),
|
|
411
|
+
status: stringAt(
|
|
412
|
+
runner,
|
|
413
|
+
'status',
|
|
414
|
+
`runnerList.runners[${index}]`
|
|
415
|
+
),
|
|
416
|
+
auth_status: stringAt(
|
|
417
|
+
runner,
|
|
418
|
+
'auth_status',
|
|
419
|
+
`runnerList.runners[${index}]`
|
|
420
|
+
),
|
|
421
|
+
supports: record(
|
|
422
|
+
runner.supports,
|
|
423
|
+
`runnerList.runners[${index}].supports`
|
|
424
|
+
),
|
|
425
|
+
chat_capabilities:
|
|
426
|
+
runner.chat_capabilities === undefined
|
|
427
|
+
? undefined
|
|
428
|
+
: record(
|
|
429
|
+
runner.chat_capabilities,
|
|
430
|
+
`runnerList.runners[${index}].chat_capabilities`
|
|
431
|
+
),
|
|
432
|
+
};
|
|
433
|
+
});
|
|
434
|
+
return {
|
|
435
|
+
...input,
|
|
436
|
+
runners,
|
|
437
|
+
default_runner: optionalString(
|
|
438
|
+
input,
|
|
439
|
+
'default_runner',
|
|
440
|
+
'runnerList'
|
|
441
|
+
),
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
export function parseInternSession(value: unknown): InternSession {
|
|
446
|
+
const input = record(value, 'session');
|
|
447
|
+
return {
|
|
448
|
+
...input,
|
|
449
|
+
id: stringAt(input, 'id', 'session'),
|
|
450
|
+
app_session_key: stringAt(input, 'app_session_key', 'session'),
|
|
451
|
+
runner_id: stringAt(input, 'runner_id', 'session'),
|
|
452
|
+
continuation_mode: stringAt(
|
|
453
|
+
input,
|
|
454
|
+
'continuation_mode',
|
|
455
|
+
'session'
|
|
456
|
+
),
|
|
457
|
+
created_at: numberAt(input, 'created_at', 'session'),
|
|
458
|
+
updated_at: numberAt(input, 'updated_at', 'session'),
|
|
459
|
+
native_session_ref: optionalString(
|
|
460
|
+
input,
|
|
461
|
+
'native_session_ref',
|
|
462
|
+
'session'
|
|
463
|
+
),
|
|
464
|
+
model: optionalString(input, 'model', 'session'),
|
|
465
|
+
mode: optionalString(input, 'mode', 'session'),
|
|
466
|
+
isolation: optionalString(input, 'isolation', 'session'),
|
|
467
|
+
cwd: optionalString(input, 'cwd', 'session'),
|
|
468
|
+
max_turns: optionalNumber(input, 'max_turns', 'session'),
|
|
469
|
+
meta: input.meta,
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
export function parseInternSessionList(value: unknown): InternSessionList {
|
|
474
|
+
const input = record(value, 'sessionList');
|
|
475
|
+
if (!Array.isArray(input.sessions)) {
|
|
476
|
+
throw new InternProtocolError(
|
|
477
|
+
'sessionList.sessions',
|
|
478
|
+
'expected an array'
|
|
479
|
+
);
|
|
480
|
+
}
|
|
481
|
+
return {
|
|
482
|
+
...input,
|
|
483
|
+
sessions: input.sessions.map(parseInternSession),
|
|
484
|
+
};
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
export function parseInternTurn(value: unknown): InternTurn {
|
|
488
|
+
const input = record(value, 'turn');
|
|
489
|
+
return {
|
|
490
|
+
...input,
|
|
491
|
+
id: stringAt(input, 'id', 'turn'),
|
|
492
|
+
session_id: stringAt(input, 'session_id', 'turn'),
|
|
493
|
+
sequence: numberAt(input, 'sequence', 'turn'),
|
|
494
|
+
status: stringAt(input, 'status', 'turn'),
|
|
495
|
+
continuation_mode: stringAt(input, 'continuation_mode', 'turn'),
|
|
496
|
+
requested_at: numberAt(input, 'requested_at', 'turn'),
|
|
497
|
+
started_at: optionalNumber(input, 'started_at', 'turn'),
|
|
498
|
+
completed_at: optionalNumber(input, 'completed_at', 'turn'),
|
|
499
|
+
user_message: optionalString(input, 'user_message', 'turn'),
|
|
500
|
+
final_text: optionalString(input, 'final_text', 'turn'),
|
|
501
|
+
error: optionalString(input, 'error', 'turn'),
|
|
502
|
+
runner_run_id: optionalString(input, 'runner_run_id', 'turn'),
|
|
503
|
+
runner_job_id: optionalString(input, 'runner_job_id', 'turn'),
|
|
504
|
+
user_message_id: optionalNumber(input, 'user_message_id', 'turn'),
|
|
505
|
+
assistant_message_id: optionalNumber(
|
|
506
|
+
input,
|
|
507
|
+
'assistant_message_id',
|
|
508
|
+
'turn'
|
|
509
|
+
),
|
|
510
|
+
model: optionalString(input, 'model', 'turn'),
|
|
511
|
+
mode: optionalString(input, 'mode', 'turn'),
|
|
512
|
+
isolation: optionalString(input, 'isolation', 'turn'),
|
|
513
|
+
cwd: optionalString(input, 'cwd', 'turn'),
|
|
514
|
+
};
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
export function parseInternEvent(value: unknown): InternEvent {
|
|
518
|
+
const input = record(value, 'event');
|
|
519
|
+
return {
|
|
520
|
+
...input,
|
|
521
|
+
id: numberAt(input, 'id', 'event'),
|
|
522
|
+
turn_id: stringAt(input, 'turn_id', 'event'),
|
|
523
|
+
seq: numberAt(input, 'seq', 'event'),
|
|
524
|
+
ts: numberAt(input, 'ts', 'event'),
|
|
525
|
+
type: stringAt(input, 'type', 'event'),
|
|
526
|
+
stream: optionalString(input, 'stream', 'event'),
|
|
527
|
+
text: optionalString(input, 'text', 'event'),
|
|
528
|
+
job_id: optionalString(input, 'job_id', 'event'),
|
|
529
|
+
payload: input.payload,
|
|
530
|
+
};
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
export function parseInternApprovalDecision(
|
|
534
|
+
value: unknown
|
|
535
|
+
): InternApprovalDecision {
|
|
536
|
+
const input = record(value, 'approvalDecision');
|
|
537
|
+
return {
|
|
538
|
+
...input,
|
|
539
|
+
request_id: numberAt(input, 'request_id', 'approvalDecision'),
|
|
540
|
+
status: optionalString(input, 'status', 'approvalDecision'),
|
|
541
|
+
token: optionalString(input, 'token', 'approvalDecision'),
|
|
542
|
+
allowlist_id: optionalNumber(
|
|
543
|
+
input,
|
|
544
|
+
'allowlist_id',
|
|
545
|
+
'approvalDecision'
|
|
546
|
+
),
|
|
547
|
+
session_key: optionalString(
|
|
548
|
+
input,
|
|
549
|
+
'session_key',
|
|
550
|
+
'approvalDecision'
|
|
551
|
+
),
|
|
552
|
+
};
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
export function parseInternTurnList(value: unknown): InternTurnList {
|
|
556
|
+
const input = record(value, 'turnList');
|
|
557
|
+
if (!Array.isArray(input.turns)) {
|
|
558
|
+
throw new InternProtocolError('turnList.turns', 'expected an array');
|
|
559
|
+
}
|
|
560
|
+
return {
|
|
561
|
+
...input,
|
|
562
|
+
turns: input.turns.map(parseInternTurn),
|
|
563
|
+
};
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
export function parseInternEventList(value: unknown): InternEventList {
|
|
567
|
+
const input = record(value, 'eventList');
|
|
568
|
+
if (!Array.isArray(input.events)) {
|
|
569
|
+
throw new InternProtocolError('eventList.events', 'expected an array');
|
|
570
|
+
}
|
|
571
|
+
return {
|
|
572
|
+
...input,
|
|
573
|
+
events: input.events.map(parseInternEvent),
|
|
574
|
+
};
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
export function parseInternStartedTurn(value: unknown): InternStartedTurn {
|
|
578
|
+
const input = record(value, 'startedTurn');
|
|
579
|
+
return {
|
|
580
|
+
...input,
|
|
581
|
+
session_id: stringAt(input, 'session_id', 'startedTurn'),
|
|
582
|
+
turn_id: stringAt(input, 'turn_id', 'startedTurn'),
|
|
583
|
+
job_id: stringAt(input, 'job_id', 'startedTurn'),
|
|
584
|
+
status: stringAt(input, 'status', 'startedTurn'),
|
|
585
|
+
};
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
export function parseInternActionAcknowledgement(
|
|
589
|
+
value: unknown
|
|
590
|
+
): InternActionAcknowledgement {
|
|
591
|
+
const input = record(value, 'action');
|
|
592
|
+
return {
|
|
593
|
+
...input,
|
|
594
|
+
status: stringAt(input, 'status', 'action'),
|
|
595
|
+
};
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
export function parseInternTurnDecision(value: unknown): InternTurnDecision {
|
|
599
|
+
const input = record(value, 'turnDecision');
|
|
600
|
+
return {
|
|
601
|
+
...input,
|
|
602
|
+
status: stringAt(input, 'status', 'turnDecision'),
|
|
603
|
+
decision: stringAt(input, 'decision', 'turnDecision'),
|
|
604
|
+
route: optionalString(input, 'route', 'turnDecision'),
|
|
605
|
+
approval_id: optionalNumber(input, 'approval_id', 'turnDecision'),
|
|
606
|
+
native_continued: optionalBoolean(
|
|
607
|
+
input,
|
|
608
|
+
'native_continued',
|
|
609
|
+
'turnDecision'
|
|
610
|
+
),
|
|
611
|
+
fallback_to_token: optionalBoolean(
|
|
612
|
+
input,
|
|
613
|
+
'fallback_to_token',
|
|
614
|
+
'turnDecision'
|
|
615
|
+
),
|
|
616
|
+
allowlist_session: optionalBoolean(
|
|
617
|
+
input,
|
|
618
|
+
'allowlist_session',
|
|
619
|
+
'turnDecision'
|
|
620
|
+
),
|
|
621
|
+
allowlist_id: optionalNumber(
|
|
622
|
+
input,
|
|
623
|
+
'allowlist_id',
|
|
624
|
+
'turnDecision'
|
|
625
|
+
),
|
|
626
|
+
token: optionalString(input, 'token', 'turnDecision'),
|
|
627
|
+
};
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
export function parseInternArtifact(value: unknown): InternArtifact {
|
|
631
|
+
const input = record(value, 'artifact');
|
|
632
|
+
return {
|
|
633
|
+
...input,
|
|
634
|
+
id: stringAt(input, 'id', 'artifact'),
|
|
635
|
+
mime: stringAt(input, 'mime', 'artifact'),
|
|
636
|
+
size_bytes: numberAt(input, 'size_bytes', 'artifact'),
|
|
637
|
+
offset: numberAt(input, 'offset', 'artifact'),
|
|
638
|
+
read_bytes: numberAt(input, 'read_bytes', 'artifact'),
|
|
639
|
+
truncated: booleanAt(input, 'truncated', 'artifact'),
|
|
640
|
+
content: stringAt(input, 'content', 'artifact'),
|
|
641
|
+
};
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
function parseInternApproval(value: unknown, index: number): InternApproval {
|
|
645
|
+
const path = `approvalList.items[${index}]`;
|
|
646
|
+
const input = record(value, path);
|
|
647
|
+
const id = input.id;
|
|
648
|
+
if (
|
|
649
|
+
(typeof id !== 'string' && typeof id !== 'number') ||
|
|
650
|
+
(typeof id === 'number' && !Number.isFinite(id))
|
|
651
|
+
) {
|
|
652
|
+
throw new InternProtocolError(`${path}.id`, 'expected an ID');
|
|
653
|
+
}
|
|
654
|
+
return {
|
|
655
|
+
...input,
|
|
656
|
+
id,
|
|
657
|
+
type: stringAt(input, 'type', path),
|
|
658
|
+
status: stringAt(input, 'status', path),
|
|
659
|
+
requested_at: numberAt(input, 'requested_at', path),
|
|
660
|
+
expires_at: optionalNumber(input, 'expires_at', path),
|
|
661
|
+
resolved_at: optionalNumber(input, 'resolved_at', path),
|
|
662
|
+
preview: optionalString(input, 'preview', path),
|
|
663
|
+
};
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
export function parseInternApprovalList(value: unknown): InternApprovalList {
|
|
667
|
+
const input = record(value, 'approvalList');
|
|
668
|
+
if (!Array.isArray(input.items)) {
|
|
669
|
+
throw new InternProtocolError(
|
|
670
|
+
'approvalList.items',
|
|
671
|
+
'expected an array'
|
|
672
|
+
);
|
|
673
|
+
}
|
|
674
|
+
return {
|
|
675
|
+
...input,
|
|
676
|
+
items: input.items.map(parseInternApproval),
|
|
677
|
+
};
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
export function parseInternPairResult(value: unknown): InternPairResult {
|
|
681
|
+
const input = record(value, 'pairResult');
|
|
682
|
+
return {
|
|
683
|
+
...input,
|
|
684
|
+
certificate: record(input.certificate, 'pairResult.certificate'),
|
|
685
|
+
certificate_hash: stringAt(
|
|
686
|
+
input,
|
|
687
|
+
'certificate_hash',
|
|
688
|
+
'pairResult'
|
|
689
|
+
),
|
|
690
|
+
device: record(input.device, 'pairResult.device'),
|
|
691
|
+
};
|
|
692
|
+
}
|