Skip to content

fix(coding-agent): sync pi v0.80.6 runtime updates - #1718

Merged
flora131 merged 9 commits into
mainfrom
fix/1703-pi-0.80.6-sync
Jul 10, 2026
Merged

fix(coding-agent): sync pi v0.80.6 runtime updates#1718
flora131 merged 9 commits into
mainfrom
fix/1703-pi-0.80.6-sync

Conversation

@flora131

@flora131 flora131 commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator

Summary

Syncs Atomic's Pi-derived dependencies and applicable coding-agent behavior from official earendil-works/pi v0.80.3 through v0.80.6. The implementation audits upstream changes rather than wholesale-replacing Atomic code, ports the relevant runtime fixes, and preserves deliberate Atomic behavior and packaging.

Closes #1703

Changes

  • Updated all issue-listed pi-agent-core, pi-ai, and pi-tui dependency ranges to ^0.80.6, with consistent updates to bun.lock, the root package-lock.json, and packages/coding-agent/npm-shrinkwrap.json; all Atomic workspace package versions remain 0.0.0.
  • Audited 102 upstream coding-agent files across 47 relevant commits and documented each applicable, inherited, already-equivalent, or non-applicable change in research/docs/2026-07-10-pi-0.80.6-sync-audit.md.
  • Ported applicable runtime fixes covering stale compaction usage, lax/null message content, layered model overrides, request-wide pricing tiers, authenticated model restoration, Windows context traversal, auth persistence failures, strict bash timeout validation, session metadata/reset behavior, interactive ordering, and native clipboard packaging/fallbacks.
  • Added model-capability-aware max thinking support across the CLI, settings, SDK/RPC/extension surfaces, Cursor model mapping, workflow stages, and bundled subagents, plus request-wide cost.tiers support for custom models, partial overrides, and extension-registered providers.
  • Propagated v0.80.6 model metadata and max thinking support through the supported coding-agent, workflow, subagent, Cursor, documentation, and test surfaces.
  • Added targeted regression coverage and updated user-facing docs, examples, README content, and only the relevant Unreleased changelog sections.
  • Addressed the latest reviewer feedback by tightening startup registry layering, restricting restoration-only model synthesis, normalizing derived message content without mutating durable entries, handling caller-relative clipboard staging paths, and aligning audit/docs evidence.

Preserved Atomic Divergences

  • Retains Atomic branding, @bastani/* package names, the atomic CLI, .atomic paths, bundled first-party extensions, and compatible loader aliases.
  • Keeps Verbatim Compaction and its necessary provider-context stale-usage guard instead of upstream summary/cut-point compaction.
  • Keeps hashline-only editing, lock-free auth reads with transactional writes, Atomic's timeout ceiling, and Atomic-specific Copilot/Gemini model, retry, sanitization, signature, streaming, and transport behavior.
  • Preserves Atomic's split standalone launcher/archive layout while adding correct all-target native clipboard staging.

Validation

  • Focused reviewer regression tests: 29 passed
  • bun run test:unit: 3,005 passed
  • bun run test:integration: 248 passed, 1 skipped
  • Coding-agent test suite: 2,489 passed, 37 skipped
  • bun run typecheck: passed
  • bun run lint: passed
  • bun run check:file-length: passed
  • bun run check:shrinkwrap: passed
  • Documentation link checks: passed
  • bun install --frozen-lockfile: passed with no worktree changes
  • Commit hooks: passed

Notes

The full upstream disposition, dependency integrity data, preserved divergences, and terminal/runtime QA evidence are recorded in the sync audit (research/docs/2026-07-10-pi-0.80.6-sync-audit.md). No browser QA is applicable because the user-facing changes affect CLI/TUI and runtime behavior rather than browser UI.

Diff footprint: 120 files changed (+2,665 / -284).

flora131 added 7 commits July 9, 2026 23:38
Sync every pi-derived dependency and generated lock surface through the
official 0.80.6 release.

Port the applicable runtime and coding-agent fixes with targeted regression
coverage, carry max-thinking compatibility through Atomic's bundled
surfaces, and preserve Atomic branding, paths, providers, compaction,
editing, and binary-layout divergences.

Document the complete v0.80.3 through v0.80.6 audit and the equivalent or
non-applicable conclusions for issue #1703.

Refs: #1703
Assistant-model: GPT-5.4
Stage every clipboard native target through an isolated Bun install,
preserve tri-state model restoration, and normalize lax persisted messages
before Verbatim Compaction analysis.

Keep streaming custom components ordered without detaching the live
assistant, add production-entry regression coverage, and make inherited
workflow/footer tests deterministic.

Refs: #1703
Assistant-model: GPT-5.4
Record the post-rebase validation matrix, reviewer follow-up evidence, and final end-to-end results for the pi v0.80.6 sync.

Assistant-model: OpenAI GPT-5.4
Preserve disjoint legacy and primary model override entries with complete-entry precedence and source-aware request headers. Resolve caller-relative TMPDIR before entering the repository so normal and skip-deps binary builds stage native bindings correctly from external working directories.

Assistant-model: GPT-5.6
Assistant-model: GPT-5.6 Sol
@mintlify

mintlify Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
bastani 🟢 Ready View Preview Jul 10, 2026, 6:14 PM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@claude

claude Bot commented Jul 10, 2026

Copy link
Copy Markdown

Code Review — pi v0.80.6 sync

Reviewed the substantive runtime changes (dependency/lockfile/doc churn skimmed). This is a high-quality, audit-driven port rather than a wholesale replacement, and the test coverage is genuinely strong (new suites for layered overrides, cost tiers, lax content, auth persistence, timeout validation, clipboard packaging, interactive ordering, restoration paths). Nicely done. A few observations and questions below — mostly confirmations, nothing I'd consider blocking.

Strengths

  • max thinking level is propagated consistently and completely — copilot synthesis, cursor mapper, subagents THINKING_LEVELS/getSupportedThinkingLevels, settings types, TypeBox schema, and docs all move together. No obvious gaps.
  • AuthStorage transactional writes (persistProviderChange) are a real correctness improvement: dropping the optimistic this.data[provider] = credential before persistence, only committing this.data from the locked merged result, and surfacing failures instead of silently swallowing them. The refresh path's synchronizedData capture (assigning this.data only after the lock resolves) is the right pattern. I confirmed the interactive login call site (interactive-auth-login.ts:129) is inside a try/catch that surfaces the error — so the new throw-on-failure contract is handled there.
  • getAncestorDirectories cleanly fixes the Windows drive-root traversal (terminating on parentOf(dir) === dir instead of comparing against resolve("/")).
  • Layered header invalidation (mergeModelRequestHeaders + ModelRequestHeaderSource) is subtle but correct: incoming layers only invalidate prior headers that originated from the same source key before re-applying.
  • normalizeDerivedSessionEntries deriving a normalized path for replay/analysis without mutating durable session entries is the right call — the message === entry.message identity short-circuit avoids needless clones.

Questions / things to confirm

  1. Bash timeout is now a hard error, not a clamp. normalizeTimeoutSeconds/validateExplicitTimeoutSeconds now throw for timeout > 3600, <= 0, or non-finite, whereas the old code clamped into [1, 3600]. That's a deliberate behavior change (and matches upstream), but a model that previously passed e.g. timeout: 7200 and got a silently-clamped 3600 will now get a tool error. Worth making sure the user-facing docs/changelog note the 3600s ceiling explicitly so it reads as intended rather than a regression. Minor: validation now runs twice (once in normalizeTimeoutSeconds, once in createLocalBashOperations.exec) — harmless but redundant.

  2. RESTORABLE_DYNAMIC_MODEL_PROVIDERS is a hardcoded allowlist (cursor, github-copilot, openrouter, vercel-ai-gateway). For a saved model that isn't found in the registry, synthesis is now restricted to these four. This should be fine because statically-configured custom providers (models.json) are already found in the registry and take the found branch — but can you confirm there's no regression for a user-defined OpenAI-compatible gateway whose remote model id later goes absent? That case would now silently drop to undefined instead of synthesizing a fallback.

  3. appendNewChildrenBeforeAttachedChild mutates container.children directly via .splice(). It works (the appended children are already properly attached via addMessageToChat, so this is a pure reorder that avoids re-mounting the streaming anchor) and it's well tested. The only concern is coupling to pi-tui's internal array representation — if Container.children ever becomes a getter returning a copy, this silently no-ops. A one-line comment noting why the direct splice is safe (vs. removeChild/addChild) would help future maintainers.

  4. normalizeMessageContent now switches on role and returns unknown roles unchanged, narrowing normalization to user/assistant/toolResult/custom. Confirm no other role that can carry content: null (e.g. bash-execution-derived messages) reaches a provider unnormalized.

Nits

  • research/docs/2026-07-10-pi-0.80.6-sync-audit.md is a large point-in-time artifact checked into the repo — fine as an audit trail, just flagging it will go stale after the next sync.

Overall this looks careful and well-tested; the questions above are confirmations rather than defects. 🚢-able once #2 and #4 are sanity-checked.

@claude

claude Bot commented Jul 10, 2026

Copy link
Copy Markdown

Review: fix(coding-agent): sync pi v0.80.6 runtime updates

Reviewed the runtime source changes commit-by-commit (skimming the docs/lockfile/changelog churn). Overall this is a high-quality, low-risk sync PR: the ported fixes are faithful to upstream, the divergences called out in the description hold up in the diff, and test coverage is genuinely thorough (new suites for auth persistence, bash timeout validation, lax message content, layered overrides, cost tiers, clipboard packaging, interactive ordering, model-path layering, etc.). Type/lint/length gates and the full test matrix are reported green.

A few notes below — none are blocking.

Strengths

  • Non-mutating normalization. normalizeMessageContent (now role-switched) plus normalizeDerivedSessionEntries build a safe derived path for replay/compaction analysis without rewriting durable session entries. The spread-only clone (message === entry.message ? entry : {...}) keeps identity stable, which matters for the downstream Map/Set keying in session-manager-history.ts.
  • max thinking level is propagated consistently across every surface (settings types, selectors, theme, cursor mapper, subagents, workflows schema/fallback/TUI, copilot synthesis) — I didn't find a spot that was missed.
  • Layered model overrides. The modelRequestHeaderSources tracking in model-registry-custom-loader.ts correctly invalidates a lower layer's header only when the higher layer actually owns that key (invalidate guards on sources.get(key) === source), which is the subtle part.
  • Self-correcting review loop. The later commits generalized the initially-hardcoded RESTORABLE_DYNAMIC_MODEL_PROVIDERS set into ModelRegistry.canRestoreUnknownModel() (derived from built-in vs. custom OpenAI-compatible providers) and documented the intentional direct-splice in interactive-child-ordering.ts. Good to see the reviewer feedback folded in rather than left as a TODO.

Observations (non-blocking)

  1. auth-storage.tsset()/remove() now throw. The optimistic in-memory write was removed and persistProviderChange now rethrows on persistence failure (and reloads + rethrows when loadError is already set). This is the correct fix (surfacing silent auth-write failures), but it's a behavior change for callers — anything that previously called set()/remove() fire-and-forget will now propagate an exception. The new interactive-auth-login/auth-storage-persistence tests cover the intended paths; worth a quick scan that no other caller relied on the old swallow-and-continue semantics.

  2. compaction.tsgetLastAssistantUsageInfo timestamp handling. The new forward scan tracks a monotonic latestPrefixTimestamp via Math.max(...). If any message ever carried a non-numeric timestamp, Math.max(x, undefined) → NaN would poison every subsequent >= comparison and stop selecting usage entries. In practice AgentMessage.timestamp is always a number so this is fine, and it mirrors upstream — just flagging it as the one place the logic is sensitive to malformed input.

  3. interactive-child-ordering.ts — direct container.children.splice. Bypassing pi-tui's addChild/removeChild is deliberate (and now commented) to avoid remounting the live streaming component. It does couple to pi-tui's internal assumption that children is a plain reorder-safe array with no separate index/dirty bookkeeping. Fine as long as that holds across pi-tui bumps; may be worth a lightweight test asserting order + anchor-identity preservation so a future pi-tui change can't silently regress it.

Test coverage

Excellent and targeted — each ported fix has a matching regression test, including Windows-path branches (USERPROFILE/HOMEDRIVE/HOMEPATH) and skip-mode clipboard staging. No gaps stood out beyond the optional ordering-invariant test suggested above.

Nice work — clean, well-documented, and the audit doc (research/docs/2026-07-10-pi-0.80.6-sync-audit.md) makes the disposition of every upstream commit easy to verify.

@flora131
flora131 merged commit 60e7c7b into main Jul 10, 2026
9 checks passed
@claude

claude Bot commented Jul 10, 2026

Copy link
Copy Markdown

PR Review — pi v0.80.6 sync

Reviewed the substantive source changes (lock/doc/changelog churn skimmed). This is a large but well-executed sync: the audit doc (research/docs/2026-07-10-pi-0.80.6-sync-audit.md) makes the porting decisions traceable, Atomic divergences are preserved deliberately, and nearly every ported fix ships with focused regression coverage. New helpers are cleanly factored and the validation matrix in the description is reassuring.

Highlights

  • Layered model-override merge (model-registry-custom-loader.ts): the source-aware header invalidation (mergeModelRequestHeaders keyed by "model" vs "modelOverride") is a nice touch — it lets a later layer supersede an earlier one only within the same source class, and deep-clones per-provider override maps instead of aliasing them.
  • resolveRestoredModelReference cleanly separates "exact unauthenticated model = authoritative failure" from "absent id may be reconstructed", and canRestoreUnknownModel scopes synthesis to remote-catalog / custom OpenAI-compatible providers. Good restraint vs. the previous blanket fallback.
  • auth-storage no longer optimistically mutates this.data before a successful persist, reloads on prior loadError, and now surfaces persistence failures by throwing — a real correctness improvement over the silent return.
  • Clipboard staging rework (disposable install, --os * --cpu *, version cross-checks, TMPDIR canonicalization before cd) avoids mutating repo manifests/lockfiles during release builds, with an EXIT trap for cleanup.

Minor notes (non-blocking)

  1. Bash timeout is now a hard error instead of a clamp. normalizeTimeoutSeconds previously clamped any value into [1, 3600]; it now throws via validateExplicitTimeoutSeconds for <= 0, non-finite, or > 3600. Since bashCommand.timeout is model/caller-supplied and reaches this at execution time (bash.ts:307), a request that used to silently clamp (e.g. 7200 to 3600) now fails the tool call. Matches upstream strict intent and is recoverable (the model can retry), but it is a user-visible behavior change — worth a changelog/docs line if not already called out.

  2. Repeated re-normalization of the same path. normalizeDerivedSessionEntries is idempotent but re-runs over the same entries several times in one compaction pass — prepareContextCompaction normalizes, then buildEffectiveContextDeletionFilters(derivedPath) and buildContextDeletionFilteredPath(derivedPath, …) each normalize again (session-manager-history.ts), allocating a fresh array each call. Correct, but avoidable O(n) churn for large sessions; normalizing once at the boundary would tighten it.

  3. OPENAI_COMPATIBLE_APIS is duplicated in both model-registry.ts and model-registry-loader.ts. Minor DRY — a shared const would prevent drift.

  4. appendNewChildrenBeforeAttachedChild captures anchorIndex before append() and reuses it for the final splice. Correct only because append() is assumed to append to the tail (so the anchor index stays stable). A one-line comment noting that assumption would harden it against a future mid-list append.

Test coverage
Strong. New suites cover layered overrides, cost tiers, restoration-only synthesis, lax message content, bash timeout validation, auth persistence, clipboard packaging, interactive ordering, and pi-ai 0.80.6 catalog/pricing behavior. No gaps stood out for the ported logic.

Nothing here is blocking — items 1-4 are polish. Nice work on the audit trail and the divergence-preservation discipline.

@flora131
flora131 deleted the fix/1703-pi-0.80.6-sync branch August 14, 2026 01:16
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.

Sync pi dependencies and coding-agent fixes through v0.80.6

1 participant