@juspay/neurolink 2.1.0 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +36 -9
- package/README.md +17 -39
- package/dist/cli/index.js +40 -18
- package/dist/lib/mcp/plugins/filesystem-mcp.d.ts +1 -1
- package/dist/lib/neurolink.d.ts +2 -0
- package/dist/lib/neurolink.js +5 -3
- package/dist/lib/providers/agent-enhanced-provider.js +61 -53
- package/dist/lib/providers/amazonBedrock.js +11 -7
- package/dist/lib/providers/anthropic.js +13 -11
- package/dist/lib/providers/azureOpenAI.js +10 -10
- package/dist/lib/providers/googleAIStudio.js +14 -7
- package/dist/lib/providers/googleVertexAI.js +14 -7
- package/dist/lib/providers/huggingFace.js +11 -7
- package/dist/lib/providers/mistralAI.js +11 -7
- package/dist/lib/providers/ollama.js +12 -4
- package/dist/lib/providers/openAI.js +11 -7
- package/dist/lib/providers/timeout-wrapper.d.ts +2 -2
- package/dist/lib/providers/timeout-wrapper.js +3 -3
- package/dist/lib/proxy/proxy-fetch.d.ts +18 -0
- package/dist/lib/proxy/proxy-fetch.js +64 -0
- package/dist/lib/utils/timeout.d.ts +4 -4
- package/dist/lib/utils/timeout.js +42 -34
- package/dist/mcp/plugins/filesystem-mcp.d.ts +1 -1
- package/dist/mcp/plugins/filesystem-mcp.js +1 -1
- package/dist/neurolink.d.ts +2 -0
- package/dist/neurolink.js +5 -3
- package/dist/providers/agent-enhanced-provider.js +61 -53
- package/dist/providers/amazonBedrock.js +11 -7
- package/dist/providers/anthropic.js +13 -11
- package/dist/providers/azureOpenAI.js +10 -10
- package/dist/providers/googleAIStudio.js +14 -7
- package/dist/providers/googleVertexAI.js +14 -7
- package/dist/providers/huggingFace.js +11 -7
- package/dist/providers/mistralAI.js +11 -7
- package/dist/providers/ollama.js +12 -4
- package/dist/providers/openAI.js +11 -7
- package/dist/providers/timeout-wrapper.d.ts +2 -2
- package/dist/providers/timeout-wrapper.js +3 -3
- package/dist/proxy/proxy-fetch.d.ts +18 -0
- package/dist/proxy/proxy-fetch.js +64 -0
- package/dist/utils/timeout.d.ts +4 -4
- package/dist/utils/timeout.js +42 -34
- package/package.json +2 -1
|
@@ -66,14 +66,15 @@ export class AgentEnhancedProvider {
|
|
|
66
66
|
try {
|
|
67
67
|
mcpLogger.info("[AgentEnhancedProvider] Initializing MCP integration...");
|
|
68
68
|
this.mcpSystem = new UnifiedMCPSystem({
|
|
69
|
-
configPath: this.config.mcpDiscoveryOptions?.configFiles?.[0] ||
|
|
69
|
+
configPath: this.config.mcpDiscoveryOptions?.configFiles?.[0] ||
|
|
70
|
+
".mcp-config.json",
|
|
70
71
|
enableExternalServers: true,
|
|
71
72
|
enableInternalServers: true,
|
|
72
|
-
autoInitialize: false
|
|
73
|
+
autoInitialize: false,
|
|
73
74
|
});
|
|
74
75
|
// ADD TIMEOUT to prevent hanging forever
|
|
75
76
|
const initPromise = this.mcpSystem.initialize();
|
|
76
|
-
const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error(
|
|
77
|
+
const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error("MCP initialization timeout after 15 seconds")), this.config.mcpInitTimeoutMs || 15000));
|
|
77
78
|
await Promise.race([initPromise, timeoutPromise]);
|
|
78
79
|
this.mcpInitialized = true;
|
|
79
80
|
mcpLogger.info("[AgentEnhancedProvider] MCP integration initialized successfully");
|
|
@@ -101,10 +102,13 @@ export class AgentEnhancedProvider {
|
|
|
101
102
|
return directTools;
|
|
102
103
|
}
|
|
103
104
|
// Get MCP tools if available
|
|
104
|
-
|
|
105
|
+
const mcpTools = {};
|
|
105
106
|
try {
|
|
106
107
|
// Skip if MCP failed to initialize or is still initializing
|
|
107
|
-
if (this.mcpInitFailed ||
|
|
108
|
+
if (this.mcpInitFailed ||
|
|
109
|
+
this.mcpInitializing ||
|
|
110
|
+
!this.mcpInitialized ||
|
|
111
|
+
!this.mcpSystem) {
|
|
108
112
|
return directTools;
|
|
109
113
|
}
|
|
110
114
|
const mcpToolInfos = await this.mcpSystem.listTools();
|
|
@@ -123,7 +127,7 @@ export class AgentEnhancedProvider {
|
|
|
123
127
|
? new AbortController()
|
|
124
128
|
: undefined;
|
|
125
129
|
if (toolAbortController && toolTimeout) {
|
|
126
|
-
const timeoutMs = typeof toolTimeout ===
|
|
130
|
+
const timeoutMs = typeof toolTimeout === "string"
|
|
127
131
|
? parseTimeout(toolTimeout)
|
|
128
132
|
: toolTimeout;
|
|
129
133
|
timeoutId = setTimeout(() => {
|
|
@@ -131,31 +135,35 @@ export class AgentEnhancedProvider {
|
|
|
131
135
|
}, timeoutMs);
|
|
132
136
|
}
|
|
133
137
|
const context = {
|
|
134
|
-
sessionId:
|
|
135
|
-
userId:
|
|
138
|
+
sessionId: "cli-session",
|
|
139
|
+
userId: "cli-user",
|
|
136
140
|
secureFS: {
|
|
137
141
|
readFile: async (path, encoding) => {
|
|
138
|
-
const fs = await import(
|
|
139
|
-
return encoding
|
|
142
|
+
const fs = await import("fs/promises");
|
|
143
|
+
return encoding
|
|
144
|
+
? fs.readFile(path, {
|
|
145
|
+
encoding: encoding,
|
|
146
|
+
})
|
|
147
|
+
: fs.readFile(path);
|
|
140
148
|
},
|
|
141
149
|
writeFile: async (path, content) => {
|
|
142
|
-
const fs = await import(
|
|
150
|
+
const fs = await import("fs/promises");
|
|
143
151
|
await fs.writeFile(path, content);
|
|
144
152
|
},
|
|
145
153
|
readdir: async (path) => {
|
|
146
|
-
const fs = await import(
|
|
154
|
+
const fs = await import("fs/promises");
|
|
147
155
|
return fs.readdir(path);
|
|
148
156
|
},
|
|
149
157
|
stat: async (path) => {
|
|
150
|
-
const fs = await import(
|
|
158
|
+
const fs = await import("fs/promises");
|
|
151
159
|
return fs.stat(path);
|
|
152
160
|
},
|
|
153
161
|
mkdir: async (path, options) => {
|
|
154
|
-
const fs = await import(
|
|
162
|
+
const fs = await import("fs/promises");
|
|
155
163
|
await fs.mkdir(path, options);
|
|
156
164
|
},
|
|
157
165
|
exists: async (path) => {
|
|
158
|
-
const fs = await import(
|
|
166
|
+
const fs = await import("fs/promises");
|
|
159
167
|
try {
|
|
160
168
|
await fs.access(path);
|
|
161
169
|
return true;
|
|
@@ -163,34 +171,34 @@ export class AgentEnhancedProvider {
|
|
|
163
171
|
catch {
|
|
164
172
|
return false;
|
|
165
173
|
}
|
|
166
|
-
}
|
|
174
|
+
},
|
|
167
175
|
},
|
|
168
176
|
path: {
|
|
169
177
|
join: (...paths) => {
|
|
170
|
-
const path = require(
|
|
178
|
+
const path = require("path");
|
|
171
179
|
return path.join(...paths);
|
|
172
180
|
},
|
|
173
181
|
resolve: (...paths) => {
|
|
174
|
-
const path = require(
|
|
182
|
+
const path = require("path");
|
|
175
183
|
return path.resolve(...paths);
|
|
176
184
|
},
|
|
177
185
|
relative: (from, to) => {
|
|
178
|
-
const path = require(
|
|
186
|
+
const path = require("path");
|
|
179
187
|
return path.relative(from, to);
|
|
180
188
|
},
|
|
181
189
|
dirname: (path) => {
|
|
182
|
-
const pathLib = require(
|
|
190
|
+
const pathLib = require("path");
|
|
183
191
|
return pathLib.dirname(path);
|
|
184
192
|
},
|
|
185
193
|
basename: (path, ext) => {
|
|
186
|
-
const pathLib = require(
|
|
194
|
+
const pathLib = require("path");
|
|
187
195
|
return pathLib.basename(path, ext);
|
|
188
|
-
}
|
|
196
|
+
},
|
|
189
197
|
},
|
|
190
|
-
grantedPermissions: [
|
|
198
|
+
grantedPermissions: ["read", "write", "execute"],
|
|
191
199
|
log: (level, message, data) => {
|
|
192
200
|
const logFn = mcpLogger[level];
|
|
193
|
-
if (typeof logFn ===
|
|
201
|
+
if (typeof logFn === "function") {
|
|
194
202
|
if (data) {
|
|
195
203
|
logFn(`${message} ${JSON.stringify(data)}`);
|
|
196
204
|
}
|
|
@@ -198,7 +206,7 @@ export class AgentEnhancedProvider {
|
|
|
198
206
|
logFn(message);
|
|
199
207
|
}
|
|
200
208
|
}
|
|
201
|
-
}
|
|
209
|
+
},
|
|
202
210
|
};
|
|
203
211
|
const toolPromise = this.mcpSystem.executeTool(toolInfo.name, args, context);
|
|
204
212
|
let result;
|
|
@@ -207,10 +215,10 @@ export class AgentEnhancedProvider {
|
|
|
207
215
|
result = await Promise.race([
|
|
208
216
|
toolPromise,
|
|
209
217
|
new Promise((_, reject) => {
|
|
210
|
-
toolAbortController.signal.addEventListener(
|
|
218
|
+
toolAbortController.signal.addEventListener("abort", () => {
|
|
211
219
|
reject(new Error(`Tool ${toolInfo.name} timed out after ${this.config.toolExecutionTimeout}`));
|
|
212
220
|
});
|
|
213
|
-
})
|
|
221
|
+
}),
|
|
214
222
|
]);
|
|
215
223
|
}
|
|
216
224
|
else {
|
|
@@ -230,7 +238,7 @@ export class AgentEnhancedProvider {
|
|
|
230
238
|
mcpLogger.error(`MCP tool ${toolInfo.name} execution failed:`, error);
|
|
231
239
|
throw error;
|
|
232
240
|
}
|
|
233
|
-
}
|
|
241
|
+
},
|
|
234
242
|
};
|
|
235
243
|
}
|
|
236
244
|
mcpLogger.info(`[AgentEnhancedProvider] Loaded ${Object.keys(mcpTools).length} MCP tools`);
|
|
@@ -246,22 +254,20 @@ export class AgentEnhancedProvider {
|
|
|
246
254
|
: optionsOrPrompt;
|
|
247
255
|
const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt, schema, timeout, } = options;
|
|
248
256
|
// Get combined tools (direct + MCP) if enabled
|
|
249
|
-
const tools = this.config.enableTools
|
|
250
|
-
? await this.getCombinedTools()
|
|
251
|
-
: {};
|
|
257
|
+
const tools = this.config.enableTools ? await this.getCombinedTools() : {};
|
|
252
258
|
const log = (msg, data) => {
|
|
253
|
-
mcpLogger.info(`[AgentEnhancedProvider] ${msg}`, data ? JSON.stringify(data, null, 2) :
|
|
259
|
+
mcpLogger.info(`[AgentEnhancedProvider] ${msg}`, data ? JSON.stringify(data, null, 2) : "");
|
|
254
260
|
};
|
|
255
|
-
log(
|
|
261
|
+
log("Starting text generation", {
|
|
256
262
|
prompt: prompt.substring(0, 100),
|
|
257
263
|
toolsCount: Object.keys(tools).length,
|
|
258
|
-
maxSteps: this.config.maxSteps
|
|
264
|
+
maxSteps: this.config.maxSteps,
|
|
259
265
|
});
|
|
260
266
|
try {
|
|
261
267
|
// Parse timeout if provided
|
|
262
268
|
let abortSignal;
|
|
263
269
|
if (timeout) {
|
|
264
|
-
const timeoutMs = typeof timeout ===
|
|
270
|
+
const timeoutMs = typeof timeout === "string" ? parseTimeout(timeout) : timeout;
|
|
265
271
|
if (timeoutMs !== undefined) {
|
|
266
272
|
abortSignal = AbortSignal.timeout(timeoutMs);
|
|
267
273
|
}
|
|
@@ -279,24 +285,26 @@ export class AgentEnhancedProvider {
|
|
|
279
285
|
toolChoice: this.shouldForceToolUsage(prompt) ? "required" : "auto",
|
|
280
286
|
abortSignal, // Pass abort signal for timeout support
|
|
281
287
|
});
|
|
282
|
-
log(
|
|
288
|
+
log("Generation completed", {
|
|
283
289
|
text: result.text?.substring(0, 200),
|
|
284
290
|
finishReason: result.finishReason,
|
|
285
291
|
toolCallsCount: result.toolCalls?.length || 0,
|
|
286
292
|
toolResultsCount: result.toolResults?.length || 0,
|
|
287
|
-
stepsCount: result.steps?.length || 0
|
|
293
|
+
stepsCount: result.steps?.length || 0,
|
|
288
294
|
});
|
|
289
295
|
// Check if tools were called but no final text was generated
|
|
290
|
-
if (result.finishReason ===
|
|
291
|
-
|
|
296
|
+
if (result.finishReason === "tool-calls" &&
|
|
297
|
+
!result.text &&
|
|
298
|
+
result.toolResults?.length > 0) {
|
|
299
|
+
log("Tools called but no final text generated, creating summary response");
|
|
292
300
|
try {
|
|
293
301
|
// Extract tool results and create a summary prompt
|
|
294
|
-
let toolResultsSummary =
|
|
302
|
+
let toolResultsSummary = "";
|
|
295
303
|
if (result.toolResults) {
|
|
296
304
|
for (const toolResult of result.toolResults) {
|
|
297
305
|
const resultData = toolResult.result || toolResult;
|
|
298
306
|
// Try to extract meaningful data from the result
|
|
299
|
-
if (typeof resultData ===
|
|
307
|
+
if (typeof resultData === "object" && resultData !== null) {
|
|
300
308
|
if (resultData.success && resultData.items) {
|
|
301
309
|
// This looks like a filesystem listing
|
|
302
310
|
toolResultsSummary += `Directory listing for ${resultData.path}:\n`;
|
|
@@ -311,34 +319,36 @@ export class AgentEnhancedProvider {
|
|
|
311
319
|
else {
|
|
312
320
|
toolResultsSummary += String(resultData);
|
|
313
321
|
}
|
|
314
|
-
toolResultsSummary +=
|
|
322
|
+
toolResultsSummary += "\n\n";
|
|
315
323
|
}
|
|
316
324
|
}
|
|
317
|
-
log(
|
|
325
|
+
log("Tool results extracted", {
|
|
318
326
|
summaryLength: toolResultsSummary.length,
|
|
319
|
-
preview: toolResultsSummary.substring(0, 200)
|
|
327
|
+
preview: toolResultsSummary.substring(0, 200),
|
|
320
328
|
});
|
|
321
329
|
// Create a simple, direct summary
|
|
322
330
|
const finalText = `Based on the user request "${prompt}", here's what I found:\n\n${toolResultsSummary}`;
|
|
323
|
-
log(
|
|
331
|
+
log("Final text created", {
|
|
324
332
|
textLength: finalText.length,
|
|
325
|
-
preview: finalText.substring(0, 200)
|
|
333
|
+
preview: finalText.substring(0, 200),
|
|
326
334
|
});
|
|
327
335
|
// Return result with the formatted text
|
|
328
336
|
return {
|
|
329
337
|
...result,
|
|
330
338
|
text: finalText,
|
|
331
|
-
finishReason:
|
|
339
|
+
finishReason: "stop",
|
|
332
340
|
};
|
|
333
341
|
}
|
|
334
342
|
catch (error) {
|
|
335
|
-
log(
|
|
343
|
+
log("Error in summary generation", {
|
|
344
|
+
error: error instanceof Error ? error.message : String(error),
|
|
345
|
+
});
|
|
336
346
|
// Fallback: return raw tool results
|
|
337
347
|
const fallbackText = `Tool execution completed. Raw results: ${JSON.stringify(result.toolResults, null, 2)}`;
|
|
338
348
|
return {
|
|
339
349
|
...result,
|
|
340
350
|
text: fallbackText,
|
|
341
|
-
finishReason:
|
|
351
|
+
finishReason: "stop",
|
|
342
352
|
};
|
|
343
353
|
}
|
|
344
354
|
}
|
|
@@ -356,14 +366,12 @@ export class AgentEnhancedProvider {
|
|
|
356
366
|
: optionsOrPrompt;
|
|
357
367
|
const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt, timeout, } = options;
|
|
358
368
|
// Get combined tools (direct + MCP) if enabled
|
|
359
|
-
const tools = this.config.enableTools
|
|
360
|
-
? await this.getCombinedTools()
|
|
361
|
-
: {};
|
|
369
|
+
const tools = this.config.enableTools ? await this.getCombinedTools() : {};
|
|
362
370
|
try {
|
|
363
371
|
// Parse timeout if provided
|
|
364
372
|
let abortSignal;
|
|
365
373
|
if (timeout) {
|
|
366
|
-
const timeoutMs = typeof timeout ===
|
|
374
|
+
const timeoutMs = typeof timeout === "string" ? parseTimeout(timeout) : timeout;
|
|
367
375
|
if (timeoutMs !== undefined) {
|
|
368
376
|
abortSignal = AbortSignal.timeout(timeoutMs);
|
|
369
377
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createAmazonBedrock } from "@ai-sdk/amazon-bedrock";
|
|
2
2
|
import { streamText, generateText, Output, } from "ai";
|
|
3
3
|
import { logger } from "../utils/logger.js";
|
|
4
|
-
import { createTimeoutController, TimeoutError, getDefaultTimeout } from "../utils/timeout.js";
|
|
4
|
+
import { createTimeoutController, TimeoutError, getDefaultTimeout, } from "../utils/timeout.js";
|
|
5
5
|
// Default system context
|
|
6
6
|
const DEFAULT_SYSTEM_CONTEXT = {
|
|
7
7
|
systemPrompt: "You are a helpful AI assistant.",
|
|
@@ -129,7 +129,7 @@ export class AmazonBedrock {
|
|
|
129
129
|
const options = typeof optionsOrPrompt === "string"
|
|
130
130
|
? { prompt: optionsOrPrompt }
|
|
131
131
|
: optionsOrPrompt;
|
|
132
|
-
const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema, timeout = getDefaultTimeout(provider,
|
|
132
|
+
const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema, timeout = getDefaultTimeout(provider, "stream"), } = options;
|
|
133
133
|
// Use schema from options or fallback parameter
|
|
134
134
|
const finalSchema = schema || analysisSchema;
|
|
135
135
|
logger.debug(`[${functionTag}] Stream request started`, {
|
|
@@ -141,7 +141,7 @@ export class AmazonBedrock {
|
|
|
141
141
|
timeout,
|
|
142
142
|
});
|
|
143
143
|
// Create timeout controller if timeout is specified
|
|
144
|
-
const timeoutController = createTimeoutController(timeout, provider,
|
|
144
|
+
const timeoutController = createTimeoutController(timeout, provider, "stream");
|
|
145
145
|
const streamOptions = {
|
|
146
146
|
model: this.model,
|
|
147
147
|
prompt: prompt,
|
|
@@ -149,7 +149,9 @@ export class AmazonBedrock {
|
|
|
149
149
|
temperature,
|
|
150
150
|
maxTokens,
|
|
151
151
|
// Add abort signal if available
|
|
152
|
-
...(timeoutController && {
|
|
152
|
+
...(timeoutController && {
|
|
153
|
+
abortSignal: timeoutController.controller.signal,
|
|
154
|
+
}),
|
|
153
155
|
onError: (event) => {
|
|
154
156
|
const error = event.error;
|
|
155
157
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -234,7 +236,7 @@ export class AmazonBedrock {
|
|
|
234
236
|
const options = typeof optionsOrPrompt === "string"
|
|
235
237
|
? { prompt: optionsOrPrompt }
|
|
236
238
|
: optionsOrPrompt;
|
|
237
|
-
const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema, timeout = getDefaultTimeout(provider,
|
|
239
|
+
const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema, timeout = getDefaultTimeout(provider, "generate"), } = options;
|
|
238
240
|
// Use schema from options or fallback parameter
|
|
239
241
|
const finalSchema = schema || analysisSchema;
|
|
240
242
|
logger.debug(`[${functionTag}] Generate text started`, {
|
|
@@ -247,7 +249,7 @@ export class AmazonBedrock {
|
|
|
247
249
|
timeout,
|
|
248
250
|
});
|
|
249
251
|
// Create timeout controller if timeout is specified
|
|
250
|
-
const timeoutController = createTimeoutController(timeout, provider,
|
|
252
|
+
const timeoutController = createTimeoutController(timeout, provider, "generate");
|
|
251
253
|
const generateOptions = {
|
|
252
254
|
model: this.model,
|
|
253
255
|
prompt: prompt,
|
|
@@ -255,7 +257,9 @@ export class AmazonBedrock {
|
|
|
255
257
|
temperature,
|
|
256
258
|
maxTokens,
|
|
257
259
|
// Add abort signal if available
|
|
258
|
-
...(timeoutController && {
|
|
260
|
+
...(timeoutController && {
|
|
261
|
+
abortSignal: timeoutController.controller.signal,
|
|
262
|
+
}),
|
|
259
263
|
};
|
|
260
264
|
if (finalSchema) {
|
|
261
265
|
generateOptions.experimental_output = Output.object({
|
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { AIProviderName } from "../core/types.js";
|
|
8
8
|
import { logger } from "../utils/logger.js";
|
|
9
|
-
import { createTimeoutController, TimeoutError, getDefaultTimeout } from "../utils/timeout.js";
|
|
9
|
+
import { createTimeoutController, TimeoutError, getDefaultTimeout, } from "../utils/timeout.js";
|
|
10
|
+
import { createProxyFetch } from "../proxy/proxy-fetch.js";
|
|
10
11
|
export class AnthropicProvider {
|
|
11
12
|
name = AIProviderName.ANTHROPIC;
|
|
12
13
|
apiKey;
|
|
@@ -40,7 +41,8 @@ export class AnthropicProvider {
|
|
|
40
41
|
};
|
|
41
42
|
logger.debug(`[AnthropicProvider.makeRequest] ${stream ? "Streaming" : "Non-streaming"} request to ${url}`);
|
|
42
43
|
logger.debug(`[AnthropicProvider.makeRequest] Model: ${body.model}, Max tokens: ${body.max_tokens}`);
|
|
43
|
-
const
|
|
44
|
+
const proxyFetch = createProxyFetch();
|
|
45
|
+
const response = await proxyFetch(url, {
|
|
44
46
|
method: "POST",
|
|
45
47
|
headers,
|
|
46
48
|
body: JSON.stringify(body),
|
|
@@ -61,7 +63,7 @@ export class AnthropicProvider {
|
|
|
61
63
|
const options = typeof optionsOrPrompt === "string"
|
|
62
64
|
? { prompt: optionsOrPrompt }
|
|
63
65
|
: optionsOrPrompt;
|
|
64
|
-
const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = "You are Claude, an AI assistant created by Anthropic. You are helpful, harmless, and honest.", timeout = getDefaultTimeout(provider,
|
|
66
|
+
const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = "You are Claude, an AI assistant created by Anthropic. You are helpful, harmless, and honest.", timeout = getDefaultTimeout(provider, "generate"), } = options;
|
|
65
67
|
logger.debug(`[${functionTag}] Prompt: "${prompt.substring(0, 100)}...", Temperature: ${temperature}, Max tokens: ${maxTokens}, Timeout: ${timeout}`);
|
|
66
68
|
const requestBody = {
|
|
67
69
|
model: this.getModel(),
|
|
@@ -76,7 +78,7 @@ export class AnthropicProvider {
|
|
|
76
78
|
system: systemPrompt,
|
|
77
79
|
};
|
|
78
80
|
// Create timeout controller if timeout is specified
|
|
79
|
-
const timeoutController = createTimeoutController(timeout, provider,
|
|
81
|
+
const timeoutController = createTimeoutController(timeout, provider, "generate");
|
|
80
82
|
try {
|
|
81
83
|
const response = await this.makeRequest("messages", requestBody, false, timeoutController?.controller.signal);
|
|
82
84
|
const data = await response.json();
|
|
@@ -107,9 +109,9 @@ export class AnthropicProvider {
|
|
|
107
109
|
message: error.message,
|
|
108
110
|
});
|
|
109
111
|
}
|
|
110
|
-
else if (error?.name ===
|
|
112
|
+
else if (error?.name === "AbortError") {
|
|
111
113
|
// Convert AbortError to TimeoutError
|
|
112
|
-
const timeoutError = new TimeoutError(`${provider} generate operation timed out after ${timeout}`, timeoutController?.timeoutMs || 0, provider,
|
|
114
|
+
const timeoutError = new TimeoutError(`${provider} generate operation timed out after ${timeout}`, timeoutController?.timeoutMs || 0, provider, "generate");
|
|
113
115
|
logger.error(`[${functionTag}] Timeout error`, {
|
|
114
116
|
provider,
|
|
115
117
|
timeout: timeoutController?.timeoutMs,
|
|
@@ -131,7 +133,7 @@ export class AnthropicProvider {
|
|
|
131
133
|
const options = typeof optionsOrPrompt === "string"
|
|
132
134
|
? { prompt: optionsOrPrompt }
|
|
133
135
|
: optionsOrPrompt;
|
|
134
|
-
const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = "You are Claude, an AI assistant created by Anthropic. You are helpful, harmless, and honest.", timeout = getDefaultTimeout(provider,
|
|
136
|
+
const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = "You are Claude, an AI assistant created by Anthropic. You are helpful, harmless, and honest.", timeout = getDefaultTimeout(provider, "stream"), } = options;
|
|
135
137
|
logger.debug(`[${functionTag}] Streaming prompt: "${prompt.substring(0, 100)}...", Timeout: ${timeout}`);
|
|
136
138
|
const requestBody = {
|
|
137
139
|
model: this.getModel(),
|
|
@@ -147,7 +149,7 @@ export class AnthropicProvider {
|
|
|
147
149
|
stream: true,
|
|
148
150
|
};
|
|
149
151
|
// Create timeout controller if timeout is specified
|
|
150
|
-
const timeoutController = createTimeoutController(timeout, provider,
|
|
152
|
+
const timeoutController = createTimeoutController(timeout, provider, "stream");
|
|
151
153
|
try {
|
|
152
154
|
const response = await this.makeRequest("messages", requestBody, true, timeoutController?.controller.signal);
|
|
153
155
|
if (!response.body) {
|
|
@@ -174,9 +176,9 @@ export class AnthropicProvider {
|
|
|
174
176
|
message: error.message,
|
|
175
177
|
});
|
|
176
178
|
}
|
|
177
|
-
else if (error?.name ===
|
|
179
|
+
else if (error?.name === "AbortError") {
|
|
178
180
|
// Convert AbortError to TimeoutError
|
|
179
|
-
const timeoutError = new TimeoutError(`${provider} stream operation timed out after ${timeout}`, timeoutController?.timeoutMs || 0, provider,
|
|
181
|
+
const timeoutError = new TimeoutError(`${provider} stream operation timed out after ${timeout}`, timeoutController?.timeoutMs || 0, provider, "stream");
|
|
180
182
|
logger.error(`[${functionTag}] Timeout error`, {
|
|
181
183
|
provider,
|
|
182
184
|
timeout: timeoutController?.timeoutMs,
|
|
@@ -198,7 +200,7 @@ export class AnthropicProvider {
|
|
|
198
200
|
while (true) {
|
|
199
201
|
// Check if aborted
|
|
200
202
|
if (signal?.aborted) {
|
|
201
|
-
throw new Error(
|
|
203
|
+
throw new Error("AbortError");
|
|
202
204
|
}
|
|
203
205
|
const { done, value } = await reader.read();
|
|
204
206
|
if (done) {
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { AIProviderName } from "../core/types.js";
|
|
8
8
|
import { logger } from "../utils/logger.js";
|
|
9
|
-
import { createTimeoutController, TimeoutError, getDefaultTimeout } from "../utils/timeout.js";
|
|
9
|
+
import { createTimeoutController, TimeoutError, getDefaultTimeout, } from "../utils/timeout.js";
|
|
10
10
|
export class AzureOpenAIProvider {
|
|
11
11
|
name = AIProviderName.AZURE;
|
|
12
12
|
apiKey;
|
|
@@ -74,7 +74,7 @@ export class AzureOpenAIProvider {
|
|
|
74
74
|
const options = typeof optionsOrPrompt === "string"
|
|
75
75
|
? { prompt: optionsOrPrompt }
|
|
76
76
|
: optionsOrPrompt;
|
|
77
|
-
const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = "You are a helpful AI assistant.", timeout = getDefaultTimeout(provider,
|
|
77
|
+
const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = "You are a helpful AI assistant.", timeout = getDefaultTimeout(provider, "generate"), } = options;
|
|
78
78
|
logger.debug(`[${functionTag}] Prompt: "${prompt.substring(0, 100)}...", Temperature: ${temperature}, Max tokens: ${maxTokens}, Timeout: ${timeout}`);
|
|
79
79
|
const messages = [];
|
|
80
80
|
if (systemPrompt) {
|
|
@@ -93,7 +93,7 @@ export class AzureOpenAIProvider {
|
|
|
93
93
|
max_tokens: maxTokens,
|
|
94
94
|
};
|
|
95
95
|
// Create timeout controller if timeout is specified
|
|
96
|
-
const timeoutController = createTimeoutController(timeout, provider,
|
|
96
|
+
const timeoutController = createTimeoutController(timeout, provider, "generate");
|
|
97
97
|
try {
|
|
98
98
|
const response = await this.makeRequest(requestBody, false, timeoutController?.controller.signal);
|
|
99
99
|
const data = await response.json();
|
|
@@ -124,9 +124,9 @@ export class AzureOpenAIProvider {
|
|
|
124
124
|
message: error.message,
|
|
125
125
|
});
|
|
126
126
|
}
|
|
127
|
-
else if (error?.name ===
|
|
127
|
+
else if (error?.name === "AbortError") {
|
|
128
128
|
// Convert AbortError to TimeoutError
|
|
129
|
-
const timeoutError = new TimeoutError(`${provider} generate operation timed out after ${timeout}`, timeoutController?.timeoutMs || 0, provider,
|
|
129
|
+
const timeoutError = new TimeoutError(`${provider} generate operation timed out after ${timeout}`, timeoutController?.timeoutMs || 0, provider, "generate");
|
|
130
130
|
logger.error(`[${functionTag}] Timeout error`, {
|
|
131
131
|
provider,
|
|
132
132
|
timeout: timeoutController?.timeoutMs,
|
|
@@ -148,7 +148,7 @@ export class AzureOpenAIProvider {
|
|
|
148
148
|
const options = typeof optionsOrPrompt === "string"
|
|
149
149
|
? { prompt: optionsOrPrompt }
|
|
150
150
|
: optionsOrPrompt;
|
|
151
|
-
const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = "You are a helpful AI assistant.", timeout = getDefaultTimeout(provider,
|
|
151
|
+
const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = "You are a helpful AI assistant.", timeout = getDefaultTimeout(provider, "stream"), } = options;
|
|
152
152
|
logger.debug(`[${functionTag}] Streaming prompt: "${prompt.substring(0, 100)}...", Timeout: ${timeout}`);
|
|
153
153
|
const messages = [];
|
|
154
154
|
if (systemPrompt) {
|
|
@@ -168,7 +168,7 @@ export class AzureOpenAIProvider {
|
|
|
168
168
|
stream: true,
|
|
169
169
|
};
|
|
170
170
|
// Create timeout controller if timeout is specified
|
|
171
|
-
const timeoutController = createTimeoutController(timeout, provider,
|
|
171
|
+
const timeoutController = createTimeoutController(timeout, provider, "stream");
|
|
172
172
|
try {
|
|
173
173
|
const response = await this.makeRequest(requestBody, true, timeoutController?.controller.signal);
|
|
174
174
|
if (!response.body) {
|
|
@@ -195,9 +195,9 @@ export class AzureOpenAIProvider {
|
|
|
195
195
|
message: error.message,
|
|
196
196
|
});
|
|
197
197
|
}
|
|
198
|
-
else if (error?.name ===
|
|
198
|
+
else if (error?.name === "AbortError") {
|
|
199
199
|
// Convert AbortError to TimeoutError
|
|
200
|
-
const timeoutError = new TimeoutError(`${provider} stream operation timed out after ${timeout}`, timeoutController?.timeoutMs || 0, provider,
|
|
200
|
+
const timeoutError = new TimeoutError(`${provider} stream operation timed out after ${timeout}`, timeoutController?.timeoutMs || 0, provider, "stream");
|
|
201
201
|
logger.error(`[${functionTag}] Timeout error`, {
|
|
202
202
|
provider,
|
|
203
203
|
timeout: timeoutController?.timeoutMs,
|
|
@@ -219,7 +219,7 @@ export class AzureOpenAIProvider {
|
|
|
219
219
|
while (true) {
|
|
220
220
|
// Check if aborted
|
|
221
221
|
if (signal?.aborted) {
|
|
222
|
-
throw new Error(
|
|
222
|
+
throw new Error("AbortError");
|
|
223
223
|
}
|
|
224
224
|
const { done, value } = await reader.read();
|
|
225
225
|
if (done) {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { createGoogleGenerativeAI } from "@ai-sdk/google";
|
|
2
2
|
import { streamText, generateText, Output, } from "ai";
|
|
3
3
|
import { logger } from "../utils/logger.js";
|
|
4
|
-
import { createTimeoutController, TimeoutError, getDefaultTimeout } from "../utils/timeout.js";
|
|
4
|
+
import { createTimeoutController, TimeoutError, getDefaultTimeout, } from "../utils/timeout.js";
|
|
5
|
+
import { createProxyFetch } from "../proxy/proxy-fetch.js";
|
|
5
6
|
// CRITICAL: Setup environment variables early for AI SDK compatibility
|
|
6
7
|
// The AI SDK specifically looks for GOOGLE_GENERATIVE_AI_API_KEY
|
|
7
8
|
// We need to ensure this is set before any AI SDK operations
|
|
@@ -39,8 +40,10 @@ let _google = null;
|
|
|
39
40
|
function getGoogleInstance() {
|
|
40
41
|
if (!_google) {
|
|
41
42
|
const apiKey = getGoogleAIApiKey();
|
|
43
|
+
const proxyFetch = createProxyFetch();
|
|
42
44
|
_google = createGoogleGenerativeAI({
|
|
43
45
|
apiKey: apiKey,
|
|
46
|
+
fetch: proxyFetch,
|
|
44
47
|
headers: {
|
|
45
48
|
"X-Powered-By": "NeuroLink",
|
|
46
49
|
},
|
|
@@ -110,7 +113,7 @@ export class GoogleAIStudio {
|
|
|
110
113
|
const options = typeof optionsOrPrompt === "string"
|
|
111
114
|
? { prompt: optionsOrPrompt }
|
|
112
115
|
: optionsOrPrompt;
|
|
113
|
-
const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema, tools, timeout = getDefaultTimeout(provider,
|
|
116
|
+
const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema, tools, timeout = getDefaultTimeout(provider, "stream"), } = options;
|
|
114
117
|
// Use schema from options or fallback parameter
|
|
115
118
|
const finalSchema = schema || analysisSchema;
|
|
116
119
|
logger.debug(`[${functionTag}] Stream request started`, {
|
|
@@ -126,7 +129,7 @@ export class GoogleAIStudio {
|
|
|
126
129
|
});
|
|
127
130
|
const model = this.getModel();
|
|
128
131
|
// Create timeout controller if timeout is specified
|
|
129
|
-
const timeoutController = createTimeoutController(timeout, provider,
|
|
132
|
+
const timeoutController = createTimeoutController(timeout, provider, "stream");
|
|
130
133
|
const streamOptions = {
|
|
131
134
|
model: model,
|
|
132
135
|
prompt: prompt,
|
|
@@ -135,7 +138,9 @@ export class GoogleAIStudio {
|
|
|
135
138
|
maxTokens,
|
|
136
139
|
...(tools && { tools }), // Add tools if provided
|
|
137
140
|
// Add abort signal if available
|
|
138
|
-
...(timeoutController && {
|
|
141
|
+
...(timeoutController && {
|
|
142
|
+
abortSignal: timeoutController.controller.signal,
|
|
143
|
+
}),
|
|
139
144
|
onError: (event) => {
|
|
140
145
|
const error = event.error;
|
|
141
146
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -219,7 +224,7 @@ export class GoogleAIStudio {
|
|
|
219
224
|
const options = typeof optionsOrPrompt === "string"
|
|
220
225
|
? { prompt: optionsOrPrompt }
|
|
221
226
|
: optionsOrPrompt;
|
|
222
|
-
const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema, tools, timeout = getDefaultTimeout(provider,
|
|
227
|
+
const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema, tools, timeout = getDefaultTimeout(provider, "generate"), } = options;
|
|
223
228
|
// Use schema from options or fallback parameter
|
|
224
229
|
const finalSchema = schema || analysisSchema;
|
|
225
230
|
logger.debug(`[${functionTag}] Generate request started`, {
|
|
@@ -234,7 +239,7 @@ export class GoogleAIStudio {
|
|
|
234
239
|
});
|
|
235
240
|
const model = this.getModel();
|
|
236
241
|
// Create timeout controller if timeout is specified
|
|
237
|
-
const timeoutController = createTimeoutController(timeout, provider,
|
|
242
|
+
const timeoutController = createTimeoutController(timeout, provider, "generate");
|
|
238
243
|
const generateOptions = {
|
|
239
244
|
model: model,
|
|
240
245
|
prompt: prompt,
|
|
@@ -246,7 +251,9 @@ export class GoogleAIStudio {
|
|
|
246
251
|
maxSteps: 5, // Allow multiple steps for tool execution and response generation
|
|
247
252
|
}), // Add tools if provided
|
|
248
253
|
// Add abort signal if available
|
|
249
|
-
...(timeoutController && {
|
|
254
|
+
...(timeoutController && {
|
|
255
|
+
abortSignal: timeoutController.controller.signal,
|
|
256
|
+
}),
|
|
250
257
|
};
|
|
251
258
|
if (finalSchema) {
|
|
252
259
|
generateOptions.experimental_output = Output.object({
|