mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-15 04:12:25 +00:00
Modal backend stubs
This commit is contained in:
parent
7130fa50cb
commit
ea7aa0b0d4
7 changed files with 383 additions and 56 deletions
73
atropos/backends/modal_backend.py
Normal file
73
atropos/backends/modal_backend.py
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
"""
|
||||
Modal tool backend (stub).
|
||||
|
||||
We intentionally ship a placeholder implementation so AgentEnv can expose a
|
||||
backend switch without forcing Modal as a hard dependency for Hermes-Agent.
|
||||
|
||||
When org access is available, this backend will be implemented by running a
|
||||
long-lived Modal worker (or pool) that owns N slots and exposes `execute_batch`.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, Dict, List, Optional, Tuple
|
||||
|
||||
from ..slots.executor import ExecutionResult
|
||||
from ..slots.slot import Slot
|
||||
from .base import ToolBackend
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class ModalBackendConfig:
|
||||
# Placeholders for future implementation.
|
||||
app_name: str = "atropos-sandbox"
|
||||
function_name: str = "sandbox_server"
|
||||
volume_name: Optional[str] = None
|
||||
volume_mount_path: str = "/data"
|
||||
|
||||
@classmethod
|
||||
def from_agent_env_config(cls, cfg: Any) -> "ModalBackendConfig":
|
||||
return cls(
|
||||
app_name=str(getattr(cfg, "modal_app_name", cls.app_name)),
|
||||
function_name=str(getattr(cfg, "modal_function_name", cls.function_name)),
|
||||
volume_name=(getattr(cfg, "modal_volume_name", None) or None),
|
||||
volume_mount_path=str(getattr(cfg, "modal_volume_mount_path", cls.volume_mount_path)),
|
||||
)
|
||||
|
||||
|
||||
class ModalToolBackend(ToolBackend):
|
||||
def __init__(self, config: ModalBackendConfig):
|
||||
self.config = config
|
||||
|
||||
@property
|
||||
def default_timeout_s(self) -> Optional[float]:
|
||||
return None
|
||||
|
||||
def _unavailable(self) -> RuntimeError:
|
||||
return RuntimeError(
|
||||
"Modal tool backend is not implemented yet. "
|
||||
"Keep `--env.tool_pool_mode nomad` for now."
|
||||
)
|
||||
|
||||
async def start(self) -> None:
|
||||
raise self._unavailable()
|
||||
|
||||
async def stop(self, *, purge: bool = False) -> None: # noqa: ARG002
|
||||
# If start() isn't implemented, stop() is also unavailable.
|
||||
raise self._unavailable()
|
||||
|
||||
async def acquire(self, trajectory_id: Optional[str] = None) -> Slot: # noqa: ARG002
|
||||
raise self._unavailable()
|
||||
|
||||
async def release(self, slot: Slot, *, reset_workspace: bool = False) -> None: # noqa: ARG002
|
||||
raise self._unavailable()
|
||||
|
||||
async def execute_batch(
|
||||
self,
|
||||
requests: List[Tuple[Slot, str, Dict[str, Any]]],
|
||||
*,
|
||||
timeout_s: Optional[float] = None, # noqa: ARG002
|
||||
) -> List[ExecutionResult]:
|
||||
raise self._unavailable()
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue