Files

51 lines
1.9 KiB
Python

"""Shared detection for adaptive context recovery (no assumed model window)."""
from collections.abc import Mapping
CONTEXT_RECOVERY_MESSAGE = "请补充本次需要处理的具体问题或关键材料,我会继续为你解答。"
_PATTERNS = (
"context_length_exceeded",
"maximum context length",
"max context length",
"context window exceeds limit",
"context window exceeded",
"exceeds the context window",
"max_model_len",
"prompt is too long",
"input is too long",
"too many tokens",
"input token count",
"prompt token count",
"exceeds the model's context",
"exceeds model context",
"上下文长度",
"最大上下文",
"输入 token 数超过",
"输入token数超过",
)
def is_context_length_error(exc: BaseException) -> bool:
"""Inspect provider error codes as well as text, without matching all 400s."""
values = [str(exc), str(getattr(exc, "code", "")), str(getattr(exc, "error_code", ""))]
# Compatible gateways may use numeric codes and put the only context-size
# signal in their message. Our adapter keeps that text private so __str__
# and framework logs cannot expose provider bodies; classify it in-process.
classification_detail = getattr(exc, "_classification_detail", None)
if isinstance(classification_detail, str):
values.append(classification_detail)
body = getattr(exc, "body", None)
if isinstance(body, Mapping):
error = body.get("error", body)
if isinstance(error, Mapping):
values.extend(str(error.get(key, "")) for key in ("code", "type", "message"))
return any(pattern in value.lower() for value in values for pattern in _PATTERNS)
class ContextRecoveryExhausted(RuntimeError):
"""Internal failure for contracts that cannot degrade to conversational text."""
def __init__(self) -> None:
super().__init__("context_length_exceeded: adaptive recovery exhausted")