feat(database-migrations): add migration to remove legacy model config tables and remove stale model connection code

This commit is contained in:
Anish Sarkar 2026-06-13 12:45:43 +05:30
parent 50668775f8
commit bd4a04f2e7
93 changed files with 956 additions and 11442 deletions

View file

@ -63,29 +63,22 @@ async def test_delete_search_space_idempotent_on_404(respx_mock, http):
@pytest.mark.asyncio
@respx.mock(base_url=_BASE)
async def test_set_llm_preferences_partial_update(respx_mock, http):
route = respx_mock.put("/api/v1/search-spaces/42/llm-preferences").mock(
async def test_set_model_roles_partial_update(respx_mock, http):
route = respx_mock.put("/api/v1/search-spaces/42/model-roles").mock(
return_value=httpx.Response(
200,
json={
"agent_llm_id": -10042,
"agent_llm_id": None,
"image_generation_config_id": None,
"vision_llm_config_id": None,
"agent_llm": {
"id": -10042,
"provider": "OPENROUTER",
"model_name": "anthropic/claude-sonnet-4.5",
},
"chat_model_id": -10042,
"image_gen_model_id": None,
"vision_model_id": None,
},
)
)
client = SearchSpaceClient(http, _BASE)
prefs = await client.set_llm_preferences(42, agent_llm_id=-10042)
assert prefs.agent_llm_id == -10042
assert prefs.agent_llm["provider"] == "OPENROUTER"
roles = await client.set_model_roles(42, chat_model_id=-10042)
assert roles.chat_model_id == -10042
sent_body = json.loads(route.calls[-1].request.content)
assert sent_body == {"agent_llm_id": -10042}
assert sent_body == {"chat_model_id": -10042}
# ---------------------------------------------------------------------------

View file

@ -41,14 +41,14 @@ def test_state_roundtrip_per_suite(tmp_env): # noqa: ARG001
assert get_suite_state(config, "medical") is None
state = SuiteState(
search_space_id=1,
agent_llm_id=-10042,
chat_model_id=-10042,
provider_model="anthropic/claude-sonnet-4.5",
created_at="2026-05-11T20-30-00Z",
)
set_suite_state(config, "medical", state)
legal = SuiteState(
search_space_id=2,
agent_llm_id=-1,
chat_model_id=-1,
provider_model="openai/gpt-5",
created_at="2026-05-11T21-00-00Z",
)
@ -84,25 +84,19 @@ def test_paths_are_per_suite(tmp_env): # noqa: ARG001
# ---------------------------------------------------------------------------
def test_legacy_state_back_compat_defaults_to_head_to_head():
"""state.json files written before scenarios shipped must still load.
def test_minimal_state_defaults_to_head_to_head():
"""Missing scenario / vision / native fields default safely."""
Missing ``scenario`` / ``vision_*`` / ``native_arm_model`` keys all
default to ``head-to-head`` / ``None`` so old setups keep working
after upgrade the runner's behaviour exactly mirrors the legacy
one (both arms answer with ``provider_model``).
"""
legacy = {
payload = {
"search_space_id": 7,
"agent_llm_id": -123,
"chat_model_id": -123,
"provider_model": "anthropic/claude-sonnet-4.5",
"created_at": "2026-05-11T20-30-00Z",
"ingestion_maps": {},
}
state = SuiteState.from_dict(legacy)
state = SuiteState.from_dict(payload)
assert state.scenario == DEFAULT_SCENARIO == "head-to-head"
assert state.vision_llm_config_id is None
assert state.vision_model_id is None
assert state.vision_provider_model is None
assert state.native_arm_model is None
# The native arm should still answer with the same slug as SurfSense.
@ -118,7 +112,7 @@ def test_unknown_scenario_falls_back_to_default():
payload = {
"search_space_id": 1,
"agent_llm_id": -1,
"chat_model_id": -1,
"provider_model": "openai/gpt-5",
"scenario": "unknown-scenario-name",
}
@ -130,11 +124,11 @@ def test_cost_arbitrage_state_persists_native_arm_model(tmp_env): # noqa: ARG00
config = load_config()
state = SuiteState(
search_space_id=42,
agent_llm_id=-1,
chat_model_id=-1,
provider_model="openai/gpt-5.4-mini",
created_at="2026-05-11T20-30-00Z",
scenario="cost-arbitrage",
vision_llm_config_id=-101,
vision_model_id=-101,
vision_provider_model="anthropic/claude-sonnet-4.5",
native_arm_model="anthropic/claude-sonnet-4.5",
)
@ -142,7 +136,7 @@ def test_cost_arbitrage_state_persists_native_arm_model(tmp_env): # noqa: ARG00
fetched = get_suite_state(config, "medical")
assert fetched.scenario == "cost-arbitrage"
assert fetched.vision_llm_config_id == -101
assert fetched.vision_model_id == -101
assert fetched.vision_provider_model == "anthropic/claude-sonnet-4.5"
assert fetched.native_arm_model == "anthropic/claude-sonnet-4.5"
# Cost arbitrage's whole point: native arm slug != surfsense slug.

View file

@ -27,7 +27,7 @@ async def test_smoke_against_localhost():
pytest.skip("No credentials in environment; skipping integration smoke")
bundle = await acquire_token(config)
async with client_with_auth(config, bundle) as client:
response = await client.get(f"{config.surfsense_api_base}/api/v1/global-new-llm-configs")
response = await client.get(f"{config.surfsense_api_base}/api/v1/model-connections/global")
try:
response.raise_for_status()
except httpx.HTTPStatusError as exc: