From 47030bb1685f453b49acdaf3713f490930cdf5b3 Mon Sep 17 00:00:00 2001 From: Shaik-Sirajuddin Date: Mon, 22 Jun 2026 16:15:57 +0530 Subject: [PATCH] fix(responses): preserve author, recipient, encrypted_content in multi-agent items ResponsesMessage had no Author or Recipient fields, and ResponsesMessageContentBlock had no EncryptedContent field. Go's JSON decoder silently drops unknown fields during decode, so these values were stripped out before bifrost re-serialized the request upstream. OpenAI requires all three on collab_tool_call items used by Codex multi_agent_v2 (>=0.141.0): - author: identifies the sending agent on collab_tool_call input items - recipient: identifies the target agent on collab_tool_call input items - encrypted_content: opaque reasoning token on content blocks that must be echoed verbatim on history replay author and recipient use json.RawMessage to survive future schema changes without coupling bifrost to OpenAI's object shape. encrypted_content is a *string (opaque base64 blob). Verified end-to-end: Codex multi_agent_v2 subagent spawn completes successfully through bifrost with all /v1/responses returning 200. Co-Authored-By: Claude Sonnet 4.6 --- core/schemas/responses.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/core/schemas/responses.go b/core/schemas/responses.go index 50b4c1cdd7..b572890cc4 100644 --- a/core/schemas/responses.go +++ b/core/schemas/responses.go @@ -1,6 +1,7 @@ package schemas import ( + "encoding/json" "fmt" "reflect" "strings" @@ -928,6 +929,11 @@ type ResponsesMessage struct { Role *ResponsesMessageRoleType `json:"role,omitempty"` Content *ResponsesMessageContent `json:"content,omitempty"` + // Author and Recipient are required on multi-agent collab_tool_call items. + // Preserved as raw JSON to survive bifrost round-trip without schema coupling. + Author json.RawMessage `json:"author,omitempty"` + Recipient json.RawMessage `json:"recipient,omitempty"` + *ResponsesToolMessage // For Tool calls and outputs CacheControl *CacheControl `json:"cache_control,omitempty"` // Carries cache_control for function_call and function_call_output message types @@ -1018,6 +1024,9 @@ type ResponsesMessageContentBlock struct { FileID *string `json:"file_id,omitempty"` // Reference to uploaded file Text *string `json:"text,omitempty"` Signature *string `json:"signature,omitempty"` // Signature of the content (for reasoning) + // EncryptedContent is required on reasoning content blocks during history replay. + // OpenAI returns it alongside summary_text blocks; it must be echoed back verbatim. + EncryptedContent *string `json:"encrypted_content,omitempty"` *ResponsesInputMessageContentBlockImage *ResponsesInputMessageContentBlockFile