Introduce MistralRequestCoordinator and queueing for Mistral auto-screenshots#71
Conversation
There was a problem hiding this comment.
Summary
This PR introduces MistralRequestCoordinator to centralize rate-limiting logic and implements a screenshot queueing mechanism for Mistral requests. The coordinator provides sophisticated retry logic with cooldown tracking and adaptive backoff.
Critical Issues Found
I've identified 2 critical defects that should be addressed before merging:
- ScreenCaptureApiClients.kt: The coordinator is invoked with only a single API key, defeating its purpose of multi-key rotation
- MistralRequestCoordinator.kt: Potential crash from using
apiKeys.first()instead ofkeyPool.first()
Architecture Notes
The refactoring successfully consolidates rate-limiting logic and removes ~130 lines of duplicate code from PhotoReasoningViewModel. The new queueing mechanism for auto-screenshots (latest-wins pattern) is well-designed for preventing overlapping requests.
You can now have the agent implement changes and create commits directly on your pull request's source branch. Simply comment with /q followed by your request in natural language to ask the agent to make changes.
| val coordinated = MistralRequestCoordinator.execute(apiKeys = listOf(apiKey), maxAttempts = 4) { key -> | ||
| client.newCall( | ||
| request.newBuilder() | ||
| .header("Authorization", "Bearer $key") | ||
| .build() | ||
| ).execute() | ||
| } |
There was a problem hiding this comment.
🛑 Logic Error: Passing only a single API key defeats the purpose of using MistralRequestCoordinator. The coordinator is designed to handle multiple API keys for rotation and fallback, but this implementation provides a list containing only the single apiKey parameter. This means no key rotation will occur even if the coordinator supports it, and the coordinator's multi-key logic becomes redundant overhead.
Either pass all available API keys from ApiKeyManager, or call the Mistral API directly without the coordinator if only one key is intended.
app/src/main/kotlin/com/google/ai/sample/network/MistralRequestCoordinator.kt
Outdated
Show resolved
Hide resolved
…tCoordinator.kt Co-authored-by: amazon-q-developer[bot] <208079219+amazon-q-developer[bot]@users.noreply.github.com>
|
/q Fix ScreenCaptureApiClients.kt: The coordinator is invoked with only a single API key, defeating its purpose of multi-key rotation |
|
I'll fix the issue where the MistralRequestCoordinator is being invoked with only a single API key, defeating its purpose of multi-key rotation. Changes I will implement: |
|
✅ Changes committed successfully! I've fixed the multi-key rotation issue for the Mistral API coordinator: Summary of changes:
The coordinator can now properly rotate through multiple API keys as originally intended, improving rate limit handling and request reliability. |
…or Mistral coordinator Update callMistralApi to accept and use multiple API keys for proper rotation through MistralRequestCoordinator, instead of defeating the coordinator's purpose with a single-key list
6c1a954
into
fix-compilation-errors-in-mainactivity.kt-h8jilx
Motivation
Description
MistralRequestCoordinator(app/src/main/kotlin/com/google/ai/sample/network/MistralRequestCoordinator.kt) that implements cooldown tracking,Retry-After/x-ratelimit-resetparsing, adaptive backoff, and coordinated selection/rotation of API keys viaexecute(apiKeys, maxAttempts, request).ScreenCaptureApiClients.callMistralApito useMistralRequestCoordinator.executefor performing the HTTP call and key rotation instead of calling the endpoint directly.PhotoReasoningViewModelto use the coordinator forreasonWithMistralstreaming calls and remove the previous inline per-key cooldown and retry loop.QueuedMistralScreenshotRequest,enqueueMistralAutoScreenshotRequest,dispatchMistralAutoScreenshotRequest, andreleaseAndDrainMistralAutoScreenshotQueueto ensure only one in-flight Mistral auto-screenshot request and drain a single queued request afterwards.MistralRequestCoordinator.Testing
./gradlew :app:assembleDebugand verified the build completes successfully../gradlew :app:testand observed they complete without failures.Codex Task