---
title: base
---

<div class="python-reference">
<a id="fastvideo.entrypoints.streaming.prompt.providers.base-classes"></a>
<a id="fastvideo.entrypoints.streaming.prompt.providers.base"></a>
<p>LLM provider protocol + DTOs used by the prompt enhancer.</p>
<p>Third-party users add a new provider by implementing
:class:<code>LLMProvider</code> and registering it with a prompt enhancer
instance. The shipped providers live in sibling modules
(<code>cerebras.py</code>, <code>groq.py</code>) and each is ~100-200 LOC — the
provider layer is intentionally thin so the enhancer stays
provider-agnostic.</p>
<h2 id="fastvideo.entrypoints.streaming.prompt.providers.base.LLMMessage"><code>fastvideo.entrypoints.streaming.prompt.providers.base.LLMMessage</code></h2>
<pre class="doc-signature"><code>LLMMessage(role: Literal&#91;&#x27;system&#x27;, &#x27;user&#x27;, &#x27;assistant&#x27;&#93;, content: str)</code></pre>


<details><summary>Source</summary><pre><code>@dataclass
class LLMMessage:
    role: Literal&#91;&quot;system&quot;, &quot;user&quot;, &quot;assistant&quot;&#93;
    content: str</code></pre></details>
<h2 id="fastvideo.entrypoints.streaming.prompt.providers.base.LLMRequest"><code>fastvideo.entrypoints.streaming.prompt.providers.base.LLMRequest</code></h2>
<pre class="doc-signature"><code>LLMRequest(messages: list&#91;LLMMessage&#93;, model: str, max_tokens: int | None = None, temperature: float | None = None, timeout_ms: int | None = None)</code></pre>


<details><summary>Source</summary><pre><code>@dataclass
class LLMRequest:
    messages: list&#91;LLMMessage&#93;
    model: str
    max_tokens: int | None = None
    temperature: float | None = None
    timeout_ms: int | None = None</code></pre></details>
<h2 id="fastvideo.entrypoints.streaming.prompt.providers.base.LLMResponse"><code>fastvideo.entrypoints.streaming.prompt.providers.base.LLMResponse</code></h2>
<pre class="doc-signature"><code>LLMResponse(content: str, provider: str, model: str, latency_ms: float, fallback_used: bool = False)</code></pre>


<details><summary>Source</summary><pre><code>@dataclass
class LLMResponse:
    content: str
    provider: str
    model: str
    latency_ms: float
    fallback_used: bool = False</code></pre></details>
<h2 id="fastvideo.entrypoints.streaming.prompt.providers.base.LLMProviderError"><code>fastvideo.entrypoints.streaming.prompt.providers.base.LLMProviderError</code></h2>
<pre class="doc-signature"><code>LLMProviderError(message: str, *, retryable: bool = True)</code></pre>
<p>Raised when an LLM provider fails a request.</p>
<p><code>retryable</code> controls whether the enhancer falls back to the next
provider. It is settable per-instance so the same exception type
can describe retryable transport errors (5xx, 429) and
non-retryable client errors (4xx auth/bad-request) without forcing
a separate subclass for every status family.</p>

<details><summary>Source</summary><pre><code>class LLMProviderError(RuntimeError):
    &quot;&quot;&quot;Raised when an LLM provider fails a request.

    ``retryable`` controls whether the enhancer falls back to the next
    provider. It is settable per-instance so the same exception type
    can describe retryable transport errors (5xx, 429) and
    non-retryable client errors (4xx auth/bad-request) without forcing
    a separate subclass for every status family.
    &quot;&quot;&quot;

    def __init__(self, message: str, *, retryable: bool = True) -&gt; None:
        super().__init__(message)
        self.retryable = retryable</code></pre></details>
<h2 id="fastvideo.entrypoints.streaming.prompt.providers.base.LLMTimeoutError"><code>fastvideo.entrypoints.streaming.prompt.providers.base.LLMTimeoutError</code></h2>
<pre class="doc-signature"><code>LLMTimeoutError(message: str)</code></pre>
<p>Raised when an LLM provider times out — always retryable.</p>

<details><summary>Source</summary><pre><code>class LLMTimeoutError(LLMProviderError):
    &quot;&quot;&quot;Raised when an LLM provider times out — always retryable.&quot;&quot;&quot;

    def __init__(self, message: str) -&gt; None:
        super().__init__(message, retryable=True)</code></pre></details>
<h2 id="fastvideo.entrypoints.streaming.prompt.providers.base.LLMProvider"><code>fastvideo.entrypoints.streaming.prompt.providers.base.LLMProvider</code></h2>
<pre class="doc-signature"><code>LLMProvider()</code></pre>
<p>Provider interface every LLM adapter implements.</p>
<p>Providers are async-first because every built-in implementation
talks to an HTTP API. Synchronous providers can wrap their call in
<code>asyncio.to_thread</code> internally.</p>
<details><summary>Source</summary><pre><code>@runtime_checkable
class LLMProvider(Protocol):
    &quot;&quot;&quot;Provider interface every LLM adapter implements.

    Providers are async-first because every built-in implementation
    talks to an HTTP API. Synchronous providers can wrap their call in
    ``asyncio.to_thread`` internally.
    &quot;&quot;&quot;

    name: str

    async def complete(self, request: LLMRequest) -&gt; LLMResponse:
        ...</code></pre></details>
<h3 id="fastvideo.entrypoints.streaming.prompt.providers.base.LLMProvider.complete"><code>fastvideo.entrypoints.streaming.prompt.providers.base.LLMProvider.complete</code></h3>
<pre class="doc-signature"><code>complete(request: LLMRequest) -&gt; LLMResponse</code></pre>

<details><summary>Source</summary><pre><code>async def complete(self, request: LLMRequest) -&gt; LLMResponse:
    ...</code></pre></details>
</div>
