agent-runloop 0.2.0__tar.gz → 0.2.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {agent_runloop-0.2.0 → agent_runloop-0.2.1}/PKG-INFO +1 -1
- {agent_runloop-0.2.0 → agent_runloop-0.2.1}/agent_loop/__init__.py +3 -3
- {agent_runloop-0.2.0 → agent_runloop-0.2.1}/agent_loop/loop.py +13 -1
- {agent_runloop-0.2.0 → agent_runloop-0.2.1}/pyproject.toml +1 -1
- {agent_runloop-0.2.0 → agent_runloop-0.2.1}/.gitignore +0 -0
- {agent_runloop-0.2.0 → agent_runloop-0.2.1}/LICENSE +0 -0
- {agent_runloop-0.2.0 → agent_runloop-0.2.1}/README.md +0 -0
- {agent_runloop-0.2.0 → agent_runloop-0.2.1}/agent_loop/_trace.py +0 -0
- {agent_runloop-0.2.0 → agent_runloop-0.2.1}/agent_loop/backend.py +0 -0
- {agent_runloop-0.2.0 → agent_runloop-0.2.1}/agent_loop/compose.py +0 -0
- {agent_runloop-0.2.0 → agent_runloop-0.2.1}/agent_loop/hooks.py +0 -0
- {agent_runloop-0.2.0 → agent_runloop-0.2.1}/agent_loop/ollama.py +0 -0
- {agent_runloop-0.2.0 → agent_runloop-0.2.1}/agent_loop/openai.py +0 -0
- {agent_runloop-0.2.0 → agent_runloop-0.2.1}/agent_loop/prompts.py +0 -0
- {agent_runloop-0.2.0 → agent_runloop-0.2.1}/agent_loop/py.typed +0 -0
- {agent_runloop-0.2.0 → agent_runloop-0.2.1}/agent_loop/runs.py +0 -0
- {agent_runloop-0.2.0 → agent_runloop-0.2.1}/agent_loop/usage.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: agent-runloop
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: Explicit, durable agent loop: validated tool calls, human approval, budgets, crash recovery, and composable router / waterfall / parallel / handoff / refine blocks.
|
|
5
5
|
Project-URL: Homepage, https://github.com/kroq86/agent-loop
|
|
6
6
|
Project-URL: Repository, https://github.com/kroq86/agent-loop
|
|
@@ -13,8 +13,8 @@ from agent_loop.compose import (
|
|
|
13
13
|
Sequence, Step, Timeout, Verdict, chain_task, join_answers, majority_vote, step,
|
|
14
14
|
)
|
|
15
15
|
from agent_loop.loop import (
|
|
16
|
-
AgentDecision, AgentResult, AgentStep, Budget, EventSink, FinalCheck, Status, ToolSpec,
|
|
17
|
-
current_call_id, recover_agent, resume_agent, run_agent, tool_error,
|
|
16
|
+
AgentDecision, AgentResult, AgentStep, Budget, EventSink, FinalCheck, Status, ToolSpec, ToolTimeout,
|
|
17
|
+
cancel_agent, current_call_id, recover_agent, resume_agent, run_agent, tool_error,
|
|
18
18
|
)
|
|
19
19
|
from agent_loop.runs import SqliteAgentRunStore
|
|
20
20
|
|
|
@@ -26,7 +26,7 @@ except PackageNotFoundError: # running from a source checkout
|
|
|
26
26
|
__all__ = [
|
|
27
27
|
"Agent", "AgentDecision", "AgentResult", "AgentStep", "Budget", "Context", "EventSink", "Fallback", "FinalCheck",
|
|
28
28
|
"Handoff", "HandoffNote", "LLMBackend", "LLMClassifier", "LLMCritic", "Outcome", "Parallel", "Refine", "Router",
|
|
29
|
-
"Sequence", "SqliteAgentRunStore", "Status", "Step", "Timeout", "ToolSpec", "Verdict", "cancel_agent",
|
|
29
|
+
"Sequence", "SqliteAgentRunStore", "Status", "Step", "Timeout", "ToolSpec", "ToolTimeout", "Verdict", "cancel_agent",
|
|
30
30
|
"chain_task", "current_call_id", "hooks", "join_answers", "majority_vote", "recover_agent", "resume_agent",
|
|
31
31
|
"run_agent", "step", "tool_error", "usage",
|
|
32
32
|
]
|
|
@@ -244,12 +244,24 @@ def tool_error(code: str, message: str) -> str:
|
|
|
244
244
|
return json.dumps({"error": {"code": code, "message": message}})
|
|
245
245
|
|
|
246
246
|
|
|
247
|
+
class ToolTimeout(Exception):
|
|
248
|
+
"""A tool exceeded its own `timeout_s`. Deliberately not a TimeoutError:
|
|
249
|
+
that one means the RUN's deadline, which ends the run. A slow tool is a
|
|
250
|
+
tool failure the model sees and can work around."""
|
|
251
|
+
|
|
252
|
+
|
|
247
253
|
@trace
|
|
248
254
|
async def execute_tool(spec: ToolSpec, args: BaseModel, trace_id: str) -> Any:
|
|
249
255
|
"""Separate traced node so trace.html shows each tool's validated
|
|
250
256
|
arguments and full result, under the run_agent node."""
|
|
251
257
|
trace.meta(tool=spec.name, arguments=args.model_dump(), tool_version=spec.version)
|
|
252
|
-
|
|
258
|
+
try:
|
|
259
|
+
return await asyncio.wait_for(spec.handler(args, trace_id), timeout=spec.timeout_s)
|
|
260
|
+
except TimeoutError:
|
|
261
|
+
# Only the tool's own timeout lands here: when the run's deadline
|
|
262
|
+
# fires, the wait is cancelled instead, and that surfaces as the
|
|
263
|
+
# run's TimeoutError one level up.
|
|
264
|
+
raise ToolTimeout(f"{spec.name} did not finish within its timeout of {spec.timeout_s}s") from None
|
|
253
265
|
|
|
254
266
|
|
|
255
267
|
async def _execute(state: "_RunState", spec: ToolSpec, args: BaseModel, canonical: dict,
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "agent-runloop"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.1"
|
|
8
8
|
description = "Explicit, durable agent loop: validated tool calls, human approval, budgets, crash recovery, and composable router / waterfall / parallel / handoff / refine blocks."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|