OpenAI
The openai_model server connects NeMo Gym to OpenAI without translating between API formats: a Responses request goes to OpenAI’s Responses API and returns a Responses object, and a Chat Completions request goes to OpenAI’s Chat Completions and returns a chat completion — OpenAI serves both natively.
Because it is a pass-through, the Responses endpoint also works with any other backend that implements the Responses API natively — point openai_base_url at it. In practice that is rare: most hosted backends only expose Chat Completions and instead go through Inference Providers, which translates between the two formats.
Gym pins OpenAI’s Python SDK to 2.45.0, including max reasoning effort and OpenAI’s
programmatic tool calling schema. Responses requests keep typed prompt-cache options,
the caller field of function and custom tool calls (whether the model issued the call directly
or a program item issued it), and opaque program / program_output items through validation
and continuation. Chat Completions and Anthropic conversion accept direct callers but reject
program callers and program items because the link between a tool call and its program has no
representation in those formats; drop_unrepresentable_request_fields does not drop that link.
Both conversions reject non-null allowed_callers tool eligibility, including an empty list,
and function output_schema definitions that they cannot preserve. These items do not acquire
training metadata. Strict ATIF export rejects program items and non-null caller fields that
ATIF cannot represent.
Unreported cache-write usage stays unknown internally; explicit zero and reported counts remain
intact through usage aggregation. Synthesized Responses SSE omits an unknown cache_write_tokens
instead of emitting null or inventing zero. This wire adaptation does not mutate captured usage
or change provider-reported token totals.
For training workloads that require token IDs and log probabilities, use vLLM instead. Hosted endpoints do not expose the token-level information needed for RL training.
Supported APIs
This server exposes both endpoints and forwards each directly to the upstream endpoint:
- OpenAI Responses —
/v1/responses - OpenAI Chat Completions —
/v1/chat/completions
Provider reasoning content
Responses-compatible providers sometimes use output_text for a reasoning
item’s content. Before validating provider responses, this server changes that
part’s discriminator to reasoning_text only when it contains a string text
and no other fields except optional empty annotations: []. Text, encrypted
content, item order and other response fields are preserved without modifying
the provider’s response object. Unknown or malformed shapes still go through
validation unchanged. Requests and continuation replay are unchanged.
Set Your Credentials
Store your values in env.yaml in the project root (gitignored):
Point policy_base_url at any OpenAI-compatible Responses endpoint to reuse this server with a different host.
For NVCF endpoints, requests that take longer than 340 seconds to produce a first byte need the HTTP/2 PING sidecar.
Configuration Reference
The model is fixed by configuration. This server always sends the configured openai_model (from policy_model_name) to the upstream endpoint. If an incoming request carries its own model field — as standard OpenAI-compatible clients and SDKs do — that value is overwritten, so you cannot switch models on a per-request basis. To run a different model, change the config and start a new server.
Keep a Session on One Replica
A router that pins a session to one model replica reuses that replica’s KV cache only if every request of a session carries the same session key. Set session_key_headers to the header names your router reads, and turn on rollout correlation:
rollout_correlationis a global option and defaults tofalse. It makes agents that use Gym’s agent helpers add the/ng-rollout/<id>prefix to their model calls, so the model server knows which rollout a call belongs to, without turning on model-call capture.observability_enabledand opted-in token capture add the prefix too.session_key_headersdefaults to[], so nothing changes unless you set it.- A request that carries no rollout identity gets no generated header. Static headers from
openai_default_headersstill apply to every request, inside or outside a rollout. - A session is a rollout attempt. The header carries the session key, which is the rollout’s capture key:
<rollout id>, or<rollout id>-a<N>for a retry. Agents that make model calls inside the same attempt, such as a policy and a user simulator, or a judge that calls through this model server, share one session and therefore one replica.