@opencode-ai/ai 0.0.0-dev-18317 → 0.0.0-dev-18318

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.
@@ -495,14 +495,14 @@ export declare const Event: Schema.StructWithRest<Schema.Struct<{
495
495
  readonly item_id: Schema.optional<Schema.String>;
496
496
  readonly output_index: Schema.optional<Schema.Number>;
497
497
  readonly summary_index: Schema.optional<Schema.Number>;
498
- readonly item: Schema.optional<Schema.StructWithRest<Schema.Struct<{
498
+ readonly item: Schema.optional<Schema.NullOr<Schema.StructWithRest<Schema.Struct<{
499
499
  readonly type: Schema.String;
500
500
  readonly id: Schema.optional<Schema.String>;
501
501
  readonly call_id: Schema.optional<Schema.String>;
502
502
  readonly name: Schema.optional<Schema.String>;
503
503
  readonly arguments: Schema.optional<Schema.String>;
504
504
  readonly encrypted_content: Schema.optional<Schema.NullOr<Schema.String>>;
505
- }>, readonly [Schema.$Record<Schema.String, Schema.Unknown>]>>;
505
+ }>, readonly [Schema.$Record<Schema.String, Schema.Unknown>]>>>;
506
506
  readonly response: Schema.optional<Schema.StructWithRest<Schema.Struct<{
507
507
  readonly id: Schema.optional<Schema.String>;
508
508
  readonly service_tier: Schema.optional<Schema.NullOr<Schema.String>>;
@@ -1165,7 +1165,7 @@ export declare const protocol: Protocol<{
1165
1165
  readonly arguments?: string | undefined;
1166
1166
  readonly encrypted_content?: string | null | undefined;
1167
1167
  readonly call_id?: string | undefined;
1168
- } | undefined;
1168
+ } | null | undefined;
1169
1169
  readonly delta?: string | undefined;
1170
1170
  readonly response?: {
1171
1171
  readonly [x: string]: unknown;
@@ -242,7 +242,8 @@ export const Event = Schema.StructWithRest(Schema.Struct({
242
242
  item_id: Schema.optional(Schema.String),
243
243
  output_index: Schema.optional(Schema.Number),
244
244
  summary_index: Schema.optional(Schema.Number),
245
- item: Schema.optional(StreamItem),
245
+ // OutputItemAdded/Done permit a null item in the Open Responses OpenAPI schema.
246
+ item: optionalNull(StreamItem),
246
247
  response: Schema.optional(Schema.StructWithRest(Schema.Struct({
247
248
  id: Schema.optional(Schema.String),
248
249
  service_tier: optionalNull(Schema.String),
@@ -598,7 +599,7 @@ const mapFinishReason = (event, hasFunctionCall) => {
598
599
  export const providerMetadata = (state, metadata) => ({
599
600
  [state.providerMetadataKey]: metadata,
600
601
  });
601
- const isReasoningItem = (item) => item.type === "reasoning" && typeof item.id === "string" && item.id.length > 0;
602
+ const isReasoningItem = (item) => item.type === "reasoning" && typeof item.id === "string";
602
603
  const NO_EVENTS = [];
603
604
  // `response.completed` / `response.incomplete` are clean finishes that emit a
604
605
  // `finish` event; `response.failed` and `error` are hard failures. All four end
@@ -669,7 +670,7 @@ const reasoningMetadata = (state, item) => providerMetadata(state, { itemId: ite
669
670
  // best-effort, not guaranteed.
670
671
  const onOutputItemAdded = (state, event) => {
671
672
  const item = event.item;
672
- if (item?.type === "message" && item.id) {
673
+ if (item?.type === "message" && item.id !== undefined) {
673
674
  const phase = messagePhase(item.phase);
674
675
  return [
675
676
  {
@@ -701,7 +702,7 @@ const onOutputItemAdded = (state, event) => {
701
702
  if (item?.type !== "function_call" || !item.call_id)
702
703
  return [state, NO_EVENTS];
703
704
  const id = item.id ?? item.call_id;
704
- const metadata = item.id ? providerMetadata(state, { itemId: item.id }) : undefined;
705
+ const metadata = item.id !== undefined ? providerMetadata(state, { itemId: item.id }) : undefined;
705
706
  const events = [];
706
707
  const lifecycle = Lifecycle.stepStart(state.lifecycle, events);
707
708
  return [
@@ -719,7 +720,7 @@ const onOutputItemAdded = (state, event) => {
719
720
  ];
720
721
  };
721
722
  const onReasoningSummaryPartAdded = (state, event) => {
722
- if (!event.item_id || event.summary_index === undefined)
723
+ if (event.item_id === undefined || event.summary_index === undefined)
723
724
  return [state, NO_EVENTS];
724
725
  const item = state.reasoningItems[event.item_id];
725
726
  if (!item)
@@ -749,7 +750,7 @@ const onReasoningSummaryPartAdded = (state, event) => {
749
750
  ];
750
751
  };
751
752
  const onReasoningSummaryPartDone = (state, event) => {
752
- if (!event.item_id || event.summary_index === undefined)
753
+ if (event.item_id === undefined || event.summary_index === undefined)
753
754
  return [state, NO_EVENTS];
754
755
  const item = state.reasoningItems[event.item_id];
755
756
  if (!item)
@@ -772,7 +773,7 @@ const onReasoningSummaryPartDone = (state, event) => {
772
773
  ];
773
774
  };
774
775
  const onFunctionCallArgumentsDelta = Effect.fn("OpenResponses.onFunctionCallArgumentsDelta")(function* (state, event) {
775
- if (!event.item_id)
776
+ if (event.item_id === undefined)
776
777
  return [state, NO_EVENTS];
777
778
  const tool = state.tools[event.item_id];
778
779
  if (!tool)
@@ -800,7 +801,7 @@ const onOutputItemDone = Effect.fn("OpenResponses.onOutputItemDone")(function* (
800
801
  const item = event.item;
801
802
  if (!item)
802
803
  return [state, NO_EVENTS];
803
- if (item.type === "message" && item.id) {
804
+ if (item.type === "message" && item.id !== undefined) {
804
805
  const itemPhase = messagePhase(item.phase);
805
806
  const phase = itemPhase === undefined ? state.messagePhases[item.id] : itemPhase;
806
807
  const events = [];
@@ -826,7 +827,7 @@ const onOutputItemDone = Effect.fn("OpenResponses.onOutputItemDone")(function* (
826
827
  : ToolStream.start(state.tools, id, {
827
828
  id: item.call_id,
828
829
  name: item.name,
829
- providerMetadata: item.id ? providerMetadata(state, { itemId: item.id }) : undefined,
830
+ providerMetadata: item.id !== undefined ? providerMetadata(state, { itemId: item.id }) : undefined,
830
831
  });
831
832
  const result = item.arguments === undefined
832
833
  ? yield* ToolStream.finish(state.id, tools, id)
@@ -874,7 +875,7 @@ const onResponseFinish = Effect.fn("OpenResponses.onResponseFinish")(function* (
874
875
  const reconciled = event.type === "response.completed"
875
876
  ? yield* Effect.reduce(event.response?.output ?? [], () => [state, NO_EVENTS], ([current, events], item) => {
876
877
  const id = item.id ?? (item.type === "function_call" ? item.call_id : undefined);
877
- if (!id ||
878
+ if (id === undefined ||
878
879
  ((item.type !== "function_call" || !current.tools[id]) &&
879
880
  (item.type !== "reasoning" || !current.reasoningItems[id])))
880
881
  return Effect.succeed([current, events]);
@@ -945,11 +946,12 @@ export const providerFailure = (id, event, fallback) => {
945
946
  };
946
947
  const providerError = (state, event, fallback) => providerFailure(state.id, event, fallback);
947
948
  export const step = (state, input) => {
948
- const event = input.item_id && outputItemID(state, input) !== input.item_id
949
+ // The OpenAPI requires string IDs but imposes no minLength; empty is not missing.
950
+ const event = input.item_id !== undefined && outputItemID(state, input) !== input.item_id
949
951
  ? { ...input, item_id: outputItemID(state, input) }
950
952
  : input;
951
953
  if (event.type === "response.output_text.delta" || event.type === "response.output_text.done") {
952
- if (!event.item_id)
954
+ if (event.item_id === undefined)
953
955
  return ProviderShared.eventError(state.id, `${event.type} is missing item_id`);
954
956
  return Effect.succeed(event.type === "response.output_text.delta"
955
957
  ? onOutputTextDelta(state, event, event.item_id)
@@ -957,46 +959,46 @@ export const step = (state, input) => {
957
959
  }
958
960
  if (event.type === "response.refusal.delta" || event.type === "response.refusal.done") {
959
961
  const value = event.type === "response.refusal.delta" ? event.delta : event.refusal;
960
- if (!event.item_id || typeof value !== "string")
962
+ if (event.item_id === undefined || typeof value !== "string")
961
963
  return ProviderShared.eventError(state.id, `${event.type} is malformed`);
962
964
  return Effect.succeed(event.type === "response.refusal.delta"
963
965
  ? onOutputTextDelta(state, event, event.item_id)
964
966
  : onOutputTextDone(state, { ...event, text: value }, event.item_id));
965
967
  }
966
968
  if (event.type === "response.reasoning.delta" || event.type === "response.reasoning_summary_text.delta") {
967
- if (!event.item_id)
969
+ if (event.item_id === undefined)
968
970
  return ProviderShared.eventError(state.id, `${event.type} is missing item_id`);
969
971
  return Effect.succeed(onReasoningDelta(state, event, event.item_id));
970
972
  }
971
973
  if (event.type === "response.reasoning.done" ||
972
974
  event.type === "response.reasoning_summary_text.done" ||
973
975
  event.type === "response.reasoning_text.done") {
974
- if (!event.item_id)
976
+ if (event.item_id === undefined)
975
977
  return ProviderShared.eventError(state.id, `${event.type} is missing item_id`);
976
978
  return Effect.succeed(onReasoningDone(state, event, event.item_id));
977
979
  }
978
980
  if (event.type === "response.reasoning_summary_part.added")
979
- return event.item_id
981
+ return event.item_id !== undefined
980
982
  ? Effect.succeed(onReasoningSummaryPartAdded(state, event))
981
983
  : ProviderShared.eventError(state.id, `${event.type} is missing item_id`);
982
984
  if (event.type === "response.reasoning_summary_part.done")
983
- return event.item_id
985
+ return event.item_id !== undefined
984
986
  ? Effect.succeed(onReasoningSummaryPartDone(state, event))
985
987
  : ProviderShared.eventError(state.id, `${event.type} is missing item_id`);
986
988
  if (event.type === "response.output_item.added") {
987
- if (event.item?.type === "message" && !event.item.id)
989
+ if (event.item?.type === "message" && event.item.id === undefined)
988
990
  return ProviderShared.eventError(state.id, `${event.type} message is missing id`);
989
991
  const id = event.item?.id ?? (event.item?.type === "function_call" ? event.item.call_id : undefined);
990
- return Effect.succeed(onOutputItemAdded(event.output_index !== undefined && id
992
+ return Effect.succeed(onOutputItemAdded(event.output_index !== undefined && id !== undefined
991
993
  ? { ...state, outputItems: { ...state.outputItems, [event.output_index]: id } }
992
994
  : state, event));
993
995
  }
994
996
  if (event.type === "response.function_call_arguments.delta" || event.type === "response.function_call_arguments.done")
995
- return event.item_id
997
+ return event.item_id !== undefined
996
998
  ? onFunctionCallArgumentsDelta(state, event)
997
999
  : ProviderShared.eventError(state.id, `${event.type} is missing item_id`);
998
1000
  if (event.type === "response.output_item.done") {
999
- if (event.item?.type === "message" && !event.item.id)
1001
+ if (event.item?.type === "message" && event.item.id === undefined)
1000
1002
  return ProviderShared.eventError(state.id, `${event.type} message is missing id`);
1001
1003
  return onOutputItemDone(state, event);
1002
1004
  }
@@ -386,7 +386,7 @@ export declare const protocol: Protocol<{
386
386
  readonly arguments?: string | undefined;
387
387
  readonly encrypted_content?: string | null | undefined;
388
388
  readonly call_id?: string | undefined;
389
- } | undefined;
389
+ } | null | undefined;
390
390
  readonly delta?: string | undefined;
391
391
  readonly response?: {
392
392
  readonly [x: string]: unknown;
@@ -147,7 +147,7 @@ const HOSTED_TOOLS = {
147
147
  };
148
148
  const step = (state, event) => {
149
149
  if (event.type === "response.reasoning_text.delta")
150
- return event.item_id
150
+ return event.item_id !== undefined
151
151
  ? Effect.succeed(OpenResponses.onReasoningDelta(state, event, OpenResponses.outputItemID(state, event) ?? event.item_id))
152
152
  : ProviderShared.eventError(ADAPTER, `${event.type} is missing item_id`);
153
153
  if (event.type === "response.output_item.done" && event.item && ResponsesHostedTools.isItem(event.item, HOSTED_TOOLS))
@@ -187,7 +187,7 @@ export declare const protocol: Protocol<{
187
187
  readonly arguments?: string | undefined;
188
188
  readonly encrypted_content?: string | null | undefined;
189
189
  readonly call_id?: string | undefined;
190
- } | undefined;
190
+ } | null | undefined;
191
191
  readonly delta?: string | undefined;
192
192
  readonly response?: {
193
193
  readonly [x: string]: unknown;
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-18317",
3
+ "version": "0.0.0-dev-18318",
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-18317",
33
+ "@opencode-ai/http-recorder": "0.0.0-dev-18318",
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-18317",
42
+ "@opencode-ai/schema": "0.0.0-dev-18318",
43
43
  "aws4fetch": "1.0.20",
44
44
  "effect": "4.0.0-rc.111",
45
45
  "google-auth-library": "10.5.0"