Skip to content

feat(sleep): add Pi transcript source and CLI backend - #83

Merged
Yif-Yang merged 7 commits into
microsoft:mainfrom
auspic7:feat/pi-source
Aug 2, 2026
Merged

feat(sleep): add Pi transcript source and CLI backend#83
Yif-Yang merged 7 commits into
microsoft:mainfrom
auspic7:feat/pi-source

Conversation

@auspic7

@auspic7 auspic7 commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds explicit Pi integration to SkillOpt-Sleep:

  • --source pi harvests local Pi JSONL sessions from ~/.pi/agent/sessions.
  • --backend pi runs mining, replay, judging, and reflection through a locally installed, authenticated Pi CLI.
  • Source and backend selection remain independent.

Pi is opt-in. --source auto keeps the existing Codex-then-Claude precedence and does not select Pi.

Original contribution

The original branch introduced:

  • Pi transcript parsing and source routing.
  • Extraction of user/assistant text, tool names, and lexical user feedback.
  • Exclusion of thinking blocks, tool arguments, tool outputs, and images.
  • Deliberate exclusion of transient toolResult.isError values from task-outcome feedback.
  • A Pi CLI backend with model/path configuration and isolated print-mode execution.
  • Launch, timeout, and non-zero-exit diagnostics.

The original PR reports:

  • ruff check passing on the touched files.
  • 54 passed, 1 skipped for the initial harvester and Sleep tests.
  • A real local harvest of 12 Korean/English Pi sessions producing 11 tasks.
  • A live Pi CLI call using zai/glm-5.2.

These are the original contributors' reported validations; maintainer validation is listed separately below.

Maintainer integration and hardening

Because the branch had become stale and conflicted with current main, maintainers integrated it without rewriting the original commits and added:

  • Compatibility with the current backend factory, dual-backend wiring, OpenClaw wrappers, CLI, and plugin checks.
  • Explicit-only Pi source routing; Pi does not change --source auto.
  • Pi v1/v2/v3 session validation and active-branch traversal.
  • Fail-closed handling for malformed JSONL, unsupported versions, duplicate IDs, and invalid parent chains.
  • Stronger CLI isolation: no tools, skills, context files, extensions, prompt templates, themes, or session writes.
  • Prompt delivery over stdin and redacted failure diagnostics.
  • PI_OFFLINE=1 to disable Pi startup update/package/telemetry traffic while still allowing the configured model-provider request.
  • Non-sticky caching for failed model calls.
  • Privacy documentation covering retained message text and the project cwd boundary.
  • Focused configuration, routing, integration, and compatibility tests.

Privacy boundary

Pi transcript harvesting is local and read-only. When a real backend is selected, transcript-derived prompts are sent to that backend's configured provider.

Known secret-shaped strings in retained message text are redacted on a best-effort basis. The absolute project cwd is retained for scope filtering and may appear in miner prompts; it is not covered by message-text redaction.

Validation

Maintainer-performed validation:

  • 76 passed in 1.05s across the Pi backend, harvester, integration, model-warning, and plugin-sync tests.
  • Real Pi CLI v0.83.0 against a local OpenAI-compatible test provider:
    • PI_OFFLINE=1 still reached /v1/chat/completions and returned the expected response.
    • An intentionally unavailable package plus a disabled npm command did not trigger package installation.
  • Full suite: 664 passed, 6 skipped, 130 subtests passed.
  • compileall, CLI help, and git diff --check passed.

brandon added 2 commits June 23, 2026 22:03
Adds `--source pi` to SkillOpt-Sleep so it can harvest sessions from the
pi coding agent (`~/.pi/agent/sessions/<slug>/*.jsonl`), on par with the
existing claude/codex sources.

pi schema notes (verified against real transcripts):
- entry discriminator is `type`; cwd lives on the single `session` entry
- conversational turns are `type:"message"` with `message.role` in
  {user, assistant, toolResult}
- content blocks use `toolCall` (not Claude's `tool_use`) and carry `name`;
  `thinking` blocks are private reasoning and are skipped
- toolResult messages carry `isError` + `toolName`, a per-call
  success/failure signal surfaced as a `neg:tool_error:<tool>` feedback
  signal — the checkable outcome the gate thrives on

Changes:
- skillopt_sleep/harvest_pi.py: new harvester (digest_pi_session + harvest_pi),
  stdlib-only, reuses shared helpers from harvest.py
- skillopt_sleep/config.py: `pi_home` default (~/.pi) + `pi_sessions_dir` property
- skillopt_sleep/harvest_sources.py: `pi` source + `auto` fallback
- skillopt_sleep/__main__.py: `--source pi` choice + `--pi-home` flag
- tests/test_harvest_pi.py: field extraction, scope filter, secret redaction

Verified end-to-end against real local pi sessions (Korean + English, tool
errors, thinking blocks correctly excluded).
Follow-up to PR feedback: pi's `isError` on toolResult records only whether
that single tool invocation failed mechanically. In agentic coding,
intermediate tool errors are normal and frequently followed by recovery and
a successful final result. Surfacing every such error as `neg:tool_error`
would mislabel successful sessions as failures (the verifying session that
produced `neg:tool_error:bash, neg:tool_error:edit` was in fact a successful
recovered session) and poison the miner's task-outcome labels.

Task outcome should be inferred from the user's judgment of the final result
(the lexical feedback phrases), not from transient tool mechanics.

- harvest_pi.py: drop the `neg:tool_error` emission; keep toolName
  extraction (still a useful corroborating tool-name source).
- test_harvest_pi.py: assert isError is NOT surfaced as feedback.
@auspic7

auspic7 commented Jun 23, 2026

Copy link
Copy Markdown
Contributor Author

@microsoft-github-policy-service agree

@auspic7 auspic7 closed this Jun 23, 2026
@auspic7 auspic7 reopened this Jun 23, 2026
@auspic7
auspic7 marked this pull request as draft June 23, 2026 13:28
Companion to `--source pi`: a `PiCliBackend` that drives the pi coding
agent's headless mode (`pi -p`) for replay. pi speaks the open Agent Skills
standard and supports `-p`/`--print`, so it slots in alongside the existing
claude/codex/copilot CLI backends — and crucially, the replay model is whatever
the user has configured in pi (e.g. `zai/glm-5.2`), keeping source and backend
on the same agent instead of forcing Claude/Codex.

Changes:
- skillopt_sleep/backend.py: `PiCliBackend(CliBackend)` implementing `_call`
  via `pi -p --no-session --no-tools --no-skills --no-context-files
  --no-extensions [--model M] <prompt>` from a clean temp cwd. Auth/config
  errors detected and surfaced (mirrors the Claude backend). Registered in
  `get_backend` with aliases (pi, pi_cli, pi_coding_agent) + `pi_path` arg.
- skillopt_sleep/cycle.py + config.py: thread `pi_path` through config.
- skillopt_sleep/__main__.py: `--backend pi` choice + `--pi-path` flag.
- tests/test_backend_pi.py: alias resolution, env-default model, isolated
  command construction, auth-error detection.

Verified end-to-end: `PiCliBackend(model='zai/glm-5.2')._call(...)` invokes
`pi -p` and returns the real model response in ~5s (not mock). `ruff` clean
on touched files; full suite passes (72 tests).
@Yif-Yang

Copy link
Copy Markdown
Contributor

Hi @auspic7 — thanks for this, it's a clean addition. This PR has been in draft for a while; is it ready to merge? I reviewed and tested it locally (pi harvester + backend tests pass, no regressions). One small thing worth addressing before/after merge: in skillopt_sleep/backend.py, PiCliBackend._call() swallows all launch/timeout exceptions and ignores non-zero exit codes, so a missing pi binary returns "" — indistinguishable from an empty model answer (the sibling CodexCliBackend records last_call_error + logs a warning). Also the section comment above the class still reads "Claude Code CLI backend". Happy to merge once you mark it ready — or I can help land it with those fixes if you'd like.

@Yif-Yang

Copy link
Copy Markdown
Contributor

Hi @auspic7 — thanks, 70629dc2 addresses the launch/timeout/non-zero-exit handling and the stale section label from our last note. Is this PR now ready to leave draft? If so, please rebase onto current main and mark it Ready for review; we will re-run the focused tests and review it promptly.

@Yif-Yang

Copy link
Copy Markdown
Contributor

Hi @auspic7 — friendly status check on this one. The CLA is all set, but the PR is still in draft and currently has merge conflicts. When you have a moment, could you rebase onto the latest main to resolve the conflicts and mark the PR as Ready for review? Once that is done, we will take another pass promptly. Thanks!

Copilot AI review requested due to automatic review settings August 2, 2026 19:18
@Yif-Yang Yif-Yang changed the title feat(sleep): add pi-coding-agent transcript source feat(sleep): add Pi transcript source and CLI backend Aug 2, 2026

Copilot AI left a comment

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.

Pull request overview

This PR adds an explicit Pi integration path to SkillOpt-Sleep, enabling both (1) harvesting Pi session transcripts from the local ~/.pi/agent/sessions tree and (2) running the Sleep cycle through a locally installed/authenticated Pi CLI backend, while keeping source selection (--source) and backend selection (--backend) independent and preserving existing --source auto precedence.

Changes:

  • Added a Pi transcript harvester (--source pi) with schema validation, active-branch selection for v2/v3 sessions, and secret-shaped string redaction.
  • Added a Pi CLI backend (--backend pi) that runs in print mode with strong isolation flags and offline startup env settings.
  • Expanded CLI/config/routing, OpenClaw plugin wiring, and tests/docs to cover Pi paths end-to-end.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tests/test_plugin_sync.py Extends plugin sync coverage to ensure OpenClaw wrapper matches updated shared backend factory signature (including Pi params).
tests/test_pi_integration.py Adds CLI/config and harvest routing tests ensuring --source pi is explicit and --source auto does not select Pi.
tests/test_model_change_warning.py Ensures model-key construction forwards pi_path into backend build for cache-key correctness.
tests/test_harvest_pi.py Comprehensive unit coverage for Pi session digestion/validation, branch selection, and redaction behavior.
tests/test_backend_pi.py Unit tests for Pi CLI backend invocation, isolation flags, error handling, caching semantics, and token accounting.
skillopt_sleep/harvest_sources.py Adds pi as an explicit transcript source routed to the new harvester.
skillopt_sleep/harvest_pi.py Implements Pi JSONL reading, schema checks, active-branch extraction, normalization into SessionDigest, and directory walking harvest.
skillopt_sleep/cycle.py Includes pi_path in backend construction inputs for stable model-keying and runtime wiring.
skillopt_sleep/config.py Adds pi_home, pi_path, and a derived pi_sessions_dir to configuration defaults/accessors.
skillopt_sleep/backend.py Introduces PiCliBackend, adds Pi aliases to get_backend, and wires pi_path through build_backend (single + dual backend).
skillopt_sleep/main.py Adds CLI flags --pi-home / --pi-path and extends --backend / --source choices to include pi.
plugins/README.md Documents Pi source/backend behavior, privacy boundary, and CLI flags in the plugin integration README.
plugins/openclaw/skillopt_sleep_openclaw.py Refactors reference-answer rubric formatting for readability/maintainability.
plugins/openclaw/run_sleep.py Updates OpenClaw’s backend factory shim to accept/forward the expanded shared signature including Pi params.
docs/sleep/README.md Adds Pi source/backend documentation and updates high-level pipeline description to include Pi.
docs/reference/cli.md Updates CLI reference to include Pi flags and clarifies network/no-network backend boundary language.
docs/guide/installation.md Adds optional Pi CLI installation guidance and clarifies that Pi harvesting does not require the CLI.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread skillopt_sleep/__main__.py Outdated
@Yif-Yang

Yif-Yang commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Thanks @brandon and @auspic7 for bringing the Pi integration forward, including the follow-up CLI failure handling.

Since this PR remained in draft and had diverged from main, we used the allowed maintainer edits to integrate current main and complete the compatibility, isolation, privacy-documentation, and test hardening. The four original commits and their authorship have been preserved; the maintainer integration and hardening remain separate commits in the history.

One important final behavior is that Pi remains explicit-only: --source pi enables it, while --source auto keeps the existing Codex-then-Claude precedence.

Maintainer validation completed successfully:

  • 76 focused Pi, routing, model-warning, and plugin compatibility tests passed.
  • Full suite: 664 passed, 6 skipped, 130 subtests passed.
  • Pi CLI v0.83.0 reached a local OpenAI-compatible test provider under PI_OFFLINE=1, while the package-install path remained disabled.
  • Independent integration, security, and final code reviews found no merge blocker.

We are marking this ready and proceeding with a normal merge commit so the original contribution history remains intact.

@Yif-Yang
Yif-Yang marked this pull request as ready for review August 2, 2026 19:23

@Yif-Yang Yif-Yang left a comment

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.

Maintainer integration, full-suite validation, Pi CLI smoke testing, and independent security/correctness reviews are complete. No merge blocker remains.

Copilot AI review requested due to automatic review settings August 2, 2026 19:24

@Yif-Yang Yif-Yang left a comment

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.

Re-approved on the latest head (716197e) after the maintainer hardening, focused/full regression suites, local Pi-provider smoke test, and independent integration/security reviews. Ready to merge.

@Yif-Yang
Yif-Yang merged commit 8a4c96a into microsoft:main Aug 2, 2026
1 check passed

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated no new comments.

Suppressed comments (1)

tests/test_harvest_pi.py:14

  • In this helper you write JSONL records without specifying an encoding. Most other tests in this repo use encoding="utf-8" for text writes, and leaving it implicit can cause platform-dependent behavior (e.g., Windows default code pages) if Pi sessions contain non-ASCII text.
    with open(p, "w") as f:

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.

4 participants