cc-slim/tests/test_dream.py
2026-04-15 16:01:14 +08:00

141 lines
4.9 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from __future__ import annotations
import io
import sys
from pathlib import Path
import pytest
from rich.console import Console
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
from cc_slim.commands import handle_command
from cc_slim.engine import Agent, Config
from cc_slim.memory import MemoryStore
from cc_slim.mode import ModeState
from cc_slim.permissions import PermissionChecker
from cc_slim.session import SessionStore
from cc_slim.tools import build_default_tools
def make_workspace(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> tuple[Path, MemoryStore]:
home = tmp_path / "home"
home.mkdir()
monkeypatch.setattr("cc_slim.memory.Path.home", lambda: home)
monkeypatch.setattr("cc_slim.session.Path.home", lambda: home)
workspace = tmp_path / "workspace"
workspace.mkdir()
(workspace / "AGENTS.md").write_text("# Workspace Rules\nworkspace-agents\n", encoding="utf-8")
skills = workspace / "SKILLS"
skills.mkdir()
(skills / "a.md").write_text("skill-a\n", encoding="utf-8")
memory = MemoryStore(workspace)
return workspace, memory
def make_agent(monkeypatch: pytest.MonkeyPatch, workspace: Path) -> Agent:
monkeypatch.setattr(Agent, "_build_client", lambda self: object())
config = Config(provider="openai", model="test-model", api_key="key", base_url=None)
permissions = PermissionChecker(workspace)
return Agent(config=config, tools=build_default_tools(workspace), workspace=workspace, permission_checker=permissions)
def test_dream_command_is_routed(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None:
workspace, memory = make_workspace(monkeypatch, tmp_path)
output = io.StringIO()
console = Console(file=output, force_terminal=False, color_system=None)
class DummyAgent:
def __init__(self) -> None:
self.called = False
def dream(self, store: MemoryStore) -> str:
self.called = True
assert store is memory
return "已完成 dreammemory 已更新"
agent = DummyAgent()
result = handle_command(
"/dream",
console=console,
root=workspace,
config=type("ConfigObj", (), {"model": "test-model"})(),
store=SessionStore(workspace),
memory=memory,
mode=ModeState(),
permissions=PermissionChecker(workspace),
agent=agent, # type: ignore[arg-type]
build_agent=lambda *args, **kwargs: agent,
render_history=lambda store: None,
)
assert agent.called is True
assert result is agent
assert "已完成 dreammemory 已更新" in output.getvalue()
def test_agent_dream_updates_memory_and_refreshes_prompt(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None:
workspace, memory = make_workspace(monkeypatch, tmp_path)
agent = make_agent(monkeypatch, workspace)
agent.history = [{"role": "user", "content": "请记住这个项目运行在 Windows 上"}]
original_prompt = agent.system_prompt
monkeypatch.setattr(
agent,
"_run_dream_model",
lambda current_memory, session_text: """## Constraints
- 项目默认运行在 Windows 上
## Consolidated Facts
- 需要优先考虑 PowerShell 兼容性
""",
)
result = agent.dream(memory)
sections = memory.read_sections()
assert result == "已完成 dreammemory 已更新"
assert sections["Constraints"] == "- 项目默认运行在 Windows 上"
assert sections["Consolidated Facts"] == "- 需要优先考虑 PowerShell 兼容性"
assert agent.system_prompt != original_prompt
assert "项目默认运行在 Windows 上" in agent.system_prompt
def test_dream_does_not_modify_workspace_agents(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None:
workspace, memory = make_workspace(monkeypatch, tmp_path)
agent = make_agent(monkeypatch, workspace)
agent.history = [{"role": "user", "content": "记住这个项目使用 uv run"}]
agents_before = (workspace / "AGENTS.md").read_text(encoding="utf-8")
monkeypatch.setattr(
agent,
"_run_dream_model",
lambda current_memory, session_text: """## Project Memory
- 使用 uv run 执行命令
""",
)
agent.dream(memory)
assert (workspace / "AGENTS.md").read_text(encoding="utf-8") == agents_before
def test_system_prompt_layers_remain_in_order(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None:
workspace, memory = make_workspace(monkeypatch, tmp_path)
memory.apply_dream(
"""## Project Memory
- project-memory-marker
"""
)
agent = make_agent(monkeypatch, workspace)
prompt = agent.system_prompt
system_index = prompt.index("# cc-slim System")
runtime_index = prompt.index("## 运行环境")
agents_index = prompt.index("workspace-agents")
skills_index = prompt.index("skill-a")
memory_index = prompt.index("# Memory")
assert system_index < runtime_index < agents_index < skills_index < memory_index