@ai-sdk/harness 1.0.149 → 1.0.150

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/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # @ai-sdk/harness
2
2
 
3
+ ## 1.0.150
4
+
5
+ ### Patch Changes
6
+
7
+ - 6617f11: fix(harness): preserve interleaved text and reasoning blocks by stream ID
8
+ - aae69cb: fix(harness): invoke UI stream step callbacks for HarnessAgent results
9
+ - a7a66f5: fix(harness): expose final-step reasoning through stream result accessors
10
+ - 52e3f53: fix(harness): preserve response message order across steps
11
+ - 6c0295c: fix(harness): preserve native tool result input and execution origin
12
+ - ai@7.0.139
13
+
3
14
  ## 1.0.149
4
15
 
5
16
  ### Patch Changes
@@ -251,6 +251,8 @@ var HarnessStreamTextResult = class {
251
251
  this._providerMetadata = new DelayedPromise();
252
252
  this.stepsBuffer = [];
253
253
  this.currentStepContent = [];
254
+ this.currentStepTextContent = /* @__PURE__ */ new Map();
255
+ this.currentStepReasoningContent = /* @__PURE__ */ new Map();
254
256
  this.currentStepWarnings = [];
255
257
  this.stepNumber = 0;
256
258
  this.stepStarted = false;
@@ -319,6 +321,8 @@ var HarnessStreamTextResult = class {
319
321
  */
320
322
  discardCurrentStepContent() {
321
323
  this.currentStepContent = [];
324
+ this.currentStepTextContent.clear();
325
+ this.currentStepReasoningContent.clear();
322
326
  this.currentStepWarnings = [];
323
327
  this.stepStarted = false;
324
328
  }
@@ -372,6 +376,8 @@ var HarnessStreamTextResult = class {
372
376
  if (this.currentStepWarnings.length > 0) this.aggregateWarnings.push(...this.currentStepWarnings);
373
377
  this.stepNumber += 1;
374
378
  this.currentStepContent = [];
379
+ this.currentStepTextContent.clear();
380
+ this.currentStepReasoningContent.clear();
375
381
  this.currentStepWarnings = [];
376
382
  this.stepStarted = false;
377
383
  return step;
@@ -426,8 +432,8 @@ var HarnessStreamTextResult = class {
426
432
  const aggregatedContent = this.stepsBuffer.flatMap((s) => s.content);
427
433
  this._content.resolve(aggregatedContent);
428
434
  this._text.resolve(finalStep.text);
429
- this._reasoning.resolve([]);
430
- this._reasoningText.resolve(void 0);
435
+ this._reasoning.resolve(finalStep.content.filter((part) => part.type === "reasoning" || part.type === "reasoning-file"));
436
+ this._reasoningText.resolve(finalStep.reasoningText);
431
437
  this._files.resolve(this.stepsBuffer.flatMap((s) => s.files));
432
438
  this._sources.resolve(this.stepsBuffer.flatMap((s) => s.sources));
433
439
  this._toolCalls.resolve(this.stepsBuffer.flatMap((s) => s.toolCalls));
@@ -445,10 +451,11 @@ var HarnessStreamTextResult = class {
445
451
  this._request.resolve(finalStep.request);
446
452
  this._response.resolve(finalStep.response);
447
453
  this._providerMetadata.resolve(this.finalProviderMetadata);
448
- const responseMessages = await toResponseMessages({
449
- content: aggregatedContent,
454
+ const responseMessages = [];
455
+ for (const step of this.stepsBuffer) responseMessages.push(...await toResponseMessages({
456
+ content: step.content,
450
457
  tools: this.tools
451
- });
458
+ }));
452
459
  this._responseMessages.resolve(responseMessages);
453
460
  this.fullStreamController.enqueue({
454
461
  type: "finish",
@@ -640,12 +647,14 @@ var HarnessStreamTextResult = class {
640
647
  reader.releaseLock();
641
648
  }
642
649
  }
643
- toUIMessageStream({ originalMessages, generateMessageId, onEnd, onFinish, messageMetadata, sendReasoning, sendSources, sendStart, sendFinish, onError } = {}) {
650
+ toUIMessageStream({ originalMessages, generateMessageId, onStepEnd, onStepFinish, onEnd, onFinish, messageMetadata, sendReasoning, sendSources, sendStart, sendFinish, onError } = {}) {
644
651
  return createAsyncIterableStream(toUIMessageStream({
645
652
  stream: this.stream,
646
653
  tools: this.tools,
647
654
  originalMessages,
648
655
  generateMessageId,
656
+ onStepEnd,
657
+ onStepFinish,
649
658
  onEnd,
650
659
  onFinish,
651
660
  messageMetadata,
@@ -662,11 +671,13 @@ var HarnessStreamTextResult = class {
662
671
  pipeTextStreamToResponse() {
663
672
  throw notSupportedYet("pipeTextStreamToResponse");
664
673
  }
665
- toUIMessageStreamResponse({ originalMessages, generateMessageId, onEnd, onFinish, messageMetadata, sendReasoning, sendSources, sendStart, sendFinish, onError, ...init } = {}) {
674
+ toUIMessageStreamResponse({ originalMessages, generateMessageId, onStepEnd, onStepFinish, onEnd, onFinish, messageMetadata, sendReasoning, sendSources, sendStart, sendFinish, onError, ...init } = {}) {
666
675
  return createUIMessageStreamResponse({
667
676
  stream: this.toUIMessageStream({
668
677
  originalMessages,
669
678
  generateMessageId,
679
+ onStepEnd,
680
+ onStepFinish,
670
681
  onEnd,
671
682
  onFinish,
672
683
  messageMetadata,
@@ -684,22 +695,71 @@ var HarnessStreamTextResult = class {
684
695
  }
685
696
  appendToCurrentStepContent(part) {
686
697
  switch (part.type) {
687
- case "text-delta": {
688
- const last = this.currentStepContent[this.currentStepContent.length - 1];
689
- if (last && last.type === "text") last.text += part.text;
690
- else this.currentStepContent.push({
698
+ case "text-start": {
699
+ const content = {
691
700
  type: "text",
692
- text: part.text
693
- });
701
+ text: "",
702
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
703
+ };
704
+ this.currentStepTextContent.set(part.id, content);
705
+ this.currentStepContent.push(content);
694
706
  return;
695
707
  }
696
- case "reasoning-delta": {
697
- const last = this.currentStepContent[this.currentStepContent.length - 1];
698
- if (last && last.type === "reasoning") last.text += part.text;
699
- else this.currentStepContent.push({
708
+ case "text-delta": {
709
+ let content = this.currentStepTextContent.get(part.id);
710
+ if (content == null) {
711
+ content = {
712
+ type: "text",
713
+ text: "",
714
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
715
+ };
716
+ this.currentStepTextContent.set(part.id, content);
717
+ this.currentStepContent.push(content);
718
+ }
719
+ content.text += part.text;
720
+ if (part.providerMetadata != null) content.providerMetadata = part.providerMetadata;
721
+ return;
722
+ }
723
+ case "text-end": {
724
+ const content = this.currentStepTextContent.get(part.id);
725
+ if (content != null) {
726
+ if (part.providerMetadata != null) content.providerMetadata = part.providerMetadata;
727
+ if (part.citations != null) content.citations = part.citations;
728
+ this.currentStepTextContent.delete(part.id);
729
+ }
730
+ return;
731
+ }
732
+ case "reasoning-start": {
733
+ const content = {
700
734
  type: "reasoning",
701
- text: part.text
702
- });
735
+ text: "",
736
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
737
+ };
738
+ this.currentStepReasoningContent.set(part.id, content);
739
+ this.currentStepContent.push(content);
740
+ return;
741
+ }
742
+ case "reasoning-delta": {
743
+ let content = this.currentStepReasoningContent.get(part.id);
744
+ if (content == null) {
745
+ content = {
746
+ type: "reasoning",
747
+ text: "",
748
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
749
+ };
750
+ this.currentStepReasoningContent.set(part.id, content);
751
+ this.currentStepContent.push(content);
752
+ }
753
+ content.text += part.text;
754
+ if (part.providerMetadata != null) content.providerMetadata = part.providerMetadata;
755
+ return;
756
+ }
757
+ case "reasoning-end": {
758
+ const content = this.currentStepReasoningContent.get(part.id);
759
+ if (content != null) {
760
+ if (part.providerMetadata != null) content.providerMetadata = part.providerMetadata;
761
+ this.currentStepReasoningContent.delete(part.id);
762
+ }
703
763
  return;
704
764
  }
705
765
  case "tool-call":
@@ -869,11 +929,12 @@ function translateStreamPart(event, options = {}) {
869
929
  case "tool-call": return [];
870
930
  case "tool-approval-request": return [];
871
931
  case "tool-result":
872
- if (event.isError === true && (options.isProviderExecuted?.(event.toolCallId) ?? true)) return [{
932
+ const toolCall = options.getToolCall?.(event.toolCallId);
933
+ if (event.isError === true && (toolCall?.providerExecuted ?? options.isProviderExecuted?.(event.toolCallId) ?? true)) return [{
873
934
  type: "tool-error",
874
935
  toolCallId: event.toolCallId,
875
936
  toolName: event.toolName,
876
- input: void 0,
937
+ input: toolCall?.input,
877
938
  error: event.result,
878
939
  providerExecuted: true,
879
940
  ...event.dynamic !== void 0 ? { dynamic: event.dynamic } : {},
@@ -883,8 +944,9 @@ function translateStreamPart(event, options = {}) {
883
944
  type: "tool-result",
884
945
  toolCallId: event.toolCallId,
885
946
  toolName: event.toolName,
886
- input: void 0,
947
+ input: toolCall?.input,
887
948
  output: event.result,
949
+ ...toolCall?.providerExecuted !== void 0 ? { providerExecuted: toolCall.providerExecuted } : {},
888
950
  ...event.preliminary !== void 0 ? { preliminary: event.preliminary } : {},
889
951
  ...event.dynamic !== void 0 ? { dynamic: event.dynamic } : {},
890
952
  ...event.providerMetadata !== void 0 ? { providerMetadata: event.providerMetadata } : {}
@@ -1565,10 +1627,13 @@ function runPrompt(input) {
1565
1627
  const stripToolInputWorkDir = createToolInputWorkDirStripper({ sessionWorkDir: input.sessionWorkDir });
1566
1628
  const toolCallsByToolCallId = /* @__PURE__ */ new Map();
1567
1629
  const rawToolCallsByToolCallId = /* @__PURE__ */ new Map();
1568
- const translateOptions = { isProviderExecuted: (toolCallId) => {
1569
- const rawToolCall = rawToolCallsByToolCallId.get(toolCallId);
1570
- return rawToolCall == null || rawToolCall.providerExecuted === true;
1571
- } };
1630
+ const translateOptions = {
1631
+ getToolCall: (toolCallId) => toolCallsByToolCallId.get(toolCallId),
1632
+ isProviderExecuted: (toolCallId) => {
1633
+ const rawToolCall = rawToolCallsByToolCallId.get(toolCallId);
1634
+ return rawToolCall == null || rawToolCall.providerExecuted === true;
1635
+ }
1636
+ };
1572
1637
  const pendingApprovalsByApprovalId = new Map(pendingToolApprovals.map((approval) => [approval.approvalId, approval]));
1573
1638
  const pendingApprovalsByToolCallId = new Map(pendingToolApprovals.map((approval) => [approval.toolCallId, approval]));
1574
1639
  const continuationsByApprovalId = new Map((input.toolApprovalContinuations ?? []).map((continuation) => [continuation.approvalId, continuation]));