Skip to content

symfonic.agent.facade_model

facade_model

Reading the simple facade's model argument.

Split out of :mod:symfonic.agent.facade so the facade module keeps to the 300-line budget, and because this is a rule rather than plumbing: what the argument may be, and what it may deliberately not be.

FAC-4 rejects the provider alias -- Agent("anthropic:claude-…") -- because resolving a name to a provider is a registry, and a registry imports provider SDKs and consults credential chains at construction, which QUI-2 and QUI-3 forbid. Naming the model that an already-chosen provider should serve is none of those things: no lookup, no import, no credential, and the provider is still the caller's own object. The two are different questions and only the first one is closed.

as_model_config

as_model_config(model: str | ModelConfig | None) -> ModelConfig | None

Normalise the constructor's model argument.

None keeps the established meaning -- ask the provider -- rather than substituting a framework default, which is the rule FAC-5 already states for instructions. A string is read as the model's name and nothing else; it is never resolved against a provider registry.

Source code in src/symfonic/agent/facade_model.py
def as_model_config(model: str | ModelConfig | None) -> ModelConfig | None:
    """Normalise the constructor's ``model`` argument.

    ``None`` keeps the established meaning -- ask the provider -- rather than
    substituting a framework default, which is the rule FAC-5 already states
    for ``instructions``. A string is read as the model's name and nothing
    else; it is never resolved against a provider registry.
    """
    if model is None or isinstance(model, ModelConfig):
        return model
    if isinstance(model, str):
        if not model.strip():
            raise ConfigurationError(
                "model must be a non-empty model name, a ModelConfig, or None; "
                "got an empty string."
            )
        return ModelConfig(model_name=model)
    raise ConfigurationError(
        f"model must be a model name (str), a ModelConfig, or None; got "
        f"{type(model).__name__}. A provider alias such as "
        '"anthropic:claude-sonnet-4-5" is deliberately not accepted (FAC-4): '
        "choose the provider yourself and name the model it should serve."
    )