Repository navigation
Fix Google API key invalidation classification - #39
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
🚧 Files skipped from review as they are similar to previous changes (4)
📝 WalkthroughWalkthroughGoogle GenAI failures are parsed into structured evidence for request errors, quota classification, cooldowns, and API-key invalidation. Redis stores provider-scoped invalid-key metadata and recovery audits, while quota APIs and tests carry the expanded metadata. ChangesGoogle error evidence and classification
Estimated code review effort: 4 (Complex) | ~60 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #39 +/- ##
==========================================
+ Coverage 76.35% 76.82% +0.46%
==========================================
Files 38 38
Lines 10736 10902 +166
Branches 1653 1685 +32
==========================================
+ Hits 8198 8375 +177
+ Misses 1938 1930 -8
+ Partials 600 597 -3 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: babf8adb68
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| evidence = self._extract_google_error_evidence(error) | ||
| status_code = evidence.status_code |
There was a problem hiding this comment.
Restore status fallback for unstructured Google errors
When the lower layer raises a non-Google exception that only carries the HTTP status in its text (for example a wrapper/transport RuntimeError("429 quota"), which _extract_status_code_from_exception() still explicitly supports), this now leaves status_code as None. The generic branch then records bounded evidence without the 429/400/403 signal, so quota/invalid-key state is not updated, and the mediator sees the new generic Google GenAI request failed. message and returns a 500 instead of the upstream status. Falling back to _extract_status_code_from_exception(error) when structured evidence has no status preserves the previous behavior for these unstructured errors.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
🧹 Nitpick comments (1)
smolrouter/redis_backend.py (1)
1613-1625: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick winRecovery audit list grows unbounded.
recover_invalidlpushes togoogle_invalid_key_recovery_audit:{provider}but never trims it, so the list grows without bound as recoveries accumulate. Consider capping it (e.g.pipe.ltrim(audit_key, 0, MAX_AUDIT-1)in the same transaction) or setting a TTL.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@smolrouter/redis_backend.py` around lines 1613 - 1625, Update recover_invalid’s audit-list transaction after the audit_key lpush to bound google_invalid_key_recovery_audit:{provider}, using the existing audit-limit constant if available and trimming it to retain only the newest entries. Keep the trim in the same pipeline/transaction so each recovery cannot leave the list unbounded.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@smolrouter/redis_backend.py`:
- Around line 1613-1625: Update recover_invalid’s audit-list transaction after
the audit_key lpush to bound google_invalid_key_recovery_audit:{provider}, using
the existing audit-limit constant if available and trimming it to retain only
the newest entries. Keep the trim in the same pipeline/transaction so each
recovery cannot leave the list unbounded.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 795d75d2-6965-4faf-a505-f925b0770363
📒 Files selected for processing (8)
smolrouter/database.pysmolrouter/google_genai_provider.pysmolrouter/mediator.pysmolrouter/redis_backend.pytests/unit/test_database.pytests/unit/test_google_genai_helpers.pytests/unit/test_new_integrations.pytests/unit/test_redis_backend.py
|



Summary
Incident
A generic
400 INVALID_ARGUMENTmatched a broad fallback indicator and invalidated keys fleet-wide.Verification
uv run pytest -q tests/unit(1011 passed, 1 skipped)uv run ruff check smolrouter/google_genai_provider.py smolrouter/redis_backend.py smolrouter/database.py smolrouter/mediator.py tests/unit/test_google_genai_helpers.py tests/unit/test_new_integrations.py tests/unit/test_redis_backend.pySummary by CodeRabbit
Bug Fixes
Tests