Skip to content

Request Building

The core purpose of the GodeX bridge is translating an OpenAI Responses API ResponseCreateRequest into a Chat Completions API ChatCompletionCreateRequest. This is not a simple field mapping -- it requires compatibility planning, tool declaration translation, output contract negotiation, input normalization across many item types, and message merging to satisfy Chat Completions constraints. The buildChatCompletionRequest function orchestrates this entire pipeline in a fixed sequence.

At a Glance

StepFunctionOutputSource
1planBridgeCompatibilityCompatibilityPlan with parameter and format decisionsplanner.ts
2planToolsToolPlan with declarations, tool_choice, and decisionstool-plan.ts
3planOutputContractOutputContractPlan with format and synthetic instructionoutput-contract.ts
4normalizeCurrentInput + normalizeResponseItemsNormalizedChatMessage[]input-normalizer.ts
5buildChatMessagesChatCompletionMessageParam[] with merged assistant turnsmessage-builder.ts
6applyToolsrequest.tools and request.tool_choicerequest-builder.ts
7applyRequestOptionsstream, temperature, top_p, max_tokens, reasoningrequest-builder.ts

Pipeline Overview

Input Normalization

The Responses API supports many input item types that have no direct equivalent in the Chat Completions API. normalizeCurrentInput and normalizeResponseItems convert each item type into one or more ChatCompletionMessageParam entries:

Responses Item TypeChat Completions Mapping
message (role: system/user/assistant/developer){ role, content } (developer maps to system)
message with instructionsPrepended as { role: "system", content: instructions }
reasoningAppended as reasoning_content on next assistant message
function_call{ role: "assistant", tool_calls: [{ id, function }] }
function_call_output{ role: "tool", tool_call_id, content }
shell_call{ role: "assistant", tool_calls: [...] } with JSON-serialized action
shell_call_output{ role: "tool", tool_call_id, content } with formatted output
local_shell_call{ role: "assistant", tool_calls: [...] } with JSON-serialized action
local_shell_call_output{ role: "tool", tool_call_id, content }
apply_patch_call{ role: "assistant", tool_calls: [...] } with JSON-serialized operation
apply_patch_call_output{ role: "tool", tool_call_id, content }
custom_tool_call{ role: "assistant", tool_calls: [...] } with { input } payload
custom_tool_call_output{ role: "tool", tool_call_id, content }

Tool Name Mapping

Each tool call uses the provider-side name from the ToolPlan.declarations. The normalizer looks up the requested name and type in the declarations to find the mapped providerName:

Message Merging

The Chat Completions API does not allow consecutive assistant messages with separate tool calls. buildChatMessages merges adjacent assistant messages using four rules:

Previous MessageNext MessageMerge Strategy
Assistant + tool_callsAssistant + tool_callsConcatenate tool_calls arrays
Assistant (text only)Assistant (text only)Merge content strings
Assistant (text only)Assistant + tool_callsMerge text into tool-call message
Assistant + tool_callsAssistant (text only)Merge text into tool-call message
Any otherAny otherPush as separate message

Request Options Mapping

applyRequestOptions conditionally maps each Responses API parameter to the Chat Completions equivalent. A parameter is only forwarded if the provider's capabilities.parameters.supported set includes it:

Responses ParameterChat Completions FieldCondition
stream: truerequest.stream = true + stream_options.include_usageProvider supports stream; usage only if streaming.usage
temperaturerequest.temperatureProvider supports temperature
top_prequest.top_pProvider supports top_p
max_output_tokensrequest.max_tokensProvider supports max_output_tokens
reasoning.effortrequest.reasoning_effort or request.thinkingProvider capability mode: native, boolean, or none
safety_identifierrequest.user_idProvider supports safety_identifier
userrequest.user_idProvider supports user (fallback if no safety_identifier)

Reasoning Effort Mapping

Build Result Structure

buildChatCompletionRequest returns a BuildChatCompletionRequestResult containing:

FieldTypePurpose
requestChatCompletionCreateRequestThe final request to send upstream
compatibilityCompatibilityPlanAll parameter and format decisions
toolsToolPlanTool declarations, tool_choice, and tool decisions
outputOutputContractPlanResponse format handling and validation requirements

Session History Integration

When a request includes a session (from previous_response_id), the session's input_items are normalized and prepended before the current input. The system prefix (consecutive system messages) is extracted first, the synthetic instruction (if any) is inserted after it, then history and current messages follow:

[system messages from instructions] + [synthetic instruction] + [session history] + [current user/assistant messages]

Cross-References

References