diff --git a/acp_adapter/server.py b/acp_adapter/server.py index def8ec18b53..7646f332534 100644 --- a/acp_adapter/server.py +++ b/acp_adapter/server.py @@ -1623,6 +1623,13 @@ class HermesACPAgent(acp.Agent): user_text, final_response, state.history, + main_runtime={ + "model": getattr(state.agent, "model", None), + "provider": getattr(state.agent, "provider", None), + "base_url": getattr(state.agent, "base_url", None), + "api_key": getattr(state.agent, "api_key", None), + "api_mode": getattr(state.agent, "api_mode", None), + }, title_callback=_notify_title_update, ) except Exception: diff --git a/tests/acp/test_server.py b/tests/acp/test_server.py index 9b7ac1bc796..c9c9820a577 100644 --- a/tests/acp/test_server.py +++ b/tests/acp/test_server.py @@ -1323,6 +1323,11 @@ class TestPrompt: async def test_prompt_auto_titles_session(self, agent): new_resp = await agent.new_session(cwd=".") state = agent.session_manager.get_session(new_resp.session_id) + state.agent.model = "gpt-5.6-sol" + state.agent.provider = "openai-codex" + state.agent.base_url = "https://chatgpt.example.test/backend-api/codex" + state.agent.api_key = object() + state.agent.api_mode = "codex_responses" state.agent.run_conversation = MagicMock(return_value={ "final_response": "Here is the fix.", "messages": [ @@ -1343,6 +1348,13 @@ class TestPrompt: assert mock_title.call_args.args[1] == new_resp.session_id assert mock_title.call_args.args[2] == "fix the broken ACP history" assert mock_title.call_args.args[3] == "Here is the fix." + assert mock_title.call_args.kwargs["main_runtime"] == { + "model": "gpt-5.6-sol", + "provider": "openai-codex", + "base_url": "https://chatgpt.example.test/backend-api/codex", + "api_key": state.agent.api_key, + "api_mode": "codex_responses", + } assert callable(mock_title.call_args.kwargs["title_callback"]) @pytest.mark.asyncio diff --git a/tests/test_tui_gateway_server.py b/tests/test_tui_gateway_server.py index adaeeefb93d..6be6f85ed83 100644 --- a/tests/test_tui_gateway_server.py +++ b/tests/test_tui_gateway_server.py @@ -7457,6 +7457,12 @@ def test_prompt_submit_auto_titles_session_on_complete(monkeypatch): """maybe_auto_title is called after a successful (complete) prompt.""" class _Agent: + model = "gpt-5.6-sol" + provider = "openai-codex" + base_url = "https://chatgpt.example.test/backend-api/codex" + api_key = object() + api_mode = "codex_responses" + def run_conversation( self, prompt, conversation_history=None, stream_callback=None ): @@ -7489,6 +7495,13 @@ def test_prompt_submit_auto_titles_session_on_complete(monkeypatch): assert args[1] == "session-key" assert args[2] == "Tell me about Rome" assert args[3] == "Rome was founded in 753 BC." + assert mock_title.call_args.kwargs["main_runtime"] == { + "model": "gpt-5.6-sol", + "provider": "openai-codex", + "base_url": "https://chatgpt.example.test/backend-api/codex", + "api_key": _Agent.api_key, + "api_mode": "codex_responses", + } def test_prompt_submit_skips_auto_title_when_interrupted(monkeypatch): diff --git a/tui_gateway/server.py b/tui_gateway/server.py index 2f92833d33b..3e405268d84 100644 --- a/tui_gateway/server.py +++ b/tui_gateway/server.py @@ -9684,6 +9684,17 @@ def _run_prompt_submit(rid, sid: str, session: dict, text: Any) -> None: text, raw, session.get("history", []), + # Keep auxiliary auto-detection aligned with the active + # Desktop/Webapp session. Without this, providers that + # rely on runtime auth (for example OpenAI Codex OAuth) + # are skipped and the new session remains untitled. + main_runtime={ + "model": getattr(agent, "model", None), + "provider": getattr(agent, "provider", None), + "base_url": getattr(agent, "base_url", None), + "api_key": getattr(agent, "api_key", None), + "api_mode": getattr(agent, "api_mode", None), + }, # Push the generated title live so the sidebar renames # without waiting for the next list refresh (the titler # runs async, after this turn's refresh already fired).