Skip to content

Add #[Thinking] attribute for extended thinking / reasoning support#162

Open
anilcancakir wants to merge 6 commits intolaravel:0.xfrom
anilcancakir:feature/thinking-support
Open

Add #[Thinking] attribute for extended thinking / reasoning support#162
anilcancakir wants to merge 6 commits intolaravel:0.xfrom
anilcancakir:feature/thinking-support

Conversation

@anilcancakir
Copy link
Contributor

@anilcancakir anilcancakir commented Feb 13, 2026

This PR adds a #[Thinking] attribute that allows agents to opt into extended thinking (reasoning) capabilities offered by modern AI providers. The attribute follows the same pattern as the existing #[MaxTokens], #[Temperature], and #[MaxSteps] attributes.

Motivation

Several major providers now support extended thinking / reasoning modes that significantly improve output quality for complex tasks:

Currently there is no way to configure this through agent attributes.

Usage

use Laravel\Ai\Attributes\Thinking;

// Anthropic — enable with token budget
#[Thinking(budgetTokens: 10000)]
class DeepAnalysisAgent implements Agent { ... }

// OpenAI / Azure OpenAI — set reasoning effort for o1/o3 models
#[Thinking(effort: 'high')]
class ReasoningAgent implements Agent { ... }

// Gemini — both budget and effort level
#[Thinking(budgetTokens: 8000, effort: 'medium')]
class ResearchAgent implements Agent { ... }

// Simply adding the attribute enables thinking (enabled defaults to true)
#[Thinking]
class ThinkingAgent implements Agent { ... }

// Explicitly disable
#[Thinking(enabled: false)]
class StandardAgent implements Agent { ... }

When no #[Thinking] attribute is present, behavior is unchanged — $options->thinking is null and no provider options are sent.

Provider Mapping

Provider Attribute Maps To (Prism Provider Options)
Anthropic budgetTokens thinking.enabled + thinking.budgetTokens
OpenAI effort reasoning.effort
Azure OpenAI effort reasoning.effort (identical to OpenAI)
Gemini budgetTokens, effort thinkingBudget, thinkingLevel
xAI enabled thinking.enabled
Ollama enabled thinking (bool)
DeepSeek enabled thinking.type ("enabled"/"disabled")
Groq enabled, effort reasoning_format: "parsed" + reasoning_effort
Mistral enabled prompt_mode: "reasoning"
OpenRouter enabled include_reasoning (bool)

Changes

  • src/Attributes/Thinking.php — new attribute class with enabled, budgetTokens, and effort parameters
  • src/Gateway/TextGenerationOptions.php — parse #[Thinking] via reflection, add thinking property
  • src/Gateway/Prism/Concerns/CreatesPrismTextRequests.php — map thinking options to provider-specific Prism configurations for all 10 providers in withProviderOptions()

Test Coverage

Test Scenario
test_thinking_attribute_with_budget_tokens_is_parsed #[Thinking(budgetTokens: 10000)] → enabled=true, budgetTokens=10000, effort=null
test_thinking_attribute_with_effort_is_parsed #[Thinking(effort: 'high')] → enabled=true, budgetTokens=null, effort='high'
test_thinking_attribute_with_all_options_is_parsed #[Thinking(budgetTokens: 8000, effort: 'medium')] → all three values parsed
test_thinking_is_null_when_agent_has_no_thinking_attribute No attribute → thinking=null
test_thinking_options_are_correct_for_deepseek_scenario DeepSeek: enabled=true, budgetTokens silently ignored
test_thinking_options_are_correct_for_groq_scenario Groq: effort maps to reasoning_effort
test_thinking_enabled_flag_is_present_for_toggle_providers Mistral/OpenRouter: enabled flag present
test_thinking_effort_maps_to_reasoning_effort_for_azure_and_openai Azure+OpenAI: effort maps to reasoning.effort

All tests pass, Pint clean.

Copilot AI review requested due to automatic review settings February 13, 2026 23:12
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a #[Thinking] attribute that enables agents to configure extended thinking/reasoning capabilities across multiple AI providers (Anthropic, OpenAI, Gemini, xAI, and Ollama). The implementation follows the existing attribute pattern established by #[MaxTokens], #[Temperature], and #[MaxSteps], while introducing a more complex multi-parameter design to accommodate provider-specific options.

Changes:

  • Introduces a new Thinking attribute class with three parameters: enabled, budgetTokens, and effort
  • Extends TextGenerationOptions to parse and store thinking configuration from agent attributes
  • Implements provider-specific mapping logic in CreatesPrismTextRequests to translate the attribute into appropriate Prism provider options

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
src/Attributes/Thinking.php New attribute class defining enabled flag, budget tokens, and effort level parameters
src/Gateway/TextGenerationOptions.php Parses Thinking attribute via reflection and stores configuration as array in thinking property
src/Gateway/Prism/Concerns/CreatesPrismTextRequests.php Maps thinking options to provider-specific formats (Anthropic, OpenAI, Gemini, xAI, Ollama)
tests/Feature/Agents/ThinkingAgent.php Test agent with budgetTokens configuration
tests/Feature/Agents/ThinkingWithEffortAgent.php Test agent with effort configuration
tests/Feature/Agents/ThinkingFullAgent.php Test agent with all thinking parameters
tests/Feature/AgentAttributeTest.php Unit tests verifying attribute parsing for various configurations

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@pushpak1300
Copy link
Member

I really like #166 implementation for this.

@grebe-vladin
Copy link

great feature. it is really needed, without thinking config laravel ai is unusable for many newer models that have thinking baked in

@anilcancakir
Copy link
Contributor Author

I'm updating the PR for latest version now.

…support

Add #[Thinking] attribute to configure extended thinking/reasoning on
AI agents with support for Anthropic (budgetTokens), OpenAI (reasoning
effort), Gemini (thinkingBudget/thinkingLevel), xAI, and Ollama.

Includes test coverage for all attribute parsing combinations.
- Use null-safe array_filter callbacks to preserve false/0 values
- Merge OpenAI reasoning options with existing provider options to
  prevent overwriting structured output schema configuration
- Add docblock to Thinking attribute documenting valid effort values
- Extract single newInstance() call in TextGenerationOptions to avoid
  redundant reflection instantiation
@anilcancakir anilcancakir force-pushed the feature/thinking-support branch from 825b7f9 to 43647f0 Compare February 24, 2026 15:22
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@anilcancakir
Copy link
Contributor Author

Updated with last code and providers.

@MistreanuIonutCosmin
Copy link

What keeps this from being merged?

@martindruart
Copy link

Hi, this feature is a must have, thks for the work !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants