Feat/add.azure.and.other.providers (#607)
* fix: claude-4 not having the right max_tokens * feat: add bedrock support * chore: fix package-lock.json * fix: rename baseUrl to baseURL * feat: add azure support * fix: final touches of azure integration * feat: add google vertex provider * chore: fix tests and refactor task-manager.test.js * chore: move task 92 to 94
This commit is contained in:
150
src/ai-providers/google-vertex.js
Normal file
150
src/ai-providers/google-vertex.js
Normal file
@@ -0,0 +1,150 @@
|
||||
/**
|
||||
* google-vertex.js
|
||||
* AI provider implementation for Google Vertex AI models using Vercel AI SDK.
|
||||
*/
|
||||
|
||||
import { createVertex } from '@ai-sdk/google-vertex';
|
||||
import { BaseAIProvider } from './base-provider.js';
|
||||
import { resolveEnvVariable } from '../../scripts/modules/utils.js';
|
||||
import { log } from '../../scripts/modules/utils.js';
|
||||
|
||||
// Vertex-specific error classes
|
||||
class VertexAuthError extends Error {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
this.name = 'VertexAuthError';
|
||||
this.code = 'vertex_auth_error';
|
||||
}
|
||||
}
|
||||
|
||||
class VertexConfigError extends Error {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
this.name = 'VertexConfigError';
|
||||
this.code = 'vertex_config_error';
|
||||
}
|
||||
}
|
||||
|
||||
class VertexApiError extends Error {
|
||||
constructor(message, statusCode) {
|
||||
super(message);
|
||||
this.name = 'VertexApiError';
|
||||
this.code = 'vertex_api_error';
|
||||
this.statusCode = statusCode;
|
||||
}
|
||||
}
|
||||
|
||||
export class VertexAIProvider extends BaseAIProvider {
|
||||
constructor() {
|
||||
super();
|
||||
this.name = 'Google Vertex AI';
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates Vertex AI-specific authentication parameters
|
||||
* @param {object} params - Parameters to validate
|
||||
* @throws {Error} If required parameters are missing
|
||||
*/
|
||||
validateAuth(params) {
|
||||
const { apiKey, projectId, location, credentials } = params;
|
||||
|
||||
// Check for API key OR service account credentials
|
||||
if (!apiKey && !credentials) {
|
||||
throw new VertexAuthError(
|
||||
'Either Google API key (GOOGLE_API_KEY) or service account credentials (GOOGLE_APPLICATION_CREDENTIALS) is required for Vertex AI'
|
||||
);
|
||||
}
|
||||
|
||||
// Project ID is required for Vertex AI
|
||||
if (!projectId) {
|
||||
throw new VertexConfigError(
|
||||
'Google Cloud project ID is required for Vertex AI. Set VERTEX_PROJECT_ID environment variable.'
|
||||
);
|
||||
}
|
||||
|
||||
// Location is required for Vertex AI
|
||||
if (!location) {
|
||||
throw new VertexConfigError(
|
||||
'Google Cloud location is required for Vertex AI. Set VERTEX_LOCATION environment variable (e.g., "us-central1").'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns a Google Vertex AI client instance.
|
||||
* @param {object} params - Parameters for client initialization
|
||||
* @param {string} [params.apiKey] - Google API key
|
||||
* @param {string} params.projectId - Google Cloud project ID
|
||||
* @param {string} params.location - Google Cloud location (e.g., "us-central1")
|
||||
* @param {object} [params.credentials] - Service account credentials object
|
||||
* @param {string} [params.baseURL] - Optional custom API endpoint
|
||||
* @returns {Function} Google Vertex AI client function
|
||||
* @throws {Error} If required parameters are missing or initialization fails
|
||||
*/
|
||||
getClient(params) {
|
||||
try {
|
||||
// Validate required parameters
|
||||
this.validateAuth(params);
|
||||
|
||||
const { apiKey, projectId, location, credentials, baseURL } = params;
|
||||
|
||||
// Configure auth options - either API key or service account
|
||||
const authOptions = {};
|
||||
if (apiKey) {
|
||||
authOptions.apiKey = apiKey;
|
||||
} else if (credentials) {
|
||||
authOptions.googleAuthOptions = credentials;
|
||||
}
|
||||
|
||||
// Return Vertex AI client
|
||||
return createVertex({
|
||||
...authOptions,
|
||||
projectId,
|
||||
location,
|
||||
...(baseURL && { baseURL })
|
||||
});
|
||||
} catch (error) {
|
||||
this.handleError('client initialization', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle errors from Vertex AI
|
||||
* @param {string} operation - Description of the operation that failed
|
||||
* @param {Error} error - The error object
|
||||
* @throws {Error} Rethrows the error with additional context
|
||||
*/
|
||||
handleError(operation, error) {
|
||||
log('error', `Vertex AI ${operation} error:`, error);
|
||||
|
||||
// Handle known error types
|
||||
if (
|
||||
error.name === 'VertexAuthError' ||
|
||||
error.name === 'VertexConfigError' ||
|
||||
error.name === 'VertexApiError'
|
||||
) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
// Handle network/API errors
|
||||
if (error.response) {
|
||||
const statusCode = error.response.status;
|
||||
const errorMessage = error.response.data?.error?.message || error.message;
|
||||
|
||||
// Categorize by status code
|
||||
if (statusCode === 401 || statusCode === 403) {
|
||||
throw new VertexAuthError(`Authentication failed: ${errorMessage}`);
|
||||
} else if (statusCode === 400) {
|
||||
throw new VertexConfigError(`Invalid request: ${errorMessage}`);
|
||||
} else {
|
||||
throw new VertexApiError(
|
||||
`API error (${statusCode}): ${errorMessage}`,
|
||||
statusCode
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Generic error handling
|
||||
throw new Error(`Vertex AI ${operation} failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user