Source code for ralph.agents.availability
"""Agent PATH availability checks for Ralph Workflow.
Shared helper used by both the first-run welcome banner and the
`ralph --diagnose` command to determine whether configured agents
are reachable on the system PATH.
"""
from __future__ import annotations
import shutil
from typing import Literal, Protocol, runtime_checkable
from .agent_entry import AgentEntry
AgentStatus = Literal["available", "missing_on_path", "no_cmd"]
__all__ = ["AgentEntry", "AgentStatus", "HasListAgents", "check_agent_availability"]
[docs]
@runtime_checkable
class HasListAgents(Protocol):
"""Protocol for agent registries used in availability checks."""
def list_agents(self) -> list[str]: ...
def get(self, name: str) -> AgentEntry | None: ...
[docs]
def check_agent_availability(
registry: HasListAgents,
) -> list[tuple[str, AgentStatus]]:
"""Check which agents are available on PATH.
Args:
registry: Object implementing list_agents() and get(name) for agent resolution.
Returns:
List of (registry_name, status) tuples where status is one of
'available', 'missing_on_path', or 'no_cmd'.
The key is always the configured registry name so callers can join
back to the registry without a secondary display-name lookup.
"""
results: list[tuple[str, AgentStatus]] = []
for name in registry.list_agents():
agent = registry.get(name)
if agent is None:
continue
cmd = agent.cmd
if not cmd:
results.append((name, "no_cmd"))
continue
first_word = cmd.split(maxsplit=1)[0]
status: AgentStatus = (
"available" if shutil.which(first_word) is not None else "missing_on_path"
)
results.append((name, status))
return results