Repository navigation
feat(pi): offer Pi's thinking levels in Ask AI - #1704
Merged
backnotprop merged 4 commits intoOct 5, 2026
Merged
Conversation
The Pi provider reported no reasoningEfforts, so Ask AI showed no thinking dropdown for it and a chosen level never reached the runtime. - piSupportedThinkingLevels (core/model-catalog) derives a model's levels from the get_available_models row's `reasoning` and `thinkingLevelMap`, mirroring the runtime's own getSupportedThinkingLevels: off through high unless the map nulls the level, xhigh and max only when mapped, nothing for a non-reasoning model. The picker therefore never offers a level Pi would clamp away. EFFORT_LABELS gains the missing `off`. - Both providers (Bun and Node) emit reasoningEfforts, with defaultReasoningEffort 'medium' when the model takes it: Pi's own default, matching the review/guide launcher convention. - The session carries options.reasoningEffort and sends set_thinking_level after set_model, because the levels a model accepts depend on the model. With no level chosen nothing is sent, so Pi keeps its configured default. - Model labels are the canonical `provider/id` rather than the CLI display name, so two providers exposing the same model name no longer render as identical rows in the picker. No server, endpoint or UI change was needed: CatalogModel.reasoningEfforts and the effort validation already existed for Claude and Codex. Verified with a fake `pi --mode rpc` in pi-sdk-models.test.ts (6 pass, both runtimes) covering labels and levels, the level sent after the model, and the level left alone when none was chosen. The derivation was also cross-checked against the live runtime's get_available_thinking_levels for 12 sampled models: 10 reasoning models matched exactly, and the 2 non-reasoning ones deliberately get no dropdown where the runtime answers ["off"].
Review feedback on the branch: the model-independent list is what the review/guide launcher already does, so the per-model derivation goes away. - PI_THINKING_LEVELS is the shared knob: off, minimal, low, medium, high, xhigh, in Pi's own order. That is the CLI's documented `--thinking` set and the same list the launcher's picker offers (PI_THINKING in AgentsTab). piSupportedThinkingLevels and the thinkingLevelMap handling are removed. - reasoning stays the caller's check: both providers emit reasoningEfforts only when the discovery row reports the model reasons, so a non-reasoning model still gets no dropdown. - A level the selected model rejects is clamped silently by Pi (off -> minimal, xhigh/max -> high on a model that nulls them), which is the launcher's existing behavior; the picker therefore offers the knob's full range and lets the runtime resolve it. `max` stays out for the same reason it is out there. - pi-sdk-models.test.ts is removed per review.
josdirksen
force-pushed
the
feat/pi-ask-ai-thinking-levels
branch
from
October 5, 2026 09:07
61ce495 to
f954c39
Compare
…ssion-scoped pi - Levels come from each get_available_models row again (piSupportedThinkingLevels, mirroring pi-ai's getSupportedThinkingLevels): no Off where the map nulls it, xhigh and max only where the model maps them, none for a non-reasoning model. The endpoint's effort validation reads these per-model lists unchanged. - Version gate: before pi 0.84.3 (pi 2ff8ba622) RPC set_thinking_level also rewrote the user's global default thinking level. The provider now runs `pi --version` alongside discovery (kept as toolVersion; a session that wants a level shares the same probe) and only offers and sends levels on pi >= 0.84.3. Older or unknown versions: no picker, nothing sent. set_model has the same pre-0.84.3 behaviour; noted in a comment, unchanged. - No defaultReasoningEffort: pi's default level is the user's own setting, which the RPC does not report, so an unpicked level is Auto and nothing is sent. - Labels read "Name (provider)" like OpenCode's, falling back to provider/id only where two rows would still collide. - Restores the fake `pi` test for both runtimes (per-model levels incl. max and no-off, level sent after set_model, nothing on Auto, version gate), plus catalog unit tests.
…fort; one Pi level list - AIConfigBar no longer shows the first listed effort when nothing is picked and the model reports no default (nothing would be sent). It reads Auto and offers an Auto item to go back to the provider's own default (Pi). - The launcher's PI_THINKING is derived from core's PI_THINKING_LEVELS instead of a second hand list (still without max, which --thinking only accepts since pi 0.80.6).
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.
Ask AI's Pi provider now has a thinking-level picker, and the level you pick reaches the Pi session.
What it does
The levels come from each model, as reported by your installed
pi. They are read from eachget_available_modelsrow (reasoning+thinkingLevelMap) with pi's own rule (getSupportedThinkingLevels, mirrored bypiSupportedThinkingLevelsinpackages/core/model-catalog.ts):offthroughhighare offered unless the model's map sets that level tonull.xhighandmaxare offered only when the model's map names them.The endpoint's effort validation already checks against each model's own list, so a level the selected model does not list is never sent.
The level is applied after the model. The session sends
set_thinking_levelafterset_model, because the levels a model accepts depend on the model. With nothing picked, the bar reads Auto, nothing is sent, and pi keeps your own default. Pi does not report a default level, so the catalog does not claim one. The code-review Ask AI bar no longer shows the first listed level as if it were active, and it has an Auto item.Levels need pi 0.84.3 or newer. Before pi 0.84.3 (pi commit 2ff8ba622), RPC
set_thinking_levelalso rewrote the user's global default thinking level in pi's settings. The provider now runspi --versionalongside model discovery. It offers and sends levels only on pi >= 0.84.3. On an older pi, or when the version cannot be read, there is no picker and nothing is sent. The version is kept as the provider'stoolVersion. A session that wants a level before discovery has run uses the same probe, sopi --versionruns once. Pre-0.84.3set_modelhas the same global-persistence behaviour. A code comment notes it, and this PR does not change it.Model labels read
Name (provider), like OpenCode's. Two providers that serve the same model stay distinguishable. If two rows would still have the same label, both fall back toprovider/id. The review/guide launchers' Pi picker is not affected, because it readspi --list-modelsseparately.The launcher's
PI_THINKINGis now built from core'sPI_THINKING_LEVELSand is no longer a second hand-written list. Its behaviour is unchanged: it still leaves outmax, which--thinkingaccepts only on pi 0.80.6 and newer.Tests
packages/ai/providers/pi-sdk-models.test.ts: a fakepi(--version+--mode rpc), run against both the Bun and Node providers. It covers:maxand a model with nooff;Name (provider)labels;set_model;packages/core/model-catalog.test.ts:piCatalogFromRpc(level derivation, label collisions) and the version gate.bun test packages/ai packages/core apps/pi-extension: all pass.DOM_TESTS=1runs of review-editor and ui pass, except fourDocBadgestests that fail only in the combined run. That file is not changed here, and it passes when run alone.bun run typecheck(re-vendors Pi, including the newpi-version.ts) passes.