Repository navigation
feat: upgrade pi to 1.1.0, gate session reloads and teardown, import the login env - #689
Merged
Merged
Conversation
This was referenced Oct 9, 2026
🌐 Website previewPreview retired when this pull request closed. |
danyaberezun
added this pull request to stack #696
October 9, 2026 07:52
danyaberezun
marked this pull request as ready for review
October 9, 2026 08:00
danyaberezun
requested review from
Olga Lavrichenko (OLavrik),
Rustam Sadykov (SBOne-Kenobi) and
Rinat S (rsolmano)
as code owners
October 9, 2026 08:00
…the login env - pi 1.0.2 → 1.1.0; chats saved under pi's renamed Azure provider (azure-openai-responses → azure) reopen under the new id. - Session teardown emits session_shutdown, bounded by a 3 s budget, and disposes the pi session only after the emission settles. - Resource reloads run only when the session is quiescent; otherwise they are deferred, coalesced and reconsidered at settlement, preflight release and compaction end. Nothing is admitted while a reload runs. - The excluding loader re-resolves its extension set on every reload, built-ins by name honouring -builtin:*. - A GUI-launched host imports the login shell's environment alongside the PATH repair, never overriding what it has and never PI_* / THINKRAIL_*.
…es on every teardown path disposeAllSessions, abandonPreparedEntry and the failed-creation cleanup disposed the pi session right after starting the shutdown emission, which invalidates the extension context the handlers were still using.
danyaberezun
force-pushed
the
mcp-stack/1-pi-lifecycle
branch
from
October 9, 2026 12:12
a1f48c6 to
476e40a
Compare
Collaborator
Author
|
Rebased the whole stack onto |
Olga Lavrichenko (OLavrik)
approved these changes
Oct 9, 2026
4 of 5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
ThinkRail embeds pi 1.0.2. MCP support, which the PRs stacked on this one add, runs on pi's built-in MCP
engine and needs pi 1.1.0, which adds:
agent_settled.aborted(#10607).Two things break on the way:
azure-openai-responsestoazure. Achat saved under the old id no longer reopens ("The chat's saved model is unavailable").
BuildSystemPromptOptionsgainedhiddenTools, andagent_settledgained
aborted.Before anything in ThinkRail keeps long-lived resources per chat, such as an MCP server process, four
gaps in how the host drives a session need closing:
session_shutdownon teardown.AgentSession.dispose()never emitssession_shutdown, soextensions never get to close what they hold when a chat is deleted, its workspace is removed, or the
host quits.
reloadSessionResourcesrefused only while streaming. A reloadcould still land:
construction, so a reload never picked up changed settings or packages.
PATHfrom the loginshell, but imports nothing else from it. A
${VAR}reference that pi resolves then reads empty.Approach
(
RENAMED_PI_PROVIDERS:azure-openai-responses→azure), and the provider-glyph key follows.hiddenToolsandagent_settled.aborted.session_shutdownon every teardown path.dispose(), started synchronously so handlers are runningbefore the synchronous teardown disposes the session.
SESSION_SHUTDOWN_BUDGET_MS, also the host-quit budget), so ahandler that never settles cannot hold teardown.
dispose()runs only after that bounded emission settles, because it invalidatesthe runner the handlers are using.
abandoned through the same cleanup instead of leaking (
abandonPreparedEntry).still waiting for
agent_start, no compaction, no queue requeue holding a reservation.reconsidered at settlement, preflight release and compaction end (
requestSessionReload→reloaded|deferred).question answer, review fix, compaction), and background-command and subagent completions wait.
so the host now rebuilds that array in place before each load. Built-in extensions are resolved by
name and honour
-builtin:*, as pi's own discovery does.LOGIN_ENV_MARKER), feeds both theexisting
PATHrepair and an import of the variables the host doesn't have.PI_*/THINKRAIL_*and shell bookkeeping (PWD,SHLVL, …) never come fromthe shell.
TERMis set, the import is skipped.PATH, so e2e hostsstill never see the developer's environment.
Changes
package.jsoncatalog andbun.lockat pi 1.1.0, plus thepi-thinkrail-workflowand
pi-dagtest fixtures.packages/server/src/agent/agentSessionManager.ts:requestSessionReload, preflight reservations, held reservations for queuerequeues, admission at every run entry);
session_shutdownemission and deferred dispose;abandonPreparedEntry;RENAMED_PI_PROVIDERS.packages/server/src/agent/extensions.ts: the excluding loader re-resolves on every reload(
builtinExtensionNames,relabelDiscoveredExtensions;extraFactoriesareInlineExtensions).packages/shared/src/shellEnv.ts:parseLoginShellEnv,loginShellImports,LOGIN_ENV_MARKER, andresolveShellEnv({ probe }). It builds on fix(shared): always adopt the login-shell PATH at host start #686's always-probePATHrepair.reloadGate.test.ts: immediate reload when idle; deferral while streaming and while a slashcommand is in preflight; a queued-message removal racing a pending reload; no admission during a
reload.
sessionShutdown.test.ts: handlers are awaited; a hanging handler is bounded.piRuntime.test.ts: the re-resolve on every reload, including-builtin:*.runtimeGenerations.test.ts: the renamed-provider reattach.shellEnv.test.ts: import rules, marker parsing, theTERMskip.e2e/fixtures/executables.tsande2e/SPEC.md(the marker-aware fake login shell).packages/server/src/agent/SPEC.md(session lifecycle, reload gate, loader, renamedproviders) and
packages/shared/SPEC.md.Notes for reviewers:
requestSessionReload→deferred, the reconsider hooks) has no production caller yet:its first one is feat: pass each project's trust to pi and name what trusting it loads #690's trust reload. Here it is reached by
reloadGate.test.ts, while the existingreloadSessionResourcespath keeps refusing when the gate is blocked.pi's
mcpandtool-search);piRuntime.test.tsexercises it with a test built-in.removeQueuedSessionis mostly re-indentation: read that hunk with-w(a held reservation intry/finally).Screenshots
Not applicable: no visible frontend change. The only web change is the generated provider-glyph key for
pi's renamed Azure provider; the glyph is the same.
Related issues
No tracked issue. This is part of the MCP support stack (milestone 1); review and merge in order:
Base:
main.Testing
On this PR's tree:
bunx turbo run typecheck --filter='!@thinkrail/desktop'→ 19/19bun test packages/server packages/pi-delegation packages/pi-subagents packages/pi-background-commands packages/pi-todos packages/pi-dag packages/pi-thinkrail-workflow packages/contracts packages/shared packages/artifact-tests→ 1900 pass, 10 skip, 0 failbun test packages/server/src/agent/reloadGate.test.ts packages/server/src/agent/sessionShutdown.test.ts packages/server/src/agent/runtimeGenerations.test.ts packages/server/src/agent/piRuntime.test.ts packages/shared, run twice → 103/103 both timescd apps/web && bun test→ 1574 passbun test ./scripts/→ 91 pass;bunx turbo run test --continuefor every other package (desktop excluded) → 17/17 tasksbun run lint→ clean, no warnings;check:deps,check:boundaries,check:seams,check:spec-surface→ OKbun run e2e→ all 8 shards passed (490 tests)bun run build:binary && bun run smoke:binary→ smoke OKFocused live specs (real Central,
bun run e2e:full <files>):queue,skills-reload,chat-resources,reopen-chat,subagentsandagent→ 9 passed. The completebun run e2e:fullsuite was not run.The complete
bun run e2e:fullsuite ran on the top of the stack (#695), which contains this change: no-agent 8/8 shards; agent 53 passed, 2 failed —error-turn.live.spec.ts:35andvisualize.live.spec.ts:62, which fail onorigin/maintoo.Desktop:
@thinkrail/desktop's typecheck could not run as configured on this machine. Itselectrobun preparestep waits on a shared cache lock that another process holds. Run withoutprepare,cd apps/desktop && tsc --noEmitreports the same 18 electrobun-declaration errors (TS7016/TS7006/TS7031) as onorigin/mainand none from this change. Itsbun testpasses (123 pass, 1 skip, as onorigin/main). This change touches no desktop file.Checklist
bun run lint,bun run typecheck,bun run testbun run e2e, orbun run e2e:fullwhen touching agent behavior)SPEC.md/ top-level specs updated to reflect any boundary, contract, or behavior change