Source code for jeevesagent.architecture.resolver
"""Resolve architecture specs (string or instance) to a concrete
:class:`Architecture` instance.
In v0.3, only ``"react"`` is shipped as a known string. The resolver
also accepts any object that satisfies the :class:`Architecture`
protocol — most user-facing flows just pass an instance like
``ReAct(max_turns=20)`` directly.
Future: entry-point discovery so third-party packages can register
custom architectures via ``[project.entry-points."jeevesagent.architecture"]``
and be referenced by string from user code without imports.
"""
from __future__ import annotations
from ..core.errors import ConfigError
from .base import Architecture
from .plan_and_execute import PlanAndExecute
from .react import ReAct
from .reflexion import Reflexion
from .rewoo import ReWOO
from .self_refine import SelfRefine
from .tree_of_thoughts import TreeOfThoughts
KNOWN: dict[str, type[Architecture]] = {
"plan-and-execute": PlanAndExecute,
"react": ReAct,
"reflexion": Reflexion,
"rewoo": ReWOO,
"self-refine": SelfRefine,
"tree-of-thoughts": TreeOfThoughts,
}
[docs]
def resolve_architecture(spec: Architecture | str | None) -> Architecture:
"""Coerce ``spec`` to a concrete :class:`Architecture`.
* ``None`` → :class:`ReAct` (the default)
* ``str`` → looked up in :data:`KNOWN` (only ``"react"`` in v0.3)
* Architecture instance → returned as-is
Unknown strings raise :class:`ConfigError` with a list of known
names.
"""
if spec is None:
return ReAct()
if isinstance(spec, str):
cls = KNOWN.get(spec)
if cls is None:
known = ", ".join(sorted(KNOWN))
raise ConfigError(
f"unknown architecture: {spec!r}. Known: {known}. "
"Pass an Architecture instance directly for custom strategies."
)
return cls()
return spec