# OpenAi

The OpenAI Responses API client that the Codex harness uses for its model requests.

`builder.openai` takes an `OpenAi` value. `OpenAi::new` and `OpenAi::builder` take an `OpenAiAuth` or an API key string. The builder sets the model, transport, reasoning, service tier, and gateway, and `build` validates the result.

```rust
use nanocode::{Model, Nanocode, OpenAi, Thinking};

// 1. Make a client from an API key with a default model and effort
let openai = OpenAi::builder(std::env::var("OPENAI_API_KEY")?)
    .model(Model::Luna)
    .thinking(Thinking::Low)
    .build()?;

// 2. Install it as the Codex harness
let runtime = Nanocode::builder().openai(openai).build_async().await?;
```

## Signature

```rust
// OpenAi is Clone. The default factory is the standard HTTPS and
// WebSocket stack.
impl OpenAi {
    pub fn new(
        auth: impl Into<OpenAiAuth>,
    ) -> Result<OpenAi, OpenAiError>;
    pub fn builder(auth: impl Into<OpenAiAuth>) -> OpenAiBuilder;
}

impl Default for OpenAi; // native targets only
```

## Constructors

### OpenAi::new

```rust
// Builds a client with the default settings for its authentication
pub fn new(auth: impl Into<OpenAiAuth>) -> Result<OpenAi, OpenAiError>
```

Equivalent to `OpenAi::builder(auth).build()`.

```rust
// Uses an API key with every other setting at its default
let openai = OpenAi::new(std::env::var("OPENAI_API_KEY")?)?;
```

### OpenAi::builder

```rust
// Starts a builder
pub fn builder(auth: impl Into<OpenAiAuth>) -> OpenAiBuilder
```

Returns an `OpenAiBuilder` with the base URLs of the authentication mode. API-key authentication uses `https://api.openai.com/v1`. ChatGPT authentication uses `https://chatgpt.com/backend-api/codex`.

```rust
use nanocode::codex::auth::OpenAiAuth;

// Starts from an explicit OpenAiAuth value
let builder = OpenAi::builder(OpenAiAuth::api_key(key));
```

### OpenAi::default

> [!NOTE]
> `OpenAi::default` and `OpenAiAuth::chatgpt` exist only on native targets.

```rust
// Signs in with the ChatGPT login in the nanocode home
impl Default for OpenAi
```

Uses `OpenAiAuth::chatgpt()`, which reads the ChatGPT login from `auth.json` in the nanocode home when the first request needs it. A missing login returns `OpenAiAuthError::LoginRequired`, whose message names `/login codex`.

```rust
// Uses the login that `nc` stores
let runtime = Nanocode::builder()
    .openai(OpenAi::default())
    .build_async()
    .await?;
```

## OpenAiAuth

The credentials of the client, at `nanocode::codex::auth::OpenAiAuth`. `String` and `&str` convert into `OpenAiAuth::api_key`.

| Constructor                          | Behavior                                                                                                      |
| ------------------------------------ | ------------------------------------------------------------------------------------------------------------- |
| `OpenAiAuth::api_key(key)`           | Sends the API key as a bearer token.                                                                          |
| `OpenAiAuth::chatgpt()`              | Uses the ChatGPT login in `$NANOCODE_HOME/auth.json`. Native only.                                            |
| `OpenAiAuth::gateway_managed()`      | Sends no credential. A gateway, such as `ResponsesGateway::cloudflare_gateway` with `gateway_token`, adds it. |
| `OpenAiAuth::host_managed_chatgpt()` | ChatGPT mode with the credential added by the host transport.                                                 |

```rust
use nanocode::codex::auth::OpenAiAuth;

// Lets a Cloudflare AI Gateway hold the OpenAI key
let auth = OpenAiAuth::gateway_managed();
```

## Builder Methods

### model

* **Type:** `Model`
* **Default:** `Model::Astra`

Sets the model. It also sets the thinking level to the model's default, unless `thinking` set one. `Model::Glm53`, `Model::Kimi`, and `Model::Mimo` switch the client to HTTPS with full replay.

```rust
// Uses Model::Sol
let openai = OpenAi::builder(key).model(Model::Sol).build()?;
```

### thinking

* **Type:** `Thinking`
* **Default:** the model's default

Sets the reasoning effort of requests.

```rust
// Uses high effort
let openai = OpenAi::builder(key).thinking(Thinking::High).build()?;
```

### reasoning_mode

* **Type:** `ReasoningMode`
* **Default:** `ReasoningMode::Standard`

Sets the reasoning mode.

```rust
// Requests pro reasoning
let openai = OpenAi::builder(key)
    .reasoning_mode(ReasoningMode::Pro)
    .build()?;
```

### service_tier

* **Type:** `ServiceTier`
* **Default:** `ServiceTier::Standard`

Sets the service tier. `fast_mode(true)` sets `ServiceTier::Fast`, and `fast_mode(false)` sets `ServiceTier::Standard`.

```rust
// Requests priority processing
let openai = OpenAi::builder(key)
    .service_tier(ServiceTier::Priority)
    .build()?;
```

### transport

* **Type:** `ResponsesTransport`
* **Default:** `ResponsesTransport::WebSocket`

Selects WebSocket or HTTPS for the Responses API. HTTPS without stored responses uses full replay.

```rust
use nanocode::codex::transport::ResponsesTransport;

// Sends each request over HTTPS
let openai = OpenAi::builder(key)
    .transport(ResponsesTransport::Https)
    .build()?;
```

### history

* **Type:** `ResponsesHistory`
* **Default:** `ResponsesHistory::Incremental`

Selects whether a request sends only new items or replays the full history.

```rust
use nanocode::codex::transport::ResponsesHistory;

// Replays the full history on every request
let openai = OpenAi::builder(key)
    .history(ResponsesHistory::FullReplay)
    .build()?;
```

### store

* **Type:** `bool`
* **Default:** `false`

Asks the API to store responses. On HTTPS, `true` selects incremental history and `false` selects full replay.

```rust
// Stores responses so later requests can continue them
let openai = OpenAi::builder(key).store(true).build()?;
```

### websocket_warmup

* **Type:** `bool`
* **Default:** `false`

Opens the WebSocket before the first request.

```rust
// Connects ahead of the first turn
let openai = OpenAi::builder(key).websocket_warmup(true).build()?;
```

### context_window_tokens

* **Type:** `u64`
* **Default:** `272000`

Sets the context window that the harness plans for. Values above the model's maximum are lowered to the maximum.

```rust
// Plans for a smaller window
let openai = OpenAi::builder(key)
    .context_window_tokens(128_000)
    .build()?;
```

### api_base_url

* **Type:** `impl Into<String>`
* **Default:** the base URL of the authentication mode

Sets the HTTPS base URL. `websocket_url` sets the WebSocket URL.

```rust
// Points the client at a compatible local endpoint
let openai = OpenAi::builder(key)
    .api_base_url("http://127.0.0.1:8080/v1")
    .build()?;
```

### model_id_prefix

* **Type:** `impl Into<String>`

Prefixes the model ID in requests as `<prefix>/<model>`, for endpoints that name models by vendor. A prefix requires API-key authentication and the HTTPS transport.

```rust
use nanocode::codex::transport::ResponsesTransport;

// Sends openai/gpt-6-luna as the model ID
let openai = OpenAi::builder(key)
    .model(Model::Luna)
    .transport(ResponsesTransport::Https)
    .model_id_prefix("openai")
    .build()?;
```

### responses_gateway

* **Type:** `ResponsesGateway`

Routes requests through a Responses API gateway. It sets the base URL and model prefix of the gateway, and selects HTTPS with full replay and no stored responses. See [`ResponsesGateway`](/docs/api/rust/ResponsesGateway).

```rust
use nanocode::codex::transport::ResponsesGateway;

// Sends requests through OpenRouter
let openai = OpenAi::builder(key)
    .responses_gateway(ResponsesGateway::openrouter())
    .build()?;
```

### max_attempts

* **Type:** `NonZeroU32`

Sets the maximum number of attempts per request on the standard transport.

```rust
use std::num::NonZeroU32;

// Tries each request at most three times
let openai = OpenAi::builder(key)
    .max_attempts(NonZeroU32::new(3).ok_or("zero")?)
    .build()?;
```

### http_layer

> [!NOTE]
> `http_layer`, `http_client`, and `chat_gateway` exist only on native targets.

* **Type:** `impl nanocode::http::Layer`

Wraps the HTTP requests of the client in a layer. It selects HTTPS and turns off WebSocket warmup.

```rust
// Adds a layer that signs each request
let openai = OpenAi::builder(key).http_layer(signer).build()?;
```

### http_client

* **Type:** `reqwest::Client`

Uses a caller-supplied `reqwest` client for the standard transport.

```rust
// Shares one connection pool with the host
let openai = OpenAi::builder(key)
    .http_client(reqwest::Client::new())
    .build()?;
```

## Errors

### OpenAiError

`build` and `OpenAi::new` return `nanocode::codex::OpenAiError`. `InvalidConfiguration` reports a setting that cannot work, for example a Responses gateway with ChatGPT authentication. `Authorization` reports a credential error.

```rust
use nanocode::codex::{
    OpenAiError, auth::OpenAiAuth, transport::ResponsesGateway,
};

// Gateways require API-key authentication
let result = OpenAi::builder(OpenAiAuth::host_managed_chatgpt())
    .responses_gateway(ResponsesGateway::openrouter())
    .build();
if let Err(OpenAiError::InvalidConfiguration { detail }) = result {
    eprintln!("{detail}");
}
```
