feat: add OpenAI Responses API support via per-model api_flavor

Route opted-in models to /v1/responses while keeping Chat Completions as
the default. The flavor is selected per-model in the catalog YAML and
threaded through ModelCapabilities (with a new reasoning_effort field).

- Translate chat-shaped messages/tools/structured-output into the
  Responses input / text.format / flattened-tool shapes at the provider
  boundary; stored history and intra-turn tool round-trips need no
  migration.
- Normalize the typed SSE event stream back into the existing handler
  contract (content / thought / tool-call chunks) so the streaming
  accumulator and OpenAI handler stay unchanged.
- Carry encrypted reasoning items across the in-turn tool loop
  (provider-local, keyed by call_id) for stateless reasoning continuity.
- OPENAI_RESPONSES_STORE opt-in enables server-side state and
  previous_response_id chaining across turns, persisted in message
  metadata.
- Set gpt-5.5 to api_flavor: responses, reasoning_effort: medium.
- Remove AzureOpenAILLM and the azure_openai provider/catalog.
This commit is contained in:
Alex committed 2026-06-03 13:43:04 +01:00
1 parent 84630d1314
commit 142a9201f4
14 files changed
+917 -150

No files matched your search

-19
View File
@@ -60,11 +60,6 @@ EXPECTED_IDS = {
"deepseek-v4-flash",
"deepseek-v4-pro",
},
"azure_openai": {
"azure-gpt-5.5",
"azure-gpt-5.4-mini",
"azure-gpt-5.4-nano",
},
"docsgpt": {"docsgpt-local"},
"huggingface": {"huggingface-local"},
}
@@ -241,20 +236,6 @@ class TestRegistryPermutations:
ids = {m.id for m in reg.get_all_models()}
assert ids == EXPECTED_IDS["docsgpt"]
def test_azure_via_provider(self):
s = _make_settings(LLM_PROVIDER="azure_openai", API_KEY="key")
with patch("application.core.settings.settings", s):
reg = ModelRegistry()
ids = {m.id for m in reg.get_all_models()}
assert "azure-gpt-5.5" in ids
def test_azure_via_api_base(self):
s = _make_settings(OPENAI_API_BASE="https://x.openai.azure.com")
with patch("application.core.settings.settings", s):
reg = ModelRegistry()
ids = {m.id for m in reg.get_all_models()}
assert "azure-gpt-5.5" in ids
def test_everything_set(self, monkeypatch):
monkeypatch.setenv("DEEPSEEK_API_KEY", "x")
s = _make_settings(
-1
View File
@@ -37,7 +37,6 @@ class TestModelProvider:
assert ModelProvider.SAGEMAKER == "sagemaker"
assert ModelProvider.PREMAI == "premai"
assert ModelProvider.LLAMA_CPP == "llama.cpp"
assert ModelProvider.AZURE_OPENAI == "azure_openai"
class TestModelCapabilities:
-10
View File
@@ -156,16 +156,6 @@ class TestGetApiKeyForProvider:
assert get_api_key_for_provider("unknown_provider") == "sk-fallback"
@pytest.mark.unit
def test_azure_openai_key(self):
with patch("application.core.settings.settings") as mock_settings:
mock_settings.API_KEY = "sk-azure"
from application.core.model_utils import get_api_key_for_provider
assert get_api_key_for_provider("azure_openai") == "sk-azure"
# ── get_all_available_models ─────────────────────────────────────────────────