CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-openai

The official TypeScript library for the OpenAI API

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

responses-api.mddocs/

Responses API

The Responses API is OpenAI's primary interface for generating model responses. It provides a unified, powerful way to create text, image, and audio responses with support for function calling, tool use, computer use, file search, web search, and streaming. The Responses API replaces the older Chat Completions API as the recommended way to interact with OpenAI models.

Package Information

  • Package Name: openai
  • Resource Path: client.responses
  • Version: 6.9.1+
  • Language: TypeScript
  • Primary Import: import { OpenAI } from 'openai'

Core Imports

import { OpenAI } from "openai";

// Initialize client
const client = new OpenAI({
  apiKey: process.env.OPENAI_API_KEY,
});

// Access responses API
client.responses.create({ /* ... */ });
client.responses.retrieve("resp_id");
client.responses.delete("resp_id");
client.responses.cancel("resp_id");

// Sub-resources
client.responses.inputItems.list("resp_id");
client.responses.inputTokens.count({ /* ... */ });

Basic Usage

import { OpenAI } from "openai";

const client = new OpenAI();

// Simple text response
const response = await client.responses.create({
  model: "gpt-4o",
  input: "What is the capital of France?",
});

console.log(response.output_text);
// "The capital of France is Paris."

// Streaming response
const stream = await client.responses.create({
  model: "gpt-4o",
  input: "Write a poem about TypeScript",
  stream: true,
});

for await (const event of stream) {
  if (event.type === "response.text.delta") {
    process.stdout.write(event.delta);
  }
}

// Multi-turn conversation
const firstResponse = await client.responses.create({
  model: "gpt-4o",
  input: "My name is Alice",
});

const secondResponse = await client.responses.create({
  model: "gpt-4o",
  input: "What's my name?",
  previous_response_id: firstResponse.id,
});
// "Your name is Alice."

Architecture

The Responses API is built around several key components:

  • Response Object: The core response object containing model outputs, metadata, and usage information
  • Input System: Flexible input handling supporting text, images, files, audio, and structured messages
  • Output System: Multi-modal outputs including text, audio, tool calls, and reasoning
  • Streaming Engine: Real-time server-sent events (SSE) for progressive response delivery
  • Tool System: Built-in and custom tools for extending model capabilities
  • Conversation Management: Automatic conversation state tracking and multi-turn dialogue
  • Parsing Helpers: Automatic parsing of structured outputs with type safety

Capabilities

Response Creation

Creates a model response with support for text, images, tools, streaming, and more.

/**
 * Creates a model response. Provide text or image inputs to generate text or JSON outputs.
 * Have the model call your own custom code or use built-in tools like web search or file search.
 *
 * @param body - Response creation parameters
 * @param options - Optional request options (headers, timeout, etc.)
 * @returns Promise<Response> or Promise<Stream<ResponseStreamEvent>> based on stream parameter
 */
function create(
  body: ResponseCreateParams,
  options?: RequestOptions
): APIPromise<Response> | APIPromise<Stream<ResponseStreamEvent>>;

interface ResponseCreateParams {
  /** Model ID like 'gpt-4o' or 'o3' */
  model?: string;

  /** Text, image, or file inputs to the model */
  input?: string | Array<ResponseInputItem> | null;

  /** System/developer message inserted into model context */
  instructions?: string | null;

  /** Whether to stream the response */
  stream?: boolean;

  /** Sampling temperature (0-2) */
  temperature?: number | null;

  /** Nucleus sampling parameter */
  top_p?: number | null;

  /** Maximum output tokens */
  max_output_tokens?: number | null;

  /** Tools the model may call */
  tools?: Array<Tool>;

  /** How to select which tool to use */
  tool_choice?: ToolChoiceOptions | ToolChoiceAllowed | ToolChoiceTypes | ToolChoiceFunction | ToolChoiceMcp | ToolChoiceCustom | ToolChoiceApplyPatch | ToolChoiceShell;

  /** Whether to allow parallel tool calls */
  parallel_tool_calls?: boolean | null;

  /** Previous response ID for multi-turn conversations */
  previous_response_id?: string | null;

  /** Conversation ID for automatic state management */
  conversation?: string | ResponseConversationParam | null;

  /** Text response configuration */
  text?: ResponseTextConfig | null;

  /** Reasoning configuration for reasoning models */
  reasoning?: Reasoning | null;

  /** Metadata key-value pairs */
  metadata?: Metadata | null;

  /** Truncation strategy ('auto' or 'disabled') */
  truncation?: "auto" | "disabled" | null;

  /** Run response in background */
  background?: boolean | null;

  /** Prompt cache key for optimization */
  prompt_cache_key?: string;

  /** Prompt cache retention policy */
  prompt_cache_retention?: "in-memory" | "24h" | null;

  /** Service tier (auto, default, flex, scale, priority) */
  service_tier?: "auto" | "default" | "flex" | "scale" | "priority" | null;

  /** Safety identifier for user tracking */
  safety_identifier?: string;

  /** Prompt template reference */
  prompt?: ResponsePrompt | null;

  /** Whether to store the generated model response for later retrieval via API */
  store?: boolean | null;

  /** Options for streaming responses. Only set this when you set stream: true */
  stream_options?: StreamOptions | null;

  /** Specify additional output data to include in the model response */
  include?: Array<ResponseIncludable> | null;
}

/**
 * Options for streaming responses. Only used when stream: true
 */
interface StreamOptions {
  /** When true, stream obfuscation will be enabled to normalize payload sizes as mitigation against side-channel attacks */
  include_obfuscation?: boolean;
}

Usage Examples:

// Basic text response
const response = await client.responses.create({
  model: "gpt-4o",
  input: "Explain quantum computing in simple terms",
});

// Structured JSON output
const response = await client.responses.create({
  model: "gpt-4o",
  input: "Extract the person's name and email from: John Doe (john@example.com)",
  text: {
    format: {
      type: "json_schema",
      json_schema: {
        name: "PersonInfo",
        strict: true,
        schema: {
          type: "object",
          properties: {
            name: { type: "string" },
            email: { type: "string" },
          },
          required: ["name", "email"],
          additionalProperties: false,
        },
      },
    },
  },
});

// With system instructions
const response = await client.responses.create({
  model: "gpt-4o",
  instructions: "You are a helpful assistant that speaks like a pirate.",
  input: "Tell me about the weather",
});

// Image input
const response = await client.responses.create({
  model: "gpt-4o",
  input: [
    { type: "text", text: "What's in this image?" },
    {
      type: "image",
      image_url: { url: "https://example.com/image.jpg" }
    },
  ],
});

// Multi-turn conversation
const conv1 = await client.responses.create({
  model: "gpt-4o",
  input: "I'm planning a trip to Paris",
});

const conv2 = await client.responses.create({
  model: "gpt-4o",
  input: "What landmarks should I visit?",
  previous_response_id: conv1.id,
});

// With reasoning (o-series models)
const response = await client.responses.create({
  model: "o3-mini",
  input: "Solve this complex math problem: ...",
  reasoning: {
    effort: "high",
  },
});

Response Retrieval

Retrieves a previously created model response.

/**
 * Retrieves a model response with the given ID.
 * Can optionally stream the response if it's still in progress.
 *
 * @param responseID - The unique response ID (e.g., 'resp_abc123')
 * @param query - Optional query parameters
 * @param options - Optional request options
 * @returns Promise<Response> or Promise<Stream<ResponseStreamEvent>>
 */
function retrieve(
  responseID: string,
  query?: ResponseRetrieveParams,
  options?: RequestOptions
): APIPromise<Response> | APIPromise<Stream<ResponseStreamEvent>>;

interface ResponseRetrieveParams {
  /** Additional fields to include in response */
  include?: Array<ResponseIncludable>;

  /** Whether to stream the response */
  stream?: boolean;

  /**
   * When true, stream obfuscation will be enabled. Stream obfuscation adds random
   * characters to an obfuscation field on streaming delta events to normalize
   * payload sizes as a mitigation to certain side-channel attacks. Set to false
   * to optimize for bandwidth if you trust the network links.
   */
  include_obfuscation?: boolean;

  /**
   * The sequence number of the event after which to start streaming. Useful for
   * resuming a stream from a specific point.
   */
  starting_after?: number;
}

type ResponseIncludable =
  | "input_text"
  | "output_text"
  | "output[*].content[*].annotations[*].file_citation.quote"
  | "output[*].content[*].annotations[*].file_citation.file.content"
  | "web_search_call.action.sources"
  | "code_interpreter_call.outputs"
  | "computer_call_output.output.image_url"
  | "file_search_call.results"
  | "message.input_image.image_url"
  | "reasoning.encrypted_content";

Usage Examples:

// Retrieve a response
const response = await client.responses.retrieve("resp_677efb5139a88190b512bc3fef8e535d");

console.log(response.status); // 'completed'
console.log(response.output_text); // Generated text

// Retrieve with additional fields
const response = await client.responses.retrieve(
  "resp_677efb5139a88190b512bc3fef8e535d",
  {
    include: ["input_text", "output_text"],
  }
);

// Stream an in-progress response
const stream = await client.responses.retrieve(
  "resp_677efb5139a88190b512bc3fef8e535d",
  { stream: true }
);

for await (const event of stream) {
  if (event.type === "response.text.delta") {
    process.stdout.write(event.delta);
  }
}

Response Deletion

Deletes a model response permanently.

/**
 * Deletes a model response with the given ID.
 * This operation is permanent and cannot be undone.
 *
 * @param responseID - The unique response ID
 * @param options - Optional request options
 * @returns Promise<void>
 */
function delete(
  responseID: string,
  options?: RequestOptions
): APIPromise<void>;

Usage Examples:

// Delete a response
await client.responses.delete("resp_677efb5139a88190b512bc3fef8e535d");

// Delete with custom timeout
await client.responses.delete(
  "resp_677efb5139a88190b512bc3fef8e535d",
  { timeout: 30000 }
);

Response Cancellation

Cancels an in-progress background response.

/**
 * Cancels a model response with the given ID.
 * Only responses created with background: true can be cancelled.
 *
 * @param responseID - The unique response ID
 * @param options - Optional request options
 * @returns Promise<Response> - The cancelled response object
 */
function cancel(
  responseID: string,
  options?: RequestOptions
): APIPromise<Response>;

Usage Examples:

// Start a background response
const response = await client.responses.create({
  model: "gpt-4o",
  input: "Write a very long essay",
  background: true,
});

// Cancel it
const cancelled = await client.responses.cancel(response.id);
console.log(cancelled.status); // 'cancelled'

Streaming Responses

Creates a streaming response with helper methods for handling events.

/**
 * Creates a model response stream with automatic parsing and helper methods.
 * Provides a higher-level interface than the raw streaming API.
 *
 * @param body - Response creation parameters with stream: true
 * @param options - Optional request options
 * @returns ResponseStream instance with helper methods
 */
function stream<ParsedT = any>(
  body: ResponseStreamParams,
  options?: RequestOptions
): ResponseStream<ParsedT>;

class ResponseStream<ParsedT> extends Stream<ResponseStreamEvent> {
  /**
   * Waits for the final response and returns it with parsed output
   * @returns Promise<ParsedResponse<ParsedT>> containing the full response and output_parsed field
   */
  finalResponse(): Promise<ParsedResponse<ParsedT>>;

  /** Event handlers */
  on(event: "text.delta", handler: (delta: string) => void): this;
  on(event: "text.done", handler: (text: string) => void): this;
  on(event: "tool_call.delta", handler: (call: any) => void): this;
  on(event: "tool_call.done", handler: (call: any) => void): this;
  on(event: "response.completed", handler: (response: Response) => void): this;
  on(event: "error", handler: (error: Error) => void): this;
}

Usage Examples:

// Basic streaming
const stream = client.responses.stream({
  model: "gpt-4o",
  input: "Write a haiku about programming",
});

for await (const event of stream) {
  if (event.type === "response.text.delta") {
    process.stdout.write(event.delta);
  }
}

// Using event handlers
const stream = client.responses.stream({
  model: "gpt-4o",
  input: "Explain async/await",
})
  .on("text.delta", (delta) => {
    process.stdout.write(delta);
  })
  .on("text.done", (text) => {
    console.log("\n\nFinal text:", text);
  })
  .on("error", (error) => {
    console.error("Error:", error);
  });

await stream.finalResponse();

// Streaming with structured output
const stream = client.responses.stream({
  model: "gpt-4o",
  input: "Generate a user profile",
  text: {
    format: {
      type: "json_schema",
      json_schema: {
        name: "UserProfile",
        schema: {
          type: "object",
          properties: {
            name: { type: "string" },
            age: { type: "number" },
            hobbies: {
              type: "array",
              items: { type: "string" },
            },
          },
          required: ["name", "age"],
        },
      },
    },
  },
});

const finalResponse = await stream.finalResponse();
const parsed = finalResponse.output_parsed;
console.log(parsed); // { name: "...", age: ..., hobbies: [...] }

Parsed Responses

Automatically parses structured outputs with type safety.

/**
 * Creates a response and automatically parses structured output.
 * Works with Zod schemas for runtime type validation.
 *
 * @param body - Response creation parameters with structured output config
 * @param options - Optional request options
 * @returns Promise<ParsedResponse<ParsedT>> with typed parsed output
 */
function parse<ParsedT = any>(
  body: ResponseParseParams,
  options?: RequestOptions
): APIPromise<ParsedResponse<ParsedT>>;

interface ParsedResponse<ParsedT> extends Response {
  /** Original output items */
  output: Array<ParsedResponseOutputItem<ParsedT>>;

  /** Parsed structured output (null if parsing failed) */
  output_parsed: ParsedT | null;
}

Usage Examples:

import { zodResponseFormat } from "openai/helpers/zod";
import { z } from "zod";

// Define Zod schema
const CalendarEventSchema = z.object({
  name: z.string(),
  date: z.string(),
  participants: z.array(z.string()),
});

// Create response with auto-parsing
const response = await client.responses.parse({
  model: "gpt-4o",
  input: "Create a calendar event for team meeting on Jan 15th with Alice, Bob, and Charlie",
  text: {
    format: zodResponseFormat(CalendarEventSchema, "CalendarEvent"),
  },
});

// output_parsed is fully typed
const event = response.output_parsed;
if (event) {
  console.log(event.name); // Type: string
  console.log(event.date); // Type: string
  console.log(event.participants); // Type: string[]
}

Input Items Listing

Lists input items used to generate a response.

/**
 * Returns a list of input items for a given response.
 * Supports cursor-based pagination for large input sets.
 *
 * @param responseID - The unique response ID
 * @param query - Optional pagination and filtering parameters
 * @param options - Optional request options
 * @returns PagePromise for iterating through input items
 */
function inputItems.list(
  responseID: string,
  query?: InputItemListParams,
  options?: RequestOptions
): PagePromise<ResponseItemsPage, ResponseItem>;

interface InputItemListParams extends CursorPageParams {
  /** Additional fields to include */
  include?: Array<ResponseIncludable>;

  /** Order to return items ('asc' or 'desc') */
  order?: "asc" | "desc";

  /** Cursor for pagination */
  after?: string;

  /** Number of items per page (1-100) */
  limit?: number;
}

Usage Examples:

// List all input items (auto-pagination)
for await (const item of client.responses.inputItems.list("resp_abc123")) {
  console.log(item.type, item);
}

// Manual pagination
const page = await client.responses.inputItems.list("resp_abc123", {
  limit: 10,
  order: "asc",
});

console.log(page.data); // Array of items
if (page.has_more) {
  const nextPage = await page.getNextPage();
}

// With additional fields
for await (const item of client.responses.inputItems.list(
  "resp_abc123",
  { include: ["input_text"] }
)) {
  console.log(item);
}

Input Token Counting

Counts tokens for input items before creating a response.

/**
 * Get input token counts for a potential response.
 * Useful for estimating costs and ensuring inputs fit within context windows.
 *
 * @param body - Same parameters as response creation
 * @param options - Optional request options
 * @returns Promise<InputTokenCountResponse> with token count
 */
function inputTokens.count(
  body?: InputTokenCountParams,
  options?: RequestOptions
): APIPromise<InputTokenCountResponse>;

interface InputTokenCountResponse {
  /** Number of input tokens */
  input_tokens: number;

  /** Object type identifier */
  object: "response.input_tokens";
}

interface InputTokenCountParams {
  /** Model ID to count tokens for */
  model?: string | null;

  /** Input items to count */
  input?: string | Array<ResponseInputItem> | null;

  /** Instructions to count */
  instructions?: string | null;

  /** Conversation ID for context */
  conversation?: string | ResponseConversationParam | null;

  /** Previous response ID for context */
  previous_response_id?: string | null;

  /** Tools that might be used */
  tools?: Array<Tool> | null;

  /** Tool choice configuration */
  tool_choice?: any | null;

  /** Text configuration */
  text?: { format?: ResponseFormatTextConfig } | null;

  /** Reasoning configuration */
  reasoning?: Reasoning | null;

  /** Parallel tool calls setting */
  parallel_tool_calls?: boolean | null;

  /** Truncation strategy */
  truncation?: "auto" | "disabled";
}

Usage Examples:

// Count tokens for a simple input
const count = await client.responses.inputTokens.count({
  model: "gpt-4o",
  input: "What is the meaning of life?",
});

console.log(count.input_tokens); // e.g., 8

// Count with complex input
const count = await client.responses.inputTokens.count({
  model: "gpt-4o",
  instructions: "You are a helpful assistant.",
  input: [
    { type: "text", text: "Analyze this document:" },
    { type: "file", file_id: "file-abc123" },
  ],
  tools: [
    {
      type: "function",
      name: "get_weather",
      parameters: { type: "object", properties: {} },
      strict: true,
    },
  ],
});

console.log(`Token count: ${count.input_tokens}`);

// Count for multi-turn conversation
const count = await client.responses.inputTokens.count({
  model: "gpt-4o",
  input: "What did we discuss earlier?",
  previous_response_id: "resp_previous123",
});

Type Definitions

Core Response Types

/**
 * A model response object containing inputs, outputs, metadata, and usage information.
 */
interface Response {
  /** Unique identifier for this Response (e.g., 'resp_abc123') */
  id: string;

  /** Unix timestamp (seconds) of creation */
  created_at: number;

  /** Object type, always 'response' */
  object: "response";

  /** Model ID used (e.g., 'gpt-4o') */
  model: ResponsesModel;

  /** Response generation status */
  status?: ResponseStatus;

  /** Array of content items generated by the model */
  output: Array<ResponseOutputItem>;

  /** Convenience property: concatenated text output */
  output_text: string;

  /** System/developer message in model context */
  instructions: string | Array<ResponseInputItem> | null;

  /** Temperature setting (0-2) */
  temperature: number | null;

  /** Top-p nucleus sampling parameter */
  top_p: number | null;

  /** Maximum output tokens limit */
  max_output_tokens?: number | null;

  /** Tools available to the model */
  tools: Array<Tool>;

  /** Tool selection strategy */
  tool_choice: ToolChoiceOptions | ToolChoiceAllowed | ToolChoiceTypes | ToolChoiceFunction | ToolChoiceMcp | ToolChoiceCustom | ToolChoiceApplyPatch | ToolChoiceShell;

  /** Whether parallel tool calls are allowed */
  parallel_tool_calls: boolean;

  /** Previous response ID for multi-turn conversations */
  previous_response_id?: string | null;

  /** Conversation this response belongs to */
  conversation?: Response.Conversation | null;

  /** Text response configuration */
  text?: ResponseTextConfig;

  /** Reasoning configuration for reasoning models */
  reasoning?: Reasoning | null;

  /** Metadata key-value pairs (max 16 pairs) */
  metadata: Metadata | null;

  /** Truncation strategy used */
  truncation?: "auto" | "disabled" | null;

  /** Whether response ran in background */
  background?: boolean | null;

  /** Token usage statistics */
  usage?: ResponseUsage;

  /** Error information if generation failed */
  error: ResponseError | null;

  /** Details about incomplete responses */
  incomplete_details: Response.IncompleteDetails | null;

  /** Prompt template reference */
  prompt?: ResponsePrompt | null;

  /** Prompt cache key */
  prompt_cache_key?: string;

  /** Prompt cache retention policy */
  prompt_cache_retention?: "in-memory" | "24h" | null;

  /** Service tier used */
  service_tier?: "auto" | "default" | "flex" | "scale" | "priority" | null;

  /** Safety identifier */
  safety_identifier?: string;

  /** @deprecated Use prompt_cache_key instead */
  user?: string;
}

namespace Response {
  /** Details about why a response is incomplete */
  interface IncompleteDetails {
    reason?: "max_output_tokens" | "content_filter";
  }

  /** Conversation reference */
  interface Conversation {
    /** Conversation ID */
    id: string;
  }
}

/**
 * Response generation status values
 */
type ResponseStatus =
  | "completed"      // Successfully completed
  | "failed"         // Failed with error
  | "in_progress"    // Currently generating
  | "cancelled"      // Cancelled by user
  | "queued"         // Queued for processing
  | "incomplete";    // Incomplete due to max tokens or filter

/**
 * Token usage information for a response
 */
interface ResponseUsage {
  /** Number of tokens in input */
  input_tokens: number;

  /** Number of tokens in output */
  output_tokens: number;

  /** Total tokens (input + output) */
  total_tokens: number;

  /** Detailed output token breakdown */
  output_tokens_details?: ResponseUsage.OutputTokensDetails;
}

namespace ResponseUsage {
  interface OutputTokensDetails {
    /** Tokens used for reasoning (o-series models) */
    reasoning_tokens?: number;

    /** Tokens in text output */
    text_tokens?: number;

    /** Tokens in audio output */
    audio_tokens?: number;
  }
}

/**
 * Error information when response generation fails
 */
interface ResponseError {
  /** Error code */
  code: string;

  /** Human-readable error message */
  message: string;

  /** Additional error details */
  param?: string | null;

  /** Error type */
  type?: string;
}

/**
 * Text response configuration options
 */
interface ResponseTextConfig {
  /** Output format specification */
  format?: ResponseFormatTextConfig;

  /** Verbosity level for output */
  verbosity?: "low" | "medium" | "high" | null;
}

/**
 * Response format configuration for text outputs
 */
type ResponseFormatTextConfig =
  | { type: "text" }  // Plain text (default)
  | { type: "json_object" }  // Legacy JSON mode
  | ResponseFormatTextJSONSchemaConfig  // Structured Outputs
  | { type: "text_grammar"; text_grammar: { grammar: string; root_rule?: string } }  // Grammar-constrained
  | { type: "text_python"; text_python?: {} };  // Python code generation

/**
 * JSON Schema structured output configuration
 */
interface ResponseFormatTextJSONSchemaConfig {
  type: "json_schema";
  json_schema: {
    /** Schema name */
    name: string;

    /** JSON Schema definition */
    schema?: Record<string, unknown>;

    /** Whether to enforce strict validation */
    strict?: boolean | null;

    /** Schema description */
    description?: string;
  };
}

/**
 * Prompt template reference
 */
interface ResponsePrompt {
  /** Template ID */
  id: string;

  /** Template variables */
  variables?: Record<string, string>;
}

/**
 * Conversation parameter for automatic state management
 */
interface ResponseConversationParam {
  /** Conversation ID to add response to */
  id: string;
}

/**
 * Additional fields that can be included in responses
 */
type ResponseIncludable =
  | "input_text"  // Include concatenated input text
  | "output_text"  // Include concatenated output text
  | "output[*].content[*].annotations[*].file_citation.quote"  // Include file citation quotes
  | "output[*].content[*].annotations[*].file_citation.file.content"  // Include file content
  | "web_search_call.action.sources"  // Include sources from web search tool call
  | "code_interpreter_call.outputs"  // Include outputs from python code execution
  | "computer_call_output.output.image_url"  // Include image URLs from computer call output
  | "file_search_call.results"  // Include search results from file search tool call
  | "message.input_image.image_url"  // Include image URLs from input message
  | "reasoning.encrypted_content";  // Include encrypted reasoning tokens

Input Types

/**
 * Input to the model - can be a simple string or array of structured items
 */
type ResponseInput = Array<ResponseInputItem>;

/**
 * Individual input item - message or tool output
 */
type ResponseInputItem =
  | ResponseInputMessageItem
  | EasyInputMessage
  | ResponseFunctionToolCallItem
  | ResponseFunctionToolCallOutputItem
  | ResponseFunctionShellToolCall
  | ResponseFunctionShellToolCallOutput
  | ResponseApplyPatchToolCall
  | ResponseApplyPatchToolCallOutput
  | ResponseComputerToolCallOutputItem
  | ResponseCodeInterpreterToolCall
  | ResponseCustomToolCall
  | ResponseCustomToolCallOutput
  | ResponseFileSearchToolCall
  | ResponseFunctionWebSearch
  | ResponseOutputItem.ImageGenerationCall
  | ResponseOutputItem.LocalShellCall
  | ResponseOutputItem.McpCall
  | ResponseOutputItem.McpListTools
  | ResponseOutputItem.McpApprovalRequest;

/**
 * Message input with role and content
 */
interface ResponseInputMessageItem {
  /** Message content - text, images, files, or audio */
  content: string | ResponseInputMessageContentList;

  /** Message role */
  role: "user" | "assistant" | "system" | "developer";

  /** Item type */
  type: "message";

  /** Item status when returned via API */
  status?: "in_progress" | "completed" | "incomplete";
}

/**
 * Simplified message input format
 */
interface EasyInputMessage {
  /** Message content */
  content: string | ResponseInputMessageContentList;

  /** Message role */
  role: "user" | "assistant" | "system" | "developer";

  /** Optional type field */
  type?: "message";
}

/**
 * Message content list for multi-modal inputs
 */
type ResponseInputMessageContentList = Array<ResponseInputContent>;

/**
 * Content types for message inputs
 */
type ResponseInputContent =
  | ResponseInputText
  | ResponseInputImage
  | ResponseInputFile;

/**
 * Text content input
 */
interface ResponseInputText {
  /** Content type */
  type: "input_text";

  /** The text content */
  text: string;
}

/**
 * Image content input
 */
interface ResponseInputImage {
  /** Content type */
  type: "input_image";

  /** Image source - URL or file ID */
  image_url?: { url: string; detail?: "auto" | "low" | "high" } | null;
  file_id?: string | null;
}

/**
 * File content input
 */
interface ResponseInputFile {
  /** Content type */
  type: "input_file";

  /** File ID from uploads */
  file_id: string;

  /** Optional detail level */
  detail?: "auto" | "low" | "high";
}

/**
 * Audio input
 */
interface ResponseInputAudio {
  /** Content type */
  type: "input_audio";

  /** Audio format */
  format: "wav" | "mp3";

  /** Base64-encoded audio data */
  data?: string | null;

  /** Transcript of the audio */
  transcript?: string | null;
}

/**
 * Text content with inline annotations
 */
interface ResponseInputTextContent {
  /** Content type */
  type: "text";

  /** The text */
  text: string;

  /** Inline annotations (citations, file paths) */
  annotations?: Array<ResponseInputTextContent.Annotation>;
}

namespace ResponseInputTextContent {
  interface Annotation {
    /** Annotation type */
    type: "file_citation" | "file_path";

    /** Annotation details */
    file_citation?: {
      file_id: string;
      quote?: string;
    };
    file_path?: {
      file_id: string;
    };
  }
}

/**
 * Image content with URL or file
 */
interface ResponseInputImageContent {
  /** Content type */
  type: "image";

  /** Image URL */
  image_url?: { url: string; detail?: "auto" | "low" | "high" };

  /** File ID for uploaded image */
  file_id?: string;
}

/**
 * File content reference
 */
interface ResponseInputFileContent {
  /** Content type */
  type: "file";

  /** File ID */
  file_id: string;

  /** Detail level for processing */
  detail?: "auto" | "low" | "high";
}

Output Types

/**
 * Union of all possible output item types
 */
type ResponseOutputItem =
  | ResponseOutputMessage
  | ResponseFunctionToolCall
  | ResponseCustomToolCall
  | ResponseFileSearchToolCall
  | ResponseFunctionWebSearch
  | ResponseComputerToolCall
  | ResponseReasoningItem
  | ResponseCodeInterpreterToolCall
  | ResponseApplyPatchToolCall
  | ResponseApplyPatchToolCallOutput
  | ResponseFunctionShellToolCall
  | ResponseFunctionShellToolCallOutput
  | ResponseOutputItem.ImageGenerationCall
  | ResponseOutputItem.LocalShellCall
  | ResponseOutputItem.McpCall
  | ResponseOutputItem.McpListTools
  | ResponseOutputItem.McpApprovalRequest;

/**
 * Message output from the model
 */
interface ResponseOutputMessage {
  /** Unique ID of the message */
  id: string;

  /** Message type */
  type: "message";

  /** Message role (always 'assistant') */
  role: "assistant";

  /** Message status */
  status: "in_progress" | "completed" | "incomplete";

  /** Message content items */
  content: Array<ResponseOutputText | ResponseOutputRefusal | ResponseOutputAudio | ResponseContent.ReasoningTextContent>;

  /** Entity that created this message */
  created_by?: string;
}

/**
 * Text output content
 */
interface ResponseOutputText {
  /** Content type */
  type: "text";

  /** The generated text */
  text: string;

  /** Inline annotations (file citations) */
  annotations?: Array<ResponseOutputText.Annotation>;
}

namespace ResponseOutputText {
  /** File citation annotation */
  interface Annotation {
    type: "file_citation";
    text: string;
    file_citation: {
      file_id: string;
      quote?: string;
    };
    start_index: number;
    end_index: number;
  }
}

/**
 * Refusal output when model declines to answer
 */
interface ResponseOutputRefusal {
  /** Content type */
  type: "refusal";

  /** The refusal message */
  refusal: string;
}

/**
 * Audio output content
 */
interface ResponseOutputAudio {
  /** Content type */
  type: "audio";

  /** Audio ID */
  id: string;

  /** Audio data (Base64) */
  data?: string | null;

  /** Audio transcript */
  transcript?: string | null;

  /** Expiration timestamp */
  expires_at?: number | null;
}

/**
 * Reasoning output from o-series models
 */
interface ResponseReasoningItem {
  /** Unique ID */
  id: string;

  /** Item type */
  type: "reasoning";

  /** Reasoning status */
  status: "in_progress" | "completed";

  /** Reasoning content */
  content: Array<{
    type: "reasoning_text";
    reasoning_text: string;
  }>;

  /** Summary of reasoning */
  summary?: {
    type: "reasoning_summary";
    reasoning_summary: string;
  };
}

/**
 * Generic response item (union type for input/output)
 */
type ResponseItem =
  | ResponseInputMessageItem
  | ResponseOutputMessage
  | ResponseFunctionToolCall
  | ResponseFunctionToolCallOutputItem
  | ResponseCustomToolCall
  | ResponseCustomToolCallOutput
  | ResponseFileSearchToolCall
  | ResponseFunctionWebSearch
  | ResponseComputerToolCall
  | ResponseComputerToolCallOutputItem
  | ResponseCodeInterpreterToolCall
  | ResponseReasoningItem
  | ResponseApplyPatchToolCall
  | ResponseApplyPatchToolCallOutput
  | ResponseFunctionShellToolCall
  | ResponseFunctionShellToolCallOutput
  | ResponseOutputItem.ImageGenerationCall
  | ResponseOutputItem.LocalShellCall
  | ResponseOutputItem.McpCall
  | ResponseOutputItem.McpListTools
  | ResponseOutputItem.McpApprovalRequest;

Tool Types

/**
 * Union of all tool types available in Responses API
 */
type Tool =
  | FunctionTool
  | CustomTool
  | FileSearchTool
  | WebSearchTool
  | WebSearchPreviewTool
  | ComputerTool
  | CodeInterpreterTool
  | ApplyPatchTool
  | FunctionShellTool
  | McpTool
  | ImageGenerationTool
  | LocalShellTool;

/**
 * Function calling tool definition
 */
interface FunctionTool {
  /** Tool type */
  type: "function";

  /** Function name */
  name: string;

  /** Function description for model */
  description?: string | null;

  /** JSON Schema for parameters */
  parameters: Record<string, unknown> | null;

  /** Whether to enforce strict validation */
  strict: boolean | null;
}

/**
 * Custom tool with specialized input format
 */
interface CustomTool {
  /** Tool type */
  type: "custom";

  /** Tool name */
  name: string;

  /** Tool description */
  description?: string;

  /** Input format specification */
  format?: CustomToolInputFormat;
}

/**
 * File search tool for querying vector stores
 */
interface FileSearchTool {
  /** Tool type */
  type: "file_search";

  /** Vector store IDs to search */
  vector_store_ids: Array<string>;

  /** Maximum number of results (1-50) */
  max_num_results?: number;

  /** Search filters */
  filters?: ComparisonFilter | CompoundFilter | null;

  /** Ranking options */
  ranking_options?: FileSearchTool.RankingOptions;
}

namespace FileSearchTool {
  interface RankingOptions {
    /** Ranker to use */
    ranker?: "auto" | "default-2024-11-15";

    /** Score threshold (0-1) */
    score_threshold?: number;

    /** Hybrid search weights */
    hybrid_search?: {
      embedding_weight: number;
      text_weight: number;
    };
  }
}

/**
 * Web search tool for internet queries
 */
interface WebSearchTool {
  /** Tool type */
  type: "web_search";
}

/**
 * Web search tool with preview features and location support.
 * Allows the model to search the web with configurable context size and user location.
 */
interface WebSearchPreviewTool {
  /** Tool type - web_search_preview or web_search_preview_2025_03_11 */
  type: "web_search_preview" | "web_search_preview_2025_03_11";

  /**
   * High level guidance for the amount of context window space to use for search.
   * Options: 'low', 'medium', 'high'. Default: 'medium'.
   */
  search_context_size?: "low" | "medium" | "high";

  /** The user's location for localized search results */
  user_location?: {
    /** Location type - always 'approximate' */
    type: "approximate";
    /** City of the user (e.g., 'San Francisco') */
    city?: string | null;
    /** Two-letter ISO country code (e.g., 'US') */
    country?: string | null;
    /** Region of the user (e.g., 'California') */
    region?: string | null;
    /** IANA timezone (e.g., 'America/Los_Angeles') */
    timezone?: string | null;
  } | null;
}

/**
 * Computer use tool for virtual computer control
 */
interface ComputerTool {
  /** Tool type */
  type: "computer_use_preview";

  /** Display width in pixels */
  display_width: number;

  /** Display height in pixels */
  display_height: number;

  /** Environment type */
  environment: "windows" | "mac" | "linux" | "ubuntu" | "browser";
}

/**
 * Code interpreter tool for running Python code
 */
interface CodeInterpreterTool {
  /** Tool type */
  type: "code_interpreter";

  /** The code interpreter container. Can be a container ID or an object that specifies uploaded file IDs */
  container: string | CodeInterpreterToolAuto;
}

/**
 * Configuration for a code interpreter container
 */
interface CodeInterpreterToolAuto {
  /** Always 'auto' */
  type: "auto";

  /** Optional list of uploaded files to make available to your code */
  file_ids?: Array<string>;

  /** Memory limit for the container */
  memory_limit?: "1g" | "4g" | "16g" | "64g" | null;
}

/**
 * Apply patch tool for file operations
 */
interface ApplyPatchTool {
  /** Tool type */
  type: "apply_patch";
}

/**
 * Shell execution tool
 */
interface FunctionShellTool {
  /** Tool type */
  type: "shell";
}

/**
 * MCP (Model Context Protocol) tool for accessing remote MCP servers
 */
interface McpTool {
  /** Tool type */
  type: "mcp";

  /** A label for this MCP server, used to identify it in tool calls */
  server_label: string;

  /** List of allowed tool names or a filter object */
  allowed_tools?: Array<string> | McpToolFilter | null;

  /** OAuth access token for authenticating with a remote MCP server */
  authorization?: string;

  /** Service connector identifier (e.g., 'connector_dropbox', 'connector_gmail') */
  connector_id?:
    | "connector_dropbox"
    | "connector_gmail"
    | "connector_googlecalendar"
    | "connector_googledrive"
    | "connector_microsoftteams"
    | "connector_outlookcalendar"
    | "connector_outlookemail"
    | "connector_sharepoint";

  /** Optional HTTP headers to send to the MCP server */
  headers?: { [key: string]: string } | null;

  /** Specify which of the MCP server's tools require approval */
  require_approval?: McpToolApprovalFilter | "always" | "never" | null;

  /** Optional description of the MCP server */
  server_description?: string;

  /** The URL for the MCP server. One of server_url or connector_id must be provided */
  server_url?: string;
}

/**
 * Filter object to specify which MCP tools are allowed
 */
interface McpToolFilter {
  /** Whether tool modifies data or is read-only */
  read_only?: boolean;

  /** List of allowed tool names */
  tool_names?: Array<string>;
}

/**
 * Filter for MCP tool approval requirements
 */
interface McpToolApprovalFilter {
  /** Tools that always require approval */
  always?: McpToolFilterSpec;

  /** Tools that never require approval */
  never?: McpToolFilterSpec;
}

/**
 * Filter specification for MCP tool approval
 */
interface McpToolFilterSpec {
  /** Whether tool modifies data or is read-only */
  read_only?: boolean;

  /** List of tool names */
  tool_names?: Array<string>;
}

/**
 * Image generation tool using models like gpt-image-1
 */
interface ImageGenerationTool {
  /** Tool type */
  type: "image_generation";

  /** Background type for the generated image */
  background?: "transparent" | "opaque" | "auto";

  /** Control how much effort the model will exert to match input image features */
  input_fidelity?: "high" | "low" | null;

  /** Optional mask for inpainting */
  input_image_mask?: {
    image_url?: string;
    file_id?: string;
  };

  /** The image generation model to use */
  model?: "gpt-image-1" | "gpt-image-1-mini";

  /** Moderation level for the generated image */
  moderation?: "auto" | "low";

  /** Compression level for the output image (0-100) */
  output_compression?: number;

  /** The output format of the generated image */
  output_format?: "png" | "webp" | "jpeg";

  /** Number of partial images to generate in streaming mode (0-3) */
  partial_images?: number;

  /** The quality of the generated image */
  quality?: "low" | "medium" | "high" | "auto";

  /** The size of the generated image */
  size?: "1024x1024" | "1024x1536" | "1536x1024" | "auto";

  /** The style of the generated image */
  style?: "natural" | "vivid";
}

/**
 * Local shell execution tool
 */
interface LocalShellTool {
  /** Tool type */
  type: "local_shell";
}

/**
 * Tool choice configuration
 */
type ToolChoiceOptions =
  | "auto"      // Model decides
  | "required"  // Must use a tool
  | "none";     // No tools

type ToolChoiceAllowed = "allowed";  // Tools allowed but not required

type ToolChoiceTypes =
  | "function"
  | "file_search"
  | "web_search"
  | "computer_use_preview"
  | "code_interpreter"
  | "apply_patch"
  | "shell"
  | "custom"
  | "mcp";

/**
 * Specific function tool choice
 */
interface ToolChoiceFunction {
  type: "function";
  function: { name: string };
}

/**
 * Specific custom tool choice
 */
interface ToolChoiceCustom {
  type: "custom";
  custom: { name: string };
}

/**
 * Specific MCP tool choice
 */
interface ToolChoiceMcp {
  type: "mcp";
  mcp: {
    server_name: string;
    tool_name?: string;
  };
}

/**
 * Specific apply_patch tool choice
 */
interface ToolChoiceApplyPatch {
  type: "apply_patch";
}

/**
 * Specific shell tool choice
 */
interface ToolChoiceShell {
  type: "shell";
}

Tool Call Output Types

/**
 * Function tool call from model
 */
interface ResponseFunctionToolCall {
  /** Unique ID */
  id: string;

  /** Item type */
  type: "function_call";

  /** Function name */
  name: string;

  /** Function arguments (JSON string) */
  arguments: string;

  /** Unique call ID */
  call_id: string;

  /** Call status */
  status: "in_progress" | "completed";

  /** Creator entity ID */
  created_by?: string;
}

/**
 * Function tool call output
 */
interface ResponseFunctionToolCallOutputItem {
  /** Unique ID */
  id: string;

  /** Item type */
  type: "function_call_output";

  /** Corresponding call ID */
  call_id: string;

  /** Function output */
  output: string | Array<ResponseFunctionCallOutputItem>;

  /** Creator entity ID */
  created_by?: string;
}

/**
 * Function call output item types
 */
type ResponseFunctionCallOutputItem =
  | { type: "text"; text: string }
  | { type: "image"; image_url?: { url: string }; file_id?: string }
  | { type: "file"; file_id: string };

/**
 * Custom tool call
 */
interface ResponseCustomToolCall {
  /** Unique ID */
  id: string;

  /** Item type */
  type: "custom_call";

  /** Tool name */
  name: string;

  /** Tool input */
  input: string;

  /** Unique call ID */
  call_id: string;

  /** Call status */
  status: "in_progress" | "completed";

  /** Creator entity ID */
  created_by?: string;
}

/**
 * Custom tool call output
 */
interface ResponseCustomToolCallOutput {
  /** Unique ID */
  id: string;

  /** Item type */
  type: "custom_call_output";

  /** Corresponding call ID */
  call_id: string;

  /** Tool output */
  output: string | null;

  /** Creator entity ID */
  created_by?: string;
}

/**
 * File search tool call
 */
interface ResponseFileSearchToolCall {
  /** Unique ID */
  id: string;

  /** Item type */
  type: "file_search_call";

  /** Unique call ID */
  call_id: string;

  /** Search results */
  results: Array<ResponseFileSearchToolCall.Result> | null;

  /** Call status */
  status: "in_progress" | "completed" | "searching";

  /** Creator entity ID */
  created_by?: string;
}

namespace ResponseFileSearchToolCall {
  interface Result {
    /** File ID */
    file_id: string;

    /** File name */
    file_name?: string;

    /** Relevance score */
    score?: number;

    /** Matching content snippets */
    content?: Array<{ type: "text"; text: string }>;
  }
}

/**
 * Web search tool call
 */
interface ResponseFunctionWebSearch {
  /** Unique ID */
  id: string;

  /** Item type */
  type: "web_search_call";

  /** Search query */
  query: string;

  /** Unique call ID */
  call_id: string;

  /** Search results */
  results: Array<ResponseFunctionWebSearch.Result> | null;

  /** Call status */
  status: "in_progress" | "completed" | "searching";

  /** Creator entity ID */
  created_by?: string;
}

namespace ResponseFunctionWebSearch {
  interface Result {
    /** Result URL */
    url: string;

    /** Page title */
    title?: string;

    /** Content snippet */
    snippet?: string;
  }
}

/**
 * Computer use tool call
 */
interface ResponseComputerToolCall {
  /** Unique ID */
  id: string;

  /** Item type */
  type: "computer_call";

  /** Unique call ID */
  call_id: string;

  /** Computer action */
  action:
    | { type: "click"; x: number; y: number; button: "left" | "right" | "wheel" | "back" | "forward" }
    | { type: "double_click"; x: number; y: number }
    | { type: "drag"; path: Array<{ x: number; y: number }> }
    | { type: "keypress"; keys: Array<string> }
    | { type: "move"; x: number; y: number }
    | { type: "screenshot" }
    | { type: "scroll"; x: number; y: number; scroll_x: number; scroll_y: number }
    | { type: "type"; text: string }
    | { type: "wait" };

  /** Call status */
  status: "in_progress" | "completed" | "incomplete";

  /** Pending safety checks */
  pending_safety_checks: Array<{
    id: string;
    code?: string | null;
    message?: string | null;
  }>;
}

/**
 * Computer use tool output
 */
interface ResponseComputerToolCallOutputItem {
  /** Unique ID */
  id: string;

  /** Item type */
  type: "computer_call_output";

  /** Corresponding call ID */
  call_id: string;

  /** Screenshot output */
  output: ResponseComputerToolCallOutputScreenshot;

  /** Call status */
  status?: "in_progress" | "completed" | "incomplete";

  /** Acknowledged safety checks */
  acknowledged_safety_checks?: Array<{
    id: string;
    code?: string | null;
    message?: string | null;
  }>;
}

/**
 * Computer screenshot output
 */
interface ResponseComputerToolCallOutputScreenshot {
  /** Content type */
  type: "computer_screenshot";

  /** File ID of screenshot */
  file_id?: string;

  /** Image URL */
  image_url?: string;
}

/**
 * Code interpreter tool call
 */
interface ResponseCodeInterpreterToolCall {
  /** Unique ID */
  id: string;

  /** Item type */
  type: "code_interpreter_call";

  /** Python code */
  code: string | null;

  /** Container ID */
  container_id: string;

  /** Code outputs */
  outputs: Array<
    | { type: "logs"; logs: string }
    | { type: "image"; url: string }
  > | null;

  /** Call status */
  status: "in_progress" | "completed" | "incomplete" | "interpreting" | "failed";
}

/**
 * Apply patch tool call
 */
interface ResponseApplyPatchToolCall {
  /** Unique ID */
  id: string;

  /** Item type */
  type: "apply_patch_call";

  /** Unique call ID */
  call_id: string;

  /** File operation */
  operation:
    | { type: "create_file"; path: string; diff: string }
    | { type: "delete_file"; path: string }
    | { type: "update_file"; path: string; diff: string };

  /** Call status */
  status: "in_progress" | "completed";

  /** Creator entity ID */
  created_by?: string;
}

/**
 * Apply patch output
 */
interface ResponseApplyPatchToolCallOutput {
  /** Unique ID */
  id: string;

  /** Item type */
  type: "apply_patch_call_output";

  /** Corresponding call ID */
  call_id: string;

  /** Operation output */
  output?: string | null;

  /** Output status */
  status: "completed" | "failed";

  /** Creator entity ID */
  created_by?: string;
}

/**
 * Shell tool call
 */
interface ResponseFunctionShellToolCall {
  /** Unique ID */
  id: string;

  /** Item type */
  type: "shell_call";

  /** Shell command */
  command: string;

  /** Unique call ID */
  call_id: string;

  /** Call status */
  status: "in_progress" | "completed";

  /** Creator entity ID */
  created_by?: string;
}

/**
 * Shell tool output
 */
interface ResponseFunctionShellToolCallOutput {
  /** Unique ID */
  id: string;

  /** Item type */
  type: "shell_call_output";

  /** Corresponding call ID */
  call_id: string;

  /** Shell output */
  output: Array<ResponseFunctionShellCallOutputContent>;

  /** Creator entity ID */
  created_by?: string;
}

/**
 * Shell output content
 */
interface ResponseFunctionShellCallOutputContent {
  /** Content type */
  type: "text" | "image";

  /** Text content */
  text?: string;

  /** Image URL */
  image_url?: { url: string };

  /** File ID */
  file_id?: string;
}

Streaming Event Types

/**
 * Union of all streaming event types
 */
type ResponseStreamEvent =
  | ResponseCreatedEvent
  | ResponseQueuedEvent
  | ResponseInProgressEvent
  | ResponseCompletedEvent
  | ResponseFailedEvent
  | ResponseIncompleteEvent
  | ResponseErrorEvent
  | ResponseOutputItemAddedEvent
  | ResponseOutputItemDoneEvent
  | ResponseContentPartAddedEvent
  | ResponseContentPartDoneEvent
  | ResponseTextDeltaEvent
  | ResponseTextDoneEvent
  | ResponseRefusalDeltaEvent
  | ResponseRefusalDoneEvent
  | ResponseAudioDeltaEvent
  | ResponseAudioDoneEvent
  | ResponseAudioTranscriptDeltaEvent
  | ResponseAudioTranscriptDoneEvent
  | ResponseFunctionCallArgumentsDeltaEvent
  | ResponseFunctionCallArgumentsDoneEvent
  | ResponseCustomToolCallInputDeltaEvent
  | ResponseCustomToolCallInputDoneEvent
  | ResponseFileSearchCallInProgressEvent
  | ResponseFileSearchCallSearchingEvent
  | ResponseFileSearchCallCompletedEvent
  | ResponseWebSearchCallInProgressEvent
  | ResponseWebSearchCallSearchingEvent
  | ResponseWebSearchCallCompletedEvent
  | ResponseCodeInterpreterCallInProgressEvent
  | ResponseCodeInterpreterCallInterpretingEvent
  | ResponseCodeInterpreterCallCompletedEvent
  | ResponseCodeInterpreterCallCodeDeltaEvent
  | ResponseCodeInterpreterCallCodeDoneEvent
  | ResponseImageGenCallInProgressEvent
  | ResponseImageGenCallGeneratingEvent
  | ResponseImageGenCallPartialImageEvent
  | ResponseImageGenCallCompletedEvent
  | ResponseReasoningTextDeltaEvent
  | ResponseReasoningTextDoneEvent
  | ResponseReasoningSummaryPartAddedEvent
  | ResponseReasoningSummaryPartDoneEvent
  | ResponseReasoningSummaryTextDeltaEvent
  | ResponseReasoningSummaryTextDoneEvent
  | ResponseOutputTextAnnotationAddedEvent
  | ResponseMcpCallInProgressEvent
  | ResponseMcpCallArgumentsDeltaEvent
  | ResponseMcpCallArgumentsDoneEvent
  | ResponseMcpCallCompletedEvent
  | ResponseMcpCallFailedEvent
  | ResponseMcpListToolsInProgressEvent
  | ResponseMcpListToolsCompletedEvent
  | ResponseMcpListToolsFailedEvent;

/**
 * Response lifecycle events
 */

/** Emitted when response is created */
interface ResponseCreatedEvent {
  type: "response.created";
  sequence_number: number;
  response: Response;
}

/** Emitted when response is queued */
interface ResponseQueuedEvent {
  type: "response.queued";
  sequence_number: number;
  response: Response;
}

/** Emitted when response starts processing */
interface ResponseInProgressEvent {
  type: "response.in_progress";
  sequence_number: number;
  response: Response;
}

/** Emitted when response completes successfully */
interface ResponseCompletedEvent {
  type: "response.completed";
  sequence_number: number;
  response: Response;
}

/** Emitted when response fails */
interface ResponseFailedEvent {
  type: "response.failed";
  sequence_number: number;
  response: Response;
  error: ResponseError;
}

/** Emitted when response is incomplete */
interface ResponseIncompleteEvent {
  type: "response.incomplete";
  sequence_number: number;
  response: Response;
}

/** Emitted on error */
interface ResponseErrorEvent {
  type: "error";
  sequence_number: number;
  error: ResponseError;
}

/**
 * Output item events
 */

/** Emitted when new output item is added */
interface ResponseOutputItemAddedEvent {
  type: "response.output_item.added";
  sequence_number: number;
  item_id: string;
  output_index: number;
  item: ResponseOutputItem;
}

/** Emitted when output item is complete */
interface ResponseOutputItemDoneEvent {
  type: "response.output_item.done";
  sequence_number: number;
  item_id: string;
  output_index: number;
  item: ResponseOutputItem;
}

/**
 * Content part events
 */

/** Emitted when content part is added */
interface ResponseContentPartAddedEvent {
  type: "response.content_part.added";
  sequence_number: number;
  item_id: string;
  output_index: number;
  content_index: number;
  part: ResponseContent;
}

/** Emitted when content part is complete */
interface ResponseContentPartDoneEvent {
  type: "response.content_part.done";
  sequence_number: number;
  item_id: string;
  output_index: number;
  content_index: number;
  part: ResponseContent;
}

/**
 * Text streaming events
 */

/** Emitted for each text delta */
interface ResponseTextDeltaEvent {
  type: "response.text.delta";
  sequence_number: number;
  item_id: string;
  output_index: number;
  content_index: number;
  delta: string;
}

/** Emitted when text is complete */
interface ResponseTextDoneEvent {
  type: "response.text.done";
  sequence_number: number;
  item_id: string;
  output_index: number;
  content_index: number;
  text: string;
}

/**
 * Refusal streaming events
 */

/** Emitted for each refusal delta */
interface ResponseRefusalDeltaEvent {
  type: "response.refusal.delta";
  sequence_number: number;
  item_id: string;
  output_index: number;
  content_index: number;
  delta: string;
}

/** Emitted when refusal is complete */
interface ResponseRefusalDoneEvent {
  type: "response.refusal.done";
  sequence_number: number;
  item_id: string;
  output_index: number;
  content_index: number;
  refusal: string;
}

/**
 * Audio streaming events
 */

/** Emitted for each audio data chunk */
interface ResponseAudioDeltaEvent {
  type: "response.audio.delta";
  sequence_number: number;
  delta: string;  // Base64-encoded audio bytes
}

/** Emitted when audio is complete */
interface ResponseAudioDoneEvent {
  type: "response.audio.done";
  sequence_number: number;
}

/** Emitted for each audio transcript delta */
interface ResponseAudioTranscriptDeltaEvent {
  type: "response.audio.transcript.delta";
  sequence_number: number;
  delta: string;
}

/** Emitted when audio transcript is complete */
interface ResponseAudioTranscriptDoneEvent {
  type: "response.audio.transcript.done";
  sequence_number: number;
}

/**
 * Function call streaming events
 */

/** Emitted for each function arguments delta */
interface ResponseFunctionCallArgumentsDeltaEvent {
  type: "response.function_call_arguments.delta";
  sequence_number: number;
  item_id: string;
  output_index: number;
  delta: string;
}

/** Emitted when function arguments are complete */
interface ResponseFunctionCallArgumentsDoneEvent {
  type: "response.function_call_arguments.done";
  sequence_number: number;
  item_id: string;
  output_index: number;
  arguments: string;
  name: string;
  call_id: string;
}

/**
 * Custom tool call streaming events
 */

/** Emitted for each custom tool input delta */
interface ResponseCustomToolCallInputDeltaEvent {
  type: "response.custom_call_input.delta";
  sequence_number: number;
  item_id: string;
  output_index: number;
  delta: string;
}

/** Emitted when custom tool input is complete */
interface ResponseCustomToolCallInputDoneEvent {
  type: "response.custom_call_input.done";
  sequence_number: number;
  item_id: string;
  output_index: number;
  input: string;
  name: string;
  call_id: string;
}

/**
 * File search streaming events
 */

/** Emitted when file search starts */
interface ResponseFileSearchCallInProgressEvent {
  type: "response.file_search_call.in_progress";
  sequence_number: number;
  item_id: string;
  output_index: number;
}

/** Emitted when file search is actively searching */
interface ResponseFileSearchCallSearchingEvent {
  type: "response.file_search_call.searching";
  sequence_number: number;
  item_id: string;
  output_index: number;
}

/** Emitted when file search completes */
interface ResponseFileSearchCallCompletedEvent {
  type: "response.file_search_call.completed";
  sequence_number: number;
  item_id: string;
  output_index: number;
  results: Array<any>;
}

/**
 * Web search streaming events
 */

/** Emitted when web search starts */
interface ResponseWebSearchCallInProgressEvent {
  type: "response.web_search_call.in_progress";
  sequence_number: number;
  item_id: string;
  output_index: number;
}

/** Emitted when web search is actively searching */
interface ResponseWebSearchCallSearchingEvent {
  type: "response.web_search_call.searching";
  sequence_number: number;
  item_id: string;
  output_index: number;
  query: string;
}

/** Emitted when web search completes */
interface ResponseWebSearchCallCompletedEvent {
  type: "response.web_search_call.completed";
  sequence_number: number;
  item_id: string;
  output_index: number;
  results: Array<any>;
}

/**
 * Code interpreter streaming events
 */

/** Emitted when code interpreter starts */
interface ResponseCodeInterpreterCallInProgressEvent {
  type: "response.code_interpreter_call.in_progress";
  sequence_number: number;
  item_id: string;
  output_index: number;
}

/** Emitted when code is being interpreted */
interface ResponseCodeInterpreterCallInterpretingEvent {
  type: "response.code_interpreter_call.interpreting";
  sequence_number: number;
  item_id: string;
  output_index: number;
}

/** Emitted when code interpreter completes */
interface ResponseCodeInterpreterCallCompletedEvent {
  type: "response.code_interpreter_call.completed";
  sequence_number: number;
  item_id: string;
  output_index: number;
}

/** Emitted for each code delta */
interface ResponseCodeInterpreterCallCodeDeltaEvent {
  type: "response.code_interpreter_call_code.delta";
  sequence_number: number;
  item_id: string;
  output_index: number;
  delta: string;
}

/** Emitted when code is complete */
interface ResponseCodeInterpreterCallCodeDoneEvent {
  type: "response.code_interpreter_call_code.done";
  sequence_number: number;
  item_id: string;
  output_index: number;
  code: string;
}

/**
 * Image generation streaming events
 */

/** Emitted when image generation starts */
interface ResponseImageGenCallInProgressEvent {
  type: "response.image_gen_call.in_progress";
  sequence_number: number;
  item_id: string;
  output_index: number;
}

/** Emitted when image is being generated */
interface ResponseImageGenCallGeneratingEvent {
  type: "response.image_gen_call.generating";
  sequence_number: number;
  item_id: string;
  output_index: number;
}

/** Emitted for partial image data */
interface ResponseImageGenCallPartialImageEvent {
  type: "response.image_gen_call.partial_image";
  sequence_number: number;
  item_id: string;
  output_index: number;
  image_data: string;  // Partial Base64 image
}

/** Emitted when image generation completes */
interface ResponseImageGenCallCompletedEvent {
  type: "response.image_gen_call.completed";
  sequence_number: number;
  item_id: string;
  output_index: number;
}

/**
 * Reasoning streaming events (o-series models)
 */

/** Emitted for each reasoning text delta */
interface ResponseReasoningTextDeltaEvent {
  type: "response.reasoning.text.delta";
  sequence_number: number;
  item_id: string;
  output_index: number;
  content_index: number;
  delta: string;
}

/** Emitted when reasoning text is complete */
interface ResponseReasoningTextDoneEvent {
  type: "response.reasoning.text.done";
  sequence_number: number;
  item_id: string;
  output_index: number;
  content_index: number;
  text: string;
}

/** Emitted when reasoning summary part is added */
interface ResponseReasoningSummaryPartAddedEvent {
  type: "response.reasoning.summary_part.added";
  sequence_number: number;
  item_id: string;
  output_index: number;
}

/** Emitted when reasoning summary part is complete */
interface ResponseReasoningSummaryPartDoneEvent {
  type: "response.reasoning.summary_part.done";
  sequence_number: number;
  item_id: string;
  output_index: number;
}

/** Emitted for each reasoning summary text delta */
interface ResponseReasoningSummaryTextDeltaEvent {
  type: "response.reasoning.summary.text.delta";
  sequence_number: number;
  item_id: string;
  output_index: number;
  delta: string;
}

/** Emitted when reasoning summary text is complete */
interface ResponseReasoningSummaryTextDoneEvent {
  type: "response.reasoning.summary.text.done";
  sequence_number: number;
  item_id: string;
  output_index: number;
  text: string;
}

/**
 * Annotation events
 */

/** Emitted when output text annotation is added */
interface ResponseOutputTextAnnotationAddedEvent {
  type: "response.output_text.annotation.added";
  sequence_number: number;
  item_id: string;
  output_index: number;
  content_index: number;
  annotation: ResponseOutputText.Annotation;
}

/**
 * MCP streaming events
 */

/** Emitted when MCP call starts */
interface ResponseMcpCallInProgressEvent {
  type: "response.mcp_call.in_progress";
  sequence_number: number;
  item_id: string;
  output_index: number;
}

/** Emitted for each MCP arguments delta */
interface ResponseMcpCallArgumentsDeltaEvent {
  type: "response.mcp_call_arguments.delta";
  sequence_number: number;
  item_id: string;
  output_index: number;
  delta: string;
}

/** Emitted when MCP arguments are complete */
interface ResponseMcpCallArgumentsDoneEvent {
  type: "response.mcp_call_arguments.done";
  sequence_number: number;
  item_id: string;
  output_index: number;
  arguments: string;
}

/** Emitted when MCP call completes */
interface ResponseMcpCallCompletedEvent {
  type: "response.mcp_call.completed";
  sequence_number: number;
  item_id: string;
  output_index: number;
}

/** Emitted when MCP call fails */
interface ResponseMcpCallFailedEvent {
  type: "response.mcp_call.failed";
  sequence_number: number;
  item_id: string;
  output_index: number;
  error: ResponseError;
}

/** Emitted when MCP list tools starts */
interface ResponseMcpListToolsInProgressEvent {
  type: "response.mcp_list_tools.in_progress";
  sequence_number: number;
  item_id: string;
  output_index: number;
}

/** Emitted when MCP list tools completes */
interface ResponseMcpListToolsCompletedEvent {
  type: "response.mcp_list_tools.completed";
  sequence_number: number;
  item_id: string;
  output_index: number;
}

/** Emitted when MCP list tools fails */
interface ResponseMcpListToolsFailedEvent {
  type: "response.mcp_list_tools.failed";
  sequence_number: number;
  item_id: string;
  output_index: number;
  error: ResponseError;
}

Usage Examples

Basic Text Response

import { OpenAI } from "openai";

const client = new OpenAI();

// Simple question answering
const response = await client.responses.create({
  model: "gpt-4o",
  input: "What is the speed of light?",
});

console.log(response.output_text);
// "The speed of light in a vacuum is approximately 299,792,458 meters per second..."

// With system instructions
const response2 = await client.responses.create({
  model: "gpt-4o",
  instructions: "You are a physics professor explaining concepts to undergraduates.",
  input: "What is quantum entanglement?",
});

// Multi-part input
const response3 = await client.responses.create({
  model: "gpt-4o",
  input: [
    { type: "text", text: "Compare these two approaches:" },
    { type: "text", text: "Approach A: Use recursion" },
    { type: "text", text: "Approach B: Use iteration" },
  ],
});

Streaming Responses

// Basic streaming
const stream = await client.responses.create({
  model: "gpt-4o",
  input: "Write a short story about a robot",
  stream: true,
});

for await (const event of stream) {
  if (event.type === "response.text.delta") {
    process.stdout.write(event.delta);
  } else if (event.type === "response.completed") {
    console.log("\n\nTokens used:", event.response.usage?.total_tokens);
  }
}

// Using the stream helper
const stream2 = client.responses.stream({
  model: "gpt-4o",
  input: "Explain TypeScript generics",
});

// Collect full text
let fullText = "";
for await (const event of stream2) {
  if (event.type === "response.text.delta") {
    fullText += event.delta;
  }
}

// Or use helper methods
const finalResponse = await stream2.finalResponse();
console.log(finalResponse.output_text);

Structured Output (JSON)

import { zodResponseFormat } from "openai/helpers/zod";
import { z } from "zod";

// Define schema
const RecipeSchema = z.object({
  name: z.string(),
  ingredients: z.array(z.object({
    item: z.string(),
    amount: z.string(),
  })),
  instructions: z.array(z.string()),
  prepTime: z.number(),
  cookTime: z.number(),
});

// Generate structured output
const response = await client.responses.create({
  model: "gpt-4o",
  input: "Give me a recipe for chocolate chip cookies",
  text: {
    format: zodResponseFormat(RecipeSchema, "Recipe"),
  },
});

// Parse output
const recipe = JSON.parse(response.output_text);
console.log(recipe.name); // "Chocolate Chip Cookies"
console.log(recipe.ingredients[0]); // { item: "...", amount: "..." }

// Or use parse for automatic validation
const response2 = await client.responses.parse({
  model: "gpt-4o",
  input: "Generate a recipe for pasta",
  text: {
    format: zodResponseFormat(RecipeSchema, "Recipe"),
  },
});

// Fully typed and validated
const recipe2 = response2.output_parsed;
if (recipe2) {
  console.log(recipe2.cookTime); // Type: number
}

Function Calling

// Define functions
const tools = [
  {
    type: "function" as const,
    name: "get_weather",
    description: "Get the current weather in a location",
    parameters: {
      type: "object",
      properties: {
        location: {
          type: "string",
          description: "City and state, e.g., San Francisco, CA",
        },
        unit: {
          type: "string",
          enum: ["celsius", "fahrenheit"],
        },
      },
      required: ["location"],
    },
    strict: true,
  },
];

// First request
const response1 = await client.responses.create({
  model: "gpt-4o",
  input: "What's the weather like in Boston?",
  tools,
});

// Check for tool calls
const toolCall = response1.output.find(
  (item) => item.type === "function_call"
);

if (toolCall && toolCall.type === "function_call") {
  console.log("Function:", toolCall.name);
  console.log("Arguments:", toolCall.arguments);

  // Call your function
  const weatherData = await getWeather(JSON.parse(toolCall.arguments));

  // Send back results
  const response2 = await client.responses.create({
    model: "gpt-4o",
    input: [
      ...response1.output,
      {
        type: "function_call_output",
        call_id: toolCall.call_id,
        output: JSON.stringify(weatherData),
      },
    ],
    tools,
  });

  console.log(response2.output_text);
}

// Or use streaming
const stream = await client.responses.create({
  model: "gpt-4o",
  input: "What's the weather in Paris and London?",
  tools,
  stream: true,
  parallel_tool_calls: true,
});

for await (const event of stream) {
  if (event.type === "response.function_call_arguments.done") {
    console.log("Tool call:", event.name, event.arguments);
  }
}

Computer Use

// Set up computer tool
const response = await client.responses.create({
  model: "gpt-4o",
  input: "Click the submit button on the form",
  tools: [
    {
      type: "computer_use_preview",
      display_width: 1920,
      display_height: 1080,
      environment: "browser",
    },
  ],
  stream: true,
});

// Handle computer actions
for await (const event of stream) {
  if (event.type === "response.output_item.added") {
    const item = event.item;
    if (item.type === "computer_call") {
      console.log("Computer action:", item.action);

      // Execute action in your environment
      if (item.action.type === "click") {
        await executeClick(item.action.x, item.action.y);
      } else if (item.action.type === "type") {
        await executeType(item.action.text);
      } else if (item.action.type === "screenshot") {
        const screenshot = await takeScreenshot();

        // Send screenshot back
        await client.responses.create({
          model: "gpt-4o",
          input: [
            ...response.output,
            {
              type: "computer_call_output",
              call_id: item.call_id,
              output: {
                type: "computer_screenshot",
                image_url: screenshot,
              },
            },
          ],
          tools: response.tools,
        });
      }
    }
  }
}

File Search

// Upload files to vector store first
const vectorStore = await client.vectorStores.create({
  name: "Product Documentation",
});

await client.vectorStores.files.upload(
  vectorStore.id,
  await toFile(fs.readFileSync("docs.pdf"), "docs.pdf")
);

// Query with file search
const response = await client.responses.create({
  model: "gpt-4o",
  input: "How do I configure SSL certificates?",
  tools: [
    {
      type: "file_search",
      vector_store_ids: [vectorStore.id],
      max_num_results: 5,
      ranking_options: {
        ranker: "auto",
        score_threshold: 0.7,
      },
    },
  ],
});

// Check file search results
const fileSearch = response.output.find(
  (item) => item.type === "file_search_call"
);

if (fileSearch && fileSearch.type === "file_search_call" && fileSearch.results) {
  console.log("Found", fileSearch.results.length, "relevant documents");
  fileSearch.results.forEach((result) => {
    console.log(`- ${result.file_name} (score: ${result.score})`);
  });
}

console.log("\nAnswer:", response.output_text);

Web Search

// Simple web search
const response = await client.responses.create({
  model: "gpt-4o",
  input: "What are the latest developments in quantum computing?",
  tools: [{ type: "web_search" }],
});

// Check web search results
const webSearch = response.output.find(
  (item) => item.type === "web_search_call"
);

if (webSearch && webSearch.type === "web_search_call" && webSearch.results) {
  console.log("Search query:", webSearch.query);
  console.log("\nResults:");
  webSearch.results.forEach((result) => {
    console.log(`- ${result.title}`);
    console.log(`  ${result.url}`);
    console.log(`  ${result.snippet}\n`);
  });
}

console.log("\nSummary:", response.output_text);

// Streaming web search
const stream = await client.responses.create({
  model: "gpt-4o",
  input: "Compare the latest iPhone and Samsung flagship phones",
  tools: [{ type: "web_search" }],
  stream: true,
});

for await (const event of stream) {
  if (event.type === "response.web_search_call.searching") {
    console.log("Searching:", event.query);
  } else if (event.type === "response.web_search_call.completed") {
    console.log("Search completed with", event.results.length, "results");
  } else if (event.type === "response.text.delta") {
    process.stdout.write(event.delta);
  }
}

Multi-Turn Conversations

// Method 1: Using previous_response_id
const response1 = await client.responses.create({
  model: "gpt-4o",
  input: "My favorite color is blue",
});

const response2 = await client.responses.create({
  model: "gpt-4o",
  input: "What's my favorite color?",
  previous_response_id: response1.id,
});

console.log(response2.output_text); // "Your favorite color is blue."

// Method 2: Using conversation
const conversation = await client.conversations.create({
  metadata: { topic: "preferences" },
});

const response3 = await client.responses.create({
  model: "gpt-4o",
  input: "I love pizza",
  conversation: conversation.id,
});

const response4 = await client.responses.create({
  model: "gpt-4o",
  input: "What food do I love?",
  conversation: conversation.id,
});

// Method 3: Manual input management
const messages = [];

messages.push({
  type: "message" as const,
  role: "user" as const,
  content: "I'm planning a vacation",
});

const r1 = await client.responses.create({
  model: "gpt-4o",
  input: messages,
});

messages.push(...r1.output);
messages.push({
  type: "message" as const,
  role: "user" as const,
  content: "I want to go somewhere warm",
});

const r2 = await client.responses.create({
  model: "gpt-4o",
  input: messages,
});

Reasoning Models (o-series)

// Basic reasoning
const response = await client.responses.create({
  model: "o3-mini",
  input: "Solve: If a train travels 120 km in 2 hours, then stops for 30 minutes, then travels another 180 km in 3 hours, what is the average speed for the entire journey?",
  reasoning: {
    effort: "high",
  },
});

// Check reasoning content
const reasoning = response.output.find(
  (item) => item.type === "reasoning"
);

if (reasoning && reasoning.type === "reasoning") {
  console.log("Reasoning steps:");
  reasoning.content.forEach((part) => {
    if (part.type === "reasoning_text") {
      console.log("-", part.reasoning_text);
    }
  });

  if (reasoning.summary) {
    console.log("\nSummary:", reasoning.summary.reasoning_summary);
  }
}

console.log("\nFinal answer:", response.output_text);

// Streaming reasoning
const stream = await client.responses.create({
  model: "o1",
  input: "Prove that the square root of 2 is irrational",
  reasoning: { effort: "medium" },
  stream: true,
});

console.log("Reasoning process:");
for await (const event of stream) {
  if (event.type === "response.reasoning.text.delta") {
    process.stdout.write(event.delta);
  } else if (event.type === "response.reasoning.summary.text.done") {
    console.log("\n\nReasoning summary:", event.text);
  } else if (event.type === "response.text.delta") {
    process.stdout.write(event.delta);
  }
}

Background Responses

// Start a long-running response in background
const response = await client.responses.create({
  model: "gpt-4o",
  input: "Write a comprehensive guide to TypeScript, covering all major features with examples",
  max_output_tokens: 10000,
  background: true,
});

console.log("Response ID:", response.id);
console.log("Status:", response.status); // 'queued' or 'in_progress'

// Poll for completion
async function waitForResponse(responseId: string) {
  while (true) {
    const current = await client.responses.retrieve(responseId);

    if (current.status === "completed") {
      return current;
    } else if (current.status === "failed") {
      throw new Error(`Response failed: ${current.error?.message}`);
    }

    console.log("Status:", current.status);
    await new Promise((resolve) => setTimeout(resolve, 2000));
  }
}

const completed = await waitForResponse(response.id);
console.log("Completed! Output length:", completed.output_text.length);

// Or cancel if needed
await client.responses.cancel(response.id);

Image Input

// With image URL
const response = await client.responses.create({
  model: "gpt-4o",
  input: [
    { type: "text", text: "What objects are in this image?" },
    {
      type: "image",
      image_url: {
        url: "https://example.com/image.jpg",
        detail: "high",
      },
    },
  ],
});

// With uploaded file
const file = await client.files.create({
  file: await toFile(fs.readFileSync("photo.jpg"), "photo.jpg"),
  purpose: "vision",
});

const response2 = await client.responses.create({
  model: "gpt-4o",
  input: [
    { type: "text", text: "Describe this image in detail" },
    { type: "image", file_id: file.id },
  ],
});

// Multiple images
const response3 = await client.responses.create({
  model: "gpt-4o",
  input: [
    { type: "text", text: "Compare these two images" },
    { type: "image", image_url: { url: "https://example.com/image1.jpg" } },
    { type: "image", image_url: { url: "https://example.com/image2.jpg" } },
  ],
});

Custom Tools

// Define custom tool
const response = await client.responses.create({
  model: "gpt-4o",
  input: "Process this data: [1, 2, 3, 4, 5]",
  tools: [
    {
      type: "custom",
      name: "data_processor",
      description: "Processes numerical data with custom format",
      format: {
        type: "text_grammar",
        text_grammar: {
          grammar: `
            root ::= "PROCESS" ws data ws "END"
            data ::= "[" ws number (ws "," ws number)* ws "]"
            number ::= [0-9]+
            ws ::= [ \t\n]*
          `,
          root_rule: "root",
        },
      },
    },
  ],
  stream: true,
});

// Handle custom tool calls
for await (const event of stream) {
  if (event.type === "response.custom_call_input.done") {
    console.log("Custom tool input:", event.input);

    // Process with your custom logic
    const result = processData(event.input);

    // Send output back
    const response2 = await client.responses.create({
      model: "gpt-4o",
      input: [
        ...response.output,
        {
          type: "custom_call_output",
          call_id: event.call_id,
          output: result,
        },
      ],
      tools: response.tools,
    });
  }
}

Token Counting

// Count tokens before sending
const count = await client.responses.inputTokens.count({
  model: "gpt-4o",
  input: "This is my input text",
  instructions: "You are a helpful assistant",
  tools: [
    {
      type: "function",
      name: "my_function",
      parameters: { type: "object", properties: {} },
      strict: true,
    },
  ],
});

console.log("Input tokens:", count.input_tokens);

// Estimate cost
const costPer1kTokens = 0.03; // gpt-4o pricing
const estimatedCost = (count.input_tokens / 1000) * costPer1kTokens;
console.log("Estimated input cost: $" + estimatedCost.toFixed(4));

// Check if input fits in context window
const maxContextTokens = 128000; // gpt-4o context window
if (count.input_tokens > maxContextTokens) {
  console.log("Input exceeds context window!");
}

Error Handling

try {
  const response = await client.responses.create({
    model: "gpt-4o",
    input: "Hello",
  });
} catch (error) {
  if (error instanceof OpenAI.APIError) {
    console.error("API Error:", error.message);
    console.error("Status:", error.status);
    console.error("Code:", error.code);
    console.error("Type:", error.type);
  } else if (error instanceof OpenAI.RateLimitError) {
    console.error("Rate limit exceeded");
  } else if (error instanceof OpenAI.AuthenticationError) {
    console.error("Authentication failed");
  } else {
    console.error("Unexpected error:", error);
  }
}

// Handle streaming errors
const stream = await client.responses.create({
  model: "gpt-4o",
  input: "Test",
  stream: true,
});

try {
  for await (const event of stream) {
    if (event.type === "error") {
      console.error("Stream error:", event.error);
    } else if (event.type === "response.failed") {
      console.error("Response failed:", event.error);
    }
  }
} catch (error) {
  console.error("Stream exception:", error);
}

// Check response for errors
const response = await client.responses.create({
  model: "gpt-4o",
  input: "...",
});

if (response.status === "failed" && response.error) {
  console.error("Response error:", response.error.message);
}

if (response.status === "incomplete" && response.incomplete_details) {
  console.warn("Response incomplete:", response.incomplete_details.reason);
}

Best Practices

1. Use Streaming for Long Responses

Streaming provides better user experience and allows handling partial results:

const stream = client.responses.stream({
  model: "gpt-4o",
  input: "Write a long article...",
});

for await (const event of stream) {
  if (event.type === "response.text.delta") {
    // Display text as it arrives
    displayToUser(event.delta);
  }
}

2. Handle Tool Calls Properly

Always check tool call status and handle errors:

const response = await client.responses.create({
  model: "gpt-4o",
  input: "...",
  tools: myTools,
});

for (const item of response.output) {
  if (item.type === "function_call" && item.status === "completed") {
    try {
      const result = await executeFunction(item.name, item.arguments);
      // Send result back to model
    } catch (error) {
      // Send error back
      const errorOutput = {
        type: "function_call_output" as const,
        call_id: item.call_id,
        output: JSON.stringify({ error: error.message }),
      };
    }
  }
}

3. Use Structured Outputs for Predictable Data

Structured outputs ensure the model returns valid JSON:

const response = await client.responses.parse({
  model: "gpt-4o",
  input: "Extract data...",
  text: {
    format: zodResponseFormat(MySchema, "ExtractedData"),
  },
});

// output_parsed is guaranteed to match schema or be null
if (response.output_parsed) {
  // Safely use typed data
  processData(response.output_parsed);
}

4. Manage Conversation State

Choose the right approach for your use case:

// Simple multi-turn: use previous_response_id
const r1 = await client.responses.create({ input: "First message" });
const r2 = await client.responses.create({
  input: "Follow-up",
  previous_response_id: r1.id,
});

// Complex multi-turn: use conversations
const conv = await client.conversations.create();
await client.responses.create({
  input: "Message 1",
  conversation: conv.id,
});
await client.responses.create({
  input: "Message 2",
  conversation: conv.id,
});

// Full control: manual input array
const inputs = [];
inputs.push({ type: "message", role: "user", content: "Hi" });
const r = await client.responses.create({ input: inputs });
inputs.push(...r.output);

5. Monitor Token Usage

Track usage to manage costs:

const response = await client.responses.create({
  model: "gpt-4o",
  input: "...",
});

console.log("Tokens used:", response.usage);
// {
//   input_tokens: 50,
//   output_tokens: 200,
//   total_tokens: 250,
//   output_tokens_details: {
//     text_tokens: 200,
//     reasoning_tokens: 0
//   }
// }

6. Set Appropriate Timeouts

Use timeouts for long-running requests:

const response = await client.responses.create(
  {
    model: "gpt-4o",
    input: "Complex task...",
  },
  {
    timeout: 120000, // 2 minutes
  }
);

7. Use Metadata for Tracking

Add metadata for debugging and analytics:

const response = await client.responses.create({
  model: "gpt-4o",
  input: "...",
  metadata: {
    user_id: "user_123",
    session_id: "sess_456",
    request_type: "chat",
    version: "1.0",
  },
});

8. Implement Proper Error Handling

Handle different error types appropriately:

async function safeCreate(params: ResponseCreateParams) {
  try {
    return await client.responses.create(params);
  } catch (error) {
    if (error instanceof OpenAI.RateLimitError) {
      // Wait and retry
      await wait(60000);
      return await client.responses.create(params);
    } else if (error instanceof OpenAI.APIConnectionError) {
      // Network issue, retry with exponential backoff
      return await retryWithBackoff(() => client.responses.create(params));
    } else {
      // Other errors, log and rethrow
      logger.error("Response creation failed", error);
      throw error;
    }
  }
}

Migration from Chat Completions API

The Responses API replaces the Chat Completions API with a more powerful and flexible interface. Here's how to migrate:

Basic Message

Chat Completions:

const completion = await client.chat.completions.create({
  model: "gpt-4o",
  messages: [{ role: "user", content: "Hello" }],
});

console.log(completion.choices[0].message.content);

Responses API:

const response = await client.responses.create({
  model: "gpt-4o",
  input: "Hello",
});

console.log(response.output_text);

System Message

Chat Completions:

const completion = await client.chat.completions.create({
  model: "gpt-4o",
  messages: [
    { role: "system", content: "You are helpful" },
    { role: "user", content: "Hello" },
  ],
});

Responses API:

const response = await client.responses.create({
  model: "gpt-4o",
  instructions: "You are helpful",
  input: "Hello",
});

Multi-Turn Conversation

Chat Completions:

const messages = [
  { role: "user", content: "My name is Alice" },
  { role: "assistant", content: "Hello Alice!" },
  { role: "user", content: "What's my name?" },
];

const completion = await client.chat.completions.create({
  model: "gpt-4o",
  messages,
});

Responses API:

const response1 = await client.responses.create({
  model: "gpt-4o",
  input: "My name is Alice",
});

const response2 = await client.responses.create({
  model: "gpt-4o",
  input: "What's my name?",
  previous_response_id: response1.id,
});

Function Calling

Chat Completions:

const completion = await client.chat.completions.create({
  model: "gpt-4o",
  messages: [{ role: "user", content: "What's the weather?" }],
  tools: [
    {
      type: "function",
      function: {
        name: "get_weather",
        parameters: { /* ... */ },
      },
    },
  ],
});

const toolCall = completion.choices[0].message.tool_calls?.[0];

Responses API:

const response = await client.responses.create({
  model: "gpt-4o",
  input: "What's the weather?",
  tools: [
    {
      type: "function",
      name: "get_weather",
      parameters: { /* ... */ },
      strict: true,
    },
  ],
});

const toolCall = response.output.find(item => item.type === "function_call");

Streaming

Chat Completions:

const stream = await client.chat.completions.create({
  model: "gpt-4o",
  messages: [{ role: "user", content: "Hello" }],
  stream: true,
});

for await (const chunk of stream) {
  process.stdout.write(chunk.choices[0]?.delta?.content || "");
}

Responses API:

const stream = await client.responses.create({
  model: "gpt-4o",
  input: "Hello",
  stream: true,
});

for await (const event of stream) {
  if (event.type === "response.text.delta") {
    process.stdout.write(event.delta);
  }
}

Common Issues and Solutions

Issue: Response is incomplete

Problem: Response status is "incomplete" with incomplete_details.reason.

Solutions:

// Increase max tokens
const response = await client.responses.create({
  model: "gpt-4o",
  input: "...",
  max_output_tokens: 4096, // Increase limit
});

// Or use truncation
const response2 = await client.responses.create({
  model: "gpt-4o",
  input: longInput,
  truncation: "auto", // Auto-truncate input if needed
});

Issue: Tool calls not working

Problem: Model doesn't call tools or calls wrong tool.

Solutions:

// Be more specific in tool descriptions
const tools = [
  {
    type: "function",
    name: "get_weather",
    description: "Get current weather. Use this when user asks about weather conditions, temperature, or forecast.",
    parameters: { /* ... */ },
    strict: true,
  },
];

// Force tool use
const response = await client.responses.create({
  model: "gpt-4o",
  input: "What's the weather?",
  tools,
  tool_choice: "required", // Must use a tool
});

// Or specify exact tool
const response2 = await client.responses.create({
  model: "gpt-4o",
  input: "...",
  tools,
  tool_choice: {
    type: "function",
    function: { name: "get_weather" },
  },
});

Issue: Token count too high

Problem: Input exceeds model's context window.

Solutions:

// Count tokens first
const count = await client.responses.inputTokens.count({
  model: "gpt-4o",
  input: largeInput,
});

if (count.input_tokens > 128000) {
  // Truncate or summarize input
  const summarized = await summarizeInput(largeInput);

  // Or use auto-truncation
  const response = await client.responses.create({
    model: "gpt-4o",
    input: largeInput,
    truncation: "auto",
  });
}

Issue: Streaming stops unexpectedly

Problem: Stream ends without completion event.

Solutions:

// Implement error handling and reconnection
async function streamWithRetry(params: ResponseCreateParams) {
  let retries = 0;
  const maxRetries = 3;

  while (retries < maxRetries) {
    try {
      const stream = await client.responses.create({
        ...params,
        stream: true,
      });

      for await (const event of stream) {
        if (event.type === "response.completed") {
          return event.response;
        } else if (event.type === "error") {
          throw new Error(event.error.message);
        }
        // Process event
      }
    } catch (error) {
      retries++;
      if (retries >= maxRetries) throw error;
      await wait(1000 * retries); // Exponential backoff
    }
  }
}

Related Resources

  • OpenAI Platform Documentation
  • Responses API Guide
  • Function Calling Guide
  • Structured Outputs Guide
  • Tool Use Guides

Install with Tessl CLI

npx tessl i tessl/npm-openai

docs

assistants.md

audio.md

batches-evals.md

chat-completions.md

client-configuration.md

containers.md

conversations.md

embeddings.md

files-uploads.md

fine-tuning.md

helpers-audio.md

helpers-zod.md

images.md

index.md

realtime.md

responses-api.md

vector-stores.md

videos.md

tile.json