Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/utils/advisor.py
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ def decide_advisor_mode(
*,
force_client_mode: bool = False,
advisor_provider: str | None = None,
advisor_enabled: bool = True,
advisor_enabled: bool = False,
) -> str:
"""Pick activation mode for the upcoming turn.

Expand Down Expand Up @@ -422,9 +422,9 @@ def decide_advisor_mode(

``advisor_enabled`` is the master switch (settings ``advisor_enabled``,
default False in production): when False the advisor is INACTIVE regardless
of model/provider. The parameter defaults True so direct callers (the
activation truth-table tests) keep their behavior; production call sites pass
``get_settings().advisor_enabled``.
of model/provider. The parameter deliberately defaults False so callers must
explicitly opt in, just like users do through ``advisor_enabled`` in config
or the ``/advisor`` command.
"""
if not advisor_enabled:
return ADVISOR_MODE_INACTIVE
Expand Down
15 changes: 15 additions & 0 deletions tests/test_advisor_client_side.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,16 @@ def test_inactive_when_env_disabled(self) -> None:
)
self.assertEqual(mode, ADVISOR_MODE_INACTIVE)

def test_inactive_by_default_even_when_fully_configured(self) -> None:
"""The decision helper itself must be opt-in, not only its callers."""
mode = decide_advisor_mode(
self._first_party_provider(),
"claude-opus-4-6",
"claude-opus-4-6",
advisor_provider="anthropic",
)
self.assertEqual(mode, ADVISOR_MODE_INACTIVE)

def test_server_side_for_1p_with_valid_models(self) -> None:
# Server-side now requires advisor_provider == "anthropic" too.
with patch(
Expand All @@ -79,6 +89,7 @@ def test_server_side_for_1p_with_valid_models(self) -> None:
"claude-opus-4-6",
"claude-opus-4-6",
advisor_provider="anthropic",
advisor_enabled=True,
)
self.assertEqual(mode, ADVISOR_MODE_SERVER_SIDE)

Expand All @@ -93,6 +104,7 @@ def test_client_side_when_1p_with_force_client(self) -> None:
"claude-opus-4-6",
force_client_mode=True,
advisor_provider="anthropic",
advisor_enabled=True,
)
self.assertEqual(mode, ADVISOR_MODE_CLIENT_SIDE)

Expand All @@ -108,6 +120,7 @@ def test_client_side_for_1p_with_unsupported_base_model(self) -> None:
"claude-opus-4-5",
"claude-opus-4-6",
advisor_provider="anthropic",
advisor_enabled=True,
)
self.assertEqual(mode, ADVISOR_MODE_CLIENT_SIDE)

Expand All @@ -123,6 +136,7 @@ def test_client_side_for_3p_provider(self) -> None:
"gpt-5.4",
"claude-opus-4-6",
advisor_provider="anthropic",
advisor_enabled=True,
)
self.assertEqual(mode, ADVISOR_MODE_CLIENT_SIDE)

Expand All @@ -139,6 +153,7 @@ def test_client_side_cross_provider(self) -> None:
"claude-opus-4-6",
"gemini-2.5-pro",
advisor_provider="gemini",
advisor_enabled=True,
)
self.assertEqual(mode, ADVISOR_MODE_CLIENT_SIDE)

Expand Down
Loading