Files
microsoft--agent-lightning/agentlightning/runner/base.py
T
wehub-resource-sync 85742ab165
Deploy Documentation / deploy (push) Has been cancelled
CPU Test / Test (Utilities, legacy, Python 3.10) (push) Has been cancelled
CPU Test / Test (LLM proxy, stable, Python 3.11) (push) Has been cancelled
CPU Test / Test (Others, stable, Python 3.11) (push) Has been cancelled
CPU Test / Test (Store, stable, Python 3.11) (push) Has been cancelled
CPU Test / Test (Utilities, stable, Python 3.11) (push) Has been cancelled
CPU Test / Test (Weave, stable, Python 3.11) (push) Has been cancelled
CPU Test / Test (AgentOps, stable, Python 3.12) (push) Has been cancelled
CPU Test / Test (LLM proxy, stable, Python 3.12) (push) Has been cancelled
CPU Test / Test (Others, stable, Python 3.12) (push) Has been cancelled
CPU Test / Test (Weave, latest, Python 3.13) (push) Has been cancelled
Dashboard / Chromatic (push) Has been cancelled
CPU Test / Lint - fast (push) Has been cancelled
CPU Test / Lint - next (push) Has been cancelled
CPU Test / Lint - slow (push) Has been cancelled
CPU Test / Lint - JavaScript (push) Has been cancelled
CPU Test / Build documentation (push) Has been cancelled
CPU Test / Test (AgentOps, legacy, Python 3.10) (push) Has been cancelled
CPU Test / Test (LLM proxy, legacy, Python 3.10) (push) Has been cancelled
CPU Test / Test (Others, legacy, Python 3.10) (push) Has been cancelled
CPU Test / Test (Store, legacy, Python 3.10) (push) Has been cancelled
CPU Test / Test (Weave, legacy, Python 3.10) (push) Has been cancelled
CPU Test / Test (AgentOps, stable, Python 3.11) (push) Has been cancelled
CPU Test / Test (Store, stable, Python 3.12) (push) Has been cancelled
CPU Test / Test (Utilities, stable, Python 3.12) (push) Has been cancelled
CPU Test / Test (Weave, stable, Python 3.12) (push) Has been cancelled
CPU Test / Test (AgentOps, latest, Python 3.13) (push) Has been cancelled
CPU Test / Test (LLM proxy, latest, Python 3.13) (push) Has been cancelled
CPU Test / Test (Others, latest, Python 3.13) (push) Has been cancelled
CPU Test / Test (Store, latest, Python 3.13) (push) Has been cancelled
CPU Test / Test (Utilities, latest, Python 3.13) (push) Has been cancelled
CPU Test / Test (JavaScript) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:44:17 +08:00

183 lines
6.7 KiB
Python

# Copyright (c) Microsoft. All rights reserved.
"""Abstract runner interface for executing agent tasks."""
from __future__ import annotations
import logging
from contextlib import contextmanager
from typing import TYPE_CHECKING, Any, Generic, Iterator, Optional, Sequence, TypeVar
from agentlightning.execution.events import ExecutionEvent
from agentlightning.litagent import LitAgent
from agentlightning.store.base import LightningStore
from agentlightning.types import Hook, NamedResources, ParallelWorkerBase, Rollout, RolloutMode
if TYPE_CHECKING:
from agentlightning.execution.events import ExecutionEvent
T_task = TypeVar("T_task")
logger = logging.getLogger(__name__)
class Runner(ParallelWorkerBase, Generic[T_task]):
"""Abstract base class for long-running agent executors.
Runner implementations coordinate [`LitAgent`][agentlightning.LitAgent]
instances, acquire work from a [`LightningStore`][agentlightning.LightningStore],
and emit [`Rollout`][agentlightning.Rollout] objects. Subclasses decide how
to schedule work (polling, streaming, etc.) while this base class provides a
minimal lifecycle contract.
"""
def init(self, agent: LitAgent[T_task], **kwargs: Any) -> None:
"""Prepare the runner to execute tasks for `agent`.
This method is called only once during the setup for all workers, not for each worker.
Args:
agent: Agent instance providing task-specific logic.
**kwargs: Optional runner-specific configuration.
Raises:
NotImplementedError: Subclasses must supply the initialization
routine.
"""
raise NotImplementedError()
def init_worker(self, worker_id: int, store: LightningStore, **kwargs: Any) -> None:
"""Configure worker-local state before processing tasks.
This method is called for **each** worker during the setup.
Args:
worker_id: Unique identifier for this worker process or thread.
store: Shared [`LightningStore`][agentlightning.LightningStore]
backing task coordination.
**kwargs: Optional worker-specific configuration.
Raises:
NotImplementedError: Subclasses must prepare per-worker resources.
"""
raise NotImplementedError()
def run(self, *args: Any, **kwargs: Any) -> None:
"""Deprecated synchronous entry point.
Use [`iter()`][agentlightning.Runner.iter] or [`step()`][agentlightning.Runner.step] instead.
Raises:
RuntimeError: Always raised to direct callers to
[iter()][agentlightning.Runner.iter] or
[step()][agentlightning.Runner.step].
"""
raise RuntimeError("The behavior of run() of Runner is undefined. Use iter() or step() instead.")
def teardown(self, *args: Any, **kwargs: Any) -> None:
"""Release resources acquired during [`init()`][agentlightning.Runner.init].
Raises:
NotImplementedError: Subclasses must implement the shutdown routine.
"""
raise NotImplementedError()
def teardown_worker(self, worker_id: int, *args: Any, **kwargs: Any) -> None:
"""Release per-worker resources allocated by [`init_worker()`][agentlightning.Runner.init_worker].
Args:
worker_id: Identifier of the worker being torn down.
Raises:
NotImplementedError: Subclasses must implement the shutdown routine.
"""
raise NotImplementedError()
@contextmanager
def run_context(
self,
*,
agent: LitAgent[T_task],
store: LightningStore,
hooks: Optional[Sequence[Hook]] = None,
worker_id: Optional[int] = None,
) -> Iterator[Runner[T_task]]:
"""Initialize and tear down a runner within a simple context manager.
The helper is primarily intended for debugging runner implementations
outside of a full [`Trainer`][agentlightning.Trainer] stack.
Args:
agent: Agent executed by this runner.
store: Backing [`LightningStore`][agentlightning.LightningStore].
If you don't have one, you can easily create one with
[`InMemoryLightningStore`][agentlightning.InMemoryLightningStore].
hooks: Optional sequence of hooks recognised by the runner.
Not all runners support hooks.
worker_id: Override the worker identifier used during setup. Defaults
to `0`.
"""
_initialized: bool = False
_worker_initialized: bool = False
try:
self.init(agent=agent, hooks=hooks)
_initialized = True
self.init_worker(worker_id=0, store=store)
_worker_initialized = True
yield self
finally:
try:
if _worker_initialized:
self.teardown_worker(worker_id=worker_id if worker_id is not None else 0)
except Exception:
logger.error("Error during runner worker teardown", exc_info=True)
try:
if _initialized:
self.teardown()
except Exception:
logger.error("Error during runner teardown", exc_info=True)
async def iter(self, *, event: Optional[ExecutionEvent] = None) -> None:
"""Run the runner, continuously iterating over tasks in the store.
This method runs in a loop, polling the store for new tasks and executing
them until interrupted by the event or when no more tasks are available.
Args:
event: Cooperative stop signal. When set, the runner should complete
the current unit of work and exit the loop.
Raises:
NotImplementedError: Subclasses provide the iteration behavior.
"""
raise NotImplementedError()
async def step(
self,
input: T_task,
*,
resources: Optional[NamedResources] = None,
mode: Optional[RolloutMode] = None,
event: Optional[ExecutionEvent] = None,
) -> Rollout:
"""Execute a single task with the given input.
This method provides fine-grained control for executing individual tasks
directly, bypassing the store's task queue.
Args:
input: Task payload consumed by the agent.
resources: Optional named resources scoped to this invocation.
mode: Optional rollout mode such as `"train"` or `"eval"`.
event: Cooperative stop signal for long-running tasks.
Returns:
Completed rollout produced by the agent.
Raises:
NotImplementedError: Subclasses provide the execution behavior.
"""
raise NotImplementedError()