Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 69 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ FLASH (**F**ast **L**ocal **A**gent **SH**ell) CLI is an AI-powered command-line
- **Image Recognition**: Send a local image to a vision-capable model with `/image <path> [prompt]`, or let the AI open one itself with its `view_image` tool.
- **Page Screenshots**: The AI renders a page it built in a headless browser with its `screenshot` tool and looks at the result, so it can see a broken layout instead of guessing from the HTML.
- **Page Control**: The AI opens a page with `open_page` and then clicks buttons, fills forms, presses keys, and runs JavaScript on it with `interact`, seeing a fresh screenshot, the page's elements, and its console errors after every step, so it can debug what a page *does*, not just how it looks.
- **Voice Mode**: `/voice on` downloads a Vosk speech model and a Piper voice, then lets you talk to Flash and hear its replies, with typing still available at any time.
- **Context Management**: Automatic history trimming to stay within token limits.
- **Markdown Support**: Rich formatting for AI responses in the terminal.

Expand Down Expand Up @@ -144,35 +145,98 @@ python run.py
`/image <path> [prompt]` attaches a local image (`.png`, `.jpg`, `.jpeg`,
`.webp`, `.gif`, `.bmp`) to your next message and sends both to the model.
If you leave off the prompt, Flash asks it to describe the image. This
requires a vision-capable model text-only models will ignore the image
requires a vision-capable model text-only models will ignore the image
or error. Pull one and switch to it first, e.g.:

```bash
ollama pull llama3.2-vision
```

```
Flash Onyx 2+ is vision capable.

```console
/model llama3.2-vision
/image ~/Pictures/screenshot.png What's going on in this UI?
```

The model can also open an image on its own with the `view_image` tool, so
you can just name the file in a normal message and let it look:

```
```prompt
Why does the legend in ~/Desktop/plot.png overlap the bars?
```

It accepts the same file types (up to 20 MB) and sees the image for that
turn only, calling `view_image` again later if it needs another look.

### Voice mode

`/voice on` turns Flash into something you can talk to. The first time it
runs it downloads the two models it needs into `~/.flash/models`: a Vosk
speech-recognition model for listening (about 40 MB) and a Piper voice for
speaking (about 60 MB). After that everything runs locally, with no audio
leaving the machine.

```FLASH
/voice on
```

With voice mode on, press Enter on an empty prompt to start talking. Flash
records until you stop, prints what it heard, and sends it as your message;
the reply is printed as usual and read aloud. It then listens again on its
own, so a conversation carries on hands-free with no keypress between
turns. Say nothing for eight seconds (`VOICE_NO_SPEECH_SECONDS`), or press
Ctrl+C, and it hands the prompt back. Typing works exactly as before, so
slash commands and long paths can still be typed rather than dictated.

Say **"interrupt"** while Flash is talking and it stops mid-sentence and
listens for what you say next, so you never have to sit through an answer
that started off wrong. "stop talking" and "be quiet" work too, as does
Ctrl+C, and the word can be changed with `VOICE_INTERRUPT_WORD`. It is
matched as a whole word, so "the interrupted process" is just a message.

Say **"voice off"** (or "stop listening", "exit voice mode") to end the
conversation. That hands the prompt back but leaves voice mode armed, so
pressing Enter starts talking again without re-enabling anything. To turn
the feature off altogether, type `/voice off`; the setting is saved in
`~/.flash.env` as `VOICE`, so voice mode survives a restart either way.

Only the prose of a reply is spoken. Code blocks, tables, and URLs are
skipped, because they are on screen already and unpleasant to listen to,
and a long answer is cut at a sentence once it passes `VOICE_MAX_CHARS`.
Flash also tells the model that it is being heard rather than read, so
replies in voice mode come back shorter and plainer.

Voice mode needs three extra packages: `vosk`, `piper-tts`, and
`sounddevice`. `install.sh` and `install.ps1` install them for you, so
this is only needed if you installed Flash some other way. Flash installed
with pipx keeps its own environment, so the packages go in with `inject`:

```bash
pipx inject flash vosk piper-tts sounddevice
```

For a plain pip install of Flash it is the extra instead:

```bash
pip install "flash[voice]"
```

`/voice on` prints whichever of the two commands fits your install. On
Linux
`sounddevice` also needs PortAudio from the system (`apt install
libportaudio2`); the macOS and Windows wheels bundle it. The voice and the
listening model can be swapped with `VOICE_PIPER_VOICE` and
`VOICE_VOSK_MODEL`, and the microphone's sensitivity tuned with
`VOICE_SILENCE_THRESHOLD`; see [docs/CONFIGURATION.md](docs/CONFIGURATION.md).

### Page screenshots

The `screenshot` tool renders a local `.html` file or a URL in a headless
Chromium and attaches the picture, so a vision-capable model can check
what it built rather than trusting its own source:

```
```prompt
Build me a pricing page in ~/Desktop/pricing.html, then check how it
looks on a phone.
```
Expand Down Expand Up @@ -253,7 +317,7 @@ flash "flash://?prompt=What+is+Python"
```

The prompt is URL-encoded, so use `+` or `%20` for spaces. Flash always shows
the prompt and asks before sending it to the model — any web page can open a
the prompt and asks before sending it to the model. Any web page can open a
`flash://` link, so nothing runs unattended. For the same reason, URL prompts
may not start with `/` or `!`: they carry questions for the model, never Flash
commands or shell escapes.
Expand Down
39 changes: 36 additions & 3 deletions docs/CONFIGURATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ OLLAMA_HOST=http://localhost:11434
## Backend

FLASH uses [Ollama](https://ollama.com) as its backend. It does not require
an API key. Instead, it connects to an Ollama server over HTTP either on your
an API key. Instead, it connects to an Ollama server over HTTP, either on your
own machine (the default) or on another host.

Requirements:
Expand All @@ -39,13 +39,46 @@ Requirements:

| Variable | Required | Default | Minimum | Description |
| -------- | -------- | ------- | ------- | ----------- |
| `MODEL` | Yes | | | Name of the Ollama model to use, e.g. `llama3.1`, `qwen2.5`, `mistral`. Must be pulled on the target server. |
| `OLLAMA_HOST` | No | `http://localhost:11434` | | Base URL of the Ollama server. Change this to switch from a local server to a remote one. |
| `MODEL` | Yes | - | - | Name of the Ollama model to use, e.g. `llama3.1`, `qwen2.5`, `mistral`. Must be pulled on the target server. |
| `OLLAMA_HOST` | No | `http://localhost:11434` | - | Base URL of the Ollama server. Change this to switch from a local server to a remote one. |
| `MAX_HISTORY_MESSAGES` | No | `6` | `2` | Maximum number of chat messages kept in memory before the oldest are dropped. |
| `MAX_HISTORY_CHARS` | No | `3000` | `1000` | Maximum total characters of history kept. Older messages are dropped once this is exceeded. |
| `MAX_TOOL_ROUNDS` | No | `10` | `1` | Maximum number of tool-calling rounds allowed per request. |
| `MAX_TOOL_OUTPUT_CHARS` | No | `1200` | `500` | Tool output longer than this is truncated (middle removed) before being sent back to the model. |
| `MAX_OUTPUT_TOKENS` | No | `1024` | `128` | Maximum tokens the model may generate per response. Maps to Ollama's `num_predict` option. |
| `VOICE` | No | `0` | - | `1` turns voice mode on at startup: press Enter on an empty prompt to speak, and replies are read aloud. Usually set with `/voice on` rather than by hand. |
| `VOICE_VOSK_MODEL` | No | `vosk-model-small-en-us-0.15` | - | Name of the [Vosk model](https://alphacephei.com/vosk/models) used for listening. Downloaded to `~/.flash/models` on first use. |
| `VOICE_PIPER_VOICE` | No | `en_US-amy-medium` | - | Name of the [Piper voice](https://huggingface.co/rhasspy/piper-voices) used for speaking, as `locale-speaker-quality`. |
| `VOICE_SILENCE_SECONDS` | No | `1.2` | `0.2` | How long you have to stop talking before Flash decides your turn is over. |
| `VOICE_INTERRUPT_WORD` | No | `interrupt` | - | Word that stops a reply being read aloud when you say it over the top. Matched as a whole word; "stop talking" and "be quiet" always work as well. |
| `VOICE_NO_SPEECH_SECONDS` | No | `8` | `1` | How long a listening turn waits for you to start speaking before handing the prompt back. This is what ends a hands-free conversation. |
| `VOICE_SILENCE_THRESHOLD` | No | `500` | `0` | Loudness (0-32768) above which audio counts as speech. Raise it in a noisy room; lower it if a quiet voice is missed. |
| `VOICE_MAX_CHARS` | No | `700` | `80` | Longest reply spoken aloud. Past this the voice stops at a sentence and says the rest is on screen. |

### Notes on the voice options

- Every `VOICE_*` option is read when it is used, so `/set` followed by
`/refresh` changes voice mode without restarting Flash, including
swapping the voice or the listening model.
- An unreadable value (a typo, a unit like `8 seconds`) falls back to the
default rather than failing.

- Voice mode needs the `vosk`, `piper-tts`, and `sounddevice` packages.
The installers add them for every install; `/voice on` prints the right
command if they are somehow missing, and downloads the two models the
first time it runs.
- Voice mode listens again after each reply, so a conversation continues
without a keypress. It stops when you stay quiet for
`VOICE_NO_SPEECH_SECONDS`, press Ctrl+C, or leave voice mode.
- While a reply is being read aloud, Flash listens for
`VOICE_INTERRUPT_WORD`. Saying it cuts the reply off and starts
listening for your next message.
- Saying "voice off" (or "exit voice mode", "stop listening") ends the
conversation and hands the prompt back, leaving `VOICE` set so Enter
starts talking again. Typing `/voice off` is what turns the feature off,
since a dictated slash command cannot reach Flash.
- The models live in `~/.flash/models`. Deleting that directory frees the
space; the next `/voice on` downloads them again.

### Notes on the numeric options

Expand Down
Loading
Loading