@juspay/neurolink 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/README.md +31 -5
- package/dist/cli/commands/config.d.ts +6 -6
- package/dist/cli/index.js +29 -30
- package/dist/core/types.d.ts +2 -0
- package/dist/lib/core/types.d.ts +2 -0
- package/dist/lib/neurolink.d.ts +2 -0
- package/dist/lib/neurolink.js +23 -2
- package/dist/lib/providers/agent-enhanced-provider.d.ts +1 -0
- package/dist/lib/providers/agent-enhanced-provider.js +59 -3
- package/dist/lib/providers/amazonBedrock.js +70 -24
- package/dist/lib/providers/anthropic.js +77 -15
- package/dist/lib/providers/azureOpenAI.js +77 -15
- package/dist/lib/providers/googleAIStudio.js +70 -26
- package/dist/lib/providers/googleVertexAI.js +70 -24
- package/dist/lib/providers/huggingFace.js +70 -26
- package/dist/lib/providers/mistralAI.js +70 -26
- package/dist/lib/providers/ollama.d.ts +1 -1
- package/dist/lib/providers/ollama.js +24 -10
- package/dist/lib/providers/openAI.js +67 -23
- package/dist/lib/providers/timeout-wrapper.d.ts +40 -0
- package/dist/lib/providers/timeout-wrapper.js +100 -0
- package/dist/lib/utils/timeout.d.ts +69 -0
- package/dist/lib/utils/timeout.js +130 -0
- package/dist/neurolink.d.ts +2 -0
- package/dist/neurolink.js +23 -2
- package/dist/providers/agent-enhanced-provider.d.ts +1 -0
- package/dist/providers/agent-enhanced-provider.js +59 -3
- package/dist/providers/amazonBedrock.js +70 -24
- package/dist/providers/anthropic.js +77 -15
- package/dist/providers/azureOpenAI.js +77 -15
- package/dist/providers/googleAIStudio.js +70 -26
- package/dist/providers/googleVertexAI.js +70 -24
- package/dist/providers/huggingFace.js +70 -26
- package/dist/providers/mistralAI.js +70 -26
- package/dist/providers/ollama.d.ts +1 -1
- package/dist/providers/ollama.js +24 -10
- package/dist/providers/openAI.js +67 -23
- package/dist/providers/timeout-wrapper.d.ts +40 -0
- package/dist/providers/timeout-wrapper.js +100 -0
- package/dist/utils/timeout.d.ts +69 -0
- package/dist/utils/timeout.js +130 -0
- package/package.json +1 -1
|
@@ -1,6 +1,7 @@
|
|
|
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
5
|
// CRITICAL: Setup environment variables early for AI SDK compatibility
|
|
5
6
|
// The AI SDK specifically looks for GOOGLE_GENERATIVE_AI_API_KEY
|
|
6
7
|
// We need to ensure this is set before any AI SDK operations
|
|
@@ -109,7 +110,7 @@ export class GoogleAIStudio {
|
|
|
109
110
|
const options = typeof optionsOrPrompt === "string"
|
|
110
111
|
? { prompt: optionsOrPrompt }
|
|
111
112
|
: optionsOrPrompt;
|
|
112
|
-
const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema, tools, } = options;
|
|
113
|
+
const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema, tools, timeout = getDefaultTimeout(provider, 'stream'), } = options;
|
|
113
114
|
// Use schema from options or fallback parameter
|
|
114
115
|
const finalSchema = schema || analysisSchema;
|
|
115
116
|
logger.debug(`[${functionTag}] Stream request started`, {
|
|
@@ -121,8 +122,11 @@ export class GoogleAIStudio {
|
|
|
121
122
|
hasSchema: !!finalSchema,
|
|
122
123
|
hasTools: !!tools,
|
|
123
124
|
toolCount: tools ? Object.keys(tools).length : 0,
|
|
125
|
+
timeout,
|
|
124
126
|
});
|
|
125
127
|
const model = this.getModel();
|
|
128
|
+
// Create timeout controller if timeout is specified
|
|
129
|
+
const timeoutController = createTimeoutController(timeout, provider, 'stream');
|
|
126
130
|
const streamOptions = {
|
|
127
131
|
model: model,
|
|
128
132
|
prompt: prompt,
|
|
@@ -130,6 +134,8 @@ export class GoogleAIStudio {
|
|
|
130
134
|
temperature,
|
|
131
135
|
maxTokens,
|
|
132
136
|
...(tools && { tools }), // Add tools if provided
|
|
137
|
+
// Add abort signal if available
|
|
138
|
+
...(timeoutController && { abortSignal: timeoutController.controller.signal }),
|
|
133
139
|
onError: (event) => {
|
|
134
140
|
const error = event.error;
|
|
135
141
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -171,18 +177,31 @@ export class GoogleAIStudio {
|
|
|
171
177
|
});
|
|
172
178
|
}
|
|
173
179
|
const result = streamText(streamOptions);
|
|
180
|
+
// For streaming, we can't clean up immediately, but the timeout will auto-clean
|
|
181
|
+
// The user should handle the stream and any timeout errors
|
|
174
182
|
return result;
|
|
175
183
|
}
|
|
176
184
|
catch (err) {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
}
|
|
185
|
+
// Log timeout errors specifically
|
|
186
|
+
if (err instanceof TimeoutError) {
|
|
187
|
+
logger.error(`[${functionTag}] Timeout error`, {
|
|
188
|
+
provider,
|
|
189
|
+
modelName: this.modelName,
|
|
190
|
+
timeout: err.timeout,
|
|
191
|
+
message: err.message,
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
logger.error(`[${functionTag}] Exception`, {
|
|
196
|
+
provider,
|
|
197
|
+
modelName: this.modelName,
|
|
198
|
+
message: "Error in streaming text",
|
|
199
|
+
err: String(err),
|
|
200
|
+
promptLength: typeof optionsOrPrompt === "string"
|
|
201
|
+
? optionsOrPrompt.length
|
|
202
|
+
: optionsOrPrompt.prompt.length,
|
|
203
|
+
});
|
|
204
|
+
}
|
|
186
205
|
throw err; // Re-throw error to trigger fallback
|
|
187
206
|
}
|
|
188
207
|
}
|
|
@@ -200,7 +219,7 @@ export class GoogleAIStudio {
|
|
|
200
219
|
const options = typeof optionsOrPrompt === "string"
|
|
201
220
|
? { prompt: optionsOrPrompt }
|
|
202
221
|
: optionsOrPrompt;
|
|
203
|
-
const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema, tools, } = options;
|
|
222
|
+
const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema, tools, timeout = getDefaultTimeout(provider, 'generate'), } = options;
|
|
204
223
|
// Use schema from options or fallback parameter
|
|
205
224
|
const finalSchema = schema || analysisSchema;
|
|
206
225
|
logger.debug(`[${functionTag}] Generate request started`, {
|
|
@@ -211,8 +230,11 @@ export class GoogleAIStudio {
|
|
|
211
230
|
maxTokens,
|
|
212
231
|
hasTools: !!tools,
|
|
213
232
|
toolCount: tools ? Object.keys(tools).length : 0,
|
|
233
|
+
timeout,
|
|
214
234
|
});
|
|
215
235
|
const model = this.getModel();
|
|
236
|
+
// Create timeout controller if timeout is specified
|
|
237
|
+
const timeoutController = createTimeoutController(timeout, provider, 'generate');
|
|
216
238
|
const generateOptions = {
|
|
217
239
|
model: model,
|
|
218
240
|
prompt: prompt,
|
|
@@ -223,29 +245,51 @@ export class GoogleAIStudio {
|
|
|
223
245
|
tools,
|
|
224
246
|
maxSteps: 5, // Allow multiple steps for tool execution and response generation
|
|
225
247
|
}), // Add tools if provided
|
|
248
|
+
// Add abort signal if available
|
|
249
|
+
...(timeoutController && { abortSignal: timeoutController.controller.signal }),
|
|
226
250
|
};
|
|
227
251
|
if (finalSchema) {
|
|
228
252
|
generateOptions.experimental_output = Output.object({
|
|
229
253
|
schema: finalSchema,
|
|
230
254
|
});
|
|
231
255
|
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
256
|
+
try {
|
|
257
|
+
const result = await generateText(generateOptions);
|
|
258
|
+
// Clean up timeout if successful
|
|
259
|
+
timeoutController?.cleanup();
|
|
260
|
+
logger.debug(`[${functionTag}] Generate text completed`, {
|
|
261
|
+
provider,
|
|
262
|
+
modelName: this.modelName,
|
|
263
|
+
usage: result.usage,
|
|
264
|
+
finishReason: result.finishReason,
|
|
265
|
+
responseLength: result.text?.length || 0,
|
|
266
|
+
timeout,
|
|
267
|
+
});
|
|
268
|
+
return result;
|
|
269
|
+
}
|
|
270
|
+
finally {
|
|
271
|
+
// Always cleanup timeout
|
|
272
|
+
timeoutController?.cleanup();
|
|
273
|
+
}
|
|
241
274
|
}
|
|
242
275
|
catch (err) {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
276
|
+
// Log timeout errors specifically
|
|
277
|
+
if (err instanceof TimeoutError) {
|
|
278
|
+
logger.error(`[${functionTag}] Timeout error`, {
|
|
279
|
+
provider,
|
|
280
|
+
modelName: this.modelName,
|
|
281
|
+
timeout: err.timeout,
|
|
282
|
+
message: err.message,
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
logger.error(`[${functionTag}] Exception`, {
|
|
287
|
+
provider,
|
|
288
|
+
modelName: this.modelName,
|
|
289
|
+
message: "Error in generating text",
|
|
290
|
+
err: String(err),
|
|
291
|
+
});
|
|
292
|
+
}
|
|
249
293
|
throw err; // Re-throw error to trigger fallback
|
|
250
294
|
}
|
|
251
295
|
}
|
|
@@ -23,6 +23,7 @@ async function getCreateVertexAnthropic() {
|
|
|
23
23
|
}
|
|
24
24
|
import { streamText, generateText, Output, } from "ai";
|
|
25
25
|
import { logger } from "../utils/logger.js";
|
|
26
|
+
import { createTimeoutController, TimeoutError, getDefaultTimeout } from "../utils/timeout.js";
|
|
26
27
|
// Default system context
|
|
27
28
|
const DEFAULT_SYSTEM_CONTEXT = {
|
|
28
29
|
systemPrompt: "You are a helpful AI assistant.",
|
|
@@ -285,7 +286,7 @@ export class GoogleVertexAI {
|
|
|
285
286
|
const options = typeof optionsOrPrompt === "string"
|
|
286
287
|
? { prompt: optionsOrPrompt }
|
|
287
288
|
: optionsOrPrompt;
|
|
288
|
-
const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema, } = options;
|
|
289
|
+
const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema, timeout = getDefaultTimeout(provider, 'stream'), } = options;
|
|
289
290
|
// Use schema from options or fallback parameter
|
|
290
291
|
const finalSchema = schema || analysisSchema;
|
|
291
292
|
logger.debug(`[${functionTag}] Stream request started`, {
|
|
@@ -296,14 +297,19 @@ export class GoogleVertexAI {
|
|
|
296
297
|
temperature,
|
|
297
298
|
maxTokens,
|
|
298
299
|
hasSchema: !!finalSchema,
|
|
300
|
+
timeout,
|
|
299
301
|
});
|
|
300
302
|
const model = await this.getModel();
|
|
303
|
+
// Create timeout controller if timeout is specified
|
|
304
|
+
const timeoutController = createTimeoutController(timeout, provider, 'stream');
|
|
301
305
|
const streamOptions = {
|
|
302
306
|
model: model,
|
|
303
307
|
prompt: prompt,
|
|
304
308
|
system: systemPrompt,
|
|
305
309
|
temperature,
|
|
306
310
|
maxTokens,
|
|
311
|
+
// Add abort signal if available
|
|
312
|
+
...(timeoutController && { abortSignal: timeoutController.controller.signal }),
|
|
307
313
|
onError: (event) => {
|
|
308
314
|
const error = event.error;
|
|
309
315
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -345,16 +351,30 @@ export class GoogleVertexAI {
|
|
|
345
351
|
});
|
|
346
352
|
}
|
|
347
353
|
const result = streamText(streamOptions);
|
|
354
|
+
// For streaming, we can't clean up immediately, but the timeout will auto-clean
|
|
355
|
+
// The user should handle the stream and any timeout errors
|
|
348
356
|
return result;
|
|
349
357
|
}
|
|
350
358
|
catch (err) {
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
359
|
+
// Log timeout errors specifically
|
|
360
|
+
if (err instanceof TimeoutError) {
|
|
361
|
+
logger.error(`[${functionTag}] Timeout error`, {
|
|
362
|
+
provider,
|
|
363
|
+
modelName: this.modelName,
|
|
364
|
+
isAnthropic: isAnthropicModel(this.modelName),
|
|
365
|
+
timeout: err.timeout,
|
|
366
|
+
message: err.message,
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
else {
|
|
370
|
+
logger.error(`[${functionTag}] Exception`, {
|
|
371
|
+
provider,
|
|
372
|
+
modelName: this.modelName,
|
|
373
|
+
message: "Error in streaming text",
|
|
374
|
+
err: String(err),
|
|
375
|
+
promptLength: prompt.length,
|
|
376
|
+
});
|
|
377
|
+
}
|
|
358
378
|
throw err; // Re-throw error to trigger fallback
|
|
359
379
|
}
|
|
360
380
|
}
|
|
@@ -372,7 +392,7 @@ export class GoogleVertexAI {
|
|
|
372
392
|
const options = typeof optionsOrPrompt === "string"
|
|
373
393
|
? { prompt: optionsOrPrompt }
|
|
374
394
|
: optionsOrPrompt;
|
|
375
|
-
const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema, } = options;
|
|
395
|
+
const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema, timeout = getDefaultTimeout(provider, 'generate'), } = options;
|
|
376
396
|
// Use schema from options or fallback parameter
|
|
377
397
|
const finalSchema = schema || analysisSchema;
|
|
378
398
|
logger.debug(`[${functionTag}] Generate request started`, {
|
|
@@ -382,37 +402,63 @@ export class GoogleVertexAI {
|
|
|
382
402
|
promptLength: prompt.length,
|
|
383
403
|
temperature,
|
|
384
404
|
maxTokens,
|
|
405
|
+
timeout,
|
|
385
406
|
});
|
|
386
407
|
const model = await this.getModel();
|
|
408
|
+
// Create timeout controller if timeout is specified
|
|
409
|
+
const timeoutController = createTimeoutController(timeout, provider, 'generate');
|
|
387
410
|
const generateOptions = {
|
|
388
411
|
model: model,
|
|
389
412
|
prompt: prompt,
|
|
390
413
|
system: systemPrompt,
|
|
391
414
|
temperature,
|
|
392
415
|
maxTokens,
|
|
416
|
+
// Add abort signal if available
|
|
417
|
+
...(timeoutController && { abortSignal: timeoutController.controller.signal }),
|
|
393
418
|
};
|
|
394
419
|
if (finalSchema) {
|
|
395
420
|
generateOptions.experimental_output = Output.object({
|
|
396
421
|
schema: finalSchema,
|
|
397
422
|
});
|
|
398
423
|
}
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
424
|
+
try {
|
|
425
|
+
const result = await generateText(generateOptions);
|
|
426
|
+
// Clean up timeout if successful
|
|
427
|
+
timeoutController?.cleanup();
|
|
428
|
+
logger.debug(`[${functionTag}] Generate text completed`, {
|
|
429
|
+
provider,
|
|
430
|
+
modelName: this.modelName,
|
|
431
|
+
usage: result.usage,
|
|
432
|
+
finishReason: result.finishReason,
|
|
433
|
+
responseLength: result.text?.length || 0,
|
|
434
|
+
timeout,
|
|
435
|
+
});
|
|
436
|
+
return result;
|
|
437
|
+
}
|
|
438
|
+
finally {
|
|
439
|
+
// Always cleanup timeout
|
|
440
|
+
timeoutController?.cleanup();
|
|
441
|
+
}
|
|
408
442
|
}
|
|
409
443
|
catch (err) {
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
444
|
+
// Log timeout errors specifically
|
|
445
|
+
if (err instanceof TimeoutError) {
|
|
446
|
+
logger.error(`[${functionTag}] Timeout error`, {
|
|
447
|
+
provider,
|
|
448
|
+
modelName: this.modelName,
|
|
449
|
+
isAnthropic: isAnthropicModel(this.modelName),
|
|
450
|
+
timeout: err.timeout,
|
|
451
|
+
message: err.message,
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
else {
|
|
455
|
+
logger.error(`[${functionTag}] Exception`, {
|
|
456
|
+
provider,
|
|
457
|
+
modelName: this.modelName,
|
|
458
|
+
message: "Error in generating text",
|
|
459
|
+
err: String(err),
|
|
460
|
+
});
|
|
461
|
+
}
|
|
416
462
|
throw err; // Re-throw error to trigger fallback
|
|
417
463
|
}
|
|
418
464
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { HfInference } from "@huggingface/inference";
|
|
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
5
|
// Default system context
|
|
5
6
|
const DEFAULT_SYSTEM_CONTEXT = {
|
|
6
7
|
systemPrompt: "You are a helpful AI assistant.",
|
|
@@ -228,7 +229,7 @@ export class HuggingFace {
|
|
|
228
229
|
const options = typeof optionsOrPrompt === "string"
|
|
229
230
|
? { prompt: optionsOrPrompt }
|
|
230
231
|
: optionsOrPrompt;
|
|
231
|
-
const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema, } = options;
|
|
232
|
+
const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema, timeout = getDefaultTimeout(provider, 'stream'), } = options;
|
|
232
233
|
// Use schema from options or fallback parameter
|
|
233
234
|
const finalSchema = schema || analysisSchema;
|
|
234
235
|
logger.debug(`[${functionTag}] Stream request started`, {
|
|
@@ -238,14 +239,19 @@ export class HuggingFace {
|
|
|
238
239
|
temperature,
|
|
239
240
|
maxTokens,
|
|
240
241
|
hasSchema: !!finalSchema,
|
|
242
|
+
timeout,
|
|
241
243
|
});
|
|
242
244
|
const model = this.getModel();
|
|
245
|
+
// Create timeout controller if timeout is specified
|
|
246
|
+
const timeoutController = createTimeoutController(timeout, provider, 'stream');
|
|
243
247
|
const streamOptions = {
|
|
244
248
|
model: model,
|
|
245
249
|
prompt: prompt,
|
|
246
250
|
system: systemPrompt,
|
|
247
251
|
temperature,
|
|
248
252
|
maxTokens,
|
|
253
|
+
// Add abort signal if available
|
|
254
|
+
...(timeoutController && { abortSignal: timeoutController.controller.signal }),
|
|
249
255
|
onError: (event) => {
|
|
250
256
|
const error = event.error;
|
|
251
257
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -287,18 +293,31 @@ export class HuggingFace {
|
|
|
287
293
|
});
|
|
288
294
|
}
|
|
289
295
|
const result = streamText(streamOptions);
|
|
296
|
+
// For streaming, we can't clean up immediately, but the timeout will auto-clean
|
|
297
|
+
// The user should handle the stream and any timeout errors
|
|
290
298
|
return result;
|
|
291
299
|
}
|
|
292
300
|
catch (err) {
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
}
|
|
301
|
+
// Log timeout errors specifically
|
|
302
|
+
if (err instanceof TimeoutError) {
|
|
303
|
+
logger.error(`[${functionTag}] Timeout error`, {
|
|
304
|
+
provider,
|
|
305
|
+
modelName: this.modelName,
|
|
306
|
+
timeout: err.timeout,
|
|
307
|
+
message: err.message,
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
else {
|
|
311
|
+
logger.error(`[${functionTag}] Exception`, {
|
|
312
|
+
provider,
|
|
313
|
+
modelName: this.modelName,
|
|
314
|
+
message: "Error in streaming text",
|
|
315
|
+
err: String(err),
|
|
316
|
+
promptLength: typeof optionsOrPrompt === "string"
|
|
317
|
+
? optionsOrPrompt.length
|
|
318
|
+
: optionsOrPrompt.prompt.length,
|
|
319
|
+
});
|
|
320
|
+
}
|
|
302
321
|
throw err; // Re-throw error to trigger fallback
|
|
303
322
|
}
|
|
304
323
|
}
|
|
@@ -316,7 +335,7 @@ export class HuggingFace {
|
|
|
316
335
|
const options = typeof optionsOrPrompt === "string"
|
|
317
336
|
? { prompt: optionsOrPrompt }
|
|
318
337
|
: optionsOrPrompt;
|
|
319
|
-
const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema, } = options;
|
|
338
|
+
const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema, timeout = getDefaultTimeout(provider, 'generate'), } = options;
|
|
320
339
|
// Use schema from options or fallback parameter
|
|
321
340
|
const finalSchema = schema || analysisSchema;
|
|
322
341
|
logger.debug(`[${functionTag}] Generate request started`, {
|
|
@@ -325,37 +344,62 @@ export class HuggingFace {
|
|
|
325
344
|
promptLength: prompt.length,
|
|
326
345
|
temperature,
|
|
327
346
|
maxTokens,
|
|
347
|
+
timeout,
|
|
328
348
|
});
|
|
329
349
|
const model = this.getModel();
|
|
350
|
+
// Create timeout controller if timeout is specified
|
|
351
|
+
const timeoutController = createTimeoutController(timeout, provider, 'generate');
|
|
330
352
|
const generateOptions = {
|
|
331
353
|
model: model,
|
|
332
354
|
prompt: prompt,
|
|
333
355
|
system: systemPrompt,
|
|
334
356
|
temperature,
|
|
335
357
|
maxTokens,
|
|
358
|
+
// Add abort signal if available
|
|
359
|
+
...(timeoutController && { abortSignal: timeoutController.controller.signal }),
|
|
336
360
|
};
|
|
337
361
|
if (finalSchema) {
|
|
338
362
|
generateOptions.experimental_output = Output.object({
|
|
339
363
|
schema: finalSchema,
|
|
340
364
|
});
|
|
341
365
|
}
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
366
|
+
try {
|
|
367
|
+
const result = await generateText(generateOptions);
|
|
368
|
+
// Clean up timeout if successful
|
|
369
|
+
timeoutController?.cleanup();
|
|
370
|
+
logger.debug(`[${functionTag}] Generate text completed`, {
|
|
371
|
+
provider,
|
|
372
|
+
modelName: this.modelName,
|
|
373
|
+
usage: result.usage,
|
|
374
|
+
finishReason: result.finishReason,
|
|
375
|
+
responseLength: result.text?.length || 0,
|
|
376
|
+
timeout,
|
|
377
|
+
});
|
|
378
|
+
return result;
|
|
379
|
+
}
|
|
380
|
+
finally {
|
|
381
|
+
// Always cleanup timeout
|
|
382
|
+
timeoutController?.cleanup();
|
|
383
|
+
}
|
|
351
384
|
}
|
|
352
385
|
catch (err) {
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
386
|
+
// Log timeout errors specifically
|
|
387
|
+
if (err instanceof TimeoutError) {
|
|
388
|
+
logger.error(`[${functionTag}] Timeout error`, {
|
|
389
|
+
provider,
|
|
390
|
+
modelName: this.modelName,
|
|
391
|
+
timeout: err.timeout,
|
|
392
|
+
message: err.message,
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
else {
|
|
396
|
+
logger.error(`[${functionTag}] Exception`, {
|
|
397
|
+
provider,
|
|
398
|
+
modelName: this.modelName,
|
|
399
|
+
message: "Error in generating text",
|
|
400
|
+
err: String(err),
|
|
401
|
+
});
|
|
402
|
+
}
|
|
359
403
|
throw err; // Re-throw error to trigger fallback
|
|
360
404
|
}
|
|
361
405
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createMistral } from "@ai-sdk/mistral";
|
|
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
5
|
// Default system context
|
|
5
6
|
const DEFAULT_SYSTEM_CONTEXT = {
|
|
6
7
|
systemPrompt: "You are a helpful AI assistant.",
|
|
@@ -88,7 +89,7 @@ export class MistralAI {
|
|
|
88
89
|
const options = typeof optionsOrPrompt === "string"
|
|
89
90
|
? { prompt: optionsOrPrompt }
|
|
90
91
|
: optionsOrPrompt;
|
|
91
|
-
const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema, } = options;
|
|
92
|
+
const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema, timeout = getDefaultTimeout(provider, 'stream'), } = options;
|
|
92
93
|
// Use schema from options or fallback parameter
|
|
93
94
|
const finalSchema = schema || analysisSchema;
|
|
94
95
|
logger.debug(`[${functionTag}] Stream request started`, {
|
|
@@ -98,14 +99,19 @@ export class MistralAI {
|
|
|
98
99
|
temperature,
|
|
99
100
|
maxTokens,
|
|
100
101
|
hasSchema: !!finalSchema,
|
|
102
|
+
timeout,
|
|
101
103
|
});
|
|
102
104
|
const model = this.getModel();
|
|
105
|
+
// Create timeout controller if timeout is specified
|
|
106
|
+
const timeoutController = createTimeoutController(timeout, provider, 'stream');
|
|
103
107
|
const streamOptions = {
|
|
104
108
|
model: model,
|
|
105
109
|
prompt: prompt,
|
|
106
110
|
system: systemPrompt,
|
|
107
111
|
temperature,
|
|
108
112
|
maxTokens,
|
|
113
|
+
// Add abort signal if available
|
|
114
|
+
...(timeoutController && { abortSignal: timeoutController.controller.signal }),
|
|
109
115
|
onError: (event) => {
|
|
110
116
|
const error = event.error;
|
|
111
117
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -147,18 +153,31 @@ export class MistralAI {
|
|
|
147
153
|
});
|
|
148
154
|
}
|
|
149
155
|
const result = streamText(streamOptions);
|
|
156
|
+
// For streaming, we can't clean up immediately, but the timeout will auto-clean
|
|
157
|
+
// The user should handle the stream and any timeout errors
|
|
150
158
|
return result;
|
|
151
159
|
}
|
|
152
160
|
catch (err) {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
}
|
|
161
|
+
// Log timeout errors specifically
|
|
162
|
+
if (err instanceof TimeoutError) {
|
|
163
|
+
logger.error(`[${functionTag}] Timeout error`, {
|
|
164
|
+
provider,
|
|
165
|
+
modelName: this.modelName,
|
|
166
|
+
timeout: err.timeout,
|
|
167
|
+
message: err.message,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
logger.error(`[${functionTag}] Exception`, {
|
|
172
|
+
provider,
|
|
173
|
+
modelName: this.modelName,
|
|
174
|
+
message: "Error in streaming text",
|
|
175
|
+
err: String(err),
|
|
176
|
+
promptLength: typeof optionsOrPrompt === "string"
|
|
177
|
+
? optionsOrPrompt.length
|
|
178
|
+
: optionsOrPrompt.prompt.length,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
162
181
|
throw err; // Re-throw error to trigger fallback
|
|
163
182
|
}
|
|
164
183
|
}
|
|
@@ -176,7 +195,7 @@ export class MistralAI {
|
|
|
176
195
|
const options = typeof optionsOrPrompt === "string"
|
|
177
196
|
? { prompt: optionsOrPrompt }
|
|
178
197
|
: optionsOrPrompt;
|
|
179
|
-
const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema, } = options;
|
|
198
|
+
const { prompt, temperature = 0.7, maxTokens = 1000, systemPrompt = DEFAULT_SYSTEM_CONTEXT.systemPrompt, schema, timeout = getDefaultTimeout(provider, 'generate'), } = options;
|
|
180
199
|
// Use schema from options or fallback parameter
|
|
181
200
|
const finalSchema = schema || analysisSchema;
|
|
182
201
|
logger.debug(`[${functionTag}] Generate request started`, {
|
|
@@ -185,37 +204,62 @@ export class MistralAI {
|
|
|
185
204
|
promptLength: prompt.length,
|
|
186
205
|
temperature,
|
|
187
206
|
maxTokens,
|
|
207
|
+
timeout,
|
|
188
208
|
});
|
|
189
209
|
const model = this.getModel();
|
|
210
|
+
// Create timeout controller if timeout is specified
|
|
211
|
+
const timeoutController = createTimeoutController(timeout, provider, 'generate');
|
|
190
212
|
const generateOptions = {
|
|
191
213
|
model: model,
|
|
192
214
|
prompt: prompt,
|
|
193
215
|
system: systemPrompt,
|
|
194
216
|
temperature,
|
|
195
217
|
maxTokens,
|
|
218
|
+
// Add abort signal if available
|
|
219
|
+
...(timeoutController && { abortSignal: timeoutController.controller.signal }),
|
|
196
220
|
};
|
|
197
221
|
if (finalSchema) {
|
|
198
222
|
generateOptions.experimental_output = Output.object({
|
|
199
223
|
schema: finalSchema,
|
|
200
224
|
});
|
|
201
225
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
226
|
+
try {
|
|
227
|
+
const result = await generateText(generateOptions);
|
|
228
|
+
// Clean up timeout if successful
|
|
229
|
+
timeoutController?.cleanup();
|
|
230
|
+
logger.debug(`[${functionTag}] Generate text completed`, {
|
|
231
|
+
provider,
|
|
232
|
+
modelName: this.modelName,
|
|
233
|
+
usage: result.usage,
|
|
234
|
+
finishReason: result.finishReason,
|
|
235
|
+
responseLength: result.text?.length || 0,
|
|
236
|
+
timeout,
|
|
237
|
+
});
|
|
238
|
+
return result;
|
|
239
|
+
}
|
|
240
|
+
finally {
|
|
241
|
+
// Always cleanup timeout
|
|
242
|
+
timeoutController?.cleanup();
|
|
243
|
+
}
|
|
211
244
|
}
|
|
212
245
|
catch (err) {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
246
|
+
// Log timeout errors specifically
|
|
247
|
+
if (err instanceof TimeoutError) {
|
|
248
|
+
logger.error(`[${functionTag}] Timeout error`, {
|
|
249
|
+
provider,
|
|
250
|
+
modelName: this.modelName,
|
|
251
|
+
timeout: err.timeout,
|
|
252
|
+
message: err.message,
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
logger.error(`[${functionTag}] Exception`, {
|
|
257
|
+
provider,
|
|
258
|
+
modelName: this.modelName,
|
|
259
|
+
message: "Error in generating text",
|
|
260
|
+
err: String(err),
|
|
261
|
+
});
|
|
262
|
+
}
|
|
219
263
|
throw err; // Re-throw error to trigger fallback
|
|
220
264
|
}
|
|
221
265
|
}
|
|
@@ -17,7 +17,7 @@ import type { Schema } from "ai";
|
|
|
17
17
|
export declare class Ollama implements AIProvider {
|
|
18
18
|
private baseUrl;
|
|
19
19
|
private modelName;
|
|
20
|
-
private
|
|
20
|
+
private defaultTimeout;
|
|
21
21
|
constructor(modelName?: string);
|
|
22
22
|
/**
|
|
23
23
|
* Gets the appropriate model instance
|