@juspay/neurolink 10.12.9 → 11.1.0
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 +32 -0
- package/dist/browser/neurolink.min.js +504 -506
- package/dist/cli/commands/setup.d.ts +20 -1
- package/dist/cli/commands/setup.js +160 -36
- package/dist/cli/factories/commandFactory.d.ts +1157 -1
- package/dist/cli/factories/commandFactory.js +20 -53
- package/dist/core/baseProvider.js +3 -3
- package/dist/core/dynamicModels.d.ts +1 -1
- package/dist/core/dynamicModels.js +1 -23
- package/dist/core/modelConfiguration.d.ts +1 -70
- package/dist/core/modelConfiguration.js +0 -303
- package/dist/core/modules/GenerationHandler.js +2 -2
- package/dist/core/modules/structuredOutputPolicy.d.ts +2 -2
- package/dist/core/modules/structuredOutputPolicy.js +2 -2
- package/dist/factories/providerDescriptors.d.ts +18 -0
- package/dist/factories/providerDescriptors.js +536 -0
- package/dist/factories/providerFactory.d.ts +28 -2
- package/dist/factories/providerFactory.js +53 -42
- package/dist/factories/providerRegistry.js +33 -32
- package/dist/index.d.ts +10 -1
- package/dist/index.js +13 -3
- package/dist/lib/core/baseProvider.js +3 -3
- package/dist/lib/core/dynamicModels.d.ts +1 -1
- package/dist/lib/core/dynamicModels.js +1 -23
- package/dist/lib/core/modelConfiguration.d.ts +1 -70
- package/dist/lib/core/modelConfiguration.js +0 -303
- package/dist/lib/core/modules/GenerationHandler.js +2 -2
- package/dist/lib/core/modules/structuredOutputPolicy.d.ts +2 -2
- package/dist/lib/core/modules/structuredOutputPolicy.js +2 -2
- package/dist/lib/factories/providerDescriptors.d.ts +18 -0
- package/dist/lib/factories/providerDescriptors.js +537 -0
- package/dist/lib/factories/providerFactory.d.ts +28 -2
- package/dist/lib/factories/providerFactory.js +53 -42
- package/dist/lib/factories/providerRegistry.js +33 -32
- package/dist/lib/index.d.ts +10 -1
- package/dist/lib/index.js +13 -3
- package/dist/lib/models/anthropicModels.d.ts +0 -7
- package/dist/lib/models/anthropicModels.js +0 -9
- package/dist/lib/neurolink.js +25 -37
- package/dist/lib/providers/amazonBedrock/client.js +34 -16
- package/dist/lib/providers/anthropic/client.js +39 -34
- package/dist/lib/providers/anthropic/constants.d.ts +0 -1
- package/dist/lib/providers/anthropic/constants.js +0 -2
- package/dist/lib/providers/anthropic/index.d.ts +0 -1
- package/dist/lib/providers/anthropic/index.js +0 -1
- package/dist/lib/providers/azureOpenai.js +17 -15
- package/dist/lib/providers/cloudflare.js +12 -21
- package/dist/lib/providers/cohere.js +31 -25
- package/dist/lib/providers/deepseek.js +23 -26
- package/dist/lib/providers/fireworks.js +12 -21
- package/dist/lib/providers/googleAiStudio/client.d.ts +2 -0
- package/dist/lib/providers/googleAiStudio/client.js +39 -17
- package/dist/lib/providers/googleAiStudio/index.d.ts +0 -1
- package/dist/lib/providers/googleAiStudio/index.js +0 -1
- package/dist/lib/providers/googleNativeGemini3/index.d.ts +0 -1
- package/dist/lib/providers/googleNativeGemini3/index.js +0 -1
- package/dist/lib/providers/googleVertex/client.d.ts +0 -51
- package/dist/lib/providers/googleVertex/client.js +107 -777
- package/dist/lib/providers/groq.js +19 -22
- package/dist/lib/providers/huggingFace/client.d.ts +1 -1
- package/dist/lib/providers/huggingFace/client.js +27 -25
- package/dist/lib/providers/huggingFace/index.d.ts +0 -1
- package/dist/lib/providers/huggingFace/index.js +0 -1
- package/dist/lib/providers/jina.d.ts +0 -1
- package/dist/lib/providers/jina.js +0 -1
- package/dist/lib/providers/litellm/client.js +54 -39
- package/dist/lib/providers/litellm/index.d.ts +0 -2
- package/dist/lib/providers/litellm/index.js +0 -2
- package/dist/lib/providers/llamaCpp.d.ts +1 -0
- package/dist/lib/providers/llamaCpp.js +24 -18
- package/dist/lib/providers/lmStudio.js +25 -42
- package/dist/lib/providers/mistral.js +12 -24
- package/dist/lib/providers/nvidiaNim/client.js +37 -34
- package/dist/lib/providers/nvidiaNim/index.d.ts +0 -1
- package/dist/lib/providers/nvidiaNim/index.js +0 -1
- package/dist/lib/providers/ollama/client.js +51 -58
- package/dist/lib/providers/ollama/index.d.ts +0 -1
- package/dist/lib/providers/ollama/index.js +0 -1
- package/dist/lib/providers/openAI/client.js +37 -40
- package/dist/lib/providers/openAI/index.d.ts +0 -2
- package/dist/lib/providers/openAI/index.js +0 -2
- package/dist/lib/providers/openRouter/client.js +53 -47
- package/dist/lib/providers/openRouter/utils.d.ts +0 -2
- package/dist/lib/providers/openRouter/utils.js +0 -12
- package/dist/lib/providers/openaiChatCompletionsBase.d.ts +9 -0
- package/dist/lib/providers/openaiChatCompletionsBase.js +73 -16
- package/dist/lib/providers/openaiCompatible/client.js +36 -32
- package/dist/lib/providers/perplexity.d.ts +2 -1
- package/dist/lib/providers/perplexity.js +14 -22
- package/dist/lib/providers/replicate.d.ts +0 -1
- package/dist/lib/providers/replicate.js +22 -9
- package/dist/lib/providers/togetherAi.js +12 -21
- package/dist/lib/providers/voyage.d.ts +0 -1
- package/dist/lib/providers/voyage.js +0 -1
- package/dist/lib/providers/xai.js +17 -26
- package/dist/lib/server/errors.d.ts +1 -1
- package/dist/lib/server/errors.js +2 -2
- package/dist/lib/server/index.d.ts +2 -2
- package/dist/lib/server/index.js +5 -3
- package/dist/lib/server/middleware/rateLimit.d.ts +0 -4
- package/dist/lib/server/middleware/rateLimit.js +0 -4
- package/dist/lib/types/errors.d.ts +35 -0
- package/dist/lib/types/index.d.ts +0 -1
- package/dist/lib/types/index.js +0 -1
- package/dist/lib/types/providers.d.ts +66 -11
- package/dist/lib/utils/errorClassifier.d.ts +30 -0
- package/dist/lib/utils/errorClassifier.js +94 -0
- package/dist/lib/utils/fileDetector.js +6 -43
- package/dist/lib/utils/providerConfig.d.ts +0 -8
- package/dist/lib/utils/providerConfig.js +0 -37
- package/dist/lib/utils/providerHealth.d.ts +42 -7
- package/dist/lib/utils/providerHealth.js +115 -122
- package/dist/lib/utils/providerUtils.js +21 -87
- package/dist/models/anthropicModels.d.ts +0 -7
- package/dist/models/anthropicModels.js +0 -9
- package/dist/neurolink.js +25 -37
- package/dist/providers/amazonBedrock/client.js +34 -16
- package/dist/providers/amazonSagemaker.d.ts +1 -1
- package/dist/providers/anthropic/client.js +39 -34
- package/dist/providers/anthropic/constants.d.ts +0 -1
- package/dist/providers/anthropic/constants.js +0 -2
- package/dist/providers/anthropic/index.d.ts +0 -1
- package/dist/providers/anthropic/index.js +0 -1
- package/dist/providers/azureOpenai.js +17 -15
- package/dist/providers/cloudflare.js +12 -21
- package/dist/providers/cohere.js +31 -25
- package/dist/providers/deepseek.js +23 -26
- package/dist/providers/fireworks.js +12 -21
- package/dist/providers/googleAiStudio/client.d.ts +2 -0
- package/dist/providers/googleAiStudio/client.js +39 -17
- package/dist/providers/googleAiStudio/index.d.ts +0 -1
- package/dist/providers/googleAiStudio/index.js +0 -1
- package/dist/providers/googleNativeGemini3/index.d.ts +0 -1
- package/dist/providers/googleNativeGemini3/index.js +0 -1
- package/dist/providers/googleVertex/client.d.ts +0 -51
- package/dist/providers/googleVertex/client.js +107 -777
- package/dist/providers/groq.js +19 -22
- package/dist/providers/huggingFace/client.d.ts +1 -1
- package/dist/providers/huggingFace/client.js +27 -25
- package/dist/providers/huggingFace/index.d.ts +0 -1
- package/dist/providers/huggingFace/index.js +0 -1
- package/dist/providers/jina.d.ts +0 -1
- package/dist/providers/jina.js +0 -1
- package/dist/providers/litellm/client.js +54 -39
- package/dist/providers/litellm/index.d.ts +0 -2
- package/dist/providers/litellm/index.js +0 -2
- package/dist/providers/llamaCpp.d.ts +1 -0
- package/dist/providers/llamaCpp.js +24 -18
- package/dist/providers/lmStudio.js +25 -42
- package/dist/providers/mistral.js +12 -24
- package/dist/providers/nvidiaNim/client.js +37 -34
- package/dist/providers/nvidiaNim/index.d.ts +0 -1
- package/dist/providers/nvidiaNim/index.js +0 -1
- package/dist/providers/ollama/client.js +51 -58
- package/dist/providers/ollama/index.d.ts +0 -1
- package/dist/providers/ollama/index.js +0 -1
- package/dist/providers/openAI/client.js +37 -40
- package/dist/providers/openAI/index.d.ts +0 -2
- package/dist/providers/openAI/index.js +0 -2
- package/dist/providers/openRouter/client.js +53 -47
- package/dist/providers/openRouter/utils.d.ts +0 -2
- package/dist/providers/openRouter/utils.js +0 -12
- package/dist/providers/openaiChatCompletionsBase.d.ts +9 -0
- package/dist/providers/openaiChatCompletionsBase.js +73 -16
- package/dist/providers/openaiCompatible/client.js +36 -32
- package/dist/providers/perplexity.d.ts +2 -1
- package/dist/providers/perplexity.js +14 -22
- package/dist/providers/replicate.d.ts +0 -1
- package/dist/providers/replicate.js +22 -9
- package/dist/providers/sagemaker/language-model.d.ts +2 -2
- package/dist/providers/togetherAi.js +12 -21
- package/dist/providers/voyage.d.ts +0 -1
- package/dist/providers/voyage.js +0 -1
- package/dist/providers/xai.js +17 -26
- package/dist/server/errors.d.ts +1 -1
- package/dist/server/errors.js +2 -2
- package/dist/server/index.d.ts +2 -2
- package/dist/server/index.js +5 -3
- package/dist/server/middleware/rateLimit.d.ts +0 -4
- package/dist/server/middleware/rateLimit.js +0 -4
- package/dist/types/errors.d.ts +35 -0
- package/dist/types/index.d.ts +0 -1
- package/dist/types/index.js +0 -1
- package/dist/types/providers.d.ts +66 -11
- package/dist/utils/errorClassifier.d.ts +30 -0
- package/dist/utils/errorClassifier.js +93 -0
- package/dist/utils/fileDetector.js +6 -43
- package/dist/utils/providerConfig.d.ts +0 -8
- package/dist/utils/providerConfig.js +0 -37
- package/dist/utils/providerHealth.d.ts +42 -7
- package/dist/utils/providerHealth.js +115 -122
- package/dist/utils/providerUtils.js +21 -87
- package/package.json +21 -75
- package/dist/lib/providers/anthropic/utils.d.ts +0 -7
- package/dist/lib/providers/anthropic/utils.js +0 -150
- package/dist/lib/providers/googleAiStudio/utils.d.ts +0 -2
- package/dist/lib/providers/googleAiStudio/utils.js +0 -19
- package/dist/lib/providers/googleNativeGemini3/constants.d.ts +0 -1
- package/dist/lib/providers/googleNativeGemini3/constants.js +0 -2
- package/dist/lib/providers/huggingFace/utils.d.ts +0 -2
- package/dist/lib/providers/huggingFace/utils.js +0 -8
- package/dist/lib/providers/index.d.ts +0 -33
- package/dist/lib/providers/index.js +0 -34
- package/dist/lib/providers/litellm/constants.d.ts +0 -1
- package/dist/lib/providers/litellm/constants.js +0 -3
- package/dist/lib/providers/litellm/utils.d.ts +0 -5
- package/dist/lib/providers/litellm/utils.js +0 -11
- package/dist/lib/providers/nvidiaNim/utils.d.ts +0 -9
- package/dist/lib/providers/nvidiaNim/utils.js +0 -101
- package/dist/lib/providers/ollama/utils.d.ts +0 -8
- package/dist/lib/providers/ollama/utils.js +0 -43
- package/dist/lib/providers/openAI/constants.d.ts +0 -1
- package/dist/lib/providers/openAI/constants.js +0 -3
- package/dist/lib/providers/openAI/utils.d.ts +0 -2
- package/dist/lib/providers/openAI/utils.js +0 -8
- package/dist/lib/types/universalProviderOptions.d.ts +0 -89
- package/dist/lib/types/universalProviderOptions.js +0 -55
- package/dist/providers/anthropic/utils.d.ts +0 -7
- package/dist/providers/anthropic/utils.js +0 -149
- package/dist/providers/googleAiStudio/utils.d.ts +0 -2
- package/dist/providers/googleAiStudio/utils.js +0 -18
- package/dist/providers/googleNativeGemini3/constants.d.ts +0 -1
- package/dist/providers/googleNativeGemini3/constants.js +0 -1
- package/dist/providers/huggingFace/utils.d.ts +0 -2
- package/dist/providers/huggingFace/utils.js +0 -7
- package/dist/providers/index.d.ts +0 -33
- package/dist/providers/index.js +0 -33
- package/dist/providers/litellm/constants.d.ts +0 -1
- package/dist/providers/litellm/constants.js +0 -2
- package/dist/providers/litellm/utils.d.ts +0 -5
- package/dist/providers/litellm/utils.js +0 -10
- package/dist/providers/nvidiaNim/utils.d.ts +0 -9
- package/dist/providers/nvidiaNim/utils.js +0 -100
- package/dist/providers/ollama/utils.d.ts +0 -8
- package/dist/providers/ollama/utils.js +0 -42
- package/dist/providers/openAI/constants.d.ts +0 -1
- package/dist/providers/openAI/constants.js +0 -2
- package/dist/providers/openAI/utils.d.ts +0 -2
- package/dist/providers/openAI/utils.js +0 -7
- package/dist/types/universalProviderOptions.d.ts +0 -89
- package/dist/types/universalProviderOptions.js +0 -54
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
// Native SDK imports - no more @ai-sdk/google-vertex dependency
|
|
3
3
|
import fs from "fs";
|
|
4
4
|
import path from "path";
|
|
5
|
-
import os from "os";
|
|
6
5
|
import { AIProviderName, ErrorCategory, ErrorSeverity, } from "../../constants/enums.js";
|
|
7
6
|
import { BaseProvider } from "../../core/baseProvider.js";
|
|
8
7
|
import { unwrapImagePayload } from "../../adapters/imageFormatSupport.js";
|
|
@@ -14,6 +13,7 @@ import { isSchemaComplexityError } from "../../core/modules/structuredOutputPoli
|
|
|
14
13
|
import { redactUrlForError, stringifyContentSafe, } from "../../utils/logSanitize.js";
|
|
15
14
|
import { createProxyFetch } from "../../proxy/proxyFetch.js";
|
|
16
15
|
import { AuthenticationError, InvalidModelError, NetworkError, ProviderError, RateLimitError, } from "../../types/index.js";
|
|
16
|
+
import { classifyProviderError } from "../../utils/errorClassifier.js";
|
|
17
17
|
import { ERROR_CODES, NeuroLinkError } from "../../utils/errorHandling.js";
|
|
18
18
|
import { applyVertexAnthropicCacheBreakpoints } from "../../utils/anthropicCacheBreakpoints.js";
|
|
19
19
|
import { FileDetector } from "../../utils/fileDetector.js";
|
|
@@ -368,167 +368,6 @@ const hasGoogleCredentials = () => {
|
|
|
368
368
|
(process.env.GOOGLE_AUTH_CLIENT_EMAIL &&
|
|
369
369
|
process.env.GOOGLE_AUTH_PRIVATE_KEY));
|
|
370
370
|
};
|
|
371
|
-
// Cache the runtime-created credentials file path so we don't write a new file
|
|
372
|
-
// on every settings creation (which would leak files in /tmp). The file is also
|
|
373
|
-
// cleaned up on process exit.
|
|
374
|
-
let cachedRuntimeCredentialsFile = null;
|
|
375
|
-
let credentialsCleanupRegistered = false;
|
|
376
|
-
const registerCredentialsCleanup = (filePath) => {
|
|
377
|
-
if (credentialsCleanupRegistered) {
|
|
378
|
-
return;
|
|
379
|
-
}
|
|
380
|
-
credentialsCleanupRegistered = true;
|
|
381
|
-
const cleanup = () => {
|
|
382
|
-
try {
|
|
383
|
-
if (fs.existsSync(filePath)) {
|
|
384
|
-
fs.unlinkSync(filePath);
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
catch {
|
|
388
|
-
// Ignore cleanup errors — best-effort
|
|
389
|
-
}
|
|
390
|
-
};
|
|
391
|
-
process.once("exit", cleanup);
|
|
392
|
-
process.once("SIGINT", () => {
|
|
393
|
-
cleanup();
|
|
394
|
-
process.exit(130);
|
|
395
|
-
});
|
|
396
|
-
process.once("SIGTERM", () => {
|
|
397
|
-
cleanup();
|
|
398
|
-
process.exit(143);
|
|
399
|
-
});
|
|
400
|
-
};
|
|
401
|
-
// Enhanced Vertex settings creation with authentication fallback and proxy support
|
|
402
|
-
const createVertexSettings = async (region) => {
|
|
403
|
-
const location = region || getVertexLocation();
|
|
404
|
-
const project = getVertexProjectId();
|
|
405
|
-
const baseSettings = {
|
|
406
|
-
project,
|
|
407
|
-
location,
|
|
408
|
-
fetch: createProxyFetch(),
|
|
409
|
-
};
|
|
410
|
-
// Note: Global endpoint handling is managed by the @google/genai SDK based on location parameter.
|
|
411
|
-
// Authentication is handled via GOOGLE_APPLICATION_CREDENTIALS environment variable
|
|
412
|
-
// or the temporary credentials file approach below.
|
|
413
|
-
// 🎯 OPTION 2: Create credentials file from environment variables at runtime
|
|
414
|
-
// This solves the problem where GOOGLE_APPLICATION_CREDENTIALS exists in ZSHRC locally
|
|
415
|
-
// but the file doesn't exist on production servers
|
|
416
|
-
// First, try to create credentials file from individual environment variables
|
|
417
|
-
const requiredEnvVarsForFile = {
|
|
418
|
-
type: process.env.GOOGLE_AUTH_TYPE,
|
|
419
|
-
project_id: process.env.GOOGLE_AUTH_BREEZE_PROJECT_ID,
|
|
420
|
-
private_key: process.env.GOOGLE_AUTH_PRIVATE_KEY,
|
|
421
|
-
client_email: process.env.GOOGLE_AUTH_CLIENT_EMAIL,
|
|
422
|
-
client_id: process.env.GOOGLE_AUTH_CLIENT_ID,
|
|
423
|
-
auth_uri: process.env.GOOGLE_AUTH_AUTH_URI,
|
|
424
|
-
token_uri: process.env.GOOGLE_AUTH_TOKEN_URI,
|
|
425
|
-
auth_provider_x509_cert_url: process.env.GOOGLE_AUTH_AUTH_PROVIDER_CERT_URL,
|
|
426
|
-
client_x509_cert_url: process.env.GOOGLE_AUTH_CLIENT_CERT_URL,
|
|
427
|
-
universe_domain: process.env.GOOGLE_AUTH_UNIVERSE_DOMAIN,
|
|
428
|
-
};
|
|
429
|
-
// If we have the essential fields, create a runtime credentials file
|
|
430
|
-
// (or reuse the one we already wrote earlier in this process)
|
|
431
|
-
if (requiredEnvVarsForFile.client_email &&
|
|
432
|
-
requiredEnvVarsForFile.private_key) {
|
|
433
|
-
try {
|
|
434
|
-
// Reuse cached file if it still exists on disk
|
|
435
|
-
if (cachedRuntimeCredentialsFile &&
|
|
436
|
-
fs.existsSync(cachedRuntimeCredentialsFile)) {
|
|
437
|
-
process.env.GOOGLE_APPLICATION_CREDENTIALS =
|
|
438
|
-
cachedRuntimeCredentialsFile;
|
|
439
|
-
return baseSettings;
|
|
440
|
-
}
|
|
441
|
-
// Build complete service account credentials object
|
|
442
|
-
const serviceAccountCredentials = {
|
|
443
|
-
type: requiredEnvVarsForFile.type || "service_account",
|
|
444
|
-
project_id: requiredEnvVarsForFile.project_id || getVertexProjectId(),
|
|
445
|
-
private_key: requiredEnvVarsForFile.private_key.replace(/\\n/g, "\n"),
|
|
446
|
-
client_email: requiredEnvVarsForFile.client_email,
|
|
447
|
-
client_id: requiredEnvVarsForFile.client_id || "",
|
|
448
|
-
auth_uri: requiredEnvVarsForFile.auth_uri ||
|
|
449
|
-
"https://accounts.google.com/o/oauth2/auth",
|
|
450
|
-
token_uri: requiredEnvVarsForFile.token_uri ||
|
|
451
|
-
"https://oauth2.googleapis.com/token",
|
|
452
|
-
auth_provider_x509_cert_url: requiredEnvVarsForFile.auth_provider_x509_cert_url ||
|
|
453
|
-
"https://www.googleapis.com/oauth2/v1/certs",
|
|
454
|
-
client_x509_cert_url: requiredEnvVarsForFile.client_x509_cert_url || "",
|
|
455
|
-
universe_domain: requiredEnvVarsForFile.universe_domain || "googleapis.com",
|
|
456
|
-
};
|
|
457
|
-
// Create temporary credentials file (once per process)
|
|
458
|
-
const tmpDir = os.tmpdir();
|
|
459
|
-
const credentialsFileName = `google-credentials-${Date.now()}-${Math.random().toString(36).substring(2, 11)}.json`;
|
|
460
|
-
const credentialsFilePath = path.join(tmpDir, credentialsFileName);
|
|
461
|
-
fs.writeFileSync(credentialsFilePath, JSON.stringify(serviceAccountCredentials, null, 2),
|
|
462
|
-
// Owner read/write only — credentials should not be world-readable
|
|
463
|
-
{ mode: 0o600 });
|
|
464
|
-
// Set the environment variable to point to our runtime-created file
|
|
465
|
-
process.env.GOOGLE_APPLICATION_CREDENTIALS = credentialsFilePath;
|
|
466
|
-
cachedRuntimeCredentialsFile = credentialsFilePath;
|
|
467
|
-
registerCredentialsCleanup(credentialsFilePath);
|
|
468
|
-
// Now continue with the normal flow - check if the file exists
|
|
469
|
-
const fileExists = fs.existsSync(credentialsFilePath);
|
|
470
|
-
if (fileExists) {
|
|
471
|
-
return baseSettings;
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
catch {
|
|
475
|
-
// Silent error handling for runtime credentials file creation
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
// 🎯 OPTION 1: Check for principal account authentication (Accept any valid GOOGLE_APPLICATION_CREDENTIALS file (service account OR ADC))
|
|
479
|
-
if (process.env.GOOGLE_APPLICATION_CREDENTIALS_NEUROLINK) {
|
|
480
|
-
const credentialsPath = process.env.GOOGLE_APPLICATION_CREDENTIALS_NEUROLINK;
|
|
481
|
-
// Check if the credentials file exists
|
|
482
|
-
let fileExists = false;
|
|
483
|
-
try {
|
|
484
|
-
fileExists = fs.existsSync(credentialsPath);
|
|
485
|
-
}
|
|
486
|
-
catch {
|
|
487
|
-
// fileExists remains false
|
|
488
|
-
}
|
|
489
|
-
if (fileExists) {
|
|
490
|
-
return baseSettings;
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
else {
|
|
494
|
-
if (process.env.GOOGLE_APPLICATION_CREDENTIALS) {
|
|
495
|
-
const credentialsPath = process.env.GOOGLE_APPLICATION_CREDENTIALS;
|
|
496
|
-
// Check if the credentials file exists
|
|
497
|
-
let fileExists = false;
|
|
498
|
-
try {
|
|
499
|
-
fileExists = fs.existsSync(credentialsPath);
|
|
500
|
-
}
|
|
501
|
-
catch {
|
|
502
|
-
// fileExists remains false
|
|
503
|
-
}
|
|
504
|
-
if (fileExists) {
|
|
505
|
-
return baseSettings;
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
// Log warning if no valid authentication is available
|
|
510
|
-
// Note: Authentication is handled via GOOGLE_APPLICATION_CREDENTIALS environment variable
|
|
511
|
-
// or the temporary credentials file approach (OPTION 2 above).
|
|
512
|
-
logger.warn("No valid authentication found for Google Vertex AI", {
|
|
513
|
-
authMethod: "none",
|
|
514
|
-
authenticationAttempts: {
|
|
515
|
-
principalAccountFile: {
|
|
516
|
-
envVarSet: !!process.env.GOOGLE_APPLICATION_CREDENTIALS,
|
|
517
|
-
filePath: process.env.GOOGLE_APPLICATION_CREDENTIALS || "NOT_SET",
|
|
518
|
-
fileExists: false, // We already checked above
|
|
519
|
-
},
|
|
520
|
-
explicitCredentials: {
|
|
521
|
-
hasClientEmail: !!process.env.GOOGLE_AUTH_CLIENT_EMAIL,
|
|
522
|
-
hasPrivateKey: !!process.env.GOOGLE_AUTH_PRIVATE_KEY,
|
|
523
|
-
},
|
|
524
|
-
},
|
|
525
|
-
troubleshooting: [
|
|
526
|
-
"1. Ensure GOOGLE_APPLICATION_CREDENTIALS points to an existing file, OR",
|
|
527
|
-
"2. Set individual environment variables: GOOGLE_AUTH_CLIENT_EMAIL and GOOGLE_AUTH_PRIVATE_KEY",
|
|
528
|
-
],
|
|
529
|
-
});
|
|
530
|
-
return baseSettings;
|
|
531
|
-
};
|
|
532
371
|
// Create Anthropic-specific Vertex settings for native @anthropic-ai/vertex-sdk
|
|
533
372
|
const createVertexAnthropicSettings = async (region, timeoutMs) => {
|
|
534
373
|
const location = region || getVertexLocation();
|
|
@@ -805,209 +644,6 @@ export class GoogleVertexProvider extends BaseProvider {
|
|
|
805
644
|
context: { provider: this.providerName, model: this.modelName },
|
|
806
645
|
});
|
|
807
646
|
}
|
|
808
|
-
/**
|
|
809
|
-
* Initialize model creation tracking
|
|
810
|
-
*/
|
|
811
|
-
initializeModelCreationLogging() {
|
|
812
|
-
const modelCreationId = `vertex-model-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;
|
|
813
|
-
const modelCreationStartTime = Date.now();
|
|
814
|
-
const modelCreationHrTimeStart = process.hrtime.bigint();
|
|
815
|
-
const modelName = this.modelName || getDefaultVertexModel();
|
|
816
|
-
return {
|
|
817
|
-
modelCreationId,
|
|
818
|
-
modelCreationStartTime,
|
|
819
|
-
modelCreationHrTimeStart,
|
|
820
|
-
modelName,
|
|
821
|
-
};
|
|
822
|
-
}
|
|
823
|
-
/**
|
|
824
|
-
* Check if model is Anthropic-based and attempt creation
|
|
825
|
-
*/
|
|
826
|
-
async attemptAnthropicModelCreation(modelName, modelCreationId, modelCreationStartTime, modelCreationHrTimeStart) {
|
|
827
|
-
const isAnthropic = isAnthropicModel(modelName);
|
|
828
|
-
if (!isAnthropic) {
|
|
829
|
-
return null;
|
|
830
|
-
}
|
|
831
|
-
logger.debug("Creating Anthropic model using vertexAnthropic provider", {
|
|
832
|
-
modelName,
|
|
833
|
-
});
|
|
834
|
-
if (!hasAnthropicSupport()) {
|
|
835
|
-
logger.warn(`[GoogleVertexProvider] Anthropic support not available, falling back to Google model`);
|
|
836
|
-
return null;
|
|
837
|
-
}
|
|
838
|
-
try {
|
|
839
|
-
const anthropicModel = await this.createAnthropicModel(modelName);
|
|
840
|
-
if (anthropicModel) {
|
|
841
|
-
return anthropicModel;
|
|
842
|
-
}
|
|
843
|
-
// Anthropic model creation returned null, falling back to Google model
|
|
844
|
-
}
|
|
845
|
-
catch (error) {
|
|
846
|
-
logger.error(`[GoogleVertexProvider] ❌ LOG_POINT_V006_ANTHROPIC_MODEL_ERROR`, {
|
|
847
|
-
logPoint: "V006_ANTHROPIC_MODEL_ERROR",
|
|
848
|
-
modelCreationId,
|
|
849
|
-
timestamp: new Date().toISOString(),
|
|
850
|
-
elapsedMs: Date.now() - modelCreationStartTime,
|
|
851
|
-
elapsedNs: (process.hrtime.bigint() - modelCreationHrTimeStart).toString(),
|
|
852
|
-
modelName,
|
|
853
|
-
error: error instanceof Error ? error.message : String(error),
|
|
854
|
-
errorName: error instanceof Error ? error.name : "UnknownError",
|
|
855
|
-
errorStack: error instanceof Error ? error.stack : undefined,
|
|
856
|
-
fallbackToGoogle: true,
|
|
857
|
-
message: "Anthropic model creation failed - falling back to Google model",
|
|
858
|
-
});
|
|
859
|
-
}
|
|
860
|
-
// Fall back to regular model if Anthropic not available
|
|
861
|
-
logger.warn(`Anthropic model ${modelName} requested but not available, falling back to Google model`);
|
|
862
|
-
return null;
|
|
863
|
-
}
|
|
864
|
-
/**
|
|
865
|
-
* Create Google Vertex model with comprehensive logging and error handling
|
|
866
|
-
*/
|
|
867
|
-
async createGoogleVertexModel(modelName, modelCreationId, modelCreationStartTime, modelCreationHrTimeStart) {
|
|
868
|
-
logger.debug("Creating Google Vertex model", {
|
|
869
|
-
modelName,
|
|
870
|
-
project: this.projectId,
|
|
871
|
-
location: this.location,
|
|
872
|
-
});
|
|
873
|
-
const vertexSettingsStartTime = process.hrtime.bigint();
|
|
874
|
-
logger.debug(`[GoogleVertexProvider] ⚙️ LOG_POINT_V008_VERTEX_SETTINGS_START`, {
|
|
875
|
-
logPoint: "V008_VERTEX_SETTINGS_START",
|
|
876
|
-
modelCreationId,
|
|
877
|
-
timestamp: new Date().toISOString(),
|
|
878
|
-
elapsedMs: Date.now() - modelCreationStartTime,
|
|
879
|
-
elapsedNs: (process.hrtime.bigint() - modelCreationHrTimeStart).toString(),
|
|
880
|
-
vertexSettingsStartTimeNs: vertexSettingsStartTime.toString(),
|
|
881
|
-
// Network configuration analysis
|
|
882
|
-
networkConfig: {
|
|
883
|
-
projectId: this.projectId,
|
|
884
|
-
location: this.location,
|
|
885
|
-
expectedEndpoint: `https://${this.location}-aiplatform.googleapis.com`,
|
|
886
|
-
httpProxy: process.env.HTTP_PROXY || process.env.http_proxy,
|
|
887
|
-
httpsProxy: process.env.HTTPS_PROXY || process.env.https_proxy,
|
|
888
|
-
noProxy: process.env.NO_PROXY || process.env.no_proxy,
|
|
889
|
-
proxyConfigured: !!(process.env.HTTP_PROXY ||
|
|
890
|
-
process.env.HTTPS_PROXY ||
|
|
891
|
-
process.env.http_proxy ||
|
|
892
|
-
process.env.https_proxy),
|
|
893
|
-
},
|
|
894
|
-
message: "Starting Vertex settings creation with network configuration analysis",
|
|
895
|
-
});
|
|
896
|
-
try {
|
|
897
|
-
const vertexSettings = await createVertexSettings(this.location);
|
|
898
|
-
const vertexSettingsEndTime = process.hrtime.bigint();
|
|
899
|
-
const vertexSettingsDurationNs = vertexSettingsEndTime - vertexSettingsStartTime;
|
|
900
|
-
logger.debug(`[GoogleVertexProvider] ✅ LOG_POINT_V009_VERTEX_SETTINGS_SUCCESS`, {
|
|
901
|
-
logPoint: "V009_VERTEX_SETTINGS_SUCCESS",
|
|
902
|
-
modelCreationId,
|
|
903
|
-
timestamp: new Date().toISOString(),
|
|
904
|
-
elapsedMs: Date.now() - modelCreationStartTime,
|
|
905
|
-
elapsedNs: (process.hrtime.bigint() - modelCreationHrTimeStart).toString(),
|
|
906
|
-
vertexSettingsDurationNs: vertexSettingsDurationNs.toString(),
|
|
907
|
-
vertexSettingsDurationMs: Number(vertexSettingsDurationNs) / 1000000,
|
|
908
|
-
// Settings analysis
|
|
909
|
-
vertexSettingsAnalysis: {
|
|
910
|
-
hasSettings: !!vertexSettings,
|
|
911
|
-
settingsType: typeof vertexSettings,
|
|
912
|
-
settingsKeys: vertexSettings ? Object.keys(vertexSettings) : [],
|
|
913
|
-
projectId: vertexSettings?.project,
|
|
914
|
-
location: vertexSettings?.location,
|
|
915
|
-
hasFetch: !!vertexSettings?.fetch,
|
|
916
|
-
settingsSize: vertexSettings
|
|
917
|
-
? JSON.stringify(vertexSettings).length
|
|
918
|
-
: 0,
|
|
919
|
-
},
|
|
920
|
-
message: "Vertex settings created successfully",
|
|
921
|
-
});
|
|
922
|
-
return await this.createVertexInstance(vertexSettings, modelName, modelCreationId, modelCreationStartTime, modelCreationHrTimeStart);
|
|
923
|
-
}
|
|
924
|
-
catch (error) {
|
|
925
|
-
const vertexSettingsErrorTime = process.hrtime.bigint();
|
|
926
|
-
const vertexSettingsDurationNs = vertexSettingsErrorTime - vertexSettingsStartTime;
|
|
927
|
-
const totalErrorDurationNs = vertexSettingsErrorTime - modelCreationHrTimeStart;
|
|
928
|
-
logger.error(`[GoogleVertexProvider] ❌ LOG_POINT_V014_VERTEX_SETTINGS_ERROR`, {
|
|
929
|
-
logPoint: "V014_VERTEX_SETTINGS_ERROR",
|
|
930
|
-
modelCreationId,
|
|
931
|
-
timestamp: new Date().toISOString(),
|
|
932
|
-
totalElapsedMs: Date.now() - modelCreationStartTime,
|
|
933
|
-
totalElapsedNs: totalErrorDurationNs.toString(),
|
|
934
|
-
totalErrorDurationMs: Number(totalErrorDurationNs) / 1000000,
|
|
935
|
-
vertexSettingsDurationNs: vertexSettingsDurationNs.toString(),
|
|
936
|
-
vertexSettingsDurationMs: Number(vertexSettingsDurationNs) / 1000000,
|
|
937
|
-
// Comprehensive error analysis
|
|
938
|
-
error: error instanceof Error ? error.message : String(error),
|
|
939
|
-
errorName: error instanceof Error ? error.name : "UnknownError",
|
|
940
|
-
errorStack: error instanceof Error ? error.stack : undefined,
|
|
941
|
-
// Network diagnostic information
|
|
942
|
-
networkDiagnostics: {
|
|
943
|
-
errorCode: error?.code || "UNKNOWN",
|
|
944
|
-
errorErrno: error?.errno || "UNKNOWN",
|
|
945
|
-
errorAddress: error?.address || "UNKNOWN",
|
|
946
|
-
errorPort: error?.port || "UNKNOWN",
|
|
947
|
-
errorSyscall: error?.syscall || "UNKNOWN",
|
|
948
|
-
errorHostname: error?.hostname || "UNKNOWN",
|
|
949
|
-
isTimeoutError: error instanceof Error &&
|
|
950
|
-
(error.message.includes("timeout") ||
|
|
951
|
-
error.message.includes("ETIMEDOUT")),
|
|
952
|
-
isNetworkError: error instanceof Error &&
|
|
953
|
-
(error.message.includes("ENOTFOUND") ||
|
|
954
|
-
error.message.includes("ECONNREFUSED") ||
|
|
955
|
-
error.message.includes("ETIMEDOUT")),
|
|
956
|
-
isAuthError: error instanceof Error &&
|
|
957
|
-
(error.message.includes("PERMISSION_DENIED") ||
|
|
958
|
-
error.message.includes("401") ||
|
|
959
|
-
error.message.includes("403")),
|
|
960
|
-
infrastructureIssue: error instanceof Error &&
|
|
961
|
-
error.message.includes("ETIMEDOUT") &&
|
|
962
|
-
error.message.includes("aiplatform.googleapis.com"),
|
|
963
|
-
},
|
|
964
|
-
// Environment at error time
|
|
965
|
-
errorEnvironment: {
|
|
966
|
-
httpProxy: process.env.HTTP_PROXY || process.env.http_proxy,
|
|
967
|
-
httpsProxy: process.env.HTTPS_PROXY || process.env.https_proxy,
|
|
968
|
-
googleAppCreds: process.env.GOOGLE_APPLICATION_CREDENTIALS_NEUROLINK ||
|
|
969
|
-
process.env.GOOGLE_APPLICATION_CREDENTIALS ||
|
|
970
|
-
"NOT_SET",
|
|
971
|
-
hasGoogleServiceKey: !!process.env.GOOGLE_SERVICE_ACCOUNT_KEY,
|
|
972
|
-
nodeVersion: process.version,
|
|
973
|
-
memoryUsage: process.memoryUsage(),
|
|
974
|
-
uptime: process.uptime(),
|
|
975
|
-
},
|
|
976
|
-
message: "Vertex settings creation failed - critical network/authentication error",
|
|
977
|
-
});
|
|
978
|
-
throw error;
|
|
979
|
-
}
|
|
980
|
-
}
|
|
981
|
-
/**
|
|
982
|
-
* @deprecated This method is no longer used. All models now use native SDKs.
|
|
983
|
-
*/
|
|
984
|
-
async createVertexInstance(_vertexSettings, _modelName, _modelCreationId, _modelCreationStartTime, _modelCreationHrTimeStart) {
|
|
985
|
-
// This method is dead code - all models now route to native SDK methods.
|
|
986
|
-
throw new NeuroLinkError({
|
|
987
|
-
code: ERROR_CODES.INVALID_CONFIGURATION,
|
|
988
|
-
message: "createVertexInstance is deprecated. Use executeNativeGemini3Stream/Generate or executeNativeAnthropicStream/Generate instead.",
|
|
989
|
-
category: ErrorCategory.CONFIGURATION,
|
|
990
|
-
severity: ErrorSeverity.CRITICAL,
|
|
991
|
-
retriable: false,
|
|
992
|
-
context: { provider: this.providerName },
|
|
993
|
-
});
|
|
994
|
-
}
|
|
995
|
-
/**
|
|
996
|
-
* Gets the appropriate model instance (Google or Anthropic)
|
|
997
|
-
* Uses dual provider architecture for proper model routing
|
|
998
|
-
* Creates fresh instances for each request to ensure proper authentication
|
|
999
|
-
*/
|
|
1000
|
-
async getModel() {
|
|
1001
|
-
// Initialize logging and setup
|
|
1002
|
-
const { modelCreationId, modelCreationStartTime, modelCreationHrTimeStart, modelName, } = this.initializeModelCreationLogging();
|
|
1003
|
-
// Check if this is an Anthropic model and attempt creation
|
|
1004
|
-
const anthropicModel = await this.attemptAnthropicModelCreation(modelName, modelCreationId, modelCreationStartTime, modelCreationHrTimeStart);
|
|
1005
|
-
if (anthropicModel) {
|
|
1006
|
-
return anthropicModel;
|
|
1007
|
-
}
|
|
1008
|
-
// Fall back to Google Vertex model creation
|
|
1009
|
-
return await this.createGoogleVertexModel(modelName, modelCreationId, modelCreationStartTime, modelCreationHrTimeStart);
|
|
1010
|
-
}
|
|
1011
647
|
// executeGenerate removed - BaseProvider handles all generation with tools
|
|
1012
648
|
/**
|
|
1013
649
|
* Validate stream options
|
|
@@ -6463,110 +6099,117 @@ export class GoogleVertexProvider extends BaseProvider {
|
|
|
6463
6099
|
}
|
|
6464
6100
|
formatProviderError(error) {
|
|
6465
6101
|
const errorRecord = error;
|
|
6466
|
-
if (typeof errorRecord?.name === "string" &&
|
|
6467
|
-
errorRecord.name === "TimeoutError") {
|
|
6468
|
-
return new NetworkError(`Google Vertex AI request timed out. Consider increasing timeout or using a lighter model.`, this.providerName);
|
|
6469
|
-
}
|
|
6470
|
-
const message = typeof errorRecord?.message === "string"
|
|
6471
|
-
? errorRecord.message
|
|
6472
|
-
: "Unknown error occurred";
|
|
6473
6102
|
const statusCode = typeof errorRecord?.status === "number"
|
|
6474
6103
|
? errorRecord.status
|
|
6475
6104
|
: typeof errorRecord?.statusCode === "number"
|
|
6476
6105
|
? errorRecord.statusCode
|
|
6477
6106
|
: undefined;
|
|
6478
|
-
|
|
6479
|
-
|
|
6480
|
-
|
|
6481
|
-
|
|
6482
|
-
|
|
6483
|
-
|
|
6484
|
-
|
|
6485
|
-
|
|
6486
|
-
|
|
6487
|
-
|
|
6488
|
-
|
|
6489
|
-
|
|
6490
|
-
|
|
6491
|
-
|
|
6492
|
-
|
|
6493
|
-
|
|
6494
|
-
|
|
6495
|
-
|
|
6496
|
-
|
|
6497
|
-
`
|
|
6498
|
-
|
|
6499
|
-
|
|
6500
|
-
|
|
6501
|
-
|
|
6502
|
-
|
|
6503
|
-
|
|
6504
|
-
|
|
6505
|
-
|
|
6506
|
-
|
|
6507
|
-
|
|
6508
|
-
|
|
6509
|
-
|
|
6510
|
-
|
|
6511
|
-
|
|
6512
|
-
|
|
6513
|
-
|
|
6514
|
-
|
|
6515
|
-
|
|
6516
|
-
|
|
6517
|
-
|
|
6518
|
-
|
|
6519
|
-
|
|
6520
|
-
|
|
6521
|
-
|
|
6522
|
-
|
|
6523
|
-
|
|
6524
|
-
|
|
6525
|
-
|
|
6526
|
-
:
|
|
6527
|
-
|
|
6528
|
-
|
|
6529
|
-
|
|
6530
|
-
|
|
6531
|
-
|
|
6532
|
-
|
|
6533
|
-
|
|
6534
|
-
|
|
6535
|
-
|
|
6536
|
-
|
|
6537
|
-
|
|
6538
|
-
|
|
6539
|
-
|
|
6540
|
-
|
|
6541
|
-
|
|
6542
|
-
|
|
6543
|
-
|
|
6544
|
-
|
|
6545
|
-
|
|
6546
|
-
|
|
6547
|
-
|
|
6548
|
-
|
|
6549
|
-
|
|
6550
|
-
|
|
6551
|
-
|
|
6552
|
-
|
|
6553
|
-
|
|
6554
|
-
|
|
6555
|
-
|
|
6556
|
-
|
|
6557
|
-
|
|
6558
|
-
|
|
6559
|
-
|
|
6560
|
-
|
|
6561
|
-
|
|
6562
|
-
|
|
6563
|
-
|
|
6564
|
-
|
|
6565
|
-
|
|
6566
|
-
`
|
|
6567
|
-
|
|
6568
|
-
|
|
6569
|
-
|
|
6107
|
+
const rules = [
|
|
6108
|
+
{
|
|
6109
|
+
// Duck-typed on .name rather than `instanceof TimeoutError` —
|
|
6110
|
+
// Vertex's own `withTimeout` (../../utils/async/index.js) throws a
|
|
6111
|
+
// TimeoutError class distinct from the one classifyProviderError's
|
|
6112
|
+
// built-in fast path checks (../../utils/timeout.js), so that fast
|
|
6113
|
+
// path never fires for a real Vertex timeout. This rule preserves
|
|
6114
|
+
// the pre-migration duck-typed match (both classes set
|
|
6115
|
+
// `.name = "TimeoutError"`) and the original Vertex-specific
|
|
6116
|
+
// message — see task-4-report.md for the full writeup.
|
|
6117
|
+
match: (ctx) => ctx.errorName === "TimeoutError",
|
|
6118
|
+
errorClass: NetworkError,
|
|
6119
|
+
message: "Google Vertex AI request timed out. Consider increasing timeout or using a lighter model.",
|
|
6120
|
+
},
|
|
6121
|
+
{
|
|
6122
|
+
match: (ctx) => /PERMISSION_DENIED|UNAUTHENTICATED|Invalid API key/i.test(ctx.message) ||
|
|
6123
|
+
statusCode === 401 ||
|
|
6124
|
+
statusCode === 403,
|
|
6125
|
+
errorClass: AuthenticationError,
|
|
6126
|
+
message: () => `Google Vertex AI Permission Denied. Your Google Cloud credentials don't have permission to access Vertex AI. ` +
|
|
6127
|
+
`Required Steps: 1. Ensure your service account has Vertex AI User role ` +
|
|
6128
|
+
`2. Check if Vertex AI API is enabled in your project ` +
|
|
6129
|
+
`3. Verify your project ID is correct ` +
|
|
6130
|
+
`4. Confirm your location/region has Vertex AI available`,
|
|
6131
|
+
},
|
|
6132
|
+
{
|
|
6133
|
+
match: (ctx) => /NOT_FOUND|model not found|Model not found/i.test(ctx.message) ||
|
|
6134
|
+
statusCode === 404,
|
|
6135
|
+
errorClass: InvalidModelError,
|
|
6136
|
+
message: () => {
|
|
6137
|
+
const modelSuggestions = this.getModelSuggestions(this.modelName);
|
|
6138
|
+
return (`Model '${this.modelName}' is not available in region ${this.location}. ` +
|
|
6139
|
+
`Suggested alternatives: ${modelSuggestions}. ` +
|
|
6140
|
+
`Troubleshooting: 1. Check model name spelling and format ` +
|
|
6141
|
+
`2. Verify model is available in your region ` +
|
|
6142
|
+
`3. Ensure your project has access to the model ` +
|
|
6143
|
+
`4. For Claude models, enable Anthropic integration in Google Cloud Console`);
|
|
6144
|
+
},
|
|
6145
|
+
},
|
|
6146
|
+
{
|
|
6147
|
+
// Rate limit / quota / capacity errors. Anthropic-on-Vertex capacity
|
|
6148
|
+
// exhaustion surfaces as overloaded_error (HTTP 529) — same
|
|
6149
|
+
// operational meaning as a 429, so classify it here instead of the
|
|
6150
|
+
// generic 5xx branch below.
|
|
6151
|
+
match: (ctx) => /QUOTA_EXCEEDED|RATE_LIMIT_EXCEEDED|rate limit|429/i.test(ctx.message) ||
|
|
6152
|
+
statusCode === 429 ||
|
|
6153
|
+
statusCode === 529 ||
|
|
6154
|
+
/overloaded/i.test(ctx.message),
|
|
6155
|
+
errorClass: RateLimitError,
|
|
6156
|
+
message: (ctx) => {
|
|
6157
|
+
// Surface retry guidance when the SDK error carries it.
|
|
6158
|
+
// @google/genai ApiError nests RetryInfo inside the JSON error
|
|
6159
|
+
// body's details array, so fall back to scraping retryDelay out
|
|
6160
|
+
// of the raw message.
|
|
6161
|
+
const retryDelay = typeof errorRecord?.retryDelay === "string"
|
|
6162
|
+
? errorRecord.retryDelay
|
|
6163
|
+
: (/["']?retryDelay["']?\s*[:=]\s*["']?(\d+(?:\.\d+)?s)/.exec(ctx.message)?.[1] ?? undefined);
|
|
6164
|
+
// Prefer the per-request context the native catches attach to the
|
|
6165
|
+
// error (this.modelName can be stale when options.model overrides
|
|
6166
|
+
// the instance default). Gemini models are force-routed to the
|
|
6167
|
+
// "global" endpoint regardless of configured location — report
|
|
6168
|
+
// the region the request actually hit.
|
|
6169
|
+
const requestModel = typeof errorRecord?.requestModel === "string"
|
|
6170
|
+
? errorRecord.requestModel
|
|
6171
|
+
: this.modelName;
|
|
6172
|
+
const effectiveRegion = typeof errorRecord?.requestRegion === "string"
|
|
6173
|
+
? errorRecord.requestRegion
|
|
6174
|
+
: resolveVertexRegionForModel(requestModel, this.location);
|
|
6175
|
+
return (`Google Vertex AI rate limit / shared-capacity exhausted (429 RESOURCE_EXHAUSTED / overloaded) ` +
|
|
6176
|
+
`for model '${requestModel}' in region '${effectiveRegion}'.` +
|
|
6177
|
+
(retryDelay
|
|
6178
|
+
? ` Upstream suggests retrying after ${retryDelay}.`
|
|
6179
|
+
: "") +
|
|
6180
|
+
` Solutions: 1. Retry with backoff ` +
|
|
6181
|
+
`2. Check your Vertex AI quotas in Google Cloud Console (shared-capacity 429s can occur below quota) ` +
|
|
6182
|
+
`3. Try a different region or model ` +
|
|
6183
|
+
`4. Request provisioned throughput for sustained load`);
|
|
6184
|
+
},
|
|
6185
|
+
},
|
|
6186
|
+
{
|
|
6187
|
+
match: (ctx) => /ECONNRESET|ENOTFOUND|ETIMEDOUT|ECONNREFUSED|network|connection/i.test(ctx.message),
|
|
6188
|
+
errorClass: NetworkError,
|
|
6189
|
+
message: (ctx) => `Connection error: ${ctx.message}`,
|
|
6190
|
+
},
|
|
6191
|
+
{
|
|
6192
|
+
match: (ctx) => /500|502|503|504|server error|Internal Server Error|INTERNAL|UNAVAILABLE/i.test(ctx.message) ||
|
|
6193
|
+
(statusCode !== undefined && statusCode >= 500 && statusCode < 600),
|
|
6194
|
+
errorClass: ProviderError,
|
|
6195
|
+
message: (ctx) => `Google Vertex AI server error: ${ctx.message}. Please try again later.`,
|
|
6196
|
+
},
|
|
6197
|
+
{
|
|
6198
|
+
match: (ctx) => /INVALID_ARGUMENT/i.test(ctx.message),
|
|
6199
|
+
errorClass: ProviderError,
|
|
6200
|
+
message: (ctx) => `Google Vertex AI Invalid Request: ${ctx.message}. ` +
|
|
6201
|
+
`Check: 1. Request parameters are within model limits ` +
|
|
6202
|
+
`2. Input text is properly formatted ` +
|
|
6203
|
+
`3. Temperature and other settings are valid ` +
|
|
6204
|
+
`4. Model supports your request type`,
|
|
6205
|
+
},
|
|
6206
|
+
{
|
|
6207
|
+
match: () => true,
|
|
6208
|
+
errorClass: ProviderError,
|
|
6209
|
+
message: (ctx) => `Google Vertex AI error: ${ctx.message}`,
|
|
6210
|
+
},
|
|
6211
|
+
];
|
|
6212
|
+
return classifyProviderError(error, rules, this.providerName, this.modelName);
|
|
6570
6213
|
}
|
|
6571
6214
|
/**
|
|
6572
6215
|
* Memory-safe cache management for model configurations
|
|
@@ -6662,319 +6305,6 @@ export class GoogleVertexProvider extends BaseProvider {
|
|
|
6662
6305
|
async hasAnthropicSupport() {
|
|
6663
6306
|
return hasAnthropicSupport();
|
|
6664
6307
|
}
|
|
6665
|
-
/**
|
|
6666
|
-
* @deprecated This method is no longer used. Claude models now use native @anthropic-ai/vertex-sdk
|
|
6667
|
-
* via executeNativeAnthropicStream and executeNativeAnthropicGenerate.
|
|
6668
|
-
*/
|
|
6669
|
-
async createAnthropicModel(_modelName) {
|
|
6670
|
-
// This method is dead code - all Claude models now route to native SDK methods.
|
|
6671
|
-
// Throwing an error to catch any unexpected calls to this method.
|
|
6672
|
-
throw new NeuroLinkError({
|
|
6673
|
-
code: ERROR_CODES.INVALID_CONFIGURATION,
|
|
6674
|
-
message: "createAnthropicModel is deprecated. Use executeNativeAnthropicStream or executeNativeAnthropicGenerate instead.",
|
|
6675
|
-
category: ErrorCategory.CONFIGURATION,
|
|
6676
|
-
severity: ErrorSeverity.CRITICAL,
|
|
6677
|
-
retriable: false,
|
|
6678
|
-
context: { provider: this.providerName },
|
|
6679
|
-
});
|
|
6680
|
-
}
|
|
6681
|
-
/**
|
|
6682
|
-
* Validate Vertex AI authentication configuration
|
|
6683
|
-
*/
|
|
6684
|
-
async validateVertexAuthentication() {
|
|
6685
|
-
const result = {
|
|
6686
|
-
isValid: false,
|
|
6687
|
-
method: "none",
|
|
6688
|
-
issues: [],
|
|
6689
|
-
};
|
|
6690
|
-
try {
|
|
6691
|
-
// Check for service account file authentication (preferred)
|
|
6692
|
-
if (process.env.GOOGLE_APPLICATION_CREDENTIALS_NEUROLINK ||
|
|
6693
|
-
process.env.GOOGLE_APPLICATION_CREDENTIALS) {
|
|
6694
|
-
const credentialsPath = process.env
|
|
6695
|
-
.GOOGLE_APPLICATION_CREDENTIALS_NEUROLINK
|
|
6696
|
-
? process.env.GOOGLE_APPLICATION_CREDENTIALS_NEUROLINK
|
|
6697
|
-
: process.env.GOOGLE_APPLICATION_CREDENTIALS || "";
|
|
6698
|
-
try {
|
|
6699
|
-
if (fs.existsSync(credentialsPath)) {
|
|
6700
|
-
// Validate JSON structure
|
|
6701
|
-
const credentialsContent = fs.readFileSync(credentialsPath, "utf8");
|
|
6702
|
-
const credentials = JSON.parse(credentialsContent);
|
|
6703
|
-
if (credentials.type === "service_account" &&
|
|
6704
|
-
credentials.project_id &&
|
|
6705
|
-
credentials.client_email &&
|
|
6706
|
-
credentials.private_key) {
|
|
6707
|
-
result.isValid = true;
|
|
6708
|
-
result.method = "service_account_file";
|
|
6709
|
-
return result;
|
|
6710
|
-
}
|
|
6711
|
-
else if (credentials.client_id &&
|
|
6712
|
-
credentials.client_secret &&
|
|
6713
|
-
credentials.refresh_token &&
|
|
6714
|
-
credentials.type !== "service_account") {
|
|
6715
|
-
result.isValid = true;
|
|
6716
|
-
result.method = "application_default_credentials";
|
|
6717
|
-
return result;
|
|
6718
|
-
}
|
|
6719
|
-
else {
|
|
6720
|
-
result.issues.push("Credentials file missing required fields (not service account or ADC format)");
|
|
6721
|
-
}
|
|
6722
|
-
}
|
|
6723
|
-
else {
|
|
6724
|
-
result.issues.push(`Service account file not found: ${credentialsPath}`);
|
|
6725
|
-
}
|
|
6726
|
-
}
|
|
6727
|
-
catch (fileError) {
|
|
6728
|
-
result.issues.push(`Service account file validation failed: ${fileError}`);
|
|
6729
|
-
}
|
|
6730
|
-
}
|
|
6731
|
-
// Check for individual environment variables
|
|
6732
|
-
if (process.env.GOOGLE_AUTH_CLIENT_EMAIL &&
|
|
6733
|
-
process.env.GOOGLE_AUTH_PRIVATE_KEY) {
|
|
6734
|
-
const email = process.env.GOOGLE_AUTH_CLIENT_EMAIL;
|
|
6735
|
-
const privateKey = process.env.GOOGLE_AUTH_PRIVATE_KEY;
|
|
6736
|
-
if (email.includes("@") && privateKey.includes("BEGIN PRIVATE KEY")) {
|
|
6737
|
-
result.isValid = true;
|
|
6738
|
-
result.method = "environment_variables";
|
|
6739
|
-
return result;
|
|
6740
|
-
}
|
|
6741
|
-
else {
|
|
6742
|
-
result.issues.push("Individual credentials format validation failed");
|
|
6743
|
-
}
|
|
6744
|
-
}
|
|
6745
|
-
else {
|
|
6746
|
-
result.issues.push("Missing individual credential environment variables");
|
|
6747
|
-
}
|
|
6748
|
-
if (!result.isValid) {
|
|
6749
|
-
result.issues.push("No valid authentication method found");
|
|
6750
|
-
}
|
|
6751
|
-
}
|
|
6752
|
-
catch (error) {
|
|
6753
|
-
result.issues.push(`Authentication validation error: ${error}`);
|
|
6754
|
-
}
|
|
6755
|
-
return result;
|
|
6756
|
-
}
|
|
6757
|
-
/**
|
|
6758
|
-
* Validate Vertex AI project configuration
|
|
6759
|
-
*/
|
|
6760
|
-
async validateVertexProjectConfiguration() {
|
|
6761
|
-
const result = {
|
|
6762
|
-
isValid: false,
|
|
6763
|
-
projectId: undefined,
|
|
6764
|
-
region: undefined,
|
|
6765
|
-
issues: [],
|
|
6766
|
-
};
|
|
6767
|
-
// Check project ID
|
|
6768
|
-
const projectId = process.env.GOOGLE_VERTEX_PROJECT ||
|
|
6769
|
-
process.env.GOOGLE_CLOUD_PROJECT_ID ||
|
|
6770
|
-
process.env.GOOGLE_PROJECT_ID ||
|
|
6771
|
-
process.env.GOOGLE_CLOUD_PROJECT;
|
|
6772
|
-
if (projectId) {
|
|
6773
|
-
result.projectId = projectId;
|
|
6774
|
-
// Validate project ID format
|
|
6775
|
-
const projectIdPattern = /^[a-z][a-z0-9-]{4,28}[a-z0-9]$/;
|
|
6776
|
-
if (projectIdPattern.test(projectId)) {
|
|
6777
|
-
result.isValid = true;
|
|
6778
|
-
}
|
|
6779
|
-
else {
|
|
6780
|
-
result.issues.push(`Invalid project ID format: ${projectId}`);
|
|
6781
|
-
}
|
|
6782
|
-
}
|
|
6783
|
-
else {
|
|
6784
|
-
result.issues.push("No project ID configured");
|
|
6785
|
-
}
|
|
6786
|
-
// Check region/location
|
|
6787
|
-
const region = process.env.GOOGLE_CLOUD_LOCATION ||
|
|
6788
|
-
process.env.VERTEX_LOCATION ||
|
|
6789
|
-
process.env.GOOGLE_VERTEX_LOCATION ||
|
|
6790
|
-
"us-central1";
|
|
6791
|
-
result.region = region;
|
|
6792
|
-
// Validate region format (regional format like us-central1 or global endpoint)
|
|
6793
|
-
const regionPattern = /^([a-z]+-[a-z]+\d+|global)$/;
|
|
6794
|
-
if (!regionPattern.test(region)) {
|
|
6795
|
-
result.issues.push(`Invalid region format: ${region} (expected format: 'us-central1' or 'global')`);
|
|
6796
|
-
result.isValid = false;
|
|
6797
|
-
}
|
|
6798
|
-
return result;
|
|
6799
|
-
}
|
|
6800
|
-
/**
|
|
6801
|
-
* Check if the specified region supports Anthropic models
|
|
6802
|
-
*/
|
|
6803
|
-
async checkVertexRegionalSupport(region = "us-central1") {
|
|
6804
|
-
// Based on Google Cloud documentation, these regions support Anthropic models
|
|
6805
|
-
const supportedRegions = [
|
|
6806
|
-
// North America
|
|
6807
|
-
"us-central1",
|
|
6808
|
-
"us-east1",
|
|
6809
|
-
"us-east4",
|
|
6810
|
-
"us-east5",
|
|
6811
|
-
"us-south1",
|
|
6812
|
-
"us-west1",
|
|
6813
|
-
"us-west4",
|
|
6814
|
-
"northamerica-northeast1",
|
|
6815
|
-
"northamerica-northeast2",
|
|
6816
|
-
// Europe
|
|
6817
|
-
"europe-west1",
|
|
6818
|
-
"europe-west2",
|
|
6819
|
-
"europe-west3",
|
|
6820
|
-
"europe-west4",
|
|
6821
|
-
"europe-west6",
|
|
6822
|
-
"europe-west8",
|
|
6823
|
-
"europe-west9",
|
|
6824
|
-
"europe-north1",
|
|
6825
|
-
"europe-central2",
|
|
6826
|
-
"europe-southwest1",
|
|
6827
|
-
// Asia Pacific
|
|
6828
|
-
"asia-east1",
|
|
6829
|
-
"asia-east2",
|
|
6830
|
-
"asia-northeast1",
|
|
6831
|
-
"asia-northeast2",
|
|
6832
|
-
"asia-northeast3",
|
|
6833
|
-
"asia-south1",
|
|
6834
|
-
"asia-southeast1",
|
|
6835
|
-
"asia-southeast2",
|
|
6836
|
-
"australia-southeast1",
|
|
6837
|
-
"australia-southeast2",
|
|
6838
|
-
// Middle East & Africa
|
|
6839
|
-
"me-west1",
|
|
6840
|
-
"me-central1",
|
|
6841
|
-
"africa-south1",
|
|
6842
|
-
// South America
|
|
6843
|
-
"southamerica-east1",
|
|
6844
|
-
"southamerica-west1",
|
|
6845
|
-
];
|
|
6846
|
-
return supportedRegions.includes(region);
|
|
6847
|
-
}
|
|
6848
|
-
/**
|
|
6849
|
-
* Validate Anthropic model name format and availability
|
|
6850
|
-
*/
|
|
6851
|
-
validateAnthropicModelName(modelName) {
|
|
6852
|
-
if (!modelName || typeof modelName !== "string") {
|
|
6853
|
-
return {
|
|
6854
|
-
isValid: false,
|
|
6855
|
-
issue: "Model name is required and must be a string",
|
|
6856
|
-
};
|
|
6857
|
-
}
|
|
6858
|
-
// Check if it's a Claude model
|
|
6859
|
-
if (!modelName.toLowerCase().includes("claude")) {
|
|
6860
|
-
return {
|
|
6861
|
-
isValid: false,
|
|
6862
|
-
issue: 'Model name must be a Claude model (should contain "claude")',
|
|
6863
|
-
};
|
|
6864
|
-
}
|
|
6865
|
-
// Validate against known Claude model patterns
|
|
6866
|
-
const validPatterns = [
|
|
6867
|
-
/^claude-sonnet-4@\d{8}$/,
|
|
6868
|
-
/^claude-sonnet-4-5@\d{8}$/,
|
|
6869
|
-
/^claude-opus-4@\d{8}$/,
|
|
6870
|
-
/^claude-opus-4-1@\d{8}$/,
|
|
6871
|
-
/^claude-3-7-sonnet@\d{8}$/,
|
|
6872
|
-
/^claude-3-5-sonnet-\d{8}$/,
|
|
6873
|
-
/^claude-3-5-haiku-\d{8}$/,
|
|
6874
|
-
/^claude-3-sonnet-\d{8}$/,
|
|
6875
|
-
/^claude-3-haiku-\d{8}$/,
|
|
6876
|
-
/^claude-3-opus-\d{8}$/,
|
|
6877
|
-
];
|
|
6878
|
-
const isValidFormat = validPatterns.some((pattern) => pattern.test(modelName));
|
|
6879
|
-
if (!isValidFormat) {
|
|
6880
|
-
return {
|
|
6881
|
-
isValid: false,
|
|
6882
|
-
issue: `Model name format not recognized. Expected formats like "claude-3-5-sonnet-20241022" or "claude-sonnet-4@20250514"`,
|
|
6883
|
-
};
|
|
6884
|
-
}
|
|
6885
|
-
return { isValid: true };
|
|
6886
|
-
}
|
|
6887
|
-
/**
|
|
6888
|
-
* Analyze Anthropic model creation errors for detailed troubleshooting
|
|
6889
|
-
*/
|
|
6890
|
-
analyzeAnthropicCreationError(error, context) {
|
|
6891
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
6892
|
-
const errorName = error instanceof Error ? error.name : "UnknownError";
|
|
6893
|
-
const analysis = {
|
|
6894
|
-
error: errorMessage,
|
|
6895
|
-
errorName,
|
|
6896
|
-
errorType: "UNKNOWN",
|
|
6897
|
-
isNetworkError: false,
|
|
6898
|
-
isAuthError: false,
|
|
6899
|
-
isConfigurationError: false,
|
|
6900
|
-
isModelError: false,
|
|
6901
|
-
isRegionalError: false,
|
|
6902
|
-
specificIssue: "Unknown error occurred",
|
|
6903
|
-
errorStack: error instanceof Error ? error.stack : undefined,
|
|
6904
|
-
};
|
|
6905
|
-
// Network-related errors
|
|
6906
|
-
if (errorMessage.includes("ETIMEDOUT") ||
|
|
6907
|
-
errorMessage.includes("ECONNREFUSED") ||
|
|
6908
|
-
errorMessage.includes("ENOTFOUND") ||
|
|
6909
|
-
errorMessage.includes("timeout")) {
|
|
6910
|
-
analysis.errorType = "NETWORK";
|
|
6911
|
-
analysis.isNetworkError = true;
|
|
6912
|
-
analysis.specificIssue =
|
|
6913
|
-
"Network connectivity issue - cannot reach Google Cloud endpoints";
|
|
6914
|
-
}
|
|
6915
|
-
// Authentication errors
|
|
6916
|
-
else if (errorMessage.includes("PERMISSION_DENIED") ||
|
|
6917
|
-
errorMessage.includes("401") ||
|
|
6918
|
-
errorMessage.includes("403") ||
|
|
6919
|
-
errorMessage.includes("Unauthorized") ||
|
|
6920
|
-
errorMessage.includes("Forbidden")) {
|
|
6921
|
-
analysis.errorType = "AUTHENTICATION";
|
|
6922
|
-
analysis.isAuthError = true;
|
|
6923
|
-
analysis.specificIssue =
|
|
6924
|
-
"Authentication failed - invalid credentials or insufficient permissions";
|
|
6925
|
-
}
|
|
6926
|
-
// Model availability errors
|
|
6927
|
-
else if (errorMessage.includes("NOT_FOUND") ||
|
|
6928
|
-
errorMessage.includes("404") ||
|
|
6929
|
-
(errorMessage.includes("model") && errorMessage.includes("not available"))) {
|
|
6930
|
-
analysis.errorType = "MODEL_AVAILABILITY";
|
|
6931
|
-
analysis.isModelError = true;
|
|
6932
|
-
analysis.specificIssue = `Model "${context.modelName}" not available in region "${context.region}"`;
|
|
6933
|
-
}
|
|
6934
|
-
// Regional/quota errors
|
|
6935
|
-
else if (errorMessage.includes("QUOTA_EXCEEDED") ||
|
|
6936
|
-
errorMessage.includes("quota") ||
|
|
6937
|
-
errorMessage.includes("limit")) {
|
|
6938
|
-
analysis.errorType = "QUOTA";
|
|
6939
|
-
analysis.isRegionalError = true;
|
|
6940
|
-
analysis.specificIssue = "Quota exceeded or rate limit reached";
|
|
6941
|
-
}
|
|
6942
|
-
// Configuration errors
|
|
6943
|
-
else if (errorMessage.includes("INVALID_ARGUMENT") ||
|
|
6944
|
-
errorMessage.includes("BadRequest") ||
|
|
6945
|
-
errorMessage.includes("400")) {
|
|
6946
|
-
analysis.errorType = "CONFIGURATION";
|
|
6947
|
-
analysis.isConfigurationError = true;
|
|
6948
|
-
analysis.specificIssue = "Invalid configuration or request parameters";
|
|
6949
|
-
}
|
|
6950
|
-
return analysis;
|
|
6951
|
-
}
|
|
6952
|
-
/**
|
|
6953
|
-
* Get detailed troubleshooting steps based on error analysis
|
|
6954
|
-
*/
|
|
6955
|
-
getAnthropicTroubleshootingSteps(errorAnalysis) {
|
|
6956
|
-
const steps = [];
|
|
6957
|
-
switch (errorAnalysis.errorType) {
|
|
6958
|
-
case "NETWORK":
|
|
6959
|
-
steps.push("🌐 Network Troubleshooting:", "1. Check internet connectivity", "2. Verify proxy configuration if behind corporate firewall", "3. Ensure firewall allows HTTPS to *.googleapis.com", "4. Try different network or wait for network issues to resolve", "5. Check if using VPN that might block Google Cloud endpoints");
|
|
6960
|
-
break;
|
|
6961
|
-
case "AUTHENTICATION":
|
|
6962
|
-
steps.push("🔐 Authentication Troubleshooting:", "1. Verify GOOGLE_APPLICATION_CREDENTIALS file exists and is valid", "2. Check individual credentials: GOOGLE_AUTH_CLIENT_EMAIL, GOOGLE_AUTH_PRIVATE_KEY", '3. Ensure service account has "Vertex AI User" role', "4. Verify project ID matches the one in your credentials", "5. Enable Vertex AI API: https://console.cloud.google.com/apis/library/aiplatform.googleapis.com");
|
|
6963
|
-
break;
|
|
6964
|
-
case "MODEL_AVAILABILITY":
|
|
6965
|
-
steps.push("🤖 Model Availability Troubleshooting:", "1. Verify model name format and spelling", "2. Check if Anthropic integration is enabled in your project", "3. Enable Claude models: https://console.cloud.google.com/vertex-ai/publishers/anthropic", "4. Try a different region if current region lacks Anthropic support", "5. Accept Anthropic terms and conditions in Google Cloud Console");
|
|
6966
|
-
break;
|
|
6967
|
-
case "QUOTA":
|
|
6968
|
-
steps.push("📊 Quota Troubleshooting:", "1. Check Vertex AI quotas in Google Cloud Console", "2. Request quota increase if needed", "3. Try a different model with lower resource requirements", "4. Wait before retrying if rate limited", "5. Consider using a different region with available quota");
|
|
6969
|
-
break;
|
|
6970
|
-
case "CONFIGURATION":
|
|
6971
|
-
steps.push("⚙️ Configuration Troubleshooting:", "1. Verify all required environment variables are set", "2. Check project ID and region format", "3. Ensure model name follows correct format", "4. Verify request parameters are within model limits", "5. Verify @google-cloud/vertexai and @anthropic-ai/vertex-sdk versions");
|
|
6972
|
-
break;
|
|
6973
|
-
default:
|
|
6974
|
-
steps.push("🔧 General Troubleshooting:", "1. Verify native SDK packages are properly installed", "2. Check Google Cloud service status", "3. Verify all authentication and configuration", "4. Try with a simple Claude model like claude-3-haiku-20240307", "5. Enable debug logging with NEUROLINK_DEBUG=true");
|
|
6975
|
-
}
|
|
6976
|
-
return steps;
|
|
6977
|
-
}
|
|
6978
6308
|
/**
|
|
6979
6309
|
* Register a tool with the AI provider
|
|
6980
6310
|
* @param name The name of the tool
|