Files
openclaw/docs/tools/thinking.md
Peter Steinberger bb46b79d3c refactor: internalize OpenClaw agent runtime (#85341)
* refactor: extract agent core package

Introduce packages/agent-core as the OpenClaw-owned home for reusable agent loop, harness, session, prompt, and runtime dependency contracts.

* refactor: extract shared llm runtime

Move provider model registries, stream wrappers, OAuth helpers, and LLM utilities into src/llm with plugin-sdk barrels instead of depending on the old embedded runtime layout.

* refactor: remove pi runtime internals

Rename remaining Pi-shaped agent surfaces to OpenClaw agent runtime names, delete obsolete Pi docs and package graph checks, and add the third-party notice for incorporated code.

* refactor: tighten agent session runtime

Make agent-core/runtime dependencies explicit, consolidate compaction and session transcript helpers, and move model/session helpers behind OpenClaw-owned contracts.

* refactor: remove static model and pi auth paths

Drop static model catalogs and Pi auth bridges, move model/provider facts to manifest-owned runtime contracts, and harden internal embedded-agent utilities.

* refactor: remove legacy provider compat paths

* docs: remove agent parity notes

* fix: skip provider wildcard metadata parsing

* refactor: share session extension sdk loading

* refactor: inline acpx proxy error formatter

* refactor: fold edit recovery into edit tool

* fix: accept extension batch separator

* test: align startup provider plugin expectations

* fix: restore provider-scoped release discovery

* test: align static asset packaging expectations

* fix: run static provider catalogs during scoped discovery

* fix: add provider entry catalogs for scoped live discovery

* fix: load lightweight provider catalog entries

* fix: refresh provider-scoped plugin metadata

* fix: keep provider catalog entries on release live path

* fix: keep static manifest models in release live checks

* fix: harden release model discovery

* fix: reduce OpenAI live cache probe reasoning

* fix: disable OpenAI cache probe reasoning

* ci: extend OpenAI gateway live timeout

* fix: extend live gateway model budget

* fix: stabilize release validation regressions

* fix: honor provider aliases in model rows

* fix: stabilize release validation lanes

* fix: stabilize release memory qa

* ci: stabilize release validation lanes

* ci: prefer ipv4 for live docker node calls

* fix: restore shared tool-call stream wrapper

* ci: remove legacy pi test shard alias

* fix: clean up embedded agent test drift

* fix: stabilize runtime alias status

* fix: clean up embedded agent ci drift

* fix: restore release ci invariants

* fix: clean up post-rebase runtime drift

* fix: restore release ci checks

* fix: restore release ci after rebase

* fix: remove stale pi runtime path

* test: align compaction runtime expectations

* test: update plugin prerelease expectations

* fix: handle claude live tool approvals

* fix: stabilize release validation gates

* fix: finish agent runtime import

* test: finish post-rebase agent runtime mocks

* fix: keep codex compaction native

* fix: stabilize codex app-server hook tests

* test: isolate codex diagnostic active run

* test: remove codex diagnostic completion race

# Conflicts:
#	extensions/codex/src/app-server/run-attempt.test.ts

* ci: fix full release manifest performance run id

* refactor: narrow llm plugin sdk boundary

* chore: drop generated google boundary stamps

* fix: repair rebase fallout

* fix: clean up rebased runtime references

* fix: decode codex jwt payloads as base64url

* fix: preserve shipped pi runtime alias

* fix: add scoped sdk virtual modules

* fix: decode llm codex oauth jwt as base64url

* fix: avoid stale vertex adc negative cache

* fix: harden tool arg decoding and codeql path

* fix: keep vertex adc negative checks live

* refactor: consolidate codex jwt and edit helpers

* fix: await codex oauth node runtime imports

* fix: preserve sdk tool and notice contracts

* fix: preserve shipped compat config boundaries

* fix: align codex oauth callback host

* fix: terminate agent-core loop streams on failure

* fix: keep codex oauth callback alive during fallback

* ci: include session tools in critical codeql scans

* fix: keep Cloudflare Anthropic provider auth header

* docs: redirect legacy pi runtime pages

* fix: honor bundled web provider compat discovery

* fix: protect session output spill files

* fix: keep legacy agent dir env blocked

* fix: contain auto-discovered skill symlinks

* fix: harden agent core sdk proxy surfaces

* fix: restore approval reaction sdk compat

* fix: keep live docker runs bounded

* fix: keep codex oauth redirect host aligned

* fix: resolve post-rebase agent runtime drift

* fix: redact anthropic oauth parse failures

* fix: preserve responses strict tool shaping

* fix: repair agent runtime rebase cleanup

* docs: redirect retired parity pages

* fix: bound auto-discovered resources to roots

* fix: repair post-rebase agent test drift

* fix: preserve bundled provider allowlist migration

* fix: preserve manifest-owned provider aliases

* fix: declare photon image dependency

* fix: keep provider headers out of proxy body

* fix: preserve shipped env aliases

* fix: refresh control ui i18n generated state

* fix: quote read fallback paths

* fix: preview edits through configured backend

* test: satisfy core test typecheck

* fix: preserve ZAI usage auth fallback

* test: repair codex diagnostic test

* fix: repair agent runtime rebase drift

* test: finish embedded runner import rename

* fix: repair agent runtime rebase integrations

* test: align compaction oauth fallback expectations

* fix: allow sdk-auth session models

* fix: update doctor tool schema import

* fix: preserve bedrock plugin region

* fix: stream harmony-like prose immediately

* ci: include session runtime in codeql shards

* fix: repair latest rebase integrations

* fix: honor explicit codex websocket transport

* fix: keep openai-compatible credentials provider-scoped

* fix: refresh sdk api baseline after rebase

* fix: route cli runtime aliases through openclaw harness

* test: rename stale harness mock expectation

* test: rename embedded agent overflow calls

* test: clean embedded auth test wording

* test: use openclaw stream types in deepinfra cache test

* fix: refresh sdk api baseline on latest main

* fix: honor bundled discovery compat allowlists

* fix: refresh sdk api baseline after latest rebase

* fix: remove stale rebase imports

* test: rename stale model catalog mock

* test: mock renamed doctor runtime modules

* fix: map canonical kimi env auth

* fix: use internal model registry in bench script

* fix: migrate deepinfra provider catalog entry

* fix: enforce builtin tool suppression

* fix: route compaction auth and proxy payloads safely

* refactor: prune unused llm registry leftovers

* test: update codex hooks session import

* test: fix model picker ci coverage

* test: align model picker auth mock types
2026-05-27 19:24:04 +01:00

14 KiB

summary, read_when, title
summary read_when title
Directive syntax for /think, /fast, /verbose, /trace, and reasoning visibility
Adjusting thinking, fast-mode, or verbose directive parsing or defaults
Thinking levels

What it does

  • Inline directive in any inbound body: /t <level>, /think:<level>, or /thinking <level>.
  • Levels (aliases): off | minimal | low | medium | high | xhigh | adaptive | max
    • minimal → "think"
    • low → "think hard"
    • medium → "think harder"
    • high → "ultrathink" (max budget)
    • xhigh → "ultrathink+" (GPT-5.2+ and Codex models, plus Anthropic Claude Opus 4.7 effort)
    • adaptive → provider-managed adaptive thinking (supported for Claude 4.6 on Anthropic/Bedrock, Anthropic Claude Opus 4.7, and Google Gemini dynamic thinking)
    • max → provider max reasoning (Anthropic Claude Opus 4.7; Ollama maps this to its highest native think effort)
    • x-high, x_high, extra-high, extra high, and extra_high map to xhigh.
    • highest maps to high.
  • Provider notes:
    • Thinking menus and pickers are provider-profile driven. Provider plugins declare the exact level set for the selected model, including labels such as binary on.
    • adaptive, xhigh, and max are only advertised for provider/model profiles that support them. Typed directives for unsupported levels are rejected with that model's valid options.
    • Existing stored unsupported levels are remapped by provider profile rank. adaptive falls back to medium on non-adaptive models, while xhigh and max fall back to the largest supported non-off level for the selected model.
    • Anthropic Claude 4.6 models default to adaptive when no explicit thinking level is set.
    • Anthropic Claude Opus 4.7 does not default to adaptive thinking. Its API effort default remains provider-owned unless you explicitly set a thinking level.
    • Anthropic Claude Opus 4.7 maps /think xhigh to adaptive thinking plus output_config.effort: "xhigh", because /think is a thinking directive and xhigh is the Opus 4.7 effort setting.
    • Anthropic Claude Opus 4.7 also exposes /think max; it maps to the same provider-owned max effort path.
    • Direct DeepSeek V4 models expose /think xhigh|max; both map to DeepSeek reasoning_effort: "max" while lower non-off levels map to high.
    • OpenRouter-routed DeepSeek V4 models expose /think xhigh and send OpenRouter-supported reasoning_effort values. Stored max overrides fall back to xhigh.
    • Ollama thinking-capable models expose /think low|medium|high|max; max maps to native think: "high" because Ollama's native API accepts low, medium, and high effort strings.
    • OpenAI GPT models map /think through model-specific Responses API effort support. /think off sends reasoning.effort: "none" only when the target model supports it; otherwise OpenClaw omits the disabled reasoning payload instead of sending an unsupported value.
    • Custom OpenAI-compatible catalog entries can opt into /think xhigh by setting models.providers.<provider>.models[].compat.supportedReasoningEfforts to include "xhigh". This uses the same compat metadata that maps outbound OpenAI reasoning effort payloads, so menus, session validation, agent CLI, and llm-task agree with transport behavior.
    • Stale configured OpenRouter Hunter Alpha refs skip proxy reasoning injection because that retired route could return final answer text through reasoning fields.
    • Google Gemini maps /think adaptive to Gemini's provider-owned dynamic thinking. Gemini 3 requests omit a fixed thinkingLevel, while Gemini 2.5 requests send thinkingBudget: -1; fixed levels still map to the closest Gemini thinkingLevel or budget for that model family.
    • MiniMax (minimax/*) on the Anthropic-compatible streaming path defaults to thinking: { type: "disabled" } unless you explicitly set thinking in model params or request params. This avoids leaked reasoning_content deltas from MiniMax's non-native Anthropic stream format.
    • Z.AI (zai/*) only supports binary thinking (on/off). Any non-off level is treated as on (mapped to low).
    • Moonshot (moonshot/*) maps /think off to thinking: { type: "disabled" } and any non-off level to thinking: { type: "enabled" }. When thinking is enabled, Moonshot only accepts tool_choice auto|none; OpenClaw normalizes incompatible values to auto.

Resolution order

  1. Inline directive on the message (applies only to that message).
  2. Session override (set by sending a directive-only message).
  3. Per-agent default (agents.list[].thinkingDefault in config).
  4. Global default (agents.defaults.thinkingDefault in config).
  5. Fallback: provider-declared default when available; otherwise reasoning-capable models resolve to medium or the nearest supported non-off level for that model, and non-reasoning models stay off.

Setting a session default

  • Send a message that is only the directive (whitespace allowed), e.g. /think:medium or /t high.
  • That sticks for the current session (per-sender by default). Use /think default to clear the session override and inherit the configured/provider default; aliases include inherit, clear, reset, and unpin.
  • /think off stores an explicit off override. It disables thinking until you change or clear the session override.
  • Confirmation reply is sent (Thinking level set to high. / Thinking disabled.). If the level is invalid (e.g. /thinking big), the command is rejected with a hint and the session state is left unchanged.
  • Send /think (or /think:) with no argument to see the current thinking level.

Application by agent

  • Embedded OpenClaw: the resolved level is passed to the in-process OpenClaw agent runtime.
  • Claude CLI backend: non-off levels are passed to Claude Code as --effort when using claude-cli; see CLI backends.

Fast mode (/fast)

  • Levels: on|off|default.
  • Directive-only message toggles a session fast-mode override and replies Fast mode enabled. / Fast mode disabled.. Use /fast default to clear the session override and inherit the configured default; aliases include inherit, clear, reset, and unpin.
  • Send /fast (or /fast status) with no mode to see the current effective fast-mode state.
  • OpenClaw resolves fast mode in this order:
    1. Inline/directive-only /fast on|off override (/fast default clears this layer)
    2. Session override
    3. Per-agent default (agents.list[].fastModeDefault)
    4. Per-model config: agents.defaults.models["<provider>/<model>"].params.fastMode
    5. Fallback: off
  • For openai/*, fast mode maps to OpenAI priority processing by sending service_tier=priority on supported Responses requests.
  • For openai-codex/*, fast mode sends the same service_tier=priority flag on Codex Responses. OpenClaw keeps one shared /fast toggle across both auth paths.
  • For direct public anthropic/* requests, including OAuth-authenticated traffic sent to api.anthropic.com, fast mode maps to Anthropic service tiers: /fast on sets service_tier=auto, /fast off sets service_tier=standard_only.
  • For minimax/* on the Anthropic-compatible path, /fast on (or params.fastMode: true) rewrites MiniMax-M2.7 to MiniMax-M2.7-highspeed.
  • Explicit Anthropic serviceTier / service_tier model params override the fast-mode default when both are set. OpenClaw still skips Anthropic service-tier injection for non-Anthropic proxy base URLs.
  • /status shows Fast only when fast mode is enabled.

Verbose directives (/verbose or /v)

  • Levels: on (minimal) | full | off (default).
  • Directive-only message toggles session verbose and replies Verbose logging enabled. / Verbose logging disabled.; invalid levels return a hint without changing state.
  • /verbose off stores an explicit session override; clear it via the Sessions UI by choosing inherit.
  • Inline directive affects only that message; session/global defaults apply otherwise.
  • Send /verbose (or /verbose:) with no argument to see the current verbose level.
  • When verbose is on, agents that emit structured tool results send each tool call back as its own metadata-only message, prefixed with <emoji> <tool-name>: <arg> when available. These tool summaries are sent as soon as each tool starts (separate bubbles), not as streaming deltas.
  • Tool failure summaries remain visible in normal mode, but raw error detail suffixes are hidden unless verbose is full.
  • When verbose is full, tool outputs are also forwarded after completion (separate bubble, truncated to a safe length). If you toggle /verbose on|full|off while a run is in-flight, subsequent tool bubbles honor the new setting.
  • agents.defaults.toolProgressDetail controls the shape of /verbose tool summaries and progress-draft tool lines. Use "explain" (default) for compact human labels such as 🛠️ Exec: checking JS syntax; use "raw" when you also want the raw command/detail appended for debugging. Per-agent agents.list[].toolProgressDetail overrides the default.
    • explain: 🛠️ Exec: check JS syntax for /tmp/app.js
    • raw: 🛠️ Exec: check JS syntax for /tmp/app.js, node --check /tmp/app.js

Plugin trace directives (/trace)

  • Levels: on | off (default).
  • Directive-only message toggles session plugin trace output and replies Plugin trace enabled. / Plugin trace disabled..
  • Inline directive affects only that message; session/global defaults apply otherwise.
  • Send /trace (or /trace:) with no argument to see the current trace level.
  • /trace is narrower than /verbose: it only exposes plugin-owned trace/debug lines such as Active Memory debug summaries.
  • Trace lines can appear in /status and as a follow-up diagnostic message after the normal assistant reply.

Reasoning visibility (/reasoning)

  • Levels: on|off|stream.
  • Directive-only message toggles whether thinking blocks are shown in replies.
  • When enabled, reasoning is sent as a separate message prefixed with Thinking.
  • stream (Telegram only): streams reasoning into the Telegram draft bubble while the reply is generating, then sends the final answer without reasoning.
  • Alias: /reason.
  • Send /reasoning (or /reasoning:) with no argument to see the current reasoning level.
  • Resolution order: inline directive, then session override, then per-agent default (agents.list[].reasoningDefault), then global default (agents.defaults.reasoningDefault), then fallback (off).

Malformed local-model reasoning tags are handled conservatively. Closed <think>...</think> blocks stay hidden on normal replies, and unclosed reasoning after already visible text is also hidden. If a reply is fully wrapped in a single unclosed opening tag and would otherwise deliver as empty text, OpenClaw removes the malformed opening tag and delivers the remaining text.

Heartbeats

  • Heartbeat probe body is the configured heartbeat prompt (default: Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not infer or repeat old tasks from prior chats. If nothing needs attention, reply HEARTBEAT_OK.). Inline directives in a heartbeat message apply as usual (but avoid changing session defaults from heartbeats).
  • Heartbeat delivery defaults to the final payload only. To also send the separate Thinking message (when available), set agents.defaults.heartbeat.includeReasoning: true or per-agent agents.list[].heartbeat.includeReasoning: true.

Web chat UI

  • The web chat thinking selector mirrors the session's stored level from the inbound session store/config when the page loads.
  • Picking another level writes the session override immediately via sessions.patch; it does not wait for the next send and it is not a one-shot thinkingOnce override.
  • The first option is always the clear-override choice. It shows Inherited: <resolved level>, including Inherited: Off when inherited thinking is disabled.
  • Explicit picker choices use their direct level labels while preserving provider labels when present (for example Maximum for a provider-labeled max option).
  • The picker uses thinkingLevels returned by the gateway session row/defaults, with thinkingOptions kept as a legacy label list. The browser UI does not keep its own provider regex list; plugins own model-specific level sets.
  • /think:<level> still works and updates the same stored session level, so chat directives and the picker stay in sync.

Provider profiles

  • Provider plugins can expose resolveThinkingProfile(ctx) to define the model's supported levels and default.
  • Provider plugins that proxy Claude models should reuse resolveClaudeThinkingProfile(modelId) from openclaw/plugin-sdk/provider-model-shared so direct Anthropic and proxy catalogs stay aligned.
  • Each profile level has a stored canonical id (off, minimal, low, medium, high, xhigh, adaptive, or max) and may include a display label. Binary providers use { id: "low", label: "on" }.
  • Profile hooks receive merged catalog facts when available, including reasoning, compat.thinkingFormat, and compat.supportedReasoningEfforts. Use those facts to expose binary or custom profiles only when the configured request contract supports the matching payload.
  • Tool plugins that need to validate an explicit thinking override should use api.runtime.agent.resolveThinkingPolicy({ provider, model }) plus api.runtime.agent.normalizeThinkingLevel(...); they should not keep their own provider/model level lists.
  • Tool plugins with access to configured custom model metadata can pass catalog into resolveThinkingPolicy so compat.supportedReasoningEfforts opt-ins are reflected in plugin-side validation.
  • Published legacy hooks (supportsXHighThinking, isBinaryThinking, and resolveDefaultThinkingLevel) remain as compatibility adapters, but new custom level sets should use resolveThinkingProfile.
  • Gateway rows/defaults expose thinkingLevels, thinkingOptions, and thinkingDefault so ACP/chat clients render the same profile ids and labels that runtime validation uses.