@opencode-ai/ai 0.0.0-next-16175 → 0.0.0-next-16179

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.
@@ -431,6 +431,7 @@ export declare const protocol: Protocol<{
431
431
  } | undefined;
432
432
  }, {
433
433
  tools: Partial<Record<number, ToolStream.PendingTool>>;
434
+ reasoningSignatures: {};
434
435
  lifecycle: Lifecycle.State;
435
436
  }>;
436
437
  export declare const route: Route<{
@@ -632,6 +632,9 @@ const onContentBlockStart = (state, event) => {
632
632
  tools: ToolStream.start(state.tools, event.index, {
633
633
  id: block.id ?? String(event.index),
634
634
  name: block.name ?? "",
635
+ input: block.input !== undefined && (!ProviderShared.isRecord(block.input) || Object.keys(block.input).length > 0)
636
+ ? ProviderShared.encodeJson(block.input)
637
+ : undefined,
635
638
  providerExecuted: block.type === "server_tool_use",
636
639
  }),
637
640
  },
@@ -645,19 +648,29 @@ const onContentBlockStart = (state, event) => {
645
648
  ],
646
649
  ];
647
650
  }
648
- if (block.type === "text" && block.text) {
651
+ if (block.type === "text" && block.text !== undefined) {
649
652
  const events = [];
653
+ const id = `text-${event.index ?? 0}`;
654
+ const lifecycle = Lifecycle.textStart(state.lifecycle, events, id);
650
655
  return [
651
- { ...state, lifecycle: Lifecycle.textDelta(state.lifecycle, events, `text-${event.index ?? 0}`, block.text) },
656
+ { ...state, lifecycle: block.text ? Lifecycle.textDelta(lifecycle, events, id, block.text) : lifecycle },
652
657
  events,
653
658
  ];
654
659
  }
655
- if (block.type === "thinking" && block.thinking) {
660
+ if (block.type === "thinking" && block.thinking !== undefined) {
656
661
  const events = [];
662
+ const id = `reasoning-${event.index ?? 0}`;
663
+ const providerMetadata = block.signature === undefined ? undefined : anthropicMetadata({ signature: block.signature });
664
+ const lifecycle = Lifecycle.reasoningStart(state.lifecycle, events, id, providerMetadata);
657
665
  return [
658
666
  {
659
667
  ...state,
660
- lifecycle: Lifecycle.reasoningDelta(state.lifecycle, events, `reasoning-${event.index ?? 0}`, block.thinking),
668
+ lifecycle: block.thinking
669
+ ? Lifecycle.reasoningDelta(lifecycle, events, id, block.thinking, providerMetadata)
670
+ : lifecycle,
671
+ reasoningSignatures: event.index === undefined || block.signature === undefined
672
+ ? state.reasoningSignatures
673
+ : { ...state.reasoningSignatures, [event.index]: block.signature },
661
674
  },
662
675
  events,
663
676
  ];
@@ -665,7 +678,7 @@ const onContentBlockStart = (state, event) => {
665
678
  // Redacted thinking surfaces as an empty reasoning part carrying the opaque
666
679
  // payload as `redactedData` metadata (same model as Vercel's
667
680
  // @ai-sdk/anthropic). The existing content_block_stop closes the part.
668
- if (block.type === "redacted_thinking" && block.data) {
681
+ if (block.type === "redacted_thinking" && block.data !== undefined) {
669
682
  const events = [];
670
683
  return [
671
684
  {
@@ -701,13 +714,13 @@ const onContentBlockDelta = Effect.fn("AnthropicMessages.onContentBlockDelta")(f
701
714
  ];
702
715
  }
703
716
  if (delta?.type === "signature_delta" && delta.signature) {
704
- const events = [];
717
+ const index = event.index ?? 0;
705
718
  return [
706
719
  {
707
720
  ...state,
708
- lifecycle: Lifecycle.reasoningEnd(state.lifecycle, events, `reasoning-${event.index ?? 0}`, anthropicMetadata({ signature: delta.signature })),
721
+ reasoningSignatures: { ...state.reasoningSignatures, [index]: delta.signature },
709
722
  },
710
- events,
723
+ NO_EVENTS,
711
724
  ];
712
725
  }
713
726
  if (delta?.type === "input_json_delta" && event.index !== undefined) {
@@ -729,26 +742,45 @@ const onContentBlockStop = Effect.fn("AnthropicMessages.onContentBlockStop")(fun
729
742
  const result = yield* ToolStream.finish(ADAPTER, state.tools, event.index);
730
743
  const events = [];
731
744
  const resultEvents = result.events ?? [];
745
+ const signature = state.reasoningSignatures[event.index];
732
746
  const lifecycle = resultEvents.length
733
747
  ? Lifecycle.stepStart(state.lifecycle, events)
734
- : Lifecycle.reasoningEnd(Lifecycle.textEnd(state.lifecycle, events, `text-${event.index}`), events, `reasoning-${event.index}`);
748
+ : Lifecycle.reasoningEnd(Lifecycle.textEnd(state.lifecycle, events, `text-${event.index}`), events, `reasoning-${event.index}`, signature === undefined ? undefined : anthropicMetadata({ signature }));
735
749
  events.push(...resultEvents);
736
- return [{ ...state, lifecycle, tools: result.tools }, events];
750
+ const reasoningSignatures = { ...state.reasoningSignatures };
751
+ delete reasoningSignatures[event.index];
752
+ return [{ ...state, lifecycle, tools: result.tools, reasoningSignatures }, events];
737
753
  });
738
754
  const onMessageDelta = (state, event) => {
739
755
  const usage = mergeUsage(state.usage, mapUsage(event.usage));
756
+ return [
757
+ {
758
+ ...state,
759
+ usage,
760
+ pendingFinish: {
761
+ reason: {
762
+ normalized: mapFinishReason(event.delta?.stop_reason),
763
+ raw: event.delta?.stop_reason ?? undefined,
764
+ },
765
+ providerMetadata: event.delta?.stop_sequence === null || event.delta?.stop_sequence === undefined
766
+ ? undefined
767
+ : anthropicMetadata({ stopSequence: event.delta.stop_sequence }),
768
+ },
769
+ },
770
+ NO_EVENTS,
771
+ ];
772
+ };
773
+ const onMessageStop = (state) => {
740
774
  const events = [];
741
775
  const lifecycle = Lifecycle.finish(state.lifecycle, events, {
742
- reason: {
743
- normalized: mapFinishReason(event.delta?.stop_reason),
744
- raw: event.delta?.stop_reason ?? undefined,
776
+ reason: state.pendingFinish?.reason ?? {
777
+ normalized: "unknown",
778
+ raw: undefined,
745
779
  },
746
- usage,
747
- providerMetadata: event.delta?.stop_sequence
748
- ? anthropicMetadata({ stopSequence: event.delta.stop_sequence })
749
- : undefined,
780
+ usage: state.usage,
781
+ providerMetadata: state.pendingFinish?.providerMetadata,
750
782
  });
751
- return [{ ...state, lifecycle, usage }, events];
783
+ return [{ ...state, lifecycle }, events];
752
784
  };
753
785
  // Prefix `error.type` so overloads, rate limits, and quota errors are visible
754
786
  // even when the provider message is generic or empty.
@@ -775,6 +807,8 @@ const step = (state, event) => {
775
807
  return onContentBlockStop(state, event);
776
808
  if (event.type === "message_delta")
777
809
  return Effect.succeed(onMessageDelta(state, event));
810
+ if (event.type === "message_stop")
811
+ return Effect.succeed(onMessageStop(state));
778
812
  if (event.type === "error")
779
813
  return onError(event);
780
814
  return Effect.succeed([state, NO_EVENTS]);
@@ -795,7 +829,11 @@ export const protocol = Protocol.make({
795
829
  },
796
830
  stream: {
797
831
  event: Protocol.jsonEvent(AnthropicEvent),
798
- initial: () => ({ tools: ToolStream.empty(), lifecycle: Lifecycle.initial() }),
832
+ initial: () => ({
833
+ tools: ToolStream.empty(),
834
+ reasoningSignatures: {},
835
+ lifecycle: Lifecycle.initial(),
836
+ }),
799
837
  step,
800
838
  },
801
839
  });
@@ -6,6 +6,7 @@ export interface State {
6
6
  }
7
7
  export declare const initial: () => State;
8
8
  export declare const stepStart: (state: State, events: LLMEvent[]) => State;
9
+ export declare const textStart: (state: State, events: LLMEvent[], id: string, providerMetadata?: ProviderMetadata) => State;
9
10
  export declare const textDelta: (state: State, events: LLMEvent[], id: string, text: string) => State;
10
11
  export declare const reasoningStart: (state: State, events: LLMEvent[], id: string, providerMetadata?: ProviderMetadata) => State;
11
12
  export declare const reasoningDelta: (state: State, events: LLMEvent[], id: string, text: string, providerMetadata?: ProviderMetadata) => State;
@@ -6,15 +6,18 @@ export const stepStart = (state, events) => {
6
6
  events.push(LLMEvent.stepStart({ index: 0 }));
7
7
  return { ...state, stepStarted: true };
8
8
  };
9
- export const textDelta = (state, events, id, text) => {
9
+ export const textStart = (state, events, id, providerMetadata) => {
10
+ if (state.text.has(id))
11
+ return state;
10
12
  const stepped = stepStart(state, events);
11
- if (stepped.text.has(id)) {
12
- events.push(LLMEvent.textDelta({ id, text }));
13
- return stepped;
14
- }
15
- events.push(LLMEvent.textStart({ id }), LLMEvent.textDelta({ id, text }));
13
+ events.push(LLMEvent.textStart({ id, providerMetadata }));
16
14
  return { ...stepped, text: new Set([...stepped.text, id]) };
17
15
  };
16
+ export const textDelta = (state, events, id, text) => {
17
+ const started = textStart(state, events, id);
18
+ events.push(LLMEvent.textDelta({ id, text }));
19
+ return started;
20
+ };
18
21
  export const reasoningStart = (state, events, id, providerMetadata) => {
19
22
  if (state.reasoning.has(id))
20
23
  return state;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
- "version": "0.0.0-next-16175",
3
+ "version": "0.0.0-next-16179",
4
4
  "name": "@opencode-ai/ai",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -26,7 +26,7 @@
26
26
  "devDependencies": {
27
27
  "@clack/prompts": "1.0.0-alpha.1",
28
28
  "@effect/platform-node": "4.0.0-beta.98",
29
- "@opencode-ai/http-recorder": "0.0.0-next-16175",
29
+ "@opencode-ai/http-recorder": "0.0.0-next-16179",
30
30
  "@tsconfig/bun": "1.0.9",
31
31
  "@types/bun": "1.3.13",
32
32
  "@typescript/native-preview": "7.0.0-dev.20251207.1",
@@ -35,7 +35,7 @@
35
35
  "dependencies": {
36
36
  "@smithy/eventstream-codec": "4.2.14",
37
37
  "@smithy/util-utf8": "4.2.2",
38
- "@opencode-ai/schema": "0.0.0-next-16175",
38
+ "@opencode-ai/schema": "0.0.0-next-16179",
39
39
  "aws4fetch": "1.0.20",
40
40
  "effect": "4.0.0-beta.98",
41
41
  "google-auth-library": "10.5.0"