skip to content
$worker

provider-openai-codex

v0.4.15

OpenAI Codex (ChatGPT subscription) provider; implements provider::openai-codex::stream and provider::openai-codex::refresh_models behind llm-router, with ChatGPT device-code sign-in and automatic session renewal backed by private state.

iiiverified
398 installs0 in 7d0 today
install
$iii trigger compose::add worker=provider-openai-codex@0.4.15
  • macOS: arm64
  • Linux: arm64 · armv7 · x64
  • Windows: arm64 · x64

exact versions are immutable; binary and bundle artifacts are digest-pinned.

agent-ready brief for v0.4.15
install + config + dependencies + readme + api reference, all in one place. fetch as agent-context.md for an llm to consume.
the same content rendered as discrete blocks below is exposed as a single markdown document at /workers/provider-openai-codex.md?version=0.4.15. paste it into an llm prompt or pipe it through curl from a worker.

install

install
$iii trigger compose::add worker=provider-openai-codex@0.4.15

dependencies

dependencies2

readme

README.md

provider-openai-codex

OpenAI Codex (ChatGPT subscription) provider worker behind llm-router. It lets the stack generate against a ChatGPT/Codex subscription (billed to the plan, "Sign in with ChatGPT") instead of a pay-per-token API key, by speaking OpenAI's Responses API at the Codex backend.

Implements the provider protocol from tech-specs/2026-06-agentic/llm-router.md: provider::openai-codex::stream (Responses SSE → AssistantMessageEvent frames into a router-owned channel), provider::openai-codex::refresh_models (fetches and reconciles the authenticated Codex model catalog), and provider::openai-codex::count_tokens (local prompt token estimation with the tiktoken tokenizers behind router::count_tokens; never runs the model, costs nothing, and needs no network).

⚠️ Terms-of-service caveat — local/personal dev only. This drives a personal ChatGPT subscription through the undocumented https://chatgpt.com/backend-api/codex backend with a Codex-client originator header. That is plausibly against OpenAI's terms and may risk account action; the backend is unversioned and can change without notice. Use it for local, personal development. For team/CI/production, use official API-key billing (provider-openai). You assume the risk.

Credentials

Open this provider's configuration form in the console and select Sign in with ChatGPT. Open the verification link, enter the displayed code, and approve the login. The provider finishes the login in the background, saves the session, and refreshes the model catalog. No Codex CLI is required, including when the provider runs on a remote machine.

Device login must be enabled in your ChatGPT security settings or workspace permissions. Codes expire after 15 minutes. Cancel or start a new attempt if needed; reopening the form resumes an attempt while the worker is running. Restarting the worker cancels pending attempts, but retains completed logins.

The form shows session status independently from the saved model catalog. Use Refresh models to retry catalog discovery, Switch account to replace the active account after a successful login, or Log out to sign out this provider. Logging out does not sign out the Codex CLI or revoke other clients. The provider will not silently reconnect using a local or external credential.

One account is shared by this provider's consumers in each engine namespace. Run one provider instance per namespace. Its tokens are kept in the private provider-openai-codex-auth state scope, separate from router registration. The state worker's public API and state-change subscriptions cannot expose that scope. Keep the state adapter durable to retain sessions across stack restarts; a private namespace provides access separation, not encryption at rest.

Managed credentials renew automatically within 60 seconds of expiry. Refresh requests are serialized and token rotations are persisted atomically. A revoked session requires another login; temporary storage/network errors do not erase it or switch accounts. The provider never returns tokens to the UI or writes them into router configuration.

Before the first managed login or explicit disconnect, existing installations can still use auth::get_token from an external credential vault, then a read-only ${CODEX_HOME:-$HOME/.codex}/auth.json fallback. The vault remains responsible for its own refresh. The provider never imports or writes the CLI file, and never refreshes the CLI's tokens. The file fallback needs host access and does not support an OS keyring-only login.

Authentication functions

All IDs below begin with provider::openai-codex::. These are operator APIs; the harness, event bindings, and guarded dispatchers deny agent calls to them and to the provider's private state accessors. These checks rely on the existing trusted-engine boundary: they do not isolate credentials from arbitrary code with a direct engine connection or host filesystem access.

Function Input Result
login::start {} login_id, verification_uri, user_code, expires_at (Unix seconds), interval (seconds)
login::poll {login_id} status: pending, ok, expired, canceled, or error; sanitized error when present
login::cancel {login_id} {ok: true}; idempotent, keeps the active account
auth::status {} status: signed_out, authenticated, or expired; source, account_id, pending login
auth::logout {} {ok: true} after disconnect is persisted

Unknown or pre-restart login IDs return canceled. Storage failures return an error instead of a success acknowledgment. Tokens stay entirely in the backend.

API-key credentials are rejected — they belong on provider-openai under provider id openai.

Behavior

  • Registration: self-declares via router::provider::register with backoff, and re-declares on the router::ready trigger. It advertises dynamic model listing and credential_env_var: None; identity binds via the registration_token persisted in state (scope provider-openai-codex).
  • Models: fetches the account-scoped Codex catalog from authenticated GET /backend-api/codex/models?client_version=… at startup, on explicit refresh, after successful sign-in, after router readiness, and every three minutes. Picker-visible results become namespaced router ids (codex/). Each successful non-empty response replaces the complete provider slice, adding new models and removing retired ones. Failed or empty refreshes preserve the router's persisted last-known-good slice. Namespacing prevents AmbiguousModel collisions with provider-openai.
  • Request: Responses API — input items, stream: true, store: false, optional tools and reasoning: { effort }. Headers: Authorization: Bearer, chatgpt-account-id, Codex compatibility version, openai-beta: responses=experimental, originator: codex_cli_rs.
  • SSE: response.output_text.delta → text, response.reasoning_* → thinking, response.function_call_arguments.delta → tool calls, response.completed → usage + terminal. Unknown event types are ignored (forward-compat).
  • Liveness / errors: ping at least every 30s of silence; 401/403 → auth_expired, 429 → rate_limited, context_length_exceededcontext_overflow, 5xx/network → transient, other 4xx → permanent. The provider attempts one managed-token refresh and retry on HTTP 401 before streaming starts; it never replays content already delivered. The router owns other retry policy.

Running

Standard worker CLI: --url (engine WebSocket, default ws://127.0.0.1:49134, or III_URL), --manifest (print the registry manifest and exit), --config (accepted but ignored — this worker has no file-based config).

cargo run -- --url ws://127.0.0.1:49134

Tests

cargo test    # OAuth/session modules, HTTP/SSE stubs, schema goldens
pnpm --dir ui test
pnpm --dir ui build

Regenerate the wire-schema goldens with UPDATE_GOLDENS=1 cargo test.

Troubleshooting

Symptom Cause Fix
not configured: sign in with ChatGPT … no active session select Sign in with ChatGPT in the provider form
device_login_disabled device-code sign-in is disabled enable it in ChatGPT security settings or ask your workspace administrator
storage_unavailable state worker is down or lacks private namespace support start/update the state worker and retry; credentials are not replaced by a fallback
auth_expired token was revoked or the CLI fallback expired sign in again in the provider form
requires a ChatGPT OAuth login … API keys belong on provider-openai credential is an API key this provider is OAuth-only; use provider-openai for keys
missing ChatGPT account id token lacks the account claim sign in again with a ChatGPT account
backend Unsupported parameter / shape errors Codex backend contract drifted update this worker's request/SSE mapping against the current backend
model refresh fails or returns no visible models auth/network/backend catalog problem the last known catalog is retained; fix the underlying error and call provider::openai-codex::refresh_models
model routes ambiguously a codex/* id collided with another provider keep codex ids namespaced; or pin provider: "openai-codex"

The OAuth adapter follows the upstream Codex device login and token refresh protocol at the provider's current compatibility version. See OpenAI authentication guidance for account/workspace setup.

api reference (json)

agent-api-reference.json
{
  "functions": [
    {
      "description": "Serve the provider-openai-codex worker's injected console UI assets (content function for its console:script / console:style triggers).",
      "metadata": {
        "internal": true
      },
      "name": "provider-openai-codex::ui-content",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Input of the content function: the console asks for one asset by path.",
        "properties": {
          "path": {
            "description": "The asset path from the trigger config (e.g. `state/page.js`).",
            "type": "string"
          }
        },
        "required": [
          "path"
        ],
        "title": "UiContentInput",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Output of the content function.",
        "properties": {
          "content": {
            "description": "The asset source, verbatim.",
            "type": "string"
          },
          "content_type": {
            "description": "MIME type the console should serve the asset with.",
            "type": "string"
          }
        },
        "required": [
          "content",
          "content_type"
        ],
        "title": "UiContentResult",
        "type": "object"
      }
    },
    {
      "description": "Cancel the in-flight upstream stream for a request_id (router::abort fan-out), stopping billed generation immediately.",
      "metadata": {
        "internal": true
      },
      "name": "provider::openai-codex::abort",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Input of a provider's `provider::<id>::abort`: actively cancel the in-flight upstream stream for `request_id` (the router's `request_id`, delivered to the provider as `resolution_key`) so billed generation stops immediately instead of waiting for the provider to notice the closed channel on its next write.",
        "properties": {
          "request_id": {
            "type": "string"
          }
        },
        "required": [
          "request_id"
        ],
        "title": "ProviderAbortRequest",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Output of `provider::<id>::abort`. `aborted: false` means the request was unknown — already finished, never started, or aborted before (idempotent).",
        "properties": {
          "aborted": {
            "type": "boolean"
          }
        },
        "required": [
          "aborted"
        ],
        "title": "ProviderAbortResponse",
        "type": "object"
      }
    },
    {
      "description": "Disconnect this provider, cancel pending login, and persistently disable automatic use of legacy credentials. Does not sign out the Codex CLI.",
      "metadata": {
        "internal": true
      },
      "name": "provider::openai-codex::auth::logout",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "title": "EmptyRequest",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "ok": {
            "type": "boolean"
          }
        },
        "required": [
          "ok"
        ],
        "title": "Ack",
        "type": "object"
      }
    },
    {
      "description": "Read Codex session status, credential source, account id, and any pending login. Never returns tokens.",
      "metadata": {
        "internal": true
      },
      "name": "provider::openai-codex::auth::status",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "title": "EmptyRequest",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "AuthStatus": {
            "enum": [
              "signed_out",
              "authenticated",
              "expired"
            ],
            "type": "string"
          },
          "CredentialSource": {
            "enum": [
              "managed",
              "vault",
              "local"
            ],
            "type": "string"
          },
          "LoginStartResponse": {
            "properties": {
              "expires_at": {
                "description": "Unix timestamp in seconds.",
                "format": "int64",
                "type": "integer"
              },
              "interval": {
                "description": "Seconds between status requests from the UI.",
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              },
              "login_id": {
                "type": "string"
              },
              "user_code": {
                "type": "string"
              },
              "verification_uri": {
                "type": "string"
              }
            },
            "required": [
              "expires_at",
              "interval",
              "login_id",
              "user_code",
              "verification_uri"
            ],
            "type": "object"
          }
        },
        "properties": {
          "account_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "login": {
            "anyOf": [
              {
                "$ref": "#/definitions/LoginStartResponse"
              },
              {
                "type": "null"
              }
            ]
          },
          "source": {
            "anyOf": [
              {
                "$ref": "#/definitions/CredentialSource"
              },
              {
                "type": "null"
              }
            ]
          },
          "status": {
            "$ref": "#/definitions/AuthStatus"
          }
        },
        "required": [
          "status"
        ],
        "title": "AuthStatusResponse",
        "type": "object"
      }
    },
    {
      "description": "Count prompt tokens for {model, system_prompt?, tools?, messages} locally with the tiktoken tokenizers; never runs the model and costs nothing.",
      "metadata": {
        "internal": true
      },
      "name": "provider::openai-codex::count_tokens",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "AgentFunction": {
            "description": "Function invocation schema — what a provider sees as a `tools` array entry (README § Function invocation schema; adapter boundary). These describe iii functions exposed to the model, not provider-native tools.",
            "properties": {
              "description": {
                "type": "string"
              },
              "execution_mode": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "label": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "name": {
                "type": "string"
              },
              "parameters": true
            },
            "required": [
              "description",
              "name",
              "parameters"
            ],
            "type": "object"
          },
          "AgentMessage": {
            "anyOf": [
              {
                "$ref": "#/definitions/AssistantMessage"
              },
              {
                "$ref": "#/definitions/FunctionResultMessage"
              },
              {
                "$ref": "#/definitions/CustomMessage"
              },
              {
                "$ref": "#/definitions/UserMessage"
              }
            ],
            "description": "The canonical transcript message union. Untagged: the single-variant role tags disambiguate deserialization."
          },
          "AssistantMessage": {
            "properties": {
              "content": {
                "items": {
                  "$ref": "#/definitions/ContentBlock"
                },
                "type": "array"
              },
              "error_kind": {
                "anyOf": [
                  {
                    "$ref": "#/definitions/ErrorKind"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "error_message": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "model": {
                "type": "string"
              },
              "native_stop_reason": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "provider": {
                "type": "string"
              },
              "role": {
                "$ref": "#/definitions/AssistantRoleTag"
              },
              "stop_reason": {
                "$ref": "#/definitions/StopReason"
              },
              "timestamp": {
                "format": "int64",
                "type": "integer"
              },
              "usage": {
                "anyOf": [
                  {
                    "$ref": "#/definitions/Usage"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "warnings": {
                "items": {
                  "type": "string"
                },
                "type": [
                  "array",
                  "null"
                ]
              }
            },
            "required": [
              "content",
              "model",
              "provider",
              "role",
              "stop_reason",
              "timestamp"
            ],
            "type": "object"
          },
          "AssistantRoleTag": {
            "enum": [
              "assistant"
            ],
            "type": "string"
          },
          "ContentBlock": {
            "description": "Content blocks — the atomic units of message content (README § Content blocks).",
            "oneOf": [
              {
                "properties": {
                  "text": {
                    "type": "string"
                  },
                  "type": {
                    "enum": [
                      "text"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "text",
                  "type"
                ],
                "type": "object"
              },
              {
                "properties": {
                  "attachment_id": {
                    "description": "Optional link to the stored original in the session-manager attachment store. Transcript bookkeeping for lazy readers only: the harness clears it before `router::chat`, and no provider mapping reads it. Tolerated here so a block that still carries it deserializes instead of failing the request; omitted on the wire when absent.",
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "data": {
                    "type": "string"
                  },
                  "mime": {
                    "type": "string"
                  },
                  "type": {
                    "enum": [
                      "image"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "data",
                  "mime",
                  "type"
                ],
                "type": "object"
              },
              {
                "description": "Reference to an original upload in the session-manager attachment store. A REFERENCE ONLY (never inline bytes); the harness strips it before `router::chat`. Tolerated here so a stray block deserializes instead of failing the request; every counter/mapping emits nothing for it.",
                "properties": {
                  "attachment_id": {
                    "type": "string"
                  },
                  "mime": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  },
                  "size": {
                    "format": "uint64",
                    "minimum": 0,
                    "type": "integer"
                  },
                  "type": {
                    "enum": [
                      "file"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "attachment_id",
                  "mime",
                  "name",
                  "size",
                  "type"
                ],
                "type": "object"
              },
              {
                "properties": {
                  "signature": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "text": {
                    "type": "string"
                  },
                  "type": {
                    "enum": [
                      "thinking"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "text",
                  "type"
                ],
                "type": "object"
              },
              {
                "description": "Opaque redacted thinking payload — replayed verbatim on the Anthropic wire.",
                "properties": {
                  "data": {
                    "type": "string"
                  },
                  "type": {
                    "enum": [
                      "redacted_thinking"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "data",
                  "type"
                ],
                "type": "object"
              },
              {
                "properties": {
                  "arguments": true,
                  "function_id": {
                    "type": "string"
                  },
                  "id": {
                    "type": "string"
                  },
                  "type": {
                    "enum": [
                      "function_call"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "arguments",
                  "function_id",
                  "id",
                  "type"
                ],
                "type": "object"
              },
              {
                "properties": {
                  "content": {
                    "items": {
                      "$ref": "#/definitions/ContentBlock"
                    },
                    "type": "array"
                  },
                  "function_call_id": {
                    "type": "string"
                  },
                  "is_error": {
                    "type": [
                      "boolean",
                      "null"
                    ]
                  },
                  "type": {
                    "enum": [
                      "function_result"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "content",
                  "function_call_id",
                  "type"
                ],
                "type": "object"
              }
            ]
          },
          "CustomMessage": {
            "properties": {
              "content": {
                "items": {
                  "$ref": "#/definitions/ContentBlock"
                },
                "type": "array"
              },
              "custom_type": {
                "type": "string"
              },
              "details": true,
              "display": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "role": {
                "$ref": "#/definitions/CustomRoleTag"
              },
              "timestamp": {
                "format": "int64",
                "type": "integer"
              }
            },
            "required": [
              "content",
              "custom_type",
              "role",
              "timestamp"
            ],
            "type": "object"
          },
          "CustomRoleTag": {
            "enum": [
              "custom"
            ],
            "type": "string"
          },
          "ErrorKind": {
            "enum": [
              "auth_expired",
              "rate_limited",
              "context_overflow",
              "transient",
              "permanent"
            ],
            "type": "string"
          },
          "FunctionResultMessage": {
            "properties": {
              "content": {
                "items": {
                  "$ref": "#/definitions/ContentBlock"
                },
                "type": "array"
              },
              "details": true,
              "function_call_id": {
                "type": "string"
              },
              "function_id": {
                "type": "string"
              },
              "is_error": {
                "type": "boolean"
              },
              "role": {
                "$ref": "#/definitions/FunctionResultRoleTag"
              },
              "timestamp": {
                "format": "int64",
                "type": "integer"
              }
            },
            "required": [
              "content",
              "details",
              "function_call_id",
              "function_id",
              "is_error",
              "role",
              "timestamp"
            ],
            "type": "object"
          },
          "FunctionResultRoleTag": {
            "enum": [
              "function_result"
            ],
            "type": "string"
          },
          "StopReason": {
            "enum": [
              "end",
              "length",
              "function_call",
              "aborted",
              "error"
            ],
            "type": "string"
          },
          "Usage": {
            "properties": {
              "cache_read": {
                "format": "uint64",
                "minimum": 0,
                "type": [
                  "integer",
                  "null"
                ]
              },
              "cache_write": {
                "format": "uint64",
                "minimum": 0,
                "type": [
                  "integer",
                  "null"
                ]
              },
              "cost_usd": {
                "format": "double",
                "type": [
                  "number",
                  "null"
                ]
              },
              "input": {
                "format": "uint64",
                "minimum": 0,
                "type": [
                  "integer",
                  "null"
                ]
              },
              "output": {
                "format": "uint64",
                "minimum": 0,
                "type": [
                  "integer",
                  "null"
                ]
              },
              "reasoning": {
                "format": "uint64",
                "minimum": 0,
                "type": [
                  "integer",
                  "null"
                ]
              }
            },
            "type": "object"
          },
          "UserMessage": {
            "properties": {
              "content": {
                "items": {
                  "$ref": "#/definitions/ContentBlock"
                },
                "type": "array"
              },
              "role": {
                "$ref": "#/definitions/UserRoleTag"
              },
              "timestamp": {
                "format": "int64",
                "type": "integer"
              }
            },
            "required": [
              "content",
              "role",
              "timestamp"
            ],
            "type": "object"
          },
          "UserRoleTag": {
            "description": "Single-variant role tags: exact-match on deserialize, correct wire string on serialize, and they let `AgentMessage` be an untagged union.",
            "enum": [
              "user"
            ],
            "type": "string"
          }
        },
        "properties": {
          "messages": {
            "description": "Wire agent messages, the same shape `provider::openai-codex::stream` accepts. Must be non-empty.",
            "items": {
              "$ref": "#/definitions/AgentMessage"
            },
            "type": "array"
          },
          "model": {
            "description": "Model id the prompt targets; selects the tokenizer (o200k_base for gpt-4o/gpt-5/o-series and anything unknown-modern, cl100k_base for gpt-3.5 and non-o gpt-4 families).",
            "type": "string"
          },
          "system_prompt": {
            "default": null,
            "description": "System prompt counted as its own wire message when present.",
            "type": [
              "string",
              "null"
            ]
          },
          "tools": {
            "default": null,
            "description": "Function invocation schemas; each serialized schema counts toward the total.",
            "items": {
              "$ref": "#/definitions/AgentFunction"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "messages",
          "model"
        ],
        "title": "CountTokensRequest",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "estimator": {
            "description": "Always `tiktoken`: a local tokenizer produced the estimate.",
            "type": "string"
          },
          "model": {
            "type": "string"
          },
          "tokens": {
            "description": "Estimated prompt tokens for the assembled request.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "estimator",
          "model",
          "tokens"
        ],
        "title": "CountTokensResponse",
        "type": "object"
      }
    },
    {
      "description": "Cancel a pending device login. Does not disconnect the current account.",
      "metadata": {
        "internal": true
      },
      "name": "provider::openai-codex::login::cancel",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "login_id": {
            "type": "string"
          }
        },
        "required": [
          "login_id"
        ],
        "title": "LoginIdRequest",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "ok": {
            "type": "boolean"
          }
        },
        "required": [
          "ok"
        ],
        "title": "Ack",
        "type": "object"
      }
    },
    {
      "description": "Read a device login attempt's status without exposing OAuth tokens.",
      "metadata": {
        "internal": true
      },
      "name": "provider::openai-codex::login::poll",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "login_id": {
            "type": "string"
          }
        },
        "required": [
          "login_id"
        ],
        "title": "LoginIdRequest",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "LoginStatus": {
            "enum": [
              "pending",
              "ok",
              "expired",
              "canceled",
              "error"
            ],
            "type": "string"
          },
          "SessionError": {
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              }
            },
            "required": [
              "code",
              "message"
            ],
            "type": "object"
          }
        },
        "properties": {
          "error": {
            "anyOf": [
              {
                "$ref": "#/definitions/SessionError"
              },
              {
                "type": "null"
              }
            ]
          },
          "status": {
            "$ref": "#/definitions/LoginStatus"
          }
        },
        "required": [
          "status"
        ],
        "title": "LoginPollResponse",
        "type": "object"
      }
    },
    {
      "description": "Start a ChatGPT device-code login. Returns the verification URL and one-time user code; the provider completes and saves the session in the background.",
      "metadata": {
        "internal": true
      },
      "name": "provider::openai-codex::login::start",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "title": "EmptyRequest",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "expires_at": {
            "description": "Unix timestamp in seconds.",
            "format": "int64",
            "type": "integer"
          },
          "interval": {
            "description": "Seconds between status requests from the UI.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "login_id": {
            "type": "string"
          },
          "user_code": {
            "type": "string"
          },
          "verification_uri": {
            "type": "string"
          }
        },
        "required": [
          "expires_at",
          "interval",
          "login_id",
          "user_code",
          "verification_uri"
        ],
        "title": "LoginStartResponse",
        "type": "object"
      }
    },
    {
      "description": "Internal: router::ready subscriber that re-declares this provider and refreshes its catalog.",
      "metadata": {
        "internal": true
      },
      "name": "provider::openai-codex::on_router_ready",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Event delivered to a provider's `provider::<id>::on_router_ready` (the `router::ready` trigger payload, currently `{}`). Unknown fields are ignored.",
        "title": "RouterReadyEvent",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Ack returned by a provider's `provider::<id>::on_router_ready`.",
        "properties": {
          "ok": {
            "type": "boolean"
          }
        },
        "required": [
          "ok"
        ],
        "title": "ProviderReadyAck",
        "type": "object"
      }
    },
    {
      "description": "Fetch the authenticated Codex model catalog and replace this provider's namespaced router slice; returns the active model count.",
      "metadata": {
        "internal": true
      },
      "name": "provider::openai-codex::refresh_models",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Input of a provider's `provider::<id>::refresh_models` — takes no arguments. A struct (not `Value`) keeps the request schema concrete; unknown fields (e.g. the engine-injected `_caller_worker_id`) are ignored.",
        "title": "RefreshModelsRequest",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Output of `provider::<id>::refresh_models`.",
        "properties": {
          "count": {
            "format": "uint",
            "minimum": 0,
            "type": "integer"
          },
          "ok": {
            "type": "boolean"
          }
        },
        "required": [
          "count",
          "ok"
        ],
        "title": "RefreshModelsResponse",
        "type": "object"
      }
    },
    {
      "description": "Stream an OpenAI Codex completion: resolve a ChatGPT OAuth token from the provider session, call the upstream Responses API, and relay AssistantMessageEvent frames to writer_ref.",
      "metadata": {
        "internal": true
      },
      "name": "provider::openai-codex::stream",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "AgentFunction": {
            "description": "Function invocation schema — what a provider sees as a `tools` array entry (README § Function invocation schema; adapter boundary). These describe iii functions exposed to the model, not provider-native tools.",
            "properties": {
              "description": {
                "type": "string"
              },
              "execution_mode": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "label": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "name": {
                "type": "string"
              },
              "parameters": true
            },
            "required": [
              "description",
              "name",
              "parameters"
            ],
            "type": "object"
          },
          "AgentMessage": {
            "anyOf": [
              {
                "$ref": "#/definitions/AssistantMessage"
              },
              {
                "$ref": "#/definitions/FunctionResultMessage"
              },
              {
                "$ref": "#/definitions/CustomMessage"
              },
              {
                "$ref": "#/definitions/UserMessage"
              }
            ],
            "description": "The canonical transcript message union. Untagged: the single-variant role tags disambiguate deserialization."
          },
          "AssistantMessage": {
            "properties": {
              "content": {
                "items": {
                  "$ref": "#/definitions/ContentBlock"
                },
                "type": "array"
              },
              "error_kind": {
                "anyOf": [
                  {
                    "$ref": "#/definitions/ErrorKind"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "error_message": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "model": {
                "type": "string"
              },
              "native_stop_reason": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "provider": {
                "type": "string"
              },
              "role": {
                "$ref": "#/definitions/AssistantRoleTag"
              },
              "stop_reason": {
                "$ref": "#/definitions/StopReason"
              },
              "timestamp": {
                "format": "int64",
                "type": "integer"
              },
              "usage": {
                "anyOf": [
                  {
                    "$ref": "#/definitions/Usage"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "warnings": {
                "items": {
                  "type": "string"
                },
                "type": [
                  "array",
                  "null"
                ]
              }
            },
            "required": [
              "content",
              "model",
              "provider",
              "role",
              "stop_reason",
              "timestamp"
            ],
            "type": "object"
          },
          "AssistantRoleTag": {
            "enum": [
              "assistant"
            ],
            "type": "string"
          },
          "ChannelDirection": {
            "enum": [
              "read",
              "write"
            ],
            "type": "string"
          },
          "ContentBlock": {
            "description": "Content blocks — the atomic units of message content (README § Content blocks).",
            "oneOf": [
              {
                "properties": {
                  "text": {
                    "type": "string"
                  },
                  "type": {
                    "enum": [
                      "text"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "text",
                  "type"
                ],
                "type": "object"
              },
              {
                "properties": {
                  "attachment_id": {
                    "description": "Optional link to the stored original in the session-manager attachment store. Transcript bookkeeping for lazy readers only: the harness clears it before `router::chat`, and no provider mapping reads it. Tolerated here so a block that still carries it deserializes instead of failing the request; omitted on the wire when absent.",
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "data": {
                    "type": "string"
                  },
                  "mime": {
                    "type": "string"
                  },
                  "type": {
                    "enum": [
                      "image"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "data",
                  "mime",
                  "type"
                ],
                "type": "object"
              },
              {
                "description": "Reference to an original upload in the session-manager attachment store. A REFERENCE ONLY (never inline bytes); the harness strips it before `router::chat`. Tolerated here so a stray block deserializes instead of failing the request; every counter/mapping emits nothing for it.",
                "properties": {
                  "attachment_id": {
                    "type": "string"
                  },
                  "mime": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  },
                  "size": {
                    "format": "uint64",
                    "minimum": 0,
                    "type": "integer"
                  },
                  "type": {
                    "enum": [
                      "file"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "attachment_id",
                  "mime",
                  "name",
                  "size",
                  "type"
                ],
                "type": "object"
              },
              {
                "properties": {
                  "signature": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "text": {
                    "type": "string"
                  },
                  "type": {
                    "enum": [
                      "thinking"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "text",
                  "type"
                ],
                "type": "object"
              },
              {
                "description": "Opaque redacted thinking payload — replayed verbatim on the Anthropic wire.",
                "properties": {
                  "data": {
                    "type": "string"
                  },
                  "type": {
                    "enum": [
                      "redacted_thinking"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "data",
                  "type"
                ],
                "type": "object"
              },
              {
                "properties": {
                  "arguments": true,
                  "function_id": {
                    "type": "string"
                  },
                  "id": {
                    "type": "string"
                  },
                  "type": {
                    "enum": [
                      "function_call"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "arguments",
                  "function_id",
                  "id",
                  "type"
                ],
                "type": "object"
              },
              {
                "properties": {
                  "content": {
                    "items": {
                      "$ref": "#/definitions/ContentBlock"
                    },
                    "type": "array"
                  },
                  "function_call_id": {
                    "type": "string"
                  },
                  "is_error": {
                    "type": [
                      "boolean",
                      "null"
                    ]
                  },
                  "type": {
                    "enum": [
                      "function_result"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "content",
                  "function_call_id",
                  "type"
                ],
                "type": "object"
              }
            ]
          },
          "CustomMessage": {
            "properties": {
              "content": {
                "items": {
                  "$ref": "#/definitions/ContentBlock"
                },
                "type": "array"
              },
              "custom_type": {
                "type": "string"
              },
              "details": true,
              "display": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "role": {
                "$ref": "#/definitions/CustomRoleTag"
              },
              "timestamp": {
                "format": "int64",
                "type": "integer"
              }
            },
            "required": [
              "content",
              "custom_type",
              "role",
              "timestamp"
            ],
            "type": "object"
          },
          "CustomRoleTag": {
            "enum": [
              "custom"
            ],
            "type": "string"
          },
          "ErrorKind": {
            "enum": [
              "auth_expired",
              "rate_limited",
              "context_overflow",
              "transient",
              "permanent"
            ],
            "type": "string"
          },
          "FunctionResultMessage": {
            "properties": {
              "content": {
                "items": {
                  "$ref": "#/definitions/ContentBlock"
                },
                "type": "array"
              },
              "details": true,
              "function_call_id": {
                "type": "string"
              },
              "function_id": {
                "type": "string"
              },
              "is_error": {
                "type": "boolean"
              },
              "role": {
                "$ref": "#/definitions/FunctionResultRoleTag"
              },
              "timestamp": {
                "format": "int64",
                "type": "integer"
              }
            },
            "required": [
              "content",
              "details",
              "function_call_id",
              "function_id",
              "is_error",
              "role",
              "timestamp"
            ],
            "type": "object"
          },
          "FunctionResultRoleTag": {
            "enum": [
              "function_result"
            ],
            "type": "string"
          },
          "Model": {
            "description": "The capability record (README § Model descriptor).",
            "properties": {
              "context_window": {
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              },
              "display_name": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "id": {
                "type": "string"
              },
              "input_limit": {
                "format": "uint64",
                "minimum": 0,
                "type": [
                  "integer",
                  "null"
                ]
              },
              "max_output_tokens": {
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              },
              "pricing": {
                "anyOf": [
                  {
                    "$ref": "#/definitions/Pricing"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "provider": {
                "type": "string"
              },
              "reasoning_efforts": {
                "items": {
                  "$ref": "#/definitions/ReasoningEffort"
                },
                "type": [
                  "array",
                  "null"
                ]
              },
              "speech": {
                "anyOf": [
                  {
                    "$ref": "#/definitions/SpeechModel"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Set on speech models only; see [`SpeechModel`]."
              },
              "supports_cache": {
                "type": [
                  "boolean",
                  "null"
                ]
              },
              "supports_structured_output": {
                "type": [
                  "boolean",
                  "null"
                ]
              },
              "supports_thinking": {
                "type": [
                  "boolean",
                  "null"
                ]
              },
              "supports_tools": {
                "type": [
                  "boolean",
                  "null"
                ]
              },
              "supports_vision": {
                "type": [
                  "boolean",
                  "null"
                ]
              },
              "supports_xhigh": {
                "type": [
                  "boolean",
                  "null"
                ]
              },
              "thinking_budgets": {
                "additionalProperties": {
                  "format": "uint64",
                  "minimum": 0,
                  "type": "integer"
                },
                "type": [
                  "object",
                  "null"
                ]
              }
            },
            "required": [
              "context_window",
              "id",
              "max_output_tokens",
              "provider"
            ],
            "type": "object"
          },
          "Pricing": {
            "properties": {
              "cache_read": {
                "format": "double",
                "type": [
                  "number",
                  "null"
                ]
              },
              "cache_write": {
                "format": "double",
                "type": [
                  "number",
                  "null"
                ]
              },
              "input": {
                "format": "double",
                "type": [
                  "number",
                  "null"
                ]
              },
              "output": {
                "format": "double",
                "type": [
                  "number",
                  "null"
                ]
              }
            },
            "type": "object"
          },
          "ReasoningEffort": {
            "description": "One provider-native reasoning effort advertised for a specific model.\n\nValues intentionally remain strings: provider catalogs can add efforts without requiring a router-wide enum release first.",
            "properties": {
              "description": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "effort": {
                "type": "string"
              }
            },
            "required": [
              "effort"
            ],
            "type": "object"
          },
          "ResponseFormat": {
            "properties": {
              "schema": true,
              "type": {
                "type": "string"
              }
            },
            "required": [
              "type"
            ],
            "type": "object"
          },
          "SpeechModality": {
            "description": "What a speech model does. Chat models carry no `speech` block.",
            "oneOf": [
              {
                "description": "Speech to text, served through `router::transcribe`.",
                "enum": [
                  "stt"
                ],
                "type": "string"
              },
              {
                "description": "Text to speech, served through `router::speak`.",
                "enum": [
                  "tts"
                ],
                "type": "string"
              }
            ]
          },
          "SpeechModel": {
            "description": "Facts about a speech model. Present only on models served through `router::transcribe` / `router::speak`; such models report `context_window` and `max_output_tokens` as 0.",
            "properties": {
              "languages": {
                "description": "BCP-47 tags of the languages the model handles; empty when the provider does not say.",
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              "modality": {
                "$ref": "#/definitions/SpeechModality"
              },
              "streaming": {
                "default": false,
                "description": "Realtime input (stt) or streamed audio output (tts) is available.",
                "type": "boolean"
              }
            },
            "required": [
              "modality"
            ],
            "type": "object"
          },
          "StopReason": {
            "enum": [
              "end",
              "length",
              "function_call",
              "aborted",
              "error"
            ],
            "type": "string"
          },
          "StreamChannelRef": {
            "properties": {
              "access_key": {
                "type": "string"
              },
              "channel_id": {
                "type": "string"
              },
              "direction": {
                "$ref": "#/definitions/ChannelDirection"
              }
            },
            "required": [
              "access_key",
              "channel_id",
              "direction"
            ],
            "type": "object"
          },
          "ThinkingLevel": {
            "description": "\"minimal\" requests the lowest reasoning effort and needs only `thinking` support; levels map to provider-native knobs via `Model::thinking_budgets`.",
            "enum": [
              "minimal",
              "low",
              "medium",
              "high",
              "xhigh"
            ],
            "type": "string"
          },
          "Usage": {
            "properties": {
              "cache_read": {
                "format": "uint64",
                "minimum": 0,
                "type": [
                  "integer",
                  "null"
                ]
              },
              "cache_write": {
                "format": "uint64",
                "minimum": 0,
                "type": [
                  "integer",
                  "null"
                ]
              },
              "cost_usd": {
                "format": "double",
                "type": [
                  "number",
                  "null"
                ]
              },
              "input": {
                "format": "uint64",
                "minimum": 0,
                "type": [
                  "integer",
                  "null"
                ]
              },
              "output": {
                "format": "uint64",
                "minimum": 0,
                "type": [
                  "integer",
                  "null"
                ]
              },
              "reasoning": {
                "format": "uint64",
                "minimum": 0,
                "type": [
                  "integer",
                  "null"
                ]
              }
            },
            "type": "object"
          },
          "UserMessage": {
            "properties": {
              "content": {
                "items": {
                  "$ref": "#/definitions/ContentBlock"
                },
                "type": "array"
              },
              "role": {
                "$ref": "#/definitions/UserRoleTag"
              },
              "timestamp": {
                "format": "int64",
                "type": "integer"
              }
            },
            "required": [
              "content",
              "role",
              "timestamp"
            ],
            "type": "object"
          },
          "UserRoleTag": {
            "description": "Single-variant role tags: exact-match on deserialize, correct wire string on serialize, and they let `AgentMessage` be an untagged union.",
            "enum": [
              "user"
            ],
            "type": "string"
          }
        },
        "description": "Input of a provider worker's `provider::<id>::stream` iii function — what the router forwards per attempt. (No `PartialEq`: `iii_sdk::StreamChannelRef` doesn't implement it.)",
        "properties": {
          "max_output_tokens": {
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "messages": {
            "items": {
              "$ref": "#/definitions/AgentMessage"
            },
            "type": "array"
          },
          "model": {
            "type": "string"
          },
          "model_meta": {
            "anyOf": [
              {
                "$ref": "#/definitions/Model"
              },
              {
                "type": "null"
              }
            ]
          },
          "provider_options": true,
          "resolution_key": {
            "type": [
              "string",
              "null"
            ]
          },
          "response_format": {
            "anyOf": [
              {
                "$ref": "#/definitions/ResponseFormat"
              },
              {
                "type": "null"
              }
            ]
          },
          "session_id": {
            "description": "Stable conversation identity for provider cache affinity.",
            "type": [
              "string",
              "null"
            ]
          },
          "system_prompt": {
            "type": [
              "string",
              "null"
            ]
          },
          "thinking_level": {
            "anyOf": [
              {
                "$ref": "#/definitions/ThinkingLevel"
              },
              {
                "type": "null"
              }
            ]
          },
          "tools": {
            "items": {
              "$ref": "#/definitions/AgentFunction"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "writer_ref": {
            "$ref": "#/definitions/StreamChannelRef"
          }
        },
        "required": [
          "messages",
          "model",
          "writer_ref"
        ],
        "title": "ProviderStreamInput",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Output of a provider's `provider::<id>::stream` (spec § stream contract): the function streams frames to `writer_ref` and returns this ack.",
        "properties": {
          "ok": {
            "type": "boolean"
          }
        },
        "required": [
          "ok"
        ],
        "title": "ProviderStreamOutput",
        "type": "object"
      }
    }
  ],
  "triggers": []
}