@opencode-ai/ai 0.0.0-dev-18235 → 0.0.0-dev-18237

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.
@@ -612,9 +612,13 @@ const endsInServerToolUse = (message) => {
612
612
  const last = message.content.at(-1);
613
613
  return message.role === "assistant" && last?.type === "tool-call" && last.providerExecuted === true;
614
614
  };
615
- const canUseNativeSystemUpdate = (messages, index) => {
616
- const previous = messages[index - 1];
617
- const next = messages[index + 1];
615
+ const canUseNativeSystemUpdate = (request, index) => {
616
+ const previous = request.messages[index - 1];
617
+ const next = request.messages[index + 1];
618
+ // Vertex currently rejects/404s for a system message after local tool results,
619
+ // so fold it into the user tool-result turn across continuations and history.
620
+ if (request.model.route.id === "google-vertex-messages" && previous?.role === "tool")
621
+ return false;
618
622
  return (previous !== undefined &&
619
623
  previous.role !== "system" &&
620
624
  (previous.role === "user" || previous.role === "tool" || endsInServerToolUse(previous)) &&
@@ -650,7 +654,7 @@ const lowerMessages = Effect.fn("AnthropicMessages.lowerMessages")(function* (re
650
654
  if (message.role === "system") {
651
655
  if (splitsLocalToolResults(request.messages, index))
652
656
  return yield* invalid("Anthropic Messages system updates cannot split a local tool call from its tool result");
653
- if (supportsNativeSystemUpdates(request) && canUseNativeSystemUpdate(request.messages, index)) {
657
+ if (supportsNativeSystemUpdates(request) && canUseNativeSystemUpdate(request, index)) {
654
658
  messages.push(yield* lowerNativeSystemUpdate(message, breakpoints));
655
659
  continue;
656
660
  }
@@ -703,26 +703,24 @@ const onOutputItemAdded = (state, event) => {
703
703
  events,
704
704
  ];
705
705
  }
706
- if (item?.type !== "function_call" || !item.id)
706
+ if (item?.type !== "function_call" || !item.call_id)
707
707
  return [state, NO_EVENTS];
708
- const metadata = providerMetadata(state, { itemId: item.id });
708
+ const id = item.id ?? item.call_id;
709
+ const metadata = item.id ? providerMetadata(state, { itemId: item.id }) : undefined;
709
710
  const events = [];
710
711
  const lifecycle = Lifecycle.stepStart(state.lifecycle, events);
711
712
  return [
712
713
  {
713
714
  ...state,
714
715
  lifecycle,
715
- tools: ToolStream.start(state.tools, item.id, {
716
- id: item.call_id ?? item.id,
716
+ tools: ToolStream.start(state.tools, id, {
717
+ id: item.call_id,
717
718
  name: item.name ?? "",
718
719
  input: item.arguments ?? "",
719
720
  providerMetadata: metadata,
720
721
  }),
721
722
  },
722
- [
723
- ...events,
724
- LLMEvent.toolInputStart({ id: item.call_id ?? item.id, name: item.name ?? "", providerMetadata: metadata }),
725
- ],
723
+ [...events, LLMEvent.toolInputStart({ id: item.call_id, name: item.name ?? "", providerMetadata: metadata })],
726
724
  ];
727
725
  };
728
726
  const onReasoningSummaryPartAdded = (state, event) => {
@@ -825,18 +823,19 @@ const onOutputItemDone = Effect.fn("OpenResponses.onOutputItemDone")(function* (
825
823
  ];
826
824
  }
827
825
  if (item.type === "function_call") {
828
- if (!item.id || !item.call_id || !item.name)
826
+ if (!item.call_id || !item.name)
829
827
  return [state, NO_EVENTS];
830
- const tools = state.tools[item.id]
828
+ const id = item.id ?? item.call_id;
829
+ const tools = state.tools[id]
831
830
  ? state.tools
832
- : ToolStream.start(state.tools, item.id, {
831
+ : ToolStream.start(state.tools, id, {
833
832
  id: item.call_id,
834
833
  name: item.name,
835
- providerMetadata: providerMetadata(state, { itemId: item.id }),
834
+ providerMetadata: item.id ? providerMetadata(state, { itemId: item.id }) : undefined,
836
835
  });
837
836
  const result = item.arguments === undefined
838
- ? yield* ToolStream.finish(state.id, tools, item.id)
839
- : yield* ToolStream.finishWithInput(state.id, tools, item.id, item.arguments);
837
+ ? yield* ToolStream.finish(state.id, tools, id)
838
+ : yield* ToolStream.finishWithInput(state.id, tools, id, item.arguments);
840
839
  const events = [];
841
840
  const resultEvents = result.events ?? [];
842
841
  const lifecycle = resultEvents.length ? Lifecycle.stepStart(state.lifecycle, events) : state.lifecycle;
@@ -879,9 +878,10 @@ const onOutputItemDone = Effect.fn("OpenResponses.onOutputItemDone")(function* (
879
878
  const onResponseFinish = Effect.fn("OpenResponses.onResponseFinish")(function* (state, event) {
880
879
  const reconciled = event.type === "response.completed"
881
880
  ? yield* Effect.reduce(event.response?.output ?? [], () => [state, NO_EVENTS], ([current, events], item) => {
882
- if (!item.id ||
883
- ((item.type !== "function_call" || !current.tools[item.id]) &&
884
- (item.type !== "reasoning" || !current.reasoningItems[item.id])))
881
+ const id = item.id ?? (item.type === "function_call" ? item.call_id : undefined);
882
+ if (!id ||
883
+ ((item.type !== "function_call" || !current.tools[id]) &&
884
+ (item.type !== "reasoning" || !current.reasoningItems[id])))
885
885
  return Effect.succeed([current, events]);
886
886
  return onOutputItemDone(current, { type: "response.output_item.done", item }).pipe(Effect.map(([next, emitted]) => [next, [...events, ...emitted]]));
887
887
  })
@@ -991,8 +991,9 @@ export const step = (state, input) => {
991
991
  if (event.type === "response.output_item.added") {
992
992
  if (event.item?.type === "message" && !event.item.id)
993
993
  return ProviderShared.eventError(state.id, `${event.type} message is missing id`);
994
- return Effect.succeed(onOutputItemAdded(event.output_index !== undefined && event.item?.id
995
- ? { ...state, outputItems: { ...state.outputItems, [event.output_index]: event.item.id } }
994
+ const id = event.item?.id ?? (event.item?.type === "function_call" ? event.item.call_id : undefined);
995
+ return Effect.succeed(onOutputItemAdded(event.output_index !== undefined && id
996
+ ? { ...state, outputItems: { ...state.outputItems, [event.output_index]: id } }
996
997
  : state, event));
997
998
  }
998
999
  if (event.type === "response.function_call_arguments.delta" || event.type === "response.function_call_arguments.done")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
- "version": "0.0.0-dev-18235",
3
+ "version": "0.0.0-dev-18237",
4
4
  "name": "@opencode-ai/ai",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -30,7 +30,7 @@
30
30
  "devDependencies": {
31
31
  "@clack/prompts": "1.0.0-alpha.1",
32
32
  "@effect/platform-node": "4.0.0-rc.111",
33
- "@opencode-ai/http-recorder": "0.0.0-dev-18235",
33
+ "@opencode-ai/http-recorder": "0.0.0-dev-18237",
34
34
  "@tsconfig/bun": "1.0.9",
35
35
  "@types/bun": "1.3.13",
36
36
  "@typescript/native-preview": "7.0.0-dev.20251207.1",
@@ -39,7 +39,7 @@
39
39
  "dependencies": {
40
40
  "@smithy/eventstream-codec": "4.2.14",
41
41
  "@smithy/util-utf8": "4.2.2",
42
- "@opencode-ai/schema": "0.0.0-dev-18235",
42
+ "@opencode-ai/schema": "0.0.0-dev-18237",
43
43
  "aws4fetch": "1.0.20",
44
44
  "effect": "4.0.0-rc.111",
45
45
  "google-auth-library": "10.5.0"