Download src/daemon/swarm.py from Snapkitty/sovereign-engine-v2: direct link, hf CLI and curl.
- Browser
- Download file 13.1 kB
-
https://huggingface.co/Snapkitty/sovereign-engine-v2/resolve/main/src/daemon/swarm.py
- Command line
-
hf download hf://Snapkitty/sovereign-engine-v2/src/daemon/swarm.py
-
curl -L -o swarm.py https://huggingface.co/Snapkitty/sovereign-engine-v2/resolve/main/src/daemon/swarm.py
13.1 kB
| """ | |
| Sovereign LLM Engine — Parallel Swarm Coordinator | |
| Part of SOVEREIGN PYTHON LLM ENGINE | |
| Coordinates N concurrent async agent tasks using asyncio primitives. | |
| Supports fan_out, map_reduce, and race patterns with configurable | |
| concurrency limits, per-task timeouts, and result aggregation. | |
| """ | |
| from __future__ import annotations | |
| import asyncio | |
| import logging | |
| import time | |
| from dataclasses import dataclass, field | |
| from typing import Any, Callable, Coroutine, TypeVar | |
| logger = logging.getLogger("sovereign.swarm") | |
| T = TypeVar("T") | |
| R = TypeVar("R") | |
| # Type aliases for readability | |
| AgentCallable = Callable[..., Coroutine[Any, Any, Any]] | |
| Mapper = Callable[[Any], Coroutine[Any, Any, Any]] | |
| Reducer = Callable[[list[Any]], Coroutine[Any, Any, Any]] | |
| # ========================================== | |
| # Result Types | |
| # ========================================== | |
| class TaskOutcome: | |
| """Outcome of a single task within a swarm operation.""" | |
| index: int | |
| success: bool | |
| value: Any = None | |
| error: str | None = None | |
| latency_ms: float = 0.0 | |
| class SwarmResult: | |
| """ | |
| Aggregated result from a swarm operation. | |
| Attributes: | |
| results: Successful results in order of completion (or index for fan_out). | |
| failures: Failed task outcomes. | |
| latency_ms: Wall-clock time for the entire swarm operation. | |
| winner: For race() operations — the first successful result value. | |
| """ | |
| results: list[Any] | |
| failures: list[TaskOutcome] | |
| latency_ms: float | |
| winner: Any | None = None | |
| def success_count(self) -> int: | |
| return len(self.results) | |
| def failure_count(self) -> int: | |
| return len(self.failures) | |
| def total_count(self) -> int: | |
| return self.success_count + self.failure_count | |
| def all_succeeded(self) -> bool: | |
| return self.failure_count == 0 | |
| def __repr__(self) -> str: | |
| return ( | |
| f"SwarmResult(success={self.success_count}, " | |
| f"failures={self.failure_count}, " | |
| f"latency_ms={self.latency_ms:.1f})" | |
| ) | |
| # ========================================== | |
| # Internal helpers | |
| # ========================================== | |
| async def _run_with_timeout( | |
| coro: Coroutine[Any, Any, T], | |
| timeout: float | None, | |
| index: int, | |
| semaphore: asyncio.Semaphore, | |
| ) -> TaskOutcome: | |
| """ | |
| Run a coroutine under a semaphore and optional timeout. | |
| Returns a TaskOutcome regardless of success or failure. | |
| """ | |
| start = time.monotonic() | |
| async with semaphore: | |
| try: | |
| if timeout is not None: | |
| value = await asyncio.wait_for(coro, timeout=timeout) | |
| else: | |
| value = await coro | |
| latency = (time.monotonic() - start) * 1000.0 | |
| return TaskOutcome(index=index, success=True, value=value, latency_ms=latency) | |
| except asyncio.TimeoutError: | |
| latency = (time.monotonic() - start) * 1000.0 | |
| return TaskOutcome( | |
| index=index, | |
| success=False, | |
| error=f"Task {index} timed out after {timeout}s", | |
| latency_ms=latency, | |
| ) | |
| except Exception as exc: | |
| latency = (time.monotonic() - start) * 1000.0 | |
| return TaskOutcome( | |
| index=index, | |
| success=False, | |
| error=f"{type(exc).__name__}: {exc}", | |
| latency_ms=latency, | |
| ) | |
| # ========================================== | |
| # Swarm | |
| # ========================================== | |
| class Swarm: | |
| """ | |
| Parallel swarm coordinator. | |
| All operations respect a global concurrency limit (semaphore) and an | |
| optional per-task timeout. Tasks that exceed the timeout are recorded | |
| as failures rather than raising exceptions. | |
| Args: | |
| concurrency: Maximum number of tasks running simultaneously. | |
| task_timeout: Per-task timeout in seconds (None = unlimited). | |
| """ | |
| def __init__( | |
| self, | |
| concurrency: int = 16, | |
| task_timeout: float | None = 60.0, | |
| ) -> None: | |
| if concurrency < 1: | |
| raise ValueError("concurrency must be >= 1") | |
| self._concurrency = concurrency | |
| self._task_timeout = task_timeout | |
| # ------------------------------------------------------------------ | |
| # fan_out | |
| # ------------------------------------------------------------------ | |
| async def fan_out( | |
| self, | |
| task: Any, | |
| agents: list[AgentCallable], | |
| ) -> SwarmResult: | |
| """ | |
| Dispatch the same task to every agent concurrently. | |
| Each agent in `agents` is called as ``agent(task)``. | |
| Results are returned in the same order as the agent list. | |
| Failures do not block other agents. | |
| Returns: | |
| SwarmResult with results indexed to match agent positions. | |
| """ | |
| if not agents: | |
| return SwarmResult(results=[], failures=[], latency_ms=0.0) | |
| semaphore = asyncio.Semaphore(self._concurrency) | |
| wall_start = time.monotonic() | |
| coros = [ | |
| _run_with_timeout(agent(task), self._task_timeout, idx, semaphore) | |
| for idx, agent in enumerate(agents) | |
| ] | |
| outcomes: list[TaskOutcome] = await asyncio.gather(*coros) | |
| wall_ms = (time.monotonic() - wall_start) * 1000.0 | |
| # Preserve original index order for results | |
| ordered_results: list[Any] = [None] * len(agents) | |
| failures: list[TaskOutcome] = [] | |
| for outcome in outcomes: | |
| if outcome.success: | |
| ordered_results[outcome.index] = outcome.value | |
| else: | |
| failures.append(outcome) | |
| logger.warning( | |
| "fan_out agent[%d] failed: %s", outcome.index, outcome.error | |
| ) | |
| # Remove None slots for failed agents so callers get a clean list | |
| success_results = [ | |
| ordered_results[i] | |
| for i in range(len(agents)) | |
| if outcomes[i].success | |
| ] | |
| return SwarmResult( | |
| results=success_results, | |
| failures=failures, | |
| latency_ms=wall_ms, | |
| ) | |
| # ------------------------------------------------------------------ | |
| # map_reduce | |
| # ------------------------------------------------------------------ | |
| async def map_reduce( | |
| self, | |
| items: list[Any], | |
| mapper: Mapper, | |
| reducer: Reducer, | |
| ) -> SwarmResult: | |
| """ | |
| Map items through an async mapper concurrently, then reduce. | |
| Each item in `items` is passed to ``mapper(item)`` concurrently. | |
| Successful mapped values are collected and passed to ``reducer(values)``. | |
| The reducer result is the single entry in SwarmResult.results. | |
| Failures in individual map tasks are recorded; the reducer only | |
| receives successfully mapped values. If all maps fail, the reducer | |
| is not called and SwarmResult.results is empty. | |
| Returns: | |
| SwarmResult where results[0] is the reducer output (if any map succeeded). | |
| """ | |
| if not items: | |
| reduced = await reducer([]) | |
| return SwarmResult(results=[reduced], failures=[], latency_ms=0.0) | |
| semaphore = asyncio.Semaphore(self._concurrency) | |
| wall_start = time.monotonic() | |
| map_coros = [ | |
| _run_with_timeout(mapper(item), self._task_timeout, idx, semaphore) | |
| for idx, item in enumerate(items) | |
| ] | |
| map_outcomes: list[TaskOutcome] = await asyncio.gather(*map_coros) | |
| mapped_values: list[Any] = [] | |
| failures: list[TaskOutcome] = [] | |
| for outcome in map_outcomes: | |
| if outcome.success: | |
| mapped_values.append(outcome.value) | |
| else: | |
| failures.append(outcome) | |
| logger.warning( | |
| "map_reduce mapper[%d] failed: %s", outcome.index, outcome.error | |
| ) | |
| results: list[Any] = [] | |
| if mapped_values: | |
| try: | |
| reduced_value = await reducer(mapped_values) | |
| results = [reduced_value] | |
| except Exception as exc: | |
| logger.exception("map_reduce reducer failed: %s", exc) | |
| failures.append( | |
| TaskOutcome( | |
| index=-1, | |
| success=False, | |
| error=f"Reducer {type(exc).__name__}: {exc}", | |
| ) | |
| ) | |
| wall_ms = (time.monotonic() - wall_start) * 1000.0 | |
| return SwarmResult(results=results, failures=failures, latency_ms=wall_ms) | |
| # ------------------------------------------------------------------ | |
| # race | |
| # ------------------------------------------------------------------ | |
| async def race( | |
| self, | |
| tasks: list[Coroutine[Any, Any, Any]], | |
| ) -> SwarmResult: | |
| """ | |
| Run tasks concurrently and return the first successful result. | |
| All remaining tasks are cancelled once a winner is found. | |
| If all tasks fail, SwarmResult.winner is None and all failures | |
| are recorded. | |
| Returns: | |
| SwarmResult with winner set to the first successful value. | |
| results contains only the winning value (or empty if all failed). | |
| """ | |
| if not tasks: | |
| return SwarmResult(results=[], failures=[], latency_ms=0.0, winner=None) | |
| semaphore = asyncio.Semaphore(self._concurrency) | |
| wall_start = time.monotonic() | |
| # Wrap each coroutine in a task | |
| loop = asyncio.get_running_loop() | |
| pending: set[asyncio.Task[TaskOutcome]] = set() | |
| for idx, coro in enumerate(tasks): | |
| t = loop.create_task( | |
| _run_with_timeout(coro, self._task_timeout, idx, semaphore) | |
| ) | |
| pending.add(t) | |
| winner: Any | None = None | |
| winner_found = False | |
| failures: list[TaskOutcome] = [] | |
| while pending: | |
| done, pending = await asyncio.wait( | |
| pending, return_when=asyncio.FIRST_COMPLETED | |
| ) | |
| for finished in done: | |
| outcome: TaskOutcome = finished.result() | |
| if outcome.success and not winner_found: | |
| winner = outcome.value | |
| winner_found = True | |
| logger.debug( | |
| "race winner: task[%d] in %.1fms", | |
| outcome.index, | |
| outcome.latency_ms, | |
| ) | |
| # Cancel remaining tasks | |
| for remaining in pending: | |
| remaining.cancel() | |
| # Drain cancelled tasks | |
| if pending: | |
| await asyncio.gather(*pending, return_exceptions=True) | |
| pending = set() | |
| break | |
| elif not outcome.success: | |
| failures.append(outcome) | |
| wall_ms = (time.monotonic() - wall_start) * 1000.0 | |
| if winner_found: | |
| return SwarmResult( | |
| results=[winner], | |
| failures=failures, | |
| latency_ms=wall_ms, | |
| winner=winner, | |
| ) | |
| else: | |
| return SwarmResult( | |
| results=[], | |
| failures=failures, | |
| latency_ms=wall_ms, | |
| winner=None, | |
| ) | |
| # ------------------------------------------------------------------ | |
| # Batch helper | |
| # ------------------------------------------------------------------ | |
| async def batch( | |
| self, | |
| coros: list[Coroutine[Any, Any, Any]], | |
| ) -> SwarmResult: | |
| """ | |
| Run an arbitrary list of coroutines concurrently with the swarm | |
| concurrency and timeout settings. Results are in completion order. | |
| This is a lower-level primitive used internally; fan_out and | |
| map_reduce are preferred for agent patterns. | |
| """ | |
| if not coros: | |
| return SwarmResult(results=[], failures=[], latency_ms=0.0) | |
| semaphore = asyncio.Semaphore(self._concurrency) | |
| wall_start = time.monotonic() | |
| wrapped = [ | |
| _run_with_timeout(coro, self._task_timeout, idx, semaphore) | |
| for idx, coro in enumerate(coros) | |
| ] | |
| outcomes: list[TaskOutcome] = await asyncio.gather(*wrapped) | |
| results = [o.value for o in outcomes if o.success] | |
| failures = [o for o in outcomes if not o.success] | |
| wall_ms = (time.monotonic() - wall_start) * 1000.0 | |
| return SwarmResult(results=results, failures=failures, latency_ms=wall_ms) | |