diff options
Diffstat (limited to '.rules/plan/10-10-broaden-strict-regex.md')
| -rw-r--r-- | .rules/plan/10-10-broaden-strict-regex.md | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/.rules/plan/10-10-broaden-strict-regex.md b/.rules/plan/10-10-broaden-strict-regex.md new file mode 100644 index 0000000..6d53606 --- /dev/null +++ b/.rules/plan/10-10-broaden-strict-regex.md @@ -0,0 +1,103 @@ +# Phase 10 — Broaden strict-tool-schema fallback regex + +**Estimated time:** ~10 minutes +**Touches:** `lib/dispatch/adapter/minimax.rb` +(specifically `strict_grammar_error?`). + +## Goal + +The Claude adapter retries a failed tool-using request with `strict: +false` on tool definitions when Anthropic returns a 400 error like +`"compiled grammar too large"` or `"schema too complex"`. The retry +harness (`chat_streaming_with_strict_fallback`, +`chat_non_streaming_with_strict_fallback`, the `@strict_disabled` flag) +should be KEPT — it is harmless when not triggered and useful when it +is. + +The matcher itself, currently keyed on Anthropic's exact wording, +should be broadened so that an analogous MiniMax error message also +fires the fallback. We don't yet know MiniMax's exact wording for this +class of error (or whether they have one), so the new regex must be +tolerant: match HTTP 400 responses whose error message mentions +`grammar` or `schema` and a "too large" / "too complex" / "invalid" +qualifier — case insensitive. + +## Steps + +### 1. Locate the matcher + +Find `def strict_grammar_error?` (or similarly named — search for +`grammar` in `lib/dispatch/adapter/minimax.rb`). It currently looks +like: + +```ruby +def strict_grammar_error?(err) + return false unless err.is_a?(RequestError) + return false unless err.status_code == 400 + msg = err.message.to_s + msg.match?(/compiled grammar too large/i) || + msg.match?(/schema too complex/i) +end +``` + +### 2. Broaden the regex + +Replace the body with a more tolerant matcher: + +```ruby +STRICT_GRAMMAR_PATTERNS = [ + /compiled\s+grammar\s+too\s+large/i, + /schema\s+too\s+complex/i, + /(?:grammar|schema).*?(?:too\s*(?:large|complex|big)|invalid|exceed)/i, + /tool[_\s-]?schema.*(?:too\s*(?:large|complex)|exceed)/i +].freeze + +def strict_grammar_error?(err) + return false unless err.is_a?(RequestError) + return false unless err.status_code == 400 + msg = err.message.to_s + STRICT_GRAMMAR_PATTERNS.any? { |re| msg.match?(re) } +end +``` + +Place `STRICT_GRAMMAR_PATTERNS` as a module-level constant (visibility +private to `Dispatch::Adapter::MiniMax` is fine; it does not need to be +exposed externally). + +### 3. Confirm the retry harness still uses the predicate + +Find `chat_streaming_with_strict_fallback` and +`chat_non_streaming_with_strict_fallback` (or whatever the harness +methods are called). Both should call `strict_grammar_error?(error)` +inside their `rescue RequestError => e` block. If they reference some +older predicate name, update them to call the new one. + +DO NOT change the rest of the harness logic. The single-shot retry, the +`@strict_disabled = true` latch, and the `disable_strict_tools: true` +forwarding to `RequestBuilder.build` all stay. + +## Acceptance criteria + +- The matcher returns `true` for a `RequestError` with status `400` and + message `"compiled grammar too large for tool 'foo'"`. +- The matcher returns `true` for a `RequestError` with status `400` and + message `"Tool schema is too complex"`. +- The matcher returns `true` for a `RequestError` with status `400` and + message `"grammar exceeds maximum size"`. +- The matcher returns `false` for a `RequestError` with status `400` and + message `"missing required field: messages"`. +- The matcher returns `false` for a `RequestError` with status `429`, + even if the message contains `"grammar"` (status guard). +- The matcher returns `false` for a non-`RequestError` exception. +- `bundle exec rubocop --autocorrect-all` exits 0. + +## Verification + +Run `run_tests` with `project_path=reference/dispatch-adapter-minimax`. +Rubocop must be clean. `strict_fallback_spec.rb` failures referring to +the broader matcher (e.g. tests asserting it does NOT fire on +"grammar exceeds maximum size") are addressed in phase 16. Other +failures must be investigated. + +Test coverage for the new regex variants is added in phase 16. Do NOT +add specs here. |
