@@ -14,6 +14,7 @@ def _base_urls() -> dict[str, str]:
1414 return {
1515 "anthropic" : f"{ WS } /ai-gateway/anthropic/v1" ,
1616 "gemini" : f"{ WS } /ai-gateway/gemini/v1beta" ,
17+ "openai" : f"{ WS } /ai-gateway/codex/v1" ,
1718 "oss" : f"{ WS } /ai-gateway/mlflow/v1" ,
1819 }
1920
@@ -211,6 +212,76 @@ def test_prefixes_oss_model_with_provider_id(self):
211212 assert overlay ["model" ] == "databricks-oss/system.ai.kimi-k2-7-code"
212213
213214
215+ class TestOpenAIProvider :
216+ """OpenCode reaches Databricks GPT-5 / GPT-5.6 / Codex models through the
217+ databricks-openai provider (@ai-sdk/openai against /ai-gateway/codex/v1).
218+ Without this wiring the codex/openai family is unreachable from OpenCode."""
219+
220+ def test_openai_provider_added_when_codex_models_present (self ):
221+ models = {"openai" : ["databricks-gpt-5-6-sol" ]}
222+ overlay , _ = opencode .render_overlay ("databricks-gpt-5-6-sol" , "tok" , _base_urls (), models )
223+ assert "databricks-openai" in overlay ["provider" ]
224+
225+ def test_openai_provider_uses_ai_sdk_openai_npm (self ):
226+ models = {"openai" : ["databricks-gpt-5-6-sol" ]}
227+ overlay , _ = opencode .render_overlay ("databricks-gpt-5-6-sol" , "tok" , _base_urls (), models )
228+ assert overlay ["provider" ]["databricks-openai" ]["npm" ] == "@ai-sdk/openai"
229+
230+ def test_openai_base_url_points_at_codex_gateway (self ):
231+ models = {"openai" : ["databricks-gpt-5-6-sol" ]}
232+ overlay , _ = opencode .render_overlay ("databricks-gpt-5-6-sol" , "tok" , _base_urls (), models )
233+ options = overlay ["provider" ]["databricks-openai" ]["options" ]
234+ assert options ["baseURL" ] == f"{ WS } /ai-gateway/codex/v1"
235+
236+ def test_use_responses_api_set_on_every_codex_model (self ):
237+ models = {"openai" : ["databricks-gpt-5-6-sol" , "databricks-gpt-codex" ]}
238+ overlay , _ = opencode .render_overlay ("databricks-gpt-5-6-sol" , "tok" , _base_urls (), models )
239+ provider_models = overlay ["provider" ]["databricks-openai" ]["models" ]
240+ for m in ("databricks-gpt-5-6-sol" , "databricks-gpt-codex" ):
241+ assert provider_models [m ]["options" ]["useResponsesApi" ] is True
242+
243+ def test_openai_authorization_header (self ):
244+ models = {"openai" : ["databricks-gpt-5-6-sol" ]}
245+ overlay , _ = opencode .render_overlay ("databricks-gpt-5-6-sol" , "tok" , _base_urls (), models )
246+ headers = overlay ["provider" ]["databricks-openai" ]["options" ]["headers" ]
247+ assert headers ["Authorization" ] == "Bearer tok"
248+
249+ def test_managed_keys_include_openai_provider (self ):
250+ models = {"openai" : ["databricks-gpt-5-6-sol" ]}
251+ _ , keys = opencode .render_overlay ("databricks-gpt-5-6-sol" , "tok" , _base_urls (), models )
252+ assert ["provider" , "databricks-openai" ] in keys
253+
254+ def test_prefixes_openai_model_with_provider_id (self ):
255+ models = {"openai" : ["databricks-gpt-5-6-sol" ]}
256+ overlay , _ = opencode .render_overlay ("databricks-gpt-5-6-sol" , "tok" , _base_urls (), models )
257+ assert overlay ["model" ] == "databricks-openai/databricks-gpt-5-6-sol"
258+
259+ def test_already_prefixed_openai_model_is_preserved (self ):
260+ models = {"openai" : ["databricks-gpt-5-6-sol" ]}
261+ overlay , _ = opencode .render_overlay (
262+ "databricks-openai/databricks-gpt-5-6-sol" , "tok" , _base_urls (), models
263+ )
264+ assert overlay ["model" ] == "databricks-openai/databricks-gpt-5-6-sol"
265+
266+ def test_all_four_providers_when_all_present (self ):
267+ models = {
268+ "anthropic" : ["claude-sonnet" ],
269+ "gemini" : ["gemini-2" ],
270+ "openai" : ["databricks-gpt-5-6-sol" ],
271+ "oss" : ["system.ai.kimi-k2-7-code" ],
272+ }
273+ overlay , _ = opencode .render_overlay ("claude-sonnet" , "tok" , _base_urls (), models )
274+ assert set (overlay ["provider" ].keys ()) == {
275+ "databricks-anthropic" ,
276+ "databricks-google" ,
277+ "databricks-openai" ,
278+ "databricks-oss" ,
279+ }
280+
281+ def test_provider_keys_listed_in_module (self ):
282+ assert ["provider" , "databricks-openai" ] in opencode .PROVIDER_KEYS
283+
284+
214285class TestMcpServerConfig :
215286 def test_builds_remote_server_entry_with_oauth_token_env_header (self ):
216287 entry = opencode .build_mcp_server_entry (f"{ WS } /api/2.0/mcp/external/github" )
@@ -323,6 +394,16 @@ def test_prefers_anthropic(self):
323394 state = {"opencode_models" : {"anthropic" : ["claude-sonnet" ], "gemini" : ["gemini-2" ]}}
324395 assert opencode .default_model (state ) == "claude-sonnet"
325396
397+ def test_falls_back_to_openai_before_gemini (self ):
398+ state = {
399+ "opencode_models" : {
400+ "anthropic" : [],
401+ "openai" : ["databricks-gpt-5-6-sol" ],
402+ "gemini" : ["gemini-2" ],
403+ }
404+ }
405+ assert opencode .default_model (state ) == "databricks-gpt-5-6-sol"
406+
326407 def test_falls_back_to_gemini (self ):
327408 state = {"opencode_models" : {"anthropic" : [], "gemini" : ["gemini-2" ]}}
328409 assert opencode .default_model (state ) == "gemini-2"
0 commit comments