# zidane/providers/openai

> The OpenAI provider on the Responses API, with API keys or ChatGPT (Codex) OAuth credentials.

Import: `import { … } from 'zidane/providers/openai'`. Source: [src/providers/openai.ts](https://github.com/Tahul/zidane/blob/main/src/providers/openai.ts).

Use `openai()` for OpenAI models on the Responses API. Pass a platform key as `apiKey`. With no key, it runs on `OPENAI_CODEX_API_KEY`, then on the stored Codex OAuth sign-in. It does not run on `OPENAI_API_KEY`. The agent's session id is sent as `prompt_cache_key`, so a conversation keeps hitting the same prompt cache. For the Chat Completions API, use [`openaiCompat()`](https://zidane.si/docs/reference/providers-openai-compat.md). See [Providers](https://zidane.si/docs/providers.md#openai).

```ts
import { createAgent } from 'zidane'
import { openai } from 'zidane/providers/openai'

const agent = createAgent({ provider: openai({ defaultModel: 'gpt-6-astra' }) })
const stats = await agent.run({ prompt: 'Summarize README.md in three bullets.' })
console.log(stats.turns)
```

## Functions

### `classifyOpenAIError`

Function.

Classify an OpenAI Codex error. pi-ai surfaces errors either as thrown `Error`s
(wrapping `event.error.errorMessage`) or via stream event types.

The retryable hint is set on a transient failure — pattern-matched against
`message` since pi-ai strips structured fields on plain-Error throws. Set `behavior.retry.maxAttempts: 1`
to disable the loop-level retry.

```ts
function classifyOpenAIError(err: unknown): ClassifiedError | null
```

**Parameters**

- `err` (`unknown`): Error thrown by pi-ai or the HTTP layer.

**Returns** `ClassifiedError | null`

Source: [src/providers/openai.ts:475](https://github.com/Tahul/zidane/blob/main/src/providers/openai.ts#L475)

### `mapCodexStopReason`

Function.

Map pi-ai's `StopReason` to the zidane `TurnFinishReason` union — the same
native-stop-reason fidelity anthropic's `mapStopReason` / openai-compat's
`mapOAIFinishReason` provide. `length` (max-token truncation) maps to
`'length'`, not to a clean `stop`. `hasToolCalls` is the fallback for
messages whose stop reason is missing or doesn't carry the tool-call signal.

```ts
function mapCodexStopReason(
  stopReason: string | undefined,
  hasToolCalls: boolean,
): TurnFinishReason
```

**Parameters**

- `stopReason` (`string | undefined`): pi-ai stop reason, when present.
- `hasToolCalls` (`boolean`): Whether the turn contains tool calls.

**Returns** `TurnFinishReason`

Source: [src/providers/openai.ts:372](https://github.com/Tahul/zidane/blob/main/src/providers/openai.ts#L372)

### `openai`

Function.

Creates the OpenAI provider on the Responses API.
Picks the backend per request from the credential: a Codex OAuth token streams through the ChatGPT Codex backend, a platform API key (`sk-…`) through the standard Responses API.
A run reads `params.apiKey`, then `OPENAI_CODEX_API_KEY`, then the stored OAuth credentials. `OPENAI_API_KEY` is read only by the exact token count (`countTokens`) and by the decisions helper, together with `params.apiKey` and `OPENAI_CODEX_API_KEY`.

```ts
function openai(params?: OpenAIParams): Provider
```

**Parameters**

- `params?` (`OpenAIParams`): API key or OAuth credentials, account id, default model, transport and extra headers.

**Returns** `Provider`

**Example**

```ts
import { createAgent } from 'zidane'
import { openai } from 'zidane/providers/openai'

const agent = createAgent({
  provider: openai({ apiKey: process.env.OPENAI_API_KEY }),
})
await agent.run({ prompt: 'Say hello.' })
```

Source: [src/providers/openai.ts:618](https://github.com/Tahul/zidane/blob/main/src/providers/openai.ts#L618)

### `toPiMessages`

Function.

Converts session messages to pi-ai messages for the Responses wire, pairing tool calls with their results.

```ts
function toPiMessages(messages: SessionMessage[], modelId: string): Message[]
```

**Parameters**

- `messages` (`SessionMessage[]`): Session messages to convert.
- `modelId` (`string`): Model id stamped on converted assistant messages.

**Returns** `Message[]`

Source: [src/providers/openai.ts:281](https://github.com/Tahul/zidane/blob/main/src/providers/openai.ts#L281)

## Interfaces

### `OpenAIParams`

Interface.

Options for [`openai`](https://zidane.si/docs/reference/providers-openai.md#openai): an API key or ChatGPT OAuth credentials, plus model and request settings.

```ts
interface OpenAIParams extends OAuthParams
```

**Properties**

- `access?` (`string`, from `OAuthParams`): OAuth access token supplied at runtime. Used together with `refresh` and `expires` to refresh without a credentials file.
- `account?` (`string`, from `OAuthParams`): Run on ONE stored account of the provider instead of its active one: the
  credential's stable id (`ProviderCredential.id`, see `chat/credentials`).
  Resolved to the slot holding it on every token read and refresh, so
  promoting another account mid-session never moves this provider to it.
  The provider's env key is ignored while pinned (it is the active
  credential's, not this account's). A missing account fails the call with
  [`pinnedAccountMissingError`](https://zidane.si/docs/reference/providers.md#pinnedAccountMissingError) — never a silent fallback to another
  account.
- `accountId?` (`string`): ChatGPT account id sent with runtime OAuth credentials. Normally derived from the access token.
- `apiKey?` (`string`, from `OAuthParams`): Static API key or OAuth access token sent as is, bypassing credential lookup and refresh.
- `defaultModel?` (`string`, default `'gpt-6-astra'`): Model used when a request does not set one.
- `expires?` (`number`, from `OAuthParams`): Expiry of `access` as a Unix timestamp in milliseconds.
- `extraHeaders?` (`Record<string, string>`): Extra HTTP headers merged into every request (the streaming Responses call
  and the token-count endpoint). Use for routing/attribution headers a proxy
  in front of the OpenAI Codex endpoint consumes. Merged with provider
  defaults; pi-ai lets these override defaults, so avoid `authorization` /
  `content-type` unless you intend to replace them.
- `refresh?` (`string`, from `OAuthParams`): OAuth refresh token supplied at runtime.
- `transport?` (`'auto' | 'sse' | 'websocket'`): Transport for the Codex backend: `sse`, `websocket` or `auto`. Ignored for platform API keys.

Source: [src/providers/openai.ts:64](https://github.com/Tahul/zidane/blob/main/src/providers/openai.ts#L64)
