Skip to content

feat(sessions): read Pi and Oh My Pi transcripts - #1586

Open
XY-code1 wants to merge 3 commits into
Tencent:mainfrom
XY-code1:feat/pi-session-adapter
Open

XY-code1 wants to merge 3 commits into
Tencent:mainfrom
XY-code1:feat/pi-session-adapter

Conversation

@XY-code1

@XY-code1 XY-code1 commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • add one shared, read-only PiAdapter for Pi and Oh My Pi v3 JSONL sessions
  • follow the recorded tool homes for Pi and OMP, read cwd from the session header, and keep only the active parent-linked branch
  • normalize text, thinking, images, tool calls/results, model changes, OMP's leading title slot, and later title changes
  • enable Pi/OMP session scoring in TOOLS, every README matrix, and the generated support docs

Refs #1418 (Pi / Oh My Pi row only).

Verification

  • npm run lint
  • npx tsc --noEmit
  • npm run build
  • npx vitest run src/__tests__/pi-session-adapter.test.ts src/__tests__/session-platform-facts.test.ts src/__tests__/readme-matrix.test.ts src/__tests__/tool-support.test.ts src/__tests__/agent-session-list.test.ts --maxWorkers=2
    • 59 passed, 1 skipped
  • npx vitest run tool-support -u

Representative built-CLI run against a Pi v3 fixture store:

$ node dist/index.js session platforms
pi: ✓ installed

$ node dist/index.js session migrate 123e4567-e89b-12d3-a456-426614174099 --source pi --target claude-code --cwd <repo> --yes --json
Session:   Verify Pi CLI migration (123e4567...)
Messages:  2
Fidelity:  100.0% (Mode A)
✓ Migration successful
CLI_EXIT=0

I did not label this as a real authenticated Pi/OMP session run: the local machine has no configured Pi/OMP provider session. The fixture uses the documented v3 record graph and the adapter tests cover both variants, including OMP's title slot.

Shared-state review

  • Native writers: Pi and OMP continue to own their JSONL stores.
  • New reader: PiAdapter recursively reads .jsonl files only.
  • TeamAI writers/deleters: none; writeSession throws ToolUnavailableError and deleteSession returns false.
  • Registry/store resolution: sessionStoreDir remains the single resolver, so recorded member tool roots and OMP profiles keep their existing behavior.

Real-CLI record on real Pi and Oh My Pi sessions (added by a reviewer)

Real-CLI record (teamai-cli at b1664c0c, npm ci && npm run build; baseline 3da56ad2 built the same way)

Stores: Pi 1.4.0 (@earendil-works/pi-coding-agent@1.4.0) and Oh My Pi 18.12.6
(@oh-my-pi/pi-coding-agent@18.12.6, run under Bun 1.4.0). Each wrote its own session
file through a local OpenAI-compatible stub that returns a fixed reply (no provider
account). The judge was a stub claude that prints a fixed label, so the score lines
prove the path, not a model judgment.

Isolation: env -i; HOME=<fixture home>; PATH=<node dir>:/usr/bin:/bin;
GIT_CONFIG_GLOBAL=<empty file>; GIT_CONFIG_NOSYSTEM=1; TEAMAI_NONINTERACTIVE=1;
TMPDIR=<tmp>.

$ node dist/index.js session platforms                       # head
  pi: ✓ installed                                             (exit 0)
$ node dist/index.js session push --source pi --all --scrub -y --cwd <proj> --repo-root <team clone>
  ✓ Pushed 3 session(s) from pi                               (exit 0)
$ node dist/index.js score --scorer <file> --session <pi id> --source pi
  fixture-quality: good (score 1, passed)                     (exit 0)
$ node dist/index.js session push --source omp --all --scrub -y --cwd <proj> --repo-root <team clone>
  ✓ Pushed 1 session(s) from omp                              (exit 0)
  archived title: "Fix the OMP parser" (OMP title slot empty, so the first prompt)
$ node dist/index.js score --session <omp id> --source omp
  fixture-quality: good (score 1, passed)                     (exit 0)
$ node dist/index.js session migrate <pi id> -s pi -t omp --yes
  Error: TeamAI cannot write omp sessions: omp resumes a conversation only from a store of its own. Pick another target platform.
                                                              (exit 1; no file in the Pi home changed)

Baseline 3da56ad2: each command above fails with Unknown platform "pi" / "omp" (exit 1).

@github-actions

Copy link
Copy Markdown
  • [P2 non-blocking] src/session-flow/adapters/pi.ts:232: Later model changes are ignored once any assistant message has a model. For an assistant message using model A followed by a parent-linked model_change selecting model B, readSession() still returns A in session metadata because the message lookup wins before model-change entries are considered. Resolve both record types in branch order so the latest model selection wins.

The PR description documents sufficient testing: the representative built-CLI fixture migration satisfies the real-CLI requirement. An authenticated Pi/OMP run or full provider × agent matrix is not required. No commands from the PR were run.

@XY-code1

Copy link
Copy Markdown
Contributor Author

Fixed the Windows matrix failure in b1664c0: the sessions locate matrix now covers Pi/OMP default, moved-home, profile, project, and PI_CODING_AGENT_SESSION_DIR stores; sessionStoreDir also honors the explicit Pi-family session-dir override. Local Windows-safe suite: 33 files, 4,876 tests passed. Lint, tsc, and focused session tests pass.

@github-actions

Copy link
Copy Markdown
  • [P2 non-blocking] src/session-flow/adapters/pi.ts:232: The earlier finding remains unresolved. An assistant message using model A followed by a parent-linked model_change selecting model B still yields session metadata with A, because assistant-message models take precedence over all model-change records. Resolve both record types in branch order so the latest selection wins.

The PR description documents sufficient testing: the representative built-CLI fixture migration satisfies the real-CLI requirement. An authenticated Pi/OMP run or full provider × agent matrix is not required.

No additional confident findings. Only the specified diff was read; no PR code was run, built, or installed.

@SaulMoro

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Reviewed at b1664c0 against #1418's Pi and Oh My Pi rows. The adapter works on real stores: I wrote sessions with Pi 1.4.0 and Oh My Pi 18.12.6 (through a local stub provider) and ran the built CLI. session push and score --session work for both, OMP's empty title slot falls back to the first prompt, and session migrate --target omp fails with the read-only message and writes nothing. main fails each of these with Unknown platform. I added that record to the PR body, since the issue asks for push and score on a real session.

Two things to fix before merge:

  • [P1 blocking] CI is red at this head. Lint & Test on Node 20, 22 and 24 (ubuntu) and E2E shard 3/3 fail in three cases that use pi as the example of a tool whose sessions teamai can't read. This PR makes that false. Switching them to copilot (still unreadable on main) fixes it; grep -rn "'pi'" src/__tests__ finds any others.
  • [P1 blocking] The Pi sessionDir setting is in the TOOLS note but is not read. With {"sessionDir": "<dir>"} in ~/.pi/agent/settings.json, Pi 1.4.0 writes there, and teamai session push --source pi --all archives only the default store, exits 0 and says nothing about the missing sessions. Either read the setting in sessionStoreDir (src/locate.ts:1177), resolved like the env var, or drop it from the note.

Non-blocking:

  • [P2 non-blocking] An unexpanded ~ in PI_CODING_AGENT_SESSION_DIR (from an env file or a quoted value) is resolved against the working directory; Pi expands it. expandHomeOn (src/tool-home.ts:289) handles it.
  • [P2 non-blocking] The CI review's model_change finding: agreed, reproduced on a real Pi file. Only the session-level metadata.model is affected.
  • [P2 non-blocking] docs/guide/dashboard.md:145 and its zh-CN page list the platforms teamai session covers and don't include pi and omp.
  • [P3 nit] A dangling activeLeafId returns no messages, where OMP falls back to the newest entry; the comment at platform-facts.ts:209 still names only PI_CODING_AGENT_DIR; listConversations and readSession in pi.ts repeat the same normalization.

@jeff-r2026 Your call on this one once the two blocking items are fixed: it adds Pi and Oh My Pi as readable session platforms.

@XY-code1

Copy link
Copy Markdown
Contributor Author

Addressed the blocking and follow-up findings in f74bfb9:\n\n- replaced the three stale tests that used Pi as an unreadable-session example with Copilot\n- made sessionStoreDir honor Pi's settings.json sessionDir, after the env override and with ~/relative expansion via �bsoluteOn\n- fixed PI_CODING_AGENT_SESSION_DIR tilde expansion\n- resolve assistant models and model_change records in active-branch order, so the latest event wins\n- fall back to the newest entry for a dangling �ctiveLeafId\n- added Pi/OMP to both dashboard docs\n- added regression tests for settings resolution, latest model changes, and dangling leaves\n\nLocal verification: lint, tsc, build, Windows-safe suite (33 files / 4,894 tests), focused adapter/store tests, and the dashboard E2E all pass.

@github-actions

Copy link
Copy Markdown

No new confident findings in the specified diff.

  • Resolved: The earlier model-ordering finding is fixed in src/session-flow/adapters/pi.ts:83. Assistant messages and model-change records now update metadata in active-branch order, with a regression test covering a later model change.
  • Testing: The PR description documents sufficient real-CLI verification. The representative built-CLI fixture migration satisfies the requirement; the additional Pi/OMP records provide further coverage. No full provider × agent matrix is required.

Only the specified diff was read. No PR code was run, built, or installed.

@SaulMoro

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Re-checked at f74bfb9 with real Pi 1.4.0 and Oh My Pi 18.12.6 sessions. Resolved:

  • The three tests now use Copilot as the unreadable example; no CI job fails at this head (some macOS and one E2E shard were still running).
  • sessionDir in ~/.pi/agent/settings.json is read: a session Pi writes there is archived by session push --source pi --all, ~ and relative paths resolve as in Pi, and PI_CODING_AGENT_SESSION_DIR still wins.
  • An unexpanded ~ in PI_CODING_AGENT_SESSION_DIR works, the latest model_change wins, a dangling activeLeafId falls back to the newest entry, and the dashboard pages list pi and omp.
  • push and score --session still work on a real Pi and a real OMP session.

One left:

  • [P1 blocking] Pi's project-level sessionDir is not read. Pi also reads sessionDir from <project>/.pi/settings.json, over the global file. With one set, Pi writes the project's sessions there, and teamai session push --source pi --all exits 0 and archives an older session from the default store instead. Reading the project file first fixes it; narrowing the TOOLS note to the global setting would make this a known limit rather than a bug.

Nits:

  • [P3 nit] A last entry with activeLeafId: null now shows the newest branch; OMP treats a null leaf as no leaf, and the previous head showed none.
  • [P3 nit] The win32 assertion change in the dashboard e2e test is unrelated to Pi, and dashboard-session-sharing-view.test.ts still has unreadTools: ['pi'].

@jeff-r2026 your call once the project-level sessionDir is handled.

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.

3 participants