"""Grok adapter tests (T02): synthetic session dir + real local sessions.""" import glob import json import os import sys sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from session_memory.adapters.grok import parse_session # noqa: E402 REPO_MAP = {"agentic-resources": "helix_forge", "net-kingdom": "netkingdom", "can-you-assist": "coulomb_social"} def _mk_session(dir_path, sid): os.makedirs(dir_path, exist_ok=True) with open(os.path.join(dir_path, "summary.json"), "w") as f: json.dump({"info": {"id": sid, "cwd": "/home/worsch/agentic-resources"}, "created_at": "2026-06-06T10:00:00Z", "last_active_at": "2026-06-06T10:05:00Z", "current_model_id": "grok-build", "head_branch": "main"}, f) with open(os.path.join(dir_path, "events.jsonl"), "w") as f: f.write(json.dumps({"ts": "2026-06-06T10:00:00Z", "type": "turn_started", "turn_number": 0, "model_id": "grok-build"}) + "\n") f.write(json.dumps({"ts": "2026-06-06T10:05:00Z", "type": "turn_ended", "turn_number": 0}) + "\n") with open(os.path.join(dir_path, "chat_history.jsonl"), "w") as f: for rec in [ {"type": "system", "content": "sys prompt"}, {"type": "user", "content": [{"type": "text", "text": "fix the bug"}]}, {"type": "reasoning", "content": [{"type": "text", "text": "thinking..."}]}, {"type": "assistant", "content": ""}, # empty -> skipped {"type": "tool_result", "content": "The file x.py has been updated"}, {"type": "assistant", "content": "done"}, {"type": "tool_result", "content": "6 passed"}, ]: f.write(json.dumps(rec) + "\n") with open(os.path.join(dir_path, "updates.jsonl"), "w") as f: for u in [ {"sessionUpdate": "tool_call", "toolCallId": "c1", "title": "edit_file", "rawInput": {"target_file": "x.py"}}, {"sessionUpdate": "tool_call", "toolCallId": "c2", "title": "shell", "rawInput": {"command": "pytest -q"}}, ]: f.write(json.dumps({"timestamp": "t", "method": "session/update", "params": {"sessionId": sid, "update": u}}) + "\n") def test_grok_synthetic_dir(tmp_path): d = tmp_path / "%2Fhome%2Fworsch%2Fagentic-resources" / "sid-1" _mk_session(str(d), "sid-1") norm = parse_session(str(d / "chat_history.jsonl"), REPO_MAP) assert norm is not None s = norm.session assert s.session_uid == "grok:sid-1" assert s.flavor == "grok" assert s.repo == "agentic-resources" and s.domain == "helix_forge" assert s.model == "grok-build" assert s.git_branch == "main" assert s.cost.turns == 1 assert s.cost.wall_clock_s == 300.0 kinds = [e.kind for e in norm.events] # 4 lifecycle from events.jsonl? no: turn_started + turn_ended = 2 lifecycle assert kinds.count("lifecycle") == 2 assert "user_msg" in kinds and "thinking" in kinds and "assistant_msg" in kinds # paired tool calls recovered names -> edit + test_run, each followed by tool_result assert "edit" in kinds and "test_run" in kinds edit = next(e for e in norm.events if e.kind == "edit") assert edit.tool == "edit_file" # tool_result after test_run links to it tr = [e for e in norm.events if e.kind == "tool_result"] assert len(tr) == 2 def test_real_local_grok_sessions_if_available(): base = os.path.expanduser("~/.grok/sessions") chats = glob.glob(os.path.join(base, "*", "*", "chat_history.jsonl")) if not chats: return parsed = 0 for c in chats: norm = parse_session(c, REPO_MAP) if norm is None: continue parsed += 1 assert norm.session.session_uid.startswith("grok:") seqs = [e.seq for e in norm.events] assert seqs == sorted(seqs) and len(seqs) == len(set(seqs)) assert parsed >= 1