fix: retry on "thinking block must contain thinking" upstream error
Some clients reuse assistant history from other models when switching to claude with extended thinking enabled. If a prior thinking block lacks the thinking text field, upstream returns: messages.X.content.Y.thinking: each thinking block must contain thinking Add this pattern to isThinkingBlockSignatureError so the existing FilterThinkingBlocksForRetry retry path triggers and rewrites/drops the offending blocks.
This commit is contained in:
parent
771e0ca973
commit
8211aa7066
@ -379,6 +379,37 @@ func TestFilterThinkingBlocksForRetry_RemovesRedactedThinkingAndKeepsValidConten
|
||||
require.Equal(t, "Visible", content0["text"])
|
||||
}
|
||||
|
||||
func TestFilterThinkingBlocksForRetry_DropsThinkingBlockWithEmptyContent(t *testing.T) {
|
||||
// 跨模型场景:其他模型回过的 assistant 历史里携带了 type=thinking 但 thinking 字段为空,
|
||||
// 喂给开启 extended thinking 的 claude 时上游会报:
|
||||
// "messages.1.content.0.thinking: each thinking block must contain thinking"
|
||||
// 重试应当把空 thinking 块丢弃,并保留其它有效内容。
|
||||
input := []byte(`{
|
||||
"thinking":{"type":"enabled","budget_tokens":1024},
|
||||
"messages":[
|
||||
{"role":"user","content":[{"type":"text","text":"Hi"}]},
|
||||
{"role":"assistant","content":[
|
||||
{"type":"thinking","thinking":"","signature":"sig"},
|
||||
{"type":"text","text":"Answer"}
|
||||
]}
|
||||
]
|
||||
}`)
|
||||
|
||||
out := FilterThinkingBlocksForRetry(input)
|
||||
|
||||
var req map[string]any
|
||||
require.NoError(t, json.Unmarshal(out, &req))
|
||||
_, hasThinking := req["thinking"]
|
||||
require.False(t, hasThinking, "top-level thinking should be removed")
|
||||
|
||||
msgs := req["messages"].([]any)
|
||||
assistant := msgs[1].(map[string]any)
|
||||
content := assistant["content"].([]any)
|
||||
require.Len(t, content, 1, "empty thinking block should be dropped, only text remains")
|
||||
require.Equal(t, "text", content[0].(map[string]any)["type"])
|
||||
require.Equal(t, "Answer", content[0].(map[string]any)["text"])
|
||||
}
|
||||
|
||||
func TestFilterThinkingBlocksForRetry_EmptyContentGetsPlaceholder(t *testing.T) {
|
||||
input := []byte(`{
|
||||
"thinking":{"type":"enabled"},
|
||||
|
||||
@ -6765,6 +6765,15 @@ func (s *GatewayService) isThinkingBlockSignatureError(respBody []byte) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// 检测 thinking block 缺少 thinking 字段的错误(跨模型切换时常见:
|
||||
// 其他模型回过的 assistant 历史里有 type=thinking 但没有 thinking 文本,
|
||||
// 喂给开启 extended thinking 的 claude 时会被拒)
|
||||
// 例如: "messages.1.content.0.thinking: each thinking block must contain thinking"
|
||||
if strings.Contains(msg, "thinking block must contain") {
|
||||
logger.LegacyPrintf("service.gateway", "[SignatureCheck] Detected thinking block missing content error")
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user