@f5-sales-demo/pi-ai 20.4.4 → 20.4.6
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 +1 -0
- package/package.json +2 -2
- package/src/model-thinking.ts +7 -0
- package/src/models.json +2 -1
- package/src/providers/google-vertex.ts +50 -0
package/CHANGELOG.md
CHANGED
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
### Fixed
|
|
18
18
|
|
|
19
19
|
- Preserved native Gemini finish reasons in Google provider errors instead of reporting an unknown error ([#2874](https://github.com/f5-sales-demo/xcsh/issues/2874))
|
|
20
|
+
- Resolved Vertex AI projects directly from the active gcloud configuration before invoking gcloud, so Gemini authentication remains usable when the local gcloud Python launcher is broken ([#2996](https://github.com/f5-sales-demo/xcsh/issues/2996))
|
|
20
21
|
|
|
21
22
|
<!-- markdownlint-disable MD024 -->
|
|
22
23
|
<!-- textlint-disable terminology -->
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@f5-sales-demo/pi-ai",
|
|
4
|
-
"version": "20.4.
|
|
4
|
+
"version": "20.4.6",
|
|
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": "20.4.
|
|
49
|
+
"@f5-sales-demo/pi-utils": "20.4.6",
|
|
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
|
@@ -362,6 +362,13 @@ function applyAnthropicCatalogPolicy(model: ApiModel<Api>, parsedModel: Anthropi
|
|
|
362
362
|
}
|
|
363
363
|
|
|
364
364
|
function applyOpenAICatalogPolicy(model: ApiModel<Api>, parsedModel: OpenAIModel): void {
|
|
365
|
+
// LiteLLM's GPT-5.6 Sol route accepts image input, but upstream catalog
|
|
366
|
+
// metadata currently reports text only. Keep this correction exact so other
|
|
367
|
+
// providers and GPT-5.6 variants retain their advertised capabilities.
|
|
368
|
+
if (model.provider === "litellm" && model.id === "gpt-5.6-sol") {
|
|
369
|
+
model.input = ["text", "image"];
|
|
370
|
+
}
|
|
371
|
+
|
|
365
372
|
// Codex models: 400K figure includes output budget; input window is 272K.
|
|
366
373
|
if (parsedModel.variant.startsWith("codex") && parsedModel.variant !== "codex-spark") {
|
|
367
374
|
model.contextWindow = 272000;
|
package/src/models.json
CHANGED
|
@@ -16599,7 +16599,8 @@
|
|
|
16599
16599
|
"baseUrl": "http://localhost:4000/v1",
|
|
16600
16600
|
"reasoning": true,
|
|
16601
16601
|
"input": [
|
|
16602
|
-
"text"
|
|
16602
|
+
"text",
|
|
16603
|
+
"image"
|
|
16603
16604
|
],
|
|
16604
16605
|
"cost": {
|
|
16605
16606
|
"input": 0,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as fs from "node:fs/promises";
|
|
1
2
|
import * as os from "node:os";
|
|
2
3
|
import * as path from "node:path";
|
|
3
4
|
import { $env, $which, isEnoent } from "@f5-sales-demo/pi-utils";
|
|
@@ -46,6 +47,7 @@ export interface GoogleVertexOptions extends StreamOptions {
|
|
|
46
47
|
|
|
47
48
|
export interface GoogleVertexProjectRuntime {
|
|
48
49
|
readAdcProject(): Promise<string | undefined>;
|
|
50
|
+
readLocalConfigProject?(): Promise<string | undefined>;
|
|
49
51
|
findGcloud(): string | null;
|
|
50
52
|
readConfiguredProject(gcloud: string): Promise<string | undefined>;
|
|
51
53
|
}
|
|
@@ -359,6 +361,7 @@ function resolveApiKey(options?: GoogleVertexOptions): string | undefined {
|
|
|
359
361
|
|
|
360
362
|
const defaultProjectRuntime: GoogleVertexProjectRuntime = {
|
|
361
363
|
readAdcProject,
|
|
364
|
+
readLocalConfigProject: readConfiguredGcloudProject,
|
|
362
365
|
findGcloud: () => $which("gcloud"),
|
|
363
366
|
readConfiguredProject: async gcloud => {
|
|
364
367
|
const result = await $`${gcloud} config get-value project`.quiet().nothrow();
|
|
@@ -370,6 +373,50 @@ const defaultProjectRuntime: GoogleVertexProjectRuntime = {
|
|
|
370
373
|
},
|
|
371
374
|
};
|
|
372
375
|
|
|
376
|
+
function parseGcloudCoreProject(content: string): string | undefined {
|
|
377
|
+
let inCoreSection = false;
|
|
378
|
+
for (const rawLine of content.split(/\r?\n/)) {
|
|
379
|
+
const line = rawLine.trim();
|
|
380
|
+
if (!line || line.startsWith("#") || line.startsWith(";")) continue;
|
|
381
|
+
const section = line.match(/^\[([^\]]+)]$/);
|
|
382
|
+
if (section) {
|
|
383
|
+
inCoreSection = section[1].trim() === "core";
|
|
384
|
+
continue;
|
|
385
|
+
}
|
|
386
|
+
if (!inCoreSection) continue;
|
|
387
|
+
const property = line.match(/^project\s*=\s*(.+)$/);
|
|
388
|
+
if (!property) continue;
|
|
389
|
+
const project = property[1].trim();
|
|
390
|
+
return project && project !== "(unset)" ? project : undefined;
|
|
391
|
+
}
|
|
392
|
+
return undefined;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/** Read the active gcloud project's INI file without requiring gcloud's Python launcher. */
|
|
396
|
+
export async function readConfiguredGcloudProject(
|
|
397
|
+
configDirectory: string = $env.CLOUDSDK_CONFIG || path.join(os.homedir(), ".config", "gcloud"),
|
|
398
|
+
): Promise<string | undefined> {
|
|
399
|
+
let configurationName = $env.CLOUDSDK_ACTIVE_CONFIG_NAME?.trim();
|
|
400
|
+
if (!configurationName) {
|
|
401
|
+
try {
|
|
402
|
+
configurationName = (await fs.readFile(path.join(configDirectory, "active_config"), "utf8")).trim();
|
|
403
|
+
} catch {
|
|
404
|
+
configurationName = "default";
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
if (!/^[A-Za-z0-9_-]+$/.test(configurationName)) return undefined;
|
|
408
|
+
|
|
409
|
+
try {
|
|
410
|
+
const content = await fs.readFile(
|
|
411
|
+
path.join(configDirectory, "configurations", `config_${configurationName}`),
|
|
412
|
+
"utf8",
|
|
413
|
+
);
|
|
414
|
+
return parseGcloudCoreProject(content);
|
|
415
|
+
} catch {
|
|
416
|
+
return undefined;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
|
|
373
420
|
export async function resolveGoogleVertexProject(
|
|
374
421
|
options?: GoogleVertexOptions,
|
|
375
422
|
runtime: GoogleVertexProjectRuntime = defaultProjectRuntime,
|
|
@@ -380,6 +427,9 @@ export async function resolveGoogleVertexProject(
|
|
|
380
427
|
const adcProject = await runtime.readAdcProject();
|
|
381
428
|
if (adcProject) return adcProject;
|
|
382
429
|
|
|
430
|
+
const localConfigProject = await runtime.readLocalConfigProject?.();
|
|
431
|
+
if (localConfigProject) return localConfigProject;
|
|
432
|
+
|
|
383
433
|
const gcloud = runtime.findGcloud();
|
|
384
434
|
if (gcloud) {
|
|
385
435
|
const configuredProject = await runtime.readConfiguredProject(gcloud);
|