What's broken
The agrinet_agent is configured with retries=3 in agents/agrinet.py, but the retry logic never fires for the failures that actually happen in production.
All four BAP-calling tools (weather, mandi, scheme, warehouse) import ModelRetry from pydantic_ai but only raise it for generic Exception. The specific transient failures (timeouts, non-200 status codes, connection errors) return plain strings instead. Since pydantic_ai treats a returned string as a successful tool result, the agent passes the error message straight to the LLM, which then just tells the farmer "service unavailable."
The returned string in some cases literally says "Retrying" but the code never actually retries.
Separately, agents/tools/search.py has no exception handling at all around the Marqo client call. A network blip or missing index raises an unhandled exception that crashes the entire agent request with a 500.
Where exactly
The pattern is identical across four files:
agents/tools/weather.py (lines 432-451)
agents/tools/mandi.py (lines 256-277)
agents/tools/scheme.py (lines 246-264)
agents/tools/warehouse.py (lines 318-336)
# What the code does now (same in all four files):
if response.status_code != 200:
return "Weather service unavailable. Retrying" # string, no retry happens
except requests.Timeout:
return "Weather request timed out." # string, no retry happens
except requests.RequestException as e:
return f"Weather request failed: {str(e)}" # string, no retry happens
except Exception as e:
raise ModelRetry(...) # only this one actually retries
And in agents/tools/search.py (line 91):
results = client.index(index_name).search(**search_params)['hits']
# no try/except, no ModelRetry import, nothing
Why this matters
The BAP endpoints (IMD weather, APMC mandi prices, govt scheme portal, warehouse lookup) are external government APIs. Transient 502s and timeouts are common. Right now, every time one of those APIs has a momentary hiccup, the farmer gets a dead-end "service unavailable" response even though the agent is configured to retry 3 times.
For the Marqo search tool, any network issue between the app container and Marqo crashes the full request with an unhandled exception instead of falling back to the LLM's general knowledge.
Proposed fix
For weather.py, mandi.py, scheme.py, warehouse.py:
Replace the string returns on transient failures with raise ModelRetry(...) so pydantic_ai's built-in retry logic actually kicks in:
if response.status_code != 200:
logger.error(f"Weather API returned status code {response.status_code}")
raise ModelRetry(f"Weather API returned {response.status_code}, retrying")
except requests.Timeout:
logger.error("Weather API request timed out")
raise ModelRetry("Weather API request timed out, retrying")
except requests.RequestException as e:
logger.error(f"Weather API request failed: {e}")
raise ModelRetry(f"Weather API request failed: {str(e)}")
Keep the UnexpectedModelBehavior catch as-is since that already handles the case where retries are exhausted.
For search.py:
Add ModelRetry to imports and wrap the Marqo call:
try:
results = client.index(index_name).search(**search_params)['hits']
except Exception as e:
logger.error(f"Marqo search failed: {e}")
raise ModelRetry(f"Search service error: {str(e)}")
Files changed
agents/tools/weather.py
agents/tools/mandi.py
agents/tools/scheme.py
agents/tools/warehouse.py
agents/tools/search.py
Would like to work on this.
What's broken
The
agrinet_agentis configured withretries=3inagents/agrinet.py, but the retry logic never fires for the failures that actually happen in production.All four BAP-calling tools (weather, mandi, scheme, warehouse) import
ModelRetryfrom pydantic_ai but only raise it for genericException. The specific transient failures (timeouts, non-200 status codes, connection errors) return plain strings instead. Since pydantic_ai treats a returned string as a successful tool result, the agent passes the error message straight to the LLM, which then just tells the farmer "service unavailable."The returned string in some cases literally says "Retrying" but the code never actually retries.
Separately,
agents/tools/search.pyhas no exception handling at all around the Marqo client call. A network blip or missing index raises an unhandled exception that crashes the entire agent request with a 500.Where exactly
The pattern is identical across four files:
agents/tools/weather.py (lines 432-451)
agents/tools/mandi.py (lines 256-277)
agents/tools/scheme.py (lines 246-264)
agents/tools/warehouse.py (lines 318-336)
And in agents/tools/search.py (line 91):
Why this matters
The BAP endpoints (IMD weather, APMC mandi prices, govt scheme portal, warehouse lookup) are external government APIs. Transient 502s and timeouts are common. Right now, every time one of those APIs has a momentary hiccup, the farmer gets a dead-end "service unavailable" response even though the agent is configured to retry 3 times.
For the Marqo search tool, any network issue between the app container and Marqo crashes the full request with an unhandled exception instead of falling back to the LLM's general knowledge.
Proposed fix
For weather.py, mandi.py, scheme.py, warehouse.py:
Replace the string returns on transient failures with
raise ModelRetry(...)so pydantic_ai's built-in retry logic actually kicks in:Keep the
UnexpectedModelBehaviorcatch as-is since that already handles the case where retries are exhausted.For search.py:
Add
ModelRetryto imports and wrap the Marqo call:Files changed
agents/tools/weather.pyagents/tools/mandi.pyagents/tools/scheme.pyagents/tools/warehouse.pyagents/tools/search.pyWould like to work on this.