codex-proxy / src /types /openai.ts
icebear0828
feat: add Structured Outputs support (response_format → text.format)
53d3b3b
raw
history blame
4.95 kB
/**
* OpenAI API types for /v1/chat/completions compatibility
*/
import { z } from "zod";
// --- Request ---
const ContentPartSchema = z.object({
type: z.string(),
text: z.string().optional(),
}).passthrough();
export const ChatMessageSchema = z.object({
role: z.enum(["system", "developer", "user", "assistant", "tool", "function"]),
content: z.union([z.string(), z.array(ContentPartSchema)]).nullable().optional(),
name: z.string().optional(),
// New format: tool_calls (array, on assistant messages)
tool_calls: z.array(z.object({
id: z.string(),
type: z.literal("function"),
function: z.object({
name: z.string(),
arguments: z.string(),
}),
})).optional(),
tool_call_id: z.string().optional(),
// Legacy format: function_call (single object, on assistant messages)
function_call: z.object({
name: z.string(),
arguments: z.string(),
}).optional(),
});
export const ChatCompletionRequestSchema = z.object({
model: z.string(),
messages: z.array(ChatMessageSchema).min(1),
stream: z.boolean().optional().default(false),
n: z.number().optional().default(1),
temperature: z.number().optional(),
top_p: z.number().optional(),
max_tokens: z.number().optional(),
presence_penalty: z.number().optional(),
frequency_penalty: z.number().optional(),
stop: z.union([z.string(), z.array(z.string())]).optional(),
user: z.string().optional(),
// Codex-specific extensions
reasoning_effort: z.enum(["low", "medium", "high", "xhigh"]).optional(),
service_tier: z.enum(["fast", "flex"]).nullable().optional(),
// New tool format (accepted for compatibility, not forwarded to Codex)
tools: z.array(z.object({
type: z.literal("function"),
function: z.object({
name: z.string(),
description: z.string().optional(),
parameters: z.record(z.unknown()).optional(),
}),
})).optional(),
tool_choice: z.union([
z.enum(["none", "auto", "required"]),
z.object({ type: z.literal("function"), function: z.object({ name: z.string() }) }),
]).optional(),
parallel_tool_calls: z.boolean().optional(),
// Structured output format (JSON mode / JSON Schema)
response_format: z.object({
type: z.enum(["text", "json_object", "json_schema"]),
json_schema: z.object({
name: z.string(),
schema: z.record(z.unknown()),
strict: z.boolean().optional(),
}).optional(),
}).optional(),
// Legacy function format (accepted for compatibility, not forwarded to Codex)
functions: z.array(z.object({
name: z.string(),
description: z.string().optional(),
parameters: z.record(z.unknown()).optional(),
})).optional(),
function_call: z.union([
z.enum(["none", "auto"]),
z.object({ name: z.string() }),
]).optional(),
});
export type ChatMessage = z.infer<typeof ChatMessageSchema>;
export type ChatCompletionRequest = z.infer<typeof ChatCompletionRequestSchema>;
// --- Response (non-streaming) ---
export interface ChatCompletionToolCall {
id: string;
type: "function";
function: {
name: string;
arguments: string;
};
}
export interface ChatCompletionChoice {
index: number;
message: {
role: "assistant";
content: string | null;
reasoning_content?: string | null;
tool_calls?: ChatCompletionToolCall[];
};
finish_reason: "stop" | "length" | "tool_calls" | "function_call" | null;
}
export interface ChatCompletionUsage {
prompt_tokens: number;
completion_tokens: number;
total_tokens: number;
prompt_tokens_details?: {
cached_tokens?: number;
};
completion_tokens_details?: {
reasoning_tokens?: number;
};
}
export interface ChatCompletionResponse {
id: string;
object: "chat.completion";
created: number;
model: string;
choices: ChatCompletionChoice[];
usage: ChatCompletionUsage;
}
// --- Response (streaming) ---
export interface ChatCompletionChunkToolCall {
index: number;
id?: string;
type?: "function";
function?: {
name?: string;
arguments?: string;
};
}
export interface ChatCompletionChunkDelta {
role?: "assistant";
content?: string | null;
reasoning_content?: string | null;
tool_calls?: ChatCompletionChunkToolCall[];
}
export interface ChatCompletionChunkChoice {
index: number;
delta: ChatCompletionChunkDelta;
finish_reason: "stop" | "length" | "tool_calls" | "function_call" | null;
}
export interface ChatCompletionChunk {
id: string;
object: "chat.completion.chunk";
created: number;
model: string;
choices: ChatCompletionChunkChoice[];
usage?: ChatCompletionUsage | null;
}
// --- Error ---
export interface OpenAIErrorBody {
error: {
message: string;
type: string;
param: string | null;
code: string | null;
};
}
// --- Models ---
export interface OpenAIModel {
id: string;
object: "model";
created: number;
owned_by: string;
}
export interface OpenAIModelList {
object: "list";
data: OpenAIModel[];
}