Skip to content

Add reasoning_effort control to the LLM server - #263

Merged
stikves merged 5 commits into
apple:mainfrom
stikves:sukru/reasoning-effort
Sep 22, 2026
Merged

stikves merged 5 commits into
apple:mainfrom
stikves:sukru/reasoning-effort

Conversation

@stikves

@stikves stikves commented Sep 20, 2026

Copy link
Copy Markdown
Contributor

Adds an OpenAI-compatible reasoning_effort control so callers can set the thinking budget of reasoning models through the chat completions API or a server default.

What this adds

  • ChatCompletionRequest.reasoning_effort (optional string). Canonical values are none, low, medium, high; model-specific values pass through.
  • ReasoningEffort, which maps the value to chat-template keyword arguments and applies request-over-default precedence.
  • The server injects the value through applyChatTemplate(additionalContext:).
  • --reasoning-default <level> sets the server-wide default. --no-thinking is now an alias for --reasoning-default none.

Behavior

A request that omits the field with no default set is unchanged, so current behavior is preserved. A reasoning model picks up the value when its chat template reads one of reasoning_effort, reasoning_strength, or enable_thinking; other models keep their existing output.

Testing

  • ReasoningEffortTests covers the resolver mapping, precedence, and request decoding.
  • Builds and tests pass via xcodebuild -scheme coreai-models-Package.

Opening as a draft for early review. A FoundationModels-path variant (using ContextOptions.reasoningLevel) can follow as a separate change.

Adds an OpenAI-compatible reasoning_effort field to the chat completions request and a
--reasoning-default server flag, so callers can set the thinking budget of reasoning models.
The value maps to chat-template keyword arguments (reasoning_effort, reasoning_strength,
enable_thinking) and is applied through applyChatTemplate(additionalContext:). --no-thinking
becomes an alias for --reasoning-default none. A request that omits the field keeps the
template's own default.
@stikves
stikves force-pushed the sukru/reasoning-effort branch from c8a280b to 1a51f94 Compare September 20, 2026 16:45
stikves and others added 2 commits September 22, 2026 06:58
Make --no-thinking an alias for --reasoning-default none and reject the
contradictory combination of --no-thinking with a non-none default. Gate
the legacy /no_think literal injection on the resolved effort being none
instead of an independent noThinking flag, so the two paths cannot disagree.

Drop the ungrounded reasoning_strength template var (no template in the
repo consumes it); keep reasoning_effort and enable_thinking.

Add resolution/precedence tests for disablesThinking and resolveDefault,
including the contradictory-flags case.
@stikves
stikves marked this pull request as ready for review September 22, 2026 18:00
@stikves stikves self-assigned this Sep 22, 2026
Comment thread swift/Sources/Tools/llm-server/LLMServerMain.swift Outdated
@stikves
stikves merged commit 0f0ce65 into apple:main Sep 22, 2026
3 checks passed
@stikves
stikves deleted the sukru/reasoning-effort branch September 22, 2026 23:43
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.

3 participants