0.4.11
10 · Техническая документация

10. Провайдеры моделей

AstraCode умеет работать с разными LLM-провайдерами через единый интерфейс ModelProvider. Конфигурация — в [[providers]] секциях config.toml. API-ключи хранятся отдельно — в зашифрованном ~/.astracode/secrets/local.age (см. 09-security.md).

1. Конфигурация провайдера

toml
default_provider = "local-vllm"

[[providers]]
id           = "local-vllm"
display_name = "Local vLLM"
base_url     = "http://127.0.0.1:8000/v1"

[[providers]]
id           = "openrouter"
display_name = "OpenRouter"
base_url     = "https://openrouter.ai/api/v1"

[[providers]]
id           = "provider-glm"
display_name = "Zhipu GLM"
base_url     = "https://api.z.ai/api/coding/paas/v4"

Поля [[providers]] (структура ProviderEntry, config/src/providers_toml.rs): - id — стабильный slug, ключ для default_provider / [ui_state].last_used_provider и для имени секрета (см. provider_secret_name). - display_name — что показывать в /model. - base_url — корневой URL API; должен оканчиваться на /v1, чтобы bridge мог дописать /chat/completions и /models. - model_override (опц.) — жёстко задаёт поле model в запросе upstream, независимо от того, что отправил AstraCode. Полезно, когда id модели в AstraCode не совпадает с --served-model-name бэкенда. - extra_body (опц.) — доп. поля, мерджатся (last-write-wins) в тело chat-completions-запроса. Используется для vLLM/SGLang-кнопок вроде top_k, min_p, chat_template_kwargs. - strip_strict (опц., bool) — убирает "strict": true из function-tool-схем перед отправкой. Требуется некоторым chat-completions-бэкендам (Z.AI / GLM). - forward_reasoning_summaries (опц., bool) — форвардить upstream reasoning_content как Responses reasoning-summary events. Опционально, т.к. некоторые локальные бэкенды отдают raw chain-of-thought в этом нестандартном поле.

Важно: [[providers]] — это «плоский» массив, пришедший на смену legacy-схеме [model_providers.X] + [profiles.X]. Старая model_providers map пока ещё парсится параллельно (см. config/src/config_toml.rs), но для новых конфигов рекомендуется [[providers]]. deny_unknown_fields включён — неизвестные поля (api_format, auth_method и т.п.) вызовут ошибку парсинга.

2. Wire-протокол

AstraCode всегда говорит с провайдером на Responses API (WireApi::Responses). Другие wire-протоколы (chat) удалены — попытка указать их в [model_providers.X].wire_api приводит к ошибке десериализации CHAT_WIRE_API_REMOVED_ERROR (model-provider-info/src/lib.rs).

Чтобы работать с бэкендами, понимающими только Chat Completions (vLLM, SGLang, llama.cpp, MiniMax, …), запросы маршрутизируются через in-process мост — см. §11. Это прозрачно для пользователя: в конфиге указывается обычный base_url OpenAI-compatible бэкенда, а мост транслирует Responses ↔ Chat Completions.

Поддерживаемые OpenAI-compatible бэкенды (через мост): OpenAI, Azure OpenAI, vLLM, llama.cpp server, Ollama (с правильным --openai-compat), Together, Anyscale, Fireworks, Groq, OpenRouter, любой self-hosted endpoint, локальный AstraCode-server (on-prem).

3. Установка API-ключа

API-ключи не хранятся в config.toml. Они шифруются в ~/.astracode/secrets/local.age и привязываются к id провайдера через provider_secret_name (secrets/src/lib.rs).

Через TUI:

text
/model
→ выбрать провайдера
→ ввести API-ключ (вводится скрыто)
→ ключ шифруется и пишется в ~/.astracode/secrets/local.age

Через CLI (скрытая подкоманда; ключ читается из stdin):

bash
echo "sk-..." | astracode provider-secret set openai
astracode provider-secret status openai      # проверить, что ключ есть
astracode provider-secret delete openai      # удалить ключ
astracode provider-secret probe openai       # проверить /models endpoint
astracode provider-secret probe-capabilities openai   # проверить chat-возможности модели

Ранее документация упоминала astracode auth set --provider ... --key ... — такой команды нет. Используйте astracode provider-secret set <PROVIDER_ID> (чтение ключа из stdin).

4. Альтернативная аутентификация

Помимо API-ключа в secrets-хранилище, ModelProviderInfo поддерживает (для legacy [model_providers.X]): - env_key — имя env-переменной с ключом. - experimental_bearer_token — прямой bearer-токен (не рекомендуется). - auth — command-backed bearer-token: запускает внешнюю команду, которая возвращает токен (ModelProviderAuthInfo: command, args, timeout_ms, refresh_interval_ms, cwd). Удобно для OIDC/Keycloak-флоу. - aws — AWS SigV4 для Bedrock (ModelProviderAwsAuthInfo: profile, region). Требует крейт aws-auth. Поле aws несовместимо с env_key/experimental_bearer_token/auth/requires_openai_auth.

5. Выбор модели

toml
model = "gpt-5"
model_provider = "openai"

В TUI:

text
/model

Каталог моделей берётся из model-provider-info (захардкоженный список + дозагрузка из API провайдера, если поддерживается).

models-manager кэширует список моделей.

6. On-prem / self-hosted

Локальный AstraCode-server

Если организация поднимает свой proxy-сервер (например, для централизованного биллинга и ACL):

toml
[[providers]]
id = "company-llm"
display_name = "Company LLM Gateway"
base_url = "https://llm-gateway.company.internal/v1"

default_provider = "company-llm"

Если у gateway self-signed CA:

bash
export ASTRACODE_CA_CERTIFICATE=/etc/ssl/certs/company-ca.pem
astracode

vLLM / llama.cpp

toml
[[providers]]
id = "local-llama"
display_name = "Local llama.cpp"
base_url = "http://localhost:8080/v1"

Ключ можно поставить любой (или пустой):

bash
echo "dummy" | astracode provider-secret set local-llama

Ollama

toml
[[providers]]
id = "ollama"
display_name = "Ollama"
base_url = "http://localhost:11434/v1"

7. Параметры запроса

toml
model = "gpt-5"
model_context_window = 200000
model_auto_compact_token_limit = 180000
model_reasoning_effort = "high"
plan_mode_reasoning_effort = "high"
model_verbosity = "medium"
  • model_context_window — учитывается для UI-индикатора заполнения.
  • model_auto_compact_token_limit — порог автоматического предложения /compact.
  • model_reasoning_effort — для моделей с extended thinking (o1, GPT-5 reasoning).
  • model_verbosity — для GPT-5 (low/medium/high).

Per-provider таймауты и ретраи задаются в legacy [model_providers.X] (ModelProviderInfo): - request_max_retries — макс. число ретраев HTTP-запроса. - stream_max_retries — число ретраев переподключения оборванного стрима. - stream_idle_timeout_ms — idle-таймаут стрима (мс).

8. Несколько провайдеров одновременно

Можно держать в config несколько [[providers]] и переключаться через /model:

toml
default_provider = "openai"

[[providers]]
id = "openai"
base_url = "https://api.openai.com/v1"

[[providers]]
id = "anthropic"
base_url = "https://api.anthropic.com/v1"

[[providers]]
id = "local"
base_url = "http://localhost:8000/v1"

AstraCode запомнит последний выбор в [ui_state]:

toml
[ui_state]
last_used_provider = "anthropic"
last_used_model = "claude-sonnet-4-6"

9. Прокси и сеть

Прокси-настройки для исходящих HTTP-запросов читаются из стандартных env-переменных (network-proxy/src/proxy.rs):

bash
HTTP_PROXY="http://proxy.company.com:3128"
HTTPS_PROXY="http://proxy.company.com:3128"
NO_PROXY="localhost,127.0.0.1"

Сетевая политика sandbox настраивается в профиле разрешений ([permissions.<name>.network], структура NetworkToml):

toml
[permissions.default.network]
enabled = true
proxy_url = "http://proxy.company.com:3128"
enable_socks5 = false
mode = "limited"          # limited | full
allow_local_binding = false

Поля NetworkToml (config/src/permissions_toml.rs): enabled, proxy_url, enable_socks5, socks_url, enable_socks5_udp, allow_upstream_proxy, dangerously_allow_non_loopback_proxy, dangerously_allow_all_unix_sockets, mode (limited/full), domains, unix_sockets, allow_local_binding. Подробнее о сетевой sandbox — 09-security.md.

10. Стриминг

AstraCode использует SSE (Server-Sent Events) для стриминга ответов модели: - Каждая дельта текста ассистента — OutputTextDelta. - Tool-вызовы — OutputItemAdded / OutputItemDoneToolCallInputDelta для инкрементального ввода аргументов). - Размышления (extended thinking) — ReasoningContentDeltaReasoningSummaryPartAdded).

Если провайдер не поддерживает стриминг — используется блокирующий запрос с буферизацией.

11. Chat Completions bridge (bridge + responses-api-proxy)

Клиент AstraCode всегда говорит на Responses API. Чтобы работать с бэкендами, понимающими только Chat Completions (vLLM, SGLang, llama.cpp, MiniMax, …), запросы маршрутизируются через in-process мост:

  • Крейт bridge (bridge/src/lib.rs) владеет отображением provider → bridge-target и loopback-embedding. embed поднимает loopback-listener, регистрирует его base URL глобально через model_provider_info::set_bridge_loopback_url, так что каждый to_api_provider (даже после перезагрузки Config с диска) идёт через мост. Когда провайдеров не настроено, мост держит синтетический placeholder-target с заведомо недостижимым URL (port 0 на 127.0.0.1), чтобы любой чат падал громко, а не утекал к vendor-дефолту.
  • Крейт responses-api-proxy транслирует Responses API ↔ Chat Completions, обрабатывает SSE и per-provider routing.
  • Маршрутизация провайдера субагента идёт через заголовок x-astracode-provider-id (core/src/client.rs); target разрешается в responses-api-proxy/src/bridge/state.rs, а карта всех [[providers]] собирается в bridge/src/lib.rs.

responses-api-proxy можно запустить и как отдельный локальный сервер, превращающий любой OpenAI-compatible API в Responses API — для моделей, которые ещё не поддержали Responses, но AstraCode хочет использовать его фичи (server-side conversation state).

bash
astracode-responses-api-proxy --upstream-url https://api.openai.com/v1 --port 7100

В config:

toml
[[providers]]
id = "openai-via-proxy"
base_url = "http://localhost:7100/v1"

12. Отладка запросов

bash
RUST_LOG=astracode_model_provider=debug astracode

Покажет request/response логи модуля model-provider (с маскированием API-ключей).

13. Файлы кода

  • Trait ModelProvider: model-provider/src/lib.rs
  • Каталог моделей: model-provider-info/src/lib.rs
  • Менеджер: models-manager/src/lib.rs
  • HTTP API: api/src/
  • ProviderEntry (плоские [[providers]]): config/src/providers_toml.rs
  • ModelProviderInfo / WireApi: model-provider-info/src/lib.rs
  • Auth-типы (ModelProviderAuthInfo, ModelProviderAwsAuthInfo): protocol/src/config_types.rs, model-provider-info/src/lib.rs
  • Responses-API-мост: bridge/, responses-api-proxy/
  • Секреты: secrets/src/lib.rs