Skip to documentation
Documentation navigation

Documentation navigation

Documentation / guides

Response codecs

Normalize native response envelopes into Response and Usage values.

developer

Response decoders parse an already-drained successful body and return a provider-neutral *inference.Response. The transport owns HTTP status and body limits, so a decoder sees only the bytes for a successful response.

Normalization

Every bundled decoder preserves ordered text, thinking, tool-use, and tool result blocks where the dialect has a representation. The two OpenAI dialects additionally decode a refusal into a content.RefusalBlock rather than into text, including when the refusal carries no explanation. Provider token fields are normalized into usage.Usage, which is an alias for content.Usage:

Neutral fieldMeaning
InputTokensuncached input tokens after subtracting cache-read and cache-creation subsets when the provider reports gross input
OutputTokensgenerated tokens, including dialect-specific reasoning, which the neutral contract treats as a subset of output
CacheReadTokensinput tokens served from a provider cache
CacheCreationTokensinput tokens written to a provider cache
ReasoningTokensreasoning or thought tokens when reported

Decoders validate nonnegative counts, subset relationships, and overflow. They do not gate on the reasoning-within-output convention; use content.Usage.ReasoningWithinOutput() to observe a divergence.

response, err := (openaiapi.Codec{}).DecodeResponse(body)
if err != nil {
	return err
}
if response.Usage != nil {
	contextTokens, err := response.Usage.ContextTokens()
	if err != nil {
		return err
	}
	fmt.Println(contextTokens)
}

Terminal

Finish reasons are mapped to the shared stream.FinishReason values stop, length, tool_use, and content_filter; unknown provider values become the zero FinishReasonUnknown. Empty output is valid for Anthropic and Responses, while OpenAI Chat, Gemini, and malformed Bedrock envelopes return typed/API errors when required response structure is absent.

Source and proof

Run go test ./codec/....

← back to documentation