@juspay/neurolink
Version:
Universal AI Development Platform with working MCP integration, multi-provider support, voice (TTS/STT/realtime), and professional CLI. 58+ external MCP servers discoverable, multimodal file processing, RAG pipelines. Build, test, and deploy AI applicatio
172 lines • 5.74 kB
JavaScript
/**
* Context Overflow Error Detection
*
* Cross-provider regex patterns to detect context window overflow errors.
* Modeled on Cline + pi-mono patterns.
*/
/**
* Provider-specific error patterns for context overflow.
*
* IMPORTANT: Order matters for getContextOverflowProvider - more specific
* patterns should be checked first. OpenAI patterns are very specific
* (e.g., "This model's maximum context length is") so they come first.
*/
const OVERFLOW_PATTERNS = [
{
provider: "openai",
patterns: [
/This model's maximum context length is/i,
/tokens\. However, (?:your messages|you requested)/i,
/reduce the length of the messages/i,
/Please reduce the length/i,
],
},
{
provider: "azure",
patterns: [/content_length_exceeded/i],
},
{
provider: "google",
patterns: [
/RESOURCE_EXHAUSTED/i,
/exceeds the maximum number of tokens/i,
/content is too long/i,
/request payload size exceeds/i,
/input token limit/i,
],
},
{
provider: "bedrock",
patterns: [
/ValidationException.*token/i,
/Input is too long/i,
/exceeds the model's maximum/i,
],
},
{
provider: "mistral",
patterns: [/context length exceeded/i, /maximum number of tokens/i],
},
{
provider: "openrouter",
patterns: [/context_length_exceeded/i],
},
{
provider: "anthropic",
patterns: [
/prompt is too long/i,
/input is too long/i,
/too many tokens/i,
/maximum context length/i,
],
},
];
/**
* Check if an error is a context overflow error from any provider.
*/
export function isContextOverflowError(error) {
const errorMessage = extractErrorMessage(error);
if (!errorMessage) {
return false;
}
return OVERFLOW_PATTERNS.some(({ patterns }) => patterns.some((pattern) => pattern.test(errorMessage)));
}
/**
* Identify which provider produced the context overflow error.
*/
export function getContextOverflowProvider(error) {
const errorMessage = extractErrorMessage(error);
if (!errorMessage) {
return null;
}
for (const { provider, patterns } of OVERFLOW_PATTERNS) {
if (patterns.some((pattern) => pattern.test(errorMessage))) {
return provider;
}
}
return null;
}
/**
* Extract actual token counts from provider overflow error messages.
*
* Many providers include the actual/max token counts in their error messages:
* - OpenAI: "This model's maximum context length is 128000 tokens. However, your messages resulted in 145000 tokens."
* - Anthropic: "prompt is too long: 180000 tokens > 200000 token limit"
* - Google: "exceeds the maximum number of tokens (180000 > 100000)"
*/
export function parseProviderOverflowDetails(error) {
const message = extractErrorMessage(error);
if (!message) {
return null;
}
// Guard against excessively long inputs that could slow regex matching
if (message.length > 2000) {
return null;
}
// OpenAI pattern: "resulted in X tokens" + "maximum context length is Y"
// Use single character-class number groups to prevent ReDoS (CodeQL: js/polynomial-redos)
const openaiActual = message.match(/resulted\s+in\s+(\d[\d,]{0,19})\s*tokens/i);
const openaiMax = message.match(/maximum\s+context\s+length\s+is\s+(\d[\d,]{0,19})/i);
if (openaiActual && openaiMax) {
return {
actualTokens: parseInt(openaiActual[1].replace(/,/g, ""), 10),
budgetTokens: parseInt(openaiMax[1].replace(/,/g, ""), 10),
};
}
// Anthropic pattern: "X tokens > Y token limit" or "X tokens, limit Y"
// Use single character-class number groups to prevent ReDoS (CodeQL: js/polynomial-redos)
const anthropicMatch = message.match(/(\d[\d,]{0,19})\s*tokens?\s*[>:]\s*(\d[\d,]{0,19})/i);
if (anthropicMatch) {
return {
actualTokens: parseInt(anthropicMatch[1].replace(/,/g, ""), 10),
budgetTokens: parseInt(anthropicMatch[2].replace(/,/g, ""), 10),
};
}
// Google pattern: "X > Y" or "X exceeds Y"
// Use single character-class number groups to prevent ReDoS (CodeQL: js/polynomial-redos)
const googleMatch = message.match(/(\d[\d,]{0,19})\s*(?:>|exceeds)\s*(\d[\d,]{0,19})/i);
if (googleMatch) {
return {
actualTokens: parseInt(googleMatch[1].replace(/,/g, ""), 10),
budgetTokens: parseInt(googleMatch[2].replace(/,/g, ""), 10),
};
}
return null;
}
/**
* Extract error message from various error formats.
*/
export function extractErrorMessage(error) {
if (!error) {
return null;
}
if (typeof error === "string") {
return error;
}
if (error instanceof Error) {
// Check nested error messages too
const msg = error.message;
const cause = error?.cause;
if (cause instanceof Error) {
return `${msg} ${cause.message}`;
}
return msg;
}
if (typeof error === "object") {
const obj = error;
if (typeof obj.message === "string") {
return obj.message;
}
if (typeof obj.error === "string") {
return obj.error;
}
if (typeof obj.error === "object" && obj.error !== null) {
const nested = obj.error;
if (typeof nested.message === "string") {
return nested.message;
}
}
}
return null;
}
//# sourceMappingURL=errorDetection.js.map