feat(deadline): bound LLM calls and retries by the run's execution deadline (PC-4871) - #124
Draft
vldcmp-uipath wants to merge 1 commit into
Draft
feat(deadline): bound LLM calls and retries by the run's execution deadline (PC-4871)#124vldcmp-uipath wants to merge 1 commit into
vldcmp-uipath wants to merge 1 commit into
Conversation
…adline (PC-4871) Serverless agent runs are force-killed by the control plane after a fixed execution window (15 minutes today). A single LLM call plus its automatic retries could outlast that window: the request timeout was a fixed 895s, the retry loop was bounded by attempt count rather than elapsed time, and the process died mid-call with no logs flushed and no timeout recorded on spans. The host runtime can now declare the run's hard deadline once at startup via set_execution_deadline(seconds_from_now). When set, the shared retryable transports enforce it per attempt: - cap the client-side httpx timeout of every attempt to the remaining budget - lower the X-UiPath-LLMGateway-TimeoutSeconds header to the remaining budget (never raising it above its configured value) - stop the retry loop at the deadline (stop_when_deadline_exhausted, OR-ed with the attempt-count stop) and shorten backoff sleeps so retries never sleep through the deadline - fail fast with UiPathExecutionDeadlineError when under 5s of budget remains When no deadline is set, behaviour is unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem — PC-4871
Serverless agent runs are force-killed (SIGTERM) by the control plane after a 15-minute execution window. A single LLM call plus its automatic retries can outlast that window:
X-UiPath-LLMGateway-TimeoutSeconds: 895header), leaving no room inside the window;stop_after_attempt), not after total elapsed time — 5 attempts × up to 895s each plus backoff waits;The process dies mid-call: no logs are flushed and LLM spans never record a timeout, making these failures nearly impossible to diagnose.
What this PR does
Adds an execution-deadline mechanism to the shared transports (
uipath.llm_client.utils.deadline). The host runtime declares the run's hard deadline once at startup:When a deadline is set, every request through
RetryableHTTPTransport/RetryableAsyncHTTPTransportis clamped per attempt:X-UiPath-LLMGateway-TimeoutSecondsis lowered to the remaining budget (never raised above its configured value) so the gateway can give up when the client does.stop_when_deadline_exhaustedis OR-ed with the existing attempt-count stop, and backoff sleeps (includingRetry-Afterhints) are shortened so a retry never sleeps through the deadline.UiPathExecutionDeadlineError(EXECUTION_DEADLINE_EXCEEDED) instead of starting a doomed attempt — so the run ends with a clear, traceable error.When no deadline is set (the default), behaviour is byte-for-byte unchanged — verified by the existing retry suite.
What this PR deliberately does NOT do (follow-ups)
uipath-agents-python): setset_execution_deadline()at run start from the serverless execution window. The window is not currently discoverable at runtime (no env var / context field), so this needs an env var contract with the serverless control plane (e.g.UIPATH_EXECUTION_TIME_LIMIT_SECONDS) — opt-in, so robot/long-running/local runs are unaffected.AgentHubService): the AgentHub LLM proxy currently ignores the caller's timeout header and forwards its own static config (900s) to LLM Gateway (LlmGatewayClient.CreateRequestAsync). Until AgentHub forwardsmin(caller value, configured value), item (2) above only reaches LLM Gateway on the direct-LLMGW path; on the AgentHub path the server-side hint stays 900s and enforcement is purely client-side (which still fixes the SIGTERM symptom).X-UiPath-LlmGateway-TimeoutSecondscaps the total processing time including cross-region retries, or per-attempt only.Known limitation
For streaming responses the httpx read timeout applies per chunk, so a slowly-trickling stream can still outlast the deadline. Streaming callers need their own total-elapsed cutoff (documented in the module docstring).
Test plan
tests/core/features/test_deadline.py(new, 19 tests): ContextVar helpers, fail-fast without touching the transport (sync/async/retries-disabled), header + timeout clamping (including "never raise the hint"), retry loop stopping at the deadline, wait capping (backoff and Retry-After), and no-deadline behaviour unchanged.tests/coreunit suite: 493 passed (the 42 errors are pre-existing integration tests requiring liveLLMGW_*credentials).ruff check/ruff format/pyrightclean.🤖 Generated with Claude Code