Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,15 @@ describe("checkContextWindowExceededError", () => {
expect(checkContextWindowExceededError(error)).toBe(false)
})

it("should not detect errors with different status codes", () => {
it("should detect errors with different status codes via generic check", () => {
// Note: The generic check now catches context overflow messages regardless of status code
// This is intentional to handle third-party proxies that may return different status codes
const error = {
status: 500,
message: "context length exceeded",
}

expect(checkContextWindowExceededError(error)).toBe(false)
expect(checkContextWindowExceededError(error)).toBe(true)
})
})

Expand Down Expand Up @@ -179,7 +181,9 @@ describe("checkContextWindowExceededError", () => {
expect(checkContextWindowExceededError(error)).toBe(false)
})

it("should not detect errors with different error types", () => {
it("should detect errors with different error types via generic check", () => {
// Note: The generic check now catches context overflow messages regardless of error type
// This is intentional to handle third-party proxies that may return different error structures
const error = {
error: {
error: {
Expand All @@ -189,7 +193,7 @@ describe("checkContextWindowExceededError", () => {
},
}

expect(checkContextWindowExceededError(error)).toBe(false)
expect(checkContextWindowExceededError(error)).toBe(true)
})
})

Expand Down Expand Up @@ -269,15 +273,17 @@ describe("checkContextWindowExceededError", () => {
expect(checkContextWindowExceededError(error)).toBe(false)
})

it("should handle errors that throw during property access", () => {
it("should handle errors that throw during property access via generic check", () => {
// Note: The generic check now catches context overflow messages even when some properties throw
// This is intentional to handle edge cases where error objects have problematic getters
const error = {
get status() {
throw new Error("Property access error")
},
message: "context length exceeded",
}

expect(checkContextWindowExceededError(error)).toBe(false)
expect(checkContextWindowExceededError(error)).toBe(true)
})

it("should handle mixed provider error structures", () => {
Expand Down Expand Up @@ -326,4 +332,244 @@ describe("checkContextWindowExceededError", () => {
expect(checkContextWindowExceededError(error3)).toBe(true)
})
})

describe("LiteLLM errors", () => {
it("should detect LiteLLM context window error with standard message", () => {
const error = {
message: "context length exceeded for this model",
}
expect(checkContextWindowExceededError(error)).toBe(true)
})

it("should detect LiteLLM error with nested error structure", () => {
const error = {
error: {
message: "maximum context length is 4096 tokens",
},
}
expect(checkContextWindowExceededError(error)).toBe(true)
})

it("should detect LiteLLM error with deeply nested structure", () => {
const error = {
error: {
error: {
message: "input is too long for this model",
},
},
}
expect(checkContextWindowExceededError(error)).toBe(true)
})

it("should detect LiteLLM error with detail field", () => {
const error = {
detail: "request is too large, please reduce input size",
}
expect(checkContextWindowExceededError(error)).toBe(true)
})

it("should detect LiteLLM error with context_length_exceeded type", () => {
const error = {
error: {
type: "context_length_exceeded",
message: "The request exceeds the maximum context",
},
}
expect(checkContextWindowExceededError(error)).toBe(true)
})

it("should detect LiteLLM error with context_length_exceeded code", () => {
const error = {
error: {
code: "context_length_exceeded",
message: "Error processing request",
},
}
expect(checkContextWindowExceededError(error)).toBe(true)
})

it("should detect various LiteLLM context error patterns", () => {
const patterns = [
"context length exceeded",
"maximum token limit reached",
"too many tokens in input",
"input is too long",
"exceeds max context size",
"request is too large",
"prompt is too long",
]

patterns.forEach((pattern) => {
const error = {
message: pattern,
}
expect(checkContextWindowExceededError(error)).toBe(true)
})
})

it("should detect Chinese context error messages", () => {
const patterns = ["输入超长了", "超出上下文限制", "请求太长了", "上下文超出限制"]

patterns.forEach((pattern) => {
const error = {
message: pattern,
}
expect(checkContextWindowExceededError(error)).toBe(true)
})
})

it("should not detect non-context LiteLLM errors", () => {
const error = {
message: "Invalid API key provided",
}
expect(checkContextWindowExceededError(error)).toBe(false)
})
})

describe("Generic context window errors", () => {
it("should detect string error with context overflow message", () => {
const error = "context length exceeded for this request"
expect(checkContextWindowExceededError(error)).toBe(true)
})

it("should detect error with body field containing context message", () => {
const error = {
body: "The input exceeds the maximum token limit",
}
expect(checkContextWindowExceededError(error)).toBe(true)
})

it("should detect error with text field containing context message", () => {
const error = {
text: "Please reduce the length of your input",
}
expect(checkContextWindowExceededError(error)).toBe(true)
})

it("should detect error with data field containing context message", () => {
const error = {
data: "token count exceeded the maximum allowed",
}
expect(checkContextWindowExceededError(error)).toBe(true)
})

it("should detect error with stringified error field", () => {
const error = {
error: "context window overflow detected",
}
expect(checkContextWindowExceededError(error)).toBe(true)
})

it("should detect error with cause chain", () => {
const error = {
message: "Request failed",
cause: {
message: "context length exceeded",
},
}
expect(checkContextWindowExceededError(error)).toBe(true)
})

it("should detect various generic context error patterns", () => {
const patterns = [
"context length exceeded",
"context window overflow",
"maximum token count reached",
"too many tokens",
"input is too long",
"exceeds the max length",
"request is too large",
"prompt is too long",
"token limit exceeded",
"reduce the length of your input",
]

patterns.forEach((pattern) => {
const error = {
message: pattern,
}
expect(checkContextWindowExceededError(error)).toBe(true)
})
})

it("should detect Chinese context error messages in generic check", () => {
const patterns = ["输入超长", "超出长度限制", "上下文太长", "令牌超出限制"]

patterns.forEach((pattern) => {
const error = {
message: pattern,
}
expect(checkContextWindowExceededError(error)).toBe(true)
})
})

it("should detect Japanese context error messages", () => {
const patterns = ["コンテキストが長すぎます", "入力が超過しました", "リクエストが制限を超えました"]

patterns.forEach((pattern) => {
const error = {
message: pattern,
}
expect(checkContextWindowExceededError(error)).toBe(true)
})
})

it("should detect Korean context error messages", () => {
// These patterns match the regex: /(?:컨텍스트|입력|요청).*(?:너무\s*길|초과|제한)/
const patterns = ["컨텍스트 너무 길다", "입력 초과", "요청 제한"]

patterns.forEach((pattern) => {
const error = {
message: pattern,
}
expect(checkContextWindowExceededError(error)).toBe(true)
})
})

it("should not detect non-context generic errors", () => {
const error = {
message: "Network connection failed",
}
expect(checkContextWindowExceededError(error)).toBe(false)
})

it("should not detect string errors without context keywords", () => {
const error = "Invalid authentication credentials"
expect(checkContextWindowExceededError(error)).toBe(false)
})
})

describe("Edge cases for new functions", () => {
it("should handle string input with context overflow message", () => {
expect(checkContextWindowExceededError("context length exceeded")).toBe(true)
})

it("should handle string input without context overflow message", () => {
expect(checkContextWindowExceededError("some other error")).toBe(false)
})

it("should handle deeply nested cause chain", () => {
const error = {
message: "Outer error",
cause: {
message: "Middle error",
cause: {
message: "context length exceeded",
},
},
}
expect(checkContextWindowExceededError(error)).toBe(true)
})

it("should handle error with multiple message sources", () => {
const error = {
message: "Generic error",
error: {
message: "context window exceeded",
},
detail: "Some detail",
}
expect(checkContextWindowExceededError(error)).toBe(true)
})
})
})
Loading
Loading