Repository navigation
feat: Defer Tools, opt-in defer_loading for tools sent to Meridian - #1
Merged
Merged
Conversation
…Meridian Defer Tools adds `defer_loading: true` to the tools named in `deferTools.names` (pi-extras.json), in each `before_provider_request` payload that goes to Meridian. A request goes to Meridian when the selected model uses `anthropic-messages`, the payload's model id is that model's id, and the model has a Meridian base URL (`deferTools.meridianBaseUrls`, default 127.0.0.1:3456 and localhost:3456) or its request headers carried `x-meridian-agent` (seen in `before_provider_headers`; Pi 1.5.2 resolves provider headers at request time, so `ctx.model.headers` is empty). Other providers get the payload unchanged. It is off by default: with any tool deferred, Meridian 1.89.0 lifts its single-turn cap and every tool-call turn pays an extra hidden model turn. The measured 13-tool list is exported as RECOMMENDED_DEFER_TOOLS and given in the README. Each session freezes its list at its start in a Symbol.for slot, so a config edit or /reload never changes the tools of a running session. The transform is pure: same payload, same bytes; tool and key order kept; the input is not mutated. It never defers read, bash, edit, write, codemode or powershell, keeps an existing defer_loading value, leaves a tool with cache_control loaded (Anthropic rejects cache_control on a deferred tool; Pi puts it on the last tool), and changes nothing when no tool would stay loaded. PI_EXTRAS_DEFER_TOOLS=0 turns it off. It loads second, after Tab Status and before Status Plus and Cache Compaction, so Cache Compaction captures the deferred payload for its warm requests. Pi's own cache warmer replays through onPayload, so it gets the same deferral. Subagent children do not load it.
A resumed session read pi-extras.json again, so a config edit between two runs changed its tools and rewrote its prompt cache. Now a new session writes its frozen list once, at its start, as a `defer-tools/frozen` custom entry (pi.appendEntry), and only when the list is not empty. A resumed, forked or reloaded session takes the latest such entry on its branch (sessionManager.getBranch) and ignores pi-extras.json. A session with an assistant turn and no entry freezes to an empty list, so deferral never starts in the middle of a session. Only a session with no turns reads the config.
…e key Pi puts cache_control on the last tool only while cache retention is not `none`, so skipping such a tool tied the deferred set to that setting, and a retention change in a session changed what Meridian saw. A listed tool is now deferred whether or not it has cache_control, and its cache_control key is removed (Anthropic rejects both on one tool; Meridian rebuilds tools through MCP and never forwards a client's tool cache_control). The deferred set depends only on the frozen list and the tools present. The guard that keeps one tool loaded stays. The docs no longer say that every tool-call turn pays a digest turn: Meridian 1.89.0 keeps tool search without it (upstream #1368 and #1370); older builds send deferred tools in full and add the turn. Default stays off.
jaedync
force-pushed
the
feat/defer-tools
branch
from
November 13, 2026 15:23
d47e769 to
86ca949
Compare
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.
Adds Defer Tools, an opt-in extension that marks a configured list of tools
defer_loading: truein Anthropic requests that pi sends to Meridian. Anthropic tool search then loads them on demand, so their definitions leave the prompt.What it does
before_provider_request. Changes only requests to Meridian (configured base URL, or thex-meridian-agentrequest header). Other providers are unchanged.defer-tools/frozenentry). Resume, fork and/reloaduse the stored list. A session with earlier turns and no entry stays off. A config edit reaches only new sessions, so a running session never changes its tool list.read,bash,edit,write,codemode,powershell, and never defers every tool.cache_control(the API rejects both keys; Meridian does not forward clientcache_control), so pi's cache retention setting cannot change the deferred set.deferTools.namesinpi-extras.json. Kill switch:PI_EXTRAS_DEFER_TOOLS=0.Test plan
node --test tests/defer-tools.test.ts: 30 pass (config, freeze, session entry on resume/fork/reload, Meridian detection, never-defer set, all-deferred guard, cache_control, byte-identical output, no input mutation, extension order).npm test: 0 fail.npm run typecheck,npm run audit:package,npm run test:install,npm run lint:slop: pass.pi -c): one stored entry, 99 to 100% cache hits on every turn.