Skip to content

pi: read omp session logs for history import and host detection - #196

Open
Tal Charnes (tal32123) wants to merge 2 commits into
microsoft:mainfrom
tal32123:fix/omp-session-history
Open

Tal Charnes (tal32123) wants to merge 2 commits into
microsoft:mainfrom
tal32123:fix/omp-session-history

Conversation

@tal32123

Copy link
Copy Markdown

Closes #166.

omp loads the Pi extension, so its sessions are handled on the Pi host.

  • trace/pi.py: find the session line past omp's leading title line; stamp converted user lines with the session's timestamp and cwd.
  • plugin/hosts.py: Host.log_head(); Pi keeps history from ~/.pi/agent/sessions and ~/.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>.jsonl basename; non-Claude logs are converted once.
  • default_host: OMPCODE=1 resolves to pi, checked before CLAUDECODE.

Tests: new tests/test_pi_history.py; checked against real omp sessions (history import picks up earlier sessions under host pi).

…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.
@tal32123

Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

  1. The fold gets the converted copy, then converts it again. history.py:440-441 converts the raw log (ctx.host.mechanism_trace(item["path"], workdir)) and passes converted to fold.fold_locked. But fold_locked already calls ctx.host.mechanism_trace(transcript, ...), ctx.host.prompt_count(transcript) and ctx.host.session_usage(transcript) itself (fold.py:458-486). On the Pi host those are pi_session_to_claude / pi_prompt_count / the Pi usage reader, and they all walk pi_active_branch, which needs id/parentId entries. 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. Only replay_envelope needs 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.py goes through _import_one. One that imports a small omp fixture and asserts folded.json / untool.json gained a session with prompts > 0 would catch this.

  2. 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. The import tempfile inside the function can move to the top of the module too.

  3. The stamped timestamp / cwd go on the wrong level. pi_session_to_claude adds them inside message (trace/pi.py:94-98), but the Claude readers take them from the line itself: claude_log_head reads ev.get("cwd") / ev.get("timestamp"), and claude_calls reads ev.get("cwd") (trace/claude.py:52, 198-201). So nothing reads the new fields, and test_the_converted_log_carries_the_timestamp_and_cwd pins 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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support omp (oh-my-pi) sessions: history import and host detection

2 participants