- harness/es.py: append-only event store + проекции (образец — кооп-портал) - harness/levels.py: уровни 1с/1м/1ч/1д, контекст ∝ масштабу - harness/scheduler.py: уровневые потоки, идемпотентные тики, absorbed-стабы - harness/isolated_runner.py + _llm_worker.py: LLM-тик в сабпроцессе (глобальный asyncio-рантайм Strands не переживает 2+ create_harness) - cli.py: init/task/tasks/status/events + requeue (написан самим минутным агентом) - 9router: отдельный ключ sk-simbiot, модель auto (glm-5.3 первым)
71 lines
2.5 KiB
Python
71 lines
2.5 KiB
Python
"""Sequential tool executor implementation."""
|
|
|
|
from collections.abc import AsyncGenerator
|
|
from typing import TYPE_CHECKING, Any
|
|
|
|
from typing_extensions import override
|
|
|
|
from ...telemetry.metrics import Trace
|
|
from ...types._events import ToolInterruptEvent, ToolResultEvent, TypedEvent
|
|
from ...types.tools import ToolResult, ToolUse
|
|
from ._executor import ToolExecutor
|
|
|
|
if TYPE_CHECKING: # pragma: no cover
|
|
from ...agent import Agent
|
|
from ..structured_output._structured_output_context import StructuredOutputContext
|
|
|
|
|
|
class SequentialToolExecutor(ToolExecutor):
|
|
"""Sequential tool executor."""
|
|
|
|
@override
|
|
async def _execute(
|
|
self,
|
|
agent: "Agent",
|
|
tool_uses: list[ToolUse],
|
|
tool_results: list[ToolResult],
|
|
cycle_trace: Trace,
|
|
cycle_span: Any,
|
|
invocation_state: dict[str, Any],
|
|
structured_output_context: "StructuredOutputContext | None" = None,
|
|
) -> AsyncGenerator[TypedEvent, None]:
|
|
"""Execute tools sequentially.
|
|
|
|
Breaks early if an interrupt is raised by the user.
|
|
|
|
Args:
|
|
agent: The agent for which tools are being executed.
|
|
tool_uses: Metadata and inputs for the tools to be executed.
|
|
tool_results: List of tool results from each tool execution.
|
|
cycle_trace: Trace object for the current event loop cycle.
|
|
cycle_span: Span object for tracing the cycle.
|
|
invocation_state: Context for the tool invocation.
|
|
structured_output_context: Context for structured output handling.
|
|
|
|
Yields:
|
|
Events from the tool execution stream.
|
|
"""
|
|
interrupted = False
|
|
|
|
for tool_use in tool_uses:
|
|
if agent._observe_cancellation():
|
|
cancel_result: ToolResult = {
|
|
"toolUseId": str(tool_use.get("toolUseId")),
|
|
"status": "error",
|
|
"content": [{"text": "Tool execution cancelled"}],
|
|
}
|
|
tool_results.append(cancel_result)
|
|
yield ToolResultEvent(cancel_result)
|
|
continue
|
|
|
|
events = ToolExecutor._stream_with_trace(
|
|
agent, tool_use, tool_results, cycle_trace, cycle_span, invocation_state, structured_output_context
|
|
)
|
|
async for event in events:
|
|
if isinstance(event, ToolInterruptEvent):
|
|
interrupted = True
|
|
|
|
yield event
|
|
|
|
if interrupted:
|
|
break
|