simbiot-harness/venv/lib/python3.12/site-packages/strands/vended_tools/sleep/sleep.py
Simbiot Harness b60439152b Simbiot Harness v0.1: тактовая лестница на Strands + CQRS/ES-спина
- 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 первым)
2026-09-29 15:28:50 +00:00

90 lines
3.7 KiB
Python

"""Sleep tool: pause execution for a bounded, cooperative duration.
Provides :func:`make_sleep` (a factory that lets the caller configure the
maximum permitted duration) and :data:`sleep` (a default instance with a 60-second
cap). Sleeps are implemented with :func:`asyncio.sleep`, which unblocks
immediately when the surrounding task is cancelled. When the tool is invoked
through the standard :class:`DecoratedFunctionTool` path, the raised
:class:`asyncio.CancelledError` is caught by the tool executor and surfaced as
a tool-error result; direct callers awaiting the underlying coroutine observe
the cancellation directly.
"""
from __future__ import annotations
import asyncio
import math
from typing import TYPE_CHECKING
from ...tools.decorator import tool
from .types import DEFAULT_MAX_DURATION, sleep_description
if TYPE_CHECKING:
from ...tools.decorator import DecoratedFunctionTool
def make_sleep(
*,
max_duration: float = DEFAULT_MAX_DURATION,
name: str = "sleep",
description: str | None = None,
) -> DecoratedFunctionTool:
"""Create a sleep tool with a configurable maximum duration.
The returned tool pauses execution for ``duration`` seconds via
:func:`asyncio.sleep`. Cancelling the surrounding task unblocks the sleep
immediately rather than waiting for the full duration; the resulting
:class:`asyncio.CancelledError` is caught by the standard tool executor
when the tool is invoked through :class:`DecoratedFunctionTool` and
surfaced as a tool-error result to the model.
Args:
max_duration: Upper bound on ``duration`` in seconds. Must be a finite,
positive number. Defaults to :data:`DEFAULT_MAX_DURATION` (60 s).
name: Tool name. Defaults to ``"sleep"``.
description: Tool description shown to the model.
Returns:
A decorated tool that pauses execution for the requested duration.
Raises:
ValueError: If ``max_duration`` is not a positive, finite number.
"""
if not isinstance(max_duration, (int, float)) or isinstance(max_duration, bool):
raise ValueError(f"max_duration must be a number, got {type(max_duration).__name__}")
if not math.isfinite(max_duration) or max_duration <= 0:
raise ValueError(f"max_duration must be positive and finite, got {max_duration!r}")
resolved_max = float(max_duration)
resolved_description = description if description is not None else sleep_description(resolved_max)
@tool(name=name, description=resolved_description)
async def sleep_tool(duration: float) -> str:
"""Pauses execution for the given number of seconds.
The sleep is cooperative: it uses :func:`asyncio.sleep` and aborts
immediately if the enclosing task is cancelled. Negative, non-finite,
non-numeric, or oversized durations are rejected before the sleep begins.
Args:
duration: Seconds to pause. Must be a finite, non-negative number
no larger than the tool's configured maximum.
"""
if isinstance(duration, bool) or not isinstance(duration, (int, float)):
raise ValueError(f"duration must be a number, got {type(duration).__name__}")
seconds = float(duration)
if not math.isfinite(seconds):
raise ValueError(f"duration must be a finite number, got {duration!r}")
if seconds < 0:
raise ValueError(f"duration must be non-negative, got {seconds}")
if seconds > resolved_max:
raise ValueError(f"duration {seconds} exceeds maximum of {resolved_max} seconds")
await asyncio.sleep(seconds)
return f"Slept for {duration} seconds"
return sleep_tool
sleep = make_sleep()
"""Default sleep tool with a 60-second maximum duration."""