Expand description
§Nanocodex OpenAI API
Tower-native building blocks for the OpenAI Responses API.
nanocodex-oai-api is useful without the Nanocodex agent loop. It owns the
typed request and response model, persistent Responses transport, replayable
Tower attempt boundary, and batteries-included conversation state.
§Quick start
Pass an OpenAI Platform API key to OpenAi::new. Developer instructions
create the stable boundary of a client-owned Session, and follow-on calls
retain completed history automatically:
use nanocodex_oai_api::OpenAi;
let openai = OpenAi::new(std::env::var("OPENAI_API_KEY")?)?;
let mut session = openai
.instructions(
"Remember user-provided deployment facts and say when information is missing.",
)
.build()?;
let mut turn = session.turn();
let completed = turn
.create("The production deployment region is us-west-2.")
.await?;
println!("{}", completed.output_text());
if let Some(cost) = completed.estimated_cost() {
println!("estimated {}", cost.amount());
}This crate supports gpt-5.6-sol (the default), gpt-5.6-terra, and
gpt-5.6-luna. Select a client default with
OpenAi::builder(auth).model(Model::Terra). A session keeps that model for its
lifetime, and each replayable attempt retains it across retries. Changing
models would invalidate the provider checkpoint and require an inefficient
replay of the complete retained context.
API-key HTTPS OpenAI routing gateways may qualify those same closed model
identifiers with OpenAi::builder(auth).model_id_prefix("openai"). The prefix
changes only the wire model ID; model-specific reasoning, compaction, pricing,
and snapshots continue to use the typed Model value. It does not add an
alternate provider or arbitrary-model surface.
USD estimates require no pricing configuration. Each model applies its
published standard rates, or its priority rates when
OpenAiBuilder::fast_mode is enabled. Terra and Luna usage receive the same
complete estimate and status treatment as Sol. Provider-omitted usage remains
distinguishable as usage_not_reported.
§ChatGPT subscription login
Available on native targets. The login and managed credential store are marked as such in docs.rs and are not compiled for WebAssembly.
auth::ChatGptLogin performs an authorization-code login with PKCE using a
loopback callback. The caller chooses the credential file, presents the
authorization URL, and waits for the browser callback. Successful completion
atomically writes the credential file.
The same file can then be loaded into a managed OpenAi client:
use std::path::PathBuf;
use nanocodex_oai_api::{
OpenAi,
auth::{ChatGptLogin, load_chatgpt_auth},
};
let auth_file = PathBuf::from(std::env::var("NANOCODEX_AUTH_FILE")?);
let login = ChatGptLogin::start(&auth_file).await?;
println!("Open this URL to sign in:\n\n{}", login.authorization_url());
let account = login.complete().await?;
println!("Signed in to ChatGPT account {}", account.account_id);
let auth = load_chatgpt_auth(&auth_file)?;
let openai = OpenAi::new(auth)?;
let mut session = openai
.instructions(
"Answer concisely. Preserve identifiers exactly and say when information is missing.",
)
.build()?;
let completed = session
.turn()
.create("Explain what deployment identifier deploy_01J8Y7Q2 refers to.")
.await?;
println!("{}", completed.output_text());Keep the credential file outside source control and reuse the same path on
later runs. It uses Codex’s auth.json format, so Codex and multiple Nanocodex
processes can safely share the same path. auth::load_chatgpt_auth adopts a
same-account rotation from disk before refreshing, refreshes expiring
credentials, and recovers an unauthorized request once with the refreshed
authorization.
auth::chatgpt_auth_status inspects the selected account without exposing
tokens, and auth::logout_chatgpt removes the stored credentials.
A Response is also a typed stream. It retains the completed aggregate
after the stream reaches ResponseEvent::Completed:
use futures_util::TryStreamExt;
use nanocodex_oai_api::{OpenAi, ResponseEvent};
let openai = OpenAi::new(std::env::var("OPENAI_API_KEY")?)?;
let mut session = openai
.instructions("Answer concisely and preserve exact identifiers.")
.build()?;
let mut turn = session.turn();
let mut response = turn.create("Explain the identifier req_7f3.");
while let Some(event) = response.try_next().await? {
if let ResponseEvent::OutputTextDelta(delta) = event {
print!("{delta}");
}
}
let completed = response.await?;
assert!(!completed.output_text().is_empty());§GPT Realtime voice
Available on native targets with the
realtimefeature.
OpenAi::realtime opens an independent GPT Realtime conversation using the
same credential and API base. Platform API keys use a direct Realtime
WebSocket. Managed ChatGPT credentials create the media call through the
ChatGPT backend and join its sideband control WebSocket with the same bearer
and account identity. When no host attestation is available, Nanocodex sends
the same unavailable-token envelope Codex uses when attestation generation
times out; hosts that own an attestation integration may override it with
realtime::RealtimeSessionBuilder::attestation_header.
The library accepts and emits signed 16-bit little-endian, 24 kHz mono PCM through a cheap
realtime::RealtimeSession handle and an independent
realtime::RealtimeEvents stream. It does not open audio devices, so callers
can connect a microphone, files, or ordinary stdin and stdout pipes.
The experimental nanocodex-voice crate packages default desktop devices and
background-agent delegation without moving those policies into this transport
boundary.
Both transports expose background-agent delegation as
realtime::RealtimeEvent::AgentRequest. An embedding handles that event with
its existing agent or tool loop, then calls
realtime::RealtimeSession::complete_agent_request with the typed result.
The nanocodex Ratatui consumer is one concrete desktop adapter: on macOS and
Windows, /voice connects the default microphone and speaker while preserving
the coding agent’s normal history and lifecycle. /voice list prints the
available voice names, /voice cove starts a named voice, and /voice off
stops it. Managed ChatGPT sessions use Codex’s current voice set and default to
cove; Platform sessions default to marin. The TUI uses either the coding
session’s ChatGPT subscription credential or its Platform API key directly; no
second credential is required. Other native hosts can use the device-neutral
realtime-pipe example with their audio stack.
§Ownership and replay
A session owns authoritative typed history and one concrete Tower service.
A ResponseTurn marks a logical agent turn and keeps WebSocket turn-scoped
state stable across sequential create and compact calls. Only completed
operations commit. Healthy calls send a delta plus a private continuation ID;
reconnects replay complete committed history.
The higher-level nanocodex-agent crate decides when to compact and how to
execute tools. This crate implements the provider operation and atomic history
replacement without embedding agent policy.
§Attempt accounting
Transport metrics distinguish physical Responses attempts from retries. A sent
attempt that is cancelled or fails before a provider terminal event increments
billing_uncertain_response_attempts; its ModelAttemptFailed event also sets
billing_uncertain. This does not assume that the provider charged the request.
It records that observed token usage is only a lower bound, while completed and
provider-rejected responses remain exact.
§Contract-only builds
The default client feature remains the complete OpenAI boundary, including
authentication, managed sessions, Tower services, transports, telemetry, and
pricing. Process companions that only need the dependency-light prompt,
response-item, and tool wire contracts may disable default features. This
keeps one canonical contract without linking an unused network client; it does
not create an alternate provider or transport implementation.
§Tools and managed sessions
The tools module defines the model-visible tool contract shared with
nanocodex-tools. A standalone Session does not run a tool loop or attach
a nanocodex-tools::Tools registry automatically. Use nanocodex-agent for
that batteries-included composition. Consumers implementing their own loop can
install definitions with SessionBuilder::tool_definitions and return paired
tool outputs with session::ResponseInput::items.
tools::ToolDefinition::namespace represents the provider-native Responses
namespace shape for related function tools. Function output schemas remain
client-owned execution metadata: they are available through
tools::ToolDefinition::output_schema for Code Mode declarations but are not
serialized into the provider’s function declaration.
§Going lower level
The crate root keeps the normal conversation path and shared input policy
prominent:
OpenAi, Session, ResponseTurn, Response,
CompletedResponse, Prompt, Thinking, and their errors.
sessionadds typed multimodal input, session identity, and explicit compaction results.responsescontains the complete typedOpenAIResponses protocol.toolsdefines the shared tool contract;nanocodex-toolssupplies the batteries-included runtime and implementations.authowns API-key credentials plus native managed ChatGPT login, persistence, refresh, and logout.pricingandeventsexpose automatic model-specific cost estimates and lifecycle-event components.realtimeexposes native GPT Realtime PCM streams and typed voice events.towercontains the generic attempt, response, and retry contracts.transportcontains WebSocket/HTTPS selection, replay policy, transport failures, and connection statistics.
§Custom Tower stacks
OpenAiBuilder::layer wraps each session’s concrete service without boxing
it. OpenAiBuilder::service installs a fresh caller-defined
Service<tower::ResponsesAttempt> and is useful for custom transports,
deterministic tests, and controlled replay. The standard stack owns its retry
and reconnect policy; caller middleware should add deadlines, concurrency
control, tracing, metrics, or error mapping rather than a second retry loop.
Managed sessions own attempt construction and mutable transport state; callers
do not construct the standard service or transport requests directly.
Both methods change the builder’s inferred concrete service-factory type.
Ordinary inline call chains need no type annotation. Application wrappers can
name or bound the generic result through tower::CallerServiceFactory,
tower::LayeredServiceFactory, and tower::ResponsesServiceFactory
without boxing the service stack.
Re-exports§
pub use responses::ResponseEvent;pub use session::CompletedResponse;clientpub use session::Response;clientpub use session::ResponseError;clientpub use session::ResponseErrorKind;clientpub use session::ResponseTurn;clientpub use session::Session;clientpub use session::SessionBuildError;clientpub use session::SessionBuilder;client
Modules§
- auth
client - Authentication sources and managed credential snapshots.
- events
client - Complete typed lifecycle events emitted around Responses operations. Complete typed lifecycle events emitted around Responses operations.
- pricing
client - Automatic model-specific USD estimates from provider token usage. Built-in USD estimates for supported GPT-5.6 models.
- realtime
realtimeand non-target_family=wasm - Bidirectional GPT Realtime audio sessions and typed conversation events. GPT Realtime WebSocket sessions.
- responses
- Complete typed request, event, and item model for the Responses protocol. Typed request, event, and item model for the Responses protocol.
- session
client - Managed session identities, inputs, and compaction results.
- tools
- Tool contracts shared by agent loops and concrete tool runtimes. Dependency-light contract for caller-defined and runtime-provided tools.
- tower
client - Generic Tower attempt, service, retry, and streamed-output contracts. Generic Tower attempt, retry, and completed streamed-output contracts.
- transport
client - Responses transport policy, errors, and connection statistics. Responses transport policy, errors, and connection statistics.
Structs§
- OpenAi
client - Configured, cloneable
OpenAIclient recipe. - Open
AiBuilder client - Builder for a configured
OpenAIclient and concrete Tower service factory. - Prompt
- User input for one agent turn.
- Prompt
Message - One text-only message in a synthetic prompt transcript.
Enums§
- Image
Detail - Image fidelity requested from the model.
- Model
- Supported models in the GPT-5.6 coding-model family.
- Open
AiError client - Invalid
OpenAIclient configuration. - Prompt
Input - Ordered input for one agent turn.
- Prompt
Message Role - Role of one message in a synthetic prompt transcript.
- Prompt
Validation Error - Invalid model-visible prompt content.
- Reasoning
Mode - Responses reasoning execution mode for the supported GPT-5.6 model family.
- Thinking
- Requested model reasoning effort.
- User
Input - One ordered user-supplied prompt item.
Constants§
- CONTEXT_
WINDOW_ TOKENS - Prompt-token budget used by automatic compaction to avoid long-context pricing.
- MODEL
- The default Responses model used by this SDK.