@juspay/neurolink 7.27.0 → 7.28.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 +6 -0
- package/dist/cli/commands/config.d.ts +3 -3
- package/dist/lib/mcp/toolDiscoveryService.js +1 -1
- package/dist/lib/neurolink.js +1099 -56
- package/dist/lib/providers/amazonBedrock.d.ts +2 -2
- package/dist/lib/providers/amazonBedrock.js +16 -7
- package/dist/lib/providers/googleVertex.d.ts +28 -3
- package/dist/lib/providers/googleVertex.js +1132 -84
- package/dist/lib/providers/litellm.d.ts +1 -1
- package/dist/lib/providers/litellm.js +7 -4
- package/dist/lib/providers/openaiCompatible.d.ts +1 -1
- package/dist/lib/providers/openaiCompatible.js +7 -4
- package/dist/lib/proxy/proxyFetch.js +124 -2
- package/dist/lib/utils/providerHealth.d.ts +57 -1
- package/dist/lib/utils/providerHealth.js +638 -33
- package/dist/lib/utils/transformationUtils.js +3 -3
- package/dist/mcp/toolDiscoveryService.js +1 -1
- package/dist/neurolink.js +1099 -56
- package/dist/providers/amazonBedrock.d.ts +2 -2
- package/dist/providers/amazonBedrock.js +16 -7
- package/dist/providers/googleVertex.d.ts +28 -3
- package/dist/providers/googleVertex.js +1132 -84
- package/dist/providers/litellm.d.ts +1 -1
- package/dist/providers/litellm.js +7 -4
- package/dist/providers/openaiCompatible.d.ts +1 -1
- package/dist/providers/openaiCompatible.js +7 -4
- package/dist/proxy/proxyFetch.js +124 -2
- package/dist/utils/providerHealth.d.ts +57 -1
- package/dist/utils/providerHealth.js +638 -33
- package/dist/utils/transformationUtils.js +3 -3
- package/package.json +1 -1
|
@@ -1,36 +1,29 @@
|
|
|
1
1
|
import { createVertex, } from "@ai-sdk/google-vertex";
|
|
2
|
+
import { createVertexAnthropic, } from "@ai-sdk/google-vertex/anthropic";
|
|
2
3
|
import { streamText, Output, } from "ai";
|
|
3
4
|
import { BaseProvider } from "../core/baseProvider.js";
|
|
4
5
|
import { logger } from "../utils/logger.js";
|
|
5
|
-
import { createTimeoutController, TimeoutError
|
|
6
|
+
import { createTimeoutController, TimeoutError } from "../utils/timeout.js";
|
|
6
7
|
import { DEFAULT_MAX_TOKENS, DEFAULT_MAX_STEPS } from "../core/constants.js";
|
|
7
8
|
import { ModelConfigurationManager } from "../core/modelConfiguration.js";
|
|
8
9
|
import { validateApiKey, createVertexProjectConfig, createGoogleAuthConfig, } from "../utils/providerConfig.js";
|
|
10
|
+
import fs from "fs";
|
|
11
|
+
import path from "path";
|
|
12
|
+
import os from "os";
|
|
13
|
+
import dns from "dns";
|
|
9
14
|
import { buildMessagesArray } from "../utils/messageBuilder.js";
|
|
10
15
|
import { createProxyFetch } from "../proxy/proxyFetch.js";
|
|
11
|
-
//
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
// Function to dynamically import anthropic support
|
|
15
|
-
async function getCreateVertexAnthropic() {
|
|
16
|
-
if (_anthropicImportAttempted) {
|
|
17
|
-
return _createVertexAnthropic;
|
|
18
|
-
}
|
|
19
|
-
_anthropicImportAttempted = true;
|
|
16
|
+
// Enhanced Anthropic support with direct imports
|
|
17
|
+
// Using the dual provider architecture from Vercel AI SDK
|
|
18
|
+
const hasAnthropicSupport = () => {
|
|
20
19
|
try {
|
|
21
|
-
//
|
|
22
|
-
|
|
23
|
-
const anthropicModule = (await import("@ai-sdk/google-vertex/anthropic"));
|
|
24
|
-
_createVertexAnthropic = anthropicModule.createVertexAnthropic;
|
|
25
|
-
logger.debug("[GoogleVertexAI] Anthropic module successfully loaded");
|
|
26
|
-
return _createVertexAnthropic;
|
|
20
|
+
// Verify the anthropic module is available
|
|
21
|
+
return typeof createVertexAnthropic === "function";
|
|
27
22
|
}
|
|
28
|
-
catch
|
|
29
|
-
|
|
30
|
-
logger.warn("[GoogleVertexAI] Anthropic module not available. Install @ai-sdk/google-vertex ^2.2.0 for Anthropic model support.");
|
|
31
|
-
return null;
|
|
23
|
+
catch {
|
|
24
|
+
return false;
|
|
32
25
|
}
|
|
33
|
-
}
|
|
26
|
+
};
|
|
34
27
|
// Configuration helpers - now using consolidated utility
|
|
35
28
|
const getVertexProjectId = () => {
|
|
36
29
|
return validateApiKey(createVertexProjectConfig());
|
|
@@ -53,51 +46,172 @@ const hasGoogleCredentials = () => {
|
|
|
53
46
|
process.env.GOOGLE_AUTH_PRIVATE_KEY));
|
|
54
47
|
};
|
|
55
48
|
// Enhanced Vertex settings creation with authentication fallback and proxy support
|
|
56
|
-
const createVertexSettings = () => {
|
|
49
|
+
const createVertexSettings = async () => {
|
|
57
50
|
const baseSettings = {
|
|
58
51
|
project: getVertexProjectId(),
|
|
59
52
|
location: getVertexLocation(),
|
|
60
53
|
fetch: createProxyFetch(),
|
|
61
54
|
};
|
|
62
|
-
//
|
|
55
|
+
// 🎯 OPTION 2: Create credentials file from environment variables at runtime
|
|
56
|
+
// This solves the problem where GOOGLE_APPLICATION_CREDENTIALS exists in ZSHRC locally
|
|
57
|
+
// but the file doesn't exist on production servers
|
|
58
|
+
// First, try to create credentials file from individual environment variables
|
|
59
|
+
const requiredEnvVarsForFile = {
|
|
60
|
+
type: process.env.GOOGLE_AUTH_TYPE,
|
|
61
|
+
project_id: process.env.GOOGLE_AUTH_BREEZE_PROJECT_ID,
|
|
62
|
+
private_key: process.env.GOOGLE_AUTH_PRIVATE_KEY,
|
|
63
|
+
client_email: process.env.GOOGLE_AUTH_CLIENT_EMAIL,
|
|
64
|
+
client_id: process.env.GOOGLE_AUTH_CLIENT_ID,
|
|
65
|
+
auth_uri: process.env.GOOGLE_AUTH_AUTH_URI,
|
|
66
|
+
token_uri: process.env.GOOGLE_AUTH_TOKEN_URI,
|
|
67
|
+
auth_provider_x509_cert_url: process.env.GOOGLE_AUTH_AUTH_PROVIDER_CERT_URL,
|
|
68
|
+
client_x509_cert_url: process.env.GOOGLE_AUTH_CLIENT_CERT_URL,
|
|
69
|
+
universe_domain: process.env.GOOGLE_AUTH_UNIVERSE_DOMAIN,
|
|
70
|
+
};
|
|
71
|
+
// If we have the essential fields, create a runtime credentials file
|
|
72
|
+
if (requiredEnvVarsForFile.client_email &&
|
|
73
|
+
requiredEnvVarsForFile.private_key) {
|
|
74
|
+
try {
|
|
75
|
+
// Build complete service account credentials object
|
|
76
|
+
const serviceAccountCredentials = {
|
|
77
|
+
type: requiredEnvVarsForFile.type || "service_account",
|
|
78
|
+
project_id: requiredEnvVarsForFile.project_id || getVertexProjectId(),
|
|
79
|
+
private_key: requiredEnvVarsForFile.private_key.replace(/\\n/g, "\n"),
|
|
80
|
+
client_email: requiredEnvVarsForFile.client_email,
|
|
81
|
+
client_id: requiredEnvVarsForFile.client_id || "",
|
|
82
|
+
auth_uri: requiredEnvVarsForFile.auth_uri ||
|
|
83
|
+
"https://accounts.google.com/o/oauth2/auth",
|
|
84
|
+
token_uri: requiredEnvVarsForFile.token_uri ||
|
|
85
|
+
"https://oauth2.googleapis.com/token",
|
|
86
|
+
auth_provider_x509_cert_url: requiredEnvVarsForFile.auth_provider_x509_cert_url ||
|
|
87
|
+
"https://www.googleapis.com/oauth2/v1/certs",
|
|
88
|
+
client_x509_cert_url: requiredEnvVarsForFile.client_x509_cert_url || "",
|
|
89
|
+
universe_domain: requiredEnvVarsForFile.universe_domain || "googleapis.com",
|
|
90
|
+
};
|
|
91
|
+
// Create temporary credentials file
|
|
92
|
+
const tmpDir = os.tmpdir();
|
|
93
|
+
const credentialsFileName = `google-credentials-${Date.now()}-${Math.random().toString(36).substring(2, 11)}.json`;
|
|
94
|
+
const credentialsFilePath = path.join(tmpDir, credentialsFileName);
|
|
95
|
+
fs.writeFileSync(credentialsFilePath, JSON.stringify(serviceAccountCredentials, null, 2));
|
|
96
|
+
// Set the environment variable to point to our runtime-created file
|
|
97
|
+
process.env.GOOGLE_APPLICATION_CREDENTIALS = credentialsFilePath;
|
|
98
|
+
// Now continue with the normal flow - check if the file exists
|
|
99
|
+
const fileExists = fs.existsSync(credentialsFilePath);
|
|
100
|
+
if (fileExists) {
|
|
101
|
+
return baseSettings;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
catch (_error) {
|
|
105
|
+
// Silent error handling for runtime credentials file creation
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// 🎯 OPTION 1: Check for principal account authentication (existing flow with debug logs)
|
|
63
109
|
if (process.env.GOOGLE_APPLICATION_CREDENTIALS) {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
110
|
+
const credentialsPath = process.env.GOOGLE_APPLICATION_CREDENTIALS;
|
|
111
|
+
// 🚨 CRITICAL FIX: Check if the credentials file actually exists
|
|
112
|
+
let fileExists = false;
|
|
113
|
+
try {
|
|
114
|
+
fileExists = fs.existsSync(credentialsPath);
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
fileExists = false;
|
|
118
|
+
}
|
|
119
|
+
if (fileExists) {
|
|
120
|
+
return baseSettings;
|
|
121
|
+
}
|
|
73
122
|
}
|
|
74
|
-
// Fallback to explicit credentials for development
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
123
|
+
// Fallback to explicit credentials for development and production
|
|
124
|
+
// Enhanced to check ALL required fields from the .env file configuration
|
|
125
|
+
const requiredEnvVars = {
|
|
126
|
+
type: process.env.GOOGLE_AUTH_TYPE,
|
|
127
|
+
project_id: process.env.GOOGLE_AUTH_BREEZE_PROJECT_ID,
|
|
128
|
+
private_key: process.env.GOOGLE_AUTH_PRIVATE_KEY,
|
|
129
|
+
client_email: process.env.GOOGLE_AUTH_CLIENT_EMAIL,
|
|
130
|
+
client_id: process.env.GOOGLE_AUTH_CLIENT_ID,
|
|
131
|
+
auth_uri: process.env.GOOGLE_AUTH_AUTH_URI,
|
|
132
|
+
token_uri: process.env.GOOGLE_AUTH_TOKEN_URI,
|
|
133
|
+
auth_provider_x509_cert_url: process.env.GOOGLE_AUTH_AUTH_PROVIDER_CERT_URL,
|
|
134
|
+
client_x509_cert_url: process.env.GOOGLE_AUTH_CLIENT_CERT_URL,
|
|
135
|
+
universe_domain: process.env.GOOGLE_AUTH_UNIVERSE_DOMAIN,
|
|
136
|
+
};
|
|
137
|
+
// Check if we have the minimal required fields (client_email and private_key are essential)
|
|
138
|
+
if (requiredEnvVars.client_email && requiredEnvVars.private_key) {
|
|
139
|
+
logger.debug("Using explicit service account credentials authentication", {
|
|
140
|
+
authMethod: "explicit_service_account_credentials",
|
|
141
|
+
hasType: !!requiredEnvVars.type,
|
|
142
|
+
hasProjectId: !!requiredEnvVars.project_id,
|
|
143
|
+
hasClientEmail: !!requiredEnvVars.client_email,
|
|
144
|
+
hasPrivateKey: !!requiredEnvVars.private_key,
|
|
145
|
+
hasClientId: !!requiredEnvVars.client_id,
|
|
146
|
+
hasAuthUri: !!requiredEnvVars.auth_uri,
|
|
147
|
+
hasTokenUri: !!requiredEnvVars.token_uri,
|
|
148
|
+
hasAuthProviderCertUrl: !!requiredEnvVars.auth_provider_x509_cert_url,
|
|
149
|
+
hasClientCertUrl: !!requiredEnvVars.client_x509_cert_url,
|
|
150
|
+
hasUniverseDomain: !!requiredEnvVars.universe_domain,
|
|
151
|
+
credentialsCompleteness: "using_individual_env_vars_as_fallback",
|
|
81
152
|
});
|
|
153
|
+
// Build complete service account credentials object
|
|
154
|
+
const serviceAccountCredentials = {
|
|
155
|
+
type: requiredEnvVars.type || "service_account",
|
|
156
|
+
project_id: requiredEnvVars.project_id || getVertexProjectId(),
|
|
157
|
+
private_key: requiredEnvVars.private_key.replace(/\\n/g, "\n"),
|
|
158
|
+
client_email: requiredEnvVars.client_email,
|
|
159
|
+
client_id: requiredEnvVars.client_id || "",
|
|
160
|
+
auth_uri: requiredEnvVars.auth_uri ||
|
|
161
|
+
"https://accounts.google.com/o/oauth2/auth",
|
|
162
|
+
token_uri: requiredEnvVars.token_uri || "https://oauth2.googleapis.com/token",
|
|
163
|
+
auth_provider_x509_cert_url: requiredEnvVars.auth_provider_x509_cert_url ||
|
|
164
|
+
"https://www.googleapis.com/oauth2/v1/certs",
|
|
165
|
+
client_x509_cert_url: requiredEnvVars.client_x509_cert_url || "",
|
|
166
|
+
universe_domain: requiredEnvVars.universe_domain || "googleapis.com",
|
|
167
|
+
};
|
|
82
168
|
return {
|
|
83
169
|
...baseSettings,
|
|
84
170
|
googleAuthOptions: {
|
|
85
|
-
credentials:
|
|
86
|
-
client_email: process.env.GOOGLE_AUTH_CLIENT_EMAIL,
|
|
87
|
-
private_key: process.env.GOOGLE_AUTH_PRIVATE_KEY.replace(/\\n/g, "\n"),
|
|
88
|
-
},
|
|
171
|
+
credentials: serviceAccountCredentials,
|
|
89
172
|
},
|
|
90
173
|
};
|
|
91
174
|
}
|
|
92
|
-
// Log warning if no valid authentication is available
|
|
175
|
+
// Log comprehensive warning if no valid authentication is available
|
|
93
176
|
logger.warn("No valid authentication found for Google Vertex AI", {
|
|
94
177
|
authMethod: "none",
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
178
|
+
authenticationAttempts: {
|
|
179
|
+
principalAccountFile: {
|
|
180
|
+
envVarSet: !!process.env.GOOGLE_APPLICATION_CREDENTIALS,
|
|
181
|
+
filePath: process.env.GOOGLE_APPLICATION_CREDENTIALS || "NOT_SET",
|
|
182
|
+
fileExists: false, // We already checked above
|
|
183
|
+
},
|
|
184
|
+
explicitCredentials: {
|
|
185
|
+
hasClientEmail: !!requiredEnvVars.client_email,
|
|
186
|
+
hasPrivateKey: !!requiredEnvVars.private_key,
|
|
187
|
+
hasProjectId: !!requiredEnvVars.project_id,
|
|
188
|
+
hasType: !!requiredEnvVars.type,
|
|
189
|
+
missingFields: Object.entries(requiredEnvVars)
|
|
190
|
+
.filter(([key, value]) => !value)
|
|
191
|
+
.map(([key]) => key),
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
troubleshooting: [
|
|
195
|
+
"1. Ensure GOOGLE_APPLICATION_CREDENTIALS points to an existing file, OR",
|
|
196
|
+
"2. Set individual environment variables: GOOGLE_AUTH_CLIENT_EMAIL and GOOGLE_AUTH_PRIVATE_KEY",
|
|
197
|
+
],
|
|
98
198
|
});
|
|
99
199
|
return baseSettings;
|
|
100
200
|
};
|
|
201
|
+
// Create Anthropic-specific Vertex settings with the same authentication and proxy support
|
|
202
|
+
const createVertexAnthropicSettings = async () => {
|
|
203
|
+
const baseVertexSettings = await createVertexSettings();
|
|
204
|
+
// GoogleVertexAnthropicProviderSettings extends GoogleVertexProviderSettings
|
|
205
|
+
// so we can use the same settings with proper typing
|
|
206
|
+
return {
|
|
207
|
+
project: baseVertexSettings.project,
|
|
208
|
+
location: baseVertexSettings.location,
|
|
209
|
+
fetch: baseVertexSettings.fetch,
|
|
210
|
+
...(baseVertexSettings.googleAuthOptions && {
|
|
211
|
+
googleAuthOptions: baseVertexSettings.googleAuthOptions,
|
|
212
|
+
}),
|
|
213
|
+
};
|
|
214
|
+
};
|
|
101
215
|
// Helper function to determine if a model is an Anthropic model
|
|
102
216
|
const isAnthropicModel = (modelName) => {
|
|
103
217
|
return modelName.toLowerCase().includes("claude");
|
|
@@ -127,7 +241,7 @@ export class GoogleVertexProvider extends BaseProvider {
|
|
|
127
241
|
// Memory-managed cache for maxTokens handling decisions to optimize streaming performance
|
|
128
242
|
static maxTokensCache = new Map();
|
|
129
243
|
static maxTokensCacheTime = 0;
|
|
130
|
-
constructor(modelName,
|
|
244
|
+
constructor(modelName, _providerName, sdk) {
|
|
131
245
|
super(modelName, "vertex", sdk);
|
|
132
246
|
// Validate Google Cloud credentials - now using consolidated utility
|
|
133
247
|
if (!hasGoogleCredentials()) {
|
|
@@ -159,50 +273,608 @@ export class GoogleVertexProvider extends BaseProvider {
|
|
|
159
273
|
}
|
|
160
274
|
/**
|
|
161
275
|
* Gets the appropriate model instance (Google or Anthropic)
|
|
276
|
+
* Uses dual provider architecture for proper model routing
|
|
162
277
|
* Creates fresh instances for each request to ensure proper authentication
|
|
163
278
|
*/
|
|
164
279
|
async getModel() {
|
|
280
|
+
// 🚀 EXHAUSTIVE LOGGING POINT V001: MODEL CREATION ENTRY
|
|
281
|
+
const modelCreationId = `vertex-model-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;
|
|
282
|
+
const modelCreationStartTime = Date.now();
|
|
283
|
+
const modelCreationHrTimeStart = process.hrtime.bigint();
|
|
165
284
|
const modelName = this.modelName || getDefaultVertexModel();
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
285
|
+
logger.debug(`[GoogleVertexProvider] 🏭 LOG_POINT_V001_MODEL_CREATION_START`, {
|
|
286
|
+
logPoint: "V001_MODEL_CREATION_START",
|
|
287
|
+
modelCreationId,
|
|
288
|
+
timestamp: new Date().toISOString(),
|
|
289
|
+
modelCreationStartTime,
|
|
290
|
+
modelCreationHrTimeStart: modelCreationHrTimeStart.toString(),
|
|
291
|
+
requestedModel: this.modelName,
|
|
292
|
+
resolvedModel: modelName,
|
|
293
|
+
defaultModel: getDefaultVertexModel(),
|
|
294
|
+
projectId: this.projectId,
|
|
295
|
+
location: this.location,
|
|
296
|
+
// Environment analysis for network issues
|
|
297
|
+
environmentAnalysis: {
|
|
298
|
+
httpProxy: process.env.HTTP_PROXY || process.env.http_proxy || "NOT_SET",
|
|
299
|
+
httpsProxy: process.env.HTTPS_PROXY || process.env.https_proxy || "NOT_SET",
|
|
300
|
+
googleAppCreds: process.env.GOOGLE_APPLICATION_CREDENTIALS || "NOT_SET",
|
|
301
|
+
googleServiceKey: process.env.GOOGLE_SERVICE_ACCOUNT_KEY
|
|
302
|
+
? "SET"
|
|
303
|
+
: "NOT_SET",
|
|
304
|
+
nodeVersion: process.version,
|
|
305
|
+
platform: process.platform,
|
|
306
|
+
arch: process.arch,
|
|
307
|
+
},
|
|
308
|
+
// Memory and performance baseline
|
|
309
|
+
memoryUsage: process.memoryUsage(),
|
|
310
|
+
cpuUsage: process.cpuUsage(),
|
|
311
|
+
message: "Starting model creation with comprehensive environment analysis",
|
|
312
|
+
});
|
|
313
|
+
// 🚀 EXHAUSTIVE LOGGING POINT V002: ANTHROPIC MODEL CHECK
|
|
314
|
+
const anthropicCheckStartTime = process.hrtime.bigint();
|
|
315
|
+
const isAnthropic = isAnthropicModel(modelName);
|
|
316
|
+
logger.debug(`[GoogleVertexProvider] 🤖 LOG_POINT_V002_ANTHROPIC_CHECK`, {
|
|
317
|
+
logPoint: "V002_ANTHROPIC_CHECK",
|
|
318
|
+
modelCreationId,
|
|
319
|
+
timestamp: new Date().toISOString(),
|
|
320
|
+
elapsedMs: Date.now() - modelCreationStartTime,
|
|
321
|
+
elapsedNs: (process.hrtime.bigint() - modelCreationHrTimeStart).toString(),
|
|
322
|
+
anthropicCheckStartTimeNs: anthropicCheckStartTime.toString(),
|
|
323
|
+
modelName,
|
|
324
|
+
isAnthropicModel: isAnthropic,
|
|
325
|
+
modelNameLowerCase: modelName.toLowerCase(),
|
|
326
|
+
containsClaude: modelName.toLowerCase().includes("claude"),
|
|
327
|
+
anthropicModelPatterns: ["claude"],
|
|
328
|
+
message: "Checking if model is Anthropic-based",
|
|
329
|
+
});
|
|
330
|
+
// Check if this is an Anthropic model and use appropriate provider
|
|
331
|
+
if (isAnthropic) {
|
|
332
|
+
// 🚀 EXHAUSTIVE LOGGING POINT V003: ANTHROPIC MODEL CREATION START
|
|
333
|
+
const anthropicModelStartTime = process.hrtime.bigint();
|
|
334
|
+
logger.debug(`[GoogleVertexProvider] 🧠 LOG_POINT_V003_ANTHROPIC_MODEL_START`, {
|
|
335
|
+
logPoint: "V003_ANTHROPIC_MODEL_START",
|
|
336
|
+
modelCreationId,
|
|
337
|
+
timestamp: new Date().toISOString(),
|
|
338
|
+
elapsedMs: Date.now() - modelCreationStartTime,
|
|
339
|
+
elapsedNs: (process.hrtime.bigint() - modelCreationHrTimeStart).toString(),
|
|
340
|
+
anthropicModelStartTimeNs: anthropicModelStartTime.toString(),
|
|
341
|
+
modelName,
|
|
342
|
+
hasAnthropicSupport: hasAnthropicSupport(),
|
|
343
|
+
message: "Creating Anthropic model using vertexAnthropic provider",
|
|
344
|
+
});
|
|
345
|
+
logger.debug("Creating Anthropic model using vertexAnthropic provider", {
|
|
346
|
+
modelName,
|
|
347
|
+
});
|
|
348
|
+
if (!hasAnthropicSupport()) {
|
|
349
|
+
logger.warn(`[GoogleVertexProvider] Anthropic support not available, falling back to Google model`);
|
|
350
|
+
}
|
|
351
|
+
else {
|
|
352
|
+
try {
|
|
353
|
+
const anthropicModel = await this.createAnthropicModel(modelName);
|
|
354
|
+
if (anthropicModel) {
|
|
355
|
+
const anthropicModelSuccessTime = process.hrtime.bigint();
|
|
356
|
+
const anthropicModelDurationNs = anthropicModelSuccessTime - anthropicModelStartTime;
|
|
357
|
+
logger.debug(`[GoogleVertexProvider] ✅ LOG_POINT_V004_ANTHROPIC_MODEL_SUCCESS`, {
|
|
358
|
+
logPoint: "V004_ANTHROPIC_MODEL_SUCCESS",
|
|
359
|
+
modelCreationId,
|
|
360
|
+
timestamp: new Date().toISOString(),
|
|
361
|
+
elapsedMs: Date.now() - modelCreationStartTime,
|
|
362
|
+
elapsedNs: (process.hrtime.bigint() - modelCreationHrTimeStart).toString(),
|
|
363
|
+
anthropicModelDurationNs: anthropicModelDurationNs.toString(),
|
|
364
|
+
anthropicModelDurationMs: Number(anthropicModelDurationNs) / 1000000,
|
|
365
|
+
modelName,
|
|
366
|
+
hasAnthropicModel: !!anthropicModel,
|
|
367
|
+
anthropicModelType: typeof anthropicModel,
|
|
368
|
+
memoryUsageAfterAnthropicCreation: process.memoryUsage(),
|
|
369
|
+
message: "Anthropic model created successfully via vertexAnthropic",
|
|
370
|
+
});
|
|
371
|
+
return anthropicModel;
|
|
372
|
+
}
|
|
373
|
+
// Anthropic model creation returned null
|
|
374
|
+
const anthropicModelNullTime = process.hrtime.bigint();
|
|
375
|
+
const anthropicModelDurationNs = anthropicModelNullTime - anthropicModelStartTime;
|
|
376
|
+
logger.warn(`[GoogleVertexProvider] ⚠️ LOG_POINT_V005_ANTHROPIC_MODEL_NULL`, {
|
|
377
|
+
logPoint: "V005_ANTHROPIC_MODEL_NULL",
|
|
378
|
+
modelCreationId,
|
|
379
|
+
timestamp: new Date().toISOString(),
|
|
380
|
+
elapsedMs: Date.now() - modelCreationStartTime,
|
|
381
|
+
elapsedNs: (process.hrtime.bigint() - modelCreationHrTimeStart).toString(),
|
|
382
|
+
anthropicModelDurationNs: anthropicModelDurationNs.toString(),
|
|
383
|
+
anthropicModelDurationMs: Number(anthropicModelDurationNs) / 1000000,
|
|
384
|
+
modelName,
|
|
385
|
+
hasAnthropicModel: false,
|
|
386
|
+
fallbackToGoogle: true,
|
|
387
|
+
message: "Anthropic model creation returned null - falling back to Google model",
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
catch (error) {
|
|
391
|
+
const anthropicModelErrorTime = process.hrtime.bigint();
|
|
392
|
+
const anthropicModelDurationNs = anthropicModelErrorTime - anthropicModelStartTime;
|
|
393
|
+
logger.error(`[GoogleVertexProvider] ❌ LOG_POINT_V006_ANTHROPIC_MODEL_ERROR`, {
|
|
394
|
+
logPoint: "V006_ANTHROPIC_MODEL_ERROR",
|
|
395
|
+
modelCreationId,
|
|
396
|
+
timestamp: new Date().toISOString(),
|
|
397
|
+
elapsedMs: Date.now() - modelCreationStartTime,
|
|
398
|
+
elapsedNs: (process.hrtime.bigint() - modelCreationHrTimeStart).toString(),
|
|
399
|
+
anthropicModelDurationNs: anthropicModelDurationNs.toString(),
|
|
400
|
+
anthropicModelDurationMs: Number(anthropicModelDurationNs) / 1000000,
|
|
401
|
+
modelName,
|
|
402
|
+
error: error instanceof Error ? error.message : String(error),
|
|
403
|
+
errorName: error instanceof Error ? error.name : "UnknownError",
|
|
404
|
+
errorStack: error instanceof Error ? error.stack : undefined,
|
|
405
|
+
fallbackToGoogle: true,
|
|
406
|
+
message: "Anthropic model creation failed - falling back to Google model",
|
|
407
|
+
});
|
|
408
|
+
}
|
|
172
409
|
}
|
|
173
410
|
// Fall back to regular model if Anthropic not available
|
|
174
411
|
logger.warn(`Anthropic model ${modelName} requested but not available, falling back to Google model`);
|
|
175
412
|
}
|
|
413
|
+
// 🚀 EXHAUSTIVE LOGGING POINT V007: GOOGLE VERTEX MODEL CREATION START
|
|
414
|
+
const googleModelStartTime = process.hrtime.bigint();
|
|
415
|
+
logger.debug(`[GoogleVertexProvider] 🌐 LOG_POINT_V007_GOOGLE_MODEL_START`, {
|
|
416
|
+
logPoint: "V007_GOOGLE_MODEL_START",
|
|
417
|
+
modelCreationId,
|
|
418
|
+
timestamp: new Date().toISOString(),
|
|
419
|
+
elapsedMs: Date.now() - modelCreationStartTime,
|
|
420
|
+
elapsedNs: (process.hrtime.bigint() - modelCreationHrTimeStart).toString(),
|
|
421
|
+
googleModelStartTimeNs: googleModelStartTime.toString(),
|
|
422
|
+
modelName,
|
|
423
|
+
projectId: this.projectId,
|
|
424
|
+
location: this.location,
|
|
425
|
+
reason: isAnthropic ? "ANTHROPIC_FALLBACK" : "DIRECT_GOOGLE_MODEL",
|
|
426
|
+
message: "Creating fresh Google Vertex model with current settings",
|
|
427
|
+
});
|
|
176
428
|
// Create fresh Google Vertex model with current settings
|
|
177
429
|
logger.debug("Creating Google Vertex model", {
|
|
178
430
|
modelName,
|
|
179
431
|
project: this.projectId,
|
|
180
432
|
location: this.location,
|
|
181
433
|
});
|
|
182
|
-
|
|
183
|
-
const
|
|
184
|
-
|
|
434
|
+
// 🚀 EXHAUSTIVE LOGGING POINT V008: VERTEX SETTINGS CREATION
|
|
435
|
+
const vertexSettingsStartTime = process.hrtime.bigint();
|
|
436
|
+
logger.debug(`[GoogleVertexProvider] ⚙️ LOG_POINT_V008_VERTEX_SETTINGS_START`, {
|
|
437
|
+
logPoint: "V008_VERTEX_SETTINGS_START",
|
|
438
|
+
modelCreationId,
|
|
439
|
+
timestamp: new Date().toISOString(),
|
|
440
|
+
elapsedMs: Date.now() - modelCreationStartTime,
|
|
441
|
+
elapsedNs: (process.hrtime.bigint() - modelCreationHrTimeStart).toString(),
|
|
442
|
+
vertexSettingsStartTimeNs: vertexSettingsStartTime.toString(),
|
|
443
|
+
// Network configuration analysis
|
|
444
|
+
networkConfig: {
|
|
445
|
+
projectId: this.projectId,
|
|
446
|
+
location: this.location,
|
|
447
|
+
expectedEndpoint: `https://${this.location}-aiplatform.googleapis.com`,
|
|
448
|
+
httpProxy: process.env.HTTP_PROXY || process.env.http_proxy,
|
|
449
|
+
httpsProxy: process.env.HTTPS_PROXY || process.env.https_proxy,
|
|
450
|
+
noProxy: process.env.NO_PROXY || process.env.no_proxy,
|
|
451
|
+
proxyConfigured: !!(process.env.HTTP_PROXY ||
|
|
452
|
+
process.env.HTTPS_PROXY ||
|
|
453
|
+
process.env.http_proxy ||
|
|
454
|
+
process.env.https_proxy),
|
|
455
|
+
},
|
|
456
|
+
message: "Starting Vertex settings creation with network configuration analysis",
|
|
457
|
+
});
|
|
458
|
+
try {
|
|
459
|
+
const vertexSettings = await createVertexSettings();
|
|
460
|
+
const vertexSettingsEndTime = process.hrtime.bigint();
|
|
461
|
+
const vertexSettingsDurationNs = vertexSettingsEndTime - vertexSettingsStartTime;
|
|
462
|
+
logger.debug(`[GoogleVertexProvider] ✅ LOG_POINT_V009_VERTEX_SETTINGS_SUCCESS`, {
|
|
463
|
+
logPoint: "V009_VERTEX_SETTINGS_SUCCESS",
|
|
464
|
+
modelCreationId,
|
|
465
|
+
timestamp: new Date().toISOString(),
|
|
466
|
+
elapsedMs: Date.now() - modelCreationStartTime,
|
|
467
|
+
elapsedNs: (process.hrtime.bigint() - modelCreationHrTimeStart).toString(),
|
|
468
|
+
vertexSettingsDurationNs: vertexSettingsDurationNs.toString(),
|
|
469
|
+
vertexSettingsDurationMs: Number(vertexSettingsDurationNs) / 1000000,
|
|
470
|
+
// Settings analysis
|
|
471
|
+
vertexSettingsAnalysis: {
|
|
472
|
+
hasSettings: !!vertexSettings,
|
|
473
|
+
settingsType: typeof vertexSettings,
|
|
474
|
+
settingsKeys: vertexSettings ? Object.keys(vertexSettings) : [],
|
|
475
|
+
projectId: vertexSettings?.project,
|
|
476
|
+
location: vertexSettings?.location,
|
|
477
|
+
hasFetch: !!vertexSettings?.fetch,
|
|
478
|
+
hasGoogleAuthOptions: !!vertexSettings?.googleAuthOptions,
|
|
479
|
+
settingsSize: vertexSettings
|
|
480
|
+
? JSON.stringify(vertexSettings).length
|
|
481
|
+
: 0,
|
|
482
|
+
},
|
|
483
|
+
message: "Vertex settings created successfully",
|
|
484
|
+
});
|
|
485
|
+
// 🚀 EXHAUSTIVE LOGGING POINT V010: VERTEX INSTANCE CREATION
|
|
486
|
+
const vertexInstanceStartTime = process.hrtime.bigint();
|
|
487
|
+
logger.debug(`[GoogleVertexProvider] 🏗️ LOG_POINT_V010_VERTEX_INSTANCE_START`, {
|
|
488
|
+
logPoint: "V010_VERTEX_INSTANCE_START",
|
|
489
|
+
modelCreationId,
|
|
490
|
+
timestamp: new Date().toISOString(),
|
|
491
|
+
elapsedMs: Date.now() - modelCreationStartTime,
|
|
492
|
+
elapsedNs: (process.hrtime.bigint() - modelCreationHrTimeStart).toString(),
|
|
493
|
+
vertexInstanceStartTimeNs: vertexInstanceStartTime.toString(),
|
|
494
|
+
// Pre-creation network environment
|
|
495
|
+
networkEnvironment: {
|
|
496
|
+
dnsServers: (() => {
|
|
497
|
+
try {
|
|
498
|
+
return dns.getServers ? dns.getServers() : "NOT_AVAILABLE";
|
|
499
|
+
}
|
|
500
|
+
catch {
|
|
501
|
+
return "NOT_AVAILABLE";
|
|
502
|
+
}
|
|
503
|
+
})(),
|
|
504
|
+
networkInterfaces: (() => {
|
|
505
|
+
try {
|
|
506
|
+
return Object.keys(os.networkInterfaces());
|
|
507
|
+
}
|
|
508
|
+
catch {
|
|
509
|
+
return [];
|
|
510
|
+
}
|
|
511
|
+
})(),
|
|
512
|
+
hostname: (() => {
|
|
513
|
+
try {
|
|
514
|
+
return os.hostname();
|
|
515
|
+
}
|
|
516
|
+
catch {
|
|
517
|
+
return "UNKNOWN";
|
|
518
|
+
}
|
|
519
|
+
})(),
|
|
520
|
+
platform: (() => {
|
|
521
|
+
try {
|
|
522
|
+
return os.platform();
|
|
523
|
+
}
|
|
524
|
+
catch {
|
|
525
|
+
return "UNKNOWN";
|
|
526
|
+
}
|
|
527
|
+
})(),
|
|
528
|
+
release: (() => {
|
|
529
|
+
try {
|
|
530
|
+
return os.release();
|
|
531
|
+
}
|
|
532
|
+
catch {
|
|
533
|
+
return "UNKNOWN";
|
|
534
|
+
}
|
|
535
|
+
})(),
|
|
536
|
+
},
|
|
537
|
+
message: "Creating Vertex AI instance",
|
|
538
|
+
});
|
|
539
|
+
const vertex = createVertex(vertexSettings);
|
|
540
|
+
const vertexInstanceEndTime = process.hrtime.bigint();
|
|
541
|
+
const vertexInstanceDurationNs = vertexInstanceEndTime - vertexInstanceStartTime;
|
|
542
|
+
logger.debug(`[GoogleVertexProvider] ✅ LOG_POINT_V011_VERTEX_INSTANCE_SUCCESS`, {
|
|
543
|
+
logPoint: "V011_VERTEX_INSTANCE_SUCCESS",
|
|
544
|
+
modelCreationId,
|
|
545
|
+
timestamp: new Date().toISOString(),
|
|
546
|
+
elapsedMs: Date.now() - modelCreationStartTime,
|
|
547
|
+
elapsedNs: (process.hrtime.bigint() - modelCreationHrTimeStart).toString(),
|
|
548
|
+
vertexInstanceDurationNs: vertexInstanceDurationNs.toString(),
|
|
549
|
+
vertexInstanceDurationMs: Number(vertexInstanceDurationNs) / 1000000,
|
|
550
|
+
hasVertexInstance: !!vertex,
|
|
551
|
+
vertexInstanceType: typeof vertex,
|
|
552
|
+
message: "Vertex AI instance created successfully",
|
|
553
|
+
});
|
|
554
|
+
// 🚀 EXHAUSTIVE LOGGING POINT V012: MODEL INSTANCE CREATION
|
|
555
|
+
const modelInstanceStartTime = process.hrtime.bigint();
|
|
556
|
+
logger.debug(`[GoogleVertexProvider] 🎯 LOG_POINT_V012_MODEL_INSTANCE_START`, {
|
|
557
|
+
logPoint: "V012_MODEL_INSTANCE_START",
|
|
558
|
+
modelCreationId,
|
|
559
|
+
timestamp: new Date().toISOString(),
|
|
560
|
+
elapsedMs: Date.now() - modelCreationStartTime,
|
|
561
|
+
elapsedNs: (process.hrtime.bigint() - modelCreationHrTimeStart).toString(),
|
|
562
|
+
modelInstanceStartTimeNs: modelInstanceStartTime.toString(),
|
|
563
|
+
modelName,
|
|
564
|
+
hasVertexInstance: !!vertex,
|
|
565
|
+
message: "Creating model instance from Vertex AI instance",
|
|
566
|
+
});
|
|
567
|
+
const model = vertex(modelName);
|
|
568
|
+
const modelInstanceEndTime = process.hrtime.bigint();
|
|
569
|
+
const modelInstanceDurationNs = modelInstanceEndTime - modelInstanceStartTime;
|
|
570
|
+
const totalModelCreationDurationNs = modelInstanceEndTime - modelCreationHrTimeStart;
|
|
571
|
+
logger.info(`[GoogleVertexProvider] 🏁 LOG_POINT_V013_MODEL_CREATION_COMPLETE`, {
|
|
572
|
+
logPoint: "V013_MODEL_CREATION_COMPLETE",
|
|
573
|
+
modelCreationId,
|
|
574
|
+
timestamp: new Date().toISOString(),
|
|
575
|
+
totalElapsedMs: Date.now() - modelCreationStartTime,
|
|
576
|
+
totalElapsedNs: totalModelCreationDurationNs.toString(),
|
|
577
|
+
totalDurationMs: Number(totalModelCreationDurationNs) / 1000000,
|
|
578
|
+
modelInstanceDurationNs: modelInstanceDurationNs.toString(),
|
|
579
|
+
modelInstanceDurationMs: Number(modelInstanceDurationNs) / 1000000,
|
|
580
|
+
// Final model analysis
|
|
581
|
+
finalModel: {
|
|
582
|
+
hasModel: !!model,
|
|
583
|
+
modelType: typeof model,
|
|
584
|
+
modelName,
|
|
585
|
+
isAnthropicModel: isAnthropic,
|
|
586
|
+
projectId: this.projectId,
|
|
587
|
+
location: this.location,
|
|
588
|
+
},
|
|
589
|
+
// Performance summary
|
|
590
|
+
performanceSummary: {
|
|
591
|
+
vertexSettingsDurationMs: Number(vertexSettingsDurationNs) / 1000000,
|
|
592
|
+
vertexInstanceDurationMs: Number(vertexInstanceDurationNs) / 1000000,
|
|
593
|
+
modelInstanceDurationMs: Number(modelInstanceDurationNs) / 1000000,
|
|
594
|
+
totalDurationMs: Number(totalModelCreationDurationNs) / 1000000,
|
|
595
|
+
},
|
|
596
|
+
// Memory usage
|
|
597
|
+
finalMemoryUsage: process.memoryUsage(),
|
|
598
|
+
message: "Model creation completed successfully - ready for API calls",
|
|
599
|
+
});
|
|
600
|
+
return model;
|
|
601
|
+
}
|
|
602
|
+
catch (error) {
|
|
603
|
+
const vertexSettingsErrorTime = process.hrtime.bigint();
|
|
604
|
+
const vertexSettingsDurationNs = vertexSettingsErrorTime - vertexSettingsStartTime;
|
|
605
|
+
const totalErrorDurationNs = vertexSettingsErrorTime - modelCreationHrTimeStart;
|
|
606
|
+
logger.error(`[GoogleVertexProvider] ❌ LOG_POINT_V014_VERTEX_SETTINGS_ERROR`, {
|
|
607
|
+
logPoint: "V014_VERTEX_SETTINGS_ERROR",
|
|
608
|
+
modelCreationId,
|
|
609
|
+
timestamp: new Date().toISOString(),
|
|
610
|
+
totalElapsedMs: Date.now() - modelCreationStartTime,
|
|
611
|
+
totalElapsedNs: totalErrorDurationNs.toString(),
|
|
612
|
+
totalErrorDurationMs: Number(totalErrorDurationNs) / 1000000,
|
|
613
|
+
vertexSettingsDurationNs: vertexSettingsDurationNs.toString(),
|
|
614
|
+
vertexSettingsDurationMs: Number(vertexSettingsDurationNs) / 1000000,
|
|
615
|
+
// Comprehensive error analysis
|
|
616
|
+
error: error instanceof Error ? error.message : String(error),
|
|
617
|
+
errorName: error instanceof Error ? error.name : "UnknownError",
|
|
618
|
+
errorStack: error instanceof Error ? error.stack : undefined,
|
|
619
|
+
// Network diagnostic information
|
|
620
|
+
networkDiagnostics: {
|
|
621
|
+
errorCode: error?.code || "UNKNOWN",
|
|
622
|
+
errorErrno: error?.errno || "UNKNOWN",
|
|
623
|
+
errorAddress: error?.address || "UNKNOWN",
|
|
624
|
+
errorPort: error?.port || "UNKNOWN",
|
|
625
|
+
errorSyscall: error?.syscall || "UNKNOWN",
|
|
626
|
+
errorHostname: error?.hostname || "UNKNOWN",
|
|
627
|
+
isTimeoutError: error instanceof Error &&
|
|
628
|
+
(error.message.includes("timeout") ||
|
|
629
|
+
error.message.includes("ETIMEDOUT")),
|
|
630
|
+
isNetworkError: error instanceof Error &&
|
|
631
|
+
(error.message.includes("ENOTFOUND") ||
|
|
632
|
+
error.message.includes("ECONNREFUSED") ||
|
|
633
|
+
error.message.includes("ETIMEDOUT")),
|
|
634
|
+
isAuthError: error instanceof Error &&
|
|
635
|
+
(error.message.includes("PERMISSION_DENIED") ||
|
|
636
|
+
error.message.includes("401") ||
|
|
637
|
+
error.message.includes("403")),
|
|
638
|
+
infrastructureIssue: error instanceof Error &&
|
|
639
|
+
error.message.includes("ETIMEDOUT") &&
|
|
640
|
+
error.message.includes("aiplatform.googleapis.com"),
|
|
641
|
+
},
|
|
642
|
+
// Environment at error time
|
|
643
|
+
errorEnvironment: {
|
|
644
|
+
httpProxy: process.env.HTTP_PROXY || process.env.http_proxy,
|
|
645
|
+
httpsProxy: process.env.HTTPS_PROXY || process.env.https_proxy,
|
|
646
|
+
googleAppCreds: process.env.GOOGLE_APPLICATION_CREDENTIALS,
|
|
647
|
+
hasGoogleServiceKey: !!process.env.GOOGLE_SERVICE_ACCOUNT_KEY,
|
|
648
|
+
nodeVersion: process.version,
|
|
649
|
+
memoryUsage: process.memoryUsage(),
|
|
650
|
+
uptime: process.uptime(),
|
|
651
|
+
},
|
|
652
|
+
message: "Vertex settings creation failed - critical network/authentication error",
|
|
653
|
+
});
|
|
654
|
+
throw error;
|
|
655
|
+
}
|
|
185
656
|
}
|
|
186
657
|
// executeGenerate removed - BaseProvider handles all generation with tools
|
|
187
658
|
async executeStream(options, analysisSchema) {
|
|
659
|
+
// 🚀 EXHAUSTIVE LOGGING POINT S001: STREAM EXECUTION ENTRY
|
|
660
|
+
const streamExecutionId = `vertex-stream-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;
|
|
661
|
+
const streamExecutionStartTime = Date.now();
|
|
662
|
+
const streamExecutionHrTimeStart = process.hrtime.bigint();
|
|
188
663
|
const functionTag = "GoogleVertexProvider.executeStream";
|
|
189
664
|
let chunkCount = 0;
|
|
190
|
-
|
|
665
|
+
logger.info(`[GoogleVertexProvider] 🎬 LOG_POINT_S001_STREAM_EXECUTION_START`, {
|
|
666
|
+
logPoint: "S001_STREAM_EXECUTION_START",
|
|
667
|
+
streamExecutionId,
|
|
668
|
+
timestamp: new Date().toISOString(),
|
|
669
|
+
streamExecutionStartTime,
|
|
670
|
+
streamExecutionHrTimeStart: streamExecutionHrTimeStart.toString(),
|
|
671
|
+
functionTag,
|
|
672
|
+
// Input analysis
|
|
673
|
+
inputAnalysis: {
|
|
674
|
+
hasOptions: !!options,
|
|
675
|
+
optionsType: typeof options,
|
|
676
|
+
optionsKeys: options ? Object.keys(options) : [],
|
|
677
|
+
hasInputText: !!options?.input?.text,
|
|
678
|
+
inputTextLength: options?.input?.text?.length || 0,
|
|
679
|
+
inputTextPreview: options?.input?.text?.substring(0, 200) || "NO_TEXT",
|
|
680
|
+
hasAnalysisSchema: !!analysisSchema,
|
|
681
|
+
schemaType: analysisSchema ? typeof analysisSchema : "NO_SCHEMA",
|
|
682
|
+
disableTools: options?.disableTools || false,
|
|
683
|
+
temperature: options?.temperature,
|
|
684
|
+
maxTokens: options?.maxTokens,
|
|
685
|
+
},
|
|
686
|
+
// Provider context
|
|
687
|
+
providerContext: {
|
|
688
|
+
modelName: this.modelName,
|
|
689
|
+
providerName: this.providerName,
|
|
690
|
+
projectId: this.projectId,
|
|
691
|
+
location: this.location,
|
|
692
|
+
defaultTimeout: this.defaultTimeout,
|
|
693
|
+
},
|
|
694
|
+
// Network environment
|
|
695
|
+
networkEnvironment: {
|
|
696
|
+
httpProxy: process.env.HTTP_PROXY || process.env.http_proxy || "NOT_SET",
|
|
697
|
+
httpsProxy: process.env.HTTPS_PROXY || process.env.https_proxy || "NOT_SET",
|
|
698
|
+
googleAppCreds: process.env.GOOGLE_APPLICATION_CREDENTIALS || "NOT_SET",
|
|
699
|
+
hasGoogleServiceKey: !!process.env.GOOGLE_SERVICE_ACCOUNT_KEY,
|
|
700
|
+
expectedEndpoint: `https://${this.location}-aiplatform.googleapis.com`,
|
|
701
|
+
proxyConfigured: !!(process.env.HTTP_PROXY ||
|
|
702
|
+
process.env.HTTPS_PROXY ||
|
|
703
|
+
process.env.http_proxy ||
|
|
704
|
+
process.env.https_proxy),
|
|
705
|
+
},
|
|
706
|
+
// Performance baseline
|
|
707
|
+
memoryUsage: process.memoryUsage(),
|
|
708
|
+
cpuUsage: process.cpuUsage(),
|
|
709
|
+
message: "Stream execution starting with comprehensive analysis",
|
|
710
|
+
});
|
|
711
|
+
// 🚀 EXHAUSTIVE LOGGING POINT S002: TIMEOUT CONTROLLER SETUP
|
|
712
|
+
const timeoutSetupStartTime = process.hrtime.bigint();
|
|
191
713
|
const timeout = this.getTimeout(options);
|
|
714
|
+
logger.debug(`[GoogleVertexProvider] ⏰ LOG_POINT_S002_TIMEOUT_SETUP`, {
|
|
715
|
+
logPoint: "S002_TIMEOUT_SETUP",
|
|
716
|
+
streamExecutionId,
|
|
717
|
+
timestamp: new Date().toISOString(),
|
|
718
|
+
elapsedMs: Date.now() - streamExecutionStartTime,
|
|
719
|
+
elapsedNs: (process.hrtime.bigint() - streamExecutionHrTimeStart).toString(),
|
|
720
|
+
timeoutSetupStartTimeNs: timeoutSetupStartTime.toString(),
|
|
721
|
+
timeout,
|
|
722
|
+
providerName: this.providerName,
|
|
723
|
+
streamType: "stream",
|
|
724
|
+
message: "Setting up timeout controller for stream execution",
|
|
725
|
+
});
|
|
726
|
+
// Add timeout controller for consistency with other providers
|
|
192
727
|
const timeoutController = createTimeoutController(timeout, this.providerName, "stream");
|
|
728
|
+
const timeoutSetupEndTime = process.hrtime.bigint();
|
|
729
|
+
const timeoutSetupDurationNs = timeoutSetupEndTime - timeoutSetupStartTime;
|
|
730
|
+
logger.debug(`[GoogleVertexProvider] ✅ LOG_POINT_S003_TIMEOUT_SETUP_SUCCESS`, {
|
|
731
|
+
logPoint: "S003_TIMEOUT_SETUP_SUCCESS",
|
|
732
|
+
streamExecutionId,
|
|
733
|
+
timestamp: new Date().toISOString(),
|
|
734
|
+
elapsedMs: Date.now() - streamExecutionStartTime,
|
|
735
|
+
elapsedNs: (process.hrtime.bigint() - streamExecutionHrTimeStart).toString(),
|
|
736
|
+
timeoutSetupDurationNs: timeoutSetupDurationNs.toString(),
|
|
737
|
+
timeoutSetupDurationMs: Number(timeoutSetupDurationNs) / 1000000,
|
|
738
|
+
hasTimeoutController: !!timeoutController,
|
|
739
|
+
timeoutValue: timeout,
|
|
740
|
+
message: "Timeout controller setup completed",
|
|
741
|
+
});
|
|
193
742
|
try {
|
|
743
|
+
// 🚀 EXHAUSTIVE LOGGING POINT S004: STREAM OPTIONS VALIDATION
|
|
744
|
+
const validationStartTime = process.hrtime.bigint();
|
|
745
|
+
logger.debug(`[GoogleVertexProvider] ✔️ LOG_POINT_S004_VALIDATION_START`, {
|
|
746
|
+
logPoint: "S004_VALIDATION_START",
|
|
747
|
+
streamExecutionId,
|
|
748
|
+
timestamp: new Date().toISOString(),
|
|
749
|
+
elapsedMs: Date.now() - streamExecutionStartTime,
|
|
750
|
+
elapsedNs: (process.hrtime.bigint() - streamExecutionHrTimeStart).toString(),
|
|
751
|
+
validationStartTimeNs: validationStartTime.toString(),
|
|
752
|
+
message: "Starting stream options validation",
|
|
753
|
+
});
|
|
194
754
|
this.validateStreamOptions(options);
|
|
755
|
+
const validationEndTime = process.hrtime.bigint();
|
|
756
|
+
const validationDurationNs = validationEndTime - validationStartTime;
|
|
757
|
+
logger.debug(`[GoogleVertexProvider] ✅ LOG_POINT_S005_VALIDATION_SUCCESS`, {
|
|
758
|
+
logPoint: "S005_VALIDATION_SUCCESS",
|
|
759
|
+
streamExecutionId,
|
|
760
|
+
timestamp: new Date().toISOString(),
|
|
761
|
+
elapsedMs: Date.now() - streamExecutionStartTime,
|
|
762
|
+
elapsedNs: (process.hrtime.bigint() - streamExecutionHrTimeStart).toString(),
|
|
763
|
+
validationDurationNs: validationDurationNs.toString(),
|
|
764
|
+
validationDurationMs: Number(validationDurationNs) / 1000000,
|
|
765
|
+
message: "Stream options validation successful",
|
|
766
|
+
});
|
|
767
|
+
// 🚀 EXHAUSTIVE LOGGING POINT S006: MESSAGE ARRAY BUILDING
|
|
768
|
+
const messagesBuildStartTime = process.hrtime.bigint();
|
|
769
|
+
logger.debug(`[GoogleVertexProvider] 📝 LOG_POINT_S006_MESSAGES_BUILD_START`, {
|
|
770
|
+
logPoint: "S006_MESSAGES_BUILD_START",
|
|
771
|
+
streamExecutionId,
|
|
772
|
+
timestamp: new Date().toISOString(),
|
|
773
|
+
elapsedMs: Date.now() - streamExecutionStartTime,
|
|
774
|
+
elapsedNs: (process.hrtime.bigint() - streamExecutionHrTimeStart).toString(),
|
|
775
|
+
messagesBuildStartTimeNs: messagesBuildStartTime.toString(),
|
|
776
|
+
message: "Building message array from stream options",
|
|
777
|
+
});
|
|
195
778
|
// Build message array from options
|
|
196
779
|
const messages = buildMessagesArray(options);
|
|
780
|
+
const messagesBuildEndTime = process.hrtime.bigint();
|
|
781
|
+
const messagesBuildDurationNs = messagesBuildEndTime - messagesBuildStartTime;
|
|
782
|
+
logger.debug(`[GoogleVertexProvider] ✅ LOG_POINT_S007_MESSAGES_BUILD_SUCCESS`, {
|
|
783
|
+
logPoint: "S007_MESSAGES_BUILD_SUCCESS",
|
|
784
|
+
streamExecutionId,
|
|
785
|
+
timestamp: new Date().toISOString(),
|
|
786
|
+
elapsedMs: Date.now() - streamExecutionStartTime,
|
|
787
|
+
elapsedNs: (process.hrtime.bigint() - streamExecutionHrTimeStart).toString(),
|
|
788
|
+
messagesBuildDurationNs: messagesBuildDurationNs.toString(),
|
|
789
|
+
messagesBuildDurationMs: Number(messagesBuildDurationNs) / 1000000,
|
|
790
|
+
messagesCount: messages?.length || 0,
|
|
791
|
+
messagesType: typeof messages,
|
|
792
|
+
hasMessages: !!messages,
|
|
793
|
+
message: "Message array built successfully",
|
|
794
|
+
});
|
|
795
|
+
// 🚀 EXHAUSTIVE LOGGING POINT S008: INITIAL STREAM REQUEST LOG
|
|
796
|
+
logger.debug(`[GoogleVertexProvider] 🚀 LOG_POINT_S008_STREAM_REQUEST_DETAILS`, {
|
|
797
|
+
logPoint: "S008_STREAM_REQUEST_DETAILS",
|
|
798
|
+
streamExecutionId,
|
|
799
|
+
timestamp: new Date().toISOString(),
|
|
800
|
+
elapsedMs: Date.now() - streamExecutionStartTime,
|
|
801
|
+
elapsedNs: (process.hrtime.bigint() - streamExecutionHrTimeStart).toString(),
|
|
802
|
+
// Detailed request information
|
|
803
|
+
streamRequestDetails: {
|
|
804
|
+
modelName: this.modelName,
|
|
805
|
+
promptLength: options.input.text.length,
|
|
806
|
+
hasSchema: !!analysisSchema,
|
|
807
|
+
messagesCount: messages?.length || 0,
|
|
808
|
+
temperature: options?.temperature,
|
|
809
|
+
maxTokens: options?.maxTokens,
|
|
810
|
+
disableTools: options?.disableTools || false,
|
|
811
|
+
},
|
|
812
|
+
message: "Starting comprehensive stream request processing",
|
|
813
|
+
});
|
|
197
814
|
logger.debug(`${functionTag}: Starting stream request`, {
|
|
198
815
|
modelName: this.modelName,
|
|
199
816
|
promptLength: options.input.text.length,
|
|
200
817
|
hasSchema: !!analysisSchema,
|
|
201
818
|
});
|
|
202
|
-
|
|
819
|
+
// 🚀 EXHAUSTIVE LOGGING POINT S009: MODEL CREATION FOR STREAM
|
|
820
|
+
const modelCreationStartTime = process.hrtime.bigint();
|
|
821
|
+
logger.debug(`[GoogleVertexProvider] 🏭 LOG_POINT_S009_MODEL_CREATION_FOR_STREAM`, {
|
|
822
|
+
logPoint: "S009_MODEL_CREATION_FOR_STREAM",
|
|
823
|
+
streamExecutionId,
|
|
824
|
+
timestamp: new Date().toISOString(),
|
|
825
|
+
elapsedMs: Date.now() - streamExecutionStartTime,
|
|
826
|
+
elapsedNs: (process.hrtime.bigint() - streamExecutionHrTimeStart).toString(),
|
|
827
|
+
modelCreationStartTimeNs: modelCreationStartTime.toString(),
|
|
828
|
+
requestedModel: this.modelName,
|
|
829
|
+
message: "Starting model creation for stream execution (this will include network setup)",
|
|
830
|
+
});
|
|
831
|
+
const model = await this.getModel(); // This is where network connection happens!
|
|
832
|
+
const modelCreationEndTime = process.hrtime.bigint();
|
|
833
|
+
const modelCreationDurationNs = modelCreationEndTime - modelCreationStartTime;
|
|
834
|
+
logger.info(`[GoogleVertexProvider] ✅ LOG_POINT_S010_MODEL_CREATION_SUCCESS`, {
|
|
835
|
+
logPoint: "S010_MODEL_CREATION_SUCCESS",
|
|
836
|
+
streamExecutionId,
|
|
837
|
+
timestamp: new Date().toISOString(),
|
|
838
|
+
elapsedMs: Date.now() - streamExecutionStartTime,
|
|
839
|
+
elapsedNs: (process.hrtime.bigint() - streamExecutionHrTimeStart).toString(),
|
|
840
|
+
modelCreationDurationNs: modelCreationDurationNs.toString(),
|
|
841
|
+
modelCreationDurationMs: Number(modelCreationDurationNs) / 1000000,
|
|
842
|
+
hasModel: !!model,
|
|
843
|
+
modelType: typeof model,
|
|
844
|
+
message: "Model creation completed successfully - network connection established",
|
|
845
|
+
});
|
|
846
|
+
// 🚀 EXHAUSTIVE LOGGING POINT S011: TOOLS SETUP FOR STREAMING
|
|
847
|
+
const toolsSetupStartTime = process.hrtime.bigint();
|
|
848
|
+
logger.debug(`[GoogleVertexProvider] 🛠️ LOG_POINT_S011_TOOLS_SETUP_START`, {
|
|
849
|
+
logPoint: "S011_TOOLS_SETUP_START",
|
|
850
|
+
streamExecutionId,
|
|
851
|
+
timestamp: new Date().toISOString(),
|
|
852
|
+
elapsedMs: Date.now() - streamExecutionStartTime,
|
|
853
|
+
elapsedNs: (process.hrtime.bigint() - streamExecutionHrTimeStart).toString(),
|
|
854
|
+
toolsSetupStartTimeNs: toolsSetupStartTime.toString(),
|
|
855
|
+
disableTools: options?.disableTools || false,
|
|
856
|
+
supportsTools: this.supportsTools(),
|
|
857
|
+
message: "Setting up tools for streaming",
|
|
858
|
+
});
|
|
203
859
|
// Get all available tools (direct + MCP + external) for streaming
|
|
204
860
|
const shouldUseTools = !options.disableTools && this.supportsTools();
|
|
205
861
|
const tools = shouldUseTools ? await this.getAllTools() : {};
|
|
862
|
+
const toolsSetupEndTime = process.hrtime.bigint();
|
|
863
|
+
const toolsSetupDurationNs = toolsSetupEndTime - toolsSetupStartTime;
|
|
864
|
+
logger.debug(`[GoogleVertexProvider] ✅ LOG_POINT_S012_TOOLS_SETUP_SUCCESS`, {
|
|
865
|
+
logPoint: "S012_TOOLS_SETUP_SUCCESS",
|
|
866
|
+
streamExecutionId,
|
|
867
|
+
timestamp: new Date().toISOString(),
|
|
868
|
+
elapsedMs: Date.now() - streamExecutionStartTime,
|
|
869
|
+
elapsedNs: (process.hrtime.bigint() - streamExecutionHrTimeStart).toString(),
|
|
870
|
+
toolsSetupDurationNs: toolsSetupDurationNs.toString(),
|
|
871
|
+
toolsSetupDurationMs: Number(toolsSetupDurationNs) / 1000000,
|
|
872
|
+
shouldUseTools,
|
|
873
|
+
toolCount: Object.keys(tools).length,
|
|
874
|
+
toolNames: Object.keys(tools),
|
|
875
|
+
hasTools: Object.keys(tools).length > 0,
|
|
876
|
+
message: "Tools setup completed for streaming",
|
|
877
|
+
});
|
|
206
878
|
logger.debug(`${functionTag}: Tools for streaming`, {
|
|
207
879
|
shouldUseTools,
|
|
208
880
|
toolCount: Object.keys(tools).length,
|
|
@@ -409,41 +1081,417 @@ export class GoogleVertexProvider extends BaseProvider {
|
|
|
409
1081
|
* @returns Promise<boolean> indicating if Anthropic support is available
|
|
410
1082
|
*/
|
|
411
1083
|
async hasAnthropicSupport() {
|
|
412
|
-
|
|
413
|
-
return createVertexAnthropic !== null;
|
|
1084
|
+
return hasAnthropicSupport();
|
|
414
1085
|
}
|
|
415
1086
|
/**
|
|
416
|
-
* Create an Anthropic model instance
|
|
417
|
-
* Uses fresh vertex settings for each request
|
|
1087
|
+
* Create an Anthropic model instance using vertexAnthropic provider
|
|
1088
|
+
* Uses fresh vertex settings for each request with comprehensive validation
|
|
418
1089
|
* @param modelName Anthropic model name (e.g., 'claude-3-sonnet@20240229')
|
|
419
1090
|
* @returns LanguageModelV1 instance or null if not available
|
|
420
1091
|
*/
|
|
421
|
-
createAnthropicModel(modelName) {
|
|
422
|
-
|
|
423
|
-
|
|
1092
|
+
async createAnthropicModel(modelName) {
|
|
1093
|
+
const validationId = `anthropic-validation-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;
|
|
1094
|
+
logger.debug("[GoogleVertexProvider] 🧠 Starting comprehensive Anthropic model validation", {
|
|
1095
|
+
validationId,
|
|
1096
|
+
modelName,
|
|
1097
|
+
timestamp: new Date().toISOString(),
|
|
1098
|
+
});
|
|
1099
|
+
// 1. SDK Module Availability Validation
|
|
1100
|
+
if (!hasAnthropicSupport()) {
|
|
1101
|
+
logger.error("[GoogleVertexProvider] ❌ SDK module validation failed", {
|
|
1102
|
+
validationId,
|
|
1103
|
+
issue: "createVertexAnthropic function not available",
|
|
1104
|
+
solution: "Update @ai-sdk/google-vertex to latest version with Anthropic support",
|
|
1105
|
+
command: "npm install @ai-sdk/google-vertex@latest",
|
|
1106
|
+
documentation: "https://sdk.vercel.ai/providers/ai-sdk-providers/google-vertex#anthropic-models",
|
|
1107
|
+
});
|
|
1108
|
+
return null;
|
|
1109
|
+
}
|
|
1110
|
+
// 2. Authentication Validation
|
|
1111
|
+
const authValidation = await this.validateVertexAuthentication();
|
|
1112
|
+
if (!authValidation.isValid) {
|
|
1113
|
+
logger.error("[GoogleVertexProvider] ❌ Authentication validation failed", {
|
|
1114
|
+
validationId,
|
|
1115
|
+
method: authValidation.method,
|
|
1116
|
+
issues: authValidation.issues,
|
|
1117
|
+
solutions: [
|
|
1118
|
+
"Option 1: Set GOOGLE_APPLICATION_CREDENTIALS to valid service account file",
|
|
1119
|
+
"Option 2: Set individual env vars: GOOGLE_AUTH_CLIENT_EMAIL, GOOGLE_AUTH_PRIVATE_KEY",
|
|
1120
|
+
"Documentation: https://cloud.google.com/docs/authentication/provide-credentials-adc",
|
|
1121
|
+
],
|
|
1122
|
+
});
|
|
1123
|
+
return null;
|
|
1124
|
+
}
|
|
1125
|
+
// 3. Project Configuration Validation
|
|
1126
|
+
const projectValidation = await this.validateVertexProjectConfiguration();
|
|
1127
|
+
if (!projectValidation.isValid) {
|
|
1128
|
+
logger.error("[GoogleVertexProvider] ❌ Project configuration validation failed", {
|
|
1129
|
+
validationId,
|
|
1130
|
+
projectId: projectValidation.projectId,
|
|
1131
|
+
region: projectValidation.region,
|
|
1132
|
+
issues: projectValidation.issues,
|
|
1133
|
+
solutions: [
|
|
1134
|
+
"Set GOOGLE_VERTEX_PROJECT or GOOGLE_CLOUD_PROJECT environment variable",
|
|
1135
|
+
"Ensure project exists and has Vertex AI API enabled",
|
|
1136
|
+
"Check: https://console.cloud.google.com/apis/library/aiplatform.googleapis.com",
|
|
1137
|
+
],
|
|
1138
|
+
});
|
|
1139
|
+
return null;
|
|
1140
|
+
}
|
|
1141
|
+
// 4. Regional Support Validation
|
|
1142
|
+
const regionSupported = await this.checkVertexRegionalSupport(projectValidation.region);
|
|
1143
|
+
if (!regionSupported) {
|
|
1144
|
+
logger.warn("[GoogleVertexProvider] ⚠️ Regional support warning", {
|
|
1145
|
+
validationId,
|
|
1146
|
+
region: projectValidation.region,
|
|
1147
|
+
warning: "Anthropic models may not be available in this region",
|
|
1148
|
+
supportedRegions: [
|
|
1149
|
+
"us-central1",
|
|
1150
|
+
"us-east4",
|
|
1151
|
+
"europe-west1",
|
|
1152
|
+
"asia-southeast1",
|
|
1153
|
+
],
|
|
1154
|
+
solution: "Set GOOGLE_CLOUD_LOCATION to a supported region",
|
|
1155
|
+
});
|
|
1156
|
+
// Continue with warning, don't block
|
|
1157
|
+
}
|
|
1158
|
+
// 5. Model Name Validation
|
|
1159
|
+
const modelValidation = this.validateAnthropicModelName(modelName);
|
|
1160
|
+
if (!modelValidation.isValid) {
|
|
1161
|
+
logger.error("[GoogleVertexProvider] ❌ Model name validation failed", {
|
|
1162
|
+
validationId,
|
|
1163
|
+
modelName,
|
|
1164
|
+
issue: modelValidation.issue,
|
|
1165
|
+
recommendedModels: [
|
|
1166
|
+
"claude-sonnet-4@20250514",
|
|
1167
|
+
"claude-opus-4@20250514",
|
|
1168
|
+
"claude-3-5-sonnet-20241022",
|
|
1169
|
+
"claude-3-5-haiku-20241022",
|
|
1170
|
+
],
|
|
1171
|
+
});
|
|
1172
|
+
return null;
|
|
1173
|
+
}
|
|
1174
|
+
try {
|
|
1175
|
+
// 6. Settings Creation with Enhanced Error Handling
|
|
1176
|
+
logger.debug("[GoogleVertexProvider] 🔧 Creating vertexAnthropic settings", {
|
|
1177
|
+
validationId,
|
|
1178
|
+
authMethod: authValidation.method,
|
|
1179
|
+
projectId: projectValidation.projectId,
|
|
1180
|
+
region: projectValidation.region,
|
|
1181
|
+
});
|
|
1182
|
+
const vertexAnthropicSettings = await createVertexAnthropicSettings();
|
|
1183
|
+
// 7. Settings Validation
|
|
1184
|
+
if (!vertexAnthropicSettings.project ||
|
|
1185
|
+
!vertexAnthropicSettings.location) {
|
|
1186
|
+
logger.error("[GoogleVertexProvider] ❌ Settings validation failed", {
|
|
1187
|
+
validationId,
|
|
1188
|
+
hasProject: !!vertexAnthropicSettings.project,
|
|
1189
|
+
hasLocation: !!vertexAnthropicSettings.location,
|
|
1190
|
+
hasProxy: !!vertexAnthropicSettings.fetch,
|
|
1191
|
+
hasAuth: !!vertexAnthropicSettings.googleAuthOptions,
|
|
1192
|
+
});
|
|
424
1193
|
return null;
|
|
425
1194
|
}
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
1195
|
+
logger.debug("[GoogleVertexProvider] ✅ Creating vertexAnthropic instance", {
|
|
1196
|
+
validationId,
|
|
1197
|
+
modelName,
|
|
1198
|
+
project: vertexAnthropicSettings.project,
|
|
1199
|
+
location: vertexAnthropicSettings.location,
|
|
1200
|
+
hasProxy: !!vertexAnthropicSettings.fetch,
|
|
1201
|
+
hasAuth: !!vertexAnthropicSettings.googleAuthOptions,
|
|
1202
|
+
});
|
|
1203
|
+
// 8. Provider Instance Creation
|
|
1204
|
+
const vertexAnthropicInstance = createVertexAnthropic(vertexAnthropicSettings);
|
|
1205
|
+
// 9. Model Instance Creation with Network Error Handling
|
|
1206
|
+
const model = vertexAnthropicInstance(modelName);
|
|
1207
|
+
logger.info("[GoogleVertexProvider] ✅ Anthropic model created successfully", {
|
|
1208
|
+
validationId,
|
|
1209
|
+
modelName,
|
|
1210
|
+
hasModel: !!model,
|
|
1211
|
+
modelType: typeof model,
|
|
1212
|
+
authMethod: authValidation.method,
|
|
1213
|
+
projectId: projectValidation.projectId,
|
|
1214
|
+
region: projectValidation.region,
|
|
1215
|
+
validationsPassed: [
|
|
1216
|
+
"SDK_MODULE_AVAILABLE",
|
|
1217
|
+
"AUTHENTICATION_VALID",
|
|
1218
|
+
"PROJECT_CONFIGURED",
|
|
1219
|
+
"MODEL_NAME_VALID",
|
|
1220
|
+
"SETTINGS_CREATED",
|
|
1221
|
+
"PROVIDER_INSTANCE_CREATED",
|
|
1222
|
+
"MODEL_INSTANCE_CREATED",
|
|
1223
|
+
],
|
|
1224
|
+
});
|
|
1225
|
+
return model;
|
|
1226
|
+
}
|
|
1227
|
+
catch (error) {
|
|
1228
|
+
// Enhanced error analysis and reporting
|
|
1229
|
+
const errorAnalysis = this.analyzeAnthropicCreationError(error, {
|
|
1230
|
+
validationId,
|
|
1231
|
+
modelName,
|
|
1232
|
+
projectId: projectValidation.projectId,
|
|
1233
|
+
region: projectValidation.region,
|
|
1234
|
+
authMethod: authValidation.method,
|
|
1235
|
+
});
|
|
1236
|
+
logger.error("[GoogleVertexProvider] ❌ Anthropic model creation failed", {
|
|
1237
|
+
validationId,
|
|
1238
|
+
modelName,
|
|
1239
|
+
...errorAnalysis,
|
|
1240
|
+
detailedTroubleshooting: this.getAnthropicTroubleshootingSteps(errorAnalysis),
|
|
1241
|
+
});
|
|
1242
|
+
return null;
|
|
1243
|
+
}
|
|
1244
|
+
}
|
|
1245
|
+
/**
|
|
1246
|
+
* Validate Vertex AI authentication configuration
|
|
1247
|
+
*/
|
|
1248
|
+
async validateVertexAuthentication() {
|
|
1249
|
+
const result = {
|
|
1250
|
+
isValid: false,
|
|
1251
|
+
method: "none",
|
|
1252
|
+
issues: [],
|
|
1253
|
+
};
|
|
1254
|
+
try {
|
|
1255
|
+
// Check for service account file authentication (preferred)
|
|
1256
|
+
if (process.env.GOOGLE_APPLICATION_CREDENTIALS) {
|
|
1257
|
+
const credentialsPath = process.env.GOOGLE_APPLICATION_CREDENTIALS;
|
|
1258
|
+
try {
|
|
1259
|
+
if (fs.existsSync(credentialsPath)) {
|
|
1260
|
+
// Validate JSON structure
|
|
1261
|
+
const credentialsContent = fs.readFileSync(credentialsPath, "utf8");
|
|
1262
|
+
const credentials = JSON.parse(credentialsContent);
|
|
1263
|
+
if (credentials.type === "service_account" &&
|
|
1264
|
+
credentials.project_id &&
|
|
1265
|
+
credentials.client_email &&
|
|
1266
|
+
credentials.private_key) {
|
|
1267
|
+
result.isValid = true;
|
|
1268
|
+
result.method = "service_account_file";
|
|
1269
|
+
return result;
|
|
1270
|
+
}
|
|
1271
|
+
else {
|
|
1272
|
+
result.issues.push("Service account file missing required fields");
|
|
1273
|
+
}
|
|
1274
|
+
}
|
|
1275
|
+
else {
|
|
1276
|
+
result.issues.push(`Service account file not found: ${credentialsPath}`);
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1279
|
+
catch (fileError) {
|
|
1280
|
+
result.issues.push(`Service account file validation failed: ${fileError}`);
|
|
1281
|
+
}
|
|
430
1282
|
}
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
1283
|
+
// Check for individual environment variables
|
|
1284
|
+
if (process.env.GOOGLE_AUTH_CLIENT_EMAIL &&
|
|
1285
|
+
process.env.GOOGLE_AUTH_PRIVATE_KEY) {
|
|
1286
|
+
const email = process.env.GOOGLE_AUTH_CLIENT_EMAIL;
|
|
1287
|
+
const privateKey = process.env.GOOGLE_AUTH_PRIVATE_KEY;
|
|
1288
|
+
if (email.includes("@") && privateKey.includes("BEGIN PRIVATE KEY")) {
|
|
1289
|
+
result.isValid = true;
|
|
1290
|
+
result.method = "environment_variables";
|
|
1291
|
+
return result;
|
|
1292
|
+
}
|
|
1293
|
+
else {
|
|
1294
|
+
result.issues.push("Individual credentials format validation failed");
|
|
1295
|
+
}
|
|
437
1296
|
}
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
if (!model ||
|
|
441
|
-
typeof model !== "object" ||
|
|
442
|
-
!("specificationVersion" in model)) {
|
|
443
|
-
throw new Error("Failed to create valid LanguageModelV1 instance");
|
|
1297
|
+
else {
|
|
1298
|
+
result.issues.push("Missing individual credential environment variables");
|
|
444
1299
|
}
|
|
445
|
-
|
|
446
|
-
|
|
1300
|
+
if (!result.isValid) {
|
|
1301
|
+
result.issues.push("No valid authentication method found");
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1304
|
+
catch (error) {
|
|
1305
|
+
result.issues.push(`Authentication validation error: ${error}`);
|
|
1306
|
+
}
|
|
1307
|
+
return result;
|
|
1308
|
+
}
|
|
1309
|
+
/**
|
|
1310
|
+
* Validate Vertex AI project configuration
|
|
1311
|
+
*/
|
|
1312
|
+
async validateVertexProjectConfiguration() {
|
|
1313
|
+
const result = {
|
|
1314
|
+
isValid: false,
|
|
1315
|
+
projectId: undefined,
|
|
1316
|
+
region: undefined,
|
|
1317
|
+
issues: [],
|
|
1318
|
+
};
|
|
1319
|
+
// Check project ID
|
|
1320
|
+
const projectId = process.env.GOOGLE_VERTEX_PROJECT ||
|
|
1321
|
+
process.env.GOOGLE_CLOUD_PROJECT_ID ||
|
|
1322
|
+
process.env.GOOGLE_PROJECT_ID ||
|
|
1323
|
+
process.env.GOOGLE_CLOUD_PROJECT;
|
|
1324
|
+
if (projectId) {
|
|
1325
|
+
result.projectId = projectId;
|
|
1326
|
+
// Validate project ID format
|
|
1327
|
+
const projectIdPattern = /^[a-z][a-z0-9-]{4,28}[a-z0-9]$/;
|
|
1328
|
+
if (projectIdPattern.test(projectId)) {
|
|
1329
|
+
result.isValid = true;
|
|
1330
|
+
}
|
|
1331
|
+
else {
|
|
1332
|
+
result.issues.push(`Invalid project ID format: ${projectId}`);
|
|
1333
|
+
}
|
|
1334
|
+
}
|
|
1335
|
+
else {
|
|
1336
|
+
result.issues.push("No project ID configured");
|
|
1337
|
+
}
|
|
1338
|
+
// Check region/location
|
|
1339
|
+
const region = process.env.GOOGLE_CLOUD_LOCATION ||
|
|
1340
|
+
process.env.VERTEX_LOCATION ||
|
|
1341
|
+
process.env.GOOGLE_VERTEX_LOCATION ||
|
|
1342
|
+
"us-central1";
|
|
1343
|
+
result.region = region;
|
|
1344
|
+
// Validate region format
|
|
1345
|
+
const regionPattern = /^[a-z]+-[a-z]+\d+$/;
|
|
1346
|
+
if (!regionPattern.test(region)) {
|
|
1347
|
+
result.issues.push(`Invalid region format: ${region}`);
|
|
1348
|
+
result.isValid = false;
|
|
1349
|
+
}
|
|
1350
|
+
return result;
|
|
1351
|
+
}
|
|
1352
|
+
/**
|
|
1353
|
+
* Check if the specified region supports Anthropic models
|
|
1354
|
+
*/
|
|
1355
|
+
async checkVertexRegionalSupport(region = "us-central1") {
|
|
1356
|
+
// Based on Google Cloud documentation, these regions support Anthropic models
|
|
1357
|
+
const supportedRegions = [
|
|
1358
|
+
"us-central1",
|
|
1359
|
+
"us-east4",
|
|
1360
|
+
"us-west1",
|
|
1361
|
+
"us-west4",
|
|
1362
|
+
"europe-west1",
|
|
1363
|
+
"europe-west4",
|
|
1364
|
+
"asia-southeast1",
|
|
1365
|
+
"asia-northeast1",
|
|
1366
|
+
];
|
|
1367
|
+
return supportedRegions.includes(region);
|
|
1368
|
+
}
|
|
1369
|
+
/**
|
|
1370
|
+
* Validate Anthropic model name format and availability
|
|
1371
|
+
*/
|
|
1372
|
+
validateAnthropicModelName(modelName) {
|
|
1373
|
+
if (!modelName || typeof modelName !== "string") {
|
|
1374
|
+
return {
|
|
1375
|
+
isValid: false,
|
|
1376
|
+
issue: "Model name is required and must be a string",
|
|
1377
|
+
};
|
|
1378
|
+
}
|
|
1379
|
+
// Check if it's a Claude model
|
|
1380
|
+
if (!modelName.toLowerCase().includes("claude")) {
|
|
1381
|
+
return {
|
|
1382
|
+
isValid: false,
|
|
1383
|
+
issue: 'Model name must be a Claude model (should contain "claude")',
|
|
1384
|
+
};
|
|
1385
|
+
}
|
|
1386
|
+
// Validate against known Claude model patterns
|
|
1387
|
+
const validPatterns = [
|
|
1388
|
+
/^claude-sonnet-4@\d{8}$/,
|
|
1389
|
+
/^claude-opus-4@\d{8}$/,
|
|
1390
|
+
/^claude-3-5-sonnet-\d{8}$/,
|
|
1391
|
+
/^claude-3-5-haiku-\d{8}$/,
|
|
1392
|
+
/^claude-3-sonnet-\d{8}$/,
|
|
1393
|
+
/^claude-3-haiku-\d{8}$/,
|
|
1394
|
+
/^claude-3-opus-\d{8}$/,
|
|
1395
|
+
];
|
|
1396
|
+
const isValidFormat = validPatterns.some((pattern) => pattern.test(modelName));
|
|
1397
|
+
if (!isValidFormat) {
|
|
1398
|
+
return {
|
|
1399
|
+
isValid: false,
|
|
1400
|
+
issue: `Model name format not recognized. Expected formats like "claude-3-5-sonnet-20241022" or "claude-sonnet-4@20250514"`,
|
|
1401
|
+
};
|
|
1402
|
+
}
|
|
1403
|
+
return { isValid: true };
|
|
1404
|
+
}
|
|
1405
|
+
/**
|
|
1406
|
+
* Analyze Anthropic model creation errors for detailed troubleshooting
|
|
1407
|
+
*/
|
|
1408
|
+
analyzeAnthropicCreationError(error, context) {
|
|
1409
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1410
|
+
const errorName = error instanceof Error ? error.name : "UnknownError";
|
|
1411
|
+
const analysis = {
|
|
1412
|
+
error: errorMessage,
|
|
1413
|
+
errorName,
|
|
1414
|
+
errorType: "UNKNOWN",
|
|
1415
|
+
isNetworkError: false,
|
|
1416
|
+
isAuthError: false,
|
|
1417
|
+
isConfigurationError: false,
|
|
1418
|
+
isModelError: false,
|
|
1419
|
+
isRegionalError: false,
|
|
1420
|
+
specificIssue: "Unknown error occurred",
|
|
1421
|
+
errorStack: error instanceof Error ? error.stack : undefined,
|
|
1422
|
+
};
|
|
1423
|
+
// Network-related errors
|
|
1424
|
+
if (errorMessage.includes("ETIMEDOUT") ||
|
|
1425
|
+
errorMessage.includes("ECONNREFUSED") ||
|
|
1426
|
+
errorMessage.includes("ENOTFOUND") ||
|
|
1427
|
+
errorMessage.includes("timeout")) {
|
|
1428
|
+
analysis.errorType = "NETWORK";
|
|
1429
|
+
analysis.isNetworkError = true;
|
|
1430
|
+
analysis.specificIssue =
|
|
1431
|
+
"Network connectivity issue - cannot reach Google Cloud endpoints";
|
|
1432
|
+
}
|
|
1433
|
+
// Authentication errors
|
|
1434
|
+
else if (errorMessage.includes("PERMISSION_DENIED") ||
|
|
1435
|
+
errorMessage.includes("401") ||
|
|
1436
|
+
errorMessage.includes("403") ||
|
|
1437
|
+
errorMessage.includes("Unauthorized") ||
|
|
1438
|
+
errorMessage.includes("Forbidden")) {
|
|
1439
|
+
analysis.errorType = "AUTHENTICATION";
|
|
1440
|
+
analysis.isAuthError = true;
|
|
1441
|
+
analysis.specificIssue =
|
|
1442
|
+
"Authentication failed - invalid credentials or insufficient permissions";
|
|
1443
|
+
}
|
|
1444
|
+
// Model availability errors
|
|
1445
|
+
else if (errorMessage.includes("NOT_FOUND") ||
|
|
1446
|
+
errorMessage.includes("404") ||
|
|
1447
|
+
(errorMessage.includes("model") && errorMessage.includes("not available"))) {
|
|
1448
|
+
analysis.errorType = "MODEL_AVAILABILITY";
|
|
1449
|
+
analysis.isModelError = true;
|
|
1450
|
+
analysis.specificIssue = `Model "${context.modelName}" not available in region "${context.region}"`;
|
|
1451
|
+
}
|
|
1452
|
+
// Regional/quota errors
|
|
1453
|
+
else if (errorMessage.includes("QUOTA_EXCEEDED") ||
|
|
1454
|
+
errorMessage.includes("quota") ||
|
|
1455
|
+
errorMessage.includes("limit")) {
|
|
1456
|
+
analysis.errorType = "QUOTA";
|
|
1457
|
+
analysis.isRegionalError = true;
|
|
1458
|
+
analysis.specificIssue = "Quota exceeded or rate limit reached";
|
|
1459
|
+
}
|
|
1460
|
+
// Configuration errors
|
|
1461
|
+
else if (errorMessage.includes("INVALID_ARGUMENT") ||
|
|
1462
|
+
errorMessage.includes("BadRequest") ||
|
|
1463
|
+
errorMessage.includes("400")) {
|
|
1464
|
+
analysis.errorType = "CONFIGURATION";
|
|
1465
|
+
analysis.isConfigurationError = true;
|
|
1466
|
+
analysis.specificIssue = "Invalid configuration or request parameters";
|
|
1467
|
+
}
|
|
1468
|
+
return analysis;
|
|
1469
|
+
}
|
|
1470
|
+
/**
|
|
1471
|
+
* Get detailed troubleshooting steps based on error analysis
|
|
1472
|
+
*/
|
|
1473
|
+
getAnthropicTroubleshootingSteps(errorAnalysis) {
|
|
1474
|
+
const steps = [];
|
|
1475
|
+
switch (errorAnalysis.errorType) {
|
|
1476
|
+
case "NETWORK":
|
|
1477
|
+
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");
|
|
1478
|
+
break;
|
|
1479
|
+
case "AUTHENTICATION":
|
|
1480
|
+
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");
|
|
1481
|
+
break;
|
|
1482
|
+
case "MODEL_AVAILABILITY":
|
|
1483
|
+
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");
|
|
1484
|
+
break;
|
|
1485
|
+
case "QUOTA":
|
|
1486
|
+
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");
|
|
1487
|
+
break;
|
|
1488
|
+
case "CONFIGURATION":
|
|
1489
|
+
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. Update @ai-sdk/google-vertex to latest version");
|
|
1490
|
+
break;
|
|
1491
|
+
default:
|
|
1492
|
+
steps.push("🔧 General Troubleshooting:", "1. Update @ai-sdk/google-vertex to latest version", "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");
|
|
1493
|
+
}
|
|
1494
|
+
return steps;
|
|
447
1495
|
}
|
|
448
1496
|
/**
|
|
449
1497
|
* Register a tool with the AI provider
|