@ai-sdk/harness 1.0.71 → 1.0.73

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.
@@ -2,7 +2,9 @@ import { HarnessCapabilityUnsupportedError } from '../errors/harness-capability-
2
2
  import type {
3
3
  HarnessV1Bootstrap,
4
4
  HarnessV1BuiltinToolFiltering,
5
+ HarnessV1JSONSchema,
5
6
  HarnessV1NetworkSandboxSession,
7
+ HarnessV1ResponseFormat,
6
8
  HarnessV1SandboxProvider,
7
9
  } from '../v1';
8
10
  import {
@@ -18,6 +20,7 @@ import type {
18
20
  AgentCallParameters,
19
21
  AgentStreamParameters,
20
22
  GenerateTextResult,
23
+ OutputInterface as Output,
21
24
  ReasoningFileOutput,
22
25
  ReasoningOutput,
23
26
  StopCondition,
@@ -118,11 +121,12 @@ export class HarnessAgent<
118
121
  THarness extends HarnessAgentAdapter<any> = HarnessAgentAdapter,
119
122
  TUserTools extends ToolSet = {},
120
123
  RUNTIME_CONTEXT extends Context = Context,
124
+ OUTPUT extends Output = never,
121
125
  > implements Agent<
122
126
  never,
123
127
  HarnessAllTools<THarness, TUserTools>,
124
128
  RUNTIME_CONTEXT,
125
- never
129
+ OUTPUT
126
130
  > {
127
131
  readonly version = 'agent-v1' as const;
128
132
  readonly id: string | undefined;
@@ -138,7 +142,8 @@ export class HarnessAgent<
138
142
  private readonly settings: HarnessAgentSettings<
139
143
  THarness,
140
144
  TUserTools,
141
- RUNTIME_CONTEXT
145
+ RUNTIME_CONTEXT,
146
+ OUTPUT
142
147
  >;
143
148
  private readonly stopConditions: Array<
144
149
  StopCondition<HarnessAllTools<THarness, TUserTools>, RUNTIME_CONTEXT>
@@ -151,7 +156,12 @@ export class HarnessAgent<
151
156
  private readonly permissionMode: HarnessAgentPermissionMode;
152
157
 
153
158
  constructor(
154
- settings: HarnessAgentSettings<THarness, TUserTools, RUNTIME_CONTEXT>,
159
+ settings: HarnessAgentSettings<
160
+ THarness,
161
+ TUserTools,
162
+ RUNTIME_CONTEXT,
163
+ OUTPUT
164
+ >,
155
165
  ) {
156
166
  const sandboxConfig = resolveSandboxConfig(settings);
157
167
  validateSandboxBootstrapSettings(sandboxConfig);
@@ -400,16 +410,18 @@ export class HarnessAgent<
400
410
  GenerateTextResult<
401
411
  HarnessAllTools<THarness, TUserTools>,
402
412
  RUNTIME_CONTEXT,
403
- never
413
+ OUTPUT
404
414
  >
405
415
  > {
406
416
  const turnInput = this._resolveTurnInput(options);
407
417
  const runtimeContext = {} as RUNTIME_CONTEXT;
418
+ const responseFormat = await this._resolveResponseFormat();
408
419
  const { result, done } = this._startTurn({
409
420
  session: options.session,
410
421
  turnInput,
411
422
  runtimeContext,
412
423
  abortSignal: options.abortSignal,
424
+ responseFormat,
413
425
  });
414
426
  await done;
415
427
  return this._toGenerateResult(result);
@@ -426,16 +438,18 @@ export class HarnessAgent<
426
438
  StreamTextResult<
427
439
  HarnessAllTools<THarness, TUserTools>,
428
440
  RUNTIME_CONTEXT,
429
- never
441
+ OUTPUT
430
442
  >
431
443
  > {
432
444
  const turnInput = this._resolveTurnInput(options);
433
445
  const runtimeContext = {} as RUNTIME_CONTEXT;
446
+ const responseFormat = await this._resolveResponseFormat();
434
447
  const { result } = this._startTurn({
435
448
  session: options.session,
436
449
  turnInput,
437
450
  runtimeContext,
438
451
  abortSignal: options.abortSignal,
452
+ responseFormat,
439
453
  });
440
454
  return result;
441
455
  }
@@ -454,10 +468,11 @@ export class HarnessAgent<
454
468
  GenerateTextResult<
455
469
  HarnessAllTools<THarness, TUserTools>,
456
470
  RUNTIME_CONTEXT,
457
- never
471
+ OUTPUT
458
472
  >
459
473
  > {
460
474
  const runtimeContext = {} as RUNTIME_CONTEXT;
475
+ const responseFormat = await this._resolveResponseFormat();
461
476
 
462
477
  const { result, done } = this._startTurn({
463
478
  session: options.session,
@@ -468,6 +483,7 @@ export class HarnessAgent<
468
483
  },
469
484
  runtimeContext,
470
485
  abortSignal: options.abortSignal,
486
+ responseFormat,
471
487
  });
472
488
  await done;
473
489
  return this._toGenerateResult(result);
@@ -490,10 +506,11 @@ export class HarnessAgent<
490
506
  StreamTextResult<
491
507
  HarnessAllTools<THarness, TUserTools>,
492
508
  RUNTIME_CONTEXT,
493
- never
509
+ OUTPUT
494
510
  >
495
511
  > {
496
512
  const runtimeContext = {} as RUNTIME_CONTEXT;
513
+ const responseFormat = await this._resolveResponseFormat();
497
514
 
498
515
  const { result } = this._startTurn({
499
516
  session: options.session,
@@ -504,6 +521,7 @@ export class HarnessAgent<
504
521
  },
505
522
  runtimeContext,
506
523
  abortSignal: options.abortSignal,
524
+ responseFormat,
507
525
  });
508
526
  return result;
509
527
  }
@@ -521,18 +539,20 @@ export class HarnessAgent<
521
539
  };
522
540
  runtimeContext: RUNTIME_CONTEXT;
523
541
  abortSignal: AbortSignal | undefined;
542
+ responseFormat: HarnessV1ResponseFormat | undefined;
524
543
  }): {
525
544
  result: StreamTextResult<
526
545
  HarnessAllTools<THarness, TUserTools>,
527
546
  RUNTIME_CONTEXT,
528
- never
547
+ OUTPUT
529
548
  >;
530
549
  done: Promise<void>;
531
550
  } {
532
551
  if (input.turnInput.mode === 'continue') {
533
552
  return input.session.continueTurn<
534
553
  HarnessAllTools<THarness, TUserTools>,
535
- RUNTIME_CONTEXT
554
+ RUNTIME_CONTEXT,
555
+ OUTPUT
536
556
  >({
537
557
  instructions: this.settings.instructions,
538
558
  tools: this.tools,
@@ -541,6 +561,8 @@ export class HarnessAgent<
541
561
  builtinToolFiltering: this.builtinToolFiltering,
542
562
  runtimeContext: input.runtimeContext,
543
563
  abortSignal: input.abortSignal,
564
+ responseFormat: input.responseFormat,
565
+ output: this.settings.output,
544
566
  telemetry: this.settings.telemetry,
545
567
  stopConditions: this.stopConditions,
546
568
  toolApprovalContinuations: input.turnInput.toolApprovalContinuations,
@@ -550,7 +572,8 @@ export class HarnessAgent<
550
572
 
551
573
  return input.session.promptTurn<
552
574
  HarnessAllTools<THarness, TUserTools>,
553
- RUNTIME_CONTEXT
575
+ RUNTIME_CONTEXT,
576
+ OUTPUT
554
577
  >({
555
578
  prompt: input.turnInput.prompt,
556
579
  instructions: this.settings.instructions,
@@ -560,6 +583,8 @@ export class HarnessAgent<
560
583
  builtinToolFiltering: this.builtinToolFiltering,
561
584
  runtimeContext: input.runtimeContext,
562
585
  abortSignal: input.abortSignal,
586
+ responseFormat: input.responseFormat,
587
+ output: this.settings.output,
563
588
  telemetry: this.settings.telemetry,
564
589
  stopConditions: this.stopConditions,
565
590
  });
@@ -677,28 +702,51 @@ export class HarnessAgent<
677
702
  streamResult: StreamTextResult<
678
703
  HarnessAllTools<THarness, TUserTools>,
679
704
  RUNTIME_CONTEXT,
680
- never
705
+ OUTPUT
681
706
  >,
682
707
  ): Promise<
683
708
  GenerateTextResult<
684
709
  HarnessAllTools<THarness, TUserTools>,
685
710
  RUNTIME_CONTEXT,
686
- never
711
+ OUTPUT
687
712
  >
688
713
  > {
689
714
  // The stream is already drained by the time generate() calls this helper
690
715
  // (done has resolved). `steps` is the single source of truth the result
691
716
  // derives everything else from, mirroring core's `generateText` result.
692
- const [steps, usage, responseMessages] = await Promise.all([
717
+ const [steps, usage, responseMessages, output] = await Promise.all([
693
718
  streamResult.steps,
694
719
  streamResult.usage,
695
720
  streamResult.responseMessages,
721
+ this.settings.output == null
722
+ ? Promise.resolve(undefined as never)
723
+ : streamResult.output,
696
724
  ]);
697
725
 
698
726
  return new HarnessGenerateTextResult<
699
727
  HarnessAllTools<THarness, TUserTools>,
700
- RUNTIME_CONTEXT
701
- >({ steps, usage, responseMessages });
728
+ RUNTIME_CONTEXT,
729
+ OUTPUT
730
+ >({ steps, usage, responseMessages, output });
731
+ }
732
+
733
+ private async _resolveResponseFormat(): Promise<
734
+ HarnessV1ResponseFormat | undefined
735
+ > {
736
+ const responseFormat = await this.settings.output?.responseFormat;
737
+ if (responseFormat == null || responseFormat.type === 'text') {
738
+ return responseFormat == null ? undefined : { type: 'text' };
739
+ }
740
+ return {
741
+ type: 'json',
742
+ ...(responseFormat.schema == null
743
+ ? {}
744
+ : { schema: responseFormat.schema as HarnessV1JSONSchema }),
745
+ ...(responseFormat.name == null ? {} : { name: responseFormat.name }),
746
+ ...(responseFormat.description == null
747
+ ? {}
748
+ : { description: responseFormat.description }),
749
+ };
702
750
  }
703
751
  }
704
752
 
@@ -713,28 +761,31 @@ export class HarnessAgent<
713
761
  class HarnessGenerateTextResult<
714
762
  TOOLS extends ToolSet,
715
763
  RUNTIME_CONTEXT extends Context,
716
- > implements GenerateTextResult<TOOLS, RUNTIME_CONTEXT, never> {
717
- readonly steps: GenerateTextResult<TOOLS, RUNTIME_CONTEXT, never>['steps'];
718
- readonly usage: GenerateTextResult<TOOLS, RUNTIME_CONTEXT, never>['usage'];
764
+ OUTPUT extends Output,
765
+ > implements GenerateTextResult<TOOLS, RUNTIME_CONTEXT, OUTPUT> {
766
+ readonly steps: GenerateTextResult<TOOLS, RUNTIME_CONTEXT, OUTPUT>['steps'];
767
+ readonly usage: GenerateTextResult<TOOLS, RUNTIME_CONTEXT, OUTPUT>['usage'];
719
768
  readonly responseMessages: GenerateTextResult<
720
769
  TOOLS,
721
770
  RUNTIME_CONTEXT,
722
- never
771
+ OUTPUT
723
772
  >['responseMessages'];
724
- readonly output = undefined as never;
773
+ readonly output: GenerateTextResult<TOOLS, RUNTIME_CONTEXT, OUTPUT>['output'];
725
774
 
726
775
  constructor(options: {
727
- steps: GenerateTextResult<TOOLS, RUNTIME_CONTEXT, never>['steps'];
728
- usage: GenerateTextResult<TOOLS, RUNTIME_CONTEXT, never>['usage'];
776
+ steps: GenerateTextResult<TOOLS, RUNTIME_CONTEXT, OUTPUT>['steps'];
777
+ usage: GenerateTextResult<TOOLS, RUNTIME_CONTEXT, OUTPUT>['usage'];
729
778
  responseMessages: GenerateTextResult<
730
779
  TOOLS,
731
780
  RUNTIME_CONTEXT,
732
- never
781
+ OUTPUT
733
782
  >['responseMessages'];
783
+ output: GenerateTextResult<TOOLS, RUNTIME_CONTEXT, OUTPUT>['output'];
734
784
  }) {
735
785
  this.steps = options.steps;
736
786
  this.usage = options.usage;
737
787
  this.responseMessages = options.responseMessages;
788
+ this.output = options.output;
738
789
  }
739
790
 
740
791
  get finalStep() {