# JELLAI

An AI-native TV experience layered over an **existing Emby media server**. Not a library you browse —
a channel that's already on, plus a concierge you talk to. A single tool-calling model runs the whole
loop: it drives the gateway tools (search, schedule, playback handoff) and talks to you from a
personality prompt. Always-on chat, TV-style time-block scheduling, mood awareness, and preference
learning seeded from your real watch history.

**Status:** v1 — working prototype. TV-first, single user. Built on the Emby you already have (one
server, one source of truth — your watch history is the personalization seed).

## What it feels like

You don't open JELLAI. It's already there — your media server, just with the lights turned down and
a concierge in the corner. A **TONIGHT strip** runs along the bottom, and a 💬 door waits bottom-right.
Nothing covers what you're watching.

![Home with the TONIGHT strip and concierge door](docs/screenshots/01-home-strip.png)

Tap the door and the **concierge panel** slides in from the right — video keeps playing. Tell it how
you feel, not what to search for: *"build me a chill TV night — something funny and easygoing."* It
talks back in its own voice, then **builds a real lineup** into the strip: time blocks, in order, drawn
from your actual library. Don't like it? `[yes] [swap] [keep]` — one word steers the whole night.
Click any block to start playing from there, in Emby's own player.

![Concierge panel building a lineup, strip filled with time blocks](docs/screenshots/02-concierge-lineup.png)

> The strip is the spine. Ask once, and the rest of the night schedules itself — then re-schedules
> live every time you change your mind. That's the whole product: a channel that's already on, tuned
> to you, that you can talk to.

These are real screenshots — a live themed Emby client driving the running gateway and a **local**
language model. No cloud LLM in the loop.

## How it works

```
Emby web UI  ──CSS/JS inject──▶  concierge panel ──WebSocket──▶  gateway ──▶  local LLM (Ollama)
(your server)                     (overlay theme)                (tool loop)    tool-calling
       ▲                                                            │
       └──────────────── Emby REST API (/Items, schedule, playback)─┘
```

- **Frontend (v1):** a concierge panel + schedule strip injected into the Emby web client via CSS/JS.
  It couples to almost nothing in Emby's DOM — it only appends its own fixed-position nodes — so it
  survives Emby updates. Playback always delegates to Emby's own player. The eventual target is a
  custom SPA over the Emby REST API.
- **Gateway:** a small Python WebSocket server mediating between the UI and a local model. It runs a
  tool-calling loop against one stock instruct model — no fine-tune unless a measured gap demands it.
- **Tools:** search, TV-style scheduling, and watch-state queries against the Emby API. The model sees
  JSON tool schemas and composes them (e.g. "movie night" → a movies-only lineup).

## Why build on Emby instead of a new frontend

The original plan was a dedicated themed media app. We reversed it and built on the existing Emby:

- **Single source of truth** — no duplicate library scan, no second metadata DB.
- **Watch history is the personalization seed** — per-user learning is the whole premise, and that
  history already lives in Emby. A fresh install starts cold.
- **Emby is enough** — a full documented REST API, plus community CSS/JS injection for the overlay.

## Status & scope

Working today: the concierge loop, live TV-style scheduling into the strip, mood-aware search with
type/year/rating/sort filters, and one-word lineup steering. Deliberately out of v1: content
acquisition, multi-user profiles, and model fine-tuning — added only against a measured need.
