Repository navigation
pi: read omp session logs for history import and host detection - #196
Tal Charnes (tal32123) wants to merge 2 commits into
Conversation
…ion (microsoft#166) omp is a Pi fork that loads the Pi extension, so its live sessions fold under the pi host. Two things kept its earlier sessions out of history import: - its logs start with a {"type":"title"} line before the session one, and carry extra entry types (custom, model_change, ...) between the messages; - they are named <timestamp>_<session id>.jsonl under ~/.omp/agent/sessions/<folder>/, not <session id>.jsonl. Changes: - trace/pi: pi_session_header scans the first few entries for the session line, and pi_session_to_claude stamps user lines with the session's timestamp and cwd so the envelope readers (log head, history import, loop-guard envelope) work on converted copies. - hosts: new Host.log_head (default the Claude Code head; Pi reads its own session line). Pi keeps_history: both ~/.pi/agent/sessions and omp's ~/.omp/agent/sessions, ids taken from after the last underscore. - history: the plan reads ctx.host.log_head / ctx.host.prompt_count; _still_eligible accepts the <timestamp>_<id>.jsonl basename; a non-Claude imported log is converted once and both the fold and the envelope read that converted copy. - default_host: OMPCODE=1 (omp marks its shells that as well as CLAUDECODE=1) resolves to pi, checked before Claude Code's marker. Tested against 725 real omp sessions in ~/.omp/agent/sessions: the firstmate repository plans 19 earlier sessions, imports all 19, and te status reports '+19 from earlier history' under host pi. New tests/test_pi_history.py covers the title-line header, the extra entry types, the file-name id, the resumed-import basename, the converted timestamp/cwd, and the OMPCODE/CLAUDECODE ordering.
|
@microsoft-github-policy-service agree |
Muhammad Abdullah Butt (1AbdullahButt)
left a comment
There was a problem hiding this comment.
I traced _import_one for a Pi/omp log through fold.fold_locked and the Pi host's readers at the PR head. The listing, header scan and OMPCODE detection look right, but the import step folds the wrong file.
-
The fold gets the converted copy, then converts it again.
history.py:440-441converts the raw log (ctx.host.mechanism_trace(item["path"], workdir)) and passesconvertedtofold.fold_locked. Butfold_lockedalready callsctx.host.mechanism_trace(transcript, ...),ctx.host.prompt_count(transcript)andctx.host.session_usage(transcript)itself (fold.py:458-486). On the Pi host those arepi_session_to_claude/pi_prompt_count/ the Pi usage reader, and they all walkpi_active_branch, which needsid/parentIdentries. The converted Claude-format lines have none, so the fold sees an empty branch: no tool calls, zero prompts, zero usage. An imported omp session is counted as "read" but teaches nothing. Onlyreplay_envelopeneeds the Claude-format copy:rec = fold.fold_locked(ctx, sid, item["path"], imported=True, span=...) ... replay_envelope(ctx, converted or item["path"])
None of the tests in
tests/test_pi_history.pygoes through_import_one. One that imports a small omp fixture and assertsfolded.json/untool.jsongained a session withprompts > 0would catch this. -
The temp directory is never removed.
tempfile.mkdtemp(prefix="te-import-")(history.py:439) runs once per imported session and isn't cleaned up. With the 725 omp logs mentioned in #166 that's 725 directories left in%TEMP%//tmp.with tempfile.TemporaryDirectory(prefix="te-import-", ignore_cleanup_errors=True) as workdir:around the fold and the replay fixes it. Theimport tempfileinside the function can move to the top of the module too. -
The stamped
timestamp/cwdgo on the wrong level.pi_session_to_claudeadds them insidemessage(trace/pi.py:94-98), but the Claude readers take them from the line itself:claude_log_headreadsev.get("cwd")/ev.get("timestamp"), andclaude_callsreadsev.get("cwd")(trace/claude.py:52, 198-201). So nothing reads the new fields, andtest_the_converted_log_carries_the_timestamp_and_cwdpins the inner location. Writing{"type": "user", "timestamp": started, "cwd": cwd, "message": {...}}would match Claude Code's own logs.
Smaller: _epoch is now exported from trace/__init__.py as a public name with a leading underscore. A thin trace.iso_epoch wrapper, or importing it from trace.claude in hosts.py, would keep __all__ clean.
Reviewed with help from Claude Code.
…ir, stamp converted lines (#1) The import converted the log and handed the converted copy to fold_locked, which converts again; on Pi the second pass finds no id/parentId entries and folded to zero prompts. Fold from the raw path and convert only for the envelope replay, inside a TemporaryDirectory. pi_session_to_claude now writes timestamp and cwd on the line, where the Claude readers look. Rename trace._epoch to trace.iso_epoch.
Closes #166.
omp loads the Pi extension, so its sessions are handled on the Pi host.
trace/pi.py: find thesessionline past omp's leadingtitleline; stamp converted user lines with the session's timestamp and cwd.plugin/hosts.py:Host.log_head(); Pi keeps history from~/.pi/agent/sessionsand~/.omp/agent/sessions, with the id taken from<timestamp>_<id>.jsonl.plugin/history.py: plan reads the host's log head and prompt count; accepts the<timestamp>_<id>.jsonlbasename; non-Claude logs are converted once.default_host:OMPCODE=1resolves topi, checked beforeCLAUDECODE.Tests: new
tests/test_pi_history.py; checked against real omp sessions (history import picks up earlier sessions under hostpi).