Model options
model_options
¶
Aggregate and namespace ACP model selectors for the host proxy.
The proxy hides multiple in-container agents behind a single ACP
endpoint by namespacing each agent's model ids as agent:model.
Three operations live here, layered on top of the ACP SDK's pydantic
models:
build_aggregated_session_new— the pre-bindsession/newreply that advertises the union of every authenticated agent's models under one selector.build_model_option— theconfigOptions[category=model]entry that mirrors the aggregate selector for clients that read it instead ofmodels.namespace_model_options_in_place— the post-bind rewrite that puts theagent:prefix back on the bare model ids a bound backend emits in its own config options.
Plus the small vocabulary helpers (split_namespaced,
humanise_model_id)
that callers across the proxy share.
MODEL_OPTION_CATEGORY = 'model'
module-attribute
¶
ACP semantic category for the model selector configOption.
Used as both the category and the id field of the
acp.schema.SessionConfigOptionSelect we
build — keeping them in sync prevents drift between the discriminator
the proxy emits and the one downstream code matches on.
MODEL_NAMESPACE_SEP = ':'
module-attribute
¶
Separator between agent and model in the namespaced id (e.g.
claude:opus-4.6). Chosen over / to avoid collisions with
OpenRouter-style ids like anthropic/claude-opus-4.
build_aggregated_session_new(session_id, models)
¶
Build the pre-bind session/new reply for models.
Empty models yields a schema-valid response with no models or
configOptions block — both have non-nullable required fields the
proxy can't fill in for an empty list, and modelling "no models" as
an empty selector trips client validation.
Source code in src/terok_executor/acp/model_options.py
build_model_option(namespaced_models, *, current)
¶
Build a category: "model" select option with namespaced ids.
Source code in src/terok_executor/acp/model_options.py
namespace_model_options_in_place(config_options, bound_agent)
¶
Prefix bare model ids in config_options with bound_agent:.
Used on every backend → client frame that carries
configOptions[*] post-bind (ConfigOptionUpdate notification,
SetSessionConfigOptionResponse). Already-namespaced values are
left alone so the function is idempotent — paths the proxy itself
constructed (e.g. ack of a model pick) round-trip cleanly.
Source code in src/terok_executor/acp/model_options.py
split_namespaced(namespaced)
¶
Split agent:model into (agent, model).
Empty halves signal a malformed id — callers that need to validate
do so by checking both halves. Centralises the partition so the
proxy's bind/lookup paths stop spelling
.partition(MODEL_NAMESPACE_SEP) themselves.
Source code in src/terok_executor/acp/model_options.py
humanise_model_id(namespaced)
¶
Render claude:opus-4.6 as Claude: opus-4.6 for the picker.
Colon matches the wire-level MODEL_NAMESPACE_SEP
so an OpenCode-style opencode:opencode/big-pickle reads as one
provider plus one slash-bearing model id. Forwards verbatim if the
input isn't a namespaced pair.