Repository navigation
v0.63.1: Signed Thinking Again
Fixed
-
A thinking block keeps its signature on OpenCode 2.1. The host renamed the reasoning event's payload field from
statetonative(packages/core/src/session/runner/publish-llm-event.tspublishesnative;packages/schema/session-legacy.tsrenames it on the durable events). Plugboard readstateonly, so on 2.1 every thinking block reached the caller withsignature: ""while the reasoning text still arrived, and a client that sent that block back got it refused. The reasoning end now reads either field.Found by the check matrix on a hub running 2.1.4:
api: thinking/count_tokenswent fromthinking block signedon 2.0.32 tothinking block missingon 2.1.4, reproducible on three runs.
The full story
1 commit since v0.63.0, grouped by type and oldest first. Each entry is the commit message as written.
Fixes (1)
fix(session): read the reasoning signature from native on OpenCode 2.1 (e723e8e)
OpenCode 2.1 renamed the reasoning event's payload field from state to native, so on 2.1.4 every thinking block reached the caller with an empty signature while its text still arrived.
Host evidence, both at the tags in anomalyco/opencode:
packages/core/src/session/runner/publish-llm-event.tspublishesnative: native(event.providerMetadata)onsession.reasoning.ended(v2.1.4); v2.0.32 published the same value asstate.packages/schema/session-legacy.tscarries the rename for durable events ("session.reasoning.ended": ["state", "native"]), andSessionMessage.Nativeis documented there as provider-owned replay data keyed by the producing provider's metadata fields, so the value is the same shapesignatureOfalready reads.
Found on the hub after the 2.1.4 upgrade: the check matrix row api: thinking/count_tokens reported thinking block signed on 2.0.32 and thinking block missing on 2.1.4, three runs in a row. The body of the /v1/messages answer carried the thinking text with "signature": "", so the loss was in the plugin, not the provider.
signatureOf handled both the unwrapped and the provider-wrapped form, but the caller only ever passed item.state. The reasoning end now passes item.state ?? item.native, which keeps 2.0.x working (no native there) and restores the signature on 2.1.
Two tests in test/session/collector.test.ts cover the new field (a signature and a redacted block). Both fail with state only; with the fix the collector suite is 99 pass and the full suite 3875 pass, 130 skip, 0 fail. The test helper takes the field name as an argument so the old field stays a case of its own.
A client that replays an unsigned thinking block is refused, so this would have broken every Anthropic thinking conversation at its second turn on 2.1.
Full diff: v0.63.0...v0.63.1