mirror of
https://github.com/VectifyAI/PageIndex.git
synced 2026-10-02 07:44:37 +08:00
* Tool-path rate limits: retry at the bridge, then fail the run fast A PageIndex cloud 429 (or 5xx) on a tool call used to reach the model as an INTERNAL_ERROR envelope saying "try again": the model re-called once with no wait, then wrote the failure into its answer, and chat() returned normally with no status anywhere. The same 429 before the loop (the doc_id targeting lookup) already propagated raw. - McpBridge mounts a urllib3 Retry: 429/502/503 and connection failures, three attempts, 0/2/4 s apart or as Retry-After says; read timeouts are never replayed (240 s each, and the server may have acted); a Retry-After past a minute is a quota, not a blip, so the backoff runs instead of sleeping it out. Exhausted, the last response falls through to the existing >= 400 branch, so the status_code survives. - _bridge_invoker re-raises 429/5xx alongside 401/403. The frameworks turn a raised tool exception back into model-visible text, so each chat() door gets its own escape: the in-process MCPServer's failure_error_function lets a PageIndex-caused failure propagate and _translate_run_error unwraps it from the framework's wrapper (which also un-flattens the 401 case); the Messages lane runs each turn's tools through the runner's public generate_tool_call_response() and raises before the next model call. - _model_backend_error keeps the provider's status_code. Claude Agent SDK tools cannot fail fast: the SDK MCP server converts handler exceptions into JSON-RPC errors for Claude Code by design. Claude-Session: https://claude.ai/code/session_014S88dcSz7jykegAWyWZk8E * Tool-path fail-fast: cover unreachable servers and all 5xx The bridge retry is now a plain urllib3 Retry: 429 and every 5xx retried three times at the fixed 0/2/4 s backoff, Retry-After ignored. That drops the _Retry subclass, whose get_retry_after raised InvalidHeader on a non-integer header (turning a 429 into "could not reach the server"), honoured a 60 s Retry-After three times over, and let a 413 carrying Retry-After replay. 500 and 504 join the forcelist so the invoker's "what survived the bridge's retries" holds for every status it re-raises. Retry is imported from requests.adapters, the declared dependency. The invoker re-raises transport failures too: once the bridge's own connection retries fail, the model cannot reach the server either, and the envelope only sent it round the retry loop. The handshake error blames the API key only on 401/403: a rate-limited handshake is now a run-terminating error and was telling users to rotate a working key. Docstrings on agent_tools()/build_agent_tools and the Anthropic adapter state the real raise set: 401/403, post-retry 429/5xx, unreachable server. Claude-Session: https://claude.ai/code/session_013xk3xt9KgHNTjsYmFLKxbu * fix: surface Messages tool failures before advancing runner * fix: require urllib3 1.26 for MCP retries * fix: keep the Messages fail-fast quiet and single-path Raise ToolError from the tools chat(protocol="messages") runs instead of the raw PageIndexAPIError: the Anthropic runner log.exception()s any other exception, so every fail-fast printed a 20-line traceback from anthropic's internals before the SDK raised its own error. The lane still records the failure and raises it right after the runner's tool batch, so the ToolError content never reaches the model. Drop the two post-loop _messages_fail_fast calls: the runner executes tools only through the public generate_tool_call_response (0.108.0 through 1.4.0), which checked_tool_response wraps, so they could never fire. Annotate _pageindex_cause for the py.typed package. Claude-Session: https://claude.ai/code/session_01CfYSeq8kM7HjfF79TGbsiT * fix: fail fast on the cloud's account-limit tool errors; one 5xx list RATE_LIMITED / USAGE_LIMIT_REACHED (pageindex-chat #472) arrive as a normal tool error inside HTTP 200, already retried server-side; the invoker re-raises them as 429 / 402, the way a post-retry status escapes, so every lane fails fast without a per-lane change. The bridge retries the whole 5xx range, the same range the invoker re-raises; a non-JSON 200 body (a JSONDecodeError is a RequestException too) stays a model-visible envelope, since the server was reached. The MCP stub tests keep the machine's proxy out of 127.0.0.1. Claude-Session: https://claude.ai/code/session_01F7vqmZdnWeKC9SUBytDrdf * fix: raise the account-limit escape outside the invoker's own try _raise_account_limit fired inside _invoke's try, so its escape depended on 429 and 402 also appearing in the except's re-raise tuple: two lists in one function that had to agree. The check now runs after the try, where the except cannot swallow it, and 402 leaves the tuple (the MCP route never answers HTTP 402; it was there only to let the raise through). The mcp_stub fixture also sets the lowercase no_proxy: requests reads that spelling first, so a machine with no_proxy set still routed the stub requests through its proxy despite NO_PROXY.
15 lines
297 B
Plaintext
15 lines
297 B
Plaintext
litellm==1.97.0
|
|
openai>=1.70.0
|
|
requests>=2.28.0
|
|
# MCP retries use Retry(allowed_methods=...), added in urllib3 1.26.
|
|
urllib3>=1.26
|
|
openai-agents>=0.18.1
|
|
mcp>=1.19.0,<3
|
|
# pymupdf # optional
|
|
PyPDF2==3.0.1
|
|
pypdfium2==5.13.0
|
|
python-dotenv==1.2.2
|
|
pyyaml==6.0.2
|
|
regex>=2024.0.0
|
|
sortedcontainers==2.4.0
|