---
title: enhancer
---

<div class="python-reference">
<a id="fastvideo.entrypoints.streaming.prompt.enhancer-classes"></a>
<a id="fastvideo.entrypoints.streaming.prompt.enhancer-functions"></a>
<a id="fastvideo.entrypoints.streaming.prompt.enhancer.PromptEnhancer-functions"></a>
<a id="fastvideo.entrypoints.streaming.prompt.enhancer"></a>
<p>Provider-agnostic prompt orchestration for the streaming server.</p>
<p>Three operations the streaming server needs:</p>
<ul>
<li><code>enhance</code> — polish a user prompt (add cinematic detail, fix syntax)</li>
<li><code>auto_extend</code> — generate a follow-on prompt for loop generation</li>
<li><code>rewrite</code> — rewrite a seed prompt for a user-directed rewrite flow</li>
</ul>
<p>All three share the same orchestration: pick a provider in priority
order, submit an <code>LLMRequest</code>, fall back to the next provider on
retryable errors, and surface a structured :class:<code>LLMResponse</code> back
to the caller.</p>
<p>System prompts are loaded from <code>system_prompt_dir</code> on construction
and can be hot-reloaded via :meth:<code>PromptEnhancer.reload_system_prompts</code>.
The streaming server's management endpoint calls that method in
response to a <code>rewrite_seed_prompts_started</code> frame.</p>
<h2 id="fastvideo.entrypoints.streaming.prompt.enhancer.LLMMessage"><code>fastvideo.entrypoints.streaming.prompt.enhancer.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>


<h2 id="fastvideo.entrypoints.streaming.prompt.enhancer.LLMProvider"><code>fastvideo.entrypoints.streaming.prompt.enhancer.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>
<h3 id="fastvideo.entrypoints.streaming.prompt.enhancer.LLMProvider.complete"><code>fastvideo.entrypoints.streaming.prompt.enhancer.LLMProvider.complete</code></h3>
<pre class="doc-signature"><code>complete(request: LLMRequest) -&gt; LLMResponse</code></pre>

<h2 id="fastvideo.entrypoints.streaming.prompt.enhancer.LLMProviderError"><code>fastvideo.entrypoints.streaming.prompt.enhancer.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>

<h2 id="fastvideo.entrypoints.streaming.prompt.enhancer.LLMRequest"><code>fastvideo.entrypoints.streaming.prompt.enhancer.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>


<h2 id="fastvideo.entrypoints.streaming.prompt.enhancer.LLMResponse"><code>fastvideo.entrypoints.streaming.prompt.enhancer.LLMResponse</code></h2>
<pre class="doc-signature"><code>LLMResponse(content: str, provider: str, model: str, latency_ms: float, fallback_used: bool = False)</code></pre>


<h2 id="fastvideo.entrypoints.streaming.prompt.enhancer.init_logger"><code>fastvideo.entrypoints.streaming.prompt.enhancer.init_logger</code></h2>
<pre class="doc-signature"><code>init_logger(name: str) -&gt; _FastvideoLogger</code></pre>
<p>The main purpose of this function is to ensure that loggers are
retrieved in such a way that we can be sure the root fastvideo logger has
already been configured.</p>
<h2 id="fastvideo.entrypoints.streaming.prompt.enhancer.PromptOperation"><code>fastvideo.entrypoints.streaming.prompt.enhancer.PromptOperation</code></h2>
<pre class="doc-signature"><code>PromptOperation()</code></pre>

<details><summary>Source</summary><pre><code>class PromptOperation(enum.Enum):
    ENHANCE = &quot;enhance&quot;
    AUTO_EXTEND = &quot;auto_extend&quot;
    REWRITE = &quot;rewrite&quot;</code></pre></details>
<h2 id="fastvideo.entrypoints.streaming.prompt.enhancer.PromptEnhancer"><code>fastvideo.entrypoints.streaming.prompt.enhancer.PromptEnhancer</code></h2>
<pre class="doc-signature"><code>PromptEnhancer(*, providers: Sequence&#91;LLMProvider&#93;, model: str, timeout_ms: int = 20000, temperature: float = 0.7, max_tokens: int | None = 256, system_prompt_dir: str | None = None)</code></pre>
<p>Orchestrates prompt operations across a priority-ordered provider
list with structured fallback + hot-reloadable system prompts.</p>
<p>Usage::</p>
<pre><code>enhancer = PromptEnhancer(
    providers=[CerebrasProvider(), GroqProvider()],
    model="gpt-oss-120b",
    system_prompt_dir="/etc/fastvideo/prompts",
)
response = await enhancer.enhance("a fox running through snow")
</code></pre>

<details><summary>Source</summary><pre><code>class PromptEnhancer:
    &quot;&quot;&quot;Orchestrates prompt operations across a priority-ordered provider
    list with structured fallback + hot-reloadable system prompts.

    Usage::

        enhancer = PromptEnhancer(
            providers=&#91;CerebrasProvider(), GroqProvider()&#93;,
            model=&quot;gpt-oss-120b&quot;,
            system_prompt_dir=&quot;/etc/fastvideo/prompts&quot;,
        )
        response = await enhancer.enhance(&quot;a fox running through snow&quot;)
    &quot;&quot;&quot;

    def __init__(
        self,
        *,
        providers: Sequence&#91;LLMProvider&#93;,
        model: str,
        timeout_ms: int = 20000,
        temperature: float = 0.7,
        max_tokens: int | None = 256,
        system_prompt_dir: str | None = None,
    ) -&gt; None:
        if not providers:
            raise ValueError(&quot;PromptEnhancer requires at least one LLMProvider&quot;)
        self._providers = list(providers)
        self._model = model
        self._timeout_ms = timeout_ms
        self._temperature = temperature
        self._max_tokens = max_tokens
        self._system_prompt_dir = system_prompt_dir
        self._system_prompts = self._load_system_prompts()

    @property
    def providers(self) -&gt; list&#91;LLMProvider&#93;:
        return list(self._providers)

    def register_provider(self, provider: LLMProvider, *, priority: int = -1) -&gt; None:
        &quot;&quot;&quot;Insert an additional provider. ``priority=0`` makes it primary;
        ``priority=-1`` (default) appends as a fallback.&quot;&quot;&quot;
        if priority &lt; 0:
            self._providers.append(provider)
        else:
            self._providers.insert(priority, provider)

    def reload_system_prompts(self) -&gt; None:
        &quot;&quot;&quot;Re-read the system prompt files from ``system_prompt_dir``.

        The streaming server exposes this via a management endpoint so
        operators can iterate on prompt templates without restarting
        workers.
        &quot;&quot;&quot;
        self._system_prompts = self._load_system_prompts()
        logger.info(&quot;prompt enhancer: reloaded system prompts from %s&quot;, self._system_prompt_dir or &quot;defaults&quot;)

    async def enhance(self, prompt: str) -&gt; LLMResponse:
        return await self._run(
            PromptOperation.ENHANCE,
            system=self._system_prompts.enhance,
            user=prompt,
        )

    async def auto_extend(self, prior_prompts: Sequence&#91;str&#93;) -&gt; LLMResponse:
        user = &quot;\n&quot;.join(prior_prompts)
        return await self._run(
            PromptOperation.AUTO_EXTEND,
            system=self._system_prompts.auto_extend,
            user=user,
        )

    async def rewrite(self, seed_prompt: str) -&gt; LLMResponse:
        return await self._run(
            PromptOperation.REWRITE,
            system=self._system_prompts.rewrite,
            user=seed_prompt,
        )

    async def _run(
        self,
        operation: PromptOperation,
        *,
        system: str,
        user: str,
    ) -&gt; LLMResponse:
        request = LLMRequest(
            messages=&#91;
                LLMMessage(role=&quot;system&quot;, content=system),
                LLMMessage(role=&quot;user&quot;, content=user),
            &#93;,
            model=self._model,
            max_tokens=self._max_tokens,
            temperature=self._temperature,
            timeout_ms=self._timeout_ms,
        )
        last_error: LLMProviderError | None = None
        for idx, provider in enumerate(self._providers):
            try:
                response = await provider.complete(request)
                if idx &gt; 0:
                    # Mark the fallback flag without losing any other
                    # response fields the provider populated.
                    response = replace(response, fallback_used=True)
                return response
            except LLMProviderError as exc:
                logger.warning(&quot;prompt %s: provider %s failed: %s; trying next&quot;, operation.value, provider.name, exc)
                last_error = exc
                if not exc.retryable:
                    break
        assert last_error is not None
        raise last_error

    def _load_system_prompts(self) -&gt; _SystemPrompts:
        if not self._system_prompt_dir:
            return _DEFAULT_SYSTEM_PROMPTS
        return _SystemPrompts(
            enhance=_read_prompt(self._system_prompt_dir, &quot;enhance.txt&quot;, _DEFAULT_SYSTEM_PROMPTS.enhance),
            auto_extend=_read_prompt(self._system_prompt_dir, &quot;auto_extend.txt&quot;, _DEFAULT_SYSTEM_PROMPTS.auto_extend),
            rewrite=_read_prompt(self._system_prompt_dir, &quot;rewrite.txt&quot;, _DEFAULT_SYSTEM_PROMPTS.rewrite),
        )</code></pre></details>
<h3 id="fastvideo.entrypoints.streaming.prompt.enhancer.PromptEnhancer.register_provider"><code>fastvideo.entrypoints.streaming.prompt.enhancer.PromptEnhancer.register_provider</code></h3>
<pre class="doc-signature"><code>register_provider(provider: LLMProvider, *, priority: int = -1) -&gt; None</code></pre>
<p>Insert an additional provider. <code>priority=0</code> makes it primary;
<code>priority=-1</code> (default) appends as a fallback.</p>
<details><summary>Source</summary><pre><code>def register_provider(self, provider: LLMProvider, *, priority: int = -1) -&gt; None:
    &quot;&quot;&quot;Insert an additional provider. ``priority=0`` makes it primary;
    ``priority=-1`` (default) appends as a fallback.&quot;&quot;&quot;
    if priority &lt; 0:
        self._providers.append(provider)
    else:
        self._providers.insert(priority, provider)</code></pre></details>
<h3 id="fastvideo.entrypoints.streaming.prompt.enhancer.PromptEnhancer.reload_system_prompts"><code>fastvideo.entrypoints.streaming.prompt.enhancer.PromptEnhancer.reload_system_prompts</code></h3>
<pre class="doc-signature"><code>reload_system_prompts() -&gt; None</code></pre>
<p>Re-read the system prompt files from <code>system_prompt_dir</code>.</p>
<p>The streaming server exposes this via a management endpoint so
operators can iterate on prompt templates without restarting
workers.</p>
<details><summary>Source</summary><pre><code>def reload_system_prompts(self) -&gt; None:
    &quot;&quot;&quot;Re-read the system prompt files from ``system_prompt_dir``.

    The streaming server exposes this via a management endpoint so
    operators can iterate on prompt templates without restarting
    workers.
    &quot;&quot;&quot;
    self._system_prompts = self._load_system_prompts()
    logger.info(&quot;prompt enhancer: reloaded system prompts from %s&quot;, self._system_prompt_dir or &quot;defaults&quot;)</code></pre></details>
<h3 id="fastvideo.entrypoints.streaming.prompt.enhancer.PromptEnhancer.enhance"><code>fastvideo.entrypoints.streaming.prompt.enhancer.PromptEnhancer.enhance</code></h3>
<pre class="doc-signature"><code>enhance(prompt: str) -&gt; LLMResponse</code></pre>

<details><summary>Source</summary><pre><code>async def enhance(self, prompt: str) -&gt; LLMResponse:
    return await self._run(
        PromptOperation.ENHANCE,
        system=self._system_prompts.enhance,
        user=prompt,
    )</code></pre></details>
<h3 id="fastvideo.entrypoints.streaming.prompt.enhancer.PromptEnhancer.auto_extend"><code>fastvideo.entrypoints.streaming.prompt.enhancer.PromptEnhancer.auto_extend</code></h3>
<pre class="doc-signature"><code>auto_extend(prior_prompts: Sequence&#91;str&#93;) -&gt; LLMResponse</code></pre>

<details><summary>Source</summary><pre><code>async def auto_extend(self, prior_prompts: Sequence&#91;str&#93;) -&gt; LLMResponse:
    user = &quot;\n&quot;.join(prior_prompts)
    return await self._run(
        PromptOperation.AUTO_EXTEND,
        system=self._system_prompts.auto_extend,
        user=user,
    )</code></pre></details>
<h3 id="fastvideo.entrypoints.streaming.prompt.enhancer.PromptEnhancer.rewrite"><code>fastvideo.entrypoints.streaming.prompt.enhancer.PromptEnhancer.rewrite</code></h3>
<pre class="doc-signature"><code>rewrite(seed_prompt: str) -&gt; LLMResponse</code></pre>

<details><summary>Source</summary><pre><code>async def rewrite(self, seed_prompt: str) -&gt; LLMResponse:
    return await self._run(
        PromptOperation.REWRITE,
        system=self._system_prompts.rewrite,
        user=seed_prompt,
    )</code></pre></details>
</div>
