72b7c6c8d1
PR #67934 marked auto-discovered catalogs by writing two sentinel keys INSIDE the user-facing ``models`` mapping of custom provider entries: ``__discovered_model_catalog__`` (written by _save_discovered_models_to_config) and ``__explicit_model_allowlist__`` (injected by _normalize_custom_provider_entry). Every consumer of that mapping — pickers, selectors, gateway/agent readers, and the user's own config.yaml — had to know to filter those keys, and any site that didn't listed them as phantom model IDs (``__discovered_model_catalog__`` showing up as a selectable "model"). The v11→v12 config migration and the ACP session-state test caught exactly that leak on main. Replace the in-mapping sentinels with a single entry-level flag: - ``models_discovered: true`` now sits next to ``models``/``base_url`` on the provider entry; the models mapping stays a clean ``{model_id: metadata}`` dict with no reserved keys. - _save_discovered_models_to_config writes the new shape and refreshes catalogs it previously discovered (entry-level flag or legacy sentinel) instead of treating them as user-curated metadata. - _normalize_custom_provider_entry no longer injects ``__explicit_model_allowlist__``; a dict-shaped models mapping counts as an explicit allowlist exactly when the entry is NOT marked models_discovered. - _models_config_is_allowlist takes the discovered flag as a parameter (new helper _entry_models_discovered resolves it, including the legacy in-mapping sentinel); all call sites updated (model_switch.py, model_setup_flows.py, acp_adapter/server.py). - Backward compat, no config version bump: configs written by a pre-fix Hermes (sentinels inside models) still read correctly — ``__discovered_model_catalog__: true`` is treated as models_discovered, both sentinel keys are stripped from model listings, and the next discovery save migrates the entry to the clean shape. Covered by a new regression test. Also restore ``except Exception:`` on the pre-existing guards this PR had narrowed to specific exception tuples (the resolve_runtime_provider fallback in switch_model, the picker discovery/cache guards in list_authenticated_providers, _get_model_config_dict, and _credential_fingerprint). Those guards were intentionally broad on main — a failed resolution or probe must degrade to the fallback path, never crash the model switch. Guards the PR introduced for its own new probe code keep their authored tuples. The ACP new_session payload also goes back to probe_current_custom_provider=False, matching the contract main's test_new_session_returns_authenticated_cross_provider_model_state pins (session opens must not block on live-probing the current custom endpoint).