ractogateway._validation

Shared Pydantic response-model validation helpers for all developer kits.

All three kits (OpenAI, Google, Anthropic) use identical validation and retry logic. Centralizing it here means a bug fix or improvement applies to every provider at once.

Validation strategy

  1. Attempt response_model.model_validate(response.parsed).

  2. On pydantic.ValidationError, format the field-level errors into a plain-English correction prompt that includes the bad JSON.

  3. Call adapter_run(correction_msg) to get a fresh LLM response.

  4. Repeat up to config.max_validation_retries times.

  5. If still failing, raise ResponseModelValidationError with the last error and raw response attached.

Streaming note

Streaming responses cannot be retried (the content has already been delivered token-by-token to the caller). validate_stream_final() raises ResponseModelValidationError immediately on the final chunk if validation fails.

ractogateway._validation.with_inferred_response_model(config, prompt)[source]

Return config with inferred response_model when prompt uses a model output.

If config.response_model is unset and prompt.output_format is a Pydantic model class, we infer that same model for validation/retries.

Return type:

Any

ractogateway._validation.validate_and_retry(response, config, *, adapter_run)[source]

Validate response against config.response_model, retrying on failure.

Parameters:
  • response (LLMResponse) – The initial LLMResponse from the provider API.

  • config (Any) – A ChatConfig with response_model and max_validation_retries fields.

  • adapter_run (Callable[[str], LLMResponse]) – A callable (correction_user_message: str) -> LLMResponse. The kit creates this closure to carry the original prompt, model, temperature, and extra kwargs so retries use the same provider settings.

Return type:

LLMResponse

Returns:

LLMResponse – The response with .parsed replaced by the validated Pydantic model dump on success.

Raises:

ResponseModelValidationError – When all retry attempts are exhausted and Pydantic still rejects the output.

async ractogateway._validation.async_validate_and_retry(response, config, *, adapter_arun)[source]

Async variant of validate_and_retry().

Parameters:

adapter_arun (Callable[[str], Awaitable[LLMResponse]]) – An async callable async (correction_user_message: str) -> LLMResponse.

Return type:

LLMResponse

ractogateway._validation.validate_stream_final(accumulated_text, config)[source]

Validate the final accumulated stream text against config.response_model.

Streaming cannot be retried because content is already delivered token-by-token. On failure a ResponseModelValidationError is raised so callers get a clear, actionable error instead of silently receiving invalid data.

Parameters:
  • accumulated_text (str) – The full streamed text concatenated across all chunks.

  • config (Any) – ChatConfig with response_model.

Return type:

Any

Returns:

Any – The validated Pydantic model dump (dict) on success, or the raw parsed value when response_model is None.

Raises:

ResponseModelValidationError – When response_model is set and validation fails.