Use of AI: AudioSilo is developed by me (a human), with assistance from AI, primarily Claude Code, to help me write, clean up, document, and review the code. That doesn't mean the app is generated on autopilot or "vibe coded". Nothing goes out until I've read it, tested it, and decided it belongs. AI is what lets one person keep up this pace, and I think it's important to disclose that.
An internal name. "Bridge" is a working name (BRIDGE-PLAN.md decision 14). The images are public: pull them from
ghcr.io/kodestar/audiosilo-bridgewith no login.
The Bridge is the optional, always-on companion to an AudioSilo server. It writes to the library folders and runs the heavy jobs (transcription, generated character sheets and recaps, and later podcast fetching, read-along alignment, Audible backups and file moves), so the server itself can stay read-only and safe to expose to the internet.
- The Bridge calls the server; the server never calls the Bridge. It pairs once with a code from the server's admin console, then sends a heartbeat every 30 seconds and asks the server for jobs. Remove the Bridge and nothing breaks: its buttons just disappear from the server.
- Every library mapping is checked, not assumed. The Bridge compares a known book's file sizes through its own mount with what the server sees, and probes whether it can write there, before any job may write into that library.
- Its own page (port 8091) handles pairing, the library mappings, settings, the jobs it ran (with Retry for a job that needs attention), the agent container's state, the monthly budget, the ASR workers, and its log. It answers only the local network and always asks for its password.
- AI agents never run in the Bridge. They run in a separate
agentcontainer that sees only a shared staging folder and its own config: no library, none of the Bridge's data, and a network of its own with internet access only.
What it does today: on top of the pairing, heartbeat, job queue with leases,
mapping checks and the proof job bridge.verify, the Bridge generates characters,
recaps and descriptions (sidecars.generate, sidecars.describe), finds a
chapterless book's chapters in its narration (chapters.detect), shares kept
results with the community metadata (sidecars.contribute, meta.correct), and
subscribes to and fetches podcasts (podcast.*). An admin starts a job from the
server's console or the player; the Bridge transcribes the book (or reads its
.epub), runs the AI agents in a separate container, and saves the results with the
book in its .audiosilo/ folder, where the server picks them up. Transcription can
run on another computer with an ASR worker (below). The plan lives in the
workspace's BRIDGE-PLAN.md.
Code is licensed AGPL-3.0 (see LICENSE).
compose.example.yaml runs the server, the Bridge and the
agent container together. The server mounts the library folders read-only, the
Bridge mounts the same folders read-write. Mount them at the same path in both
containers and the Bridge needs no mapping. The Bridge and the agent container share
one staging volume, and nothing else.
- Start both containers. The Bridge prints the password for its page once, in its log, on the first start.
- In the server's admin console, open Settings > Bridge and press Connect a bridge.
- Open the Bridge's page (
http://<host>:8091), sign in, and paste the server's address and the code. Or setAUDIOSILO_BRIDGE_SERVER_URLandAUDIOSILO_BRIDGE_PAIR_CODEfor the first start. - Back in the console, the Bridge shows as online with each library's mapping.
Verify queues
bridge.verifyfor a library to prove the loop. - Give the agent container a credential, using an account of the Bridge's own:
put
CLAUDE_CODE_OAUTH_TOKEN(fromclaude setup-tokenon any machine) in a.envfile beside the compose file, or sign codex in once withdocker compose exec agent audiosilo-bridge agent-login codexand setAUDIOSILO_BRIDGE_AGENT_BACKEND: codexon the Bridge. An API key (ANTHROPIC_API_KEY,OPENAI_API_KEY) works too, billed per token. The Bridge's page shows the agent as ready within about 15 seconds. - Generate characters and recaps from a book's page in the console (or the player, as an admin). The console shows an estimate first, then the job's stage, ETA and spend.
Images (ghcr.io/kodestar/audiosilo-bridge, public from v0.3.0, no login needed):
| Tag | What | Arch |
|---|---|---|
latest |
the full image: Go, ffmpeg and a CPU whisper.cpp for transcription | amd64, arm64 |
latest-slim |
Go and ffmpeg only, for a Bridge that never transcribes | amd64, arm64 |
latest-cuda |
transcription on an NVIDIA GPU (--gpus all) |
amd64 |
latest-agent |
the agent container: the claude and codex CLIs, run by audiosilo-bridge agent-runner |
amd64, arm64 |
Only latest-agent carries an AI agent CLI (decision 15). latest, latest-slim
and latest-cuda also carry the ASR worker builds the Bridge serves. Run it as the compose
example does: user 10002, all capabilities dropped, a read-only root, its own
network.
Speech recognition is much faster on a Mac with Apple Silicon (Metal) or a computer with an NVIDIA GPU. A worker on such a computer connects to the Bridge over the local network and takes every book's transcription while it is connected; it needs no library and no mapping.
-
On the Bridge's page, open Workers, name the worker and press Add worker.
-
Copy the one-line command it shows and paste it into a terminal on the worker's computer (macOS or Linux, arm64 or amd64):
curl -fsSL http://<bridge>:8091/worker/install.sh | sh -s -- --token asw_...
The script downloads the Bridge's own
audiosilo-bridgebuild for that computer from the Bridge (the images carry them), puts it in~/.audiosilo-bridge-worker/bin, and installs the worker as a service that starts at login (launchd on macOS, a systemd user unit on Linux).--runruns it in the terminal instead;--dir <path>puts the program elsewhere. Running it again updates an installed worker (--tokencan be left out then: it keeps the saved one). -
On a Mac the worker uses mlx-whisper on Metal, which needs Python 3 and ffmpeg from Homebrew; its first start builds it and downloads the model.
To install by hand, download the archive for the worker's computer from the
releases, check it against
checksums.txt, and run the commands the Workers tab shows under "Install it by
hand". audiosilo-bridge worker uninstall removes the service. More in the user
guide: Running an ASR worker.
<data>/config.yaml, with AUDIOSILO_BRIDGE_* environment overrides (a setting the
environment sets is locked on the page; an empty variable counts as unset). The data
folder is /bridge-data in the images (AUDIOSILO_BRIDGE_DATA), else
~/.audiosilo-bridge.
| Setting | Environment | Default | |
|---|---|---|---|
listen |
AUDIOSILO_BRIDGE_LISTEN |
:8091 |
the page's address |
server.url |
AUDIOSILO_BRIDGE_SERVER_URL |
the server as the Bridge reaches it: where a pairing code from the environment goes, and the pairing form's starting value | |
public_url |
AUDIOSILO_BRIDGE_PUBLIC_URL |
the page as your LAN reaches it; the console links to it | |
libraries |
AUDIOSILO_BRIDGE_LIBRARIES (<id>=<path>;...) |
the server's own root path | where the Bridge sees each library |
mapping.check_minutes |
AUDIOSILO_BRIDGE_MAPPING_CHECK_MINUTES |
10 |
how often the mappings are checked |
AUDIOSILO_BRIDGE_PAIR_CODE |
pair on start (first start only) | ||
AUDIOSILO_BRIDGE_SECRET_KEY |
<data>/secret.key |
the key that seals the stored secrets (32 bytes, hex or base64) | |
PUID / PGID |
1000 |
the user the Bridge runs as (Unraid: 99/100); a start as another user (--user) needs a data folder that user owns |
|
agent.backend |
AUDIOSILO_BRIDGE_AGENT_BACKEND |
claude |
the CLI the agent container runs: claude or codex |
agent.staging_dir |
AUDIOSILO_BRIDGE_AGENT_STAGING_DIR |
<data>/staging |
the folder shared with the agent container (an absolute path; compose uses /staging) |
agent.claim_timeout_seconds |
AUDIOSILO_BRIDGE_AGENT_CLAIM_TIMEOUT_SECONDS |
120 |
how long a job waits for the agent container to pick it up before the book waits and tries again (10 to 3600) |
agent.monthly_budget_usd |
AUDIOSILO_BRIDGE_AGENT_MONTHLY_BUDGET_USD |
100 |
the agent spend cap for a calendar month (UTC), across every book; 0 is no cap. Over it, books wait until the 1st |
agent.book_budget_usd |
AUDIOSILO_BRIDGE_AGENT_BOOK_BUDGET_USD |
75 |
the agent spend cap for one book |
podcasts.allow_networks |
AUDIOSILO_BRIDGE_PODCASTS_ALLOW_NETWORKS (comma-separated CIDRs) |
private networks podcast feeds and artwork may come from; only for trusted feed hosts on your LAN (a list warns at start and on Status). Applies at the next start | |
podcasts.max_feed_mb |
AUDIOSILO_BRIDGE_PODCASTS_MAX_FEED_MB |
32 |
the largest podcast feed fetched, once decoded (1 to 64). Applies at the next start |
transcripts.retention_days |
AUDIOSILO_BRIDGE_TRANSCRIPTS_RETENTION_DAYS |
30 |
how long a finished book's transcripts are kept (0: deleted when its job ends); the facts and results stay |
AUDIOSILO_BRIDGE_GITHUB_TOKEN |
a GitHub token that can open issues on the community repos, for jobs that contribute their results (contribute: issue); read live, never stored, and used instead of the Accounts tab's GitHub sign-in while set |
The engine's other settings (tools, asr, supervisor, contribution,
metadata, the agent's models and timeout) are carried over from
audiosilo-sidecars and apply at the next start. The supervisor's automatic
recoveries are on by default; its model-assisted lane and backend failover are
always off (they would run an agent in the Bridge). The agent concurrency is the
agent container's --slots (default 1).
Go 1.26 and Node 24. See CLAUDE.md for the gate, the layout and the conventions, and PACKAGES.md for each package's rules.
go build ./... && go vet ./... && go test -race ./... && golangci-lint run
cd web && npm run typecheck && npm run lint && npm run format && npm test
scripts/build-web.sh # the page, embedded into bin/audiosilo-bridge
./bin/audiosilo-bridge --data ./data
docker build --target slim -t audiosilo-bridge:slim . # slim | cuda | agent | full