Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion open-sse/handlers/chatCore/nonStreamingClientTranslate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,12 @@ export function translateNonStreamingClientResponse(
item.namespace = identity.namespace;
item.name = identity.name;
}
Object.assign(item, plaintextCollaborationFields(item.namespace, item.name));
// #15088 - the empty marker means "this call was translated from
// plaintext Chat Completions". A native Responses body already carries
// the protocol's own encrypted_function_args (present or absent).
if (responsePayloadFormat !== FORMATS.OPENAI_RESPONSES) {
Object.assign(item, plaintextCollaborationFields(item.namespace, item.name));
}
}
}
} else if (clientResponseFormat === FORMATS.OPENAI) {
Expand Down
6 changes: 6 additions & 0 deletions open-sse/handlers/responseSanitizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -888,12 +888,18 @@ function sanitizeResponsesOutputItem(item: unknown, index: number): JsonRecord |

if (type === "function_call") {
const callId = toString(itemRecord.call_id) || toString(itemRecord.id) || `call_${index}`;
const namespace = toString(itemRecord.namespace);
return {
id: toString(itemRecord.id) || `fc_${callId}`,
type: "function_call",
call_id: callId,
name: toString(itemRecord.name) || "",
arguments: stripZeroWidthToolArgumentJson(itemRecord.arguments),
...(namespace ? { namespace } : {}),
...(itemRecord.status !== undefined ? { status: itemRecord.status } : {}),
...(itemRecord.encrypted_function_args !== undefined
? { encrypted_function_args: itemRecord.encrypted_function_args }
: {}),
};
}

Expand Down
19 changes: 10 additions & 9 deletions open-sse/utils/stream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1787,18 +1787,18 @@ export function createSSEStream(options: StreamOptions = {}) {
parsed.response.output
);
}
// #7936 — restore `namespace` + `name` fields on passthrough
// Responses function_call items for downstream Codex clients.
if (
parsed.type === "response.output_item.added" ||
parsed.type === "response.output_item.done" ||
parsed.type === "response.completed"
) {
// #7936 - restore `namespace` + `name` on passthrough Responses
// function_call items. The restoration mutates `parsed`, so a
// real change must be re-serialized; otherwise the client still
// receives the flattened wire name.
const responsesIdentityRestored =
(parsed.type === "response.output_item.added" ||
parsed.type === "response.output_item.done" ||
parsed.type === "response.completed") &&
restoreResponsesPassthroughFunctionCallIdentity(
parsed as JsonRecord,
requestToolIdentityMap
);
}
if (
parsed.type === "response.completed" &&
passthroughResponsesPendingFunctionCalls.size > 0
Expand Down Expand Up @@ -1843,7 +1843,8 @@ export function createSSEStream(options: StreamOptions = {}) {
textualToolCallBackfilled ||
responsesIdsNormalized ||
usageNormalized ||
responsesCommentaryStrippedFromCompleted
responsesCommentaryStrippedFromCompleted ||
responsesIdentityRestored
) {
output = `data: ${JSON.stringify(parsed)}\n\n`;
injectedUsage = true;
Expand Down
Loading
Loading