pi-provider-litellm 2.3.0 → 3.0.1
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 +148 -24
- package/package.json +13 -18
- package/src/backend-identity.ts +100 -0
- package/src/cost.ts +52 -0
- package/src/discover.ts +1318 -0
- package/src/gcloud-token.ts +160 -0
- package/src/index.ts +2044 -0
- package/src/mcp-tools.ts +1341 -0
- package/src/model-groups.ts +947 -0
- package/src/protocols.ts +42 -0
- package/src/provider.ts +248 -0
- package/src/public-catalog.ts +272 -0
- package/src/skills.ts +275 -0
- package/src/thinking-levels.ts +35 -0
- package/src/types.ts +164 -0
- package/dist/cost.d.ts +0 -2
- package/dist/cost.js +0 -49
- package/dist/discover.d.ts +0 -12
- package/dist/discover.js +0 -380
- package/dist/gcloud-token-cli.d.ts +0 -1
- package/dist/gcloud-token-cli.js +0 -8
- package/dist/gcloud-token.d.ts +0 -7
- package/dist/gcloud-token.js +0 -133
- package/dist/index.d.ts +0 -2
- package/dist/index.js +0 -1226
- package/dist/litellm.d.ts +0 -1
- package/dist/litellm.js +0 -10
- package/dist/mcp-tools.d.ts +0 -5
- package/dist/mcp-tools.js +0 -181
- package/dist/provider.d.ts +0 -16
- package/dist/provider.js +0 -40
- package/dist/skills.d.ts +0 -14
- package/dist/skills.js +0 -225
- package/dist/types.d.ts +0 -108
- package/dist/types.js +0 -1
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
|
|
6
|
+
export const CACHE_TTL_MS = 50 * 60 * 1000;
|
|
7
|
+
export const GCLOUD_TOKEN_CACHE_KEY = "gcloud-adc";
|
|
8
|
+
|
|
9
|
+
const ADC_FILENAME = "application_default_credentials.json";
|
|
10
|
+
|
|
11
|
+
let cachedToken: string | null = null;
|
|
12
|
+
let cachedAt = 0;
|
|
13
|
+
let cachedTokenKey: string | null = null;
|
|
14
|
+
|
|
15
|
+
interface AuthorizedUserCredentials {
|
|
16
|
+
type: "authorized_user";
|
|
17
|
+
client_id: string;
|
|
18
|
+
client_secret: string;
|
|
19
|
+
refresh_token: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
interface ServiceAccountCredentials {
|
|
23
|
+
type: "service_account";
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
type GoogleCredentials = AuthorizedUserCredentials | ServiceAccountCredentials | { type?: string };
|
|
27
|
+
|
|
28
|
+
function isAuthorizedUserCredentials(credentials: GoogleCredentials): credentials is AuthorizedUserCredentials {
|
|
29
|
+
const authorizedUser = credentials as Partial<AuthorizedUserCredentials>;
|
|
30
|
+
return (
|
|
31
|
+
credentials.type === "authorized_user" &&
|
|
32
|
+
typeof authorizedUser.client_id === "string" &&
|
|
33
|
+
authorizedUser.client_id.trim() !== "" &&
|
|
34
|
+
typeof authorizedUser.client_secret === "string" &&
|
|
35
|
+
authorizedUser.client_secret.trim() !== "" &&
|
|
36
|
+
typeof authorizedUser.refresh_token === "string" &&
|
|
37
|
+
authorizedUser.refresh_token.trim() !== ""
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function isGcloudTokenAuthEnabled(): boolean {
|
|
42
|
+
const raw = process.env.LITELLM_GCLOUD_TOKEN_AUTH;
|
|
43
|
+
return raw !== undefined && raw !== "" && raw !== "0";
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function getAdcPath(): string | null {
|
|
47
|
+
const envPath = process.env.GOOGLE_APPLICATION_CREDENTIALS;
|
|
48
|
+
if (envPath) return envPath;
|
|
49
|
+
|
|
50
|
+
const candidates = [join(homedir(), ".config", "gcloud", ADC_FILENAME)];
|
|
51
|
+
if (process.env.APPDATA) candidates.push(join(process.env.APPDATA, "gcloud", ADC_FILENAME));
|
|
52
|
+
|
|
53
|
+
return candidates.find((path) => existsSync(path)) ?? null;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function getCredentialsCacheKey(credentials: AuthorizedUserCredentials): string {
|
|
57
|
+
return `${GCLOUD_TOKEN_CACHE_KEY}:authorized_user:${credentials.client_id}:${credentials.refresh_token}`;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async function readCredentials(path: string): Promise<GoogleCredentials | null> {
|
|
61
|
+
try {
|
|
62
|
+
return JSON.parse(await readFile(path, "utf8")) as GoogleCredentials;
|
|
63
|
+
} catch {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Single ADC resolution path: locate the file, read it, and either return usable
|
|
69
|
+
// authorized_user credentials or warn with the specific reason they are not.
|
|
70
|
+
async function resolveAuthorizedUserAdc(): Promise<AuthorizedUserCredentials | null> {
|
|
71
|
+
const adcPath = getAdcPath();
|
|
72
|
+
if (!adcPath) {
|
|
73
|
+
console.warn(
|
|
74
|
+
"LiteLLM gcloud auth: No Google ADC file found. Set GOOGLE_APPLICATION_CREDENTIALS or run `gcloud auth application-default login`.",
|
|
75
|
+
);
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const credentials = await readCredentials(adcPath);
|
|
80
|
+
if (!credentials) {
|
|
81
|
+
console.warn(`LiteLLM gcloud auth: Failed to read ADC file: ${adcPath}`);
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (isAuthorizedUserCredentials(credentials)) return credentials;
|
|
86
|
+
|
|
87
|
+
if (credentials.type === "authorized_user") {
|
|
88
|
+
console.warn("LiteLLM gcloud auth: authorized_user ADC has invalid or incomplete required fields.");
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (credentials.type === "service_account") {
|
|
93
|
+
console.warn("LiteLLM gcloud auth: Service account credentials are not supported; use authorized_user ADC.");
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
console.warn(`LiteLLM gcloud auth: Unknown credential type: ${credentials.type ?? "missing"}`);
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Reports whether a complete `authorized_user` ADC file is present, emitting the same
|
|
102
|
+
// diagnostics as the token path. This is a check on credential *shape*: whether the
|
|
103
|
+
// refresh token is still honored by Google is only knowable at mint time, and
|
|
104
|
+
// `apiKey.check` deliberately performs no network call.
|
|
105
|
+
export async function hasGcloudAdcCredentials(): Promise<boolean> {
|
|
106
|
+
return (await resolveAuthorizedUserAdc()) !== null;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async function exchangeRefreshToken(credentials: AuthorizedUserCredentials): Promise<string | null> {
|
|
110
|
+
const body = new URLSearchParams({
|
|
111
|
+
grant_type: "refresh_token",
|
|
112
|
+
client_id: credentials.client_id,
|
|
113
|
+
client_secret: credentials.client_secret,
|
|
114
|
+
refresh_token: credentials.refresh_token,
|
|
115
|
+
}).toString();
|
|
116
|
+
|
|
117
|
+
try {
|
|
118
|
+
const response = await fetch("https://oauth2.googleapis.com/token", {
|
|
119
|
+
method: "POST",
|
|
120
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
121
|
+
body,
|
|
122
|
+
signal: AbortSignal.timeout(10_000),
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
if (!response.ok) {
|
|
126
|
+
console.warn(`LiteLLM gcloud auth: Token exchange failed (${response.status})`);
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const data = (await response.json()) as { access_token?: unknown };
|
|
131
|
+
return typeof data.access_token === "string" && data.access_token ? data.access_token : null;
|
|
132
|
+
} catch (error) {
|
|
133
|
+
console.warn(
|
|
134
|
+
`LiteLLM gcloud auth: Token exchange failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
135
|
+
);
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export async function getGcloudToken(): Promise<string | null> {
|
|
141
|
+
const credentials = await resolveAuthorizedUserAdc();
|
|
142
|
+
if (!credentials) return null;
|
|
143
|
+
|
|
144
|
+
const cacheKey = getCredentialsCacheKey(credentials);
|
|
145
|
+
if (cachedToken && cachedTokenKey === cacheKey && Date.now() - cachedAt < CACHE_TTL_MS) return cachedToken;
|
|
146
|
+
|
|
147
|
+
const token = await exchangeRefreshToken(credentials);
|
|
148
|
+
if (token) {
|
|
149
|
+
cachedToken = token;
|
|
150
|
+
cachedTokenKey = cacheKey;
|
|
151
|
+
cachedAt = Date.now();
|
|
152
|
+
}
|
|
153
|
+
return token;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export function resetGcloudTokenCache(): void {
|
|
157
|
+
cachedToken = null;
|
|
158
|
+
cachedTokenKey = null;
|
|
159
|
+
cachedAt = 0;
|
|
160
|
+
}
|