devto 2026-10-23 원문 보기 ↗
Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady Submission 🦥
This is a submission for the Hacktoberfest Open-Source AI Challenge: Week 3, Slow and Steady.
paste-sloth is a background process. you copy the way you already do, and when the text is a mess you hold ctrl, press space, press V, and let go. the clipboard goes to a model, comes back restructured, and gets pasted into whichever window has focus. csv becomes a markdown table, json gets pretty-printed, logs become one entry per line.
name,score,city
ada,10,lagos
grace,12,accra
the usual repair is a second app: paste into a chat, type "just the table", wait, select the reply, copy it, go back, paste. that whole loop is now one chord. the chord is awkward on purpose, so it never fires while you're typing, and the model is small enough that leaving it running feels lazy rather than expensive.
the gif is a real paste-sloth clean run against a stub server. the stub is rude on purpose: it answers with Here is the table: and a code fence, so you can watch the tool strip both, check the numbers, and print the table. paste-sloth clean restructures the clipboard once and prints the result - the easy way to see what the model does before the keyboard is involved.
the installer is one line. it finds python 3.11 or newer, makes a venv, and opens a menu:
# macOS or Linux
curl -fsSL https://raw.githubusercontent.com/walsoup/paste-sloth/main/install.sh | bash
# Windows
irm https://raw.githubusercontent.com/walsoup/paste-sloth/main/install.ps1 | iex
enter on the first row asks for a base url, a key, and a model name. down, then enter, is the local option: it installs ollama if it's missing and downloads gemma 4 e2b at 1-bit (IQ1_S, about 2.4 gb - google doesn't publish a 1-bit file, so it's an importance-matrix quant of the instruction-tuned weights), then writes the config and an autostart entry.
the model does the one job a very small model can be asked to do. the code holds the pen for everything else.
the request is a chat completion at temperature 0. the system prompt is short: reply with only the restructured text, keep every value, pick the structure that fits. before the reply touches the clipboard it gets checked:
the number check is the part i would not ship without:
def introduces_numbers(source: str, output: str) -> bool:
"""True when the output contains a number the input never had.
Dropped numbers are allowed: stripping timestamps from a log is legitimate.
Ordered-list markers the model adds (``1.``, ``2)``) are not data.
"""
invented = number_tokens(output, ignore_list_markers=True) - number_tokens(
source, ignore_list_markers=False
)
return bool(invented)
the chord was the fiddly part, because space is also a spacebar. ctrl is forwarded as it happens. space is held back, and if you press another key or release space before V, the held space gets replayed, so autocomplete and input-method switching still work. V while both are held is the paste, and both keys are swallowed so the app doesn't also get a raw paste. a second chord while a request is in flight is ignored. ctrl+space+esc releases the keyboard and quits.
on linux this is evdev with an exclusive grab plus a uinput virtual keyboard - wayland won't let an ordinary app watch every key or type into other windows, and a desktop shortcut can't express ctrl+space+V because space is not a modifier. the grab needs a one-time sudo setup, which paste-sloth setup prints. windows and macos use pynput.
base_url takes any openai-compatible endpoint, local or hosted. your clipboard, your pick.repo: https://github.com/walsoup/paste-sloth - python 3.11, MIT.