Source code for ralph.agents.builtin_spec

"""Single declarative source for the 7 built-in agent declarations.

The :class:`BuiltinAgentSpec` dataclass mirrors the kwargs accepted by
:func:`ralph.agents.registration.register_agent_support` and the legacy
:class:`AgentSupport.from_registration_kwargs` so the 7 built-in entries
in :mod:`ralph.agents.builtin` can be expressed as a single declarative
row per agent, instead of repeating the kwargs across seven function calls.

Use :meth:`BuiltinAgentSpec.to_support` to materialize the dataclass into
an :class:`AgentSupport` instance.  The resulting ``is_builtin`` flag is
always ``True`` so the catalog can treat these entries as reserved.
"""

from __future__ import annotations

import dataclasses
from dataclasses import dataclass
from typing import TYPE_CHECKING, cast

from ralph.agents.support import AgentSupport
from ralph.config.enums import AgentTransport, JsonParserType

if TYPE_CHECKING:
    from collections.abc import Callable

    from ralph.agents._contracts import StrategyFactory
    from ralph.agents.parsers.base import AgentParser


# Fields that are NOT forwarded to ``AgentSupport.from_registration_kwargs``
# via **kwargs because they are passed as positional / named arguments by
# :meth:`BuiltinAgentSpec.to_support`.  Kept as a frozenset so the surface
# is explicit and future built-in agent additions do not silently break
# the 7-entry frozen contract pinned by
# ``test_agents/test_builtin_spec_consolidation.py``.
_BUILTIN_SPEC_POSITIONAL_FIELDS: frozenset[str] = frozenset(
    {"transport", "parser_factory", "strategy_factory"}
)


[docs] @dataclass(frozen=True, slots=True) class BuiltinAgentSpec: """Declarative description of one built-in agent. Attributes: transport: Transport enum value. parser_factory: Callable returning a parser instance. strategy_factory: Callable returning an execution strategy instance. json_parser: Parser type token. cmd: Executable command; defaults to ``name`` on materialization. output_flag: Optional output format flag. yolo_flag: Optional autonomous flag string. verbose_flag: Optional verbose flag string. can_commit: Whether the agent can run git commit. model_flag: Optional model/provider flag. print_flag: Optional print flag. streaming_flag: Optional streaming flag. session_flag: Optional session continuation flag template. display_name: Human-readable display name. interactive: Whether the agent is interactive (PTY). subagent_capability: Whether the agent exposes usable sub-agent tooling. no_default_session_flag: When True, suppress the default ``--resume {}`` session template that would otherwise be set by :meth:`AgentSupport.from_registration_kwargs` for interactive agents. Used for agy. """ transport: AgentTransport parser_factory: Callable[[], AgentParser] strategy_factory: StrategyFactory json_parser: JsonParserType = JsonParserType.GENERIC cmd: str | None = None output_flag: str | None = None yolo_flag: str | None = None verbose_flag: str | None = None can_commit: bool = False model_flag: str | None = None print_flag: str | None = None streaming_flag: str | None = None session_flag: str | None = None display_name: str | None = None interactive: bool = False subagent_capability: bool | None = None no_default_session_flag: bool = False
[docs] def to_support(self, name: str) -> AgentSupport: """Materialize the dataclass into an :class:`AgentSupport`. Forwards every dataclass field as a keyword argument to :meth:`AgentSupport.from_registration_kwargs` so future BuiltinAgentSpec additions do not require updating two parallel kwarg lists. ``is_builtin=True`` is always set. Args: name: Agent name to assign to the resulting support. Returns: The materialized :class:`AgentSupport` with ``is_builtin=True``. """ asdict_result: dict[str, object] = cast( "dict[str, object]", dataclasses.asdict(self), ) kwargs: dict[str, object] = { field: value for field, value in asdict_result.items() if field not in _BUILTIN_SPEC_POSITIONAL_FIELDS } return AgentSupport.from_registration_kwargs( name, transport=self.transport, parser_factory=self.parser_factory, strategy_factory=self.strategy_factory, is_builtin=True, **kwargs, # type: ignore[arg-type] # reason: autogenerated code has no type support, see docs/agents/type-ignore-policy.md#autogenerated-code )