# ADR: Model Runtime Hardening ## Status Accepted for the model runtime rearchitecture branch. ## Context Provider APIs have diverged across chat completions, responses APIs, reasoning, structured output, multimodal input, native streaming, local OpenAI-compatible servers, and tool-calling protocols. A provider-level boolean is no longer enough to tell users what will work. ## Decision Praval uses a provider-neutral `ModelRuntime` and public contracts in `praval.models`. Runtime responsibilities: - Resolve capabilities from provider, model, endpoint, local preset, and explicit overrides. - Validate requests before provider execution. - Normalize streaming events. - Own tool execution policy, HITL pause/resume state, retries, usage accounting, and observability spans. - Preserve legacy string-returning APIs. Provider responsibilities: - Translate neutral requests into provider wire payloads. - Translate provider responses and stream chunks into neutral runtime objects. - Redact secrets in provider errors. ## Capability Resolution Profiles include provider, model, endpoint, local preset, default parameters, context window, output token limits, unsupported combinations, and downgrade policy. The default downgrade policy is `error`. ## Streaming Semantics The runtime emits `start`, then adapter events, then `final`. Providers with `native_streaming=True` must implement a native stream path or validation fails. Fake streaming is reserved for explicit emulated profiles. ## Multimodal Normalization `ContentPart` values are validated before provider execution. Providers only serialize supported text, image, file, and audio shapes into their wire format. Unsupported content types fail deterministically. ## Local Provider Policy OpenAI-compatible local servers are conservative by default. Text and native streaming are enabled. Tools, structured output, reasoning, and multimodal input require explicit opt-in profiles or per-call capability overrides. ## Async Execution Adapters may implement native `ainvoke()` and `astream()`. The runtime falls back to a thread executor for legacy sync providers. ## Agent Communication and Realtime Scope Reef remains Praval's native agent-to-agent communication system. The model runtime operates inside an agent and does not replace Reef or introduce a second A2A abstraction. In Praval, a realtime model session would be a persistent provider connection with a continuous stream of input and output events, potentially including bidirectional audio over WebRTC or WebSocket. That lifecycle differs from a normal request, a streamed text response, or a Reef message. Realtime model sessions are not part of 0.8. Request-based `Agent.transcribe()` and `Agent.speak()` remain supported. They perform bounded transcription and speech-generation requests and do not keep a persistent audio session open. ## Consequences Users get predictable failures instead of silent downgrades. Provider adapters stay smaller, and tests can run the same contract suite across real SDKs, fake SDKs, and local-compatible HTTP servers.