nemo_gym.anthropic_utils

View as Markdown

NeMo Gym Pydantic types for the Anthropic Messages API boundary.

This mirrors the wrapping strategy in nemo_gym/openai_utils.py, but deliberately stays small. Anthropic is only a wire format at the proxy boundary — the internal canonical representation is the Responses API (the NeMoGym* types in openai_utils). So unlike openai_utils, this module does not replicate the *ForTraining hierarchies or an async client (the anthropic SDK is never used as a client — it uses httpx, whose O(n^2) connection pooling hangs at high concurrency). Types only.

Two boundary types, one per direction:

  • :class:NeMoGymAnthropicMessageCreateParamsNonStreaming — the request validator. The SDK’s MessageCreateParams is a TypedDict with no runtime validation, so we copy it as a BaseModel for strict server-side validation at the ingress proxy endpoint, exactly as NeMoGymResponseCreateParamsNonStreaming does for the Responses API.
  • :class:NeMoGymAnthropicMessage — the response validator. A thin subclass of the SDK’s Message (already a BaseModel), used to validate what we emit, mirroring NeMoGymResponse(Response).

Module Contents

Classes

NameDescription
NeMoGymAnthropicMessageThin subclass of the SDK’s Message response model, used to validate what we emit.
NeMoGymAnthropicMessageCreateParamsNonStreamingCopy of anthropic.types.message_create_params.MessageCreateParamsBase as a BaseModel.

API

class nemo_gym.anthropic_utils.NeMoGymAnthropicMessage()

Bases: AnthropicMessage

Thin subclass of the SDK’s Message response model, used to validate what we emit.

Message.content is already typed as List[...] in the pinned anthropic version, so no iterable override is needed here; the subclass exists for symmetry with NeMoGymResponse and to give the egress/ingress response path a single NeMoGym* validation point.

class nemo_gym.anthropic_utils.NeMoGymAnthropicMessageCreateParamsNonStreaming()

Bases: BaseModel

Copy of anthropic.types.message_create_params.MessageCreateParamsBase as a BaseModel.

The SDK ships this as a TypedDict (no runtime validation). We need server-side validation at the ingress proxy, so we re-declare it here, mirroring NeMoGymResponseCreateParamsNonStreaming.

The Iterable fields (messages, tools, and the list arm of system) are overridden to List so Pydantic eagerly validates them into real, re-iterable, indexable, JSON-serializable lists rather than single-use lazy ValidatorIterators.

Note on extra="forbid": this matches the strict Responses-API policy and rejects unknown fields. Anthropic occasionally introduces beta body fields ahead of an SDK bump; if the ingress client (e.g. the Claude Code CLI) sends one, relax this to ignore.

cache_control
Optional[CacheControlEphemeralParam] = None
container
Optional[str] = None
inference_geo
Optional[str] = None
max_tokens
int
messages
List[MessageParam]
metadata
Optional[MetadataParam] = None
model
ModelParam
model_config
= ConfigDict(extra='forbid')
output_config
Optional[OutputConfigParam] = None
service_tier
Optional[Literal['auto', 'standard_only']] = None
stop_sequences
Optional[List[str]] = None
stream
Optional[Literal[False]] = None
system
Optional[Union[str, List[TextBlockParam]]] = None
temperature
Optional[float] = None
thinking
Optional[ThinkingConfigParam] = None
tool_choice
Optional[ToolChoiceParam] = None
tools
Optional[List[ToolUnionParam]] = Field(default=None)
top_k
Optional[int] = None
top_p
Optional[float] = None