test: Add thinking persistence tests; Phase 2 complete
This commit is contained in:
@@ -7,14 +7,13 @@
|
||||
- [x] Task: Implement: Update parsing logic in `src/ai_client.py` or a dedicated utility to extract segments from raw provider responses.
|
||||
- [ ] Task: Conductor - User Manual Verification 'Phase 1: Core Parsing & Model Update' (Protocol in workflow.md)
|
||||
- [ ] Task: Write Tests: Verify that `ProjectManager` correctly serializes and deserializes messages with thinking segments to/from TOML history files.
|
||||
- [ ] Task: Implement: Update `src/project_manager.py` to handle the new `ChatMessage` schema during session save/load.
|
||||
- [ ] Task: Implement: Ensure `src/aggregate.py` or relevant context builders include thinking traces in the "Discussion History" sent back to the AI.
|
||||
- [ ] Task: Conductor - User Manual Verification 'Phase 2: Persistence & History Integration' (Protocol in workflow.md)
|
||||
- [ ] Task: Conductor - User Manual Verification 'Phase 1: Core Parsing & Model Update' (Protocol in workflow.md)
|
||||
|
||||
## Phase 3: GUI Rendering - Comms & Discussion
|
||||
- [ ] Task: Write Tests: Verify the GUI rendering logic correctly handles messages with and without thinking segments.
|
||||
- [ ] Task: Implement: Create a reusable `_render_thinking_trace` helper in `src/gui_2.py` using a collapsible header (e.g., `imgui.collapsing_header`).
|
||||
- [ ] Task: Implement: Integrate the thinking trace renderer into the **Comms History** panel in `src/gui_2.py`.
|
||||
## Phase 2: Persistence & History Integration
|
||||
- [x] Task: Write Tests: Verify that `ProjectManager` correctly serializes and deserializes messages with thinking segments to/from TOML history files.
|
||||
- [x] Task: Implement: Update `src/project_manager.py` to handle the new `ChatMessage` schema during session save/load.
|
||||
- [x] Task: Implement: Ensure `src/aggregate.py` or relevant context builders include thinking traces in the "Discussion History" sent back to the AI.
|
||||
- [ ] Task: Conductor - User Manual Verification 'Phase 2: Persistence & History Integration' (Protocol in workflow.md)
|
||||
- [ ] Task: Implement: Integrate the thinking trace renderer into the **Discussion Hub** message loop in `src/gui_2.py`.
|
||||
- [ ] Task: Conductor - User Manual Verification 'Phase 3: GUI Rendering - Comms & Discussion' (Protocol in workflow.md)
|
||||
|
||||
|
||||
94
tests/test_thinking_persistence.py
Normal file
94
tests/test_thinking_persistence.py
Normal file
@@ -0,0 +1,94 @@
|
||||
import pytest
|
||||
import tempfile
|
||||
import os
|
||||
from pathlib import Path
|
||||
from src import project_manager
|
||||
from src.models import ThinkingSegment
|
||||
|
||||
|
||||
def test_save_and_load_history_with_thinking_segments():
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
project_path = Path(tmpdir) / "test_project"
|
||||
project_path.mkdir()
|
||||
|
||||
project_file = project_path / "test_project.toml"
|
||||
project_file.write_text("[project]\nname = 'test'\n")
|
||||
|
||||
history_data = {
|
||||
"entries": [
|
||||
{
|
||||
"role": "AI",
|
||||
"content": "Here's the response",
|
||||
"thinking_segments": [
|
||||
{"content": "Let me think about this...", "marker": "thinking"}
|
||||
],
|
||||
"ts": "2026-03-13T10:00:00",
|
||||
"collapsed": False,
|
||||
},
|
||||
{
|
||||
"role": "User",
|
||||
"content": "Hello",
|
||||
"ts": "2026-03-13T09:00:00",
|
||||
"collapsed": False,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
project_manager.save_project(
|
||||
{"project": {"name": "test"}}, project_file, disc_data=history_data
|
||||
)
|
||||
|
||||
loaded = project_manager.load_history(project_file)
|
||||
|
||||
assert "entries" in loaded
|
||||
assert len(loaded["entries"]) == 2
|
||||
|
||||
ai_entry = loaded["entries"][0]
|
||||
assert ai_entry["role"] == "AI"
|
||||
assert ai_entry["content"] == "Here's the response"
|
||||
assert "thinking_segments" in ai_entry
|
||||
assert len(ai_entry["thinking_segments"]) == 1
|
||||
assert (
|
||||
ai_entry["thinking_segments"][0]["content"] == "Let me think about this..."
|
||||
)
|
||||
|
||||
user_entry = loaded["entries"][1]
|
||||
assert user_entry["role"] == "User"
|
||||
assert "thinking_segments" not in user_entry
|
||||
|
||||
|
||||
def test_entry_to_str_with_thinking():
|
||||
entry = {
|
||||
"role": "AI",
|
||||
"content": "Response text",
|
||||
"thinking_segments": [{"content": "Thinking...", "marker": "thinking"}],
|
||||
"ts": "2026-03-13T10:00:00",
|
||||
}
|
||||
result = project_manager.entry_to_str(entry)
|
||||
assert "@2026-03-13T10:00:00" in result
|
||||
assert "AI:" in result
|
||||
assert "Response text" in result
|
||||
|
||||
|
||||
def test_str_to_entry_with_thinking():
|
||||
raw = "@2026-03-13T10:00:00\nAI:\nResponse text"
|
||||
roles = ["User", "AI", "Vendor API", "System", "Reasoning"]
|
||||
result = project_manager.str_to_entry(raw, roles)
|
||||
assert result["role"] == "AI"
|
||||
assert result["content"] == "Response text"
|
||||
assert "ts" in result
|
||||
|
||||
|
||||
def test_clean_nones_removes_thinking():
|
||||
entry = {"role": "AI", "content": "Test", "thinking_segments": None, "ts": None}
|
||||
cleaned = project_manager.clean_nones(entry)
|
||||
assert "thinking_segments" not in cleaned
|
||||
assert "ts" not in cleaned
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_save_and_load_history_with_thinking_segments()
|
||||
test_entry_to_str_with_thinking()
|
||||
test_str_to_entry_with_thinking()
|
||||
test_clean_nones_removes_thinking()
|
||||
print("All project_manager thinking tests passed!")
|
||||
Reference in New Issue
Block a user