diff --git a/env.example b/env.example index a5d5c70..0b5b164 100644 --- a/env.example +++ b/env.example @@ -7,6 +7,8 @@ # Republic model format: provider:model_id # Default in code is `openrouter:qwen/qwen3-coder-next`. # BUB_MODEL=openrouter:qwen/qwen3-coder-next +# API transport: `completion`, `responses`, or `messages`. +# BUB_API_FORMAT=completion # BUB_MAX_STEPS=50 # BUB_MAX_TOKENS=1024 # BUB_MODEL_TIMEOUT_SECONDS=300 diff --git a/src/bub/builtin/agent.py b/src/bub/builtin/agent.py index 79c8f6d..db47942 100644 --- a/src/bub/builtin/agent.py +++ b/src/bub/builtin/agent.py @@ -226,6 +226,7 @@ def _build_llm(settings: AgentSettings, tape_store: AsyncTapeStore) -> LLM: settings.model, api_key=settings.api_key, api_base=settings.api_base, + api_format=settings.api_format, api_key_resolver=api_key_resolver, tape_store=tape_store, context=default_tape_context(), diff --git a/src/bub/builtin/settings.py b/src/bub/builtin/settings.py index 7accc94..12c609a 100644 --- a/src/bub/builtin/settings.py +++ b/src/bub/builtin/settings.py @@ -1,4 +1,5 @@ import pathlib +from typing import Literal from pydantic import Field from pydantic_settings import BaseSettings, SettingsConfigDict @@ -18,6 +19,7 @@ class AgentSettings(BaseSettings): model: str = DEFAULT_MODEL api_key: str | None = None api_base: str | None = None + api_format: Literal["completion", "responses", "messages"] = "completion" max_steps: int = 50 max_tokens: int = DEFAULT_MAX_TOKENS model_timeout_seconds: int | None = None diff --git a/tests/test_builtin_settings.py b/tests/test_builtin_settings.py new file mode 100644 index 0000000..e3f2b46 --- /dev/null +++ b/tests/test_builtin_settings.py @@ -0,0 +1,11 @@ +from __future__ import annotations + +from bub.builtin.settings import AgentSettings + + +def test_agent_settings_reads_api_format_from_env(monkeypatch) -> None: + monkeypatch.setenv("BUB_API_FORMAT", "responses") + + settings = AgentSettings() + + assert settings.api_format == "responses"