Files
EvoScientist-Multi/tests/test_new_command.py
T
jfilipiuk 3cda9894c7 feat: agent-teams part C - expert selection UX (depends on part B) (#371)
* feat: bias main-agent delegation toward configurable.active_teams

* feat: add /experts and /expert TUI commands for expert-skill summoning

* feat: align expert-selection wording with WebUI (invite/dismiss)

* chore: clear active_teams on /new, cleanup active_team.py comment

* fix: use local append_to_system_message in ActiveTeamMiddleware

* fix: prevent configurable_extra from overriding thread_id

* fix: cache expert-skill lookup for /expert completions

* fix: suppress /expert completions past first arg and on exact match

* fix: invalidate /expert completion cache on skill install/uninstall

* fix: refuse /expert invites for non-dispatchable expert skills

* fix: fire /expert cache invalidation on every install_skill / uninstall_skill path

* fix: propagate active_teams to Rich CLI and serve dispatch surfaces

* fix: keep invited experts across channel shutdown

* fix: match /expert completions case-insensitively
2026-08-07 17:07:01 +01:00

88 lines
3.3 KiB
Python

"""Tests for the /new command."""
from unittest.mock import AsyncMock, MagicMock
class TestNewCommand:
async def test_execute_calls_start_new_session(self):
from EvoScientist.commands.base import CommandContext
from EvoScientist.commands.implementation.session import NewCommand
ui = MagicMock()
ui.start_new_session = AsyncMock()
ctx = CommandContext(
agent=None,
thread_id="old-tid",
ui=ui,
workspace_dir="/old/ws",
)
await NewCommand().execute(ctx, [])
ui.start_new_session.assert_awaited_once()
def test_requires_agent_false(self):
from EvoScientist.commands.implementation.session import NewCommand
assert NewCommand().requires_agent is False
async def test_no_agent_access(self):
"""Command body must not touch ctx.agent (it's still loading)."""
from EvoScientist.commands.base import CommandContext
from EvoScientist.commands.implementation.session import NewCommand
ui = MagicMock()
ui.start_new_session = AsyncMock()
ctx = CommandContext(agent=None, thread_id="tid", ui=ui)
# No AttributeError even though ctx.agent is None
await NewCommand().execute(ctx, [])
async def test_clears_invited_experts_and_announces(self):
"""/new dismisses invited experts uniformly with channel-shutdown clear."""
from EvoScientist.commands.base import ChannelRuntime, CommandContext
from EvoScientist.commands.implementation.session import NewCommand
ui = MagicMock()
ui.start_new_session = AsyncMock()
runtime = ChannelRuntime()
runtime.active_teams = ["idea-brainstorm"]
ctx = CommandContext(
agent=None,
thread_id="tid",
ui=ui,
channel_runtime=runtime,
)
await NewCommand().execute(ctx, [])
assert runtime.active_teams == []
messages = [call.args[0] for call in ui.append_system.call_args_list]
assert any(
"Dismissed experts on new session: idea-brainstorm" in msg
for msg in messages
)
async def test_no_announcement_when_no_experts_invited(self):
"""No noise on ``/new`` when the invite list is already empty."""
from EvoScientist.commands.base import ChannelRuntime, CommandContext
from EvoScientist.commands.implementation.session import NewCommand
ui = MagicMock()
ui.start_new_session = AsyncMock()
runtime = ChannelRuntime()
ctx = CommandContext(
agent=None,
thread_id="tid",
ui=ui,
channel_runtime=runtime,
)
await NewCommand().execute(ctx, [])
ui.append_system.assert_not_called()
async def test_no_announcement_without_channel_runtime(self):
"""Runs cleanly when no ChannelRuntime is attached."""
from EvoScientist.commands.base import CommandContext
from EvoScientist.commands.implementation.session import NewCommand
ui = MagicMock()
ui.start_new_session = AsyncMock()
ctx = CommandContext(agent=None, thread_id="tid", ui=ui, channel_runtime=None)
await NewCommand().execute(ctx, [])
ui.append_system.assert_not_called()