[LLM-Gen] Codex Responses API Subset Analysis¶
Human Motivation¶
I asked the code agent to compare the OpenAI /response API with Codex usage, as I want to know:
- How Codex uses the
/responseAPI - What features offered by the
/responseAPI are not used by Codex
The OpenAI /response API documentation is extensive. It doesn't make sense to analyze it manually.
Generated Docs¶
The following content analyzes the differences between the OpenAI Responses API specification and the Codex Rust implementation (ResponsesApiRequest in codex-rs/codex-api/src/common.rs).
1. Architectural Positioning¶
Codex implements a subset of the OpenAI Responses API with two core architectural differences:
1.1 State Management
| Aspect | OpenAI API | Codex | Trade-off |
|---|---|---|---|
| Conversation state | Server-side (conversation, previous_response_id) | Client-side (ContextManager) | Codex: full control for editing/compression; OpenAI: simpler client logic |
| History transmission | Optional incremental | Required full history | Bandwidth cost mitigated by prompt_cache_key for prefix caching |
| State persistence | OpenAI servers | Local storage | Enables stateless architecture and complex context operations |
| Caching | Built-in conversation cache | prompt_cache_key for prefix caching | Leverages OpenAI's prefix caching to avoid reprocessing |
1.2 Parameter Simplification
Codex removes generative tuning parameters:
- Sampling:
temperature,top_p,top_logprobs - Resource limits:
max_output_tokens,max_tool_calls - Stream options:
stream_options,truncation
Rationale: Optimized for code generation with model defaults. Use OpenAI SDK directly if fine-grained control is needed.
2. API Schema Mapping¶
JSON structure showing OpenAI Responses API request fields with Codex support status:
{
// ===== Core Parameters =====
"model": "[weak] String (no Enum constraint)",
"instructions": "[full] string",
"input": "[subset+extension] Vec<ResponseItem>, see Section 3",
// ===== Tool Control =====
"tools": "[weak] Vec<serde_json::Value> (avoids 12+ type union)",
"tool_choice": "[simplified] string only (e.g. \"auto\"), no object constraint",
"parallel_tool_calls": "[full] boolean",
// ===== Generation Control =====
"temperature": "[not supported] uses model default",
"top_p": "[not supported] uses model default",
"top_logprobs": "[not supported] uses model default",
"max_output_tokens": "[not supported] uses model default",
"max_tool_calls": "[not supported] uses model default",
"reasoning": "[full] { effort?, summary? }",
"text": "[partial] json_schema format only",
"stream": "[full] SSE streaming",
// ===== State Management (architectural difference, not supported) =====
"conversation": "[not supported] Codex uses client-side state",
"previous_response_id": "[not supported] Codex uses client-side state",
"prompt": "[not supported] use input field instead",
"prompt_cache_retention": "[not supported] uses model default",
// ===== Optimization Options =====
"prompt_cache_key": "[full] string key for prefix caching",
"service_tier": "[weak] Option<String> (no Enum constraint)",
"include": "[weak] Vec<String> (no enum validation)",
// ===== Metadata (not supported) =====
"metadata": "[not supported]",
"user": "[not supported] use session-level identifier",
// ===== Other (not supported) =====
"background": "[not supported]",
"context_management": "[not supported]",
"safety_identifier": "[not supported]",
"stream_options": "[not supported]",
"truncation": "[not supported]"
}
Legend:
[full]- Fully implemented[weak]- Implemented but relaxed type constraints (Enum → String)[simplified]- Partial implementation, complex features removed[partial]- Only subset of sub-features supported[not supported]- Not implemented, uses model default or architectural alternative
Coverage:
- By field count: ~50% (13 of 30 fields)
- Weighted by functionality: ~60% (core features complete, tuning params and metadata missing)
3. Input Field Processing¶
OpenAI API accepts 25+ input types. Codex represents all as Vec<ResponseItem> and filters/transforms before transmission.
3.1 Supported OpenAI Standard Types
Sent directly to OpenAI:
| ResponseItem Variant | OpenAI Type |
|---|---|
Message | EasyInputMessage / ResponseOutputMessage |
Reasoning | Reasoning |
FunctionCall | FunctionCall |
FunctionCallOutput | FunctionCallOutput |
WebSearchCall | WebSearchCall |
ImageGenerationCall | ImageGenerationCall |
3.2 Codex-Specific Extensions
Internal types processed by ContextManager::for_prompt() before transmission:
| Type | Purpose | Pre-transmission Processing |
|---|---|---|
LocalShellCall | Local shell command execution | Ensures call_id has corresponding FunctionCallOutput |
CustomToolCall | Custom tool invocation | Ensures call_id has corresponding CustomToolCallOutput |
CustomToolCallOutput | Custom tool result | Kept in history for context |
GhostSnapshot | Compression snapshot (GhostCommit) | Filtered out, not transmitted |
Compaction | Encrypted compression summary | Used for token estimation |
Other | Fallback for unknown types | Forward compatibility |
3.3 Transformation Pipeline
Internal ResponseItem Vec
↓
┌─────────────────────────────────────────┐
│ ContextManager::for_prompt() │
│ │
│ 1. normalize_history() │
│ - ensure_call_outputs_present() │
│ - remove_orphan_outputs() │
│ - rewrite_image_generation_calls() │
│ - strip_images_when_unsupported() │
│ │
│ 2. retain(|item| !GhostSnapshot) │
└─────────────────────────────────────────┘
↓
Ready for OpenAI ResponseItem Vec
↓
JSON Serialization
↓
OpenAI API Request
4. Type Safety and Engineering Trade-offs¶
Codex uses "relaxed exterior, strict interior" typing strategy:
4.1 Weak Types at External Boundaries
model,service_tier,include: Enum → Stringtools: 12+ type union →Vec<serde_json::Value>
Benefits:
- Forward compatibility: new fields/values require no code changes
- Reduced maintenance: avoids syncing OpenAI's massive type definitions
- Decoupled upgrades: API changes don't block compilation
Costs:
- Runtime validation: invalid values rejected at request time
- Lost autocomplete: IDE can't provide enum completion
4.2 Strong Types Internally
inputfield usesVec<ResponseItem>enum for full type safety in memory- Enables complex context operations (editing, compression, rollback) without breaking structure
4.3 Engineering Conclusion
Layered strategy prioritizes flexibility and compatibility at system boundaries (API interaction) while maintaining type safety and maintainability internally (state management).
5. Code Comparison¶
5.1 OpenAI Standard API
const response = await openai.responses.create({
model: "gpt-5",
conversation: "conv_abc123", // server-side state
input: "New user message", // simplified input
temperature: 0.8, // sampling control
max_output_tokens: 4000, // resource limit
tool_choice: { // complex constraint
type: "allowed_tools",
mode: "required",
tools: [{ type: "function", name: "get_weather" }]
}
});
5.2 Codex Implementation
let request = ResponsesApiRequest {
model: "gpt-5".to_string(), // String, no enum
instructions: "System instructions".to_string(),
input: vec![ // full history, ResponseItem enum
/* Message, FunctionCall, FunctionCallOutput, ... */
],
tools: vec![ // Vec<Value>, no types
/* tool definitions as JSON */
],
tool_choice: "auto".to_string(), // simplified string
parallel_tool_calls: true,
reasoning: Some(Reasoning {
effort: Some(ReasoningEffortConfig::Medium),
summary: Some(ReasoningSummaryConfig::Auto),
}),
store: false,
stream: true,
prompt_cache_key: Some(conversation_id),
// no temperature, top_p, max_output_tokens
// no conversation, previous_response_id
};
Document Version: 5.0 (Restructured) Generated: 2025-03-11 Based on: spec.md and codex-rs/codex-api/src/common.rs