@f5-sales-demo/pi-ai 21.0.0 → 21.2.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/CHANGELOG.md +4 -0
- package/package.json +2 -2
- package/src/model-thinking.ts +20 -3
- package/src/models.json +25 -13
- package/src/providers/google-shared.ts +8 -4
- package/src/providers/google-vertex.ts +14 -11
- package/src/types.ts +4 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,10 @@
|
|
|
4
4
|
|
|
5
5
|
## Unreleased
|
|
6
6
|
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- Replaced Vertex Gemini 3.6 Flash with GA Gemini 3.7 Flash and made full Vertex Gemini Flash and Pro models default to HIGH thinking while preserving supported explicit effort overrides ([#3460](https://github.com/f5-sales-demo/xcsh/issues/3460)).
|
|
10
|
+
|
|
7
11
|
### Fixed
|
|
8
12
|
|
|
9
13
|
- Omit an empty OpenAI-compatible `tools` field unless prior tool-call history requires the explicit empty array, and suppress the internal no-auth credential sentinel from keyless request headers ([#2942](https://github.com/f5-sales-demo/xcsh/issues/2942), [#3361](https://github.com/f5-sales-demo/xcsh/issues/3361)).
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@f5-sales-demo/pi-ai",
|
|
4
|
-
"version": "21.
|
|
4
|
+
"version": "21.2.0",
|
|
5
5
|
"description": "Unified LLM API with automatic model discovery and provider configuration",
|
|
6
6
|
"homepage": "https://github.com/f5-sales-demo/xcsh",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"@anthropic-ai/sdk": "^0.115",
|
|
47
47
|
"@aws-sdk/client-bedrock-runtime": "^3",
|
|
48
48
|
"@bufbuild/protobuf": "^2.11",
|
|
49
|
-
"@f5-sales-demo/pi-utils": "21.
|
|
49
|
+
"@f5-sales-demo/pi-utils": "21.2.0",
|
|
50
50
|
"@google/genai": "^2.15",
|
|
51
51
|
"@sinclair/typebox": "^0.34",
|
|
52
52
|
"@smithy/node-http-handler": "^4.4",
|
package/src/model-thinking.ts
CHANGED
|
@@ -80,7 +80,7 @@ const ANTHROPIC_ADAPTIVE_EFFORTS: readonly Effort[] = [
|
|
|
80
80
|
*/
|
|
81
81
|
const ANTHROPIC_EXTENDED_EFFORT_VERSIONS: ReadonlySet<string> = new Set(["5.0"]);
|
|
82
82
|
|
|
83
|
-
const GEMINI_3_PRO_EFFORTS: readonly Effort[] = [Effort.Low, Effort.High];
|
|
83
|
+
const GEMINI_3_PRO_EFFORTS: readonly Effort[] = [Effort.Low, Effort.Medium, Effort.High];
|
|
84
84
|
const GEMINI_3_FLASH_EFFORTS: readonly Effort[] = [Effort.Minimal, Effort.Low, Effort.Medium, Effort.High];
|
|
85
85
|
const GPT_5_2_PLUS_EFFORTS: readonly Effort[] = [Effort.Low, Effort.Medium, Effort.High, Effort.XHigh];
|
|
86
86
|
const GPT_5_1_CODEX_MINI_EFFORTS: readonly Effort[] = [Effort.Medium, Effort.High];
|
|
@@ -397,11 +397,22 @@ function inferModelThinking<TApi extends Api>(model: ApiModel<TApi>): ThinkingCo
|
|
|
397
397
|
if (!minLevel || !maxLevel) {
|
|
398
398
|
throw new Error(`Model ${model.provider}/${model.id} resolved to an empty thinking range`);
|
|
399
399
|
}
|
|
400
|
-
|
|
400
|
+
const thinking: ThinkingConfig = {
|
|
401
401
|
mode: inferThinkingControlMode(model, parsedModel),
|
|
402
402
|
minLevel,
|
|
403
403
|
maxLevel,
|
|
404
404
|
};
|
|
405
|
+
if (
|
|
406
|
+
model.provider === "google-vertex" &&
|
|
407
|
+
parsedModel.family === "gemini" &&
|
|
408
|
+
!model.id.toLowerCase().includes("lite")
|
|
409
|
+
) {
|
|
410
|
+
thinking.defaultLevel = Effort.High;
|
|
411
|
+
if (parsedModel.version.major === 3) {
|
|
412
|
+
thinking.canDisable = false;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
return thinking;
|
|
405
416
|
}
|
|
406
417
|
|
|
407
418
|
function normalizeThinkingConfig(thinking: ThinkingConfig | undefined): ThinkingConfig | undefined {
|
|
@@ -414,7 +425,13 @@ function normalizeThinkingConfig(thinking: ThinkingConfig | undefined): Thinking
|
|
|
414
425
|
function thinkingsEqual(left: ThinkingConfig | undefined, right: ThinkingConfig | undefined): boolean {
|
|
415
426
|
if (left === right) return true;
|
|
416
427
|
if (!left || !right) return false;
|
|
417
|
-
return
|
|
428
|
+
return (
|
|
429
|
+
left.mode === right.mode &&
|
|
430
|
+
left.minLevel === right.minLevel &&
|
|
431
|
+
left.maxLevel === right.maxLevel &&
|
|
432
|
+
left.defaultLevel === right.defaultLevel &&
|
|
433
|
+
left.canDisable === right.canDisable
|
|
434
|
+
);
|
|
418
435
|
}
|
|
419
436
|
|
|
420
437
|
function expandEffortRange(thinking: ThinkingConfig): readonly Effort[] {
|
package/src/models.json
CHANGED
|
@@ -7030,9 +7030,9 @@
|
|
|
7030
7030
|
}
|
|
7031
7031
|
},
|
|
7032
7032
|
"google-vertex": {
|
|
7033
|
-
"gemini-3.
|
|
7034
|
-
"id": "gemini-3.
|
|
7035
|
-
"name": "Gemini 3.
|
|
7033
|
+
"gemini-3.7-flash": {
|
|
7034
|
+
"id": "gemini-3.7-flash",
|
|
7035
|
+
"name": "Gemini 3.7 Flash",
|
|
7036
7036
|
"api": "google-vertex",
|
|
7037
7037
|
"provider": "google-vertex",
|
|
7038
7038
|
"baseUrl": "https://{location}-aiplatform.googleapis.com",
|
|
@@ -7042,9 +7042,9 @@
|
|
|
7042
7042
|
"image"
|
|
7043
7043
|
],
|
|
7044
7044
|
"cost": {
|
|
7045
|
-
"input": 0,
|
|
7046
|
-
"output":
|
|
7047
|
-
"cacheRead": 0,
|
|
7045
|
+
"input": 0.75,
|
|
7046
|
+
"output": 3.75,
|
|
7047
|
+
"cacheRead": 0.075,
|
|
7048
7048
|
"cacheWrite": 0
|
|
7049
7049
|
},
|
|
7050
7050
|
"contextWindow": 1048576,
|
|
@@ -7052,7 +7052,9 @@
|
|
|
7052
7052
|
"thinking": {
|
|
7053
7053
|
"mode": "google-level",
|
|
7054
7054
|
"minLevel": "low",
|
|
7055
|
-
"maxLevel": "high"
|
|
7055
|
+
"maxLevel": "high",
|
|
7056
|
+
"defaultLevel": "high",
|
|
7057
|
+
"canDisable": false
|
|
7056
7058
|
}
|
|
7057
7059
|
},
|
|
7058
7060
|
"gemini-1.5-flash": {
|
|
@@ -7177,7 +7179,8 @@
|
|
|
7177
7179
|
"thinking": {
|
|
7178
7180
|
"mode": "budget",
|
|
7179
7181
|
"minLevel": "minimal",
|
|
7180
|
-
"maxLevel": "high"
|
|
7182
|
+
"maxLevel": "high",
|
|
7183
|
+
"defaultLevel": "high"
|
|
7181
7184
|
}
|
|
7182
7185
|
},
|
|
7183
7186
|
"gemini-2.5-flash-lite": {
|
|
@@ -7252,7 +7255,8 @@
|
|
|
7252
7255
|
"thinking": {
|
|
7253
7256
|
"mode": "budget",
|
|
7254
7257
|
"minLevel": "minimal",
|
|
7255
|
-
"maxLevel": "high"
|
|
7258
|
+
"maxLevel": "high",
|
|
7259
|
+
"defaultLevel": "high"
|
|
7256
7260
|
}
|
|
7257
7261
|
},
|
|
7258
7262
|
"gemini-3-flash-preview": {
|
|
@@ -7277,7 +7281,9 @@
|
|
|
7277
7281
|
"thinking": {
|
|
7278
7282
|
"mode": "google-level",
|
|
7279
7283
|
"minLevel": "minimal",
|
|
7280
|
-
"maxLevel": "high"
|
|
7284
|
+
"maxLevel": "high",
|
|
7285
|
+
"defaultLevel": "high",
|
|
7286
|
+
"canDisable": false
|
|
7281
7287
|
}
|
|
7282
7288
|
},
|
|
7283
7289
|
"gemini-3-pro-preview": {
|
|
@@ -7302,7 +7308,9 @@
|
|
|
7302
7308
|
"thinking": {
|
|
7303
7309
|
"mode": "google-level",
|
|
7304
7310
|
"minLevel": "low",
|
|
7305
|
-
"maxLevel": "high"
|
|
7311
|
+
"maxLevel": "high",
|
|
7312
|
+
"defaultLevel": "high",
|
|
7313
|
+
"canDisable": false
|
|
7306
7314
|
}
|
|
7307
7315
|
},
|
|
7308
7316
|
"gemini-3.1-pro-preview": {
|
|
@@ -7327,7 +7335,9 @@
|
|
|
7327
7335
|
"thinking": {
|
|
7328
7336
|
"mode": "google-level",
|
|
7329
7337
|
"minLevel": "low",
|
|
7330
|
-
"maxLevel": "high"
|
|
7338
|
+
"maxLevel": "high",
|
|
7339
|
+
"defaultLevel": "high",
|
|
7340
|
+
"canDisable": false
|
|
7331
7341
|
}
|
|
7332
7342
|
},
|
|
7333
7343
|
"gemini-3.1-pro-preview-customtools": {
|
|
@@ -7352,7 +7362,9 @@
|
|
|
7352
7362
|
"thinking": {
|
|
7353
7363
|
"mode": "google-level",
|
|
7354
7364
|
"minLevel": "low",
|
|
7355
|
-
"maxLevel": "high"
|
|
7365
|
+
"maxLevel": "high",
|
|
7366
|
+
"defaultLevel": "high",
|
|
7367
|
+
"canDisable": false
|
|
7356
7368
|
}
|
|
7357
7369
|
}
|
|
7358
7370
|
},
|
|
@@ -62,10 +62,10 @@ function resolveThoughtSignature(isSameProviderAndModel: boolean, signature: str
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
/**
|
|
65
|
-
*
|
|
65
|
+
* Models with strict Google tool round trips require explicit matching call/response IDs.
|
|
66
66
|
*/
|
|
67
67
|
export function requiresToolCallId(modelId: string): boolean {
|
|
68
|
-
return modelId.startsWith("claude-");
|
|
68
|
+
return modelId.startsWith("claude-") || modelId === "gemini-3.7-flash";
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
function getGeminiMajorVersion(modelId: string): number | undefined {
|
|
@@ -177,7 +177,7 @@ export function convertMessages<T extends GoogleApiType>(model: Model<T>, contex
|
|
|
177
177
|
...(requiresToolCallId(model.id) ? { id: block.id } : {}),
|
|
178
178
|
},
|
|
179
179
|
};
|
|
180
|
-
if (model.provider === "google-vertex" && part?.functionCall?.id) {
|
|
180
|
+
if (model.provider === "google-vertex" && model.id !== "gemini-3.7-flash" && part?.functionCall?.id) {
|
|
181
181
|
delete part.functionCall.id; // Vertex AI does not support 'id' in functionCall
|
|
182
182
|
}
|
|
183
183
|
if (effectiveSignature) {
|
|
@@ -228,7 +228,11 @@ export function convertMessages<T extends GoogleApiType>(model: Model<T>, contex
|
|
|
228
228
|
},
|
|
229
229
|
};
|
|
230
230
|
|
|
231
|
-
if (
|
|
231
|
+
if (
|
|
232
|
+
model.provider === "google-vertex" &&
|
|
233
|
+
model.id !== "gemini-3.7-flash" &&
|
|
234
|
+
functionResponsePart.functionResponse?.id
|
|
235
|
+
) {
|
|
232
236
|
delete functionResponsePart.functionResponse.id; // Vertex AI does not support 'id' in functionResponse
|
|
233
237
|
}
|
|
234
238
|
|
|
@@ -108,7 +108,7 @@ export const streamGoogleVertex: StreamFunction<"google-vertex"> = (
|
|
|
108
108
|
const project = apiKey ? undefined : await resolveGoogleVertexProject(options);
|
|
109
109
|
const location = apiKey ? undefined : resolveGoogleVertexLocation(options);
|
|
110
110
|
const client = apiKey ? createClientWithApiKey(model, apiKey) : createClient(model, project!, location!);
|
|
111
|
-
const params =
|
|
111
|
+
const params = buildGoogleVertexParams(model, context, options);
|
|
112
112
|
options?.onPayload?.(params);
|
|
113
113
|
rawRequestDump = {
|
|
114
114
|
provider: model.provider,
|
|
@@ -467,33 +467,34 @@ export function googleVertexRequestUrl(modelId: string, project: string, locatio
|
|
|
467
467
|
return `https://${host}/${API_VERSION}/projects/${project}/locations/${location}/publishers/google/models/${modelId}:streamGenerateContent`;
|
|
468
468
|
}
|
|
469
469
|
|
|
470
|
-
function
|
|
470
|
+
export function buildGoogleVertexParams(
|
|
471
471
|
model: Model<"google-vertex">,
|
|
472
472
|
context: Context,
|
|
473
473
|
options: GoogleVertexOptions = {},
|
|
474
474
|
): GenerateContentParameters {
|
|
475
475
|
const contents = convertMessages(model, context);
|
|
476
|
+
const isGemini37Flash = model.id === "gemini-3.7-flash";
|
|
476
477
|
|
|
477
478
|
const generationConfig: GoogleVertexSamplingConfig = {};
|
|
478
|
-
if (options.temperature !== undefined) {
|
|
479
|
+
if (!isGemini37Flash && options.temperature !== undefined) {
|
|
479
480
|
generationConfig.temperature = options.temperature;
|
|
480
481
|
}
|
|
481
482
|
if (options.maxTokens !== undefined) {
|
|
482
483
|
generationConfig.maxOutputTokens = options.maxTokens;
|
|
483
484
|
}
|
|
484
|
-
if (options.topP !== undefined) {
|
|
485
|
+
if (!isGemini37Flash && options.topP !== undefined) {
|
|
485
486
|
generationConfig.topP = options.topP;
|
|
486
487
|
}
|
|
487
|
-
if (options.topK !== undefined) {
|
|
488
|
+
if (!isGemini37Flash && options.topK !== undefined) {
|
|
488
489
|
generationConfig.topK = options.topK;
|
|
489
490
|
}
|
|
490
|
-
if (options.minP !== undefined) {
|
|
491
|
+
if (!isGemini37Flash && options.minP !== undefined) {
|
|
491
492
|
generationConfig.minP = options.minP;
|
|
492
493
|
}
|
|
493
|
-
if (options.presencePenalty !== undefined) {
|
|
494
|
+
if (!isGemini37Flash && options.presencePenalty !== undefined) {
|
|
494
495
|
generationConfig.presencePenalty = options.presencePenalty;
|
|
495
496
|
}
|
|
496
|
-
if (options.repetitionPenalty !== undefined) {
|
|
497
|
+
if (!isGemini37Flash && options.repetitionPenalty !== undefined) {
|
|
497
498
|
generationConfig.repetitionPenalty = options.repetitionPenalty;
|
|
498
499
|
}
|
|
499
500
|
|
|
@@ -513,11 +514,13 @@ function buildParams(
|
|
|
513
514
|
config.toolConfig = undefined;
|
|
514
515
|
}
|
|
515
516
|
|
|
516
|
-
if (options.thinking?.enabled
|
|
517
|
+
if (model.reasoning && (options.thinking?.enabled || isGemini37Flash)) {
|
|
517
518
|
const cfg: ThinkingConfig = { includeThoughts: true };
|
|
518
|
-
if (options.thinking
|
|
519
|
+
if (options.thinking?.level !== undefined) {
|
|
519
520
|
cfg.thinkingLevel = THINKING_LEVEL_MAP[options.thinking.level];
|
|
520
|
-
} else if (
|
|
521
|
+
} else if (isGemini37Flash) {
|
|
522
|
+
cfg.thinkingLevel = ThinkingLevel.HIGH;
|
|
523
|
+
} else if (options.thinking?.budgetTokens !== undefined) {
|
|
521
524
|
cfg.thinkingBudget = options.thinking.budgetTokens;
|
|
522
525
|
}
|
|
523
526
|
config.thinkingConfig = cfg;
|
package/src/types.ts
CHANGED
|
@@ -83,6 +83,10 @@ export interface ThinkingConfig {
|
|
|
83
83
|
minLevel: Effort;
|
|
84
84
|
/** Most intensive supported user-facing effort level. */
|
|
85
85
|
maxLevel: Effort;
|
|
86
|
+
/** Model-specific effort used when no explicit or saved effort is selected. */
|
|
87
|
+
defaultLevel?: Effort;
|
|
88
|
+
/** Whether callers may explicitly disable thinking. Defaults to true. */
|
|
89
|
+
canDisable?: boolean;
|
|
86
90
|
/** Provider-specific transport used to encode the selected effort. */
|
|
87
91
|
mode: ThinkingControlMode;
|
|
88
92
|
}
|