praval.models

Provider-neutral model contracts for Praval.

These types describe model input, output, tools, events, and capabilities without binding the rest of Praval to one provider’s wire format.

Classes

AudioResponse(**data)

Provider-neutral transcription or synthesized-audio response.

ContentPart(**data)

A single multimodal content part.

EmbeddingRequest(**data)

Provider-neutral embedding request.

EmbeddingResponse(**data)

Provider-neutral embedding response.

ModelEvent(**data)

A streaming model event.

ModelMessage(**data)

A provider-neutral conversation message.

ModelRequest(**data)

Provider-neutral model request.

ModelResponse(**data)

Provider-neutral model response.

ProviderAdapter(*args, **kwargs)

Protocol implemented by provider-neutral adapters.

ProviderCapabilities(**data)

Capabilities exposed by a provider or a provider/model pair.

ProviderProfile(**data)

A registered provider/model profile.

ReasoningConfig(**data)

Reasoning controls for providers that support them.

SpeechRequest(**data)

Provider-neutral request to synthesize speech from text.

StructuredOutputConfig(**data)

Structured output request configuration.

ToolCall(**data)

A model-requested tool invocation.

ToolResult(**data)

A result returned from a tool invocation.

ToolSpec(**data)

Provider-neutral tool declaration.

TranscriptionRequest(**data)

Provider-neutral request to transcribe an audio file or byte payload.

Usage(**data)

Provider-neutral token usage.

class praval.models.AudioResponse(**data)[source]

Bases: BaseModel

Provider-neutral transcription or synthesized-audio response.

Parameters:
  • text (str | None)

  • data (bytes | None)

  • provider (str | None)

  • model (str | None)

  • format (str | None)

  • mime_type (str | None)

  • raw (Any)

  • metadata (Dict[str, Any])

model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

text: str | None
data: bytes | None
provider: str | None
model: str | None
format: str | None
mime_type: str | None
raw: Any
metadata: Dict[str, Any]
class praval.models.ContentPart(**data)[source]

Bases: BaseModel

A single multimodal content part.

Parameters:
  • type (str)

  • text (str | None)

  • data (str | None)

  • url (str | None)

  • mime_type (str | None)

  • metadata (Dict[str, Any])

  • extra_data (Any)

model_config: ClassVar[ConfigDict] = {'extra': 'allow'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

type: str
text: str | None
data: str | None
url: str | None
mime_type: str | None
metadata: Dict[str, Any]
classmethod text_part(text)[source]

Create a text content part.

Return type:

ContentPart

Parameters:

text (str)

classmethod image_url(url, mime_type=None)[source]

Create an image URL content part.

Return type:

ContentPart

Parameters:
  • url (str)

  • mime_type (str | None)

classmethod image_base64(data, mime_type='image/png')[source]

Create an inline base64 image content part.

Return type:

ContentPart

Parameters:
  • data (str)

  • mime_type (str)

classmethod audio_url(url, mime_type=None)[source]

Create an audio URL content part.

Return type:

ContentPart

Parameters:
  • url (str)

  • mime_type (str | None)

classmethod audio_base64(data, mime_type='audio/wav')[source]

Create an inline base64 audio content part.

Return type:

ContentPart

Parameters:
  • data (str)

  • mime_type (str)

classmethod video_url(url, mime_type=None)[source]

Create a video URL content part.

Return type:

ContentPart

Parameters:
  • url (str)

  • mime_type (str | None)

classmethod video_base64(data, mime_type='video/mp4')[source]

Create an inline base64 video content part.

Return type:

ContentPart

Parameters:
  • data (str)

  • mime_type (str)

classmethod file_url(url, mime_type='application/octet-stream', *, name=None)[source]

Create a remote file content part.

Return type:

ContentPart

Parameters:
  • url (str)

  • mime_type (str)

  • name (str | None)

classmethod file_data(data, mime_type, *, name=None)[source]

Create an inline file content part.

Return type:

ContentPart

Parameters:
  • data (str)

  • mime_type (str)

  • name (str | None)

class praval.models.EmbeddingRequest(**data)[source]

Bases: BaseModel

Provider-neutral embedding request.

Parameters:
  • inputs (List[Any])

  • provider (str | None)

  • model (str | None)

  • dimensions (int | None)

  • provider_options (Dict[str, Any])

  • metadata (Dict[str, Any])

model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

inputs: List[Any]
provider: str | None
model: str | None
dimensions: int | None
provider_options: Dict[str, Any]
metadata: Dict[str, Any]
class praval.models.EmbeddingResponse(**data)[source]

Bases: BaseModel

Provider-neutral embedding response.

Parameters:
  • embeddings (List[List[float]])

  • provider (str | None)

  • model (str | None)

  • dimensions (int | None)

  • raw (Any)

  • metadata (Dict[str, Any])

model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

embeddings: List[List[float]]
provider: str | None
model: str | None
dimensions: int | None
raw: Any
metadata: Dict[str, Any]
class praval.models.ModelEvent(**data)[source]

Bases: BaseModel

A streaming model event.

Parameters:
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

type: str
delta: str
response: ModelResponse | None
tool_call: ToolCall | None
tool_result: ToolResult | None
usage: Usage | None
metadata: Dict[str, Any]
class praval.models.ModelMessage(**data)[source]

Bases: BaseModel

A provider-neutral conversation message.

Parameters:
  • role (str)

  • content (Any)

  • name (str | None)

  • tool_call_id (str | None)

  • metadata (Dict[str, Any])

  • extra_data (Any)

model_config: ClassVar[ConfigDict] = {'extra': 'allow'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

role: str
content: Any
name: str | None
tool_call_id: str | None
metadata: Dict[str, Any]
class praval.models.ModelRequest(**data)[source]

Bases: BaseModel

Provider-neutral model request.

Parameters:
  • messages (List[ModelMessage])

  • provider (str | None)

  • model (str | None)

  • tools (List[ToolSpec])

  • temperature (float | None)

  • max_output_tokens (int | None)

  • stream (bool)

  • response_schema (StructuredOutputConfig | None)

  • reasoning (ReasoningConfig | None)

  • provider_options (Dict[str, Any])

  • stream_options (Dict[str, Any])

  • timeout (float | None)

  • metadata (Dict[str, Any])

  • hitl_context (Dict[str, Any] | None)

model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

messages: List[ModelMessage]
provider: str | None
model: str | None
tools: List[ToolSpec]
temperature: float | None
max_output_tokens: int | None
stream: bool
response_schema: StructuredOutputConfig | None
reasoning: ReasoningConfig | None
provider_options: Dict[str, Any]
stream_options: Dict[str, Any]
timeout: float | None
metadata: Dict[str, Any]
hitl_context: Dict[str, Any] | None
class praval.models.ModelResponse(**data)[source]

Bases: BaseModel

Provider-neutral model response.

Parameters:
  • content (str)

  • provider (str | None)

  • model (str | None)

  • messages (List[ModelMessage])

  • tool_calls (List[ToolCall])

  • usage (Usage | None)

  • finish_reason (str | None)

  • raw (Any)

  • metadata (Dict[str, Any])

model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

content: str
provider: str | None
model: str | None
messages: List[ModelMessage]
tool_calls: List[ToolCall]
usage: Usage | None
finish_reason: str | None
raw: Any
metadata: Dict[str, Any]
property text: str

Return response content as text.

class praval.models.ProviderAdapter(*args, **kwargs)[source]

Bases: Protocol

Protocol implemented by provider-neutral adapters.

provider_name: str
capabilities: ProviderCapabilities
invoke(request)[source]

Execute a non-streaming model request.

Return type:

ModelResponse

Parameters:

request (ModelRequest)

stream(request)[source]

Execute a streaming model request.

Return type:

Iterator[ModelEvent]

Parameters:

request (ModelRequest)

async ainvoke(request)[source]

Execute a non-streaming request asynchronously.

Return type:

ModelResponse

Parameters:

request (ModelRequest)

astream(request)[source]

Execute a streaming model request asynchronously.

Return type:

AsyncIterator[ModelEvent]

Parameters:

request (ModelRequest)

close()[source]

Release provider resources.

Return type:

None

__init__(*args, **kwargs)
class praval.models.ProviderCapabilities(**data)[source]

Bases: BaseModel

Capabilities exposed by a provider or a provider/model pair.

Parameters:
  • text (bool)

  • chat_completions (bool)

  • responses_api (bool)

  • tools (bool)

  • streaming (bool)

  • native_streaming (bool)

  • tool_streaming (bool)

  • structured_outputs (bool)

  • json_schema_mode (str | None)

  • multimodal (bool)

  • image_input (bool)

  • file_input (bool)

  • audio_input (bool)

  • video_input (bool)

  • audio_transcription (bool)

  • speech_generation (bool)

  • reasoning (bool)

  • reasoning_effort (bool)

  • reasoning_budget (bool)

  • embeddings (bool)

  • local (bool)

  • server_tools (bool)

  • mcp (bool)

  • computer_use (bool)

text: bool
chat_completions: bool
responses_api: bool
tools: bool
streaming: bool
native_streaming: bool
tool_streaming: bool
structured_outputs: bool
json_schema_mode: str | None
multimodal: bool
image_input: bool
file_input: bool
audio_input: bool
video_input: bool
audio_transcription: bool
speech_generation: bool
reasoning: bool
reasoning_effort: bool
reasoning_budget: bool
embeddings: bool
local: bool
server_tools: bool
mcp: bool
computer_use: bool
supports(capability)[source]

Return whether a named capability is enabled.

Return type:

bool

Parameters:

capability (str)

model_config: ClassVar[ConfigDict] = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class praval.models.ProviderProfile(**data)[source]

Bases: BaseModel

A registered provider/model profile.

Parameters:
  • provider (str)

  • model (str)

  • display_name (str | None)

  • capabilities (ProviderCapabilities)

  • default (bool)

  • endpoint (str | None)

  • local_preset (str | None)

  • context_window (int | None)

  • max_output_tokens (int | None)

  • default_parameters (Dict[str, Any])

  • unsupported_combinations (List[Dict[str, Any]])

  • downgrade_policy (str)

  • notes (str)

provider: str
model: str
display_name: str | None
capabilities: ProviderCapabilities
default: bool
endpoint: str | None
local_preset: str | None
context_window: int | None
max_output_tokens: int | None
default_parameters: Dict[str, Any]
unsupported_combinations: List[Dict[str, Any]]
downgrade_policy: str
notes: str
model_config: ClassVar[ConfigDict] = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class praval.models.ReasoningConfig(**data)[source]

Bases: BaseModel

Reasoning controls for providers that support them.

Parameters:
  • effort (str | None)

  • summary (str | None)

  • encrypted (bool)

  • budget_tokens (int | None)

  • mode (str | None)

  • display (str | None)

effort: str | None
summary: str | None
encrypted: bool
budget_tokens: int | None
mode: str | None
display: str | None
model_config: ClassVar[ConfigDict] = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class praval.models.SpeechRequest(**data)[source]

Bases: BaseModel

Provider-neutral request to synthesize speech from text.

Parameters:
  • input (str)

  • provider (str | None)

  • model (str | None)

  • voice (str)

  • response_format (str)

  • speed (float)

  • instructions (str | None)

  • provider_options (Dict[str, Any])

  • timeout (float | None)

  • metadata (Dict[str, Any])

model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

input: str
provider: str | None
model: str | None
voice: str
response_format: str
speed: float
instructions: str | None
provider_options: Dict[str, Any]
timeout: float | None
metadata: Dict[str, Any]
class praval.models.StructuredOutputConfig(**data)[source]

Bases: BaseModel

Structured output request configuration.

Parameters:
  • schema (Dict[str, Any] | None)

  • name (str | None)

  • strict (bool)

model_config: ClassVar[ConfigDict] = {'populate_by_name': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

json_schema: Dict[str, Any] | None
name: str | None
strict: bool
class praval.models.ToolCall(**data)[source]

Bases: BaseModel

A model-requested tool invocation.

Parameters:
  • id (str)

  • name (str)

  • arguments (Dict[str, Any])

  • raw (Any)

  • extra_data (Any)

model_config: ClassVar[ConfigDict] = {'extra': 'allow'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

id: str
name: str
arguments: Dict[str, Any]
raw: Any
class praval.models.ToolResult(**data)[source]

Bases: BaseModel

A result returned from a tool invocation.

Parameters:
  • tool_call_id (str)

  • name (str)

  • content (str)

  • is_error (bool)

  • metadata (Dict[str, Any])

  • extra_data (Any)

model_config: ClassVar[ConfigDict] = {'extra': 'allow'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

tool_call_id: str
name: str
content: str
is_error: bool
metadata: Dict[str, Any]
class praval.models.ToolSpec(**data)[source]

Bases: BaseModel

Provider-neutral tool declaration.

Parameters:
  • name (str)

  • description (str)

  • parameters (Dict[str, Any])

  • strict (bool)

  • requires_approval (bool)

  • risk_level (str)

  • approval_reason (str)

  • metadata (Dict[str, Any])

  • extra_data (Any)

model_config: ClassVar[ConfigDict] = {'extra': 'allow'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

name: str
description: str
parameters: Dict[str, Any]
strict: bool
requires_approval: bool
risk_level: str
approval_reason: str
metadata: Dict[str, Any]
class praval.models.TranscriptionRequest(**data)[source]

Bases: BaseModel

Provider-neutral request to transcribe an audio file or byte payload.

Parameters:
  • audio (Any)

  • provider (str | None)

  • model (str | None)

  • filename (str | None)

  • mime_type (str | None)

  • language (str | None)

  • prompt (str | None)

  • response_format (str)

  • temperature (float | None)

  • provider_options (Dict[str, Any])

  • timeout (float | None)

  • metadata (Dict[str, Any])

model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

audio: Any
provider: str | None
model: str | None
filename: str | None
mime_type: str | None
language: str | None
prompt: str | None
response_format: str
temperature: float | None
provider_options: Dict[str, Any]
timeout: float | None
metadata: Dict[str, Any]
class praval.models.Usage(**data)[source]

Bases: BaseModel

Provider-neutral token usage.

Parameters:
  • input_tokens (int)

  • output_tokens (int)

  • total_tokens (int)

  • reasoning_tokens (int)

input_tokens: int
output_tokens: int
total_tokens: int
reasoning_tokens: int
model_config: ClassVar[ConfigDict] = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].