Repository navigation
feat(runtime): controllable thinking level for sessions #523
Description
Background
The Maka runtime can already stream thinking content (ThinkingDeltaEvent) and marks reasoning-capable models (reasoning: true in model-catalog.ts), but it cannot control the thinking level. A reasoning model thinks at its default depth with no way to raise, lower, or turn it off. The CLI/TUI inherits this gap, which blocks dogfooding the TUI against reasoning models like GLM, Kimi, or DeepSeek.
Current State
buildProviderOptions(packages/runtime/src/model-factory.ts) returns an empty options object per provider; it never sendsreasoning_effort(OpenAI protocol) orthinking.budget_tokens(Anthropic protocol).- There is no
thinkingLevelfield on session, settings, or the turn request. - The TUI
/modelpicker only switches model id; there is no thinking-variant or level switch. - Pi (sibling
@earendil-works/pi-coding-agent) already has a full thinking-level system:settings.defaultThinkingLevel, per-modelthinkingLevelMap(off/minimal/low/medium/high/xhigh), andsupportsReasoningEffort.
Goal
Let a user pick a thinking level per session from the TUI, mapped to each provider's reasoning-effort / thinking-budget parameter, with the chosen level shown in the statusline.
Proposed Plan
Phase 1 — Provider options
buildProviderOptions accepts a thinking level and emits the protocol-correct parameter:
reasoning_effortforopenai/openai-compatible/zai-coding-plan/ollama/ ark-style providersthinking.budget_tokensforanthropic/claude-subscription/kimi-coding-plan/MiniMax
Phase 2 — Model metadata
Add a thinkingLevelMap to provider/model definitions (mirror Pi's ~/.pi/agent/models.json) so each level maps to the provider-specific value, e.g. { high: 'high', xhigh: 'max' }.
Phase 3 — Plumbing
Add thinkingLevel to session/settings and the turn request, thread it from the session driver through the backend to buildProviderOptions.
Phase 4 — TUI UI
/thinking <level> slash command (and/or a variant row in the model picker); show the current level in the statusline next to the model.
Phase 5 — Transcript
Render ThinkingDeltaEvent blocks (the event type already exists) with a hide toggle (Pi's hideThinkingBlock).
Non-Goals
- Auto-discovering whether a provider supports reasoning effort; rely on the declared
thinkingLevelMap. - Encoding thinking as a separate model id (e.g.
glm-4.6-thinking); keep level as a session-level control. - Per-message thinking-budget overrides in the first version; start with a per-session level.
Acceptance Criteria
- A
/thinkingcommand changes the session thinking level; subsequent turns send the mapped parameter. buildProviderOptionssendsreasoning_effortfor OpenAI-protocol providers andthinking.budget_tokensfor Anthropic-protocol providers.- A reasoning-capable model can be set to
off(no thinking) and to higher levels, observable in the provider request. - The statusline shows the current thinking level.
- Thinking blocks render in the transcript and can be collapsed/hidden.
- Existing provider option behavior (safety settings,
store: false, etc.) is preserved.
References
buildProviderOptions:packages/runtime/src/model-factory.tsThinkingDeltaEvent/ThinkingCompleteEvent:packages/core/src/events.ts- model reasoning capability:
packages/core/src/model-catalog.ts - provider catalog (
zai-coding-plan,ollama,openai-compatible):packages/core/src/llm-connections.ts - Pi reference config:
~/.pi/agent/models.json(thinkingLevelMap),~/.pi/agent/settings.json(defaultThinkingLevel)
Activity
feat(core): add ThinkingLevel type and per-model variant resolver
feat(runtime): map thinking level to ai-sdk provider options
feat(desktop): thinking level switcher in the composer
feat(cli): /thinking slash command and thinking transcript in the TUI
feat(desktop): thinking level menu inside the model picker
feat(cli): /thinking slash command and thinking transcript in the TUI
feat(core): add ThinkingLevel type and per-model variant resolver
feat(runtime): map thinking level to ai-sdk provider options
feat(desktop): thinking level menu inside the model picker
feat(cli): /thinking slash command and thinking transcript in the TUI
feat(core): add ThinkingLevel type and per-model variant resolver
feat(runtime): map thinking level to ai-sdk provider options
feat(desktop): thinking level menu inside the model picker
feat(cli): /thinking slash command and thinking transcript in the TUI
feat(runtime): controllable per-model thinking level for sessions (#528)
Astro-Han commentedon Jul 9, 2026
Closing as done.
Landed in #528 (merged 2026-07-05): per-session
thinkingLevelwithThinkingLevelvocabulary andthinkingVariantsForModel,buildProviderOptions(..., thinkingLevel?)mapping to provider options (reasoningEffort/ thinking budget /thinkingConfig), Desktop model-picker secondary menu + chip, CLI/thinking+ statusline indicator, and transcript thinking rendering.Acceptance criteria from this issue are met. Follow-ups called out in #528 (not required to close here) if wanted later:
settings.defaultThinkingLevel)Related polish after #528 (thinking display/persistence, not the control surface): #580, #585, #592, #633, #636.