File size: 1,348 Bytes
5f43c7d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
"""Narrator backend selector — ONE seam, two implementations.

`get_narrator()` returns a client implementing the same prose-only interface the
rest of the app already depends on (`.chat`, `.chat_with_tools`, `.wait_until_ready`,
`.model_id`). It chooses the backend from the `HER_BACKEND` env var:

  * `llama` (default) — the local llama.cpp `llama-server` client (unchanged local
    app; trace content never leaves the machine).
  * `hf`            — an in-process transformers model running on a Hugging Face
    ZeroGPU GPU via `@spaces.GPU` (the Space deployment).

This is the ONLY place that knows which backend is live, so server/app.py stays
backend-agnostic and the local product is untouched. Still prose-only at the seam:
neither backend reads JSONL or computes a number.
"""
from __future__ import annotations

import os


def get_narrator():
    """Return the active narrator client for this process (see module docstring)."""
    backend = os.environ.get("HER_BACKEND", "llama").lower()
    if backend == "hf":
        # The HF backend loads its model at MODULE import (ZeroGPU requirement), so
        # return the already-loaded singleton rather than constructing per call.
        from narrator.hf_narrator import NARRATOR
        return NARRATOR
    from narrator.client import NarratorClient
    return NarratorClient()