You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
PraisonAI exposes a graded reasoning-effort control (praisonai run --thinking off|minimal|low|medium|high, and the Agent.thinking_budget property), but it is currently a dormant, provider-blind, non-persistent knob:
It is mapped only to an extended-thinking token budget (an Anthropic/Gemini-style mechanism), and that budget is not applied to the request pipeline at all.
No provider's native reasoning-effort parameter (reasoning_effort for OpenAI o-series / GPT‑5 / xAI reasoning models) is ever emitted by core.
Reasoning effort is one of the most important cost/quality dials for CLI-first coding workflows. Today, setting it has little or no effect on the actual provider request for a large class of models, and it does not travel with a session.
Current behaviour
The CLI flag is graded and threaded onto the agent:
src/praisonai-code/praisonai_code/cli/commands/run.py:1124 — --thinking (off, minimal, low, medium, high), resolved via thinking_to_budget(...) and set with agent.thinking_budget = thinking_budget (run.py:1984). A code comment (run.py:1878) states it is "a per-invocation override".
The budget is never applied by the core request pipeline. The core module says so explicitly:
src/praisonai-agents/praisonaiagents/thinking/__init__.py — "agent.thinking_budget stores this object on the agent as a hint, but the core Agent request pipeline does not yet apply it automatically."
agent/agent.py stores _thinking_budget (property at ~agent.py:3195) but nothing in llm/ consumes it.
No native reasoning-effort parameter is emitted anywhere in core: a repository-wide search for reasoning_effort under src/praisonai-agents/praisonaiagents/ returns zero matches.
Net effect: on OpenAI/xAI reasoning models --thinking high is effectively a no-op at the provider layer, and on any model the setting is forgotten when a session is resumed.
Desired behaviour
A single, graded, provider-portable reasoning-effort setting that core translates to each provider's native mechanism:
Models without a reasoning control → silently ignored (no error, backward-compatible).
The setting is persisted on the session and restored on --continue/--session, exactly as the model already is (Resuming a session should restore the model it was created with #3685), so effort is sticky across a multi-turn coding session while remaining overridable per invocation.
Uniform 3-way surface: Agent(reasoning_effort="high") (Python), agent: { reasoning_effort: high } (YAML), --thinking/--effort high (CLI) — all resolving to the same core control.
Layer placement
Primary layer: core (praisonaiagents)
Why not core → n/a (this is core). The translation from a unified effort level to each provider's native request parameter belongs in the LLM request pipeline (llm/llm.py), and persistence belongs in the session store (session/store.py) — both core.
Why not wrapper: the wrapper already has the graded CLI flag; it cannot make the setting take effect at the provider layer or persist it in the session record without core support. Wrapper is a secondary touch only.
Why not tools: reasoning effort is a property of the model request, not an agent-callable integration.
Why not plugins: this is core request-shaping and lifecycle state, not an optional lifecycle guardrail/policy.
Secondary touch (optional): wrapper (praisonai-code) — thread --thinking/--effort into the persisted session field and restore it on resume; surface the effort in --output json.
3-way surface (CLI + YAML + Python): yes
Proposed approach
Introduce a normalised reasoning_effort on the LLM request path (reuse the existing off|minimal|low|medium|high levels). Keep thinking_budget as a backward-compatible alias that resolves into the same normalised effort.
In llm/llm.py, when building provider parameters, resolve effort against the detected provider family (the code already classifies providers, e.g. _is_anthropic_model() / provider detection around llm.py:615): emit native reasoning_effort for OpenAI/xAI reasoning models, an extended-thinking thinking budget for Anthropic/Gemini, and nothing for non-reasoning models.
Persist the resolved effort alongside the model on the session record (session/store.py), and restore it on resume in the wrapper next to the existing model-restore logic (run.py ~1266).
Expose the control identically across Python/YAML/CLI; keep off and unset as no-ops with zero overhead when unused (lazy, per existing thinking/__init__.py design notes).
Resolution sketch
llm/llm.py: add a small _resolve_reasoning_params(effort, model) helper returning the provider-appropriate kwargs; call it where request params are assembled on both the custom and OpenAI-native paths.
agent/agent.py: accept reasoning_effort= (string level) in addition to the existing thinking_budget int; normalise both to one internal value.
session/store.py: persist reasoning_effort in the session/model record; run.py: restore it on --continue/--session unless --thinking/--effort overrides.
Docs/tests: a real agentic test that Agent(model="<openai-reasoning-model>", reasoning_effort="high").start("real task") sends reasoning_effort=high to the provider, and that resume restores the effort.
Severity
Medium-High — reasoning effort is a primary cost/quality lever for coding agents; today it is effectively inert at the provider layer for a major model family and is not sticky across a resumed session.
Validation
thinking/__init__.py documents that thinking_budget is not applied by the request pipeline; grep reasoning_effort under praisonaiagents/ returns zero matches, confirming no native reasoning parameter is emitted.
cli/features/thinking.py:THINKING_BUDGET_MAP shows effort is collapsed to a token budget only.
run.py treats --thinking as a per-invocation override; session/store.py persists the model but not effort, so resume cannot restore it.
Summary
PraisonAI exposes a graded reasoning-effort control (
praisonai run --thinking off|minimal|low|medium|high, and theAgent.thinking_budgetproperty), but it is currently a dormant, provider-blind, non-persistent knob:reasoning_effortfor OpenAI o-series / GPT‑5 / xAI reasoning models) is ever emitted by core.--continue) does not restore it — even though the model is restored on resume (Resuming a session should restore the model it was created with #3685).Reasoning effort is one of the most important cost/quality dials for CLI-first coding workflows. Today, setting it has little or no effect on the actual provider request for a large class of models, and it does not travel with a session.
Current behaviour
src/praisonai-code/praisonai_code/cli/commands/run.py:1124—--thinking (off, minimal, low, medium, high), resolved viathinking_to_budget(...)and set withagent.thinking_budget = thinking_budget(run.py:1984). A code comment (run.py:1878) states it is "a per-invocation override".src/praisonai-code/praisonai_code/cli/features/thinking.py—THINKING_BUDGET_MAP = {off: None, minimal: 2000, low: 4000, medium: 8000, high: 16000}.src/praisonai-agents/praisonaiagents/thinking/__init__.py— "agent.thinking_budgetstores this object on the agent as a hint, but the core Agent request pipeline does not yet apply it automatically."agent/agent.pystores_thinking_budget(property at ~agent.py:3195) but nothing inllm/consumes it.reasoning_effortundersrc/praisonai-agents/praisonaiagents/returns zero matches.src/praisonai-agents/praisonaiagents/session/store.pyrecords the model on the session (restored on resume per Resuming a session should restore the model it was created with #3685) but has no reasoning-effort/variant field.Net effect: on OpenAI/xAI reasoning models
--thinking highis effectively a no-op at the provider layer, and on any model the setting is forgotten when a session is resumed.Desired behaviour
reasoning_effort(minimal|low|medium|high).thinkingtoken budget.--continue/--session, exactly as the model already is (Resuming a session should restore the model it was created with #3685), so effort is sticky across a multi-turn coding session while remaining overridable per invocation.Agent(reasoning_effort="high")(Python),agent: { reasoning_effort: high }(YAML),--thinking/--effort high(CLI) — all resolving to the same core control.Layer placement
praisonaiagents)llm/llm.py), and persistence belongs in the session store (session/store.py) — both core.praisonai-code) — thread--thinking/--effortinto the persisted session field and restore it on resume; surface the effort in--output json.Proposed approach
reasoning_efforton the LLM request path (reuse the existingoff|minimal|low|medium|highlevels). Keepthinking_budgetas a backward-compatible alias that resolves into the same normalised effort.llm/llm.py, when building provider parameters, resolve effort against the detected provider family (the code already classifies providers, e.g._is_anthropic_model()/ provider detection aroundllm.py:615): emit nativereasoning_effortfor OpenAI/xAI reasoning models, an extended-thinkingthinkingbudget for Anthropic/Gemini, and nothing for non-reasoning models.session/store.py), and restore it on resume in the wrapper next to the existing model-restore logic (run.py~1266).offand unset as no-ops with zero overhead when unused (lazy, per existingthinking/__init__.pydesign notes).Resolution sketch
llm/llm.py: add a small_resolve_reasoning_params(effort, model)helper returning the provider-appropriate kwargs; call it where request params are assembled on both the custom and OpenAI-native paths.agent/agent.py: acceptreasoning_effort=(string level) in addition to the existingthinking_budgetint; normalise both to one internal value.session/store.py: persistreasoning_effortin the session/model record;run.py: restore it on--continue/--sessionunless--thinking/--effortoverrides.Agent(model="<openai-reasoning-model>", reasoning_effort="high").start("real task")sendsreasoning_effort=highto the provider, and that resume restores the effort.Severity
Medium-High — reasoning effort is a primary cost/quality lever for coding agents; today it is effectively inert at the provider layer for a major model family and is not sticky across a resumed session.
Validation
thinking/__init__.pydocuments thatthinking_budgetis not applied by the request pipeline;grep reasoning_effortunderpraisonaiagents/returns zero matches, confirming no native reasoning parameter is emitted.cli/features/thinking.py:THINKING_BUDGET_MAPshows effort is collapsed to a token budget only.run.pytreats--thinkingas a per-invocation override;session/store.pypersists the model but not effort, so resume cannot restore it.