@opencode/ai 2.0.14 → 2.0.16
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.
- package/README.md +399 -56
- package/dist/experimental/evaluation-client.d.ts +1 -1
- package/dist/experimental/evaluation-client.js +39 -3
- package/dist/experimental/evaluation.d.ts +4 -4
- package/dist/experimental/evaluation.js +2 -2
- package/dist/experimental/system-one.d.ts +3 -3
- package/dist/experimental/system-one.js +40 -51
- package/dist/generation.d.ts +83 -0
- package/dist/generation.js +113 -0
- package/dist/image-client.d.ts +16 -7
- package/dist/image-client.js +29 -13
- package/dist/image.d.ts +1410 -81
- package/dist/image.js +97 -67
- package/dist/index.d.ts +17 -2
- package/dist/index.js +12 -1
- package/dist/llm.d.ts +9 -1
- package/dist/media-model.d.ts +44 -0
- package/dist/media-model.js +49 -0
- package/dist/media.d.ts +213 -0
- package/dist/media.js +227 -0
- package/dist/promise.d.ts +974 -0
- package/dist/promise.js +81 -0
- package/dist/protocols/alibaba-chat.d.ts +12 -0
- package/dist/protocols/alibaba-responses.d.ts +2 -2
- package/dist/protocols/anthropic-messages.js +8 -19
- package/dist/protocols/assemblyai-transcription.d.ts +40 -0
- package/dist/protocols/assemblyai-transcription.js +138 -0
- package/dist/protocols/bedrock-converse.d.ts +4 -4
- package/dist/protocols/bedrock-converse.js +6 -17
- package/dist/protocols/bfl-images.d.ts +32 -0
- package/dist/protocols/bfl-images.js +153 -0
- package/dist/protocols/cartesia-speech.d.ts +127 -0
- package/dist/protocols/cartesia-speech.js +126 -0
- package/dist/protocols/deepgram-speech.d.ts +119 -0
- package/dist/protocols/deepgram-speech.js +92 -0
- package/dist/protocols/deepgram-transcription.d.ts +25 -0
- package/dist/protocols/deepgram-transcription.js +129 -0
- package/dist/protocols/elevenlabs-speech.d.ts +122 -0
- package/dist/protocols/elevenlabs-speech.js +115 -0
- package/dist/protocols/fal-images.d.ts +24 -0
- package/dist/protocols/fal-images.js +114 -0
- package/dist/protocols/fal-video.d.ts +29 -0
- package/dist/protocols/fal-video.js +88 -0
- package/dist/protocols/gemini.d.ts +30 -9
- package/dist/protocols/gemini.js +45 -35
- package/dist/protocols/google-images.d.ts +9 -21
- package/dist/protocols/google-images.js +158 -133
- package/dist/protocols/google-speech.d.ts +130 -0
- package/dist/protocols/google-speech.js +84 -0
- package/dist/protocols/google-transcription.d.ts +173 -0
- package/dist/protocols/google-transcription.js +138 -0
- package/dist/protocols/google-video.d.ts +26 -0
- package/dist/protocols/google-video.js +158 -0
- package/dist/protocols/meta-images.d.ts +7 -12
- package/dist/protocols/meta-images.js +85 -66
- package/dist/protocols/meta-responses.d.ts +4 -4
- package/dist/protocols/meta-responses.js +1 -1
- package/dist/protocols/mistral-chat.js +7 -6
- package/dist/protocols/open-responses.d.ts +17 -9
- package/dist/protocols/open-responses.js +24 -14
- package/dist/protocols/openai-chat.d.ts +118 -1
- package/dist/protocols/openai-chat.js +125 -44
- package/dist/protocols/openai-compatible-chat.d.ts +12 -0
- package/dist/protocols/openai-compatible-responses.d.ts +2 -2
- package/dist/protocols/openai-images.d.ts +128 -18
- package/dist/protocols/openai-images.js +177 -154
- package/dist/protocols/openai-responses.d.ts +15 -15
- package/dist/protocols/openai-responses.js +5 -6
- package/dist/protocols/openai-speech.d.ts +116 -0
- package/dist/protocols/openai-speech.js +98 -0
- package/dist/protocols/openai-transcription.d.ts +207 -0
- package/dist/protocols/openai-transcription.js +190 -0
- package/dist/protocols/replicate-images.d.ts +28 -0
- package/dist/protocols/replicate-images.js +133 -0
- package/dist/protocols/runway-video.d.ts +38 -0
- package/dist/protocols/runway-video.js +146 -0
- package/dist/protocols/shared.d.ts +27 -17
- package/dist/protocols/shared.js +52 -35
- package/dist/protocols/stability-images.d.ts +38 -0
- package/dist/protocols/stability-images.js +148 -0
- package/dist/protocols/utils/bedrock-media.d.ts +2 -3
- package/dist/protocols/utils/bedrock-media.js +4 -4
- package/dist/protocols/utils/fal-queue.d.ts +28 -0
- package/dist/protocols/utils/fal-queue.js +69 -0
- package/dist/protocols/utils/gemini-generate-content.d.ts +65 -0
- package/dist/protocols/utils/gemini-generate-content.js +65 -0
- package/dist/protocols/utils/gemini-json-schema.d.ts +3 -0
- package/dist/protocols/utils/gemini-json-schema.js +76 -0
- package/dist/protocols/utils/media-input.d.ts +18 -0
- package/dist/protocols/utils/media-input.js +35 -0
- package/dist/protocols/utils/responses-compaction.js +6 -5
- package/dist/protocols/utils/speech-stream.d.ts +49 -0
- package/dist/protocols/utils/speech-stream.js +67 -0
- package/dist/protocols/utils/tool-schema.d.ts +2 -2
- package/dist/protocols/utils/tool-schema.js +40 -17
- package/dist/protocols/utils/tool-stream.d.ts +27 -3
- package/dist/protocols/xai-images.d.ts +9 -15
- package/dist/protocols/xai-images.js +75 -84
- package/dist/protocols/xai-responses.d.ts +2 -2
- package/dist/protocols/xai-video.d.ts +34 -0
- package/dist/protocols/xai-video.js +147 -0
- package/dist/protocols/zai-chat.d.ts +13 -1
- package/dist/protocols/zai-images.d.ts +9 -13
- package/dist/protocols/zai-images.js +59 -57
- package/dist/provider-error.js +3 -0
- package/dist/providers/alibaba.d.ts +14 -2
- package/dist/providers/amazon-bedrock-mantle.d.ts +14 -2
- package/dist/providers/amazon-bedrock.d.ts +2 -2
- package/dist/providers/assemblyai.d.ts +25 -0
- package/dist/providers/assemblyai.js +29 -0
- package/dist/providers/azure.d.ts +18 -6
- package/dist/providers/baseten.d.ts +24 -0
- package/dist/providers/black-forest-labs.d.ts +25 -0
- package/dist/providers/black-forest-labs.js +28 -0
- package/dist/providers/cartesia.d.ts +24 -0
- package/dist/providers/cartesia.js +22 -0
- package/dist/providers/cerebras.d.ts +24 -0
- package/dist/providers/cerebras.js +6 -1
- package/dist/providers/cloudflare-ai-gateway.d.ts +30 -6
- package/dist/providers/cloudflare-workers-ai.d.ts +24 -0
- package/dist/providers/deepgram.d.ts +29 -0
- package/dist/providers/deepgram.js +31 -0
- package/dist/providers/deepinfra.d.ts +24 -0
- package/dist/providers/deepinfra.js +6 -1
- package/dist/providers/deepseek.d.ts +24 -0
- package/dist/providers/elevenlabs.d.ts +24 -0
- package/dist/providers/elevenlabs.js +28 -0
- package/dist/providers/fal.d.ts +29 -0
- package/dist/providers/fal.js +33 -0
- package/dist/providers/fireworks.d.ts +24 -0
- package/dist/providers/google-vertex-chat.d.ts +12 -0
- package/dist/providers/google-vertex-responses.d.ts +2 -2
- package/dist/providers/google-vertex.d.ts +10 -3
- package/dist/providers/google.d.ts +25 -3
- package/dist/providers/google.js +11 -2
- package/dist/providers/groq.d.ts +24 -0
- package/dist/providers/index.d.ts +10 -0
- package/dist/providers/index.js +10 -0
- package/dist/providers/meta.d.ts +14 -2
- package/dist/providers/minimax.d.ts +14 -2
- package/dist/providers/moonshot.d.ts +14 -2
- package/dist/providers/moonshot.js +3 -3
- package/dist/providers/openai-compatible-responses.d.ts +2 -2
- package/dist/providers/openai-compatible.d.ts +12 -0
- package/dist/providers/openai.d.ts +25 -3
- package/dist/providers/openai.js +10 -1
- package/dist/providers/openrouter.d.ts +67 -0
- package/dist/providers/openrouter.js +13 -1
- package/dist/providers/replicate.d.ts +25 -0
- package/dist/providers/replicate.js +22 -0
- package/dist/providers/runway.d.ts +24 -0
- package/dist/providers/runway.js +22 -0
- package/dist/providers/stability.d.ts +28 -0
- package/dist/providers/stability.js +23 -0
- package/dist/providers/togetherai.d.ts +24 -0
- package/dist/providers/vercel-ai-gateway.d.ts +41 -0
- package/dist/providers/vercel-ai-gateway.js +85 -0
- package/dist/providers/xai.d.ts +17 -0
- package/dist/providers/xai.js +5 -2
- package/dist/providers/zai-coding-plan.d.ts +15 -3
- package/dist/providers/zai.d.ts +13 -1
- package/dist/route/auth.d.ts +4 -1
- package/dist/route/auth.js +6 -0
- package/dist/route/client.d.ts +9 -1
- package/dist/route/endpoint.d.ts +10 -10
- package/dist/route/executor-service.d.ts +12 -0
- package/dist/route/executor-service.js +3 -0
- package/dist/route/executor.d.ts +4 -9
- package/dist/route/executor.js +3 -3
- package/dist/route/framing.d.ts +5 -1
- package/dist/route/framing.js +9 -0
- package/dist/route/index.d.ts +2 -0
- package/dist/route/index.js +2 -0
- package/dist/route/media-protocol.d.ts +158 -0
- package/dist/route/media-protocol.js +96 -0
- package/dist/route/media.d.ts +97 -0
- package/dist/route/media.js +236 -0
- package/dist/schema/errors.d.ts +13 -3
- package/dist/schema/errors.js +7 -0
- package/dist/schema/events.d.ts +557 -40
- package/dist/schema/events.js +35 -2
- package/dist/schema/messages.d.ts +95 -8
- package/dist/schema/messages.js +8 -6
- package/dist/schema/options.d.ts +6 -3
- package/dist/schema/options.js +6 -2
- package/dist/speech-client.d.ts +21 -0
- package/dist/speech-client.js +25 -0
- package/dist/speech.d.ts +1150 -0
- package/dist/speech.js +119 -0
- package/dist/testing.d.ts +72 -8
- package/dist/transcription-client.d.ts +28 -0
- package/dist/transcription-client.js +44 -0
- package/dist/transcription.d.ts +1504 -0
- package/dist/transcription.js +133 -0
- package/dist/utils/bytes.d.ts +1 -0
- package/dist/utils/bytes.js +10 -0
- package/dist/utils/media-type.d.ts +7 -0
- package/dist/utils/media-type.js +70 -0
- package/dist/utils/sanitize.js +3 -1
- package/dist/video-client.d.ts +28 -0
- package/dist/video-client.js +40 -0
- package/dist/video.d.ts +1359 -0
- package/dist/video.js +119 -0
- package/package.json +7 -3
- package/dist/protocols/utils/gemini-tool-schema.d.ts +0 -2
- package/dist/protocols/utils/gemini-tool-schema.js +0 -103
- package/dist/protocols/utils/image-input.d.ts +0 -21
- package/dist/protocols/utils/image-input.js +0 -20
|
@@ -33,6 +33,12 @@ declare const GeminiBody: Schema.Struct<{
|
|
|
33
33
|
readonly mimeType: Schema.String;
|
|
34
34
|
readonly data: Schema.String;
|
|
35
35
|
}>;
|
|
36
|
+
readonly thoughtSignature: Schema.optional<Schema.NullOr<Schema.String>>;
|
|
37
|
+
}>, Schema.Struct<{
|
|
38
|
+
readonly fileData: Schema.Struct<{
|
|
39
|
+
readonly mimeType: Schema.String;
|
|
40
|
+
readonly fileUri: Schema.String;
|
|
41
|
+
}>;
|
|
36
42
|
}>, Schema.Struct<{
|
|
37
43
|
readonly functionCall: Schema.Struct<{
|
|
38
44
|
readonly id: Schema.optional<Schema.NullOr<Schema.String>>;
|
|
@@ -50,6 +56,7 @@ declare const GeminiBody: Schema.Struct<{
|
|
|
50
56
|
readonly mimeType: Schema.String;
|
|
51
57
|
readonly data: Schema.String;
|
|
52
58
|
}>;
|
|
59
|
+
readonly thoughtSignature: Schema.optional<Schema.NullOr<Schema.String>>;
|
|
53
60
|
}>>>;
|
|
54
61
|
}>;
|
|
55
62
|
}>]>>>>;
|
|
@@ -69,7 +76,7 @@ declare const GeminiBody: Schema.Struct<{
|
|
|
69
76
|
readonly functionDeclarations: Schema.$Array<Schema.Struct<{
|
|
70
77
|
readonly name: Schema.String;
|
|
71
78
|
readonly description: Schema.String;
|
|
72
|
-
readonly
|
|
79
|
+
readonly parametersJsonSchema: Schema.$Record<Schema.String, Schema.Unknown>;
|
|
73
80
|
}>>;
|
|
74
81
|
}>>>;
|
|
75
82
|
toolConfig: Schema.optional<Schema.Struct<{
|
|
@@ -106,10 +113,16 @@ export declare const protocol: Protocol<{
|
|
|
106
113
|
readonly mimeType: string;
|
|
107
114
|
readonly data: string;
|
|
108
115
|
};
|
|
116
|
+
readonly thoughtSignature?: string | null | undefined;
|
|
109
117
|
} | {
|
|
110
118
|
readonly text: string;
|
|
111
119
|
readonly thought?: boolean | null | undefined;
|
|
112
120
|
readonly thoughtSignature?: string | null | undefined;
|
|
121
|
+
} | {
|
|
122
|
+
readonly fileData: {
|
|
123
|
+
readonly mimeType: string;
|
|
124
|
+
readonly fileUri: string;
|
|
125
|
+
};
|
|
113
126
|
} | {
|
|
114
127
|
readonly functionCall: {
|
|
115
128
|
readonly name: string;
|
|
@@ -127,6 +140,7 @@ export declare const protocol: Protocol<{
|
|
|
127
140
|
readonly mimeType: string;
|
|
128
141
|
readonly data: string;
|
|
129
142
|
};
|
|
143
|
+
readonly thoughtSignature?: string | null | undefined;
|
|
130
144
|
}[] | undefined;
|
|
131
145
|
};
|
|
132
146
|
})[] | null | undefined;
|
|
@@ -134,11 +148,11 @@ export declare const protocol: Protocol<{
|
|
|
134
148
|
}[];
|
|
135
149
|
readonly tools?: readonly {
|
|
136
150
|
readonly functionDeclarations: readonly {
|
|
137
|
-
readonly description: string;
|
|
138
151
|
readonly name: string;
|
|
139
|
-
readonly
|
|
152
|
+
readonly description: string;
|
|
153
|
+
readonly parametersJsonSchema: {
|
|
140
154
|
readonly [x: string]: unknown;
|
|
141
|
-
}
|
|
155
|
+
};
|
|
142
156
|
}[];
|
|
143
157
|
}[] | undefined;
|
|
144
158
|
readonly serviceTier?: string | undefined;
|
|
@@ -192,11 +206,11 @@ export declare const protocol: Protocol<{
|
|
|
192
206
|
readonly safetyRatings?: unknown;
|
|
193
207
|
} | null | undefined;
|
|
194
208
|
readonly usageMetadata?: {
|
|
195
|
-
readonly cachedContentTokenCount?: number | null | undefined;
|
|
196
|
-
readonly thoughtsTokenCount?: number | null | undefined;
|
|
197
209
|
readonly promptTokenCount?: number | null | undefined;
|
|
198
210
|
readonly candidatesTokenCount?: number | null | undefined;
|
|
199
211
|
readonly totalTokenCount?: number | null | undefined;
|
|
212
|
+
readonly cachedContentTokenCount?: number | null | undefined;
|
|
213
|
+
readonly thoughtsTokenCount?: number | null | undefined;
|
|
200
214
|
} | null | undefined;
|
|
201
215
|
}, {
|
|
202
216
|
route: string;
|
|
@@ -213,10 +227,16 @@ export declare const route: Route<{
|
|
|
213
227
|
readonly mimeType: string;
|
|
214
228
|
readonly data: string;
|
|
215
229
|
};
|
|
230
|
+
readonly thoughtSignature?: string | null | undefined;
|
|
216
231
|
} | {
|
|
217
232
|
readonly text: string;
|
|
218
233
|
readonly thought?: boolean | null | undefined;
|
|
219
234
|
readonly thoughtSignature?: string | null | undefined;
|
|
235
|
+
} | {
|
|
236
|
+
readonly fileData: {
|
|
237
|
+
readonly mimeType: string;
|
|
238
|
+
readonly fileUri: string;
|
|
239
|
+
};
|
|
220
240
|
} | {
|
|
221
241
|
readonly functionCall: {
|
|
222
242
|
readonly name: string;
|
|
@@ -234,6 +254,7 @@ export declare const route: Route<{
|
|
|
234
254
|
readonly mimeType: string;
|
|
235
255
|
readonly data: string;
|
|
236
256
|
};
|
|
257
|
+
readonly thoughtSignature?: string | null | undefined;
|
|
237
258
|
}[] | undefined;
|
|
238
259
|
};
|
|
239
260
|
})[] | null | undefined;
|
|
@@ -241,11 +262,11 @@ export declare const route: Route<{
|
|
|
241
262
|
}[];
|
|
242
263
|
readonly tools?: readonly {
|
|
243
264
|
readonly functionDeclarations: readonly {
|
|
244
|
-
readonly description: string;
|
|
245
265
|
readonly name: string;
|
|
246
|
-
readonly
|
|
266
|
+
readonly description: string;
|
|
267
|
+
readonly parametersJsonSchema: {
|
|
247
268
|
readonly [x: string]: unknown;
|
|
248
|
-
}
|
|
269
|
+
};
|
|
249
270
|
}[];
|
|
250
271
|
}[] | undefined;
|
|
251
272
|
readonly serviceTier?: string | undefined;
|
package/dist/protocols/gemini.js
CHANGED
|
@@ -7,8 +7,9 @@ import { Framing } from "../route/framing.js";
|
|
|
7
7
|
import { Protocol } from "../route/protocol.js";
|
|
8
8
|
import { AIError, LLMEvent, Usage, } from "../schema/index.js";
|
|
9
9
|
import { classifyProviderFailure } from "../provider-error.js";
|
|
10
|
+
import { Media } from "../media.js";
|
|
10
11
|
import { JsonObject, knownString, lenient, optionalArray, optionalNull, ProviderShared } from "./shared.js";
|
|
11
|
-
import {
|
|
12
|
+
import { GeminiGenerateContent } from "./utils/gemini-generate-content.js";
|
|
12
13
|
import { Lifecycle } from "./utils/lifecycle.js";
|
|
13
14
|
import { ToolSchemaProjection } from "./utils/tool-schema.js";
|
|
14
15
|
const ADAPTER = "gemini";
|
|
@@ -54,6 +55,14 @@ const GeminiInlineDataPart = Schema.Struct({
|
|
|
54
55
|
mimeType: Schema.String,
|
|
55
56
|
data: Schema.String,
|
|
56
57
|
}),
|
|
58
|
+
thoughtSignature: optionalNull(Schema.String),
|
|
59
|
+
});
|
|
60
|
+
/** Gemini Files API reference; the only remote input Gemini accepts. */
|
|
61
|
+
const GeminiFileDataPart = Schema.Struct({
|
|
62
|
+
fileData: Schema.Struct({
|
|
63
|
+
mimeType: Schema.String,
|
|
64
|
+
fileUri: Schema.String,
|
|
65
|
+
}),
|
|
57
66
|
});
|
|
58
67
|
const GeminiFunctionCallPart = Schema.Struct({
|
|
59
68
|
functionCall: Schema.Struct({
|
|
@@ -74,6 +83,7 @@ const GeminiFunctionResponsePart = Schema.Struct({
|
|
|
74
83
|
const GeminiContentPart = Schema.Union([
|
|
75
84
|
GeminiTextPart,
|
|
76
85
|
GeminiInlineDataPart,
|
|
86
|
+
GeminiFileDataPart,
|
|
77
87
|
GeminiFunctionCallPart,
|
|
78
88
|
GeminiFunctionResponsePart,
|
|
79
89
|
]);
|
|
@@ -92,7 +102,7 @@ const GeminiSystemInstruction = Schema.Struct({
|
|
|
92
102
|
const GeminiFunctionDeclaration = Schema.Struct({
|
|
93
103
|
name: Schema.String,
|
|
94
104
|
description: Schema.String,
|
|
95
|
-
|
|
105
|
+
parametersJsonSchema: JsonObject,
|
|
96
106
|
});
|
|
97
107
|
const GeminiTool = Schema.Struct({
|
|
98
108
|
functionDeclarations: Schema.Array(GeminiFunctionDeclaration),
|
|
@@ -176,34 +186,14 @@ const GeminiEvent = Schema.Struct({
|
|
|
176
186
|
usageMetadata: optionalNull(GeminiUsage),
|
|
177
187
|
});
|
|
178
188
|
// =============================================================================
|
|
179
|
-
// Tool Schema Conversion
|
|
180
|
-
// =============================================================================
|
|
181
|
-
// Tool-schema conversion has two distinct concerns:
|
|
182
|
-
//
|
|
183
|
-
// 1. Sanitize — fix common authoring mistakes Gemini rejects: integer/number
|
|
184
|
-
// enums (must be strings), `required` entries that don't match a property,
|
|
185
|
-
// untyped arrays (`items` must be present), and `properties`/`required`
|
|
186
|
-
// keys on non-object scalars. Mirrors OpenCode's historical Gemini rules.
|
|
187
|
-
//
|
|
188
|
-
// 2. Project — lossy mapping from JSON Schema to Gemini's schema dialect:
|
|
189
|
-
// drop empty root parameter schemas while preserving nested empty objects,
|
|
190
|
-
// expand type arrays into `anyOf`, derive `nullable: true` from null members,
|
|
191
|
-
// coerce `const` to `[const]` enum, recurse properties/items, and propagate
|
|
192
|
-
// only an allowlisted set of keys (description, required, format, type,
|
|
193
|
-
// nullable, enum, properties, items, allOf, anyOf, oneOf, minLength).
|
|
194
|
-
// Anything outside the allowlist (e.g. `additionalProperties`, `$ref`) is
|
|
195
|
-
// silently dropped.
|
|
196
|
-
//
|
|
197
|
-
// Sanitize runs first, then project. The implementation lives in
|
|
198
|
-
// `utils/gemini-tool-schema` so this protocol keeps the same shape as the other
|
|
199
|
-
// provider protocols.
|
|
200
|
-
// =============================================================================
|
|
201
189
|
// Request Lowering
|
|
202
190
|
// =============================================================================
|
|
203
|
-
|
|
191
|
+
// Tool schemas go in `parametersJsonSchema`, which accepts standard JSON Schema. Gemini's schema
|
|
192
|
+
// rules are this API's default, including for tuned endpoints whose IDs do not name Gemini.
|
|
193
|
+
const lowerTool = (tool, model) => ({
|
|
204
194
|
name: tool.name,
|
|
205
195
|
description: tool.description,
|
|
206
|
-
|
|
196
|
+
parametersJsonSchema: ToolSchemaProjection.modelCompatibility(tool.inputSchema, model, "gemini"),
|
|
207
197
|
});
|
|
208
198
|
const lowerToolConfig = (toolChoice) => ProviderShared.matchToolChoice("Gemini", toolChoice, {
|
|
209
199
|
auto: () => ({ functionCallingConfig: { mode: "AUTO" } }),
|
|
@@ -211,11 +201,10 @@ const lowerToolConfig = (toolChoice) => ProviderShared.matchToolChoice("Gemini",
|
|
|
211
201
|
required: () => ({ functionCallingConfig: { mode: "ANY" } }),
|
|
212
202
|
tool: (name) => ({ functionCallingConfig: { mode: "ANY", allowedFunctionNames: [name] } }),
|
|
213
203
|
});
|
|
214
|
-
const
|
|
204
|
+
const lowerContentPart = Effect.fn("Gemini.lowerContentPart")(function* (part) {
|
|
215
205
|
if (part.type === "text")
|
|
216
206
|
return { text: part.text };
|
|
217
|
-
|
|
218
|
-
return { inlineData: { mimeType: media.mime, data: media.base64 } };
|
|
207
|
+
return yield* GeminiGenerateContent.mediaPart("Gemini", part.media);
|
|
219
208
|
});
|
|
220
209
|
const providerMetadata = (key, metadata) => ({ [key]: metadata });
|
|
221
210
|
const thoughtSignature = (metadata, key) => {
|
|
@@ -259,7 +248,7 @@ const lowerMessages = Effect.fn("Gemini.lowerMessages")(function* (request) {
|
|
|
259
248
|
for (const part of message.content) {
|
|
260
249
|
if (!ProviderShared.supportsContent(part, ["text", "media"]))
|
|
261
250
|
return yield* ProviderShared.unsupportedContent("Gemini", "user", ["text", "media"]);
|
|
262
|
-
parts.push(yield*
|
|
251
|
+
parts.push(yield* lowerContentPart(part));
|
|
263
252
|
}
|
|
264
253
|
contents.push({ role: "user", parts });
|
|
265
254
|
continue;
|
|
@@ -269,12 +258,23 @@ const lowerMessages = Effect.fn("Gemini.lowerMessages")(function* (request) {
|
|
|
269
258
|
// Parallel Gemini 3 calls may carry one signature on the first call; unsigned sibling calls are valid.
|
|
270
259
|
let hasSignedToolCall = false;
|
|
271
260
|
for (const part of message.content) {
|
|
272
|
-
if (!ProviderShared.supportsContent(part, ["text", "reasoning", "tool-call"]))
|
|
273
|
-
return yield* ProviderShared.unsupportedContent("Gemini", "assistant", [
|
|
261
|
+
if (!ProviderShared.supportsContent(part, ["text", "reasoning", "tool-call", "media"]))
|
|
262
|
+
return yield* ProviderShared.unsupportedContent("Gemini", "assistant", [
|
|
263
|
+
"text",
|
|
264
|
+
"reasoning",
|
|
265
|
+
"tool-call",
|
|
266
|
+
"media",
|
|
267
|
+
]);
|
|
274
268
|
if (part.type === "text") {
|
|
275
269
|
parts.push({ text: part.text, thoughtSignature: thoughtSignature(part.providerMetadata, metadataKey) });
|
|
276
270
|
continue;
|
|
277
271
|
}
|
|
272
|
+
// Generated images replay as model-role inline data so multi-turn image editing keeps the prior output.
|
|
273
|
+
if (part.type === "media") {
|
|
274
|
+
const lowered = yield* lowerContentPart(part);
|
|
275
|
+
parts.push({ ...lowered, thoughtSignature: thoughtSignature(part.providerMetadata, metadataKey) });
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
278
278
|
if (part.type === "reasoning") {
|
|
279
279
|
parts.push({
|
|
280
280
|
text: part.text,
|
|
@@ -324,7 +324,7 @@ const lowerMessages = Effect.fn("Gemini.lowerMessages")(function* (request) {
|
|
|
324
324
|
for (const item of content) {
|
|
325
325
|
if (item.type === "text")
|
|
326
326
|
continue;
|
|
327
|
-
const value = ProviderShared.
|
|
327
|
+
const value = yield* ProviderShared.requireInlineMedia("Gemini", ProviderShared.toolFileMedia(item).media);
|
|
328
328
|
media.push({ inlineData: { mimeType: value.mime, data: value.base64 } });
|
|
329
329
|
}
|
|
330
330
|
if (legacyToolMedia && media.length > 0)
|
|
@@ -357,7 +357,6 @@ const fromRequest = Effect.fn("Gemini.fromRequest")(function* (request) {
|
|
|
357
357
|
const hasTools = flattened.tools.length > 0;
|
|
358
358
|
const generation = request.generation;
|
|
359
359
|
const options = yield* decodeOptions(request.providerOptions ?? {});
|
|
360
|
-
const toolSchemaCompatibility = request.model.compatibility?.toolSchema;
|
|
361
360
|
const generationConfig = {
|
|
362
361
|
maxOutputTokens: generation?.maxTokens,
|
|
363
362
|
temperature: generation?.temperature,
|
|
@@ -380,7 +379,7 @@ const fromRequest = Effect.fn("Gemini.fromRequest")(function* (request) {
|
|
|
380
379
|
tools: hasTools
|
|
381
380
|
? [
|
|
382
381
|
{
|
|
383
|
-
functionDeclarations: flattened.tools.map((tool) => lowerTool(tool,
|
|
382
|
+
functionDeclarations: flattened.tools.map((tool) => lowerTool(tool, request.model)),
|
|
384
383
|
},
|
|
385
384
|
]
|
|
386
385
|
: undefined,
|
|
@@ -539,6 +538,17 @@ const step = (state, event) => {
|
|
|
539
538
|
reasoningSignature = signature;
|
|
540
539
|
else if (signature !== undefined && "text" in part)
|
|
541
540
|
textSignature = signature;
|
|
541
|
+
// Image-capable Gemini models return generated images as inline data parts; surface them as first-class output.
|
|
542
|
+
if ("inlineData" in part) {
|
|
543
|
+
lifecycle = Lifecycle.stepStart(lifecycle, events);
|
|
544
|
+
events.push(LLMEvent.media({
|
|
545
|
+
media: Media.base64(part.inlineData.data, part.inlineData.mimeType),
|
|
546
|
+
providerMetadata: signature
|
|
547
|
+
? providerMetadata(state.providerMetadataKey, { thoughtSignature: signature })
|
|
548
|
+
: undefined,
|
|
549
|
+
}));
|
|
550
|
+
continue;
|
|
551
|
+
}
|
|
542
552
|
if ("text" in part && part.text.length > 0) {
|
|
543
553
|
if (part.thought) {
|
|
544
554
|
if (textId !== undefined) {
|
|
@@ -1,30 +1,18 @@
|
|
|
1
|
-
import { ImageModel } from "../image.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { ImageModel, ImageResponse, type ImageRequestFor } from "../image.js";
|
|
2
|
+
import { MediaProtocol } from "../route/media-protocol.js";
|
|
3
|
+
import { MediaRoute } from "../route/media.js";
|
|
4
4
|
export declare const DEFAULT_BASE_URL = "https://generativelanguage.googleapis.com/v1beta";
|
|
5
5
|
export type GoogleImageString<Known extends string> = Known | (string & {});
|
|
6
|
+
/** Provider-native options. Common fields (`aspectRatio`, `seed`, `images`) live on the request. */
|
|
6
7
|
export type GoogleImageOptions = {
|
|
7
|
-
readonly aspectRatio?: GoogleImageString<"1:1" | "2:3" | "3:2" | "3:4" | "4:3" | "4:5" | "5:4" | "9:16" | "16:9" | "21:9">;
|
|
8
8
|
readonly imageSize?: GoogleImageString<"1K" | "2K" | "4K">;
|
|
9
|
-
readonly seed?: number;
|
|
10
9
|
readonly thinkingLevel?: GoogleImageString<"MINIMAL" | "LOW" | "MEDIUM" | "HIGH">;
|
|
11
10
|
readonly includeThoughts?: boolean;
|
|
12
11
|
} & Record<string, unknown>;
|
|
13
|
-
export type
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
readonly parts: ReadonlyArray<Record<string, unknown>>;
|
|
17
|
-
}>;
|
|
18
|
-
readonly generationConfig: Record<string, unknown>;
|
|
19
|
-
};
|
|
20
|
-
export interface ModelInput {
|
|
21
|
-
readonly id: string;
|
|
22
|
-
readonly auth: AuthDefinition;
|
|
23
|
-
readonly baseURL?: string;
|
|
24
|
-
readonly headers?: Record<string, string>;
|
|
25
|
-
readonly http?: HttpOptions;
|
|
26
|
-
}
|
|
27
|
-
export declare const model: (input: ModelInput) => ImageModel<GoogleImageOptions>;
|
|
12
|
+
export type Request = ImageRequestFor<GoogleImageOptions>;
|
|
13
|
+
export declare const protocol: MediaProtocol.Inline<Request, ImageResponse>;
|
|
14
|
+
export declare const model: (input: MediaRoute.ModelInput) => ImageModel<GoogleImageOptions>;
|
|
28
15
|
export declare const GoogleImages: {
|
|
29
|
-
readonly
|
|
16
|
+
readonly protocol: MediaProtocol.Inline<Request, ImageResponse>;
|
|
17
|
+
readonly model: (input: MediaRoute.ModelInput) => ImageModel<GoogleImageOptions>;
|
|
30
18
|
};
|