Before you start
Put API keys in~/.ravi/.env (open it with ravi daemon env), then restart the daemon so it picks them up:
Install the system tools with
brew install ffmpeg yt-dlp (macOS) or your Linux package manager.
Two rules apply to every command below:
- Generating is immediate. Delivering to a chat is not. Anything that posts into a conversation (
--send,ravi media send,ravi stickers send) is a dry-run without--execute: it prints the plan and exits with code 3. Add--executeto send. - “The current chat” means the chat of the session that runs the command. When your agent runs
--sendwhile answering a Slack thread or a WhatsApp group, the file goes back there. From your own terminal there is no current chat, so useravi media sendwith explicit--toand--account.
omni send and reports success only after Omni accepts the request.
Audio generation (text to speech)
Ravi turns text into speech with ElevenLabs.The language defaults to Portuguese (
pt-br). Pass --lang en for English, or set tts_lang in the agent defaults (see Defaults).--send, Ravi converts the MP3 to OGG/Opus (64 kbps, 48 kHz, mono) with ffmpeg and sends the .ogg. WhatsApp shows it as a voice note; Slack shows it as an audio file. If ffmpeg is missing or fails, the MP3 is sent as a regular audio file.
Transcription
Ravi transcribes audio with Whisper. It uses Groq whenGROQ_API_KEY is set, otherwise OpenAI. There is no fallback between them: if the chosen provider fails, the transcription fails.
--lang defaults to pt. Supported formats: .ogg, .opus, .mp3, .m4a, .mp4, .wav, .webm.
Audio longer than 10 minutes is split with ffmpeg into 10-minute chunks that overlap by 15 seconds, transcribed chunk by chunk and joined.
Voice messages your agent receives
Voice notes and audio files that arrive on Slack or WhatsApp are transcribed automatically, and the transcript goes into the agent’s prompt (see Files people send to your agent). This uses the same provider order, with Portuguese (pt) as the language hint. There is no setting to change that hint today; for audio in another language, transcribe the saved file again with ravi transcribe file <path> --lang <code>.
Image generation
Ravi generates and edits images with OpenAI or Gemini.Choose a provider first
There is no built-in default provider. Without one,ravi image generate fails with IMAGE_PROVIDER_NOT_CONFIGURED. Set a global default once:
image.provider, image.model, image.mode, image.quality, image.format), then the environment (RAVI_IMAGE_PROVIDER, RAVI_IMAGE_MODEL). If the selected provider fails, the command fails; retry with another --provider yourself.
Generate
ravi artifacts show <id> gives the file path once the artifact is completed. When the command runs inside a session, that session is told when the image completes or fails, so the agent does not need to poll.
With --sync, the command waits and prints the result:
Video analysis
ravi video analyze turns a YouTube URL or a local video into a Markdown file. With the default strategy (auto), YouTube videos use their subtitles through yt-dlp and fall back to Gemini when there are none. Local files always use Gemini.
The Gemini model is
gemini-2.5-flash unless you set GEMINI_VIDEO_MODEL. The subtitles path does not need GEMINI_API_KEY. Local files (.mp4, .mpeg, .mpg, .mov, .avi, .flv, .webm, .wmv, .3gpp) are uploaded to the Gemini Files API. YouTube videos must be public.
The Markdown file has the title, duration, strategy, transcript and chapters. When Gemini is used it also has a summary, topics and timestamped visual descriptions.
Send any file
ravi media send delivers an image, video, audio file or document and waits for the channel to accept it.
The type comes from the extension:
.jpg, .jpeg, .png, .gif, .webp are images; .mp4, .mov, .avi, .mkv are videos; .mp3, .ogg, .wav, .m4a, .opus are audio; anything else (including .pdf) is sent as a document.
Stickers (WhatsApp)
Ravi keeps a sticker catalog at~/.ravi/stickers/catalog.json. Only WhatsApp supports outbound stickers today. The agent never sees sticker files; when stickers are enabled for it, its prompt gets a short list of sticker IDs and when to use them.
stickers add also takes --channels <csv> (default whatsapp), --agents <csv> (default: all agents), --disabled and --overwrite. stickers send and stickers remove are dry-runs without --execute. Sending queues the sticker for the daemon to deliver.
Stickers are opt-in per agent: set "stickers": {"enabled": true} in the agent defaults (next section).
Agent, instance and global defaults
Instead of passing flags every time, store defaults:Files people send to your agent
When a message with a file arrives on Slack or WhatsApp, Ravi downloads it into the agent’s working directory and puts the local path in the prompt, so the agent can open it with its tools.- Location:
<agent cwd>/attachments/, for example~/ravi/main/attachments/. - Name:
{timestamp}-{messageId}.{ext}. - Size limit: 20 MB. A larger file, or one that fails to download, still appears in the prompt, but without a file path.
- Audio: saved and transcribed (see Transcription).
Related
- Artifacts: every generated image is recorded there.
- Skills: the first
ravi audio,ravi image,ravi videoorravi stickerscall in an agent session loads the matching skill. - Connect Slack and Connect WhatsApp: the channels media is delivered to.
- Configuration: everything
~/.ravi/.envcan hold.