@eigenpal/sdk 0.7.1 → 0.8.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.
@@ -1,68 +1,46 @@
1
1
  import type { OperationResult } from '../client';
2
- import { EigenpalError } from '../errors';
3
2
  import type { Client } from '../generated/client';
4
3
  import {
4
+ runsArtifactsGet,
5
5
  runsArtifactsList,
6
6
  runsCancel,
7
- runsComparisonGet,
8
- runsConnect,
9
- runsDefinitionGet,
10
- runsExpectedCreate,
11
- runsExpectedFileDelete,
12
- runsExpectedFileGet,
13
- runsExpectedFileUpdate,
14
- runsExpectedGet,
7
+ runsEvalResultsList,
8
+ runsEventsList,
15
9
  runsFeedbackClear,
16
10
  runsFeedbackGet,
17
11
  runsFeedbackUpdate,
18
- runsFilesDelete,
19
- runsFilesList,
20
- runsFilesUpload,
21
- runsFilesZipGet,
22
12
  runsGet,
23
13
  runsList,
14
+ runsPromote,
24
15
  runsRerun,
16
+ runsStepsList,
25
17
  runsTraceGet,
18
+ runsUsageGet,
26
19
  } from '../generated/sdk.gen';
27
20
  import type {
28
- RunArtifactsResponse,
29
- RunDefinitionResponse,
21
+ RunsArtifactsListResponse,
30
22
  RunsCancelResponse,
31
- RunsComparisonGetResponse,
32
- RunsConnectResponse,
33
- RunsExpectedCreateData,
34
- RunsExpectedCreateResponse,
35
- RunsExpectedFileDeleteResponse,
36
- RunsExpectedFileUpdateData,
37
- RunsExpectedFileUpdateResponse,
38
- RunsExpectedGetResponse,
23
+ RunsEvalResultsListResponse,
24
+ RunsEventsListResponse,
39
25
  RunsFeedbackClearResponse,
40
26
  RunsFeedbackGetResponse,
41
- RunsFeedbackUpdateData,
42
27
  RunsFeedbackUpdateResponse,
43
- RunsFilesDeleteResponse,
44
- RunsFilesListResponse,
45
- RunsFilesUploadData,
46
- RunsFilesUploadResponse,
47
28
  RunsGetResponse,
48
29
  RunsListData,
49
30
  RunsListResponse,
31
+ RunsPromoteResponse,
50
32
  RunsRerunResponse,
33
+ RunsStepsListResponse,
51
34
  RunsTraceGetResponse,
35
+ RunsUsageGetResponse,
52
36
  } from '../generated/types.gen';
53
37
 
54
38
  type Dispatch = <T>(call: () => Promise<OperationResult<T>>) => Promise<T>;
39
+ type SignalOptions = { signal?: AbortSignal };
55
40
 
56
41
  export type ListRunsOptions = NonNullable<RunsListData['query']> & { signal?: AbortSignal };
57
- type SignalOptions = { signal?: AbortSignal };
58
42
 
59
- /**
60
- * Expandable sections for `runs.get`. Each token adds one nested object with
61
- * the same name. Terminal runs expose top-level `output`, `files`, and `error`.
62
- */
63
43
  export type RunExpandSection = 'input' | 'usage' | 'execution' | 'debug';
64
-
65
- /** Typed section list, or a raw comma-separated string for forward compat. */
66
44
  export type RunExpand = readonly RunExpandSection[] | (string & {});
67
45
 
68
46
  function formatExpand(expand: RunExpand | undefined): string | undefined {
@@ -72,22 +50,18 @@ function formatExpand(expand: RunExpand | undefined): string | undefined {
72
50
  }
73
51
 
74
52
  export class RunsResource {
75
- public readonly feedback: RunsFeedbackResource;
76
- public readonly expected: RunsExpectedResource;
77
- public readonly files: RunsFilesResource;
78
53
  public readonly artifacts: RunsArtifactsResource;
79
- public readonly comparison: RunsComparisonResource;
54
+ public readonly evalResults: RunsEvalResultsResource;
55
+ public readonly feedback: RunsFeedbackResource;
80
56
  public readonly trace: RunsTraceResource;
81
57
 
82
58
  constructor(
83
59
  private readonly client: Client,
84
60
  private readonly dispatch: Dispatch
85
61
  ) {
86
- this.feedback = new RunsFeedbackResource(client, dispatch);
87
- this.expected = new RunsExpectedResource(client, dispatch);
88
- this.files = new RunsFilesResource(client, dispatch);
89
62
  this.artifacts = new RunsArtifactsResource(client, dispatch);
90
- this.comparison = new RunsComparisonResource(client, dispatch);
63
+ this.evalResults = new RunsEvalResultsResource(client, dispatch);
64
+ this.feedback = new RunsFeedbackResource(client, dispatch);
91
65
  this.trace = new RunsTraceResource(client, dispatch);
92
66
  }
93
67
 
@@ -96,17 +70,12 @@ export class RunsResource {
96
70
  return this.dispatch(() => runsList({ client: this.client, query, signal }));
97
71
  }
98
72
 
99
- /**
100
- * Fetch the canonical grouped run object. Terminal runs include top-level
101
- * `output`, `files`, and `error`. Pass `expand` (for example
102
- * `['usage', 'execution']`) to add optional nested detail objects.
103
- */
104
73
  async get(
105
74
  runId: string,
106
75
  options: { expand?: RunExpand; signal?: AbortSignal } = {}
107
76
  ): Promise<RunsGetResponse> {
108
77
  const expand = formatExpand(options.expand);
109
- return this.dispatch<RunsGetResponse>(() =>
78
+ return this.dispatch(() =>
110
79
  runsGet({
111
80
  client: this.client,
112
81
  path: { id: runId },
@@ -122,6 +91,21 @@ export class RunsResource {
122
91
  );
123
92
  }
124
93
 
94
+ async promote(
95
+ runId: string,
96
+ body: Record<string, unknown> = {},
97
+ options: SignalOptions = {}
98
+ ): Promise<RunsPromoteResponse> {
99
+ return this.dispatch(() =>
100
+ runsPromote({
101
+ client: this.client,
102
+ path: { id: runId },
103
+ body: body as never,
104
+ signal: options.signal,
105
+ })
106
+ );
107
+ }
108
+
125
109
  async rerun(
126
110
  runId: string,
127
111
  query: { version?: string; wait_for_completion?: number } = {},
@@ -132,99 +116,27 @@ export class RunsResource {
132
116
  );
133
117
  }
134
118
 
135
- async compare(
136
- referenceRunId: string,
137
- runId: string,
138
- options: {
139
- baseline?: boolean;
140
- step?: string;
141
- normalizeDates?: boolean;
142
- signal?: AbortSignal;
143
- } = {}
144
- ): Promise<RunComparisonReport> {
145
- const mode = options.baseline ? 'baseline' : 'expected';
146
- const [reference, target] = await Promise.all([
147
- this.get(referenceRunId, {
148
- expand: ['execution'],
149
- signal: options.signal,
150
- }),
151
- this.get(runId, { expand: ['execution'], signal: options.signal }),
152
- ]);
153
-
154
- if (isWorkflowRun(reference) && isWorkflowRun(target)) {
155
- return compareWorkflowRuns(referenceRunId, reference, runId, target, options.step);
156
- }
157
- if (options.step) {
158
- throw new EigenpalError(
159
- '`step` is only supported when both runs are workflow runs. Agent runs do not have workflow steps.',
160
- { status: 400 }
161
- );
162
- }
163
- if (isWorkflowRun(reference) || isWorkflowRun(target)) {
164
- throw new EigenpalError(
165
- 'Mixed workflow/agent comparisons are not supported. Compare two workflow runs or two agent runs.',
166
- { status: 400 }
167
- );
168
- }
169
- return compareArtifactRuns(
170
- referenceRunId,
171
- reference,
172
- runId,
173
- target,
174
- mode,
175
- Boolean(options.normalizeDates)
119
+ async usage(runId: string, options: SignalOptions = {}): Promise<RunsUsageGetResponse> {
120
+ return this.dispatch(() =>
121
+ runsUsageGet({ client: this.client, path: { id: runId }, signal: options.signal })
176
122
  );
177
123
  }
178
124
 
179
- async connect(runId: string, options: SignalOptions = {}): Promise<RunsConnectResponse> {
125
+ async steps(runId: string, options: SignalOptions = {}): Promise<RunsStepsListResponse> {
180
126
  return this.dispatch(() =>
181
- runsConnect({ client: this.client, path: { id: runId }, signal: options.signal })
127
+ runsStepsList({ client: this.client, path: { id: runId }, signal: options.signal })
182
128
  );
183
129
  }
184
130
 
185
- async definition(runId: string, options: SignalOptions = {}): Promise<RunDefinitionResponse> {
131
+ async events(runId: string, options: SignalOptions = {}): Promise<RunsEventsListResponse> {
186
132
  return this.dispatch(() =>
187
- runsDefinitionGet({ client: this.client, path: { id: runId }, signal: options.signal })
133
+ runsEventsList({ client: this.client, path: { id: runId }, signal: options.signal })
188
134
  );
189
135
  }
190
136
  }
191
137
 
192
- type RunRecord = Record<string, unknown>;
193
- type ComparisonMode = 'expected' | 'baseline';
194
-
195
- export type RunComparisonReport = {
196
- status: 'pass' | 'fail';
197
- runId: string;
198
- comparedWithRunId: string;
199
- mode?: ComparisonMode;
200
- steps?: Array<Record<string, unknown>>;
201
- jsonDifferences?: Array<Record<string, string>>;
202
- matchedFiles?: Array<Record<string, string>>;
203
- missingFiles?: string[];
204
- extraFiles?: string[];
205
- warnings?: string[];
206
- };
207
-
208
- function isWorkflowRun(run: unknown): run is RunRecord {
209
- return isRecord(run) && run.type === 'workflow';
210
- }
211
-
212
- function isRecord(value: unknown): value is RunRecord {
213
- return value != null && typeof value === 'object' && !Array.isArray(value);
214
- }
215
-
216
- function runExecution(run: RunRecord): RunRecord {
217
- return isRecord(run.execution) ? run.execution : {};
218
- }
219
-
220
- function runResult(run: RunRecord): RunRecord {
221
- return isRecord(run.result) ? run.result : {};
222
- }
223
-
224
138
  export function runOutput(run: unknown): unknown {
225
- if (!isRecord(run)) return undefined;
226
- if (run.output !== undefined) return run.output;
227
- return runResult(run).output;
139
+ return isRecord(run) ? run.output : undefined;
228
140
  }
229
141
 
230
142
  export function runUsage(run: unknown): unknown {
@@ -235,372 +147,73 @@ export function runExecutionDetails(run: unknown): unknown {
235
147
  return isRecord(run) ? run.execution : undefined;
236
148
  }
237
149
 
238
- function workflowSteps(run: RunRecord): unknown[] {
239
- const steps = runExecution(run).steps;
240
- return Array.isArray(steps) ? steps : [];
241
- }
242
-
243
- function agentOutputFiles(run: RunRecord): unknown[] {
244
- const rawFiles = runExecution(run).files;
245
- const files: RunRecord = isRecord(rawFiles) ? rawFiles : {};
246
- return Array.isArray(files.output) ? files.output : [];
247
- }
248
-
249
- function agentExpected(run: RunRecord): RunRecord {
250
- const expected = runExecution(run).expected;
251
- return isRecord(expected) ? expected : {};
252
- }
253
-
254
- function compareWorkflowRuns(
255
- referenceRunId: string,
256
- reference: RunRecord,
257
- runId: string,
258
- target: RunRecord,
259
- stepFilter?: string
260
- ): RunComparisonReport {
261
- const wanted = stepFilter
262
- ?.split(',')
263
- .map((step) => step.trim())
264
- .filter(Boolean);
265
- const targetSteps = new Map(
266
- workflowSteps(target)
267
- .filter(isRecord)
268
- .map((step) => [String(step.stepName ?? step.name ?? step.id ?? ''), step])
269
- );
270
- const steps = workflowSteps(reference)
271
- .filter(isRecord)
272
- .filter(
273
- (step) => !wanted?.length || wanted.includes(String(step.stepName ?? step.name ?? step.id))
274
- )
275
- .map((referenceStep) => {
276
- const stepName = String(
277
- referenceStep.stepName ?? referenceStep.name ?? referenceStep.id ?? ''
278
- );
279
- const targetStep = targetSteps.get(stepName);
280
- const referenceOutput = referenceStep.outputData ?? referenceStep.output;
281
- const targetOutput = targetStep?.outputData ?? targetStep?.output;
282
- return {
283
- stepName,
284
- referenceStatus: String(referenceStep.status ?? ''),
285
- targetStatus: String(targetStep?.status ?? 'missing'),
286
- outputState: stableJson(referenceOutput) === stableJson(targetOutput) ? 'match' : 'diff',
287
- };
288
- });
289
- return {
290
- status: steps.every((step) => step.targetStatus !== 'missing' && step.outputState === 'match')
291
- ? 'pass'
292
- : 'fail',
293
- runId,
294
- comparedWithRunId: referenceRunId,
295
- steps,
296
- };
297
- }
298
-
299
- function compareArtifactRuns(
300
- referenceRunId: string,
301
- reference: unknown,
302
- runId: string,
303
- target: unknown,
304
- mode: ComparisonMode,
305
- normalizeDates: boolean
306
- ): RunComparisonReport {
307
- const referenceRun = isRecord(reference) ? reference : {};
308
- const targetRun = isRecord(target) ? target : {};
309
- const expectedValue =
310
- mode === 'baseline' ? runOutput(referenceRun) : agentExpected(referenceRun).output;
311
- const expectedFiles =
312
- mode === 'baseline'
313
- ? names(agentOutputFiles(referenceRun))
314
- : names(agentExpected(referenceRun).files);
315
- const outputFiles = names(agentOutputFiles(targetRun));
316
- const missing = expectedFiles.filter(
317
- (name) =>
318
- !outputFiles.some(
319
- (out) => comparableName(out, normalizeDates) === comparableName(name, normalizeDates)
320
- )
321
- );
322
- const extra = outputFiles.filter(
323
- (name) =>
324
- !expectedFiles.some(
325
- (exp) => comparableName(exp, normalizeDates) === comparableName(name, normalizeDates)
326
- )
327
- );
328
- const matched = expectedFiles
329
- .filter((name) => !missing.includes(name))
330
- .map((name) => ({
331
- expected: name,
332
- actual:
333
- outputFiles.find(
334
- (out) => comparableName(out, normalizeDates) === comparableName(name, normalizeDates)
335
- ) ?? name,
336
- }));
337
- const jsonDifferences = diffJson(expectedValue, runOutput(targetRun));
338
- return {
339
- status:
340
- jsonDifferences.length === 0 && missing.length === 0 && extra.length === 0 ? 'pass' : 'fail',
341
- runId,
342
- comparedWithRunId: referenceRunId,
343
- mode,
344
- jsonDifferences,
345
- matchedFiles: matched,
346
- missingFiles: missing,
347
- extraFiles: extra,
348
- };
349
- }
350
-
351
- function names(value: unknown): string[] {
352
- if (!Array.isArray(value)) return [];
353
- return value.map((item) => (isRecord(item) ? String(item.name ?? '') : '')).filter(Boolean);
354
- }
355
-
356
- function comparableName(value: string, normalizeDates: boolean): string {
357
- if (!normalizeDates) return value;
358
- return value.replace(/\d{4}-\d{2}-\d{2}/g, '<date>').replace(/\d{8}/g, '<date>');
359
- }
360
-
361
- function stableJson(value: unknown): string {
362
- return JSON.stringify(value ?? null);
363
- }
364
-
365
- function diffJson(
366
- expected: unknown,
367
- actual: unknown,
368
- basePath = '$'
369
- ): Array<Record<string, string>> {
370
- if (expected == null) return [];
371
- if (Object.is(expected, actual)) return [];
372
- if (isRecord(expected) && isRecord(actual)) {
373
- const keys = new Set([...Object.keys(expected), ...Object.keys(actual)]);
374
- return [...keys].flatMap((key) => {
375
- const next = `${basePath}.${key}`;
376
- if (!(key in actual)) return [{ path: next, type: 'missing' }];
377
- if (!(key in expected)) return [{ path: next, type: 'extra' }];
378
- return diffJson(expected[key], actual[key], next);
379
- });
380
- }
381
- return [{ path: basePath, type: 'changed' }];
382
- }
383
-
384
- export class RunsFeedbackResource {
150
+ export class RunsArtifactsResource {
385
151
  constructor(
386
152
  private readonly client: Client,
387
153
  private readonly dispatch: Dispatch
388
154
  ) {}
389
155
 
390
- async get(runId: string, options: SignalOptions = {}): Promise<RunsFeedbackGetResponse> {
156
+ async list(runId: string, options: SignalOptions = {}): Promise<RunsArtifactsListResponse> {
391
157
  return this.dispatch(() =>
392
- runsFeedbackGet({ client: this.client, path: { id: runId }, signal: options.signal })
158
+ runsArtifactsList({ client: this.client, path: { id: runId }, signal: options.signal })
393
159
  );
394
160
  }
395
161
 
396
- async update(
397
- runId: string,
398
- body: RunsFeedbackUpdateData['body'],
399
- options: SignalOptions = {}
400
- ): Promise<RunsFeedbackUpdateResponse> {
401
- return this.dispatch(() =>
402
- runsFeedbackUpdate({
162
+ async download(runId: string, path: string, options: SignalOptions = {}): Promise<Blob> {
163
+ return this.dispatch(async () => {
164
+ const response = await runsArtifactsGet({
403
165
  client: this.client,
404
- path: { id: runId },
405
- body,
166
+ path: { id: runId, path },
406
167
  signal: options.signal,
407
- })
408
- );
409
- }
410
-
411
- async resolve(
412
- runId: string,
413
- body: Omit<NonNullable<RunsFeedbackUpdateData['body']>, 'status'> = {},
414
- options: SignalOptions = {}
415
- ): Promise<RunsFeedbackUpdateResponse> {
416
- return this.update(runId, { ...body, status: 'resolved' }, options);
417
- }
418
-
419
- async clear(runId: string, options: SignalOptions = {}): Promise<RunsFeedbackClearResponse> {
420
- return this.dispatch(() =>
421
- runsFeedbackClear({ client: this.client, path: { id: runId }, signal: options.signal })
422
- );
168
+ });
169
+ return response as OperationResult<Blob>;
170
+ });
423
171
  }
424
172
  }
425
173
 
426
- export class RunsExpectedResource {
174
+ export class RunsFeedbackResource {
427
175
  constructor(
428
176
  private readonly client: Client,
429
177
  private readonly dispatch: Dispatch
430
178
  ) {}
431
179
 
432
- async list(runId: string, options: SignalOptions = {}): Promise<RunsExpectedGetResponse> {
180
+ async get(runId: string, options: SignalOptions = {}): Promise<RunsFeedbackGetResponse> {
433
181
  return this.dispatch(() =>
434
- runsExpectedGet({ client: this.client, path: { id: runId }, signal: options.signal })
182
+ runsFeedbackGet({ client: this.client, path: { id: runId }, signal: options.signal })
435
183
  );
436
184
  }
437
185
 
438
- async copyOutput(
186
+ async update(
439
187
  runId: string,
440
- body: RunsExpectedCreateData['body'],
188
+ body: Record<string, unknown>,
441
189
  options: SignalOptions = {}
442
- ): Promise<RunsExpectedCreateResponse> {
190
+ ): Promise<RunsFeedbackUpdateResponse> {
443
191
  return this.dispatch(() =>
444
- runsExpectedCreate({
192
+ runsFeedbackUpdate({
445
193
  client: this.client,
446
194
  path: { id: runId },
447
- body,
448
- signal: options.signal,
449
- })
450
- );
451
- }
452
-
453
- async upload(
454
- runId: string,
455
- file: Blob,
456
- options: { name?: string; filename?: string; signal?: AbortSignal } = {}
457
- ): Promise<RunsExpectedCreateResponse> {
458
- const form = new FormData();
459
- if (options.filename) form.append('file', file, options.filename);
460
- else form.append('file', file);
461
- if (options.name) form.append('name', options.name);
462
- return this.dispatch(
463
- () =>
464
- this.client.post({
465
- url: '/api/v1/runs/{id}/expected',
466
- path: { id: runId },
467
- body: form,
468
- signal: options.signal,
469
- }) as Promise<OperationResult<RunsExpectedCreateResponse>>
470
- );
471
- }
472
-
473
- async rename(
474
- runId: string,
475
- filename: string,
476
- body: RunsExpectedFileUpdateData['body'],
477
- options: SignalOptions = {}
478
- ): Promise<RunsExpectedFileUpdateResponse> {
479
- return this.dispatch(() =>
480
- runsExpectedFileUpdate({
481
- client: this.client,
482
- path: { id: runId, filename },
483
- body,
195
+ body: body as never,
484
196
  signal: options.signal,
485
197
  })
486
198
  );
487
199
  }
488
200
 
489
- async delete(
490
- runId: string,
491
- filename: string,
492
- options: SignalOptions = {}
493
- ): Promise<RunsExpectedFileDeleteResponse> {
494
- return this.dispatch(() =>
495
- runsExpectedFileDelete({
496
- client: this.client,
497
- path: { id: runId, filename },
498
- signal: options.signal,
499
- })
500
- );
501
- }
502
-
503
- async download(runId: string, filename: string, options: SignalOptions = {}): Promise<Blob> {
504
- return downloadBlob(
505
- () =>
506
- runsExpectedFileGet({
507
- client: this.client,
508
- path: { id: runId, filename },
509
- parseAs: 'blob',
510
- signal: options.signal,
511
- }) as Promise<OperationResult<Blob>>
512
- );
513
- }
514
- }
515
-
516
- export class RunsFilesResource {
517
- constructor(
518
- private readonly client: Client,
519
- private readonly dispatch: Dispatch
520
- ) {}
521
-
522
- async list(runId: string, options: SignalOptions = {}): Promise<RunsFilesListResponse> {
523
- return this.dispatch(() =>
524
- runsFilesList({ client: this.client, path: { id: runId }, signal: options.signal })
525
- );
526
- }
527
-
528
- async upload(
529
- runId: string,
530
- body: RunsFilesUploadData['body'],
531
- options: SignalOptions = {}
532
- ): Promise<RunsFilesUploadResponse> {
533
- return this.dispatch(() =>
534
- runsFilesUpload({ client: this.client, path: { id: runId }, body, signal: options.signal })
535
- );
536
- }
537
-
538
- async delete(
539
- runId: string,
540
- fileId: string,
541
- options: SignalOptions = {}
542
- ): Promise<RunsFilesDeleteResponse> {
543
- return this.dispatch(() =>
544
- runsFilesDelete({
545
- client: this.client,
546
- path: { id: runId, fileId },
547
- signal: options.signal,
548
- })
549
- );
550
- }
551
- }
552
-
553
- export class RunsArtifactsResource {
554
- constructor(
555
- private readonly client: Client,
556
- private readonly dispatch: Dispatch
557
- ) {}
558
-
559
- async list(runId: string, options: SignalOptions = {}): Promise<RunArtifactsResponse> {
560
- const { signal } = options;
201
+ async clear(runId: string, options: SignalOptions = {}): Promise<RunsFeedbackClearResponse> {
561
202
  return this.dispatch(() =>
562
- runsArtifactsList({ client: this.client, path: { id: runId }, signal })
563
- );
564
- }
565
-
566
- async download(runId: string, path: string, options: SignalOptions = {}): Promise<Blob> {
567
- return downloadBlob(
568
- () =>
569
- this.client.get({
570
- url: `/api/v1/runs/${encodeURIComponent(runId)}/artifacts/${encodeArtifactPath(path)}`,
571
- parseAs: 'blob',
572
- signal: options.signal,
573
- }) as Promise<OperationResult<Blob>>
574
- );
575
- }
576
-
577
- async downloadZip(
578
- runId: string,
579
- options: { files?: string; token?: string; signal?: AbortSignal } = {}
580
- ): Promise<Blob> {
581
- const { signal, ...query } = options;
582
- return downloadBlob(
583
- () =>
584
- runsFilesZipGet({
585
- client: this.client,
586
- path: { id: runId },
587
- query,
588
- parseAs: 'blob',
589
- signal,
590
- }) as Promise<OperationResult<Blob>>
203
+ runsFeedbackClear({ client: this.client, path: { id: runId }, signal: options.signal })
591
204
  );
592
205
  }
593
206
  }
594
207
 
595
- export class RunsComparisonResource {
208
+ export class RunsEvalResultsResource {
596
209
  constructor(
597
210
  private readonly client: Client,
598
211
  private readonly dispatch: Dispatch
599
212
  ) {}
600
213
 
601
- async get(runId: string, options: SignalOptions = {}): Promise<RunsComparisonGetResponse> {
214
+ async list(runId: string, options: SignalOptions = {}): Promise<RunsEvalResultsListResponse> {
602
215
  return this.dispatch(() =>
603
- runsComparisonGet({ client: this.client, path: { id: runId }, signal: options.signal })
216
+ runsEvalResultsList({ client: this.client, path: { id: runId }, signal: options.signal })
604
217
  );
605
218
  }
606
219
  }
@@ -618,16 +231,6 @@ export class RunsTraceResource {
618
231
  }
619
232
  }
620
233
 
621
- async function downloadBlob(call: () => Promise<OperationResult<Blob>>): Promise<Blob> {
622
- const result = await call();
623
- if (result.response?.ok && result.data instanceof Blob) {
624
- return result.data;
625
- }
626
- throw new EigenpalError('Failed to download run artifact.', {
627
- status: result.response?.status ?? 0,
628
- });
629
- }
630
-
631
- function encodeArtifactPath(path: string): string {
632
- return path.split('/').map(encodeURIComponent).join('/');
234
+ function isRecord(value: unknown): value is Record<string, unknown> {
235
+ return value != null && typeof value === 'object' && !Array.isArray(value);
633
236
  }
package/src/telemetry.ts CHANGED
@@ -19,7 +19,7 @@
19
19
  export const SDK_LANGUAGE = 'typescript';
20
20
  // Rewritten at publish time by scripts/render-sdk-versions.sh.
21
21
  // Keep this string literal exactly stable — sed matches on it.
22
- export const SDK_VERSION = '0.7.1';
22
+ export const SDK_VERSION = '0.8.0';
23
23
 
24
24
  function detectRuntime(): string {
25
25
  const g = globalThis as unknown as {