test(providers): add native-orphan wire fixture (verbatim-replay baseline)

Freeze the wire payload for an unanswered native tool_use whose id is
mirrored top-level in tool_calls (the P1 invariant).  This pins the
verbatim-replay orphan path each provider repairs today — Anthropic via
the provider_content tool_use synthesis, the OpenAI-compatible lane via
sanitize_messages — as the baseline the repair-unification change is
proven byte-identical against.
This commit is contained in:
Patrick Buckley
2026-06-03 01:52:27 -07:00
parent 98cee4d20c
commit 4ebaeb8f15
6 changed files with 326 additions and 0 deletions
@@ -0,0 +1,70 @@
{
"cache_control": {
"type": "ephemeral"
},
"max_tokens": 4096,
"messages": [
{
"content": "Think about the weather.",
"role": "user"
},
{
"content": [
{
"signature": "sig-abc",
"thinking": "The user wants weather.",
"type": "thinking"
},
{
"text": "Let me check.",
"type": "text"
},
{
"id": "call_1",
"input": {
"city": "Paris"
},
"name": "get_weather",
"type": "tool_use"
}
],
"role": "assistant"
},
{
"content": [
{
"content": "Tool execution was cancelled.",
"is_error": true,
"tool_use_id": "call_1",
"type": "tool_result"
}
],
"role": "user"
}
],
"model": "claude-sonnet-4-6",
"output_config": {
"effort": "medium"
},
"temperature": 1.0,
"thinking": {
"type": "adaptive"
},
"tools": [
{
"description": "Look up the weather for a city.",
"input_schema": {
"properties": {
"city": {
"type": "string"
}
},
"required": [
"city"
],
"type": "object"
},
"name": "get_weather"
}
]
}
@@ -0,0 +1,70 @@
{
"cache_control": {
"type": "ephemeral"
},
"max_tokens": 4096,
"messages": [
{
"content": "Think about the weather.",
"role": "user"
},
{
"content": [
{
"signature": "sig-abc",
"thinking": "The user wants weather.",
"type": "thinking"
},
{
"text": "Let me check.",
"type": "text"
},
{
"id": "call_1",
"input": {
"city": "Paris"
},
"name": "get_weather",
"type": "tool_use"
}
],
"role": "assistant"
},
{
"content": [
{
"content": "Tool execution was cancelled.",
"is_error": true,
"tool_use_id": "call_1",
"type": "tool_result"
}
],
"role": "user"
}
],
"model": "claude-opus-4-8",
"output_config": {
"effort": "medium"
},
"thinking": {
"display": "summarized",
"type": "adaptive"
},
"tools": [
{
"description": "Look up the weather for a city.",
"input_schema": {
"properties": {
"city": {
"type": "string"
}
},
"required": [
"city"
],
"type": "object"
},
"name": "get_weather"
}
]
}
@@ -0,0 +1,54 @@
{
"max_tokens": 4096,
"messages": [
{
"content": "Think about the weather.",
"role": "user"
},
{
"content": "Let me check.",
"role": "assistant",
"tool_calls": [
{
"function": {
"arguments": "{\"city\": \"Paris\"}",
"name": "get_weather"
},
"id": "call_1",
"type": "function"
}
]
},
{
"content": "Tool execution was cancelled.",
"role": "tool",
"tool_call_id": "call_1"
}
],
"model": "gemini-2.5-pro",
"stream": true,
"stream_options": {
"include_usage": true
},
"temperature": 0.5,
"tools": [
{
"function": {
"description": "Look up the weather for a city.",
"name": "get_weather",
"parameters": {
"properties": {
"city": {
"type": "string"
}
},
"required": [
"city"
],
"type": "object"
}
},
"type": "function"
}
]
}
@@ -0,0 +1,54 @@
{
"max_completion_tokens": 4096,
"messages": [
{
"content": "Think about the weather.",
"role": "user"
},
{
"content": "Let me check.",
"role": "assistant",
"tool_calls": [
{
"function": {
"arguments": "{\"city\": \"Paris\"}",
"name": "get_weather"
},
"id": "call_1",
"type": "function"
}
]
},
{
"content": "Tool execution was cancelled.",
"role": "tool",
"tool_call_id": "call_1"
}
],
"model": "gpt-4o-mini",
"stream": true,
"stream_options": {
"include_usage": true
},
"temperature": 0.5,
"tools": [
{
"function": {
"description": "Look up the weather for a city.",
"name": "get_weather",
"parameters": {
"properties": {
"city": {
"type": "string"
}
},
"required": [
"city"
],
"type": "object"
}
},
"type": "function"
}
]
}
@@ -0,0 +1,55 @@
{
"include": [
"reasoning.encrypted_content"
],
"input": [
{
"content": "Think about the weather.",
"role": "user",
"type": "message"
},
{
"content": "Let me check.",
"role": "assistant",
"type": "message"
},
{
"arguments": "{\"city\": \"Paris\"}",
"call_id": "call_1",
"name": "get_weather",
"type": "function_call"
},
{
"call_id": "call_1",
"output": "Tool execution was cancelled.",
"type": "function_call_output"
}
],
"max_output_tokens": 4096,
"model": "gpt-5",
"prompt_cache_retention": "24h",
"reasoning": {
"effort": "medium"
},
"store": false,
"stream": true,
"tools": [
{
"description": "Look up the weather for a city.",
"name": "get_weather",
"parameters": {
"properties": {
"city": {
"type": "string"
}
},
"required": [
"city"
],
"type": "object"
},
"strict": false,
"type": "function"
}
]
}
+23
View File
@@ -211,6 +211,25 @@ FIX_NATIVE_REASONING: list[dict[str, Any]] = [
{"role": "tool", "tool_call_id": "call_1", "content": "18C, clear."},
]
# Native reasoning lane with an UNANSWERED tool_use — the verbatim-replay orphan.
# The native ``tool_use`` is mirrored top-level in ``tool_calls`` (the P1 invariant),
# so the send-time repair can synthesize its cancellation result by reading
# ``tool_calls`` alone. Exercises the Anthropic verbatim-replay branch that the old
# per-provider ``pc_tool_ids`` synthesis covered.
FIX_NATIVE_ORPHAN: list[dict[str, Any]] = [
{"role": "user", "content": "Think about the weather."},
{
"role": "assistant",
"content": "Let me check.",
"_provider_content": [
{"type": "thinking", "thinking": "The user wants weather.", "signature": "sig-abc"},
{"type": "text", "text": "Let me check."},
{"type": "tool_use", "id": "call_1", "name": "get_weather", "input": {"city": "Paris"}},
],
"tool_calls": [_tc("call_1")],
},
]
# Multipart user content (image attachment as the provider receives it today).
FIX_MULTIPART: list[dict[str, Any]] = [
{
@@ -249,6 +268,10 @@ _FIXTURES: dict[str, tuple[list[dict[str, Any]], dict[str, Any]]] = {
FIX_NATIVE_REASONING,
{"tools": _TOOLS, "replay_reasoning_to_model": True},
),
"native_orphan": (
FIX_NATIVE_ORPHAN,
{"tools": _TOOLS, "replay_reasoning_to_model": True},
),
"multipart": (FIX_MULTIPART, {}),
"operator_system": (FIX_OPERATOR_SYSTEM, {"tools": _TOOLS}),
}