feat: preserve Responses reasoning state and compact context (#5172)

This commit is contained in:
chengyongru
2026-07-30 22:39:43 +08:00
committed by GitHub
parent 511c764f45
commit 6a1a45d07a
37 changed files with 4778 additions and 153 deletions
+36
View File
@@ -14,6 +14,7 @@ from unittest.mock import AsyncMock, MagicMock, patch
import pytest
from nanobot.providers.base import ProviderCallContext
from nanobot.providers.openai_compat_provider import OpenAICompatProvider
from nanobot.providers.registry import find_by_name
@@ -679,6 +680,7 @@ async def test_direct_openai_gpt5_uses_responses_api() -> None:
assert call_kwargs["max_output_tokens"] == 4096
assert "input" in call_kwargs
assert "messages" not in call_kwargs
assert call_kwargs["include"] == ["reasoning.encrypted_content"]
@pytest.mark.asyncio
@@ -710,6 +712,40 @@ async def test_direct_openai_reasoning_prefers_responses_api() -> None:
assert call_kwargs["include"] == ["reasoning.encrypted_content"]
@pytest.mark.asyncio
async def test_direct_openai_retries_without_unsupported_server_compaction() -> None:
mock_chat = AsyncMock(return_value=_fake_chat_response())
mock_responses = AsyncMock(side_effect=[
_FakeResponsesError(400, "Unknown parameter: context_management"),
_fake_responses_response("compaction fallback"),
])
spec = find_by_name("openai")
with patch("nanobot.providers.openai_compat_provider.AsyncOpenAI") as mock_client_class:
client_instance = mock_client_class.return_value
client_instance.chat.completions.create = mock_chat
client_instance.responses.create = mock_responses
provider = OpenAICompatProvider(
api_key="sk-test-key",
default_model="gpt-5.6",
spec=spec,
)
result = await provider.chat_with_context(
messages=[{"role": "user", "content": "hello"}],
model="gpt-5.6",
provider_context=ProviderCallContext(context_window_tokens=200_000),
)
assert result.content == "compaction fallback"
assert result.provider_state is not None
assert mock_responses.await_count == 2
assert "context_management" in mock_responses.call_args_list[0].kwargs
assert "context_management" not in mock_responses.call_args_list[1].kwargs
assert provider.supports_native_compaction("gpt-5.6") is False
mock_chat.assert_not_awaited()
@pytest.mark.asyncio
async def test_direct_openai_gpt4o_stays_on_chat_completions() -> None:
mock_chat = AsyncMock(return_value=_fake_chat_response())