Replace isExtendedThinkingModel() model-name check with hasSignedThinkingBlocksInHistory()
which scans message history for real Anthropic-signed thinking blocks.
Content-based gating is more robust than model-name checks — works correctly
with custom model IDs, proxied models, and new model releases without code changes.
- Add isSignedThinkingPart() that matches type thinking/redacted_thinking with valid signature
- Skip synthetic parts (injected by previous hook runs)
- GPT reasoning blocks (type=reasoning, no signature) correctly excluded
- Add comprehensive tests: signed injection, redacted_thinking, reasoning negative case, synthetic skip
Inspired by PR #2653 content-based approach, combined with redacted_thinking support from 0732cb85.
Ultraworked with Sisyphus
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Previously, the validator only checked for tool_use parts, causing 'Expected thinking but found text' errors when messages had text content. Renamed hasToolParts to hasContentParts to include both tool_use and text types.
Also added CommentCheckerConfigSchema support for custom prompt configuration.
🤖 Generated with assistance of OhMyOpenCode (https://github.com/code-yeongyu/oh-my-opencode)
- Add thinking-block-validator hook for proactive prevention before API calls
- Enhance session-recovery to include previous thinking content
- Fix hook registration to actually invoke the validator
Addresses extended thinking errors with Claude Opus/Sonnet 4.5 using tool calls.
Related: https://github.com/vercel/ai/issues/7729
Related: https://github.com/sst/opencode/issues/2599