@opencode-ai/ai 0.0.0-dev-17825 → 0.0.0-dev-17829

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.
@@ -26,6 +26,9 @@ const requiresThoughtSignatureFallback = (modelID) => {
26
26
  return false;
27
27
  return !/(^|\/)gemini-robotics-er-1\.5(?:[.-]|$)/i.test(modelID);
28
28
  };
29
+ // Gemini 3 accepts media nested inside function responses; matched Gemini 2.5 variants reject it,
30
+ // so their tool-result attachments lower as a separate user turn instead.
31
+ const routesLegacyToolMedia = (modelID) => /gemini-2[.-]5(?:[.-]|$)/i.test(modelID);
29
32
  // =============================================================================
30
33
  // Request Body Schema
31
34
  // =============================================================================
@@ -197,7 +200,17 @@ const lowerToolCall = (part) => ({
197
200
  });
198
201
  const lowerMessages = Effect.fn("Gemini.lowerMessages")(function* (request) {
199
202
  const contents = [];
203
+ const legacyToolMedia = routesLegacyToolMedia(request.model.id);
204
+ let pendingMedia;
205
+ const flushMedia = () => {
206
+ if (!pendingMedia)
207
+ return;
208
+ contents.push({ role: "user", parts: [{ text: "Attached media from tool result:" }, ...pendingMedia] });
209
+ pendingMedia = undefined;
210
+ };
200
211
  for (const message of request.messages) {
212
+ if (message.role !== "tool")
213
+ flushMedia();
201
214
  if (message.role === "system") {
202
215
  const part = yield* ProviderShared.wrappedSystemUpdate("Gemini", message);
203
216
  const previous = contents.at(-1);
@@ -278,6 +291,8 @@ const lowerMessages = Effect.fn("Gemini.lowerMessages")(function* (request) {
278
291
  const value = ProviderShared.normalizeToolFile(item);
279
292
  media.push({ inlineData: { mimeType: value.mime, data: value.base64 } });
280
293
  }
294
+ if (legacyToolMedia && media.length > 0)
295
+ (pendingMedia ??= []).push(...media);
281
296
  parts.push({
282
297
  functionResponse: {
283
298
  id: functionCallId(part.providerMetadata),
@@ -286,7 +301,7 @@ const lowerMessages = Effect.fn("Gemini.lowerMessages")(function* (request) {
286
301
  name: part.name,
287
302
  content: text.join("\n"),
288
303
  },
289
- parts: media.length > 0 ? media : undefined,
304
+ parts: legacyToolMedia || media.length === 0 ? undefined : media,
290
305
  },
291
306
  });
292
307
  }
@@ -298,6 +313,7 @@ const lowerMessages = Effect.fn("Gemini.lowerMessages")(function* (request) {
298
313
  else
299
314
  contents.push({ role: "user", parts });
300
315
  }
316
+ flushMedia();
301
317
  return contents;
302
318
  });
303
319
  const resolveOptions = (request) => {
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-17825",
3
+ "version": "0.0.0-dev-17829",
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.110",
33
- "@opencode-ai/http-recorder": "0.0.0-dev-17825",
33
+ "@opencode-ai/http-recorder": "0.0.0-dev-17829",
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-17825",
42
+ "@opencode-ai/schema": "0.0.0-dev-17829",
43
43
  "aws4fetch": "1.0.20",
44
44
  "effect": "4.0.0-rc.110",
45
45
  "google-auth-library": "10.5.0"