any-llm on the command line
Built v1 sessions for docs/design-any-llm.md, after the first review pass.
Every command, the flags it touches, and each response. Glyphs, colours and today's lines are the shipped CLI's;
the any-llm wording is what the built code prints, noted under each frame. Generated by
docs/mockups/any-llm-cli-session.py.
Terminal: what shipsCommentary: why, not product
1 · First run, no provider yet
~/research $ bristlenose run interviews/ No LLM provider configured. Set one up once — bristlenose configure <provider> validates your key and stores it securely (Keychain): Claude https://console.anthropic.com/settings/keys ChatGPT https://platform.openai.com/api-keys Gemini https://aistudio.google.com/apikey Azure https://portal.azure.com For local models via Ollama: bristlenose configure local For Mistral, OpenRouter and others: bristlenose configure any-llm
2 · The extra isn't installed
~/research $ bristlenose configure any-llm ✗ any-llm isn't installed in this copy of Bristlenose. Add it: pipx install --force "bristlenose[any-llm]" ~/research $ pipx install --force "bristlenose[any-llm]" installed package bristlenose 0.43.0, installed using Python 3.12.13 These apps are now globally available - bristlenose done! ✨ 🌟 ✨
3 · configure any-llm — key already in the shell
~/research $ export MISTRAL_API_KEY=… ~/research $ bristlenose configure any-llm Which model? Write it as provider:model, e.g. mistral:mistral-large-latest Model: mistral:mistral-large-latest Using the Mistral key from your environment (MISTRAL_API_KEY). Checking with Mistral (~$0.0001, no transcript content)... ✓ Valid Transcripts will go to Mistral, through any-llm 1.27.0. any-llm is now your provider for analysis (was Claude). Switch back any time: bristlenose use claude Run it with: bristlenose run <folder>
4 · configure any-llm — no key yet, so it's stored
~/research $ bristlenose configure any-llm Which model? Write it as provider:model, e.g. mistral:mistral-large-latest Model: deepseek:deepseek-flash Enter your DeepSeek API key: Checking with DeepSeek (~$0.0001, no transcript content)... ✓ Valid ✓ Stored in Keychain as "Bristlenose DeepSeek API Key (any-llm)" Transcripts will go to DeepSeek (api.deepseek.com), through any-llm 1.27.0. any-llm is now your provider for analysis. Run it with: bristlenose run <folder>
5 · Scripted setup: --key and the model variable
~/research $ export BRISTLENOSE_ANYLLM_MODEL=openrouter:meta-llama/llama-3.3-70b-instruct:free ~/research $ bristlenose configure any-llm --key sk-or-v1-… Model: openrouter:meta-llama/llama-3.3-70b-instruct:free (from BRISTLENOSE_ANYLLM_MODEL) Checking with OpenRouter (~$0.0001, no transcript content)... ✓ Valid ✓ Stored in Keychain as "Bristlenose OpenRouter API Key (any-llm)" Transcripts will go to OpenRouter (openrouter.ai), which passes them to the model's host. Check their data policy for the model you picked. any-llm is now your provider for analysis.
6 · configure any-llm — every way it can say no
~/research $ bristlenose configure any-llm Model: mistral-large-latest ✗ Write the model as provider:model, e.g. mistral:mistral-large-latest ~/research $ bristlenose configure any-llm Model: mistrall:mistral-large-latest ✗ any-llm doesn't know a provider called "mistrall". Did you mean mistral? Providers: https://mozilla-ai.github.io/any-llm/providers/ ~/research $ bristlenose configure any-llm Model: anthropic:claude-sonnet-4-6 ✗ Claude is built in. Use: bristlenose configure claude ~/research $ bristlenose configure any-llm Model: cohere:command-r-plus ✗ Cohere needs an add-on this install doesn't have. Add it: pipx inject bristlenose "any-llm-sdk[cohere]"
7 · run — the everyday path
~/research $ bristlenose run interviews/ Bristlenose v0.43.0 · any-llm · Apple M2 Max · MLX Analysis: mistral:mistral-large-latest via any-llm → Mistral 4 sessions in interviews/ ✓ Ingested 4 sessions (4 video) 0.8s ✓ Extracted audio from 4 sessions 1.3s ✓ Transcribed 4 sessions (229 segments) 2m 41s ✓ Identified speakers for 4 sessions 6.2s ✓ Merged transcripts for 4 sessions 0.1s ✓ Segmented 4 transcripts into 35 topics 11.4s ✓ Extracted 48 quotes from 4 sessions 38.9s ✓ Clustered quotes into 4 themes (7 screens) 9.7s ✓ Rendered report 0.2s 4 participants · 7 screens · 4 themes · 48 quotes LLM: 44,920 in · 9,112 out (mistral:mistral-large-latest) Done in 3m 52s Report: http://127.0.0.1:8150/report/ Press Ctrl-C to stop the server
8 · run --llm any-llm with no model set
~/research $ bristlenose run interviews/ --llm any-llm ✗ any-llm needs a model, written as provider:model. Set it once: bristlenose configure any-llm Or per run: BRISTLENOSE_ANYLLM_MODEL=mistral:mistral-large-latest
9 · use — switching between stored keys
~/research $ bristlenose use mistral:mistral-large-latest any-llm is now your provider for analysis (was Claude). Switch back any time: bristlenose use claude Model: mistral:mistral-large-latest (was deepseek:deepseek-flash) ~/research $ bristlenose use deepseek:deepseek-flash any-llm is now your provider for analysis. Model: deepseek:deepseek-flash (was mistral:mistral-large-latest) ~/research $ bristlenose use openrouter:x-ai/grok-4 ✗ No OpenRouter API key: OPENROUTER_API_KEY isn't set and none is stored. Store one: bristlenose configure any-llm ~/research $ bristlenose use claude Claude is now your provider for analysis (was any-llm). Switch back any time: bristlenose use any-llm
10 · doctor
~/research $ bristlenose doctor bristlenose 0.43.0 ✓ FFmpeg 8.1.1 (/opt/homebrew/bin/ffmpeg) ✓ Transcription mlx-whisper 0.4.3 (MLX) ✓ Whisper model large-v3-turbo cached (1.5 GB) ✓ API key Mistral (…f2a) (environment) ✓ any-llm 1.27.0 · mistral, groq, openrouter, deepseek — Network checked by the run's preflight for Mistral — PII redaction off (use --redact-pii to enable) ✓ Voice pass model cached (40 MB) ✓ Disk space 44 GB free ✓ Serve mode 6 deps installed ✓ Auth token random (generated at serve startup) All clear.
11 · doctor — when something's off
~/research $ bristlenose doctor bristlenose 0.43.0 ✓ FFmpeg 8.1.1 (/opt/homebrew/bin/ffmpeg) ✗ API key No DeepSeek API key: DEEPSEEK_API_KEY isn't set and none is stored. — Network skipped (no key) API key Store one: bristlenose configure any-llm
12 · pipeline
~/research $ bristlenose pipeline QUOTE EXTRACTION, QUOTE CLUSTERING, THEMATIC GROUPING, DISCUSSION Claude Sonnet 4.6 (default) ✓ ● ChatGPT GPT-5.6 Terra ✓ ● Azure OpenAI ✗ no Azure OpenAI key set Gemini 3.8 Flash ✓ ? untested Local (Ollama) llama3.2 3B ✓ ⚠ small models miss multi-clause quotes any-llm mistral:mistral-large-latest (current) ✓ ? untested Apple FM — check in the desktop app OS: Darwin arm64 · RAM: 32.0 GB · keys: anthropic, openai, anyllm · ollama: running ~/research $ bristlenose pipeline # on a machine without the add-on ... any-llm ✗ any-llm not installed
13 · run — the provider says no
~/research $ bristlenose run interviews/ Bristlenose v0.43.0 · any-llm · Apple M2 Max · MLX Analysis: openrouter:anthropic/claude-sonnet-4.6 via any-llm → openrouter.ai ✓ Ingested 4 sessions (4 video) 0.8s ✓ Transcribed 4 sessions (229 segments) (cached) ✗ Identifying speakers ✗ Your OpenRouter account ran out of credit. then run bristlenose run interviews/ again. ~/research $ bristlenose run interviews/ ... ✗ Mistral rejected your API key (…x7f). Run bristlenose configure any-llm to set a new key. ~/research $ bristlenose run interviews/ ... ✗ Rate-limited by DeepSeek. Wait a minute and run bristlenose run interviews/ again.
14 · Help text
~/research $ bristlenose run --help │ --llm -l <str> LLM provider: claude, chatgpt, azure, gemini, │ │ local, any-llm. │ ~/research $ bristlenose configure --help │ * provider <str> Provider to configure: claude, chatgpt, gemini, │ │ azure, local, any-llm, or miro. │