@f5-sales-demo/pi-ai 21.5.2 → 21.5.3
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/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@f5-sales-demo/pi-ai",
|
|
4
|
-
"version": "21.5.
|
|
4
|
+
"version": "21.5.3",
|
|
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.5.
|
|
49
|
+
"@f5-sales-demo/pi-utils": "21.5.3",
|
|
50
50
|
"@google/genai": "^2.15",
|
|
51
51
|
"@sinclair/typebox": "^0.34",
|
|
52
52
|
"@smithy/node-http-handler": "^4.4",
|
|
@@ -39,7 +39,7 @@ import {
|
|
|
39
39
|
export interface GoogleVertexOptions extends StreamOptions {
|
|
40
40
|
/** OAuth bearer token from the isolated Vertex credential namespace. */
|
|
41
41
|
apiKey?: string;
|
|
42
|
-
toolChoice?: "auto" | "none" | "any";
|
|
42
|
+
toolChoice?: "auto" | "none" | "any" | { name: string };
|
|
43
43
|
thinking?: {
|
|
44
44
|
enabled: boolean;
|
|
45
45
|
budgetTokens?: number; // -1 for dynamic, 0 to disable
|
|
@@ -516,9 +516,11 @@ export function buildGoogleVertexParams(
|
|
|
516
516
|
};
|
|
517
517
|
|
|
518
518
|
if (context.tools && context.tools.length > 0 && options.toolChoice) {
|
|
519
|
+
const forcedToolName = typeof options.toolChoice === "string" ? undefined : options.toolChoice.name;
|
|
519
520
|
config.toolConfig = {
|
|
520
521
|
functionCallingConfig: {
|
|
521
|
-
mode: mapToolChoice(options.toolChoice),
|
|
522
|
+
mode: mapToolChoice(typeof options.toolChoice === "string" ? options.toolChoice : "any"),
|
|
523
|
+
...(forcedToolName && { allowedFunctionNames: [forcedToolName] }),
|
|
522
524
|
},
|
|
523
525
|
};
|
|
524
526
|
} else {
|
package/src/stream.ts
CHANGED
|
@@ -339,9 +339,7 @@ export function mapAnthropicToolChoice(choice?: ToolChoice): AnthropicOptions["t
|
|
|
339
339
|
return undefined;
|
|
340
340
|
}
|
|
341
341
|
|
|
342
|
-
function mapGoogleToolChoice(
|
|
343
|
-
choice?: ToolChoice,
|
|
344
|
-
): GoogleOptions["toolChoice"] | GoogleGeminiCliOptions["toolChoice"] | GoogleVertexOptions["toolChoice"] {
|
|
342
|
+
function mapGoogleToolChoice(choice?: ToolChoice): GoogleOptions["toolChoice"] | GoogleGeminiCliOptions["toolChoice"] {
|
|
345
343
|
if (!choice) return undefined;
|
|
346
344
|
if (typeof choice === "string") {
|
|
347
345
|
if (choice === "required") return "any";
|
|
@@ -351,6 +349,17 @@ function mapGoogleToolChoice(
|
|
|
351
349
|
return "any";
|
|
352
350
|
}
|
|
353
351
|
|
|
352
|
+
function mapGoogleVertexToolChoice(choice?: ToolChoice): GoogleVertexOptions["toolChoice"] {
|
|
353
|
+
if (!choice) return undefined;
|
|
354
|
+
if (typeof choice === "string") {
|
|
355
|
+
if (choice === "required") return "any";
|
|
356
|
+
if (choice === "auto" || choice === "none" || choice === "any") return choice;
|
|
357
|
+
return undefined;
|
|
358
|
+
}
|
|
359
|
+
const name = choice.type === "function" && "function" in choice ? choice.function.name : choice.name;
|
|
360
|
+
return name ? { name } : undefined;
|
|
361
|
+
}
|
|
362
|
+
|
|
354
363
|
function mapOpenAiToolChoice(choice?: ToolChoice): OpenAICompletionsOptions["toolChoice"] {
|
|
355
364
|
if (!choice) return undefined;
|
|
356
365
|
if (typeof choice === "string") {
|
|
@@ -637,7 +646,7 @@ export function mapOptionsForApi<TApi extends Api>(
|
|
|
637
646
|
return castApi<"google-vertex">({
|
|
638
647
|
...vertexBase,
|
|
639
648
|
thinking: { enabled: false },
|
|
640
|
-
toolChoice:
|
|
649
|
+
toolChoice: mapGoogleVertexToolChoice(options?.toolChoice),
|
|
641
650
|
});
|
|
642
651
|
}
|
|
643
652
|
|
|
@@ -652,7 +661,7 @@ export function mapOptionsForApi<TApi extends Api>(
|
|
|
652
661
|
enabled: true,
|
|
653
662
|
level: mapEffortToGoogleThinkingLevel(geminiModel, effort),
|
|
654
663
|
},
|
|
655
|
-
toolChoice:
|
|
664
|
+
toolChoice: mapGoogleVertexToolChoice(options?.toolChoice),
|
|
656
665
|
});
|
|
657
666
|
}
|
|
658
667
|
|
|
@@ -662,7 +671,7 @@ export function mapOptionsForApi<TApi extends Api>(
|
|
|
662
671
|
enabled: true,
|
|
663
672
|
budgetTokens: getGoogleBudget(geminiModel, effort, options?.thinkingBudgets),
|
|
664
673
|
},
|
|
665
|
-
toolChoice:
|
|
674
|
+
toolChoice: mapGoogleVertexToolChoice(options?.toolChoice),
|
|
666
675
|
});
|
|
667
676
|
}
|
|
668
677
|
|
|
@@ -29,12 +29,6 @@ const SCOPES = [
|
|
|
29
29
|
|
|
30
30
|
const AUTH_URL = "https://accounts.google.com/o/oauth2/v2/auth";
|
|
31
31
|
const TOKEN_URL = "https://oauth2.googleapis.com/token";
|
|
32
|
-
// Split the licensed public desktop identifier so secret scanners do not mistake
|
|
33
|
-
// the complete client ID for a user credential.
|
|
34
|
-
const VERTEX_CLIENT_ID =
|
|
35
|
-
decode("ODg0MzU0OTE5MDUyLTM2dHJjMWpqYjN0Z3VpYWMzMm92NmNvZA==") +
|
|
36
|
-
decode("MjY4YzVibGguYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20=");
|
|
37
|
-
const VERTEX_CLIENT_SECRET = decode("R09DU1BYLTlZUVdwRjdS") + decode("V0RDMFFUZGotWXhLTXdSMFp0c1g=");
|
|
38
32
|
const VERTEX_AUTH_URL = "https://accounts.google.com/o/oauth2/auth";
|
|
39
33
|
export const VERTEX_OAUTH_REDIRECT_URI = "https://antigravity.google/oauth-callback";
|
|
40
34
|
const VERTEX_OAUTH_TIMEOUT_MS = 15 * 60 * 1000;
|
|
@@ -47,6 +41,23 @@ const PROJECT_ID_PATTERN = /^[a-z][a-z0-9-]{4,28}[a-z0-9]$/;
|
|
|
47
41
|
const PROJECT_NUMBER_PATTERN = /^\d{12}$/;
|
|
48
42
|
const ANTIGRAVITY_CLI_TOKEN_PATH = join(homedir(), ".gemini", "antigravity-cli", "antigravity-oauth-token");
|
|
49
43
|
|
|
44
|
+
declare const PI_VERTEX_OAUTH_CLIENT_ID: string | undefined;
|
|
45
|
+
declare const PI_VERTEX_OAUTH_CLIENT_SECRET: string | undefined;
|
|
46
|
+
|
|
47
|
+
function resolveVertexOAuthClient(): { clientId: string; clientSecret: string } {
|
|
48
|
+
const compiledClientId = typeof PI_VERTEX_OAUTH_CLIENT_ID === "string" ? PI_VERTEX_OAUTH_CLIENT_ID.trim() : "";
|
|
49
|
+
const compiledClientSecret =
|
|
50
|
+
typeof PI_VERTEX_OAUTH_CLIENT_SECRET === "string" ? PI_VERTEX_OAUTH_CLIENT_SECRET.trim() : "";
|
|
51
|
+
const clientId = compiledClientId || Bun.env.XCSH_VERTEX_OAUTH_CLIENT_ID?.trim();
|
|
52
|
+
const clientSecret = compiledClientSecret || Bun.env.XCSH_VERTEX_OAUTH_CLIENT_SECRET?.trim();
|
|
53
|
+
if (!clientId || !clientSecret) {
|
|
54
|
+
throw new Error(
|
|
55
|
+
"Corporate Vertex OAuth credentials are unavailable in this build. Install an official xcsh binary or provide the licensed build credentials when running from source.",
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
return { clientId, clientSecret };
|
|
59
|
+
}
|
|
60
|
+
|
|
50
61
|
interface LoadCodeAssistPayload {
|
|
51
62
|
cloudaicompanionProject?: string | { id?: string };
|
|
52
63
|
currentTier?: { id?: string };
|
|
@@ -442,12 +453,13 @@ export async function exchangeVertexOAuthCode(
|
|
|
442
453
|
verifier: string,
|
|
443
454
|
fetchImpl: typeof fetch = fetch,
|
|
444
455
|
): Promise<OAuthCredentials> {
|
|
456
|
+
const { clientId, clientSecret } = resolveVertexOAuthClient();
|
|
445
457
|
const tokenResponse = await fetchImpl(TOKEN_URL, {
|
|
446
458
|
method: "POST",
|
|
447
459
|
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
448
460
|
body: new URLSearchParams({
|
|
449
|
-
client_id:
|
|
450
|
-
client_secret:
|
|
461
|
+
client_id: clientId,
|
|
462
|
+
client_secret: clientSecret,
|
|
451
463
|
code,
|
|
452
464
|
code_verifier: verifier,
|
|
453
465
|
grant_type: "authorization_code",
|
|
@@ -470,9 +482,10 @@ export async function exchangeVertexOAuthCode(
|
|
|
470
482
|
}
|
|
471
483
|
|
|
472
484
|
export function createVertexAuthorizationUrl(state: string, challenge: string): string {
|
|
485
|
+
const { clientId } = resolveVertexOAuthClient();
|
|
473
486
|
const params = new URLSearchParams({
|
|
474
487
|
access_type: "offline",
|
|
475
|
-
client_id:
|
|
488
|
+
client_id: clientId,
|
|
476
489
|
code_challenge: challenge,
|
|
477
490
|
code_challenge_method: "S256",
|
|
478
491
|
prompt: "consent",
|
|
@@ -539,12 +552,13 @@ export async function refreshVertexWithAntigravityOAuth(
|
|
|
539
552
|
refreshToken: string,
|
|
540
553
|
fetchImpl: typeof fetch = fetch,
|
|
541
554
|
): Promise<OAuthCredentials> {
|
|
555
|
+
const { clientId, clientSecret } = resolveVertexOAuthClient();
|
|
542
556
|
const response = await fetchImpl(TOKEN_URL, {
|
|
543
557
|
method: "POST",
|
|
544
558
|
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
545
559
|
body: new URLSearchParams({
|
|
546
|
-
client_id:
|
|
547
|
-
client_secret:
|
|
560
|
+
client_id: clientId,
|
|
561
|
+
client_secret: clientSecret,
|
|
548
562
|
refresh_token: refreshToken,
|
|
549
563
|
grant_type: "refresh_token",
|
|
550
564
|
}),
|