1<!--
2SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
3
4SPDX-License-Identifier: CC0-1.0
5-->
6
7# garble
8
9[](https://api.reuse.software/info/git.secluded.site/garble)
10[](https://liberapay.com/Amolith/)
11
12Transform stdin with an LLM. Pipe text in, get transformed text out.
13
14## tl;dr
15
16Mostly made to simplify [Voxtype's post-processing step](https://github.com/peteonrails/voxtype/blob/main/docs/USER_MANUAL.md#post-processing-with-llms), so I've only tried it with voice transcriptions. Happy to accept patches tuning the fairly minimal current prompts.
17
18```bash
19# Fix typos and grammar
20echo "teh quikc brown fox" | garble --directions "fix typos"
21
22# Translate
23cat letter.txt | garble --directions "translate to Pirate"
24
25# Reformat
26pbpaste | garble --directions "convert to markdown table" | pbcopy
27```
28
29## Installation
30
31```bash
32# Clone and install to ~/.local/bin
33git clone https://git.secluded.site/garble
34cd garble
35make install
36
37# Or install elsewhere
38make install PREFIX=/usr/local
39```
40
41Requires Erlang/OTP and the Gleam toolchain.
42
43## Usage
44
45```bash
46garble [--provider PROVIDER] [--model MODEL] [--directions "..."]
47```
48
49All flags are optional if configured in `~/.config/garble/config.toml`.
50
51### Flags
52
53| Flag | Description | Example values |
54| -------------- | ------------------------------------------- | ------------------------------------------- |
55| `--provider` | Provider ID | `openai`, `anthropic`, `google` |
56| `--model` | Model ID | `gpt-4o`, `claude-3-opus`, `gemini-1.5-pro` |
57| `--directions` | Instructions for how to transform the input | `"fix grammar and spelling"` |
58| `--reasoning` | Reasoning effort for thinking models | `low`, `medium`, `high` |
59
60Valid provider and model IDs are listed at https://catwalk-fe.secluded.site (an unofficial frontend for Charm's [Catwalk](https://github.com/charmbracelet/catwalk) service).
61
62### Configuration
63
64Create `~/.config/garble/config.toml`:
65
66```toml
67provider = "anthropic"
68model = "claude-sonnet-4-20250514"
69directions = "fix grammar and spelling"
70
71# API key options (in order of precedence):
72# 1. Run a command to get the key
73api_key_cmd = "op read 'op://Private/Anthropic/credential'"
74
75# 2. Or set it directly (not recommended)
76# api_key = "sk-..."
77```
78
79#### OpenAI-compatible providers
80
81For `openai-compat` providers, you can optionally specify a `dialect` to control how reasoning requests are encoded:
82
83```toml
84provider = "openai-compat"
85endpoint = "https://api.together.xyz/v1"
86model = "deepseek-ai/DeepSeek-R1"
87dialect = "together" # Optional: generic (default), together, groq, cerebras, llamacpp, tags
88```
89
90Available dialects:
91
92| Dialect | Provider |
93| ---------- | --------------------------------- |
94| `generic` | Most OpenAI-compatible providers |
95| `together` | Together AI |
96| `groq` | Groq |
97| `cerebras` | Cerebras |
98| `llamacpp` | Local llama.cpp / vLLM instances |
99| `tags` | Providers using `<think>` tags |
100
101If neither `api_key_cmd` nor `api_key` is set, garble falls back to the
102provider's environment variable (e.g. `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`).
103
104CLI flags override config file values.
105
106Here's my config.
107
108```toml
109provider = "synthetic"
110model = "hf:deepseek-ai/DeepSeek-V3.2"
111directions = """
112Correct the transcription to match how I would actually type, after edits and corrections.
113
114- Follow inline dictation instructions, example follows in the section below
115- Remove filler words like "um", "uh", "like", "you know", "so" (when meaningless)
116- Correct words from the transcription engine when the context makes obvious what the word should be, example follows in the section below
117- Remove false starts and repeated words
118- Preserve my intended meaning without rephrasing or "improving" my words
119- No markdown, no formatting, just clean plain text
120
121<dictation_interpretation_example>
122<in>
123This is. An example of speaks, an audio compression codec. Specifically tuned for reproducing. Specifically tuned for the reproduction of the human voice. No, human speech.
124</in>
125<out>
126This is an example of SPEEX, an audio compression codec specifically tuned for the reproduction of human speech.
127</out>
128</dictation_interpretation_example>
129"""
130```
131
132## Contributions
133
134Patch requests are in [amolith/llm-projects] on [pr.pico.sh]. You don't
135need a new account to contribute, you don't need to fork this repo, you
136don't need to fiddle with `git send-email`, you don't need to faff with
137your email client to get `git request-pull` working...
138
139You just need:
140
141- Git
142- SSH
143- An SSH key
144
145```sh
146# Clone this repo, make your changes, and commit them
147# Create a new patch request with
148git format-patch origin/main --stdout | ssh pr.pico.sh pr create amolith/llm-projects
149# After potential feedback, submit a revision to an existing patch request with
150git format-patch origin/main --stdout | ssh pr.pico.sh pr add {prID}
151# List patch requests
152ssh pr.pico.sh pr ls amolith/llm-projects
153```
154
155See "How do Patch Requests work?" on [pr.pico.sh]'s home page for a more
156complete example workflow.
157
158[amolith/llm-projects]: https://pr.pico.sh/r/amolith/llm-projects
159[pr.pico.sh]: https://pr.pico.sh
160
161---
162
163Some other tools if this one interested you
164
165- [git-format](https://git.secluded.site/git-format) - CLI that turns LLM input into well-formatted conventional commits and tags
166- [agent-skills](https://git.secluded.site/agent-skills) - collection of Agent Skills for extending LLM capabilities
167
168## License
169
170AGPL-3.0-or-later