from __future__ import annotations import json import sqlite3 import uuid from datetime import UTC, datetime, timedelta import pytest from EvoScientist.llm.contracts import EvoRuntimeError, HmacGrantAuthority from EvoScientist.llm.crypto import HmacKeyRing, KeyMaterial, sha256_id from EvoScientist.llm.model_config_v4 import ( EvoModelConfig, UnifiedModelConfigStore, build_supported_v3_evidence, model_profile_identity_map, normalize_v4_config, project_v4_to_v3, ) from EvoScientist.llm.runtime import EvoModelRuntime def _payload(*, provider_id: str | None = None, profile_id: str | None = None) -> dict: provider_id = provider_id or str(uuid.uuid4()) profile_id = profile_id or str(uuid.uuid4()) return { "schema_version": 4, "default_model_profile_id": profile_id, "purpose_defaults": {}, "purpose_call_limits": {}, "providers": [ { "provider_id": provider_id, "display_name": "OpenAI Production", "adapter_id": "openai", "adapter_revision": "openai-v1", "enabled": True, "connection": {"base_url": "https://api.openai.com/v1"}, "models": [ { "model_profile_id": profile_id, "provider_model_id": "gpt-test", "display_name": "General", "enabled": True, "version_policy": "rolling", "invocation": { "api_mode": "responses", "tool_call_transport": "native", }, "capabilities": {"text": True, "tools": True}, "limits": { "context_tokens": 128_000, "max_output_tokens": 8_192, }, "parameters": {}, "billing": { "sku": "internal/gpt-test", "pricing_revision": "configured-v1", "currency": "CNY", "unit_scale": 1_000_000, "input_microunits_per_million": 1_000_000, "cached_microunits_per_million": 200_000, "output_microunits_per_million": 4_000_000, "multiplier": 1, }, } ], } ], } def _ring() -> HmacKeyRing: return HmacKeyRing(KeyMaterial.create("identity-v1", "i" * 32)) def test_v4_normalization_uses_stable_profile_identity(): payload = normalize_v4_config(_payload()) identities = model_profile_identity_map(payload) assert payload["schema_version"] == 4 assert payload["default_model_profile_id"] in identities assert identities[payload["default_model_profile_id"]][1] == "gpt-test" def test_v4_rejects_enabled_model_without_billing_configuration(): raw = _payload() raw["providers"][0]["models"][0].pop("billing") with pytest.raises(EvoRuntimeError) as raised: normalize_v4_config(raw, lenient=True, warnings=[]) assert raised.value.details[0]["code"] == "CONFIG_PRICING_REQUIRED" def test_v4_accepts_explicit_zero_price_for_free_model(): raw = _payload() raw["providers"][0]["models"][0]["billing"].update( input_microunits_per_million=0, cached_microunits_per_million=0, output_microunits_per_million=0, ) payload = normalize_v4_config(raw, lenient=True, warnings=[]) assert payload["providers"][0]["models"][0]["billing"][ "input_microunits_per_million" ] == 0 def test_v4_normalization_preserves_model_output_token_limit(): raw = _payload() raw["providers"][0]["models"][0]["parameters"] = { "defaults": {"output_token_limit": 2048, "temperature": 0.2}, "purpose_overrides": { "main_agent": {"output_token_limit": 1024, "temperature": 0.3} }, "user_options": { "output_token_limit": { "default": 512, "applies_to": ["main_agent"], } }, } payload = normalize_v4_config(raw) parameters = payload["providers"][0]["models"][0]["parameters"] assert parameters["defaults"] == {"output_token_limit": 2048, "temperature": 0.2} assert parameters["purpose_overrides"]["main_agent"] == { "output_token_limit": 1024, "temperature": 0.3, } assert parameters["user_options"] == {} for limit in payload["purpose_call_limits"].values(): assert "max_output_tokens" not in limit assert payload["purpose_call_limits"]["main_agent"] == { "max_attempts_per_run": 4 } def test_v4_rejects_output_token_limit_above_model_capability(): raw = _payload() raw["providers"][0]["models"][0]["parameters"] = { "defaults": {"output_token_limit": 16_384} } with pytest.raises(EvoRuntimeError) as raised: normalize_v4_config(raw) assert raised.value.code == "LLM_ROUTE_CONFIGURATION_REQUIRED" assert raised.value.details[0]["code"] == "CONFIG_LIMIT_EXCEEDED" def test_v4_lenient_clamps_output_token_limit_to_model_capability(): raw = _payload() raw["providers"][0]["models"][0]["parameters"] = { "defaults": {"output_token_limit": 16_384} } warnings: list[dict] = [] payload = normalize_v4_config(raw, lenient=True, warnings=warnings) defaults = payload["providers"][0]["models"][0]["parameters"]["defaults"] assert defaults["output_token_limit"] == 8_192 assert any(item["code"] == "CONFIG_LIMIT_EXCEEDED" for item in warnings) def test_v4_removes_legacy_tool_transport_from_admin_config(): raw = _payload() raw["providers"][0]["models"][0]["capabilities"]["tools"] = False payload = normalize_v4_config(raw) model = payload["providers"][0]["models"][0] assert model["invocation"] == {"api_mode": "responses"} def test_v4_runtime_projection_derives_tool_transport_from_capabilities(): raw = _payload() raw["providers"][0]["models"][0]["capabilities"]["tools"] = False warnings: list[dict] = [] payload = normalize_v4_config(raw, lenient=True, warnings=warnings) model = payload["providers"][0]["models"][0] assert "tool_call_transport" not in model["invocation"] assert not any( item["code"] == "CONFIG_INVOCATION_CONTRACT_INVALID" for item in warnings ) projection = project_v4_to_v3( payload, revision=1, identity_key_id=_ring().current.key_id, bindings={payload["providers"][0]["provider_id"]: 1}, ) config = EvoModelConfig.parse(projection, require_evidence=False) route = config.concrete_routes(next(iter(config.route_selectors)))[0] assert route.tool_call_transport == "disabled" def test_v4_rejects_non_uuid_business_ids(): raw = _payload(provider_id="openai-main") with pytest.raises(EvoRuntimeError) as raised: normalize_v4_config(raw) assert raised.value.code == "LLM_ROUTE_CONFIGURATION_REQUIRED" @pytest.mark.parametrize( "base_url", [ "", "not a url", "ftp://user:pass@example.test/path?key=value#fragment", "http://127.0.0.1:11434/v1", "https://169.254.169.254/latest/meta-data", "custom://model.internal:70000/path", ], ) def test_v4_base_url_is_not_validated(base_url): raw = _payload() raw["providers"][0]["connection"]["base_url"] = base_url payload = normalize_v4_config(raw) provider_id = payload["providers"][0]["provider_id"] projection = project_v4_to_v3( payload, revision=1, identity_key_id=_ring().current.key_id, bindings={provider_id: 1}, ) assert payload["providers"][0]["connection"]["base_url"] == base_url assert projection["providers"][0]["connection"]["base_url"] == base_url def test_unified_store_commits_config_and_secret_without_evidence_gate(tmp_path): ring = _ring() store = UnifiedModelConfigStore( tmp_path / "model-config.sqlite", identity_key_ring=ring, encryption_keys={"enc-v1": "e" * 32}, current_encryption_key_id="enc-v1", ) payload = normalize_v4_config(_payload()) provider_id = payload["providers"][0]["provider_id"] profile_id = payload["default_model_profile_id"] plan = store.plan_credentials(payload, {provider_id: "sk-secret-value"}) projection = project_v4_to_v3( payload, revision=1, identity_key_id=ring.current.key_id, bindings=plan.bindings, ) evidence = build_supported_v3_evidence( projection, identity_key_ring=ring, verified_profiles={provider_id: frozenset({profile_id})}, ) request_hash = sha256_id({"payload": payload, "fingerprints": plan.fingerprints}) store.begin_operation( "save-1", request_hash=request_hash, expected_revision=0, actor="admin", lease_owner="worker-1", ) result = store.commit( payload, expected_revision=0, operation_id="save-1", actor="admin", request_hash=request_hash, credential_plan=plan, evidence=evidence, ) assert result.config_revision == 1 assert result.changed is True runtime = store.load() assert runtime.main_routes.default_alias == profile_id assert store.resolve( runtime.providers[provider_id].endpoints[provider_id].auth ).value == "sk-secret-value" revision, admin_payload, credentials = store.get_admin_config() assert revision == 1 assert admin_payload == payload assert credentials[provider_id].configured is True assert "sk-secret-value" not in str(credentials) with sqlite3.connect(store.path) as connection: assert connection.execute("SELECT COUNT(*) FROM model_config_revisions").fetchone()[0] == 1 assert connection.execute("SELECT COUNT(*) FROM provider_secret_versions").fetchone()[0] == 1 assert connection.execute("SELECT COUNT(*) FROM capability_evidence").fetchone()[0] == 0 store.record_runtime_observation( config_revision=1, provider_id=provider_id, model_profile_id=profile_id, provider_model_id="gpt-test", api_mode="responses", purpose="main_agent", outcome="succeeded", error_code=None, strategy={"structured_output": False}, ) summary = store.runtime_observation_summary() assert len(summary) == 1 assert summary[0]["model_profile_id"] == profile_id assert summary[0]["provider_id"] == provider_id assert summary[0]["latest_outcome"] == "succeeded" assert summary[0]["latest_error_code"] is None assert summary[0]["total_calls"] == 1 assert summary[0]["successful_calls"] == 1 assert summary[0]["strategy"] == {"structured_output": False} assert summary[0]["latest_at"] def test_unified_store_idempotency_rejects_same_id_different_request(tmp_path): store = UnifiedModelConfigStore( tmp_path / "model-config.sqlite", identity_key_ring=_ring(), encryption_keys={"enc-v1": "e" * 32}, current_encryption_key_id="enc-v1", ) store.begin_operation( "save-1", request_hash="hmac:one", expected_revision=0, actor="admin", lease_owner="worker-1", ) with pytest.raises(EvoRuntimeError) as raised: store.begin_operation( "save-1", request_hash="hmac:two", expected_revision=0, actor="admin", lease_owner="worker-2", ) assert raised.value.code == "IDEMPOTENCY_CONFLICT" def test_operation_failure_preserves_last_progress(tmp_path): store = UnifiedModelConfigStore( tmp_path / "model-config.sqlite", identity_key_ring=_ring(), encryption_keys={"enc-v1": "e" * 32}, current_encryption_key_id="enc-v1", ) store.begin_operation( "save-1", request_hash="request-1", expected_revision=0, actor="admin", lease_owner="worker", ) store.set_operation_status( "save-1", "PROBING", progress={"completed": 2, "total": 3} ) store.set_operation_status( "save-1", "FAILED_RETRYABLE", stage="PROBING", error_code="MODEL_PROBE_FAILED", error_details=({"path": "models.test", "code": "MODEL_TIMEOUT"},), ) operation = store.get_operation("save-1") assert operation is not None assert operation["progress"] == {"completed": 2, "total": 3} assert operation["error_details"] == [ {"path": "models.test", "code": "MODEL_TIMEOUT"} ] def test_unified_store_load_ignores_historical_evidence(tmp_path): ring = _ring() store = UnifiedModelConfigStore( tmp_path / "model-config.sqlite", identity_key_ring=ring, encryption_keys={"enc-v1": "e" * 32}, current_encryption_key_id="enc-v1", ) payload = normalize_v4_config(_payload()) provider_id = payload["providers"][0]["provider_id"] profile_id = payload["default_model_profile_id"] plan = store.plan_credentials(payload, {provider_id: "sk-secret-value"}) projection = project_v4_to_v3( payload, revision=1, identity_key_id=ring.current.key_id, bindings=plan.bindings ) evidence = build_supported_v3_evidence( projection, identity_key_ring=ring, verified_profiles={provider_id: frozenset({profile_id})}, ) store.begin_operation( "save-1", request_hash="request-1", expected_revision=0, actor="admin", lease_owner="worker", ) store.commit( payload, expected_revision=0, operation_id="save-1", actor="admin", request_hash="request-1", credential_plan=plan, evidence=evidence, ) # The supplied evidence is intentionally not persisted or read by load. # A legacy/tampered evidence row therefore cannot make the revision stale. assert store.load_revision(1).config_revision == 1 def test_rollback_publishes_a_new_monotonic_revision(tmp_path): ring = _ring() store = UnifiedModelConfigStore( tmp_path / "model-config.sqlite", identity_key_ring=ring, encryption_keys={"enc-v1": "e" * 32}, current_encryption_key_id="enc-v1", ) first = normalize_v4_config(_payload()) provider_id = first["providers"][0]["provider_id"] profile_id = first["default_model_profile_id"] def publish(payload: dict, revision: int, operation_id: str, request_hash: str): plan = store.plan_credentials( payload, {provider_id: "sk-secret-value"} if revision == 1 else {} ) projection = project_v4_to_v3( payload, revision=revision, identity_key_id=ring.current.key_id, bindings=plan.bindings, ) evidence = build_supported_v3_evidence( projection, identity_key_ring=ring, verified_profiles={provider_id: frozenset({profile_id})}, ) store.begin_operation( operation_id, request_hash=request_hash, expected_revision=revision - 1, actor="admin", lease_owner="worker", ) return store.commit( payload, expected_revision=revision - 1, operation_id=operation_id, actor="admin", request_hash=request_hash, credential_plan=plan, evidence=evidence, ) publish(first, 1, "save-1", "request-1") second = json.loads(json.dumps(first)) second["providers"][0]["display_name"] = "Changed display name" publish(second, 2, "save-2", "request-2") store.begin_operation( "rollback-1", request_hash="rollback-request", expected_revision=2, actor="admin", lease_owner="worker", ) result = store.rollback( target_revision=1, expected_revision=2, operation_id="rollback-1", actor="admin", request_hash="rollback-request", ) assert result.config_revision == 3 assert store.current_revision() == 3 assert store.get_admin_config()[1]["providers"][0]["display_name"] == "OpenAI Production" assert store.load().config_revision == 3 def test_identity_key_rotation_does_not_rotate_unchanged_credential(tmp_path): first_ring = _ring() path = tmp_path / "model-config.sqlite" store = UnifiedModelConfigStore( path, identity_key_ring=first_ring, encryption_keys={"enc-v1": "e" * 32}, current_encryption_key_id="enc-v1", ) payload = normalize_v4_config(_payload()) provider_id = payload["providers"][0]["provider_id"] profile_id = payload["default_model_profile_id"] plan = store.plan_credentials(payload, {provider_id: "sk-same-secret"}) projection = project_v4_to_v3( payload, revision=1, identity_key_id=first_ring.current.key_id, bindings=plan.bindings, ) evidence = build_supported_v3_evidence( projection, identity_key_ring=first_ring, verified_profiles={provider_id: frozenset({profile_id})}, ) store.begin_operation( "save-1", request_hash="request-1", expected_revision=0, actor="admin", lease_owner="worker", ) store.commit( payload, expected_revision=0, operation_id="save-1", actor="admin", request_hash="request-1", credential_plan=plan, evidence=evidence, ) rotated_ring = HmacKeyRing( KeyMaterial.create("identity-v2", "j" * 32), retained=(first_ring.current,) ) rotated_store = UnifiedModelConfigStore( path, identity_key_ring=rotated_ring, encryption_keys={"enc-v1": "e" * 32}, current_encryption_key_id="enc-v1", ) rotated_plan = rotated_store.plan_credentials( payload, {provider_id: "sk-same-secret"} ) assert rotated_plan.new_versions == frozenset() assert rotated_plan.bindings[provider_id] == 1 assert rotated_plan.fingerprints[provider_id] == plan.fingerprints[provider_id] def test_evidence_requires_observed_results_for_every_declared_capability(): ring = _ring() raw = _payload() raw["providers"][0]["models"][0]["capabilities"] = { "text": True, "vision": True, "tools": True, } payload = normalize_v4_config(raw) provider_id = payload["providers"][0]["provider_id"] profile_id = payload["default_model_profile_id"] projection = project_v4_to_v3( payload, revision=1, identity_key_id=ring.current.key_id, bindings={provider_id: 1}, ) with pytest.raises(EvoRuntimeError) as raised: build_supported_v3_evidence( projection, identity_key_ring=ring, probe_results={ provider_id: {profile_id: {"connectivity": "supported"}} }, ) assert raised.value.code == "CAPABILITY_EVIDENCE_STALE" def test_historical_evidence_is_not_reused_for_route_admission(tmp_path): ring = _ring() store = UnifiedModelConfigStore( tmp_path / "model-config.sqlite", identity_key_ring=ring, encryption_keys={"enc-v1": "e" * 32}, current_encryption_key_id="enc-v1", ) payload = normalize_v4_config(_payload()) provider_id = payload["providers"][0]["provider_id"] profile_id = payload["default_model_profile_id"] plan = store.plan_credentials(payload, {provider_id: "sk-secret-value"}) projection = project_v4_to_v3( payload, revision=1, identity_key_id=ring.current.key_id, bindings=plan.bindings, ) evidence = build_supported_v3_evidence( projection, identity_key_ring=ring, verified_profiles={provider_id: frozenset({profile_id})}, ) store.begin_operation( "save-1", request_hash="request-1", expected_revision=0, actor="admin", lease_owner="worker", ) store.commit( payload, expected_revision=0, operation_id="save-1", actor="admin", request_hash="request-1", credential_plan=plan, evidence=evidence, ) next_payload = json.loads(json.dumps(payload)) next_payload["providers"][0]["display_name"] = "Renamed Provider" next_plan = store.plan_credentials(next_payload, {}) next_projection = project_v4_to_v3( next_payload, revision=2, identity_key_id=ring.current.key_id, bindings=next_plan.bindings, ) observed, windows, missing = store.reusable_probe_results( next_projection, fingerprints=next_plan.fingerprints, versions=next_plan.bindings, ) assert observed == {} assert windows == {} assert missing == frozenset({(provider_id, profile_id)}) def test_availability_reflects_enabled_state(tmp_path): ring = _ring() store = UnifiedModelConfigStore( tmp_path / "model-config.sqlite", identity_key_ring=ring, encryption_keys={"enc-v1": "e" * 32}, current_encryption_key_id="enc-v1", ) raw = _payload() disabled_profile_id = str(uuid.uuid4()) disabled = json.loads(json.dumps(raw["providers"][0]["models"][0])) disabled.update( { "model_profile_id": disabled_profile_id, "provider_model_id": "disabled-model", "display_name": "Disabled", "enabled": False, } ) raw["providers"][0]["models"].append(disabled) payload = normalize_v4_config(raw) provider_id = payload["providers"][0]["provider_id"] profile_id = payload["default_model_profile_id"] plan = store.plan_credentials(payload, {provider_id: "sk-secret-value"}) store.begin_operation( "save-1", request_hash="request-1", expected_revision=0, actor="admin", lease_owner="worker", ) store.commit( payload, expected_revision=0, operation_id="save-1", actor="admin", request_hash="request-1", credential_plan=plan, evidence=[], ) availability = store.get_model_availability() assert availability[profile_id] == { "model_profile_id": profile_id, "enabled": True, "selectable": True, } assert availability[disabled_profile_id] == { "model_profile_id": disabled_profile_id, "enabled": False, "selectable": False, } def test_schema_upgrade_adds_availability_and_operation_columns(tmp_path): path = tmp_path / "model-config.sqlite" UnifiedModelConfigStore( path, identity_key_ring=_ring(), encryption_keys={"enc-v1": "e" * 32}, current_encryption_key_id="enc-v1", ) with sqlite3.connect(path) as connection: connection.execute("DROP INDEX idx_capability_evidence_semantics") connection.execute("ALTER TABLE active_model_config DROP COLUMN evidence_epoch") connection.execute("ALTER TABLE capability_evidence DROP COLUMN credential_version") connection.execute("ALTER TABLE model_config_operations DROP COLUMN stage") connection.execute("ALTER TABLE model_config_operations DROP COLUMN progress_json") connection.execute("ALTER TABLE model_config_operations DROP COLUMN error_details_json") UnifiedModelConfigStore( path, identity_key_ring=_ring(), encryption_keys={"enc-v1": "e" * 32}, current_encryption_key_id="enc-v1", ) with sqlite3.connect(path) as connection: assert "evidence_epoch" in { row[1] for row in connection.execute("PRAGMA table_info(active_model_config)") } assert "credential_version" in { row[1] for row in connection.execute("PRAGMA table_info(capability_evidence)") } operation_columns = { row[1] for row in connection.execute("PRAGMA table_info(model_config_operations)") } assert {"stage", "progress_json", "error_details_json"} <= operation_columns def test_v3_runtime_accepts_expired_historical_evidence(tmp_path): ring = _ring() store = UnifiedModelConfigStore( tmp_path / "model-config.sqlite", identity_key_ring=ring, encryption_keys={"enc-v1": "e" * 32}, current_encryption_key_id="enc-v1", ) payload = normalize_v4_config(_payload()) provider_id = payload["providers"][0]["provider_id"] profile_id = payload["default_model_profile_id"] plan = store.plan_credentials(payload, {provider_id: "sk-secret-value"}) projection = project_v4_to_v3( payload, revision=1, identity_key_id=ring.current.key_id, bindings=plan.bindings, ) now = datetime.now(UTC) evidence = build_supported_v3_evidence( projection, identity_key_ring=ring, verified_profiles={provider_id: frozenset({profile_id})}, evidence_windows={ provider_id: { profile_id: ( (now - timedelta(hours=2)).isoformat(timespec="microseconds"), (now - timedelta(hours=1)).isoformat(timespec="microseconds"), ) } }, ) store.begin_operation( "save-1", request_hash="request-1", expected_revision=0, actor="admin", lease_owner="worker", ) store.commit( payload, expected_revision=0, operation_id="save-1", actor="admin", request_hash="request-1", credential_plan=plan, evidence=evidence, ) config = store.load() authority = HmacGrantAuthority("r" * 32) runtime = EvoModelRuntime( store, admission_verifier=authority, quote_authority=authority, identity_key_ring=ring, secret_resolver=store.resolve, ) selector = config.resolve_main_selector(None) route = config.concrete_routes(selector.selector_id)[0] resolved = runtime._resolve_route(config, route, "main_agent") assert resolved.identity.model_id == "gpt-test" def test_lenient_normalization_ignores_unknown_fields_with_warning(): raw = _payload() raw["unexpected_top"] = True raw["providers"][0]["unexpected_provider"] = "x" raw["providers"][0]["models"][0]["unexpected_model"] = 1 warnings: list[dict] = [] payload = normalize_v4_config(raw, lenient=True, warnings=warnings) assert payload["schema_version"] == 4 assert [item["code"] for item in warnings] == ["CONFIG_UNKNOWN_FIELDS"] * 3 def test_lenient_normalization_clamps_out_of_range_and_timeout_conflict(): raw = _payload() raw["providers"][0]["connection"] = { "base_url": "https://api.openai.com/v1", "connect_timeout_seconds": 120, "attempt_timeout_seconds": 30, } warnings: list[dict] = [] payload = normalize_v4_config(raw, lenient=True, warnings=warnings) connection = payload["providers"][0]["connection"] assert connection["connect_timeout_seconds"] == 60 assert connection["attempt_timeout_seconds"] == 60 codes = {item["code"] for item in warnings} assert "CONFIG_VALUE_OUT_OF_RANGE" in codes assert "CONFIG_VALUE_CONFLICT" in codes def test_lenient_normalization_forces_text_capability_and_keeps_unknown_purpose(): raw = _payload() raw["providers"][0]["models"][0]["capabilities"] = {"text": False, "vision": True} raw["providers"][0]["models"][0]["parameters"] = { "purpose_overrides": {"custom_purpose": {"temperature": 0.5}} } warnings: list[dict] = [] payload = normalize_v4_config(raw, lenient=True, warnings=warnings) model = payload["providers"][0]["models"][0] assert model["capabilities"]["text"] is True assert model["parameters"]["purpose_overrides"]["custom_purpose"] == {"temperature": 0.5} assert any(item["code"] == "CONFIG_REQUIRED" for item in warnings) assert any(item["code"] == "CONFIG_REFERENCE_INVALID" for item in warnings) def test_strict_normalization_still_rejects_unknown_fields(): raw = _payload() raw["unexpected_top"] = True with pytest.raises(EvoRuntimeError): normalize_v4_config(raw) def test_unverified_enabled_model_is_selectable(tmp_path): ring = _ring() store = UnifiedModelConfigStore( tmp_path / "model-config.sqlite", identity_key_ring=ring, encryption_keys={"enc-v1": "e" * 32}, current_encryption_key_id="enc-v1", ) payload = normalize_v4_config(_payload()) provider_id = payload["providers"][0]["provider_id"] profile_id = payload["default_model_profile_id"] plan = store.plan_credentials(payload, {provider_id: "sk-secret-value"}) store.begin_operation( "save-1", request_hash="request-1", expected_revision=0, actor="admin", lease_owner="worker", ) store.commit( payload, expected_revision=0, operation_id="save-1", actor="admin", request_hash="request-1", credential_plan=plan, evidence=[], ) availability = store.get_model_availability()[profile_id] assert availability == { "model_profile_id": profile_id, "enabled": True, "selectable": True, }