bug: claude-haiku-5-5 rejects thinking.type.enabled (400) — ADAPTIVE_THINKING omits haiku

Open Beginner friendly
#2 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
79/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
typescript

Research direction

Start with the ADAPTIVE_THINKING expression and toModel logic in index.ts, then inspect the existing test.ts cases for model compatibility flags. Check how Haiku 5 model IDs match the family rule and ensure older Haiku 4 IDs remain outside it. Done means the affected catalog entry gets forceAdaptiveThinking and a regression test covers the boundary.

Written by the indexing model from the issue text.

Description

Versions
  • @commandcode/pi-commandcode-provider 0.3.0
  • @earendil-works/pi-coding-agent 1.2.0 / @earendil-works/pi-ai 1.2.0 (as bundled by gentle-shell 4.3.0)
  • Linux x64
Problem

claude-haiku-5-5 cannot be used with any thinking level: every completion fails with HTTP 400, because the model is not marked as requiring adaptive thinking and pi therefore sends the budget form of the parameter. Without a thinking level the same model answers normally.

$ pi -p --model command-code/claude-haiku-5-5:off "reply with exactly: ok"
ok

$ pi -p --model command-code/claude-haiku-5-5:high "reply with exactly: ok"
400 {"type":"error","error":{"type":"invalid_request_error","message":"{\"type\":\"error\",\"error\":{\"type\":\"invalid_request_error\",\"message\":\"\\\"thinking.type.enabled\\\" is not supported for this model. Use \\\"thinking.type.adaptive\\\" and \\\"output_config.effort\\\" to control thinking behavior.\",\"request_id\":\"req_011CgSP7SdnP43dgNJZFsstt\"}"}}

Same request directly against the gateway, to remove pi from the picture:

# budget form — what pi sends today for this model
$ curl -s $BASE/v1/messages -d '{"model":"claude-haiku-5-5","max_tokens":512,
  "thinking":{"type":"enabled","budget_tokens":1024},
  "messages":[{"role":"user","content":"deci ok"}]}'
HTTP 400  "thinking.type.enabled" is not supported for this model.
          Use "thinking.type.adaptive" and "output_config.effort" ...

# adaptive form — accepted, returns a thinking block plus text
$ curl -s $BASE/v1/messages -d '{"model":"claude-haiku-5-5","max_tokens":512,
  "thinking":{"type":"adaptive"},"output_config":{"effort":"high"},
  "messages":[{"role":"user","content":"deci ok"}]}'
HTTP 200  {"content":[{"type":"thinking",...},{"type":"text",...}],
           "usage":{"output_tokens":177,"output_tokens_details":{"thinking_tokens":84}}}
Root cause

index.ts:84 decides which models need the adaptive form:

const ADAPTIVE_THINKING = /(opus[-.](4[-.]6|4[-.]7|4[-.]8|5)|sonnet[-.](4[-.]6|5)|fable[-.]5|mythos[-.]5)/;

and index.ts:137 is the only place that sets the flag:

} else if (api === "anthropic-messages" && ADAPTIVE_THINKING.test(item.id)) {
    model.compat = { forceAdaptiveThinking: true };
}

haiku is absent, so claude-haiku-5-5 never receives forceAdaptiveThinking, and pi-ai branches on exactly that flag (pi-ai, dist/api/anthropic-messages.js):

  • :761 — with the flag: mapThinkingLevelToEffort, and :989 sends thinking: {type: "adaptive", display} plus output_config: {effort}.
  • :771 / :996 — without it: adjustMaxTokensForThinking and thinking: {type: "enabled", budget_tokens}, which this model rejects.

The catalog entry is otherwise fine: claude-haiku-5-5, context_length: 1000000, supported_endpoints: ["/messages"] — the correct anthropic-messages route is chosen; only the thinking form is wrong.

Suggested fix

Add 5.x haiku to the family list, one alternative:

const ADAPTIVE_THINKING = /(opus[-.](4[-.]6|4[-.]7|4[-.]8|5)|sonnet[-.](4[-.]6|5)|haiku[-.]5|fable[-.]5|mythos[-.]5)/;

haiku[-.]5 does not match claude-haiku-4-5-20251001, so the older model keeps the budget form it accepts today. I verified the behaviour above on claude-haiku-5-5; I could not verify claude-haiku-4-5-20251001 directly, because it answers 403 MODEL_NOT_IN_PLAN on my plan before any thinking negotiation, so the scoping of the regex rests on the documented family rule (adaptive from Opus 4.6 / Sonnet 4.6 / Fable 5 onward) rather than on a run.

A test.ts case asserting model.compat?.forceAdaptiveThinking per catalog family would catch both this gap and its mirror: a family that gets the flag but still wants the budget form.

Related

#1 is in the same function (toModel) and the same area of the model object, but a different symptom (thinking levels max/minimal from a missing thinkingLevelMap); it does not cover this model or this parameter form.

Dominant language
TypeScript
Stars
21
Forks
0
PR merge metrics
No merged PRs in 30d

Getting set up

This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from CommandCodeAI/pi-commandcode-provider

All issues in CommandCodeAI/pi-commandcode-provider

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.