UN-3034 [FIX] Add retry backoff configuration for LLMWhisperer client#1836
UN-3034 [FIX] Add retry backoff configuration for LLMWhisperer client#1836chandrasekharan-zipstack merged 18 commits intomainfrom
Conversation
WalkthroughThis PR adds configurable retry and backoff behavior for the LLMWhisperer v2 client by introducing three environment variables, updating the client dependency version, and propagating these configuration parameters through the adapter initialization chain. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes 🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
2097c44 to
513b919
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
unstract/sdk1/src/unstract/sdk1/adapters/x2text/llm_whisperer_v2/src/helper.py (1)
110-116:⚠️ Potential issue | 🟠 MajorUse the exception's status code instead of hard-coding 500.
The
LLMWhispererClientExceptioncarries a.status_codeattribute that reflects the upstream HTTP status. With the new retry logic enabled, this exception path becomes more important. Instead of always mapping it tostatus_code=500at line 159, usee.status_codewhen available so callers can distinguish 429 (throttling) from 5xx (server errors).except LLMWhispererClientException as e: logger.error(f"LLM Whisperer error: {e}") raise ExtractorError( message=f"LLM Whisperer error: {e}", actual_err=e, status_code=e.status_code or 500, ) from e🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@unstract/sdk1/src/unstract/sdk1/adapters/x2text/llm_whisperer_v2/src/helper.py` around lines 110 - 116, The exception handler for LLMWhispererClientException currently maps all errors to status_code=500; update the handler in helper.py (the except LLMWhispererClientException block) to pass the exception's actual status via e.status_code (falling back to 500 if None) when raising ExtractorError, and keep the existing logger.error and actual_err=e fields intact so callers can distinguish 429 vs 5xx errors.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@unstract/sdk1/src/unstract/sdk1/adapters/x2text/llm_whisperer_v2/src/constants.py`:
- Around line 114-116: Replace the raw import-time int/float conversions for
MAX_RETRIES, RETRY_MIN_WAIT, and RETRY_MAX_WAIT by using validation helpers
(e.g., get_int_env and get_float_env) that read os.getenv(WhispererEnv.*), treat
None or "" as the default, catch/handle non-numeric values, enforce min bounds
(e.g., MAX_RETRIES >= 0, RETRY_MIN_WAIT >= 0.0), and then validate the
relationship RETRY_MAX_WAIT >= RETRY_MIN_WAIT; update the constants assignment
to call these helpers so module import cannot crash and invalid backoff configs
are rejected with clear errors.
---
Outside diff comments:
In
`@unstract/sdk1/src/unstract/sdk1/adapters/x2text/llm_whisperer_v2/src/helper.py`:
- Around line 110-116: The exception handler for LLMWhispererClientException
currently maps all errors to status_code=500; update the handler in helper.py
(the except LLMWhispererClientException block) to pass the exception's actual
status via e.status_code (falling back to 500 if None) when raising
ExtractorError, and keep the existing logger.error and actual_err=e fields
intact so callers can distinguish 429 vs 5xx errors.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 43eccf10-b938-4493-9528-74c02bfca08a
⛔ Files ignored due to path filters (7)
platform-service/uv.lockis excluded by!**/*.lockprompt-service/uv.lockis excluded by!**/*.lockunstract/filesystem/uv.lockis excluded by!**/*.lockunstract/sdk1/uv.lockis excluded by!**/*.lockunstract/tool-registry/uv.lockis excluded by!**/*.lockunstract/workflow-execution/uv.lockis excluded by!**/*.lockuv.lockis excluded by!**/*.lock
📒 Files selected for processing (5)
backend/sample.envprompt-service/sample.envunstract/sdk1/pyproject.tomlunstract/sdk1/src/unstract/sdk1/adapters/x2text/llm_whisperer_v2/src/constants.pyunstract/sdk1/src/unstract/sdk1/adapters/x2text/llm_whisperer_v2/src/helper.py
unstract/sdk1/src/unstract/sdk1/adapters/x2text/llm_whisperer_v2/src/constants.py
Show resolved
Hide resolved
…unstract into fix/llmwhisperer-retry
|
Looks like some lock files were not updated in a long time like workflow-execution and workers. That could be the reason for such huge file diffs. |
Test ResultsSummary
Runner Tests - Full Report
|
|
Greptile SummaryThis PR adds configurable retry backoff parameters (
Confidence Score: 4/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant Env as Environment Variables
participant Defaults as WhispererDefaults
participant Helper as LLMWhispererHelper
participant Client as LLMWhispererClientV2
participant API as LLMWhisperer API
Env->>Defaults: ADAPTER_LLMW_MAX_RETRIES (default: 3)
Env->>Defaults: ADAPTER_LLMW_RETRY_MIN_WAIT (default: 1.0s)
Env->>Defaults: ADAPTER_LLMW_RETRY_MAX_WAIT (default: 60.0s)
Helper->>Client: LLMWhispererClientV2(max_retries, retry_min_wait, retry_max_wait)
activate Client
Helper->>Client: client.whisper(...)
Client->>API: POST /whisper
API-->>Client: HTTP 429 / 5xx (transient error)
Note over Client: exponential backoff retry<br/>(up to max_retries times,<br/>wait between min_wait and max_wait)
Client->>API: POST /whisper (retry)
API-->>Client: HTTP 200 OK
Client-->>Helper: response
deactivate Client
|



What
Why
How
ADAPTER_LLMW_MAX_RETRIES,ADAPTER_LLMW_RETRY_MIN_WAIT,ADAPTER_LLMW_RETRY_MAX_WAITWhispererEnvandWhispererDefaultsmax_retries,retry_min_wait,retry_max_wait) toLLMWhispererClientV2constructorsample.envfor prompt-service only (backendsample.envis not changed as the retry env vars are only needed by the prompt-service)Can this PR break any existing features. If yes, please list possible items. If no, please explain why. (PS: Admins do not merge the PR without this section filled)
Database Migrations
Env Config
ADAPTER_LLMW_MAX_RETRIES(default: 3) - Max retry attempts for transient HTTP errors. Set 0 to disable.ADAPTER_LLMW_RETRY_MIN_WAIT(default: 1.0) - Min backoff wait in seconds between retriesADAPTER_LLMW_RETRY_MAX_WAIT(default: 60.0) - Max backoff wait in seconds between retriesRelevant Docs
Related Issues or PRs
Dependencies Versions
llmwhisperer-clientversion in sdk1Notes on Testing
Screenshots
Checklist
I have read and understood the Contribution Guidelines.