@gullabs/google 0.2.0 → 0.4.0
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/LICENSE +1 -1
- package/README.md +30 -10
- package/dist/index.cjs +171 -209
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -23
- package/dist/index.d.ts +11 -23
- package/dist/index.js +171 -210
- package/dist/index.js.map +1 -1
- package/package.json +4 -6
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { ZodOptional, ZodNullable, ZodDefault, ZodObject, ZodString, ZodNumber, ZodBoolean, ZodArray, ZodEnum, ZodLiteral } from 'zod';
|
|
1
|
+
import { LlmError, EFFORT_BUDGET, assertNever, classifyError, redactSecrets } from '@gullabs/core';
|
|
3
2
|
|
|
4
3
|
// src/adapter.ts
|
|
5
4
|
|
|
6
5
|
// src/client.ts
|
|
7
6
|
var FLEX_DEFAULT_TIMEOUT_MS = 15e5;
|
|
7
|
+
var STANDARD_DEFAULT_TIMEOUT_MS = 3e5;
|
|
8
8
|
var TRANSPORT_TIMEOUT_BUFFER_MS = 5e3;
|
|
9
9
|
async function buildGoogleClient(auth) {
|
|
10
10
|
const { GoogleGenAI } = await import('@google/genai');
|
|
@@ -18,130 +18,37 @@ async function buildGoogleClient(auth) {
|
|
|
18
18
|
}
|
|
19
19
|
};
|
|
20
20
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
if (
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const shape = schema.shape;
|
|
48
|
-
const properties = {};
|
|
49
|
-
const required = [];
|
|
50
|
-
for (const [key, fieldType] of Object.entries(shape)) {
|
|
51
|
-
const fieldSchema = convertSchema(fieldType, false);
|
|
52
|
-
if (fieldSchema === void 0) return void 0;
|
|
53
|
-
properties[key] = fieldSchema;
|
|
54
|
-
if (!isOptionalField(fieldType)) {
|
|
55
|
-
required.push(key);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
const result = {
|
|
59
|
-
type: "object",
|
|
60
|
-
properties,
|
|
61
|
-
...required.length > 0 ? { required } : {},
|
|
62
|
-
...desc !== void 0 ? { description: desc } : {},
|
|
63
|
-
...nullable ? { nullable: true } : {}
|
|
64
|
-
};
|
|
65
|
-
return result;
|
|
66
|
-
}
|
|
67
|
-
if (schema instanceof ZodString) {
|
|
68
|
-
return {
|
|
69
|
-
type: "string",
|
|
70
|
-
...desc !== void 0 ? { description: desc } : {},
|
|
71
|
-
...nullable ? { nullable: true } : {}
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
if (schema instanceof ZodNumber) {
|
|
75
|
-
const checks = schema._def.checks ?? [];
|
|
76
|
-
const isInt = checks.some((c) => c.kind === "int");
|
|
77
|
-
return {
|
|
78
|
-
type: isInt ? "integer" : "number",
|
|
79
|
-
...desc !== void 0 ? { description: desc } : {},
|
|
80
|
-
...nullable ? { nullable: true } : {}
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
if (schema instanceof ZodBoolean) {
|
|
84
|
-
return {
|
|
85
|
-
type: "boolean",
|
|
86
|
-
...desc !== void 0 ? { description: desc } : {},
|
|
87
|
-
...nullable ? { nullable: true } : {}
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
if (schema instanceof ZodArray) {
|
|
91
|
-
const element = schema.element;
|
|
92
|
-
const items = convertSchema(element, false);
|
|
93
|
-
if (items === void 0) return void 0;
|
|
94
|
-
return {
|
|
95
|
-
type: "array",
|
|
96
|
-
items,
|
|
97
|
-
...desc !== void 0 ? { description: desc } : {},
|
|
98
|
-
...nullable ? { nullable: true } : {}
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
if (schema instanceof ZodEnum) {
|
|
102
|
-
return {
|
|
103
|
-
type: "string",
|
|
104
|
-
enum: schema.options,
|
|
105
|
-
...desc !== void 0 ? { description: desc } : {},
|
|
106
|
-
...nullable ? { nullable: true } : {}
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
if (schema instanceof ZodLiteral) {
|
|
110
|
-
const val = schema.value;
|
|
111
|
-
if (typeof val === "string") {
|
|
112
|
-
return {
|
|
113
|
-
type: "string",
|
|
114
|
-
enum: [val],
|
|
115
|
-
...desc !== void 0 ? { description: desc } : {},
|
|
116
|
-
...nullable ? { nullable: true } : {}
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
if (typeof val === "number") {
|
|
120
|
-
return {
|
|
121
|
-
type: "number",
|
|
122
|
-
...desc !== void 0 ? { description: desc } : {},
|
|
123
|
-
...nullable ? { nullable: true } : {}
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
if (typeof val === "boolean") {
|
|
127
|
-
return {
|
|
128
|
-
type: "boolean",
|
|
129
|
-
...desc !== void 0 ? { description: desc } : {},
|
|
130
|
-
...nullable ? { nullable: true } : {}
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
return void 0;
|
|
21
|
+
|
|
22
|
+
// src/flex-fallback.ts
|
|
23
|
+
var CAPACITY_PATTERNS = [
|
|
24
|
+
/capacity/i,
|
|
25
|
+
/overload/i,
|
|
26
|
+
/overloaded/i,
|
|
27
|
+
/unavailable/i,
|
|
28
|
+
/no\s+capacity/i,
|
|
29
|
+
/temporar(?:y|ily)/i,
|
|
30
|
+
/try\s+again/i
|
|
31
|
+
];
|
|
32
|
+
var QUOTA_PATTERNS = [
|
|
33
|
+
/quota/i,
|
|
34
|
+
/billing/i,
|
|
35
|
+
/billable/i,
|
|
36
|
+
/payment/i,
|
|
37
|
+
/rate\s+limit/i,
|
|
38
|
+
/exceeded/i,
|
|
39
|
+
/insufficient/i
|
|
40
|
+
];
|
|
41
|
+
function isGeminiCapacityError(err) {
|
|
42
|
+
if (err.kind === "server") return err.httpStatus === 503;
|
|
43
|
+
if (err.kind !== "rate_limited") return false;
|
|
44
|
+
const message = err.message;
|
|
45
|
+
if (QUOTA_PATTERNS.some((pattern) => pattern.test(message))) {
|
|
46
|
+
return false;
|
|
134
47
|
}
|
|
135
|
-
return
|
|
48
|
+
return CAPACITY_PATTERNS.some((pattern) => pattern.test(message));
|
|
136
49
|
}
|
|
137
50
|
|
|
138
51
|
// src/adapter.ts
|
|
139
|
-
var EFFORT_BUDGET = {
|
|
140
|
-
none: 0,
|
|
141
|
-
low: 1024,
|
|
142
|
-
medium: 8192,
|
|
143
|
-
high: 24576
|
|
144
|
-
};
|
|
145
52
|
function mapFinishReason(raw) {
|
|
146
53
|
if (raw === void 0) return void 0;
|
|
147
54
|
switch (raw) {
|
|
@@ -253,24 +160,45 @@ function geminiAdapter(opts) {
|
|
|
253
160
|
if (genConfig.stopSequences !== void 0) {
|
|
254
161
|
config.stopSequences = genConfig.stopSequences;
|
|
255
162
|
}
|
|
256
|
-
|
|
163
|
+
const explicit = genConfig.serviceTier;
|
|
164
|
+
const supported = req.modelDescriptor?.capabilities?.serviceTiers;
|
|
165
|
+
if (explicit !== void 0) {
|
|
166
|
+
if (req.modelDescriptor !== void 0 && (supported === void 0 || !supported.includes(explicit))) {
|
|
167
|
+
throw new LlmError(
|
|
168
|
+
`serviceTier "${explicit}" is not supported for model "${model}".`,
|
|
169
|
+
{ kind: "bad_request", retryable: false }
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
config.serviceTier = explicit;
|
|
173
|
+
} else {
|
|
174
|
+
if (req.modelDescriptor === void 0) {
|
|
175
|
+
config.serviceTier = "flex";
|
|
176
|
+
} else if (supported?.includes("flex") === true) {
|
|
177
|
+
config.serviceTier = "flex";
|
|
178
|
+
}
|
|
179
|
+
}
|
|
257
180
|
const reasoning = genConfig.reasoning;
|
|
258
181
|
if (reasoning !== void 0) {
|
|
259
182
|
const reasoningApi = req.modelDescriptor?.capabilities?.reasoningApi;
|
|
183
|
+
if (reasoning.effort !== void 0 && reasoning.budgetTokens !== void 0) {
|
|
184
|
+
throw new LlmError(
|
|
185
|
+
`Provide either reasoning.effort or reasoning.budgetTokens, not both, for model "${model}".`,
|
|
186
|
+
{ kind: "bad_request", retryable: false }
|
|
187
|
+
);
|
|
188
|
+
}
|
|
260
189
|
if (reasoningApi === "budget") {
|
|
261
|
-
const budget = reasoning.budgetTokens !== void 0 ? reasoning.budgetTokens : reasoning.effort !== void 0 ? EFFORT_BUDGET[reasoning.effort]
|
|
190
|
+
const budget = reasoning.budgetTokens !== void 0 ? reasoning.budgetTokens : reasoning.effort !== void 0 ? EFFORT_BUDGET[reasoning.effort] : void 0;
|
|
262
191
|
config.thinkingConfig = {
|
|
263
192
|
...budget !== void 0 ? { thinkingBudget: budget } : {},
|
|
264
193
|
...reasoning.includeThoughts === true ? { includeThoughts: true } : {}
|
|
265
194
|
};
|
|
266
|
-
if (reasoning.effort !== void 0 && reasoning.budgetTokens !== void 0) {
|
|
267
|
-
warnings.push({
|
|
268
|
-
type: "reasoning-mapping",
|
|
269
|
-
quality: "approximate",
|
|
270
|
-
details: "budgetTokens takes precedence over effort for thinkingBudget"
|
|
271
|
-
});
|
|
272
|
-
}
|
|
273
195
|
} else if (reasoningApi === "level") {
|
|
196
|
+
if (reasoning.budgetTokens !== void 0) {
|
|
197
|
+
throw new LlmError(
|
|
198
|
+
`reasoning.budgetTokens is not supported for model "${model}" (it uses thinkingLevel, not thinkingBudget); use reasoning.effort instead.`,
|
|
199
|
+
{ kind: "bad_request", retryable: false }
|
|
200
|
+
);
|
|
201
|
+
}
|
|
274
202
|
let thinkingLevel;
|
|
275
203
|
if (reasoning.effort !== void 0) {
|
|
276
204
|
switch (reasoning.effort) {
|
|
@@ -290,73 +218,57 @@ function geminiAdapter(opts) {
|
|
|
290
218
|
assertNever(reasoning.effort);
|
|
291
219
|
}
|
|
292
220
|
}
|
|
293
|
-
if (reasoning.budgetTokens !== void 0) {
|
|
294
|
-
warnings.push({
|
|
295
|
-
type: "reasoning-mapping",
|
|
296
|
-
quality: "approximate",
|
|
297
|
-
details: "budgetTokens is not supported for gemini-3.x models; mapping effort to thinkingLevel instead"
|
|
298
|
-
});
|
|
299
|
-
}
|
|
300
221
|
config.thinkingConfig = {
|
|
301
222
|
...thinkingLevel !== void 0 ? { thinkingLevel } : {},
|
|
302
223
|
...reasoning.includeThoughts === true ? { includeThoughts: true } : {}
|
|
303
224
|
};
|
|
304
225
|
} else {
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
});
|
|
226
|
+
throw new LlmError(
|
|
227
|
+
`Model "${model}" does not support reasoning/thinkingConfig.`,
|
|
228
|
+
{ kind: "bad_request", retryable: false }
|
|
229
|
+
);
|
|
310
230
|
}
|
|
311
231
|
}
|
|
312
|
-
|
|
313
|
-
if (
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
if (geminiSchema !== void 0) {
|
|
319
|
-
config.responseSchema = geminiSchema;
|
|
320
|
-
} else {
|
|
321
|
-
warnings.push({
|
|
322
|
-
type: "unsupported-setting",
|
|
323
|
-
setting: "output.schema",
|
|
324
|
-
details: "Could not convert Zod schema to Gemini responseSchema; proceeding with responseMimeType only. Engine will still validate."
|
|
325
|
-
});
|
|
326
|
-
}
|
|
327
|
-
} else {
|
|
328
|
-
warnings.push({
|
|
329
|
-
type: "other",
|
|
330
|
-
message: `Native Gemini responseSchema conversion is not available for vendor "${req.outputSchema["~standard"].vendor}"; proceeding with responseMimeType only. Engine will validate output client-side via Standard Schema.`
|
|
331
|
-
});
|
|
232
|
+
const structuredOutputRequested = req.outputJsonSchema !== void 0;
|
|
233
|
+
if (structuredOutputRequested) {
|
|
234
|
+
const nativeStructuredOutput = req.modelDescriptor?.capabilities?.nativeStructuredOutput !== false;
|
|
235
|
+
if (nativeStructuredOutput) {
|
|
236
|
+
config.responseMimeType = "application/json";
|
|
237
|
+
config.responseSchema = req.outputJsonSchema;
|
|
332
238
|
}
|
|
333
239
|
}
|
|
334
240
|
const googleOpts = genConfig.providerOptions?.["google"];
|
|
335
241
|
if (googleOpts !== void 0 && typeof googleOpts === "object" && googleOpts !== null) {
|
|
336
242
|
Object.assign(config, googleOpts);
|
|
337
243
|
}
|
|
244
|
+
const mergedServiceTier = config.serviceTier;
|
|
245
|
+
if (mergedServiceTier !== void 0 && req.modelDescriptor !== void 0) {
|
|
246
|
+
const supportedAfterMerge = req.modelDescriptor.capabilities?.serviceTiers;
|
|
247
|
+
if (supportedAfterMerge === void 0 || !supportedAfterMerge.includes(mergedServiceTier)) {
|
|
248
|
+
throw new LlmError(
|
|
249
|
+
`serviceTier "${mergedServiceTier}" is not supported for model "${model}".`,
|
|
250
|
+
{ kind: "bad_request", retryable: false }
|
|
251
|
+
);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
338
254
|
if (req.modelDescriptor?.capabilities?.sampling === "fixed") {
|
|
339
|
-
const
|
|
255
|
+
const offendingSampling = [];
|
|
340
256
|
if ("temperature" in config) {
|
|
341
|
-
|
|
342
|
-
droppedSampling.push("temperature");
|
|
257
|
+
offendingSampling.push("temperature");
|
|
343
258
|
}
|
|
344
259
|
if ("topP" in config) {
|
|
345
|
-
|
|
346
|
-
droppedSampling.push("topP");
|
|
260
|
+
offendingSampling.push("topP");
|
|
347
261
|
}
|
|
348
262
|
if ("topK" in config) {
|
|
349
|
-
|
|
350
|
-
droppedSampling.push("topK");
|
|
263
|
+
offendingSampling.push("topK");
|
|
351
264
|
}
|
|
352
|
-
if (
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
setting: droppedSampling.join(", "),
|
|
356
|
-
details: `Sampling parameter(s) [${droppedSampling.join(
|
|
265
|
+
if (offendingSampling.length > 0) {
|
|
266
|
+
throw new LlmError(
|
|
267
|
+
`Sampling parameters [${offendingSampling.join(
|
|
357
268
|
", "
|
|
358
|
-
)}]
|
|
359
|
-
|
|
269
|
+
)}] are not supported for model "${model}" (fixed sampling); they were supplied via providerOptions.google.`,
|
|
270
|
+
{ kind: "bad_request", retryable: false }
|
|
271
|
+
);
|
|
360
272
|
}
|
|
361
273
|
}
|
|
362
274
|
const configAsAny = config;
|
|
@@ -367,32 +279,41 @@ function geminiAdapter(opts) {
|
|
|
367
279
|
}
|
|
368
280
|
return false;
|
|
369
281
|
});
|
|
370
|
-
if (groundingRequested &&
|
|
282
|
+
if (groundingRequested && structuredOutputRequested) {
|
|
371
283
|
throw new LlmError(
|
|
372
|
-
"Grounding (googleSearch) cannot be combined with structured output (output.
|
|
284
|
+
"Grounding (googleSearch) cannot be combined with structured output (output.jsonSchema) on Gemini; choose one.",
|
|
373
285
|
{ kind: "bad_request", retryable: false }
|
|
374
286
|
);
|
|
375
287
|
}
|
|
376
|
-
let
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
"TimeoutError"
|
|
382
|
-
);
|
|
383
|
-
_flexTimeoutHandle = setTimeout(() => {
|
|
384
|
-
flexController.abort(timeoutReason);
|
|
385
|
-
}, FLEX_DEFAULT_TIMEOUT_MS);
|
|
386
|
-
if (ctx.signal !== void 0) {
|
|
387
|
-
config.abortSignal = AbortSignal.any([flexController.signal, ctx.signal]);
|
|
388
|
-
} else {
|
|
389
|
-
config.abortSignal = flexController.signal;
|
|
288
|
+
let tierTimeoutHandle;
|
|
289
|
+
const clearTierTimeout = () => {
|
|
290
|
+
if (tierTimeoutHandle !== void 0) {
|
|
291
|
+
clearTimeout(tierTimeoutHandle);
|
|
292
|
+
tierTimeoutHandle = void 0;
|
|
390
293
|
}
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
|
|
294
|
+
};
|
|
295
|
+
const applyTierTimeout = (tier) => {
|
|
296
|
+
clearTierTimeout();
|
|
297
|
+
delete config.abortSignal;
|
|
298
|
+
const defaultTimeoutMs = genConfig.timeoutMs === void 0 ? tier === "flex" ? FLEX_DEFAULT_TIMEOUT_MS : tier === "standard" ? STANDARD_DEFAULT_TIMEOUT_MS : void 0 : void 0;
|
|
299
|
+
if (defaultTimeoutMs !== void 0) {
|
|
300
|
+
const tierController = new AbortController();
|
|
301
|
+
const tierLabel = tier === "standard" ? "Standard" : "Flex";
|
|
302
|
+
const timeoutReason = new DOMException(
|
|
303
|
+
`${tierLabel} timeout: call exceeded ${defaultTimeoutMs}ms client-side ceiling (@google/genai #1277 belt-and-suspenders)`,
|
|
304
|
+
"TimeoutError"
|
|
305
|
+
);
|
|
306
|
+
tierTimeoutHandle = setTimeout(() => {
|
|
307
|
+
tierController.abort(timeoutReason);
|
|
308
|
+
}, defaultTimeoutMs);
|
|
309
|
+
config.abortSignal = ctx.signal !== void 0 ? AbortSignal.any([tierController.signal, ctx.signal]) : tierController.signal;
|
|
310
|
+
} else if (ctx.signal !== void 0) {
|
|
311
|
+
config.abortSignal = ctx.signal;
|
|
312
|
+
}
|
|
313
|
+
};
|
|
314
|
+
applyTierTimeout(config.serviceTier);
|
|
394
315
|
const callerHttpOptions = config.httpOptions;
|
|
395
|
-
const computedTimeoutMs = genConfig.timeoutMs !== void 0 ? genConfig.timeoutMs + TRANSPORT_TIMEOUT_BUFFER_MS :
|
|
316
|
+
const computedTimeoutMs = genConfig.timeoutMs !== void 0 ? genConfig.timeoutMs + TRANSPORT_TIMEOUT_BUFFER_MS : config.serviceTier === "flex" ? FLEX_DEFAULT_TIMEOUT_MS : config.serviceTier === "standard" ? STANDARD_DEFAULT_TIMEOUT_MS : void 0;
|
|
396
317
|
const mergedHttpOptions = {
|
|
397
318
|
...computedTimeoutMs !== void 0 ? { timeout: computedTimeoutMs } : {},
|
|
398
319
|
...callerHttpOptions
|
|
@@ -400,32 +321,71 @@ function geminiAdapter(opts) {
|
|
|
400
321
|
if (Object.keys(mergedHttpOptions).length > 0) {
|
|
401
322
|
config.httpOptions = mergedHttpOptions;
|
|
402
323
|
}
|
|
403
|
-
const params = {
|
|
404
|
-
model,
|
|
405
|
-
contents,
|
|
406
|
-
config
|
|
407
|
-
};
|
|
408
324
|
let response;
|
|
409
|
-
|
|
325
|
+
let servedServiceTier = config.serviceTier;
|
|
326
|
+
const dispatch = async () => {
|
|
327
|
+
const dispatchConfig = {
|
|
328
|
+
...config,
|
|
329
|
+
...config.httpOptions !== void 0 ? { httpOptions: { ...config.httpOptions } } : {}
|
|
330
|
+
};
|
|
331
|
+
const params = {
|
|
332
|
+
model,
|
|
333
|
+
contents,
|
|
334
|
+
config: dispatchConfig
|
|
335
|
+
};
|
|
410
336
|
const buildClient = opts?._clientFactory ?? buildGoogleClient;
|
|
411
337
|
const client = opts?.client !== void 0 ? opts.client : await buildClient(ctx.auth);
|
|
412
338
|
ctx.logger.debug(
|
|
413
|
-
{
|
|
339
|
+
{
|
|
340
|
+
model,
|
|
341
|
+
configKeys: Object.keys(dispatchConfig),
|
|
342
|
+
serviceTier: dispatchConfig.serviceTier
|
|
343
|
+
},
|
|
414
344
|
"llm.adapter.dispatch"
|
|
415
345
|
);
|
|
416
|
-
|
|
346
|
+
return client.models.generateContent(params);
|
|
347
|
+
};
|
|
348
|
+
try {
|
|
349
|
+
response = await dispatch();
|
|
417
350
|
} catch (rawErr) {
|
|
418
351
|
const classified = classifyError(rawErr);
|
|
419
|
-
|
|
352
|
+
const typed = new LlmError(classified.message, {
|
|
420
353
|
kind: classified.kind,
|
|
421
354
|
retryable: classified.retryable,
|
|
422
355
|
...classified.httpStatus !== void 0 ? { httpStatus: classified.httpStatus } : {},
|
|
423
356
|
...classified.retryAfterMs !== void 0 ? { retryAfterMs: classified.retryAfterMs } : {},
|
|
424
357
|
provider: "google",
|
|
425
|
-
cause: classified.cause ?? rawErr
|
|
358
|
+
cause: classified.cause ?? rawErr,
|
|
359
|
+
...servedServiceTier !== void 0 ? { servedServiceTier } : {}
|
|
426
360
|
});
|
|
361
|
+
if (config.serviceTier === "flex" && genConfig.flexFallback !== false && isGeminiCapacityError(typed)) {
|
|
362
|
+
config.serviceTier = "standard";
|
|
363
|
+
servedServiceTier = "standard";
|
|
364
|
+
const fallbackTimeout = genConfig.timeoutMs !== void 0 ? genConfig.timeoutMs + TRANSPORT_TIMEOUT_BUFFER_MS : STANDARD_DEFAULT_TIMEOUT_MS;
|
|
365
|
+
config.httpOptions = {
|
|
366
|
+
timeout: fallbackTimeout,
|
|
367
|
+
...callerHttpOptions
|
|
368
|
+
};
|
|
369
|
+
applyTierTimeout("standard");
|
|
370
|
+
try {
|
|
371
|
+
response = await dispatch();
|
|
372
|
+
} catch (fallbackRawErr) {
|
|
373
|
+
const fallbackClassified = classifyError(fallbackRawErr);
|
|
374
|
+
throw new LlmError(fallbackClassified.message, {
|
|
375
|
+
kind: fallbackClassified.kind,
|
|
376
|
+
retryable: fallbackClassified.retryable,
|
|
377
|
+
...fallbackClassified.httpStatus !== void 0 ? { httpStatus: fallbackClassified.httpStatus } : {},
|
|
378
|
+
...fallbackClassified.retryAfterMs !== void 0 ? { retryAfterMs: fallbackClassified.retryAfterMs } : {},
|
|
379
|
+
provider: "google",
|
|
380
|
+
cause: fallbackClassified.cause ?? fallbackRawErr,
|
|
381
|
+
servedServiceTier: "standard"
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
} else {
|
|
385
|
+
throw typed;
|
|
386
|
+
}
|
|
427
387
|
} finally {
|
|
428
|
-
|
|
388
|
+
clearTierTimeout();
|
|
429
389
|
}
|
|
430
390
|
const hasBlockReason = response.promptFeedback?.blockReason !== void 0;
|
|
431
391
|
const hasCandidates = response.candidates !== void 0 && response.candidates.length > 0;
|
|
@@ -468,7 +428,7 @@ function geminiAdapter(opts) {
|
|
|
468
428
|
const text = textParts.join("");
|
|
469
429
|
const reasoningText = thoughtParts.length > 0 ? thoughtParts.join("") : void 0;
|
|
470
430
|
let rawStructured;
|
|
471
|
-
if (
|
|
431
|
+
if (structuredOutputRequested && text.length > 0) {
|
|
472
432
|
try {
|
|
473
433
|
rawStructured = JSON.parse(text);
|
|
474
434
|
} catch {
|
|
@@ -480,6 +440,7 @@ function geminiAdapter(opts) {
|
|
|
480
440
|
model,
|
|
481
441
|
usage,
|
|
482
442
|
warnings,
|
|
443
|
+
...servedServiceTier !== void 0 ? { servedServiceTier } : {},
|
|
483
444
|
...text.length > 0 ? { text } : {},
|
|
484
445
|
...reasoningText !== void 0 ? { reasoningText } : {},
|
|
485
446
|
...rawStructured !== void 0 ? { rawStructured } : {},
|
|
@@ -905,6 +866,6 @@ var GoogleCacheStore = class {
|
|
|
905
866
|
}
|
|
906
867
|
};
|
|
907
868
|
|
|
908
|
-
export { FLEX_DEFAULT_TIMEOUT_MS, GoogleCacheStore, GoogleFileStore, TRANSPORT_TIMEOUT_BUFFER_MS, buildGoogleClient, geminiAdapter,
|
|
869
|
+
export { FLEX_DEFAULT_TIMEOUT_MS, GoogleCacheStore, GoogleFileStore, STANDARD_DEFAULT_TIMEOUT_MS, TRANSPORT_TIMEOUT_BUFFER_MS, buildGoogleClient, geminiAdapter, isGeminiCapacityError };
|
|
909
870
|
//# sourceMappingURL=index.js.map
|
|
910
871
|
//# sourceMappingURL=index.js.map
|