This commit is contained in:
@@ -37,7 +37,7 @@ Unified LLM API with automatic model discovery, provider configuration, token an
|
||||
- [Environment Variables](#environment-variables-nodejs-only)
|
||||
- [Checking Environment Variables](#checking-environment-variables)
|
||||
- [OAuth Providers](#oauth-providers)
|
||||
- [Vertex AI (ADC)](#vertex-ai-adc)
|
||||
- [Vertex AI](#vertex-ai)
|
||||
- [CLI Login](#cli-login)
|
||||
- [Programmatic OAuth](#programmatic-oauth)
|
||||
- [Login Flow Example](#login-flow-example)
|
||||
@@ -907,7 +907,7 @@ In Node.js environments, you can set environment variables to avoid passing API
|
||||
| Azure OpenAI | `AZURE_OPENAI_API_KEY` + `AZURE_OPENAI_BASE_URL` or `AZURE_OPENAI_RESOURCE_NAME` (optional `AZURE_OPENAI_API_VERSION`, `AZURE_OPENAI_DEPLOYMENT_NAME_MAP` like `model=deployment,model2=deployment2`) |
|
||||
| Anthropic | `ANTHROPIC_API_KEY` or `ANTHROPIC_OAUTH_TOKEN` |
|
||||
| Google | `GEMINI_API_KEY` |
|
||||
| Vertex AI | `GOOGLE_CLOUD_PROJECT` (or `GCLOUD_PROJECT`) + `GOOGLE_CLOUD_LOCATION` + ADC |
|
||||
| Vertex AI | `GOOGLE_CLOUD_API_KEY` or `GOOGLE_CLOUD_PROJECT` (or `GCLOUD_PROJECT`) + `GOOGLE_CLOUD_LOCATION` + ADC |
|
||||
| Mistral | `MISTRAL_API_KEY` |
|
||||
| Groq | `GROQ_API_KEY` |
|
||||
| Cerebras | `CEREBRAS_API_KEY` |
|
||||
@@ -975,14 +975,15 @@ Several providers require OAuth authentication instead of static API keys:
|
||||
|
||||
For paid Cloud Code Assist subscriptions, set `GOOGLE_CLOUD_PROJECT` or `GOOGLE_CLOUD_PROJECT_ID` to your project ID.
|
||||
|
||||
### Vertex AI (ADC)
|
||||
### Vertex AI
|
||||
|
||||
Vertex AI models use Application Default Credentials (ADC):
|
||||
Vertex AI models support either a Google Cloud API key or Application Default Credentials (ADC):
|
||||
|
||||
- **Local development**: Run `gcloud auth application-default login`
|
||||
- **CI/Production**: Set `GOOGLE_APPLICATION_CREDENTIALS` to point to a service account JSON key file
|
||||
- **API key**: Set `GOOGLE_CLOUD_API_KEY` or pass `apiKey` in the call options.
|
||||
- **Local development (ADC)**: Run `gcloud auth application-default login`
|
||||
- **CI/Production (ADC)**: Set `GOOGLE_APPLICATION_CREDENTIALS` to point to a service account JSON key file
|
||||
|
||||
Also set `GOOGLE_CLOUD_PROJECT` (or `GCLOUD_PROJECT`) and `GOOGLE_CLOUD_LOCATION`. You can also pass `project`/`location` in the call options.
|
||||
When using ADC, also set `GOOGLE_CLOUD_PROJECT` (or `GCLOUD_PROJECT`) and `GOOGLE_CLOUD_LOCATION`. You can also pass `project`/`location` in the call options. When using `GOOGLE_CLOUD_API_KEY`, `project` and `location` are not required.
|
||||
|
||||
Example:
|
||||
|
||||
@@ -1003,6 +1004,8 @@ import { getModel, complete } from '@mariozechner/pi-ai';
|
||||
const model = getModel('google-vertex', 'gemini-2.5-flash');
|
||||
const response = await complete(model, {
|
||||
messages: [{ role: 'user', content: 'Hello from Vertex AI' }]
|
||||
}, {
|
||||
apiKey: process.env.GOOGLE_CLOUD_API_KEY,
|
||||
});
|
||||
|
||||
for (const block of response.content) {
|
||||
|
||||
@@ -73,9 +73,13 @@ export function getEnvApiKey(provider: any): string | undefined {
|
||||
return process.env.ANTHROPIC_OAUTH_TOKEN || process.env.ANTHROPIC_API_KEY;
|
||||
}
|
||||
|
||||
// Vertex AI uses Application Default Credentials, not API keys.
|
||||
// Auth is configured via `gcloud auth application-default login`.
|
||||
// Vertex AI supports either an explicit API key or Application Default Credentials
|
||||
// Auth is configured via `gcloud auth application-default login`
|
||||
if (provider === "google-vertex") {
|
||||
if (process.env.GOOGLE_CLOUD_API_KEY) {
|
||||
return process.env.GOOGLE_CLOUD_API_KEY;
|
||||
}
|
||||
|
||||
const hasCredentials = hasVertexAdcCredentials();
|
||||
const hasProject = !!(process.env.GOOGLE_CLOUD_PROJECT || process.env.GCLOUD_PROJECT);
|
||||
const hasLocation = !!process.env.GOOGLE_CLOUD_LOCATION;
|
||||
|
||||
@@ -84,9 +84,11 @@ export const streamGoogleVertex: StreamFunction<"google-vertex", GoogleVertexOpt
|
||||
};
|
||||
|
||||
try {
|
||||
const project = resolveProject(options);
|
||||
const location = resolveLocation(options);
|
||||
const client = createClient(model, project, location, options?.headers);
|
||||
const apiKey = resolveApiKey(options);
|
||||
// Create the client using either a Vertex API key, if provided, or ADC with project and location
|
||||
const client = apiKey
|
||||
? createClientWithApiKey(model, apiKey, options?.headers)
|
||||
: createClient(model, resolveProject(options), resolveLocation(options), options?.headers);
|
||||
let params = buildParams(model, context, options);
|
||||
const nextParams = await options?.onPayload?.(params, model);
|
||||
if (nextParams !== undefined) {
|
||||
@@ -341,6 +343,31 @@ function createClient(
|
||||
});
|
||||
}
|
||||
|
||||
function createClientWithApiKey(
|
||||
model: Model<"google-vertex">,
|
||||
apiKey: string,
|
||||
optionsHeaders?: Record<string, string>,
|
||||
): GoogleGenAI {
|
||||
const httpOptions: { headers?: Record<string, string> } = {};
|
||||
|
||||
if (model.headers || optionsHeaders) {
|
||||
httpOptions.headers = { ...model.headers, ...optionsHeaders };
|
||||
}
|
||||
|
||||
const hasHttpOptions = Object.values(httpOptions).some(Boolean);
|
||||
|
||||
return new GoogleGenAI({
|
||||
vertexai: true,
|
||||
apiKey,
|
||||
apiVersion: API_VERSION,
|
||||
httpOptions: hasHttpOptions ? httpOptions : undefined,
|
||||
});
|
||||
}
|
||||
|
||||
function resolveApiKey(options?: GoogleVertexOptions): string | undefined {
|
||||
return options?.apiKey || process.env.GOOGLE_CLOUD_API_KEY;
|
||||
}
|
||||
|
||||
function resolveProject(options?: GoogleVertexOptions): string {
|
||||
const project = options?.project || process.env.GOOGLE_CLOUD_PROJECT || process.env.GCLOUD_PROJECT;
|
||||
if (!project) {
|
||||
|
||||
@@ -380,6 +380,7 @@ describe("Generate E2E Tests", () => {
|
||||
describe("Google Vertex Provider (gemini-3-flash-preview)", () => {
|
||||
const vertexProject = process.env.GOOGLE_CLOUD_PROJECT || process.env.GCLOUD_PROJECT;
|
||||
const vertexLocation = process.env.GOOGLE_CLOUD_LOCATION;
|
||||
const vertexApiKey = process.env.GOOGLE_CLOUD_API_KEY;
|
||||
const isVertexConfigured = Boolean(vertexProject && vertexLocation);
|
||||
const vertexOptions = { project: vertexProject, location: vertexLocation } as const;
|
||||
const llm = getModel("google-vertex", "gemini-3-flash-preview");
|
||||
@@ -388,6 +389,10 @@ describe("Generate E2E Tests", () => {
|
||||
await basicTextGeneration(llm, vertexOptions);
|
||||
});
|
||||
|
||||
it.skipIf(!vertexApiKey)("should complete basic text generation with Vertex API key", { retry: 3 }, async () => {
|
||||
await basicTextGeneration(llm, { apiKey: vertexApiKey! });
|
||||
});
|
||||
|
||||
it.skipIf(!isVertexConfigured)("should handle tool calling", { retry: 3 }, async () => {
|
||||
await handleToolCall(llm, vertexOptions);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user