Getting started
Run the full stack locally and complete a first search
Get from zero to a searchable video on your machine. You need Docker, Node.js, and pnpm.
Prerequisites
- pnpm (see root
packageManagerinpackage.json) - Docker: Postgres, Valkey, S3-compatible storage, and tusd run via Compose
- An AI Gateway API key: used for embeddings and Whisper transcription
Install and run
From the repo root:
pnpm install
pnpm dev:allThat script builds shared packages, starts local infra (docker-compose.dev.yml), and runs the admin UI, indexer API, worker, and search API in parallel.
| Process | Default |
|---|---|
| Admin UI | http://localhost:5173 |
| indexer-api | http://localhost:3000 |
| search-api | http://localhost:3001 |
| tusd | http://localhost:8080/files/ |
Copy each *.env.example to .env and set AI_GATEWAY_API_KEY for the server, worker, and search-api (search embeds queries). Model IDs come from your env. Parallel worktrees, Vite port overrides, and tusd hook forwarding: Local development.
End-to-end behavior is validated against the opinionated defaults: Gemini embeddings and Whisper for speech. If you swap in other models, check that model's docs for equivalent capabilities (video/image/text embed shapes, ASR output, size limits) and what the AI Gateway exposes for that provider.
First search
- Open the admin UI (http://localhost:5173 on the primary checkout).
- Upload a short MP4, MOV, WebM, or AVI video (tus → object storage).
- Pick a path and start processing:
- Multimodal: chunk + embed video segments
- Speech: extract audio → Whisper → embed transcript segments
- Vision: sample frames → embed images
- Hybrid: one shared segment grid → video + speech + vision embeds (fused RRF search)
- Wait until the task shows complete (status polling in the UI).
- Open that path's search page and try a natural-language query.
Each independent modality has its own process, search, and costs screens. Hybrid is a separate fourth path. Indexing one does not index the others.
Search from code
Once search-api is up (default publish port 3001 in deploy layouts):
import { SearchClient } from "search-client";
const client = new SearchClient({
baseUrl: "http://localhost:3001",
});
const hits = await client.search({ query: "sunset over water", limit: 10 });
// or: client.searchHybrid({ query: "…", weights: { speech: 1.5 } })See Search for transcript, frame, and hybrid methods.
Production-shaped deploys
Local pnpm dev:all is for development. For container deploys, use Self-contained or External.
Docs are published at https://sliceseeker.ashutoshbind.com/. To run the docs site locally (:4000):
pnpm --filter docs dev