git-coco 0.27.0 → 0.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/dist/index.esm.mjs +165 -7
- package/dist/index.js +165 -7
- package/package.json +1 -1
package/dist/index.esm.mjs
CHANGED
|
@@ -46,7 +46,7 @@ import { pathToFileURL } from 'url';
|
|
|
46
46
|
/**
|
|
47
47
|
* Current build version from package.json
|
|
48
48
|
*/
|
|
49
|
-
const BUILD_VERSION = "0.
|
|
49
|
+
const BUILD_VERSION = "0.28.0";
|
|
50
50
|
|
|
51
51
|
const isInteractive = (config) => {
|
|
52
52
|
return config?.mode === 'interactive' || !!config?.interactive;
|
|
@@ -226,6 +226,16 @@ class LangChainAuthenticationError extends LangChainError {
|
|
|
226
226
|
super(message, context);
|
|
227
227
|
}
|
|
228
228
|
}
|
|
229
|
+
/**
|
|
230
|
+
* Network/connection errors (service unreachable, DNS failures, etc.)
|
|
231
|
+
*/
|
|
232
|
+
class LangChainNetworkError extends LangChainError {
|
|
233
|
+
constructor(message, endpoint, provider, context) {
|
|
234
|
+
super(message, { ...context, endpoint, provider });
|
|
235
|
+
this.endpoint = endpoint;
|
|
236
|
+
this.provider = provider;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
229
239
|
|
|
230
240
|
/**
|
|
231
241
|
* Validates that a required parameter is not null or undefined
|
|
@@ -2351,6 +2361,59 @@ class Logger {
|
|
|
2351
2361
|
}
|
|
2352
2362
|
}
|
|
2353
2363
|
|
|
2364
|
+
/**
|
|
2365
|
+
* Formats a network error with helpful troubleshooting information
|
|
2366
|
+
*/
|
|
2367
|
+
function formatNetworkError(error, logger) {
|
|
2368
|
+
const endpoint = error.endpoint || 'unknown endpoint';
|
|
2369
|
+
const provider = error.provider || 'LLM service';
|
|
2370
|
+
logger.log('\nFailed to execute command', { color: 'yellow' });
|
|
2371
|
+
logger.log(`\nError: Unable to connect to ${provider}`, { color: 'red' });
|
|
2372
|
+
if (error.endpoint) {
|
|
2373
|
+
logger.log(` Endpoint: ${endpoint}`, { color: 'red' });
|
|
2374
|
+
}
|
|
2375
|
+
logger.log('\nTroubleshooting:', { color: 'cyan' });
|
|
2376
|
+
// Provider-specific troubleshooting
|
|
2377
|
+
if (provider === 'ollama' || endpoint.includes('11434')) {
|
|
2378
|
+
logger.log(' • Is Ollama running? Try: ollama serve', { color: 'white' });
|
|
2379
|
+
logger.log(' • Check if the endpoint is correct in your config', { color: 'white' });
|
|
2380
|
+
logger.log(` • Verify Ollama is accessible: curl ${endpoint}/api/version`, { color: 'white' });
|
|
2381
|
+
}
|
|
2382
|
+
else if (provider === 'openai' || endpoint.includes('openai')) {
|
|
2383
|
+
logger.log(' • Check your internet connection', { color: 'white' });
|
|
2384
|
+
logger.log(' • Verify the API endpoint is accessible', { color: 'white' });
|
|
2385
|
+
logger.log(' • If using a custom baseURL, verify it is correct', { color: 'white' });
|
|
2386
|
+
}
|
|
2387
|
+
else if (provider === 'anthropic') {
|
|
2388
|
+
logger.log(' • Check your internet connection', { color: 'white' });
|
|
2389
|
+
logger.log(' • Verify the Anthropic API is accessible', { color: 'white' });
|
|
2390
|
+
}
|
|
2391
|
+
else {
|
|
2392
|
+
logger.log(' • Check your internet connection', { color: 'white' });
|
|
2393
|
+
logger.log(' • Verify the service endpoint is correct', { color: 'white' });
|
|
2394
|
+
logger.log(' • Ensure the LLM service is running and accessible', { color: 'white' });
|
|
2395
|
+
}
|
|
2396
|
+
logger.verbose(`\nOriginal error: ${error.message}`, { color: 'gray' });
|
|
2397
|
+
}
|
|
2398
|
+
/**
|
|
2399
|
+
* Formats an authentication error with helpful information
|
|
2400
|
+
*/
|
|
2401
|
+
function formatAuthenticationError(error, logger) {
|
|
2402
|
+
logger.log('\nFailed to execute command', { color: 'yellow' });
|
|
2403
|
+
logger.log('\nError: Authentication failed', { color: 'red' });
|
|
2404
|
+
logger.log('\nTroubleshooting:', { color: 'cyan' });
|
|
2405
|
+
logger.log(' • Verify your API key is correct', { color: 'white' });
|
|
2406
|
+
logger.log(' • Check that your API key has not expired', { color: 'white' });
|
|
2407
|
+
logger.log(' • Ensure the API key is set in your environment or config', { color: 'white' });
|
|
2408
|
+
logger.verbose(`\nOriginal error: ${error.message}`, { color: 'gray' });
|
|
2409
|
+
}
|
|
2410
|
+
/**
|
|
2411
|
+
* Formats a generic error
|
|
2412
|
+
*/
|
|
2413
|
+
function formatGenericError(error, logger) {
|
|
2414
|
+
logger.log('\nFailed to execute command', { color: 'yellow' });
|
|
2415
|
+
logger.verbose(`\nError: "${error.message}"`, { color: 'red' });
|
|
2416
|
+
}
|
|
2354
2417
|
function commandExecutor(handler) {
|
|
2355
2418
|
return async (argv) => {
|
|
2356
2419
|
const options = loadConfig(argv);
|
|
@@ -2359,8 +2422,16 @@ function commandExecutor(handler) {
|
|
|
2359
2422
|
await handler(argv, logger);
|
|
2360
2423
|
}
|
|
2361
2424
|
catch (error) {
|
|
2362
|
-
|
|
2363
|
-
|
|
2425
|
+
// Handle specific error types with helpful messages
|
|
2426
|
+
if (error instanceof LangChainNetworkError) {
|
|
2427
|
+
formatNetworkError(error, logger);
|
|
2428
|
+
}
|
|
2429
|
+
else if (error instanceof LangChainAuthenticationError) {
|
|
2430
|
+
formatAuthenticationError(error, logger);
|
|
2431
|
+
}
|
|
2432
|
+
else {
|
|
2433
|
+
formatGenericError(error, logger);
|
|
2434
|
+
}
|
|
2364
2435
|
logger.log('\nThanks for using coco, make it a great day! 👋🤖', { color: 'blue' });
|
|
2365
2436
|
process.exit(0);
|
|
2366
2437
|
}
|
|
@@ -6252,10 +6323,50 @@ async function withRetry(operation, options = {}) {
|
|
|
6252
6323
|
throw new Error(`Operation failed after ${maxAttempts} attempts. Last error: ${lastError.message}`);
|
|
6253
6324
|
}
|
|
6254
6325
|
|
|
6326
|
+
/**
|
|
6327
|
+
* Network error patterns to detect connection failures
|
|
6328
|
+
*/
|
|
6329
|
+
const NETWORK_ERROR_PATTERNS = [
|
|
6330
|
+
'fetch failed',
|
|
6331
|
+
'ECONNREFUSED',
|
|
6332
|
+
'ENOTFOUND',
|
|
6333
|
+
'ETIMEDOUT',
|
|
6334
|
+
'ECONNRESET',
|
|
6335
|
+
'ENETUNREACH',
|
|
6336
|
+
'EHOSTUNREACH',
|
|
6337
|
+
'socket hang up',
|
|
6338
|
+
'network request failed',
|
|
6339
|
+
'Failed to fetch',
|
|
6340
|
+
'getaddrinfo',
|
|
6341
|
+
'connect ECONNREFUSED',
|
|
6342
|
+
];
|
|
6343
|
+
/**
|
|
6344
|
+
* Checks if an error message indicates a network/connection failure
|
|
6345
|
+
*/
|
|
6346
|
+
function isNetworkError(error) {
|
|
6347
|
+
if (!(error instanceof Error))
|
|
6348
|
+
return false;
|
|
6349
|
+
const message = error.message.toLowerCase();
|
|
6350
|
+
const errorCause = error?.cause?.message?.toLowerCase() || '';
|
|
6351
|
+
return NETWORK_ERROR_PATTERNS.some(pattern => message.includes(pattern.toLowerCase()) ||
|
|
6352
|
+
errorCause.includes(pattern.toLowerCase()));
|
|
6353
|
+
}
|
|
6255
6354
|
/**
|
|
6256
6355
|
* Wraps errors with additional context and converts them to LangChain errors
|
|
6257
6356
|
*/
|
|
6258
6357
|
function handleLangChainError(error, context, additionalContext) {
|
|
6358
|
+
// Check for network errors first
|
|
6359
|
+
if (error instanceof Error && isNetworkError(error)) {
|
|
6360
|
+
const endpoint = additionalContext?.endpoint;
|
|
6361
|
+
const provider = additionalContext?.provider;
|
|
6362
|
+
throw new LangChainNetworkError(error.message, endpoint, provider, {
|
|
6363
|
+
originalError: error.name,
|
|
6364
|
+
originalMessage: error.message,
|
|
6365
|
+
stack: error.stack,
|
|
6366
|
+
context,
|
|
6367
|
+
...additionalContext
|
|
6368
|
+
});
|
|
6369
|
+
}
|
|
6259
6370
|
// If it's already a LangChain error, re-throw with additional context
|
|
6260
6371
|
if (error instanceof LangChainError) {
|
|
6261
6372
|
throw new LangChainExecutionError(`${context}: ${error.message}`, {
|
|
@@ -7039,21 +7150,55 @@ You must return ONLY valid JSON that matches the schema exactly. Do not include
|
|
|
7039
7150
|
}
|
|
7040
7151
|
}
|
|
7041
7152
|
|
|
7153
|
+
/**
|
|
7154
|
+
* Extracts provider and endpoint info from LLM instance if available
|
|
7155
|
+
*/
|
|
7156
|
+
function extractLlmInfo(llm) {
|
|
7157
|
+
const info = {};
|
|
7158
|
+
// Try to extract provider from class name
|
|
7159
|
+
const className = llm?.constructor?.name || '';
|
|
7160
|
+
if (className.includes('Ollama')) {
|
|
7161
|
+
info.provider = 'ollama';
|
|
7162
|
+
// Try to get baseUrl from ollama instance
|
|
7163
|
+
if ('lc_kwargs' in llm && typeof llm.lc_kwargs === 'object' && llm.lc_kwargs !== null) {
|
|
7164
|
+
const kwargs = llm.lc_kwargs;
|
|
7165
|
+
if (typeof kwargs.baseUrl === 'string') {
|
|
7166
|
+
info.endpoint = kwargs.baseUrl;
|
|
7167
|
+
}
|
|
7168
|
+
}
|
|
7169
|
+
}
|
|
7170
|
+
else if (className.includes('OpenAI')) {
|
|
7171
|
+
info.provider = 'openai';
|
|
7172
|
+
}
|
|
7173
|
+
else if (className.includes('Anthropic')) {
|
|
7174
|
+
info.provider = 'anthropic';
|
|
7175
|
+
}
|
|
7176
|
+
return info;
|
|
7177
|
+
}
|
|
7042
7178
|
/**
|
|
7043
7179
|
* Executes a LangChain pipeline with the provided LLM, prompt, variables, and parser.
|
|
7044
7180
|
* @param params - The execution parameters
|
|
7045
7181
|
* @returns The parsed result from the LLM chain
|
|
7046
7182
|
* @throws LangChainExecutionError if the chain execution fails or returns empty results
|
|
7183
|
+
* @throws LangChainNetworkError if a network/connection error occurs
|
|
7047
7184
|
*/
|
|
7048
|
-
const executeChain = async ({ llm, prompt, variables, parser }) => {
|
|
7185
|
+
const executeChain = async ({ llm, prompt, variables, parser, provider, endpoint, }) => {
|
|
7049
7186
|
validateRequired(llm, 'llm', 'executeChain');
|
|
7050
7187
|
validateRequired(prompt, 'prompt', 'executeChain');
|
|
7051
7188
|
validateRequired(variables, 'variables', 'executeChain');
|
|
7052
7189
|
validateRequired(parser, 'parser', 'executeChain');
|
|
7053
7190
|
// Validate that variables is an object
|
|
7054
7191
|
if (typeof variables !== 'object' || Array.isArray(variables)) {
|
|
7055
|
-
throw new LangChainExecutionError('executeChain: Variables must be a non-array object', {
|
|
7192
|
+
throw new LangChainExecutionError('executeChain: Variables must be a non-array object', {
|
|
7193
|
+
variables,
|
|
7194
|
+
type: typeof variables,
|
|
7195
|
+
isArray: Array.isArray(variables),
|
|
7196
|
+
});
|
|
7056
7197
|
}
|
|
7198
|
+
// Extract LLM info for error reporting if not provided
|
|
7199
|
+
const llmInfo = extractLlmInfo(llm);
|
|
7200
|
+
const effectiveProvider = provider || llmInfo.provider;
|
|
7201
|
+
const effectiveEndpoint = endpoint || llmInfo.endpoint;
|
|
7057
7202
|
try {
|
|
7058
7203
|
const chain = prompt.pipe(llm).pipe(parser);
|
|
7059
7204
|
const result = await chain.invoke(variables);
|
|
@@ -7064,14 +7209,27 @@ const executeChain = async ({ llm, prompt, variables, parser }) => {
|
|
|
7064
7209
|
}
|
|
7065
7210
|
catch (error) {
|
|
7066
7211
|
// Re-throw LangChain errors as-is
|
|
7067
|
-
if (error instanceof LangChainExecutionError) {
|
|
7212
|
+
if (error instanceof LangChainExecutionError || error instanceof LangChainNetworkError) {
|
|
7068
7213
|
throw error;
|
|
7069
7214
|
}
|
|
7215
|
+
// Check for network errors and throw specific error type
|
|
7216
|
+
if (error instanceof Error && isNetworkError(error)) {
|
|
7217
|
+
throw new LangChainNetworkError(error.message, effectiveEndpoint, effectiveProvider, {
|
|
7218
|
+
originalError: error.name,
|
|
7219
|
+
originalMessage: error.message,
|
|
7220
|
+
stack: error.stack,
|
|
7221
|
+
promptInputVariables: prompt.inputVariables,
|
|
7222
|
+
variableKeys: Object.keys(variables),
|
|
7223
|
+
parserType: parser.constructor.name,
|
|
7224
|
+
});
|
|
7225
|
+
}
|
|
7070
7226
|
// Wrap other errors with context
|
|
7071
7227
|
handleLangChainError(error, 'executeChain: Chain execution failed', {
|
|
7072
7228
|
promptInputVariables: prompt.inputVariables,
|
|
7073
7229
|
variableKeys: Object.keys(variables),
|
|
7074
|
-
parserType: parser.constructor.name
|
|
7230
|
+
parserType: parser.constructor.name,
|
|
7231
|
+
provider: effectiveProvider,
|
|
7232
|
+
endpoint: effectiveEndpoint,
|
|
7075
7233
|
});
|
|
7076
7234
|
}
|
|
7077
7235
|
};
|
package/dist/index.js
CHANGED
|
@@ -68,7 +68,7 @@ var readline__namespace = /*#__PURE__*/_interopNamespaceDefault(readline);
|
|
|
68
68
|
/**
|
|
69
69
|
* Current build version from package.json
|
|
70
70
|
*/
|
|
71
|
-
const BUILD_VERSION = "0.
|
|
71
|
+
const BUILD_VERSION = "0.28.0";
|
|
72
72
|
|
|
73
73
|
const isInteractive = (config) => {
|
|
74
74
|
return config?.mode === 'interactive' || !!config?.interactive;
|
|
@@ -248,6 +248,16 @@ class LangChainAuthenticationError extends LangChainError {
|
|
|
248
248
|
super(message, context);
|
|
249
249
|
}
|
|
250
250
|
}
|
|
251
|
+
/**
|
|
252
|
+
* Network/connection errors (service unreachable, DNS failures, etc.)
|
|
253
|
+
*/
|
|
254
|
+
class LangChainNetworkError extends LangChainError {
|
|
255
|
+
constructor(message, endpoint, provider, context) {
|
|
256
|
+
super(message, { ...context, endpoint, provider });
|
|
257
|
+
this.endpoint = endpoint;
|
|
258
|
+
this.provider = provider;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
251
261
|
|
|
252
262
|
/**
|
|
253
263
|
* Validates that a required parameter is not null or undefined
|
|
@@ -2373,6 +2383,59 @@ class Logger {
|
|
|
2373
2383
|
}
|
|
2374
2384
|
}
|
|
2375
2385
|
|
|
2386
|
+
/**
|
|
2387
|
+
* Formats a network error with helpful troubleshooting information
|
|
2388
|
+
*/
|
|
2389
|
+
function formatNetworkError(error, logger) {
|
|
2390
|
+
const endpoint = error.endpoint || 'unknown endpoint';
|
|
2391
|
+
const provider = error.provider || 'LLM service';
|
|
2392
|
+
logger.log('\nFailed to execute command', { color: 'yellow' });
|
|
2393
|
+
logger.log(`\nError: Unable to connect to ${provider}`, { color: 'red' });
|
|
2394
|
+
if (error.endpoint) {
|
|
2395
|
+
logger.log(` Endpoint: ${endpoint}`, { color: 'red' });
|
|
2396
|
+
}
|
|
2397
|
+
logger.log('\nTroubleshooting:', { color: 'cyan' });
|
|
2398
|
+
// Provider-specific troubleshooting
|
|
2399
|
+
if (provider === 'ollama' || endpoint.includes('11434')) {
|
|
2400
|
+
logger.log(' • Is Ollama running? Try: ollama serve', { color: 'white' });
|
|
2401
|
+
logger.log(' • Check if the endpoint is correct in your config', { color: 'white' });
|
|
2402
|
+
logger.log(` • Verify Ollama is accessible: curl ${endpoint}/api/version`, { color: 'white' });
|
|
2403
|
+
}
|
|
2404
|
+
else if (provider === 'openai' || endpoint.includes('openai')) {
|
|
2405
|
+
logger.log(' • Check your internet connection', { color: 'white' });
|
|
2406
|
+
logger.log(' • Verify the API endpoint is accessible', { color: 'white' });
|
|
2407
|
+
logger.log(' • If using a custom baseURL, verify it is correct', { color: 'white' });
|
|
2408
|
+
}
|
|
2409
|
+
else if (provider === 'anthropic') {
|
|
2410
|
+
logger.log(' • Check your internet connection', { color: 'white' });
|
|
2411
|
+
logger.log(' • Verify the Anthropic API is accessible', { color: 'white' });
|
|
2412
|
+
}
|
|
2413
|
+
else {
|
|
2414
|
+
logger.log(' • Check your internet connection', { color: 'white' });
|
|
2415
|
+
logger.log(' • Verify the service endpoint is correct', { color: 'white' });
|
|
2416
|
+
logger.log(' • Ensure the LLM service is running and accessible', { color: 'white' });
|
|
2417
|
+
}
|
|
2418
|
+
logger.verbose(`\nOriginal error: ${error.message}`, { color: 'gray' });
|
|
2419
|
+
}
|
|
2420
|
+
/**
|
|
2421
|
+
* Formats an authentication error with helpful information
|
|
2422
|
+
*/
|
|
2423
|
+
function formatAuthenticationError(error, logger) {
|
|
2424
|
+
logger.log('\nFailed to execute command', { color: 'yellow' });
|
|
2425
|
+
logger.log('\nError: Authentication failed', { color: 'red' });
|
|
2426
|
+
logger.log('\nTroubleshooting:', { color: 'cyan' });
|
|
2427
|
+
logger.log(' • Verify your API key is correct', { color: 'white' });
|
|
2428
|
+
logger.log(' • Check that your API key has not expired', { color: 'white' });
|
|
2429
|
+
logger.log(' • Ensure the API key is set in your environment or config', { color: 'white' });
|
|
2430
|
+
logger.verbose(`\nOriginal error: ${error.message}`, { color: 'gray' });
|
|
2431
|
+
}
|
|
2432
|
+
/**
|
|
2433
|
+
* Formats a generic error
|
|
2434
|
+
*/
|
|
2435
|
+
function formatGenericError(error, logger) {
|
|
2436
|
+
logger.log('\nFailed to execute command', { color: 'yellow' });
|
|
2437
|
+
logger.verbose(`\nError: "${error.message}"`, { color: 'red' });
|
|
2438
|
+
}
|
|
2376
2439
|
function commandExecutor(handler) {
|
|
2377
2440
|
return async (argv) => {
|
|
2378
2441
|
const options = loadConfig(argv);
|
|
@@ -2381,8 +2444,16 @@ function commandExecutor(handler) {
|
|
|
2381
2444
|
await handler(argv, logger);
|
|
2382
2445
|
}
|
|
2383
2446
|
catch (error) {
|
|
2384
|
-
|
|
2385
|
-
|
|
2447
|
+
// Handle specific error types with helpful messages
|
|
2448
|
+
if (error instanceof LangChainNetworkError) {
|
|
2449
|
+
formatNetworkError(error, logger);
|
|
2450
|
+
}
|
|
2451
|
+
else if (error instanceof LangChainAuthenticationError) {
|
|
2452
|
+
formatAuthenticationError(error, logger);
|
|
2453
|
+
}
|
|
2454
|
+
else {
|
|
2455
|
+
formatGenericError(error, logger);
|
|
2456
|
+
}
|
|
2386
2457
|
logger.log('\nThanks for using coco, make it a great day! 👋🤖', { color: 'blue' });
|
|
2387
2458
|
process.exit(0);
|
|
2388
2459
|
}
|
|
@@ -6274,10 +6345,50 @@ async function withRetry(operation, options = {}) {
|
|
|
6274
6345
|
throw new Error(`Operation failed after ${maxAttempts} attempts. Last error: ${lastError.message}`);
|
|
6275
6346
|
}
|
|
6276
6347
|
|
|
6348
|
+
/**
|
|
6349
|
+
* Network error patterns to detect connection failures
|
|
6350
|
+
*/
|
|
6351
|
+
const NETWORK_ERROR_PATTERNS = [
|
|
6352
|
+
'fetch failed',
|
|
6353
|
+
'ECONNREFUSED',
|
|
6354
|
+
'ENOTFOUND',
|
|
6355
|
+
'ETIMEDOUT',
|
|
6356
|
+
'ECONNRESET',
|
|
6357
|
+
'ENETUNREACH',
|
|
6358
|
+
'EHOSTUNREACH',
|
|
6359
|
+
'socket hang up',
|
|
6360
|
+
'network request failed',
|
|
6361
|
+
'Failed to fetch',
|
|
6362
|
+
'getaddrinfo',
|
|
6363
|
+
'connect ECONNREFUSED',
|
|
6364
|
+
];
|
|
6365
|
+
/**
|
|
6366
|
+
* Checks if an error message indicates a network/connection failure
|
|
6367
|
+
*/
|
|
6368
|
+
function isNetworkError(error) {
|
|
6369
|
+
if (!(error instanceof Error))
|
|
6370
|
+
return false;
|
|
6371
|
+
const message = error.message.toLowerCase();
|
|
6372
|
+
const errorCause = error?.cause?.message?.toLowerCase() || '';
|
|
6373
|
+
return NETWORK_ERROR_PATTERNS.some(pattern => message.includes(pattern.toLowerCase()) ||
|
|
6374
|
+
errorCause.includes(pattern.toLowerCase()));
|
|
6375
|
+
}
|
|
6277
6376
|
/**
|
|
6278
6377
|
* Wraps errors with additional context and converts them to LangChain errors
|
|
6279
6378
|
*/
|
|
6280
6379
|
function handleLangChainError(error, context, additionalContext) {
|
|
6380
|
+
// Check for network errors first
|
|
6381
|
+
if (error instanceof Error && isNetworkError(error)) {
|
|
6382
|
+
const endpoint = additionalContext?.endpoint;
|
|
6383
|
+
const provider = additionalContext?.provider;
|
|
6384
|
+
throw new LangChainNetworkError(error.message, endpoint, provider, {
|
|
6385
|
+
originalError: error.name,
|
|
6386
|
+
originalMessage: error.message,
|
|
6387
|
+
stack: error.stack,
|
|
6388
|
+
context,
|
|
6389
|
+
...additionalContext
|
|
6390
|
+
});
|
|
6391
|
+
}
|
|
6281
6392
|
// If it's already a LangChain error, re-throw with additional context
|
|
6282
6393
|
if (error instanceof LangChainError) {
|
|
6283
6394
|
throw new LangChainExecutionError(`${context}: ${error.message}`, {
|
|
@@ -7061,21 +7172,55 @@ You must return ONLY valid JSON that matches the schema exactly. Do not include
|
|
|
7061
7172
|
}
|
|
7062
7173
|
}
|
|
7063
7174
|
|
|
7175
|
+
/**
|
|
7176
|
+
* Extracts provider and endpoint info from LLM instance if available
|
|
7177
|
+
*/
|
|
7178
|
+
function extractLlmInfo(llm) {
|
|
7179
|
+
const info = {};
|
|
7180
|
+
// Try to extract provider from class name
|
|
7181
|
+
const className = llm?.constructor?.name || '';
|
|
7182
|
+
if (className.includes('Ollama')) {
|
|
7183
|
+
info.provider = 'ollama';
|
|
7184
|
+
// Try to get baseUrl from ollama instance
|
|
7185
|
+
if ('lc_kwargs' in llm && typeof llm.lc_kwargs === 'object' && llm.lc_kwargs !== null) {
|
|
7186
|
+
const kwargs = llm.lc_kwargs;
|
|
7187
|
+
if (typeof kwargs.baseUrl === 'string') {
|
|
7188
|
+
info.endpoint = kwargs.baseUrl;
|
|
7189
|
+
}
|
|
7190
|
+
}
|
|
7191
|
+
}
|
|
7192
|
+
else if (className.includes('OpenAI')) {
|
|
7193
|
+
info.provider = 'openai';
|
|
7194
|
+
}
|
|
7195
|
+
else if (className.includes('Anthropic')) {
|
|
7196
|
+
info.provider = 'anthropic';
|
|
7197
|
+
}
|
|
7198
|
+
return info;
|
|
7199
|
+
}
|
|
7064
7200
|
/**
|
|
7065
7201
|
* Executes a LangChain pipeline with the provided LLM, prompt, variables, and parser.
|
|
7066
7202
|
* @param params - The execution parameters
|
|
7067
7203
|
* @returns The parsed result from the LLM chain
|
|
7068
7204
|
* @throws LangChainExecutionError if the chain execution fails or returns empty results
|
|
7205
|
+
* @throws LangChainNetworkError if a network/connection error occurs
|
|
7069
7206
|
*/
|
|
7070
|
-
const executeChain = async ({ llm, prompt, variables, parser }) => {
|
|
7207
|
+
const executeChain = async ({ llm, prompt, variables, parser, provider, endpoint, }) => {
|
|
7071
7208
|
validateRequired(llm, 'llm', 'executeChain');
|
|
7072
7209
|
validateRequired(prompt, 'prompt', 'executeChain');
|
|
7073
7210
|
validateRequired(variables, 'variables', 'executeChain');
|
|
7074
7211
|
validateRequired(parser, 'parser', 'executeChain');
|
|
7075
7212
|
// Validate that variables is an object
|
|
7076
7213
|
if (typeof variables !== 'object' || Array.isArray(variables)) {
|
|
7077
|
-
throw new LangChainExecutionError('executeChain: Variables must be a non-array object', {
|
|
7214
|
+
throw new LangChainExecutionError('executeChain: Variables must be a non-array object', {
|
|
7215
|
+
variables,
|
|
7216
|
+
type: typeof variables,
|
|
7217
|
+
isArray: Array.isArray(variables),
|
|
7218
|
+
});
|
|
7078
7219
|
}
|
|
7220
|
+
// Extract LLM info for error reporting if not provided
|
|
7221
|
+
const llmInfo = extractLlmInfo(llm);
|
|
7222
|
+
const effectiveProvider = provider || llmInfo.provider;
|
|
7223
|
+
const effectiveEndpoint = endpoint || llmInfo.endpoint;
|
|
7079
7224
|
try {
|
|
7080
7225
|
const chain = prompt.pipe(llm).pipe(parser);
|
|
7081
7226
|
const result = await chain.invoke(variables);
|
|
@@ -7086,14 +7231,27 @@ const executeChain = async ({ llm, prompt, variables, parser }) => {
|
|
|
7086
7231
|
}
|
|
7087
7232
|
catch (error) {
|
|
7088
7233
|
// Re-throw LangChain errors as-is
|
|
7089
|
-
if (error instanceof LangChainExecutionError) {
|
|
7234
|
+
if (error instanceof LangChainExecutionError || error instanceof LangChainNetworkError) {
|
|
7090
7235
|
throw error;
|
|
7091
7236
|
}
|
|
7237
|
+
// Check for network errors and throw specific error type
|
|
7238
|
+
if (error instanceof Error && isNetworkError(error)) {
|
|
7239
|
+
throw new LangChainNetworkError(error.message, effectiveEndpoint, effectiveProvider, {
|
|
7240
|
+
originalError: error.name,
|
|
7241
|
+
originalMessage: error.message,
|
|
7242
|
+
stack: error.stack,
|
|
7243
|
+
promptInputVariables: prompt.inputVariables,
|
|
7244
|
+
variableKeys: Object.keys(variables),
|
|
7245
|
+
parserType: parser.constructor.name,
|
|
7246
|
+
});
|
|
7247
|
+
}
|
|
7092
7248
|
// Wrap other errors with context
|
|
7093
7249
|
handleLangChainError(error, 'executeChain: Chain execution failed', {
|
|
7094
7250
|
promptInputVariables: prompt.inputVariables,
|
|
7095
7251
|
variableKeys: Object.keys(variables),
|
|
7096
|
-
parserType: parser.constructor.name
|
|
7252
|
+
parserType: parser.constructor.name,
|
|
7253
|
+
provider: effectiveProvider,
|
|
7254
|
+
endpoint: effectiveEndpoint,
|
|
7097
7255
|
});
|
|
7098
7256
|
}
|
|
7099
7257
|
};
|