fix: add workspace user turn repair utility
This commit is contained in:
1 parent
a8de4e7c0a
commit
4c03fdfaa8
2 files changed
+278
No files matched your search
@@ -0,0 +1,91 @@
|
||||
import importlib.util
|
||||
import json
|
||||
import sqlite3
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
SCRIPT = Path(__file__).resolve().parents[1] / "scripts" / "repair_workspace_user_turns.py"
|
||||
spec = importlib.util.spec_from_file_location("repair_workspace_user_turns", SCRIPT)
|
||||
repair = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(repair)
|
||||
|
||||
|
||||
def test_clean_message_list_strips_workspace_prefix_and_dedupes_adjacent_user_turns():
|
||||
cleaned, stats = repair.clean_message_list([
|
||||
{"role": "user", "content": "Ok, mache weiter"},
|
||||
{"role": "user", "content": "[Workspace: /tmp/project]\nOk, mache weiter"},
|
||||
{"role": "assistant", "content": "continuing"},
|
||||
{"role": "user", "content": "[Workspace: /tmp/project]\nNext"},
|
||||
])
|
||||
|
||||
assert stats == {"stripped_workspace_prefixes": 2, "removed_adjacent_user_duplicates": 1}
|
||||
assert [m["role"] for m in cleaned] == ["user", "assistant", "user"]
|
||||
assert [m["content"] for m in cleaned] == ["Ok, mache weiter", "continuing", "Next"]
|
||||
|
||||
|
||||
def test_repair_sidecars_writes_backup_and_updates_message_count(tmp_path):
|
||||
sessions_dir = tmp_path / "sessions"
|
||||
backup_dir = tmp_path / "backup"
|
||||
sessions_dir.mkdir()
|
||||
sidecar = sessions_dir / "abc.json"
|
||||
sidecar.write_text(json.dumps({
|
||||
"session_id": "abc",
|
||||
"message_count": 3,
|
||||
"messages": [
|
||||
{"role": "user", "content": "ping"},
|
||||
{"role": "user", "content": "[Workspace: /tmp]\nping"},
|
||||
{"role": "assistant", "content": "pong"},
|
||||
],
|
||||
}), encoding="utf-8")
|
||||
|
||||
report = repair.repair_sidecars(sessions_dir, backup_dir=backup_dir, dry_run=False)
|
||||
|
||||
assert report["changed_sidecars"][0]["removed_adjacent_user_duplicates"] == 1
|
||||
updated = json.loads(sidecar.read_text(encoding="utf-8"))
|
||||
assert updated["message_count"] == 2
|
||||
assert [m["content"] for m in updated["messages"]] == ["ping", "pong"]
|
||||
assert (backup_dir / "abc.json").exists()
|
||||
|
||||
|
||||
def test_repair_state_db_strips_prefixes_deletes_duplicates_and_updates_counts(tmp_path):
|
||||
db = tmp_path / "state.db"
|
||||
con = sqlite3.connect(db)
|
||||
con.executescript("""
|
||||
create table sessions (
|
||||
id text primary key,
|
||||
message_count integer default 0,
|
||||
tool_call_count integer default 0
|
||||
);
|
||||
create table messages (
|
||||
id integer primary key autoincrement,
|
||||
session_id text not null,
|
||||
role text not null,
|
||||
content text,
|
||||
tool_name text
|
||||
);
|
||||
""")
|
||||
con.execute("insert into sessions(id, message_count, tool_call_count) values ('s1', 4, 1)")
|
||||
con.executemany(
|
||||
"insert into messages(session_id, role, content, tool_name) values (?, ?, ?, ?)",
|
||||
[
|
||||
("s1", "user", "hello", None),
|
||||
("s1", "user", "[Workspace: /tmp]\nhello", None),
|
||||
("s1", "assistant", "hi", None),
|
||||
("s1", "tool", "{}", "read_file"),
|
||||
],
|
||||
)
|
||||
con.commit()
|
||||
con.close()
|
||||
|
||||
report = repair.repair_state_db(db, backup_dir=tmp_path / "backup", dry_run=False)
|
||||
|
||||
assert report["updated_workspace_prefix_user_messages"] == 1
|
||||
assert report["removed_adjacent_user_duplicates"] == 1
|
||||
con = sqlite3.connect(db)
|
||||
assert con.execute("select message_count, tool_call_count from sessions where id = 's1'").fetchone() == (3, 1)
|
||||
assert con.execute("select role, content from messages order by id").fetchall() == [
|
||||
("user", "hello"),
|
||||
("assistant", "hi"),
|
||||
("tool", "{}"),
|
||||
]
|
||||
con.close()
|
||||
Reference in new issue
Block a user