# How Craft Agents Resolve Adaptive Thinking Models That Reject Disabled Thinking States

> Discover how Craft Agents resolves adaptive thinking models that reject disabled thinking states. Learn how Craft Agents ensures API calls succeed while honoring user intent to minimize reasoning.

- Repository: [Craft Ai Agents/craft-agents-oss](https://github.com/craft-ai-agents/craft-agents-oss)
- Tags: deep-dive
- Published: 2026-07-06

---

**Craft Agents detects Mythos-class models using a regex pattern in `isAdaptiveThinkingAlwaysOnModel` and automatically remaps requests for disabled thinking to the lowest-effort adaptive configuration, ensuring API calls succeed while honoring user intent to minimize reasoning.**

The craft-ai-agents/craft-agents-oss repository abstracts LLM reasoning controls behind a unified "thinking level" interface (Off → Low → Medium → High → XHigh → Max). While most Anthropic models support explicit `thinking: { type: 'disabled' }` requests, the newest Mythos-class models (Claude Fable 5 and Mythos 5) ship with adaptive thinking permanently enabled and reject any payload attempting to disable it. This guide explains how the resolver logic handles these constraints to resolve adaptive thinking models that reject disabled thinking states.

## The Mythos-Class Model Constraint

Anthropic’s Mythos-class architecture treats reasoning as a non-disablable core feature. When the Craft Agents UI requests **Off** or **minimizeThinking** for these models, sending `thinking: { type: 'disabled' }` to the Messages API results in a validation error. The system must therefore translate "no reasoning" intent into the lowest possible reasoning intensity that the model accepts.

## Detecting Adaptive-Always-On Models

Before resolving thinking options, the system identifies restricted models using the `isAdaptiveThinkingAlwaysOnModel` helper function defined in [`packages/shared/src/config/models.ts`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/packages/shared/src/config/models.ts). This function applies a case-insensitive regex to the model identifier:

```typescript
// packages/shared/src/config/models.ts
export function isAdaptiveThinkingAlwaysOnModel(modelId: string): boolean {
  return /claude-(fable|mythos)/i.test(modelId);
}

```

Any model ID matching `claude-fable` or `claude-mythos` triggers the adaptive-always-on code path, signaling that the resolver cannot emit disabled-thinking directives for these specific backends.

## The Resolution Logic in `resolveClaudeThinkingOptions`

The core resolution happens in [`packages/shared/src/agent/claude-agent.ts`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/packages/shared/src/agent/claude-agent.ts) within the `resolveClaudeThinkingOptions` function. This method accepts a `thinkingLevel`, `model` string, and `minimizeThinking` boolean, then branches based on model capabilities.

When the user requests minimized thinking (or selects "Off"), the resolver checks the `adaptiveAlwaysOn` flag:

```typescript
// packages/shared/src/agent/claude-agent.ts (excerpt)
export function resolveClaudeThinkingOptions(args: {
  thinkingLevel: ThinkingLevel;
  model: string;
  providerType?: BackendConfig['providerType'];
  minimizeThinking: boolean;
}): Partial<Options> {
  const { thinkingLevel, model, minimizeThinking } = args;
  const isClaude = isClaudeModel(model);
  const effort = THINKING_TO_EFFORT[thinkingLevel];
  const isHaiku = model.toLowerCase().includes('haiku');
  const supportsAdaptiveThinking = isClaude && !isHaiku;
  const adaptiveAlwaysOn = isAdaptiveThinkingAlwaysOnModel(model);

  // "Off" or minimizeThinking path
  if (minimizeThinking || !isClaude || !effort) {
    if (adaptiveAlwaysOn) {
      // Mythos-class models cannot accept disabled thinking
      return { thinking: { type: 'adaptive' }, effort: 'low' };
    }
    return supportsAdaptiveThinking
      ? { thinking: { type: 'disabled' } }
      : { maxThinkingTokens: 0 };
  }

  // Normal adaptive path
  if (supportsAdaptiveThinking) {
    return { thinking: { type: 'adaptive' }, effort };
  }

  return { maxThinkingTokens: getThinkingTokens(thinkingLevel, model) };
}

```

**Key insight:** When `adaptiveAlwaysOn` is true, the resolver swaps the disabled-thinking directive for `{ thinking: { type: 'adaptive' }, effort: 'low' }`. This satisfies the API contract while keeping reasoning intensity at its minimum viable level.

## Fallback Strategies for Legacy Models

For non-Claude models or legacy Anthropic models that lack adaptive thinking support (such as Haiku variants), the resolver bypasses the `thinking` object entirely. Instead, it invokes `getThinkingTokens()` from [`packages/shared/src/agent/thinking-levels.ts`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/packages/shared/src/agent/thinking-levels.ts) to return a static `maxThinkingTokens` budget. This ensures consistent behavior across diverse backend providers even when the adaptive thinking paradigm does not apply.

## Practical Implementation Examples

### Example 1: Mythos-Class Model (Fable 5)

When resolving options for a model that rejects disabled states, the function returns the minimal adaptive configuration:

```typescript
import { resolveClaudeThinkingOptions } from '@/agent/claude-agent';

const opts = resolveClaudeThinkingOptions({
  thinkingLevel: 'off',
  model: 'claude-fable-5',
  minimizeThinking: true,
});

console.log(opts);
// Output: { thinking: { type: 'adaptive' }, effort: 'low' }

```

This prevents the API from rejecting the request while respecting the user’s desire to minimize computational overhead.

### Example 2: Standard Adaptive Model (Opus 4.8)

For standard models that support explicit disablement, the resolver follows the normal path:

```typescript
const opts = resolveClaudeThinkingOptions({
  thinkingLevel: 'high',
  model: 'claude-opus-4-8',
  minimizeThinking: false,
});

console.log(opts);
// Output: { thinking: { type: 'adaptive' }, effort: 'high' }

```

### Example 3: Non-Claude Provider (Token Budget Fallback)

When the backend is not Anthropic, the system falls back to token-based controls:

```typescript
const opts = resolveClaudeThinkingOptions({
  thinkingLevel: 'low',
  model: 'openai-gpt-4',
  minimizeThinking: false,
});

console.log(opts);
// Output: { maxThinkingTokens: 2000 }

```

## Summary

- **Mythos-class models** (Claude Fable 5 / Mythos 5) require adaptive thinking and reject `type: 'disabled'` payloads.
- The **`isAdaptiveThinkingAlwaysOnModel`** regex detector in [`packages/shared/src/config/models.ts`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/packages/shared/src/config/models.ts) identifies these models by matching `/claude-(fable|mythos)/i`.
- The **`resolveClaudeThinkingOptions`** function in [`packages/shared/src/agent/claude-agent.ts`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/packages/shared/src/agent/claude-agent.ts) remaps "Off" requests to `{ thinking: { type: 'adaptive' }, effort: 'low' }` for restricted models.
- Legacy and non-Claude models fall back to **`maxThinkingTokens`** values defined in [`packages/shared/src/agent/thinking-levels.ts`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/packages/shared/src/agent/thinking-levels.ts).
- This resolution strategy is documented in [`packages/shared/CLAUDE.md`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/packages/shared/CLAUDE.md) and ensures API compatibility across the entire model spectrum.

## Frequently Asked Questions

### Which specific models reject disabled thinking states?

The **Claude Fable 5** and **Mythos 5** model classes reject explicit disabled thinking requests. According to the source code in [`packages/shared/src/config/models.ts`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/packages/shared/src/config/models.ts), any model ID matching the regex `/claude-(fable|mythos)/i` is flagged as having adaptive thinking always enabled.

### What configuration does Craft Agents send when I select "Off" for a Mythos model?

Instead of sending `thinking: { type: 'disabled' }`, which the API would reject, Craft Agents automatically substitutes **low-effort adaptive thinking**: `{ thinking: { type: 'adaptive' }, effort: 'low' }`. This configuration satisfies the Messages API requirements while minimizing reasoning intensity.

### How does the resolver handle non-Anthropic models?

For models that are not Claude variants or do not support adaptive thinking (such as Haiku models), `resolveClaudeThinkingOptions` returns a **`maxThinkingTokens`** value derived from `getThinkingTokens()` in [`packages/shared/src/agent/thinking-levels.ts`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/packages/shared/src/agent/thinking-levels.ts). This provides a token-budget-based fallback that works across any LLM backend.

### Where is the thinking-level mapping documented?

The behavior mapping for adaptive thinking and the special handling for Mythos-class models is documented in **[`packages/shared/CLAUDE.md`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/packages/shared/CLAUDE.md)**. This file explains how the UI’s "Off" level translates to API configurations for different model families.