Files
hermes-agent/tests/hermes_cli/test_nous_policy_surfaces.py
ethernet 890bbbda1f Merge remote-tracking branch 'origin/main' into ethie/pm-clean
# Conflicts:
#	apps/desktop/e2e/archived-hidden-session-recoverable.spec.ts
#	apps/desktop/e2e/bot-chat-message-agent-friendly-name.spec.ts
#	apps/desktop/e2e/bot-mailbox-unreadable-ticket.spec.ts
#	apps/desktop/e2e/bot-mode-roster-localized.spec.ts
#	apps/desktop/e2e/bot-mode-row-click-mirrors-registry.spec.ts
#	apps/desktop/e2e/bot-mode-tab-shows-bot-name.spec.ts
#	apps/desktop/e2e/bot-roster-group-row-organisation.spec.ts
#	apps/desktop/e2e/bot-roster-ignores-infra-dirs.spec.ts
#	apps/desktop/e2e/bot-roster-timestamp-meta.spec.ts
#	apps/desktop/e2e/bot-roster-user-sections.spec.ts
#	apps/desktop/e2e/bot-routines-pane-narrow.spec.ts
#	apps/desktop/e2e/bot-row-open-recent-session.spec.ts
#	apps/desktop/e2e/bot-tile-ignores-ambient-composer-model.spec.ts
#	apps/desktop/e2e/group-composer-auto-grow.spec.ts
#	apps/desktop/e2e/group-create-gate-remote-roster.spec.ts
#	apps/desktop/e2e/group-prompt-renamed-primary-handle.spec.ts
#	apps/desktop/e2e/hosted-room-backend-continuity.spec.ts
#	apps/desktop/e2e/hosted-room-legacy-store-migration.spec.ts
#	apps/desktop/e2e/settings-scope-chips-bot-title.spec.ts
#	apps/desktop/e2e/worktree-branch-status.spec.ts
#	apps/desktop/electron/backend-probes.test.ts
#	apps/desktop/electron/connection-apply.test.ts
#	apps/desktop/electron/desktop-electron-pin.test.ts
#	apps/desktop/electron/desktop-uninstall.test.ts
#	apps/desktop/electron/gateway-file-download-transport.test.ts
#	apps/desktop/electron/gateway-stop-before-update.test.ts
#	apps/desktop/electron/github-api-auth.test.ts
#	apps/desktop/electron/registry-primary-profile-scope.test.ts
#	apps/desktop/electron/update-api-check.test.ts
#	apps/desktop/electron/update-handoff-marker.test.ts
#	apps/desktop/electron/venv-blocker-scan.test.ts
#	apps/desktop/scripts/after-extract.test.mjs
#	apps/desktop/scripts/local-pack-publish.test.mjs
#	apps/desktop/scripts/tasks-scroll.test.mjs
#	apps/desktop/src/app/settings/model-settings.test.tsx
#	apps/desktop/src/app/updates-overlay.blockers.test.tsx
#	apps/desktop/src/components/desktop-install-overlay.test.tsx
#	apps/desktop/src/lib/update-copy.test.ts
#	scripts/ci/check_os_marker_fakes.py
#	tests-js/desktop-mac-usage-descriptions.test.ts
#	tests-js/node-engine-alignment.test.ts
#	tests/agent/lsp/test_install_and_lint_fixes.py
#	tests/agent/test_command_token_source.py
#	tests/agent/test_compression_boundary_hook.py
#	tests/agent/test_create_openai_client_ssl_verify.py
#	tests/agent/test_custom_provider_ca_probes.py
#	tests/agent/test_endpoint_blackhole.py
#	tests/agent/test_estimator_parity.py
#	tests/agent/test_in_place_compaction.py
#	tests/agent/test_moa_loop_mode.py
#	tests/agent/test_model_metadata.py
#	tests/agent/test_skill_session_platform_gate.py
#	tests/agent/test_skill_utils.py
#	tests/agent/test_ssl_ca_guard.py
#	tests/computer_use/test_doctor.py
#	tests/cron/test_codex_execution_paths.py
#	tests/cron/test_cron_bot_chat_delivery.py
#	tests/cron/test_cron_script.py
#	tests/cron/test_media_delivery_parity.py
#	tests/cron/test_misfire_catchup.py
#	tests/cron/test_parallel_pool.py
#	tests/cron/test_recurring_eagain_redispatch.py
#	tests/gateway/test_choice_picker.py
#	tests/gateway/test_control_socket_windows_live.py
#	tests/gateway/test_dingtalk.py
#	tests/gateway/test_feishu.py
#	tests/gateway/test_feishu_onboard.py
#	tests/gateway/test_gateway_shutdown.py
#	tests/gateway/test_matrix.py
#	tests/gateway/test_model_command_custom_providers.py
#	tests/gateway/test_reasoning_command.py
#	tests/gateway/test_runtime_footer.py
#	tests/gateway/test_session.py
#	tests/gateway/test_session_hygiene.py
#	tests/gateway/test_status.py
#	tests/gateway/test_teams.py
#	tests/gateway/test_turn_lease.py
#	tests/gateway/test_whatsapp_connect.py
#	tests/hermes_cli/test_approvals_command.py
#	tests/hermes_cli/test_auth_store_lock_concurrent.py
#	tests/hermes_cli/test_backup.py
#	tests/hermes_cli/test_banner_git_state.py
#	tests/hermes_cli/test_certifi_repair.py
#	tests/hermes_cli/test_cmd_update.py
#	tests/hermes_cli/test_compat_manifest_targets.py
#	tests/hermes_cli/test_computer_use_cli.py
#	tests/hermes_cli/test_cpr_local_leak.py
#	tests/hermes_cli/test_dashboard_auth_gate.py
#	tests/hermes_cli/test_dashboard_procs_kill_grace.py
#	tests/hermes_cli/test_desktop_lifecycle_windows_live.py
#	tests/hermes_cli/test_doctor.py
#	tests/hermes_cli/test_doctor_command_install.py
#	tests/hermes_cli/test_fleet_config_migration_windows_live.py
#	tests/hermes_cli/test_gateway.py
#	tests/hermes_cli/test_gateway_platform_gating.py
#	tests/hermes_cli/test_gateway_restart_loop.py
#	tests/hermes_cli/test_gateway_task_probe.py
#	tests/hermes_cli/test_gateway_wsl.py
#	tests/hermes_cli/test_gui_command.py
#	tests/hermes_cli/test_install_cua_driver.py
#	tests/hermes_cli/test_kanban_db.py
#	tests/hermes_cli/test_lazy_command_exports.py
#	tests/hermes_cli/test_lazy_refresh_venv_repair.py
#	tests/hermes_cli/test_linux_desktop_entry.py
#	tests/hermes_cli/test_local_runtime.py
#	tests/hermes_cli/test_local_runtime_updates.py
#	tests/hermes_cli/test_managed_uv.py
#	tests/hermes_cli/test_mcp_reload_confirm_gate.py
#	tests/hermes_cli/test_nous_subscription.py
#	tests/hermes_cli/test_npm_engine.py
#	tests/hermes_cli/test_personality_none.py
#	tests/hermes_cli/test_pet_toggle.py
#	tests/hermes_cli/test_plan_reconciliation_windows_live.py
#	tests/hermes_cli/test_plugin_event_bus.py
#	tests/hermes_cli/test_plugin_manifest_v2.py
#	tests/hermes_cli/test_plugin_packs.py
#	tests/hermes_cli/test_plugins_cmd.py
#	tests/hermes_cli/test_plugins_cmd_enable_disable_nested.py
#	tests/hermes_cli/test_process_identity.py
#	tests/hermes_cli/test_profiles.py
#	tests/hermes_cli/test_profiles_sidebar_cache.py
#	tests/hermes_cli/test_pty_bridge.py
#	tests/hermes_cli/test_resolve_turn_limit.py
#	tests/hermes_cli/test_serve_runtime_inventory.py
#	tests/hermes_cli/test_session_vacuum_config.py
#	tests/hermes_cli/test_set_config_value.py
#	tests/hermes_cli/test_signal_handler_kanban_worker.py
#	tests/hermes_cli/test_slash_confirm_windows.py
#	tests/hermes_cli/test_stale_pid_guard.py
#	tests/hermes_cli/test_startup_fast_guards.py
#	tests/hermes_cli/test_status.py
#	tests/hermes_cli/test_telegram_managed_bot.py
#	tests/hermes_cli/test_tools_config.py
#	tests/hermes_cli/test_update_apply_shallow_count.py
#	tests/hermes_cli/test_update_autostash.py
#	tests/hermes_cli/test_update_concurrent_quarantine.py
#	tests/hermes_cli/test_update_fetch_failure_classifier.py
#	tests/hermes_cli/test_update_fleet_probe_resume_token.py
#	tests/hermes_cli/test_update_handoff_backend_reap.py
#	tests/hermes_cli/test_update_handoff_desktop_rebuild.py
#	tests/hermes_cli/test_update_head_moved_gate.py
#	tests/hermes_cli/test_update_host_obligation.py
#	tests/hermes_cli/test_update_import_guard.py
#	tests/hermes_cli/test_update_interrupted_recovery.py
#	tests/hermes_cli/test_update_inventory.py
#	tests/hermes_cli/test_update_launchd_unloaded_gateway.py
#	tests/hermes_cli/test_update_missing_configured_deps.py
#	tests/hermes_cli/test_update_modified_notice.py
#	tests/hermes_cli/test_update_multiplex_migration_hook.py
#	tests/hermes_cli/test_update_no_gateway_restart.py
#	tests/hermes_cli/test_update_orphan_backend_reap.py
#	tests/hermes_cli/test_update_parked_branch_guard.py
#	tests/hermes_cli/test_update_post_pull_syntax_guard.py
#	tests/hermes_cli/test_update_receipt.py
#	tests/hermes_cli/test_update_self_lock.py
#	tests/hermes_cli/test_update_shim_fail_closed.py
#	tests/hermes_cli/test_update_shim_self_lock.py
#	tests/hermes_cli/test_update_sqlite_remediation.py
#	tests/hermes_cli/test_update_stale_dashboard.py
#	tests/hermes_cli/test_update_stale_virtualenv.py
#	tests/hermes_cli/test_update_venv_health.py
#	tests/hermes_cli/test_update_venv_ownership_preflight.py
#	tests/hermes_cli/test_update_wedged_gateway.py
#	tests/hermes_cli/test_update_yes_flag.py
#	tests/hermes_cli/test_update_zip_two_phase.py
#	tests/hermes_cli/test_urllib_security.py
#	tests/hermes_cli/test_ux_messages_auth_config.py
#	tests/hermes_cli/test_ux_messages_startup.py
#	tests/hermes_cli/test_venv_holder_classifier.py
#	tests/hermes_cli/test_verify_console_scripts.py
#	tests/hermes_cli/test_verify_core_dependencies.py
#	tests/hermes_cli/test_web_server.py
#	tests/hermes_cli/test_web_server_console_ws.py
#	tests/hermes_cli/test_web_server_ws_ping.py
#	tests/hermes_cli/test_web_ui_build.py
#	tests/hermes_state/test_fts_rebuild_admission.py
#	tests/hermes_state/test_hermes_state.py
#	tests/plugins/memory/test_memory_lazy_install.py
#	tests/plugins/test_google_meet_plugin.py
#	tests/plugins/test_langfuse_plugin.py
#	tests/plugins/test_security_guidance_plugin.py
#	tests/plugins/test_transform_llm_output_hook.py
#	tests/scripts/desktop_update/test_desktop_update_windows_gateway_flag.py
#	tests/scripts/desktop_update/test_desktop_update_windows_python_handoff.py
#	tests/scripts/desktop_update/test_desktop_update_windows_timestamp.py
#	tests/scripts/install/test_install_clone_throttle_fallback.py
#	tests/scripts/install/test_install_lockfile_churn.py
#	tests/scripts/install/test_install_no_initial_commit.py
#	tests/scripts/install/test_install_sh_browser_install.py
#	tests/scripts/install/test_install_sh_node_prerelease.py
#	tests/scripts/install/test_install_sh_symlink_stomp.py
#	tests/scripts/install/test_install_sh_uv_lock_config.py
#	tests/scripts/install/test_install_unmerged_index.py
#	tests/scripts/test_contributor_map.py
#	tests/scripts/test_run_tests_parallel.py
#	tests/skills/test_competitor_news_monitor_skill.py
#	tests/skills/test_document_to_action_items_skill.py
#	tests/skills/test_google_workspace_setup.py
#	tests/skills/test_google_workspace_setup_deps.py
#	tests/skills/test_grounded_citations_skill.py
#	tests/skills/test_ip_as_logo_skill.py
#	tests/skills/test_live_dashboard_skill.py
#	tests/skills/test_mcp_oauth_remote_gateway_skill.py
#	tests/skills/test_office_document_skills.py
#	tests/skills/test_openclaw_migration.py
#	tests/skills/test_product_price_monitor_skill.py
#	tests/skills/test_scrollcraft_skill.py
#	tests/skills/test_setup_wizard_generator_skill.py
#	tests/skills/test_weekly_review_planning_skill.py
#	tests/test_engines_satisfiable.py
#	tests/test_fast_safe_load.py
#	tests/test_hermes_bootstrap.py
#	tests/test_hermes_constants.py
#	tests/test_hermes_logging.py
#	tests/test_managed_runtime_resolution.py
#	tests/test_model_tools_async_bridge.py
#	tests/test_packaging_build_guard.py
#	tests/test_packaging_metadata.py
#	tests/test_yaml_indent_consistency.py
#	tests/tools/test_approval_timeout_overflow.py
#	tests/tools/test_base_environment.py
#	tests/tools/test_bot_mode_dm.py
#	tests/tools/test_browser_chromium_check.py
#	tests/tools/test_browser_hardening.py
#	tests/tools/test_browser_homebrew_paths.py
#	tests/tools/test_browser_npx_warmup.py
#	tests/tools/test_browser_orphan_reaper.py
#	tests/tools/test_browser_real_profile.py
#	tests/tools/test_browser_use_cli.py
#	tests/tools/test_clipboard.py
#	tests/tools/test_code_execution.py
#	tests/tools/test_code_execution_modes.py
#	tests/tools/test_code_execution_windows_env.py
#	tests/tools/test_computer_use.py
#	tests/tools/test_delegate_liveness_timeout.py
#	tests/tools/test_execute_code_approval_cluster.py
#	tests/tools/test_execution_flag_detection.py
#	tests/tools/test_fal_common.py
#	tests/tools/test_file_operations.py
#	tests/tools/test_file_tools.py
#	tests/tools/test_file_tools_cwd_resolution.py
#	tests/tools/test_file_tools_live.py
#	tests/tools/test_lazy_deps.py
#	tests/tools/test_lazy_deps_durable_target.py
#	tests/tools/test_lazy_deps_managed.py
#	tests/tools/test_local_env_blocklist.py
#	tests/tools/test_local_tempdir.py
#	tests/tools/test_macos_protected_search.py
#	tests/tools/test_mcp_npx_cached_bin.py
#	tests/tools/test_oneshot_completion_linger.py
#	tests/tools/test_process_registry.py
#	tests/tools/test_read_file_schema_gating.py
#	tests/tools/test_skill_improvements.py
#	tests/tools/test_skills_sync.py
#	tests/tools/test_termux_api_detection.py
#	tests/tools/test_tirith_security.py
#	tests/tools/test_transcription_tools.py
#	tests/tools/test_tts_streaming.py
#	tests/tools/test_wake_word.py
#	tests/tui_gateway/test_compute_host_borrowed_lease.py
#	tests/tui_gateway/test_compute_host_turn_protocol.py
#	tests/tui_gateway/test_isolated_orphan_activity.py
#	tests/tui_gateway/test_protocol.py
#	tests/tui_gateway/test_slash_worker_profile_home.py
#	tests/tui_gateway/test_subprocess_encoding.py
#	tests/tui_gateway/test_tui_gateway_server.py
#	ui-tui/src/__tests__/terminalParity.test.ts
#	ui-tui/src/__tests__/termuxComposerLayout.test.ts
#	ui-tui/src/__tests__/textInputFastEcho.test.ts
2026-09-23 07:02:44 -04:00

267 lines
10 KiB
Python

"""Every Nous model list is narrowed to the org's policy before it is shown.
Four surfaces build their list from the curated manifest unioned with the
Portal's ``recommended-models`` endpoint; neither source is authenticated.
"""
from __future__ import annotations
import argparse
import pytest
import hermes_cli.models as models_mod
from hermes_cli import models_pricing
CURATED = ["vendor/allowed", "vendor/blocked"]
ALLOWED = {"vendor/allowed"}
@pytest.fixture
def policy(monkeypatch):
"""An org whose policy admits only ``vendor/allowed``."""
monkeypatch.setattr(models_pricing, "nous_policy_allowed_ids", lambda **_k: ALLOWED)
return ALLOWED
@pytest.fixture
def no_policy(monkeypatch):
"""An unrestricted org — lists must come through untouched."""
monkeypatch.setattr(models_pricing, "nous_policy_allowed_ids", lambda **_k: None)
class TestLoginNous:
def _run(self, monkeypatch, tmp_path):
import hermes_cli.auth as auth_mod
import hermes_cli.auth_nous as auth_nous
import hermes_cli.nous_subscription as ns
seen: dict = {}
monkeypatch.setenv("HERMES_HOME", str(tmp_path))
monkeypatch.setattr(
auth_mod,
"_nous_device_code_login",
lambda **_k: {
"access_token": "tok",
"agent_key": "key",
"inference_base_url": "https://inference.example.com",
"portal_base_url": "https://portal.example.com",
"refresh_token": "r",
"token_expires_at": 9999999999,
},
)
monkeypatch.setattr(
auth_nous,
"_nous_device_code_login",
lambda **_k: {
"access_token": "tok",
"agent_key": "key",
"inference_base_url": "https://inference.example.com",
"portal_base_url": "https://portal.example.com",
"refresh_token": "r",
"token_expires_at": 9999999999,
},
)
monkeypatch.setattr(models_mod, "get_curated_nous_model_ids", lambda: list(CURATED))
monkeypatch.setattr(models_pricing, "get_pricing_for_provider", lambda _p: {})
monkeypatch.setattr(models_mod, "check_nous_free_tier", lambda **_k: None)
monkeypatch.setattr(
models_mod,
"union_with_portal_paid_recommendations",
lambda ids, pricing, _portal: (list(ids), pricing),
)
monkeypatch.setattr(ns, "prompt_enable_tool_gateway", lambda _c: None)
def _capture(model_ids, **kwargs):
seen["model_ids"] = list(model_ids)
return None
monkeypatch.setattr(auth_mod, "_prompt_model_selection", _capture)
args = argparse.Namespace(
portal_url=None, inference_url=None, client_id=None, scope=None,
no_browser=True, timeout=15.0, ca_bundle=None, insecure=False,
)
auth_mod._login_nous(args, auth_mod.PROVIDER_REGISTRY["nous"])
return seen
def test_hidden_model_is_not_offered(self, monkeypatch, tmp_path, policy):
assert self._run(monkeypatch, tmp_path).get("model_ids") == ["vendor/allowed"]
def test_unrestricted_org_sees_the_full_curated_list(
self, monkeypatch, tmp_path, no_policy
):
assert self._run(monkeypatch, tmp_path).get("model_ids") == CURATED
class TestModelSwitchPicker:
"""The ``/model`` picker's nous branch (``list_authenticated_providers``)."""
def _rows(self, monkeypatch):
import hermes_cli.auth as auth_mod
import hermes_cli.model_switch as ms
monkeypatch.setattr(
auth_mod,
"_load_auth_store",
lambda *a, **k: {"providers": {"nous": {"access_token": "tok"}}},
)
monkeypatch.setattr(models_mod, "get_curated_nous_model_ids", lambda: list(CURATED))
monkeypatch.setattr(models_pricing, "get_pricing_for_provider", lambda _p: {})
monkeypatch.setattr(models_mod, "check_nous_free_tier", lambda **_k: None)
monkeypatch.setattr(
models_mod,
"union_with_portal_paid_recommendations",
lambda ids, pricing, _portal: (list(ids), pricing),
)
rows = ms.list_authenticated_providers(max_models=10)
return next((r for r in rows if r["slug"] == "nous"), None)
def test_hidden_model_is_filtered(self, monkeypatch, policy):
row = self._rows(monkeypatch)
assert row is not None, "nous row should be listed"
assert "vendor/blocked" not in row["models"]
assert "vendor/allowed" in row["models"]
def test_unrestricted_org_keeps_both(self, monkeypatch, no_policy):
row = self._rows(monkeypatch)
assert row is not None
assert set(CURATED) <= set(row["models"])
def test_filter_survives_a_failed_recommendation_fetch(self, monkeypatch, policy):
"""The filter sits outside the try wrapping the Portal union."""
def _boom(_p):
raise RuntimeError("portal down")
monkeypatch.setattr(models_pricing, "get_pricing_for_provider", _boom)
row = self._rows(monkeypatch)
assert row is not None
assert "vendor/blocked" not in row["models"]
class TestRecommendedDefaultEndpoint:
"""This endpoint picks a model the user never sees chosen."""
def _call(self, monkeypatch):
import hermes_cli.auth as auth_mod
from hermes_cli.web_routers.models import get_recommended_default_model
# Blocked first, so an unfiltered list would make it the silent
# default — otherwise this passes whether or not the filter runs.
monkeypatch.setattr(
models_mod, "get_curated_nous_model_ids",
lambda: ["vendor/blocked", "vendor/allowed"],
)
monkeypatch.setattr(models_pricing, "get_pricing_for_provider", lambda _p: {})
monkeypatch.setattr(models_mod, "check_nous_free_tier", lambda **_k: None)
monkeypatch.setattr(
models_mod,
"union_with_portal_paid_recommendations",
lambda ids, pricing, _portal: (list(ids), pricing),
)
monkeypatch.setattr(auth_mod, "get_provider_auth_state", lambda _p: {})
return get_recommended_default_model(provider="nous")
def test_hidden_model_is_never_the_silent_default(self, monkeypatch, policy):
assert self._call(monkeypatch)["model"] == "vendor/allowed"
def test_unrestricted_org_is_unaffected(self, monkeypatch, no_policy):
assert self._call(monkeypatch)["model"] == "vendor/blocked"
class TestAuxiliaryFastModel:
"""``_fast_model_from_catalog`` uses the catalog's keys as a source of ids."""
def _pick(self, monkeypatch, *, catalog):
import agent.auxiliary_client as aux
seen: dict = {}
def _fake_fetch(*, api_key=None, base_url="", timeout=8.0, **_k):
seen["api_key"] = api_key
return {mid: {} for mid in catalog}
monkeypatch.setattr(
models_pricing, "_resolve_nous_pricing_credentials",
lambda: ("sk-nous", "https://inference.example.com"),
)
monkeypatch.setattr(models_pricing, "fetch_models_with_pricing", _fake_fetch)
picked = aux._fast_model_from_catalog("nous")
return picked, seen
def test_hidden_model_is_not_selected(self, monkeypatch, policy):
import agent.auxiliary_client as aux
monkeypatch.setattr(
models_pricing, "nous_policy_allowed_ids", lambda **_k: {"vendor/allowed"}
)
monkeypatch.setattr(aux, "_FAST_MODEL_FAMILIES", ("vendor/",))
monkeypatch.setattr(aux, "_FAST_MODEL_EXCLUDE", ())
picked, _ = self._pick(
monkeypatch, catalog=["vendor/blocked", "vendor/allowed"]
)
assert picked == "vendor/allowed"
class TestNousPrefetch:
"""The nous disk-cache entry is write-only, so prefetching it is a round
trip for nothing."""
class TestPolicyNoticeIsShown:
def test_login_prints_it(self, monkeypatch, tmp_path, policy, capsys):
import hermes_cli.nous_account as account_mod
monkeypatch.setattr(account_mod, "nous_policy_present", lambda: True)
TestLoginNous()._run(monkeypatch, tmp_path)
assert account_mod.nous_policy_notice(removed=True) in capsys.readouterr().out
class TestAuxFallbackRespectsPolicy:
"""Steps 2-4 of the aux ladder are policy-blind: `resolve_aux_model` queries
a public recommendation and the rest are hardcoded."""
def _patch(self, monkeypatch, *, allowed, recommended):
import agent.auxiliary_client as aux
import providers
monkeypatch.setattr(models_pricing, "nous_policy_allowed_ids", lambda **_k: allowed)
monkeypatch.setattr(
models_pricing, "_resolve_nous_pricing_credentials",
lambda: ("sk", "https://inference.example.com"),
)
# No fast-family match, so the catalog step yields nothing.
monkeypatch.setattr(
models_pricing, "fetch_models_with_pricing",
lambda **_k: {"vendor/allowed-large": {}},
)
class _Profile:
default_aux_model = ""
def resolve_aux_model(self, **_k):
return recommended
monkeypatch.setattr(providers, "get_provider_profile", lambda _p: _Profile())
return aux
def test_blocked_recommendation_is_not_used(self, monkeypatch):
aux = self._patch(
monkeypatch, allowed={"vendor/allowed-large"},
recommended="vendor/blocked-haiku",
)
assert aux._get_aux_model_for_provider("nous", prefer_fast=True) == ""
def test_allowed_recommendation_still_used(self, monkeypatch):
aux = self._patch(
monkeypatch, allowed={"vendor/allowed-large", "vendor/ok-haiku"},
recommended="vendor/ok-haiku",
)
assert (
aux._get_aux_model_for_provider("nous", prefer_fast=True)
== "vendor/ok-haiku"
)
def test_ungoverned_org_is_unaffected(self, monkeypatch):
aux = self._patch(
monkeypatch, allowed=None, recommended="vendor/anything"
)
assert (
aux._get_aux_model_for_provider("nous", prefer_fast=True)
== "vendor/anything"
)