Default chat-only providers to Chat Completions
Route Nebius, Z.AI, Z.AI Coding, and Gemini API OAuth directly through Chat Completions. Avoid unsupported /responses probes and keep provider defaults aligned with documented upstream capabilities.
Alessandro committed
Jul 31, 2026 at 18:17 UTC
0c663403a3cc7fc7256b0954b36180ae33dae693
5 files changed
+84
-1
conf/AGENTS.md
+1
@@ -16,6 +16,7 @@
16
- Do not commit API keys, provider secrets, local account identifiers, or private endpoints.
17
- Keep provider IDs and settings keys stable unless all loaders, UI references, migrations, and tests are updated.
18
- Defaults must work in a clean checkout and in Docker.
19
+- Providers without a native Responses path in the supported LiteLLM runtime, or intentionally standardized on Chat Completions, must set `a0_api_mode: chat`; native Responses providers rely on the Responses default.
20
- Templates must avoid accidentally unignoring private runtime content.
21
22
## Work Guidance
conf/model_providers.yaml
+29
@@ -32,6 +32,7 @@ chat:
32
models_list:
33
endpoint_url: "https://api.venice.ai/api/v1/models"
34
kwargs:
35
+ a0_api_mode: chat
36
api_base: https://llm.agent-zero.ai/v1
37
venice_parameters:
38
include_venice_system_prompt: false
@@ -42,6 +43,8 @@ chat:
43
endpoint_url: "https://api.anthropic.com/v1/models"
44
params:
45
limit: "1000"
46
+ kwargs:
47
+ a0_api_mode: chat
48
cerebras:
49
name: Cerebras
50
litellm_provider: cerebras
@@ -55,11 +58,15 @@ chat:
58
litellm_provider: cometapi
59
models_list:
60
endpoint_url: "https://api.cometapi.com/v1/models"
61
+ kwargs:
62
+ a0_api_mode: chat
63
deepseek:
64
name: DeepSeek
65
litellm_provider: deepseek
66
models_list:
67
endpoint_url: "https://api.deepseek.com/models"
68
+ kwargs:
69
+ a0_api_mode: chat
70
github_copilot:
71
name: GitHub Copilot
72
litellm_provider: github_copilot
@@ -77,14 +84,20 @@ chat:
84
params:
85
pageSize: "1000"
86
default_base: "https://generativelanguage.googleapis.com"
87
+ kwargs:
88
+ a0_api_mode: chat
89
groq:
90
name: Groq
91
litellm_provider: groq
92
models_list:
93
endpoint_url: "https://api.groq.com/openai/v1/models"
94
+ kwargs:
95
+ a0_api_mode: chat
96
huggingface:
97
name: HuggingFace
98
litellm_provider: huggingface
99
+ kwargs:
100
+ a0_api_mode: chat
101
lm_studio:
102
name: LM Studio
103
litellm_provider: lm_studio
@@ -110,23 +123,30 @@ chat:
123
litellm_provider: mistral
124
models_list:
125
endpoint_url: "https://api.mistral.ai/v1/models"
126
+ kwargs:
127
+ a0_api_mode: chat
128
moonshot:
129
name: Moonshot AI
130
litellm_provider: moonshot
131
models_list:
132
endpoint_url: "https://api.moonshot.cn/v1/models"
133
+ kwargs:
134
+ a0_api_mode: chat
135
nebius:
136
name: Nebius Token Factory
137
litellm_provider: openai
138
models_list:
139
endpoint_url: "/models"
140
kwargs:
141
+ a0_api_mode: chat
142
api_base: https://api.tokenfactory.nebius.com/v1
143
nvidia_nim:
144
name: NVIDIA NIM
145
litellm_provider: nvidia_nim
146
models_list:
147
endpoint_url: "https://integrate.api.nvidia.com/v1/models"
148
+ kwargs:
149
+ a0_api_mode: chat
150
ollama:
151
name: Ollama
152
litellm_provider: ollama
@@ -170,12 +190,15 @@ chat:
190
bedrock:
191
name: AWS Bedrock
192
litellm_provider: bedrock
193
+ kwargs:
194
+ a0_api_mode: chat
195
openrouter:
196
name: OpenRouter
197
litellm_provider: openrouter
198
models_list:
199
endpoint_url: "https://openrouter.ai/api/v1/models"
200
kwargs:
201
+ a0_api_mode: chat
202
extra_headers:
203
"HTTP-Referer": "https://agent-zero.ai/"
204
"X-Title": "Agent Zero"
@@ -185,6 +208,8 @@ chat:
208
litellm_provider: sambanova
209
models_list:
210
endpoint_url: "https://api.sambanova.ai/v1/models"
211
+ kwargs:
212
+ a0_api_mode: chat
213
venice:
214
name: Venice.ai
215
litellm_provider: openai
@@ -210,12 +235,15 @@ chat:
235
litellm_provider: xai
236
models_list:
237
endpoint_url: "https://api.x.ai/v1/models"
238
+ kwargs:
239
+ a0_api_mode: chat
240
zai:
241
name: Z.AI
242
litellm_provider: openai
243
models_list:
244
endpoint_url: "/models"
245
kwargs:
246
+ a0_api_mode: chat
247
api_base: https://api.z.ai/api/paas/v4
248
zai_coding:
249
name: Z.AI Coding
@@ -223,6 +251,7 @@ chat:
251
models_list:
252
endpoint_url: "/models"
253
kwargs:
254
+ a0_api_mode: chat
255
api_base: https://api.z.ai/api/coding/paas/v4
256
other:
257
name: Other OpenAI compatible
plugins/_oauth/AGENTS.md
+1
@@ -46,6 +46,7 @@
46
- Codex Responses proxy requests must include Codex client metadata and compatibility headers such as `client_metadata`, `x-codex-installation-id`, `originator`, `session-id`, and `thread-id`, and must forward `input` as a list for upstream Codex compatibility.
47
- Codex Responses proxy requests must translate the legacy top-level `reasoning_effort` field to `reasoning.effort`; an explicit native `reasoning` field takes precedence.
48
- Codex Responses proxy defaults for reasoning effort, reasoning summary, and text verbosity come from the `codex` plugin config; explicit native request values take precedence.
49
+- OAuth providers without upstream Responses support must set `a0_api_mode: chat`; native Responses providers rely on the default, since a local proxy route alone does not prove upstream support.
50
51
## Work Guidance
52
plugins/_oauth/conf/model_providers.yaml
+1
@@ -22,6 +22,7 @@ chat:
22
models_list:
23
endpoint_url: "/models"
24
kwargs:
25
+ a0_api_mode: chat
26
api_base: "http://127.0.0.1/oauth/gemini-api/v1"
27
xai_grok_oauth:
28
name: xAI Grok Account
tests/test_model_config_api_keys.py
+52
-1
@@ -356,7 +356,7 @@ def test_direct_venice_chat_provider_defaults_to_chat_completions(monkeypatch):
356
assert venice["kwargs"]["venice_parameters"] == {
357
"include_venice_system_prompt": False
358
}
359
- assert "a0_api_mode" not in provider_config["chat"]["a0_venice"]["kwargs"]
359
+ assert provider_config["chat"]["a0_venice"]["kwargs"]["a0_api_mode"] == "chat"
360
assert "a0_api_mode" not in provider_config["embedding"]["venice"]["kwargs"]
361
362
model = models.get_chat_model("venice", "llama-3.3-70b")
@@ -485,6 +485,57 @@ def test_local_chat_providers_default_to_chat_completions():
485
assert "a0_api_mode" not in provider_config["embedding"][provider]["kwargs"]
486
487
488
+def test_provider_api_mode_defaults_use_intended_transport():
489
+ import yaml
490
+
491
+ provider_config = yaml.safe_load(
492
+ (PROJECT_ROOT / "conf" / "model_providers.yaml").read_text(encoding="utf-8")
493
+ )
494
+ oauth_provider_config = yaml.safe_load(
495
+ (
496
+ PROJECT_ROOT
497
+ / "plugins"
498
+ / "_oauth"
499
+ / "conf"
500
+ / "model_providers.yaml"
501
+ ).read_text(encoding="utf-8")
502
+ )
503
+
504
+ chat_providers = (
505
+ "anthropic",
506
+ "cometapi",
507
+ "deepseek",
508
+ "google",
509
+ "groq",
510
+ "huggingface",
511
+ "mistral",
512
+ "moonshot",
513
+ "nebius",
514
+ "nvidia_nim",
515
+ "bedrock",
516
+ "openrouter",
517
+ "sambanova",
518
+ "xai",
519
+ "zai",
520
+ "zai_coding",
521
+ )
522
+ responses_providers = ("azure", "github_copilot", "openai")
523
+
524
+ for provider in chat_providers:
525
+ assert provider_config["chat"][provider]["kwargs"]["a0_api_mode"] == "chat"
526
+
527
+ for provider in responses_providers:
528
+ assert "a0_api_mode" not in provider_config["chat"][provider].get("kwargs", {})
529
+
530
+ assert (
531
+ oauth_provider_config["chat"]["gemini_api_oauth"]["kwargs"]["a0_api_mode"]
532
+ == "chat"
533
+ )
534
+
535
+ for provider in ("codex_oauth", "github_copilot_oauth", "xai_grok_oauth"):
536
+ assert "a0_api_mode" not in oauth_provider_config["chat"][provider]["kwargs"]
537
+
538
+
539
def test_missing_api_key_banner_does_not_include_auto_modal_metadata(monkeypatch):
540
from plugins._model_config.helpers import model_config
541