v2.4.1 (#475)
Co-authored-by: Quentin Torroba <quentin.torroba@mistral.ai> Co-authored-by: Clement Sirieix <clem.sirieix@gmail.com> Co-authored-by: Kim-Adeline Miguel <kimadeline.miguel@mistral.ai> Co-authored-by: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
parent
dd372ce494
commit
e9428bce23
54 changed files with 877 additions and 362 deletions
|
|
@ -28,7 +28,7 @@ class TestACPInitialize:
|
|||
session_capabilities=SessionCapabilities(list=SessionListCapabilities()),
|
||||
)
|
||||
assert response.agent_info == Implementation(
|
||||
name="@mistralai/mistral-vibe", title="Mistral Vibe", version="2.4.0"
|
||||
name="@mistralai/mistral-vibe", title="Mistral Vibe", version="2.4.1"
|
||||
)
|
||||
|
||||
assert response.auth_methods == []
|
||||
|
|
@ -52,7 +52,7 @@ class TestACPInitialize:
|
|||
session_capabilities=SessionCapabilities(list=SessionListCapabilities()),
|
||||
)
|
||||
assert response.agent_info == Implementation(
|
||||
name="@mistralai/mistral-vibe", title="Mistral Vibe", version="2.4.0"
|
||||
name="@mistralai/mistral-vibe", title="Mistral Vibe", version="2.4.1"
|
||||
)
|
||||
|
||||
assert response.auth_methods is not None
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from vibe.acp.utils import get_proxy_help_text
|
||||
from vibe.core.paths.global_paths import GLOBAL_ENV_FILE
|
||||
from vibe.core.paths import GLOBAL_ENV_FILE
|
||||
from vibe.core.proxy_setup import SUPPORTED_PROXY_VARS
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -23,9 +23,11 @@ from vibe.core.config import (
|
|||
SessionLoggingConfig,
|
||||
VibeConfig,
|
||||
)
|
||||
from vibe.core.config.harness_files import (
|
||||
init_harness_files_manager,
|
||||
reset_harness_files_manager,
|
||||
)
|
||||
from vibe.core.llm.types import BackendLike
|
||||
from vibe.core.paths import global_paths
|
||||
from vibe.core.paths.config_paths import unlock_config_paths
|
||||
|
||||
|
||||
def get_base_config() -> dict[str, Any]:
|
||||
|
|
@ -69,13 +71,16 @@ def config_dir(
|
|||
config_file = config_dir / "config.toml"
|
||||
config_file.write_text(tomli_w.dumps(get_base_config()), encoding="utf-8")
|
||||
|
||||
monkeypatch.setattr(global_paths, "_DEFAULT_VIBE_HOME", config_dir)
|
||||
monkeypatch.setattr("vibe.core.paths._vibe_home._DEFAULT_VIBE_HOME", config_dir)
|
||||
return config_dir
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def _unlock_config_paths():
|
||||
unlock_config_paths()
|
||||
def _init_harness_files_manager():
|
||||
reset_harness_files_manager()
|
||||
init_harness_files_manager("user", "project")
|
||||
yield
|
||||
reset_harness_files_manager()
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
|
|
|
|||
|
|
@ -1,184 +1,334 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
from unittest.mock import patch
|
||||
|
||||
from vibe.core.paths.config_paths import (
|
||||
discover_local_agents_dirs,
|
||||
discover_local_skills_dirs,
|
||||
discover_local_tools_dirs,
|
||||
)
|
||||
import pytest
|
||||
|
||||
from vibe.core.config.harness_files import HarnessFilesManager
|
||||
from vibe.core.trusted_folders import trusted_folders_manager
|
||||
|
||||
|
||||
class TestDiscoverLocalSkillsDirs:
|
||||
def test_returns_empty_list_when_dir_not_trusted(self, tmp_path: Path) -> None:
|
||||
(tmp_path / ".vibe" / "skills").mkdir(parents=True)
|
||||
with patch("vibe.core.paths.config_paths.trusted_folders_manager") as mock_tfm:
|
||||
mock_tfm.is_trusted.return_value = False
|
||||
assert discover_local_skills_dirs(tmp_path) == []
|
||||
|
||||
def test_returns_empty_list_when_trusted_but_no_skills_dirs(
|
||||
self, tmp_path: Path
|
||||
class TestTrustedWorkdir:
|
||||
def test_returns_none_when_project_not_in_sources(
|
||||
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
with patch("vibe.core.paths.config_paths.trusted_folders_manager") as mock_tfm:
|
||||
mock_tfm.is_trusted.return_value = True
|
||||
assert discover_local_skills_dirs(tmp_path) == []
|
||||
monkeypatch.chdir(tmp_path)
|
||||
mgr = HarnessFilesManager(sources=("user",))
|
||||
assert mgr.trusted_workdir is None
|
||||
|
||||
def test_returns_vibe_skills_only_when_only_it_exists(self, tmp_path: Path) -> None:
|
||||
def test_returns_none_when_not_trusted(
|
||||
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
monkeypatch.chdir(tmp_path)
|
||||
monkeypatch.setattr(trusted_folders_manager, "is_trusted", lambda _: False)
|
||||
mgr = HarnessFilesManager(sources=("user", "project"))
|
||||
assert mgr.trusted_workdir is None
|
||||
|
||||
def test_returns_cwd_when_project_in_sources_and_trusted(
|
||||
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
monkeypatch.chdir(tmp_path)
|
||||
monkeypatch.setattr(trusted_folders_manager, "is_trusted", lambda _: True)
|
||||
mgr = HarnessFilesManager(sources=("user", "project"))
|
||||
assert mgr.trusted_workdir == tmp_path
|
||||
|
||||
|
||||
class TestProjectToolsDirs:
|
||||
def test_returns_empty_when_project_not_in_sources(
|
||||
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
monkeypatch.chdir(tmp_path)
|
||||
mgr = HarnessFilesManager(sources=("user",))
|
||||
assert mgr.project_tools_dirs == []
|
||||
|
||||
def test_returns_empty_when_not_trusted(
|
||||
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
monkeypatch.chdir(tmp_path)
|
||||
monkeypatch.setattr(trusted_folders_manager, "is_trusted", lambda _: False)
|
||||
(tmp_path / ".vibe" / "tools").mkdir(parents=True)
|
||||
mgr = HarnessFilesManager(sources=("user", "project"))
|
||||
assert mgr.project_tools_dirs == []
|
||||
|
||||
def test_returns_empty_when_tools_dir_does_not_exist(
|
||||
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
monkeypatch.chdir(tmp_path)
|
||||
monkeypatch.setattr(trusted_folders_manager, "is_trusted", lambda _: True)
|
||||
mgr = HarnessFilesManager(sources=("user", "project"))
|
||||
assert mgr.project_tools_dirs == []
|
||||
|
||||
def test_returns_path_when_tools_dir_exists_and_trusted(
|
||||
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
monkeypatch.chdir(tmp_path)
|
||||
monkeypatch.setattr(trusted_folders_manager, "is_trusted", lambda _: True)
|
||||
tools_dir = tmp_path / ".vibe" / "tools"
|
||||
tools_dir.mkdir(parents=True)
|
||||
mgr = HarnessFilesManager(sources=("user", "project"))
|
||||
assert mgr.project_tools_dirs == [tools_dir]
|
||||
|
||||
def test_ignores_tools_when_file_not_dir(
|
||||
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
monkeypatch.chdir(tmp_path)
|
||||
monkeypatch.setattr(trusted_folders_manager, "is_trusted", lambda _: True)
|
||||
(tmp_path / ".vibe").mkdir()
|
||||
(tmp_path / ".vibe" / "tools").write_text("", encoding="utf-8")
|
||||
mgr = HarnessFilesManager(sources=("user", "project"))
|
||||
assert mgr.project_tools_dirs == []
|
||||
|
||||
def test_finds_tools_dirs_recursively(
|
||||
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
monkeypatch.chdir(tmp_path)
|
||||
monkeypatch.setattr(trusted_folders_manager, "is_trusted", lambda _: True)
|
||||
(tmp_path / ".vibe" / "tools").mkdir(parents=True)
|
||||
(tmp_path / "sub" / ".vibe" / "tools").mkdir(parents=True)
|
||||
mgr = HarnessFilesManager(sources=("user", "project"))
|
||||
assert mgr.project_tools_dirs == [
|
||||
tmp_path / ".vibe" / "tools",
|
||||
tmp_path / "sub" / ".vibe" / "tools",
|
||||
]
|
||||
|
||||
def test_does_not_descend_into_ignored_dirs(
|
||||
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
monkeypatch.chdir(tmp_path)
|
||||
monkeypatch.setattr(trusted_folders_manager, "is_trusted", lambda _: True)
|
||||
(tmp_path / ".vibe" / "tools").mkdir(parents=True)
|
||||
(tmp_path / ".git" / ".vibe" / "tools").mkdir(parents=True)
|
||||
mgr = HarnessFilesManager(sources=("user", "project"))
|
||||
assert mgr.project_tools_dirs == [tmp_path / ".vibe" / "tools"]
|
||||
|
||||
|
||||
class TestProjectAgentsDirs:
|
||||
def test_returns_empty_when_project_not_in_sources(
|
||||
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
monkeypatch.chdir(tmp_path)
|
||||
mgr = HarnessFilesManager(sources=("user",))
|
||||
assert mgr.project_agents_dirs == []
|
||||
|
||||
def test_returns_empty_when_not_trusted(
|
||||
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
monkeypatch.chdir(tmp_path)
|
||||
monkeypatch.setattr(trusted_folders_manager, "is_trusted", lambda _: False)
|
||||
(tmp_path / ".vibe" / "agents").mkdir(parents=True)
|
||||
mgr = HarnessFilesManager(sources=("user", "project"))
|
||||
assert mgr.project_agents_dirs == []
|
||||
|
||||
def test_returns_empty_when_agents_dir_does_not_exist(
|
||||
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
monkeypatch.chdir(tmp_path)
|
||||
monkeypatch.setattr(trusted_folders_manager, "is_trusted", lambda _: True)
|
||||
mgr = HarnessFilesManager(sources=("user", "project"))
|
||||
assert mgr.project_agents_dirs == []
|
||||
|
||||
def test_returns_path_when_agents_dir_exists_and_trusted(
|
||||
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
monkeypatch.chdir(tmp_path)
|
||||
monkeypatch.setattr(trusted_folders_manager, "is_trusted", lambda _: True)
|
||||
agents_dir = tmp_path / ".vibe" / "agents"
|
||||
agents_dir.mkdir(parents=True)
|
||||
mgr = HarnessFilesManager(sources=("user", "project"))
|
||||
assert mgr.project_agents_dirs == [agents_dir]
|
||||
|
||||
def test_ignores_agents_when_file_not_dir(
|
||||
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
monkeypatch.chdir(tmp_path)
|
||||
monkeypatch.setattr(trusted_folders_manager, "is_trusted", lambda _: True)
|
||||
(tmp_path / ".vibe").mkdir()
|
||||
(tmp_path / ".vibe" / "agents").write_text("", encoding="utf-8")
|
||||
mgr = HarnessFilesManager(sources=("user", "project"))
|
||||
assert mgr.project_agents_dirs == []
|
||||
|
||||
def test_finds_agents_dirs_recursively(
|
||||
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
monkeypatch.chdir(tmp_path)
|
||||
monkeypatch.setattr(trusted_folders_manager, "is_trusted", lambda _: True)
|
||||
(tmp_path / ".vibe" / "agents").mkdir(parents=True)
|
||||
(tmp_path / "sub" / "deep" / ".vibe" / "agents").mkdir(parents=True)
|
||||
mgr = HarnessFilesManager(sources=("user", "project"))
|
||||
assert mgr.project_agents_dirs == [
|
||||
tmp_path / ".vibe" / "agents",
|
||||
tmp_path / "sub" / "deep" / ".vibe" / "agents",
|
||||
]
|
||||
|
||||
def test_does_not_descend_into_ignored_dirs(
|
||||
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
monkeypatch.chdir(tmp_path)
|
||||
monkeypatch.setattr(trusted_folders_manager, "is_trusted", lambda _: True)
|
||||
(tmp_path / ".vibe" / "agents").mkdir(parents=True)
|
||||
(tmp_path / "__pycache__" / ".vibe" / "agents").mkdir(parents=True)
|
||||
mgr = HarnessFilesManager(sources=("user", "project"))
|
||||
assert mgr.project_agents_dirs == [tmp_path / ".vibe" / "agents"]
|
||||
|
||||
|
||||
class TestUserToolsDirs:
|
||||
def test_returns_empty_when_user_not_in_sources(self) -> None:
|
||||
mgr = HarnessFilesManager(sources=("project",))
|
||||
assert mgr.user_tools_dirs == []
|
||||
|
||||
def test_returns_empty_when_dir_does_not_exist(
|
||||
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
monkeypatch.setattr("vibe.core.paths._vibe_home._DEFAULT_VIBE_HOME", tmp_path)
|
||||
mgr = HarnessFilesManager(sources=("user",))
|
||||
assert mgr.user_tools_dirs == []
|
||||
|
||||
def test_returns_path_when_user_in_sources_and_dir_exists(
|
||||
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
monkeypatch.setattr("vibe.core.paths._vibe_home._DEFAULT_VIBE_HOME", tmp_path)
|
||||
tools_dir = tmp_path / "tools"
|
||||
tools_dir.mkdir()
|
||||
mgr = HarnessFilesManager(sources=("user",))
|
||||
assert mgr.user_tools_dirs == [tools_dir]
|
||||
|
||||
|
||||
class TestUserSkillsDirs:
|
||||
def test_returns_empty_when_user_not_in_sources(self) -> None:
|
||||
mgr = HarnessFilesManager(sources=("project",))
|
||||
assert mgr.user_skills_dirs == []
|
||||
|
||||
def test_returns_empty_when_dir_does_not_exist(
|
||||
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
monkeypatch.setattr("vibe.core.paths._vibe_home._DEFAULT_VIBE_HOME", tmp_path)
|
||||
mgr = HarnessFilesManager(sources=("user",))
|
||||
assert mgr.user_skills_dirs == []
|
||||
|
||||
def test_returns_path_when_user_in_sources_and_dir_exists(
|
||||
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
monkeypatch.setattr("vibe.core.paths._vibe_home._DEFAULT_VIBE_HOME", tmp_path)
|
||||
skills_dir = tmp_path / "skills"
|
||||
skills_dir.mkdir()
|
||||
mgr = HarnessFilesManager(sources=("user",))
|
||||
assert mgr.user_skills_dirs == [skills_dir]
|
||||
|
||||
|
||||
class TestUserAgentsDirs:
|
||||
def test_returns_empty_when_user_not_in_sources(self) -> None:
|
||||
mgr = HarnessFilesManager(sources=("project",))
|
||||
assert mgr.user_agents_dirs == []
|
||||
|
||||
def test_returns_empty_when_dir_does_not_exist(
|
||||
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
monkeypatch.setattr("vibe.core.paths._vibe_home._DEFAULT_VIBE_HOME", tmp_path)
|
||||
mgr = HarnessFilesManager(sources=("user",))
|
||||
assert mgr.user_agents_dirs == []
|
||||
|
||||
def test_returns_path_when_user_in_sources_and_dir_exists(
|
||||
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
monkeypatch.setattr("vibe.core.paths._vibe_home._DEFAULT_VIBE_HOME", tmp_path)
|
||||
agents_dir = tmp_path / "agents"
|
||||
agents_dir.mkdir()
|
||||
mgr = HarnessFilesManager(sources=("user",))
|
||||
assert mgr.user_agents_dirs == [agents_dir]
|
||||
|
||||
|
||||
class TestProjectSkillsDirs:
|
||||
def test_returns_empty_list_when_no_skills_dirs(
|
||||
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
monkeypatch.chdir(tmp_path)
|
||||
monkeypatch.setattr(trusted_folders_manager, "is_trusted", lambda _: True)
|
||||
mgr = HarnessFilesManager(sources=("user", "project"))
|
||||
assert mgr.project_skills_dirs == []
|
||||
|
||||
def test_returns_vibe_skills_only_when_only_it_exists(
|
||||
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
monkeypatch.chdir(tmp_path)
|
||||
monkeypatch.setattr(trusted_folders_manager, "is_trusted", lambda _: True)
|
||||
vibe_skills = tmp_path / ".vibe" / "skills"
|
||||
vibe_skills.mkdir(parents=True)
|
||||
with patch("vibe.core.paths.config_paths.trusted_folders_manager") as mock_tfm:
|
||||
mock_tfm.is_trusted.return_value = True
|
||||
result = discover_local_skills_dirs(tmp_path)
|
||||
assert result == [vibe_skills]
|
||||
mgr = HarnessFilesManager(sources=("user", "project"))
|
||||
assert mgr.project_skills_dirs == [vibe_skills]
|
||||
|
||||
def test_returns_agents_skills_only_when_only_it_exists(
|
||||
self, tmp_path: Path
|
||||
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
monkeypatch.chdir(tmp_path)
|
||||
monkeypatch.setattr(trusted_folders_manager, "is_trusted", lambda _: True)
|
||||
agents_skills = tmp_path / ".agents" / "skills"
|
||||
agents_skills.mkdir(parents=True)
|
||||
with patch("vibe.core.paths.config_paths.trusted_folders_manager") as mock_tfm:
|
||||
mock_tfm.is_trusted.return_value = True
|
||||
result = discover_local_skills_dirs(tmp_path)
|
||||
assert result == [agents_skills]
|
||||
mgr = HarnessFilesManager(sources=("user", "project"))
|
||||
assert mgr.project_skills_dirs == [agents_skills]
|
||||
|
||||
def test_returns_both_in_order_when_both_exist(self, tmp_path: Path) -> None:
|
||||
def test_returns_both_in_order_when_both_exist(
|
||||
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
monkeypatch.chdir(tmp_path)
|
||||
monkeypatch.setattr(trusted_folders_manager, "is_trusted", lambda _: True)
|
||||
vibe_skills = tmp_path / ".vibe" / "skills"
|
||||
agents_skills = tmp_path / ".agents" / "skills"
|
||||
vibe_skills.mkdir(parents=True)
|
||||
agents_skills.mkdir(parents=True)
|
||||
with patch("vibe.core.paths.config_paths.trusted_folders_manager") as mock_tfm:
|
||||
mock_tfm.is_trusted.return_value = True
|
||||
result = discover_local_skills_dirs(tmp_path)
|
||||
assert result == [vibe_skills, agents_skills]
|
||||
mgr = HarnessFilesManager(sources=("user", "project"))
|
||||
assert mgr.project_skills_dirs == [vibe_skills, agents_skills]
|
||||
|
||||
def test_ignores_vibe_skills_when_file_not_dir(self, tmp_path: Path) -> None:
|
||||
def test_ignores_vibe_skills_when_file_not_dir(
|
||||
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
monkeypatch.chdir(tmp_path)
|
||||
monkeypatch.setattr(trusted_folders_manager, "is_trusted", lambda _: True)
|
||||
(tmp_path / ".vibe").mkdir()
|
||||
(tmp_path / ".vibe" / "skills").write_text("", encoding="utf-8")
|
||||
with patch("vibe.core.paths.config_paths.trusted_folders_manager") as mock_tfm:
|
||||
mock_tfm.is_trusted.return_value = True
|
||||
result = discover_local_skills_dirs(tmp_path)
|
||||
assert result == []
|
||||
mgr = HarnessFilesManager(sources=("user", "project"))
|
||||
assert mgr.project_skills_dirs == []
|
||||
|
||||
def test_returns_empty_when_project_not_in_sources(
|
||||
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
monkeypatch.chdir(tmp_path)
|
||||
monkeypatch.setattr(trusted_folders_manager, "is_trusted", lambda _: True)
|
||||
vibe_skills = tmp_path / ".vibe" / "skills"
|
||||
vibe_skills.mkdir(parents=True)
|
||||
mgr = HarnessFilesManager(sources=("user",))
|
||||
assert mgr.project_skills_dirs == []
|
||||
|
||||
def test_returns_empty_when_not_trusted(
|
||||
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
monkeypatch.chdir(tmp_path)
|
||||
monkeypatch.setattr(trusted_folders_manager, "is_trusted", lambda _: False)
|
||||
vibe_skills = tmp_path / ".vibe" / "skills"
|
||||
vibe_skills.mkdir(parents=True)
|
||||
mgr = HarnessFilesManager(sources=("user", "project"))
|
||||
assert mgr.project_skills_dirs == []
|
||||
|
||||
def test_finds_skills_dirs_recursively_in_trusted_folder(
|
||||
self, tmp_path: Path
|
||||
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
monkeypatch.chdir(tmp_path)
|
||||
monkeypatch.setattr(trusted_folders_manager, "is_trusted", lambda _: True)
|
||||
(tmp_path / ".vibe" / "skills").mkdir(parents=True)
|
||||
(tmp_path / "sub" / ".agents" / "skills").mkdir(parents=True)
|
||||
(tmp_path / "sub" / "deep" / ".vibe" / "skills").mkdir(parents=True)
|
||||
with patch("vibe.core.paths.config_paths.trusted_folders_manager") as mock_tfm:
|
||||
mock_tfm.is_trusted.return_value = True
|
||||
result = discover_local_skills_dirs(tmp_path)
|
||||
assert result == [
|
||||
mgr = HarnessFilesManager(sources=("user", "project"))
|
||||
assert mgr.project_skills_dirs == [
|
||||
tmp_path / ".vibe" / "skills",
|
||||
tmp_path / "sub" / ".agents" / "skills",
|
||||
tmp_path / "sub" / "deep" / ".vibe" / "skills",
|
||||
]
|
||||
|
||||
def test_does_not_descend_into_ignored_dirs(self, tmp_path: Path) -> None:
|
||||
def test_does_not_descend_into_ignored_dirs(
|
||||
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
monkeypatch.chdir(tmp_path)
|
||||
monkeypatch.setattr(trusted_folders_manager, "is_trusted", lambda _: True)
|
||||
(tmp_path / ".vibe" / "skills").mkdir(parents=True)
|
||||
(tmp_path / "node_modules" / ".vibe" / "skills").mkdir(parents=True)
|
||||
with patch("vibe.core.paths.config_paths.trusted_folders_manager") as mock_tfm:
|
||||
mock_tfm.is_trusted.return_value = True
|
||||
result = discover_local_skills_dirs(tmp_path)
|
||||
assert result == [tmp_path / ".vibe" / "skills"]
|
||||
|
||||
|
||||
class TestDiscoverLocalToolsDirs:
|
||||
def test_returns_empty_list_when_dir_not_trusted(self, tmp_path: Path) -> None:
|
||||
(tmp_path / ".vibe" / "tools").mkdir(parents=True)
|
||||
with patch("vibe.core.paths.config_paths.trusted_folders_manager") as mock_tfm:
|
||||
mock_tfm.is_trusted.return_value = False
|
||||
assert discover_local_tools_dirs(tmp_path) == []
|
||||
|
||||
def test_returns_empty_list_when_trusted_but_no_tools_dir(
|
||||
self, tmp_path: Path
|
||||
) -> None:
|
||||
with patch("vibe.core.paths.config_paths.trusted_folders_manager") as mock_tfm:
|
||||
mock_tfm.is_trusted.return_value = True
|
||||
assert discover_local_tools_dirs(tmp_path) == []
|
||||
|
||||
def test_returns_tools_dir_when_exists(self, tmp_path: Path) -> None:
|
||||
vibe_tools = tmp_path / ".vibe" / "tools"
|
||||
vibe_tools.mkdir(parents=True)
|
||||
with patch("vibe.core.paths.config_paths.trusted_folders_manager") as mock_tfm:
|
||||
mock_tfm.is_trusted.return_value = True
|
||||
result = discover_local_tools_dirs(tmp_path)
|
||||
assert result == [vibe_tools]
|
||||
|
||||
def test_ignores_tools_when_file_not_dir(self, tmp_path: Path) -> None:
|
||||
(tmp_path / ".vibe").mkdir()
|
||||
(tmp_path / ".vibe" / "tools").write_text("", encoding="utf-8")
|
||||
with patch("vibe.core.paths.config_paths.trusted_folders_manager") as mock_tfm:
|
||||
mock_tfm.is_trusted.return_value = True
|
||||
result = discover_local_tools_dirs(tmp_path)
|
||||
assert result == []
|
||||
|
||||
def test_finds_tools_dirs_recursively(self, tmp_path: Path) -> None:
|
||||
(tmp_path / ".vibe" / "tools").mkdir(parents=True)
|
||||
(tmp_path / "sub" / ".vibe" / "tools").mkdir(parents=True)
|
||||
with patch("vibe.core.paths.config_paths.trusted_folders_manager") as mock_tfm:
|
||||
mock_tfm.is_trusted.return_value = True
|
||||
result = discover_local_tools_dirs(tmp_path)
|
||||
assert result == [
|
||||
tmp_path / ".vibe" / "tools",
|
||||
tmp_path / "sub" / ".vibe" / "tools",
|
||||
]
|
||||
|
||||
def test_does_not_descend_into_ignored_dirs(self, tmp_path: Path) -> None:
|
||||
(tmp_path / ".vibe" / "tools").mkdir(parents=True)
|
||||
(tmp_path / ".git" / ".vibe" / "tools").mkdir(parents=True)
|
||||
with patch("vibe.core.paths.config_paths.trusted_folders_manager") as mock_tfm:
|
||||
mock_tfm.is_trusted.return_value = True
|
||||
result = discover_local_tools_dirs(tmp_path)
|
||||
assert result == [tmp_path / ".vibe" / "tools"]
|
||||
|
||||
|
||||
class TestDiscoverLocalAgentsDirs:
|
||||
def test_returns_empty_list_when_dir_not_trusted(self, tmp_path: Path) -> None:
|
||||
(tmp_path / ".vibe" / "agents").mkdir(parents=True)
|
||||
with patch("vibe.core.paths.config_paths.trusted_folders_manager") as mock_tfm:
|
||||
mock_tfm.is_trusted.return_value = False
|
||||
assert discover_local_agents_dirs(tmp_path) == []
|
||||
|
||||
def test_returns_empty_list_when_trusted_but_no_agents_dir(
|
||||
self, tmp_path: Path
|
||||
) -> None:
|
||||
with patch("vibe.core.paths.config_paths.trusted_folders_manager") as mock_tfm:
|
||||
mock_tfm.is_trusted.return_value = True
|
||||
assert discover_local_agents_dirs(tmp_path) == []
|
||||
|
||||
def test_returns_agents_dir_when_exists(self, tmp_path: Path) -> None:
|
||||
vibe_agents = tmp_path / ".vibe" / "agents"
|
||||
vibe_agents.mkdir(parents=True)
|
||||
with patch("vibe.core.paths.config_paths.trusted_folders_manager") as mock_tfm:
|
||||
mock_tfm.is_trusted.return_value = True
|
||||
result = discover_local_agents_dirs(tmp_path)
|
||||
assert result == [vibe_agents]
|
||||
|
||||
def test_ignores_agents_when_file_not_dir(self, tmp_path: Path) -> None:
|
||||
(tmp_path / ".vibe").mkdir()
|
||||
(tmp_path / ".vibe" / "agents").write_text("", encoding="utf-8")
|
||||
with patch("vibe.core.paths.config_paths.trusted_folders_manager") as mock_tfm:
|
||||
mock_tfm.is_trusted.return_value = True
|
||||
result = discover_local_agents_dirs(tmp_path)
|
||||
assert result == []
|
||||
|
||||
def test_finds_agents_dirs_recursively(self, tmp_path: Path) -> None:
|
||||
(tmp_path / ".vibe" / "agents").mkdir(parents=True)
|
||||
(tmp_path / "sub" / "deep" / ".vibe" / "agents").mkdir(parents=True)
|
||||
with patch("vibe.core.paths.config_paths.trusted_folders_manager") as mock_tfm:
|
||||
mock_tfm.is_trusted.return_value = True
|
||||
result = discover_local_agents_dirs(tmp_path)
|
||||
assert result == [
|
||||
tmp_path / ".vibe" / "agents",
|
||||
tmp_path / "sub" / "deep" / ".vibe" / "agents",
|
||||
]
|
||||
|
||||
def test_does_not_descend_into_ignored_dirs(self, tmp_path: Path) -> None:
|
||||
(tmp_path / ".vibe" / "agents").mkdir(parents=True)
|
||||
(tmp_path / "__pycache__" / ".vibe" / "agents").mkdir(parents=True)
|
||||
with patch("vibe.core.paths.config_paths.trusted_folders_manager") as mock_tfm:
|
||||
mock_tfm.is_trusted.return_value = True
|
||||
result = discover_local_agents_dirs(tmp_path)
|
||||
assert result == [tmp_path / ".vibe" / "agents"]
|
||||
mgr = HarnessFilesManager(sources=("user", "project"))
|
||||
assert mgr.project_skills_dirs == [tmp_path / ".vibe" / "skills"]
|
||||
|
|
|
|||
|
|
@ -4,8 +4,12 @@ from pathlib import Path
|
|||
|
||||
import pytest
|
||||
|
||||
from vibe.core.paths.config_paths import CONFIG_FILE
|
||||
from vibe.core.paths.global_paths import GLOBAL_CONFIG_FILE, VIBE_HOME
|
||||
from vibe.core.config.harness_files import (
|
||||
HarnessFilesManager,
|
||||
init_harness_files_manager,
|
||||
reset_harness_files_manager,
|
||||
)
|
||||
from vibe.core.paths import VIBE_HOME
|
||||
from vibe.core.trusted_folders import trusted_folders_manager
|
||||
|
||||
|
||||
|
|
@ -21,11 +25,18 @@ class TestResolveConfigFile:
|
|||
|
||||
monkeypatch.setattr(trusted_folders_manager, "is_trusted", lambda _: True)
|
||||
|
||||
assert CONFIG_FILE.path == local_config
|
||||
assert CONFIG_FILE.path.is_file()
|
||||
assert CONFIG_FILE.path.read_text(encoding="utf-8") == 'active_model = "test"'
|
||||
reset_harness_files_manager()
|
||||
init_harness_files_manager("user", "project")
|
||||
from vibe.core.config.harness_files import get_harness_files_manager
|
||||
|
||||
def test_resolves_local_config_when_exists_and_folder_is_not_trusted(
|
||||
mgr = get_harness_files_manager()
|
||||
resolved = mgr.config_file
|
||||
assert resolved is not None
|
||||
assert resolved == local_config
|
||||
assert resolved.is_file()
|
||||
assert resolved.read_text(encoding="utf-8") == 'active_model = "test"'
|
||||
|
||||
def test_resolves_global_config_when_folder_is_not_trusted(
|
||||
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
monkeypatch.chdir(tmp_path)
|
||||
|
|
@ -34,7 +45,12 @@ class TestResolveConfigFile:
|
|||
local_config = local_config_dir / "config.toml"
|
||||
local_config.write_text('active_model = "test"', encoding="utf-8")
|
||||
|
||||
assert CONFIG_FILE.path == GLOBAL_CONFIG_FILE.path
|
||||
reset_harness_files_manager()
|
||||
init_harness_files_manager("user", "project")
|
||||
from vibe.core.config.harness_files import get_harness_files_manager
|
||||
|
||||
mgr = get_harness_files_manager()
|
||||
assert mgr.config_file == VIBE_HOME.path / "config.toml"
|
||||
|
||||
def test_falls_back_to_global_config_when_local_missing(
|
||||
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
|
|
@ -43,7 +59,12 @@ class TestResolveConfigFile:
|
|||
# Ensure no local config exists
|
||||
assert not (tmp_path / ".vibe" / "config.toml").exists()
|
||||
|
||||
assert CONFIG_FILE.path == GLOBAL_CONFIG_FILE.path
|
||||
reset_harness_files_manager()
|
||||
init_harness_files_manager("user", "project")
|
||||
from vibe.core.config.harness_files import get_harness_files_manager
|
||||
|
||||
mgr = get_harness_files_manager()
|
||||
assert mgr.config_file == VIBE_HOME.path / "config.toml"
|
||||
|
||||
def test_respects_vibe_home_env_var(
|
||||
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
|
|
@ -51,3 +72,11 @@ class TestResolveConfigFile:
|
|||
assert VIBE_HOME.path != tmp_path
|
||||
monkeypatch.setenv("VIBE_HOME", str(tmp_path))
|
||||
assert VIBE_HOME.path == tmp_path
|
||||
|
||||
def test_returns_none_when_no_sources(self) -> None:
|
||||
mgr = HarnessFilesManager(sources=())
|
||||
assert mgr.config_file is None
|
||||
|
||||
def test_user_only_returns_global_config(self) -> None:
|
||||
mgr = HarnessFilesManager(sources=("user",))
|
||||
assert mgr.config_file == VIBE_HOME.path / "config.toml"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from vibe.core.paths.global_paths import PLANS_DIR
|
||||
from vibe.core.paths import PLANS_DIR
|
||||
from vibe.core.plan_session import PlanSession
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ from __future__ import annotations
|
|||
|
||||
import pytest
|
||||
|
||||
from vibe.core.paths.global_paths import GLOBAL_ENV_FILE
|
||||
from vibe.core.paths import GLOBAL_ENV_FILE
|
||||
from vibe.core.proxy_setup import (
|
||||
SUPPORTED_PROXY_VARS,
|
||||
ProxySetupError,
|
||||
|
|
|
|||
|
|
@ -7,9 +7,8 @@ from unittest.mock import patch
|
|||
import pytest
|
||||
import tomli_w
|
||||
|
||||
from vibe.core.paths.global_paths import TRUSTED_FOLDERS_FILE
|
||||
from vibe.core.paths import AGENTS_MD_FILENAMES, TRUSTED_FOLDERS_FILE
|
||||
from vibe.core.trusted_folders import (
|
||||
AGENTS_MD_FILENAMES,
|
||||
TrustedFoldersManager,
|
||||
has_agents_md_file,
|
||||
has_trustable_content,
|
||||
|
|
|
|||
19
tests/core/test_utils.py
Normal file
19
tests/core/test_utils.py
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from vibe.core.utils import get_server_url_from_api_base
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("api_base", "expected"),
|
||||
[
|
||||
("https://api.mistral.ai/v1", "https://api.mistral.ai"),
|
||||
("https://on-prem.example.com/v1", "https://on-prem.example.com"),
|
||||
("http://localhost:8080/v2", "http://localhost:8080"),
|
||||
("not-a-url", None),
|
||||
("ftp://example.com/v1", None),
|
||||
],
|
||||
)
|
||||
def test_get_server_url_from_api_base(api_base, expected):
|
||||
assert get_server_url_from_api_base(api_base) == expected
|
||||
|
|
@ -14,10 +14,10 @@ from unittest.mock import patch
|
|||
|
||||
from pydantic import ValidationError
|
||||
|
||||
from vibe.core.paths.config_paths import unlock_config_paths
|
||||
from vibe.core.config.harness_files import init_harness_files_manager
|
||||
|
||||
if __name__ == "__main__":
|
||||
unlock_config_paths()
|
||||
init_harness_files_manager("user", "project")
|
||||
|
||||
from tests import TESTS_ROOT
|
||||
from tests.mock.utils import MOCK_DATA_ENV_VAR
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import pytest
|
|||
from textual.pilot import Pilot
|
||||
from textual.widgets import Input
|
||||
|
||||
from vibe.core.paths.global_paths import GLOBAL_ENV_FILE
|
||||
from vibe.core.paths import GLOBAL_ENV_FILE
|
||||
from vibe.setup.onboarding import OnboardingApp
|
||||
from vibe.setup.onboarding.screens.api_key import ApiKeyScreen
|
||||
|
||||
|
|
|
|||
|
|
@ -16,8 +16,7 @@ from vibe.core.agents.models import (
|
|||
_deep_merge,
|
||||
)
|
||||
from vibe.core.config import VibeConfig
|
||||
from vibe.core.paths.config_paths import ConfigPath
|
||||
from vibe.core.paths.global_paths import GlobalPath
|
||||
from vibe.core.config.harness_files import HarnessFilesManager
|
||||
from vibe.core.tools.base import ToolPermission
|
||||
from vibe.core.types import LLMChunk, LLMMessage, LLMUsage, Role
|
||||
|
||||
|
|
@ -176,11 +175,18 @@ class TestAgentApplyToConfig:
|
|||
global_prompts.mkdir(parents=True)
|
||||
(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.config.PROMPTS_DIR", ConfigPath(lambda: project_prompts)
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
"vibe.core.config.GLOBAL_PROMPTS_DIR", GlobalPath(lambda: global_prompts)
|
||||
"vibe.core.config._settings.get_harness_files_manager", lambda: mock_manager
|
||||
)
|
||||
|
||||
base = VibeConfig(include_project_context=False, include_prompt_detail=False)
|
||||
|
|
@ -555,11 +561,18 @@ class TestAgentLoopInitialization:
|
|||
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.config.PROMPTS_DIR", ConfigPath(lambda: project_prompts)
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
"vibe.core.config.GLOBAL_PROMPTS_DIR", GlobalPath(lambda: global_prompts)
|
||||
"vibe.core.config._settings.get_harness_files_manager", lambda: mock_manager
|
||||
)
|
||||
|
||||
custom_agent = AgentProfile(
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from unittest.mock import AsyncMock, patch
|
||||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import mistralai
|
||||
import pytest
|
||||
|
||||
from tests.mock.utils import collect_result
|
||||
from vibe.core.tools.base import BaseToolState, ToolError
|
||||
from vibe.core.config import Backend, ProviderConfig
|
||||
from vibe.core.tools.base import BaseToolState, InvokeContext, ToolError
|
||||
from vibe.core.tools.builtins.websearch import WebSearch, WebSearchArgs, WebSearchConfig
|
||||
|
||||
|
||||
|
|
@ -151,6 +152,61 @@ async def test_run_sdk_error_wrapped(websearch):
|
|||
await collect_result(websearch.run(WebSearchArgs(query="test")))
|
||||
|
||||
|
||||
def test_resolve_server_url_no_ctx(websearch):
|
||||
assert websearch._resolve_server_url(None) is None
|
||||
|
||||
|
||||
def test_resolve_server_url_no_agent_manager(websearch):
|
||||
ctx = InvokeContext(tool_call_id="t1", agent_manager=None)
|
||||
assert websearch._resolve_server_url(ctx) is None
|
||||
|
||||
|
||||
def test_resolve_server_url_with_mistral_provider(websearch):
|
||||
config = MagicMock()
|
||||
config.providers = [
|
||||
ProviderConfig(
|
||||
name="mistral",
|
||||
api_base="https://on-prem.example.com/v1",
|
||||
api_key_env_var="MISTRAL_API_KEY",
|
||||
backend=Backend.MISTRAL,
|
||||
)
|
||||
]
|
||||
agent_manager = MagicMock()
|
||||
agent_manager.config = config
|
||||
|
||||
ctx = InvokeContext(tool_call_id="t1", agent_manager=agent_manager)
|
||||
assert websearch._resolve_server_url(ctx) == "https://on-prem.example.com"
|
||||
|
||||
|
||||
def test_resolve_server_url_with_default_provider(websearch):
|
||||
config = MagicMock()
|
||||
config.providers = [
|
||||
ProviderConfig(
|
||||
name="mistral",
|
||||
api_base="https://api.mistral.ai/v1",
|
||||
api_key_env_var="MISTRAL_API_KEY",
|
||||
backend=Backend.MISTRAL,
|
||||
)
|
||||
]
|
||||
agent_manager = MagicMock()
|
||||
agent_manager.config = config
|
||||
|
||||
ctx = InvokeContext(tool_call_id="t1", agent_manager=agent_manager)
|
||||
assert websearch._resolve_server_url(ctx) == "https://api.mistral.ai"
|
||||
|
||||
|
||||
def test_resolve_server_url_no_mistral_provider(websearch):
|
||||
config = MagicMock()
|
||||
config.providers = [
|
||||
ProviderConfig(name="llamacpp", api_base="http://127.0.0.1:8080/v1")
|
||||
]
|
||||
agent_manager = MagicMock()
|
||||
agent_manager.config = config
|
||||
|
||||
ctx = InvokeContext(tool_call_id="t1", agent_manager=agent_manager)
|
||||
assert websearch._resolve_server_url(ctx) is None
|
||||
|
||||
|
||||
def test_is_available_with_key(monkeypatch):
|
||||
monkeypatch.setenv("MISTRAL_API_KEY", "key")
|
||||
assert WebSearch.is_available() is True
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue