Skip to content

Pi 0.80.8 spawn runtime compatibility#16

Open
grzegorznowak wants to merge 6 commits into
agenticoding:mainfrom
grzegorznowak:story-05-spawn-pi-0808-runtime-compatibility
Open

Pi 0.80.8 spawn runtime compatibility#16
grzegorznowak wants to merge 6 commits into
agenticoding:mainfrom
grzegorznowak:story-05-spawn-pi-0808-runtime-compatibility

Conversation

@grzegorznowak

@grzegorznowak grzegorznowak commented Jul 18, 2026

Copy link
Copy Markdown
Collaborator

Why this PR exists

Upgrading Pi from 0.80.7 to 0.80.8 broke every /spawn path in this extension before a child agent could be created. Pi 0.80.8 removed the old extension-owned AuthStorage / ModelRegistry.create() session bootstrap and replaced createAgentSession({ authStorage, modelRegistry }) with the public ModelRuntime-based session API. The existing spawn boundary still constructed the removed objects, so inherited-model and explicitly selected-model invocations both failed with TypeError: Cannot read properties of undefined (reading 'create').

Model routing exposed this compatibility break; it did not cause it. The failure happened before route selection could affect child creation, and the original non-routing spawn path used the same obsolete bootstrap. Here, a child session is the isolated Pi agent session that executes a spawned task, while ModelRuntime is Pi's public runtime object for model discovery, provider authentication, and session model access.

User-visible before and after

Before: on Pi 0.80.8, /spawn could not create a child, whether it inherited the parent's model or received an explicit selection.

After: child sessions are created through Pi's supported public runtime/session APIs on Pi 0.80.8 and later. The selected model and thinking level, active tools, notebook access, readonly boundaries, working directory, and transcript isolation are preserved. Child sessions have exactly-once cleanup; renderer recovery remains TUI-safe; and compatibility is checked at the supported floor, against current Pi, and in a packaged host. Parent-only transient provider or credential state fails explicitly rather than silently falling back to another model.

What changed

  • Migrated child creation from the removed auth/registry bootstrap to a child-owned public ModelRuntime and AgentSession lifecycle.
  • Kept ctx.modelRegistry only as Pi's synchronous compatibility facade for extension-side model lookup; it is not used to construct child sessions.
  • Preserved requested model identity and thinking input while reporting the child session's effective public thinking level.
  • Hardened child disposal across success, failure, abort, reset, stale-result, and renderer-interaction paths.
  • Made renderer invalidation recovery current-work aware and free of stdout/stderr diagnostics.
  • Made floor, current-Pi, and packaged-host compatibility checks cwd-independent, shell-free, and portable across Unix and Windows.

Requirements

  • Let Pi operators spawn child agents on Pi 0.80.8 or later without relying on APIs removed in that release.
  • Preserve the parent-selected model and thinking level, active tools, notebook tools, readonly restrictions, working directory, and parent/child session isolation.
  • Dispose every created child session exactly once across successful, failed, aborted, reset, and stale-result paths.
  • Report unavailable parent-only transient provider or credential state clearly without silently selecting a different model.
  • Keep renderer frame recovery safe for Pi's terminal UI without emitting stdout/stderr diagnostics.
  • Continuously prove compatibility at the minimum supported runtime, against synchronized current Pi packages, and when installed as a package in a clean host.

Acceptance criteria

  • On exact Pi 0.80.8 without model-network access or live credentials, both inherited/default and explicitly selected child-model invocations complete through supported public APIs; the selected provider/model identity remains unchanged.
  • Removed pre-0.80.8 bootstrap APIs and private parent runtime/auth access are absent from the child-session boundary.
  • Pi's max thinking level is accepted and reaches the child unchanged.
  • Child sessions preserve the configured working directory, allowed active tools, notebook access, readonly tool boundaries, guarded readonly shell behavior, and transcript isolation.
  • Every created child session is disposed exactly once after normal completion, prompt failure, empty output, abort, reset, stale-epoch races, or renderer interaction; stale results are not returned.
  • Cleanup failures do not mask an earlier execution failure and remain observable; cleanup-only failures are surfaced.
  • Parent-only transient provider or credential state produces an explicit resolution or authorization error with no model fallback.
  • Package metadata declares Node 22.19.0 or later, wildcard Pi and TypeBox peers, and exact development-floor versions for Pi 0.80.8 and TypeBox 1.1.38.
  • Required checks pass for the exact floor, synchronized current Pi, recursive installed dependency graphs, and a packaged extension loaded by a clean Pi 0.80.8 host.
  • A renderer component failure emits no console.* output, does not block healthy components, and recovers on a later frame.
  • Compatibility minimums, transient-state limitations, and the child-runtime lifecycle change are documented for operators and maintainers.

Contract changes

  • The minimum supported Pi version is 0.80.8; Pi 0.80.7 and earlier are not supported.
  • The minimum supported Node.js version is 22.19.0.
  • Pi and TypeBox remain host-provided wildcard peer dependencies, with Pi 0.80.8 and TypeBox 1.1.38 as the exact development compatibility floor.
  • Spawn accepts Pi's max thinking level.
  • Parent-only transient providers, in-memory credentials, inline provider factories, and catalog mutations are not guaranteed to be available to child sessions; failures are reported without model fallback.

Out of scope

  • Compatibility with Pi 0.80.7 or dual-version adapters.
  • Model-selection or routing policy, provider failover, and Model Groups UX.
  • Sharing private parent runtime/auth state or copying transient provider configuration and credentials into child sessions.
  • New session start/shutdown lifecycle semantics.
  • Unrelated package allowlist/content cleanup, strict engine enforcement, or dependency maintenance.
  • Pre-existing executable-tool inheritance and no-text cancellation-reason semantics; these are tracked separately in #17.

How to verify

npm ci
npm run typecheck
npm test
npm run test:e2e
npm run test:snapshots:check
npx audit-ci --config audit-ci.jsonc
npm run test:compat:floor
npm run test:compat:current
npm run test:package-host
npm pack --dry-run --ignore-scripts

Confirm that the exact-floor and current-Pi checks report a coherent installed Pi graph, the packaged-host check loads the extension beside Pi 0.80.8 using host-provided peers, and all commands complete without outbound model requests or terminal diagnostics.

References

@grzegorznowak

Copy link
Copy Markdown
Collaborator Author

Implemented the approved CURe repair scope:

  • 126c023 — restore and retry failed nested TUI invalidations without reviving disposed/reset work; added real-component throw-once/disposal regressions.
  • dc32f2d — continue forwarding requested thinking unchanged while reporting Pi's effective session.thinkingLevel in running/final details.
  • 71b95ad — make compatibility scripts cwd-independent and Windows-safe (fileURLToPath, shell-free npm CLI invocation, complete subprocess diagnostics), with Windows CI execution.

Pre-existing child-runtime semantics are tracked separately in #17.

Verification is green: typecheck, 430 unit tests, 16 E2E tests, snapshots, audit, exact-floor compatibility, current-Pi compatibility, package-host smoke, and all five PR checks including the expanded Windows compatibility run.

@ofriw ofriw 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.

Note: This review was generated by an AI agent. If you'd like to talk with other humans, drop by our Discord!


Nice progress overall, but there’s one blocking portability issue in the new compatibility scripts. Both scripts/test-compat-current.mjs and scripts/test-package-host.mjs derive the repo root with new URL("..", import.meta.url).pathname. That gives you a URL pathname, not a safe filesystem path, so encoded characters like spaces stay encoded and Windows path handling is unreliable. In practice that can break cpSync(root, ...), cwd: root, and tarball path joins depending on where the repo is checked out.

The evidence is straightforward: the project already uses the correct pattern in scripts/run-node-test.mjs (fileURLToPath(import.meta.url) + dirname/resolve), while the two new scripts use .pathname directly. Since these scripts are part of the compatibility proof this PR adds, they need to be robust on the same cross-platform matrix the PR is trying to guarantee. Please switch both scripts to filesystem-path conversion via fileURLToPath(...) and keep the rest of the logic as-is.


Attached is an agent optimized description of the changes in this PR - AGENT_REVIEW.md

@grzegorznowak

Copy link
Copy Markdown
Collaborator Author

@ofriw Thanks for the review. This appears to target the snapshot before current PR head 71b95ad (fix(scripts): make compatibility checks portable).

The flagged .pathname expressions exist in 71b95ad^, but current HEAD replaces both with repoRootFromScript(import.meta.url), implemented using fileURLToPath(),
dirname(), and resolve(). tests/unit/compat-process.test.ts also covers paths containing spaces, Windows npm invocation, and prohibits .pathname in these scripts.

So the concern was valid for the earlier revision, but is resolved at the current PR head.

@grzegorznowak
grzegorznowak requested a review from ofriw July 19, 2026 13:32
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.

2 participants