agent-health-timeout
Skill0 starsChanged 6 months agoMITView on GitHub
Implements timeout wrappers and a circuit breaker pattern for agent runs. Use when protecting services from slow or failing agent calls, adding deadline enforcement via asyncio.wait_for, or implementing automatic circuit breaking to stop calling a degraded agent.
In this repository65 other files it gives its agents.
- AGENTS.mdAGENTS.md
- skills/building-agents/agents.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- llms-full.txtllms.txt
- llms.txtllms.txt
- adding-guardrailsSkill
- agent-permission-scopingSkill
- agent-session-isolationSkill
- agent-step-loggingSkill
- agent-supervisor-routerSkill
- agent-telemetrySkill
- async-agent-backgroundSkill
- building-agentsSkill
- building-teamsSkill
- building-toolsSkill
- calendar-scheduling-toolSkill
- callback-tracing-handlerSkill
- chain-of-thought-promptingSkill
- chat-model-configurationSkill
- code-execution-sandboxSkill
- common-agent-patternsSkill
- context-window-managementSkill
- conversation-memorySkill
- conversation-state-dbSkill
- database-query-toolSkill
- document-loadersSkill
- document-rerankingSkill
- email-notification-toolSkill
- embedding-model-ingestionSkill
- fallback-model-chainSkill
- few-shot-injectionSkill
- filesystem-toolSkill
- human-in-the-loopSkill
- hybrid-searchSkill
- inspecting-streamsSkill
- integrating-with-laurenSkill
- json-schema-enforcementSkill
- llm-provider-connectionSkill
- llm-rate-limitingSkill
- long-term-vector-memorySkill
- managing-memorySkill
- migrating-to-lauren-aiSkill
- multi-agent-delegationSkill
- multi-tool-orchestrationSkill
- multi-turn-tool-stateSkill
- output-guardrailsSkill
- plan-and-execute-agentSkill
- prompt-injection-defenseSkill
- prompt-versioningSkill
- rag-pipelineSkill
- react-agent-loopSkill
- response-validation-retrySkill
- rest-api-toolSkill
- securing-agentsSkill
- semantic-cacheSkill
- streaming-response-handlerSkill
- structured-output-parsingSkill
- sub-agent-spawningSkill
- system-prompt-templatingSkill
- testing-agentsSkill
- The first 60 shown.
The file
Files
Use
codemap find "SymbolName"to locate any symbol before reading — it gives exact file + line range and is faster than grep across the whole repo.
Agent Health Check & Timeout Handling
Overview
Two utilities are provided:
run_with_timeout— wrapsAgentRunnerBase.run()withasyncio.wait_forand mapsTimeoutErrorto a structured error dict.CircuitBreaker— tracks consecutive failures and opens the circuit afterfailure_thresholdfailures, preventing calls duringreset_timeout.
Timeout wrapper
# resilience/timeout.py
import asyncio
from lauren_ai._agents._runner import AgentRunnerBase as AgentRunner
async def run_with_timeout(
runner: AgentRunner,
agent_instance,
prompt: str,
timeout: float = 30.0,
) -> dict:
try:
response = await asyncio.wait_for(
runner.run(agent_instance, prompt),
timeout=timeout,
)
return {
"status": "ok",
"content": response.content,
"turns": response.turns,
}
except asyncio.TimeoutError:
return {"status": "timeout", "error": f"Agent timed out after {timeout}s"}
except Exception as e:
return {"status": "error", "error": str(e)}Circuit breaker
# resilience/circuit_breaker.py
import time
class CircuitBreaker:
"""Three-state circuit breaker: closed → open → half-open."""
def __init__(self, failure_threshold: int = 3, reset_timeout: float = 60.0):
self._failures = 0
self._threshold = failure_threshold
self._reset_timeout = reset_timeout
self._state = "closed" # closed | open | half-open
self._last_failure = 0.0
def record_failure(self) -> None:
self._failures += 1
self._last_failure = time.monotonic()
if self._failures >= self._threshold:
self._state = "open"
def record_success(self) -> None:
self._failures = 0
self._state = "closed"
def can_call(self) -> bool:
if self._state == "closed":
return True
if self._state == "open":
elapsed = time.monotonic() - self._last_failure
if elapsed > self._reset_timeout:
self._state = "half-open"
return True
return False
return True # half-open: allow one probe call
@property
def state(self) -> str:
return self._stateCombined usage
async def resilient_run(runner, agent, prompt, *, cb: CircuitBreaker) -> dict:
if not cb.can_call():
return {"status": "circuit_open", "error": "Agent circuit is open"}
result = await run_with_timeout(runner, agent, prompt, timeout=30.0)
if result["status"] == "ok":
cb.record_success()
else:
cb.record_failure()
return resultLauren controller health endpoint
# controllers/health.py
from lauren import controller, get
from lauren_ai import AgentRunner
@controller("/health")
class HealthController:
def __init__(self, runner: AgentRunner) -> None:
self._runner = runner
@get("/agent")
async def agent_health(self) -> dict:
# Quick ping — one-turn, low max_tokens
result = await run_with_timeout(self._runner, PingAgent(), "ping", timeout=5.0)
return {"status": result["status"]}Reference files
| File | Contents |
src/lauren_ai/_agents/_runner.py | AgentRunnerBase.run() |
src/lauren_ai/_exceptions.py | AgentMaxTurnsError, AgentBudgetExceededError |
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

