Skip to content

feat: Thought signature support - #20

Closed
Takshil-Kunadia wants to merge 4 commits into
WordPress:trunkfrom
Takshil-Kunadia:feat/thought-signature-support
Closed

Takshil-Kunadia wants to merge 4 commits into
WordPress:trunkfrom
Takshil-Kunadia:feat/thought-signature-support

Conversation

@Takshil-Kunadia

Copy link
Copy Markdown

Closes #14

Summary

Round-trips MessagePart::thoughtSignature on the Anthropic adapter so multi-turn extended-thinking + tool-use exchanges work. Without it, Anthropic API rejects the request because the signature field is missing.

Test plan

  • Inbound verified the Title_Generation Ability in Abilities Explorer, with vendor temporarily upgraded to php-ai-client 1.3.1 and extended thinking. Captured a 384-char signature on the inbound MessagePart.
  • Outbound verified with a multi-turn CLI test: turn 1 produced a thinking + tool_use response; turn 2 echoed the assistant message back (with the captured signature) together with a tool_result. Anthropic accepted turn 2 and returned the final answer confirming the signature field is correctly serialised in the outbound JSON.

@github-actions

github-actions Bot commented Apr 28, 2026 •

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: Takshil-Kunadia <takshil@git.wordpress.org>
Co-authored-by: jeffpaul <jeffpaul@git.wordpress.org>
Co-authored-by: JasonTheAdams <jason_the_adams@git.wordpress.org>
Co-authored-by: felixarntz <flixos90@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@Takshil-Kunadia

Copy link
Copy Markdown
Author

@felixarntz separate question while you're looking at this - whats the plan on bumping wordpress/php-ai-client dep to maybe "^0.4 || ^1.0 || dev-trunk"?

It would let us drop the version compare and write the calls directly. PHPStan would also gain accurate type info instead of being bypassed.

@JasonTheAdams JasonTheAdams left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @Takshil-Kunadia! A couple of questions here. I'm also curious if we need the backwards-compatibility checks since thinking would fail otherwise in earlier versions. But maybe the old failure is better than an invalid method call?

Comment thread src/Models/AnthropicTextGenerationModel.php Outdated
Comment on lines +254 to +256
if (null !== $signature) {
$data['signature'] = $signature;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a condition in which the signature for a thinking part could be null? For my understanding this is a requirement and this being null would mean the data is incomplete and Anthropic is going to throw an error.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes Anthropic always returns signature on thinking blocks. The null check is defensive as getThoughtSignature() returns ?string, and omitting the field when null is the least-bad fallback (single-turn requests work fine without it). Happy to change to fail-fast if you prefer.

@Takshil-Kunadia
Takshil-Kunadia force-pushed the feat/thought-signature-support branch from 5b4e1df to d39dd85 Compare May 7, 2026 10:12
@Takshil-Kunadia

Copy link
Copy Markdown
Author

Thanks, @Takshil-Kunadia! A couple of questions here. I'm also curious if we need the backwards-compatibility checks since thinking would fail otherwise in earlier versions. But maybe the old failure is better than an invalid method call?

Thinking doesn't fail on 0.4.x. It works for single-turn. The guards ensure it continues to work (degraded) rather than crashing with a fatal error or TypeError. Extended thinking works on sdk 0.4.x for single-turn requests, the code path is reachable. Its the multi-turn tool-use continuations that need signatures (added in 1.3.0). So the guards prevent crashes when a 0.4.x user hits this path rather than relying on a different failure mode upstream.

@jeffpaul
jeffpaul requested a review from a team August 24, 2026 17:45
@jeffpaul

Copy link
Copy Markdown
Member

@JasonTheAdams @superdav42 back to you for review

@superdav42 superdav42 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good we just need to remove the version check because we require the 1.3.1 version since this was shipped in WP 7.0

? $partData['signature']
: null;
$messagePartArgs = [$partData['thinking'], MessagePartChannelEnum::thought()];
if (null !== $signature && version_compare(AiClient::VERSION, '1.3.0', '>=')) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (null !== $signature && version_compare(AiClient::VERSION, '1.3.0', '>=')) {
if (null !== $signature) {

Comment on lines +252 to +257
if (method_exists($part, 'getThoughtSignature')) {
$signature = $part->getThoughtSignature();
if (null !== $signature) {
$data['signature'] = $signature;
}
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have php-ai-client 1.3.1 as the min required so we can remove this check now

Suggested change
if (method_exists($part, 'getThoughtSignature')) {
$signature = $part->getThoughtSignature();
if (null !== $signature) {
$data['signature'] = $signature;
}
}
$signature = $part->getThoughtSignature();
if (null !== $signature) {
$data['signature'] = $signature;
}


namespace WordPress\AnthropicAiProvider\Models;

use WordPress\AiClient\AiClient;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
use WordPress\AiClient\AiClient;

@superdav42

Copy link
Copy Markdown
Member

Closing as superseded by #31.

@superdav42 superdav42 closed this Sep 9, 2026
@jeffpaul jeffpaul removed this from the 1.0.5 milestone Oct 1, 2026
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.

Add support for thought tokens count in results

4 participants