2.0.0
Co-Authored-By: Quentin Torroba <quentin.torroba@mistral.ai> Co-Authored-By: Michel Thomazo <michel.thomazo@mistral.ai> Co-Authored-By: Clément Drouin <clement.drouin@mistral.ai> Co-Authored-By: Vincent Guilloux <vincent.guilloux@mistral.ai> Co-Authored-By: Clément Siriex <clement.sirieix@mistral.ai> Co-Authored-By: Kim-Adeline Miguel <kimadeline.miguel@mistral.ai> Co-Authored-By: Thaddee Tyl <thaddee.tyl@gmail.com> Co-Authored-By: David Brochart <david.brochart@gmail.com> Co-Authored-By: Joseph Guhlin <joseph.guhlin@gmail.com> Co-Authored-By: Thomas Kenbeek <thomaskenbeek@gmail.com> Co-Authored-By: Remenby31 <baptiste.cruvellier31@gmail.com>
This commit is contained in:
parent
79f215d91c
commit
d33db9fff8
217 changed files with 16911 additions and 4305 deletions
|
|
@ -61,7 +61,7 @@ def make_controller(
|
|||
("/exit", "Exit application"),
|
||||
("/vim", "Toggle vim keybindings"),
|
||||
]
|
||||
completer = CommandCompleter(commands)
|
||||
completer = CommandCompleter(lambda: commands)
|
||||
view = StubView()
|
||||
controller = SlashCommandController(completer, view)
|
||||
|
||||
|
|
@ -162,3 +162,74 @@ def test_on_key_enter_submits_selected_completion() -> None:
|
|||
assert result is CompletionResult.SUBMIT
|
||||
assert view.replacements == [Replacement(0, 2, "/compact")]
|
||||
assert view.reset_count == 1
|
||||
|
||||
|
||||
def test_callable_entries_updates_completions_dynamically() -> None:
|
||||
"""Test that CommandCompleter with a callable updates entries when the callable returns different values.
|
||||
|
||||
This simulates config reload where available skills change.
|
||||
"""
|
||||
available_skills: list[tuple[str, str]] = []
|
||||
|
||||
def get_entries() -> list[tuple[str, str]]:
|
||||
base_commands = [("/help", "Display help"), ("/config", "Show configuration")]
|
||||
return base_commands + available_skills
|
||||
|
||||
completer = CommandCompleter(get_entries)
|
||||
view = StubView()
|
||||
controller = SlashCommandController(completer, view)
|
||||
|
||||
# Initially, only base commands are available
|
||||
controller.on_text_changed("/", cursor_index=1)
|
||||
suggestions, _ = view.suggestion_events[-1]
|
||||
assert [s.alias for s in suggestions] == ["/help", "/config"]
|
||||
|
||||
# Simulate config reload: add a skill
|
||||
available_skills.append(("/summarize", "Summarize the conversation"))
|
||||
|
||||
# Now completions should include the new skill
|
||||
controller.on_text_changed("/", cursor_index=1)
|
||||
suggestions, _ = view.suggestion_events[-1]
|
||||
assert [s.alias for s in suggestions] == ["/help", "/config", "/summarize"]
|
||||
|
||||
# And searching for "/s" should find the new skill
|
||||
controller.on_text_changed("/s", cursor_index=2)
|
||||
suggestions, _ = view.suggestion_events[-1]
|
||||
assert [s.alias for s in suggestions] == ["/summarize"]
|
||||
assert suggestions[0].description == "Summarize the conversation"
|
||||
|
||||
|
||||
def test_callable_entries_reflects_enabled_disabled_skills() -> None:
|
||||
"""Test that skill enable/disable changes are reflected in completions.
|
||||
|
||||
This simulates the scenario where a user changes enabled_skills in config
|
||||
and runs /reload.
|
||||
"""
|
||||
enabled_skills: set[str] = {"commit", "review"}
|
||||
|
||||
all_skills = [
|
||||
("/commit", "Create a git commit"),
|
||||
("/review", "Review code changes"),
|
||||
("/deploy", "Deploy to production"),
|
||||
]
|
||||
|
||||
def get_entries() -> list[tuple[str, str]]:
|
||||
return [(name, desc) for name, desc in all_skills if name[1:] in enabled_skills]
|
||||
|
||||
completer = CommandCompleter(get_entries)
|
||||
view = StubView()
|
||||
controller = SlashCommandController(completer, view)
|
||||
|
||||
# Initially only commit and review are enabled
|
||||
controller.on_text_changed("/", cursor_index=1)
|
||||
suggestions, _ = view.suggestion_events[-1]
|
||||
assert [s.alias for s in suggestions] == ["/commit", "/review"]
|
||||
|
||||
# Simulate config reload: enable deploy, disable commit
|
||||
enabled_skills.discard("commit")
|
||||
enabled_skills.add("deploy")
|
||||
|
||||
# Now completions should reflect the change
|
||||
controller.on_text_changed("/", cursor_index=1)
|
||||
suggestions, _ = view.suggestion_events[-1]
|
||||
assert [s.alias for s in suggestions] == ["/review", "/deploy"]
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ from textual.widgets import Markdown
|
|||
from vibe.cli.textual_ui.app import VibeApp
|
||||
from vibe.cli.textual_ui.widgets.chat_input.completion_popup import CompletionPopup
|
||||
from vibe.cli.textual_ui.widgets.chat_input.container import ChatInputContainer
|
||||
from vibe.core.agent_loop import AgentLoop
|
||||
from vibe.core.config import SessionLoggingConfig, VibeConfig
|
||||
|
||||
|
||||
|
|
@ -20,7 +21,8 @@ def vibe_config() -> VibeConfig:
|
|||
|
||||
@pytest.fixture
|
||||
def vibe_app(vibe_config: VibeConfig) -> VibeApp:
|
||||
return VibeApp(config=vibe_config)
|
||||
agent_loop = AgentLoop(vibe_config)
|
||||
return VibeApp(agent_loop=agent_loop)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
|
@ -60,7 +62,7 @@ async def test_pressing_tab_writes_selected_command_and_keeps_popup_visible(
|
|||
await pilot.press(*"/co")
|
||||
await pilot.press("tab")
|
||||
|
||||
assert chat_input.value == "/config"
|
||||
assert chat_input.value == "/compact"
|
||||
assert popup.styles.display == "block"
|
||||
|
||||
|
||||
|
|
@ -88,11 +90,11 @@ async def test_arrow_navigation_updates_selected_suggestion(vibe_app: VibeApp) -
|
|||
|
||||
await pilot.press(*"/c")
|
||||
|
||||
ensure_selected_command(popup, "/config")
|
||||
await pilot.press("down")
|
||||
ensure_selected_command(popup, "/clear")
|
||||
await pilot.press("down")
|
||||
ensure_selected_command(popup, "/compact")
|
||||
await pilot.press("up")
|
||||
ensure_selected_command(popup, "/config")
|
||||
ensure_selected_command(popup, "/clear")
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
|
@ -102,11 +104,11 @@ async def test_arrow_navigation_cycles_through_suggestions(vibe_app: VibeApp) ->
|
|||
|
||||
await pilot.press(*"/co")
|
||||
|
||||
ensure_selected_command(popup, "/config")
|
||||
await pilot.press("down")
|
||||
ensure_selected_command(popup, "/compact")
|
||||
await pilot.press("up")
|
||||
await pilot.press("down")
|
||||
ensure_selected_command(popup, "/config")
|
||||
await pilot.press("up")
|
||||
ensure_selected_command(popup, "/compact")
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue