classifyMessageCapError function

MessageCapRefusal? classifyMessageCapError(
  1. String? errorMessage
)

gh-1680: whether errorMessage is a per-request message-array cap refusal, and — when it is — the cap limit parsed from it.

Provider-agnostic: the regexes above are the ONLY built-in knowledge; no provider or model name appears here (AC5). Returns null for non-cap errors (auth 400s, bad requests, rate limits). A cap-shaped error WITHOUT a parseable number still classifies, with MessageCapRefusal.isUnknown true (edge E1: never a wedge, the model just gets the one-pass-per-refusal fallback).

Implementation

MessageCapRefusal? classifyMessageCapError(String? errorMessage) {
  if (errorMessage == null || errorMessage.isEmpty) return null;
  final isNonOverflow = _nonOverflowPatterns.any(
    (pattern) => pattern.hasMatch(errorMessage),
  );
  if (isNonOverflow) return null;
  final limitMatch = _messageCapLimitPattern.firstMatch(errorMessage);
  if (limitMatch != null) {
    final limit = int.tryParse(limitMatch.group(2)!.replaceAll(',', ''));
    if (limit != null && limit > 0) {
      return MessageCapRefusal(maxMessages: limit);
    }
  }
  for (final pattern in _messageCapShapePatterns) {
    if (pattern.hasMatch(errorMessage)) return const MessageCapRefusal();
  }
  return null;
}