v2.11.1 (#721)
Co-authored-by: Clément Drouin <clement.drouin@mistral.ai> Co-authored-by: Clément Sirieix <clement.sirieix@mistral.ai> Co-authored-by: Guillaume LE GOFF <guillaume.lgf@gmail.com> Co-authored-by: Mert Unsal <mertunsal1905@gmail.com> Co-authored-by: Michel Thomazo <51709227+michelTho@users.noreply.github.com> Co-authored-by: Quentin <quentin.torroba@mistral.ai> Co-authored-by: Val <102326092+vdeva@users.noreply.github.com> Co-authored-by: Vincent G <10739306+VinceOPS@users.noreply.github.com> Co-authored-by: maximevoisin-pm <maxime.voisin@mistral.ai> Co-authored-by: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
parent
adb1ca74ce
commit
cf3f4ca58f
143 changed files with 3457 additions and 1351 deletions
|
|
@ -19,7 +19,7 @@ from vibe.core.agents.models import (
|
|||
_deep_merge,
|
||||
)
|
||||
from vibe.core.config import VibeConfig
|
||||
from vibe.core.config.harness_files import HarnessFilesManager
|
||||
from vibe.core.prompts import UtilityPrompt
|
||||
from vibe.core.tools.base import ToolPermission
|
||||
from vibe.core.types import LLMChunk, LLMMessage, LLMUsage, Role
|
||||
|
||||
|
|
@ -233,35 +233,11 @@ class TestAgentApplyToConfig:
|
|||
assert "ask_user_question" in result.enabled_tools
|
||||
|
||||
def test_custom_prompt_found_in_global_when_missing_from_project(
|
||||
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
self, mock_prompts_dirs: tuple[Path, Path]
|
||||
) -> None:
|
||||
"""Regression test for https://github.com/mistralai/mistral-vibe/issues/288
|
||||
|
||||
When a custom prompt .md file is absent from the project-local prompts
|
||||
directory, the system_prompt property should fall back to the global
|
||||
~/.vibe/prompts/ directory and load the file from there.
|
||||
"""
|
||||
project_prompts = tmp_path / "project" / ".vibe" / "prompts"
|
||||
project_prompts.mkdir(parents=True)
|
||||
|
||||
global_prompts = tmp_path / "home" / ".vibe" / "prompts"
|
||||
global_prompts.mkdir(parents=True)
|
||||
_, global_prompts = mock_prompts_dirs
|
||||
(global_prompts / "cc.md").write_text("Global custom prompt")
|
||||
|
||||
class _MockManager(HarnessFilesManager):
|
||||
@property
|
||||
def project_prompts_dirs(self) -> list[Path]:
|
||||
return [project_prompts]
|
||||
|
||||
@property
|
||||
def user_prompts_dirs(self) -> list[Path]:
|
||||
return [global_prompts]
|
||||
|
||||
mock_manager = _MockManager(sources=("user",))
|
||||
monkeypatch.setattr(
|
||||
"vibe.core.prompts.get_harness_files_manager", lambda: mock_manager
|
||||
)
|
||||
|
||||
base = VibeConfig(include_project_context=False, include_prompt_detail=False)
|
||||
agent = AgentProfile(
|
||||
name="cc",
|
||||
|
|
@ -275,7 +251,7 @@ class TestAgentApplyToConfig:
|
|||
assert result.system_prompt == "Global custom prompt"
|
||||
|
||||
def test_custom_prompt_overrides_builtin(
|
||||
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
self, mock_prompts_dirs: tuple[Path, Path]
|
||||
) -> None:
|
||||
"""Custom prompts in .vibe/prompts/ should override built-in prompts.
|
||||
|
||||
|
|
@ -283,24 +259,9 @@ class TestAgentApplyToConfig:
|
|||
project or user prompts directory must take priority over the
|
||||
bundled SystemPrompt enum.
|
||||
"""
|
||||
project_prompts = tmp_path / "project" / ".vibe" / "prompts"
|
||||
project_prompts.mkdir(parents=True)
|
||||
project_prompts, _ = mock_prompts_dirs
|
||||
(project_prompts / "explore.md").write_text("My custom explore prompt")
|
||||
|
||||
class _MockManager(HarnessFilesManager):
|
||||
@property
|
||||
def project_prompts_dirs(self) -> list[Path]:
|
||||
return [project_prompts]
|
||||
|
||||
@property
|
||||
def user_prompts_dirs(self) -> list[Path]:
|
||||
return []
|
||||
|
||||
mock_manager = _MockManager(sources=("user",))
|
||||
monkeypatch.setattr(
|
||||
"vibe.core.prompts.get_harness_files_manager", lambda: mock_manager
|
||||
)
|
||||
|
||||
config = VibeConfig(
|
||||
system_prompt_id="explore",
|
||||
include_project_context=False,
|
||||
|
|
@ -308,6 +269,71 @@ class TestAgentApplyToConfig:
|
|||
)
|
||||
assert config.system_prompt == "My custom explore prompt"
|
||||
|
||||
def test_custom_compaction_prompt_found_in_global_when_missing_from_project(
|
||||
self, mock_prompts_dirs: tuple[Path, Path]
|
||||
) -> None:
|
||||
_, global_prompts = mock_prompts_dirs
|
||||
(global_prompts / "proofs.md").write_text("Global custom compaction prompt")
|
||||
|
||||
config = VibeConfig(
|
||||
compaction_prompt_id="proofs",
|
||||
include_project_context=False,
|
||||
include_prompt_detail=False,
|
||||
)
|
||||
assert config.compaction_prompt == "Global custom compaction prompt"
|
||||
|
||||
def test_custom_compaction_prompt_overrides_builtin(
|
||||
self, mock_prompts_dirs: tuple[Path, Path]
|
||||
) -> None:
|
||||
project_prompts, _ = mock_prompts_dirs
|
||||
(project_prompts / "compact.md").write_text("My custom compact prompt")
|
||||
|
||||
config = VibeConfig(
|
||||
compaction_prompt_id="compact",
|
||||
include_project_context=False,
|
||||
include_prompt_detail=False,
|
||||
)
|
||||
assert config.compaction_prompt == "My custom compact prompt"
|
||||
|
||||
def test_default_compaction_prompt_falls_back_to_builtin(
|
||||
self, mock_prompts_dirs: tuple[Path, Path]
|
||||
) -> None:
|
||||
config = VibeConfig(include_project_context=False, include_prompt_detail=False)
|
||||
assert config.compaction_prompt == UtilityPrompt.COMPACT.read()
|
||||
|
||||
def test_invalid_compaction_prompt_reports_setting_name(
|
||||
self, mock_prompts_dirs: tuple[Path, Path]
|
||||
) -> None:
|
||||
project_prompts, user_prompts = mock_prompts_dirs
|
||||
(project_prompts / "alpha.md").write_text("a")
|
||||
(user_prompts / "beta.md").write_text("b")
|
||||
|
||||
with pytest.raises(ValueError) as exc_info:
|
||||
VibeConfig(
|
||||
compaction_prompt_id="unknown",
|
||||
include_project_context=False,
|
||||
include_prompt_detail=False,
|
||||
)
|
||||
|
||||
error_text = str(exc_info.value)
|
||||
assert "Invalid compaction_prompt_id value: 'unknown'" in error_text
|
||||
assert 'available prompts ("compact")' in error_text
|
||||
assert '(available: "alpha", "beta")' in error_text
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"malicious_id",
|
||||
["../../../etc/passwd", "..", ".", "subdir/compact", "back\\slash", ""],
|
||||
)
|
||||
def test_prompt_id_rejects_path_traversal(
|
||||
self, mock_prompts_dirs: tuple[Path, Path], malicious_id: str
|
||||
) -> None:
|
||||
with pytest.raises(ValueError, match="must be a bare filename"):
|
||||
VibeConfig(
|
||||
compaction_prompt_id=malicious_id,
|
||||
include_project_context=False,
|
||||
include_prompt_detail=False,
|
||||
)
|
||||
|
||||
|
||||
class TestAgentProfileOverrides:
|
||||
def test_default_agent_disables_exit_plan_mode(self) -> None:
|
||||
|
|
@ -679,30 +705,12 @@ class TestAgentManagerFiltering:
|
|||
|
||||
class TestAgentLoopInitialization:
|
||||
def test_agent_system_prompt_id_is_applied_on_init(
|
||||
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
self, mock_prompts_dirs: tuple[Path, Path], monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
project_prompts = tmp_path / "project" / ".vibe" / "prompts"
|
||||
project_prompts.mkdir(parents=True)
|
||||
|
||||
global_prompts = tmp_path / "home" / ".vibe" / "prompts"
|
||||
global_prompts.mkdir(parents=True)
|
||||
_, global_prompts = mock_prompts_dirs
|
||||
custom_prompt_content = "CUSTOM_AGENT_PROMPT_MARKER"
|
||||
(global_prompts / "custom_agent.md").write_text(custom_prompt_content)
|
||||
|
||||
class _MockManager(HarnessFilesManager):
|
||||
@property
|
||||
def project_prompts_dirs(self) -> list[Path]:
|
||||
return [project_prompts]
|
||||
|
||||
@property
|
||||
def user_prompts_dirs(self) -> list[Path]:
|
||||
return [global_prompts]
|
||||
|
||||
mock_manager = _MockManager(sources=("user",))
|
||||
monkeypatch.setattr(
|
||||
"vibe.core.prompts.get_harness_files_manager", lambda: mock_manager
|
||||
)
|
||||
|
||||
custom_agent = AgentProfile(
|
||||
name="custom_test_agent",
|
||||
display_name="Custom Test",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue