@opencode-ai/ai 0.0.0-dev-18126 → 0.0.0-dev-18131

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.
@@ -177,35 +177,7 @@ export declare const protocol: Protocol<{
177
177
  }, string, {
178
178
  readonly candidates?: readonly {
179
179
  readonly content?: {
180
- readonly parts?: readonly ({
181
- readonly inlineData: {
182
- readonly mimeType: string;
183
- readonly data: string;
184
- };
185
- } | {
186
- readonly text: string;
187
- readonly thought?: boolean | null | undefined;
188
- readonly thoughtSignature?: string | null | undefined;
189
- } | {
190
- readonly functionCall: {
191
- readonly name: string;
192
- readonly id?: string | null | undefined;
193
- readonly args?: unknown;
194
- };
195
- readonly thoughtSignature?: string | null | undefined;
196
- } | {
197
- readonly functionResponse: {
198
- readonly name: string;
199
- readonly response: unknown;
200
- readonly id?: string | undefined;
201
- readonly parts?: readonly {
202
- readonly inlineData: {
203
- readonly mimeType: string;
204
- readonly data: string;
205
- };
206
- }[] | undefined;
207
- };
208
- })[] | null | undefined;
180
+ readonly parts?: readonly unknown[] | null | undefined;
209
181
  readonly role?: "model" | "user" | null | undefined;
210
182
  } | null | undefined;
211
183
  readonly finishReason?: string | null | undefined;
@@ -224,6 +196,7 @@ export declare const protocol: Protocol<{
224
196
  readonly totalTokenCount?: number | null | undefined;
225
197
  } | null | undefined;
226
198
  }, {
199
+ route: string;
227
200
  hasToolCalls: boolean;
228
201
  lifecycle: Lifecycle.State;
229
202
  }>;
@@ -1,4 +1,4 @@
1
- import { Effect, Schema } from "effect";
1
+ import { Effect, Option, Schema } from "effect";
2
2
  import { Tool } from "@opencode-ai/schema/tool";
3
3
  import { Route } from "../route/client.js";
4
4
  import { Auth } from "../route/auth.js";
@@ -76,10 +76,15 @@ const GeminiContentPart = Schema.Union([
76
76
  GeminiFunctionCallPart,
77
77
  GeminiFunctionResponsePart,
78
78
  ]);
79
+ const decodeGeminiContentPart = Schema.decodeUnknownOption(GeminiContentPart);
79
80
  const GeminiContent = Schema.Struct({
80
81
  role: optionalNull(Schema.Literals(["user", "model"])),
81
82
  parts: optionalNull(Schema.Array(GeminiContentPart)),
82
83
  });
84
+ const GeminiResponseContent = Schema.Struct({
85
+ role: optionalNull(Schema.Literals(["user", "model"])),
86
+ parts: optionalNull(Schema.Array(Schema.Unknown)),
87
+ });
83
88
  const GeminiSystemInstruction = Schema.Struct({
84
89
  parts: Schema.Array(Schema.Struct({ text: Schema.String })),
85
90
  });
@@ -137,7 +142,7 @@ const GeminiUsage = Schema.Struct({
137
142
  totalTokenCount: optionalNull(Schema.Number),
138
143
  });
139
144
  const GeminiCandidate = Schema.Struct({
140
- content: optionalNull(GeminiContent),
145
+ content: optionalNull(GeminiResponseContent),
141
146
  finishReason: optionalNull(Schema.String),
142
147
  });
143
148
  const GeminiPromptFeedback = Schema.StructWithRest(Schema.Struct({
@@ -485,7 +490,17 @@ const step = (state, event) => {
485
490
  let textSignature = nextState.textSignature;
486
491
  // Supplier ids must be tracked across chunks of the same response, not just within one event's parts.
487
492
  const seenCallIds = new Set(nextState.seenCallIds);
488
- for (const part of candidate.content.parts ?? []) {
493
+ for (const input of candidate.content.parts ?? []) {
494
+ if (ProviderShared.isRecord(input) &&
495
+ !("text" in input) &&
496
+ !("inlineData" in input) &&
497
+ !("functionCall" in input) &&
498
+ !("functionResponse" in input))
499
+ continue;
500
+ const decoded = decodeGeminiContentPart(input);
501
+ if (Option.isNone(decoded))
502
+ return Effect.fail(ProviderShared.eventError(ADAPTER, `Invalid ${state.route} stream event`, ProviderShared.encodeJson(event)));
503
+ const part = decoded.value;
489
504
  const signature = "thoughtSignature" in part && part.thoughtSignature ? part.thoughtSignature : undefined;
490
505
  // Gemini attaches replay signatures to thought parts, visible text, or function calls;
491
506
  // each block kind must retain the signature attached to its own parts.
@@ -553,7 +568,11 @@ export const protocol = Protocol.make({
553
568
  },
554
569
  stream: {
555
570
  event: Protocol.jsonEvent(GeminiEvent),
556
- initial: () => ({ hasToolCalls: false, lifecycle: Lifecycle.initial() }),
571
+ initial: (request) => ({
572
+ route: `${request.model.provider}/${request.model.route.id}`,
573
+ hasToolCalls: false,
574
+ lifecycle: Lifecycle.initial(),
575
+ }),
557
576
  step,
558
577
  onHalt: finish,
559
578
  },
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-18126",
3
+ "version": "0.0.0-dev-18131",
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-18126",
33
+ "@opencode-ai/http-recorder": "0.0.0-dev-18131",
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-18126",
42
+ "@opencode-ai/schema": "0.0.0-dev-18131",
43
43
  "aws4fetch": "1.0.20",
44
44
  "effect": "4.0.0-rc.111",
45
45
  "google-auth-library": "10.5.0"