{"repo":"NousResearch/hermes-agent","public_id":"11884","display_label":"TUI agent construction missing provider/credential resolution","summary":"A cluster of bug reports and fixes around the TUI's `_make_agent` function failing to resolve provider, api_mode, and credentials before constructing AIAgent, causing setup errors or wrong API calls.","subsystem":null,"counts":{"members":5,"open_issues":0,"open_issues_distinct":0,"open_prs":0,"closed_issues":2,"merged_prs":1,"attempt_prs":2},"landed_fix":{"status":"merged_to_main","basis":"structural","pr":11887},"resolution":{"state":"partially_resolved","by":"pr-11887"},"freshness":{"state":"stale","last_verified_at":"2026-04-23T01:11:21+00:00","is_stale":true},"grouping":{"backbone":"STRUCTURAL_PARTIAL","link_density":0.33599999999999997},"fix_edges":[{"issue_number":11884,"pr_number":11887,"tier":"verified","basis":"closing_ref","confidence":0.95,"recoverable_from_timeline":true}],"members":[{"kind":"issue","number":11884,"title":"[Bug]: Ink TUI: bare-slug model + provider in config yields HTTP 404 at api.anthropic.com","url":null,"state":"closed"},{"kind":"issue","number":12381,"title":"TUI: `hermes --tui` shows \"Setup Required\" for bedrock/anthropic-native configs — `_make_agent` drops provider/api_mode","url":null,"state":"closed"},{"kind":"pr","number":11887,"title":"fix(tui): resolve runtime provider in _make_agent","url":null,"state":"merged","close_reason":{"category":"merged","implication":"superseded"},"merged":true,"is_fix_pr":true,"fix_tier":"verified","files_changed":["tests/tui_gateway/test_make_agent_provider.py","tui_gateway/server.py"],"fix_hunks":[{"file":"tests/tui_gateway/test_make_agent_provider.py","hunks":["@@ -0,0 +1,48 @@\n+\"\"\"Regression test for #11884: _make_agent must resolve runtime provider.\n+\n+Without resolve_runtime_provider(), bare-slug models in config\n+(e.g. ``claude-opus-4-6`` with ``model.provider: anthropic``) leave\n+provider/base_url/api_key empty in AIAgent, causing HTTP 404.\n+\"\"\"\n+\n+from unittest.mock import MagicMock, patch\n+\n+\n+def test_make_agent_passes_resolved_provider():\n+    \"\"\"_make_agent forwards provider/base_url/api_key/api_mode from\n+    resolve_runtime_provider to AIAgent.\"\"\"\n+\n+    fake_runtime = {\n+        \"provider\": \"anthropic\",\n+        \"base_url\": \"https://api.anthropic.com\",\n+        \"api_key\": \"sk-test-key\",\n+        \"api_mode\": \"anthropic_messages\",\n+        \"command\": None,\n+        \"args\": None,\n+        \"credential_pool\": None,\n+    }\n+\n+    fake_cfg = {\n+        \"model\": {\"default\": \"claude-opus-4-6\", \"provider\": \"anthropic\"},\n+        \"agent\": {\"system_prompt\": \"test\"},\n+    }\n+\n+    with patch(\"tui_gateway.server._load_cfg\", return_value=fake_cfg), \\\n+         patch(\"tui_gateway.server._get_db\", return_value=MagicMock()), \\\n+         patch(\"tui_gateway.server._load_tool_progress_mode\", return_value=\"compact\"), \\\n+         patch(\"tui_gateway.server._load_reasoning_config\", return_value=None), \\\n+         patch(\"tui_gateway.server._load_service_tier\", return_value=None), \\\n+         patch(\"tui_gateway.server._load_enabled_toolsets\", return_value=None), \\\n+         patch(\"hermes_cli.runtime_provider.resolve_runtime_provider\", return_value=fake_runtime) as mock_resolve, \\\n+         patch(\"run_agent.AIAgent\") as mock_agent:\n+\n+        from tui_gateway.server import _make_agent\n+        _make_agent(\"sid-1\", \"key-1\")\n+\n+        mock_resolve.assert_called_once_with(requested=None)\n+\n+        call_kwargs = mock_agent.call_args\n+        assert call_kwargs.kwargs[\"provider\"] == \"anthropic\"\n+        assert call_kwargs.kwargs[\"base_url\"] == \"https://api.anthropic.com\"\n+        assert call_kwargs.kwargs[\"api_key\"] == \"sk-test-key\"\n+        assert call_kwargs.kwargs[\"api_mode\"] == \"anthropic_messages\""]},{"file":"tui_gateway/server.py","hunks":["@@ -1113,13 +1113,22 @@ def _reset_session_agent(sid: str, session: dict) -> dict:\n \n def _make_agent(sid: str, key: str, session_id: str | None = None):\n     from run_agent import AIAgent\n+    from hermes_cli.runtime_provider import resolve_runtime_provider\n \n     cfg = _load_cfg()\n     system_prompt = cfg.get(\"agent\", {}).get(\"system_prompt\", \"\") or \"\"\n     if not system_prompt:\n         system_prompt = _resolve_personality_prompt(cfg)\n+    runtime = resolve_runtime_provider(requested=None)\n     return AIAgent(\n         model=_resolve_model(),\n+        provider=runtime.get(\"provider\"),\n+        base_url=runtime.get(\"base_url\"),\n+        api_key=[redacted:secret-assignment]\"api_key\"),\n+        api_mode=runtime.get(\"api_mode\"),\n+        acp_command=runtime.get(\"command\"),\n+        acp_args=runtime.get(\"args\"),\n+        credential_pool=[redacted:secret-assignment]\"credential_pool\"),\n         quiet_mode=True,\n         verbose_logging=_load_tool_progress_mode() == \"verbose\",\n         reasoning_config=_load_reasoning_config(),\n"]}]},{"kind":"pr","number":11952,"title":"fix(tui): call resolve_runtime_provider() before constructing AIAgent","url":null,"state":"closed","close_reason":{"category":"duplicate_of","implication":"duplicate"},"merged":false},{"kind":"pr","number":13163,"title":"fix(tui): pass provider credentials explicitly to AIAgent","url":null,"state":"closed","close_reason":{"refs":[{"kind":"pr","value":"#11887","number":11887},{"kind":"pr","value":"#11887","number":11887}],"category":"superseded_by_pr","implication":"superseded"},"merged":false}],"trust":{"default_tier":"verified","includes_suggested":false}}