This is a submission for the Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady
What I Built
Sloth is a single Python file that does file chores from one sentence. You type something like sort everything in Downloads by file type, a local open-weight model writes a tiny script for it, Sloth shows you the plan, and you press y once. That is the whole interface.
I pointed it at my own Downloads folder: 151 loose files, one sentence, one keypress. Afterwards the folder held exactly one file, Sloth itself.
The rule I built around: the AI plans, dumb code applies. The model's script never touches the disk. It can only call a few helpers (sloth.ls, sloth.move, sloth.match, sloth.read) that record what it wants to do. Nothing moves until I approve the preview, and every run goes onto a stackable undo list (--undo). Save a good script as a "habit" and it reruns later with no model at all.
Sloth also reads inside PDFs, Word files and screenshots (OCR), so it can sort by meaning, not just extension. All offline.
Who gets lazier? Anyone whose Downloads folder has turned into a landfill. That was me.
Demo

The model’s script and the plan, before I press y.

After y: 15 files sorted.

After --undo: every file is back.
Code
lokeshsp2010
/
sloth
Lazy file chores with local open-weight models
Sloth
Lazy file chores with local open-weight models. Describe a chore in plain English. A local model writes a tiny script, Sloth shows you the plan, and you press y once.
Built for the Hacktoberfest Open-Source AI Challenge, Week 3: "Slow and Steady". Everything runs locally through Ollama. No cloud, no API key, no per-run cost.
How it works
- You type a chore:
python sloth.py "sort everything in Downloads by file type" - A local model writes a short script using a small set of helper functions.
- The script runs inside a cage and only records what it wants to do. It never touches your disk.
- Sloth shows a preview table. You press
yto apply, or anything else to cancel. - Every applied run goes on an undo stack.
--undoreverses it.
The idea: the AI plans, dumb code applies.
Requirements
- Python 3.12 (tested on Windows)
- Ollama running locally with…
python sloth.py "sort everything in Downloads by file type" --show --save dl
python sloth.py --undo
python sloth.py --bench "sort everything in Downloads by file type"
How I Built It
Everything runs on models and packages that were already on my laptop. I downloaded nothing new for this project.
| Job | What I used |
|---|---|
| Writes the script |
llama3.1:8b-instruct-q4_K_M via Ollama, temperature 0.1, three few-shot examples |
| Quick per-file questions | hermes3:3b |
| Matches files to folders by meaning |
nomic-embed-text embeddings + cosine similarity |
| Cage for the model's script | RestrictedPython |
| Reads files offline |
pypdf, docx2txt, rapidocr-onnxruntime
|
| Preview table | rich |
Background mode (--watch, experimental, not field-tested) |
watchdog |
This is the script llama3.1 actually wrote for my chore, printed with --show:
d = Path.home() / "Downloads"
for f in sloth.ls(d):
kind = sloth.kind(f)
folder = d / kind
if not folder.exists():
folder.mkdir()
sloth.move(f, folder)
The cage is guardrails, not a fortress: RestrictedPython, a home-folder lock, blocked file-writing methods, and the fact that the script only plans. I would not run untrusted code through it.
Where it broke (the honest part)
Small local models fail confidently. Here is what went wrong on my real files:
-
Wrong destination. I said "sort Downloads". It moved my files into
DocumentsandPicturesinstead of folders inside Downloads. Fix: a prompt rule to create new folders inside the folder being sorted. -
Forced guesses. I gave
match()three bare labels, so embeddings had to pick one. A bank statement landed in "Resumes". Fix: label descriptions, plus aReviewbucket when two labels score too close. I have not tuned that threshold properly. -
The silent partial. The preview showed 9 actions while my folder held over 100 files. The model's script only handled leftovers (and moved
desktop.iniinto "Installers"). I pressedyanyway. Fix: a "HEADS UP: N other files are NOT touched" warning. -
My cage was too tight. The jail blocked
mkdir, so a correct script failed. Fix:mkdirbecame a harmless no-op, since folders are created on apply. - Empty plans. Now Sloth tells the model "zero actions, look again" and retries once.
- Undo leaves empty folders behind. Files go back where they were, but the folders Sloth created stay. Known wart, next on my list.
The fix was never a bigger model. It was preview, a coverage warning and undo. When my first runs misfiled things, --undo put everything back.
Why Does Open Innovation Matter?
-
My files stay mine. To sort by meaning, Sloth reads the inside of my PDFs, Word files and screenshots. My Downloads folder holds tax and bank paperwork. With a closed API that is an upload. Here, nothing left the machine. I even skipped the
:cloudmodels in my Ollama list, because they would have broken that promise. - I could read what the model decided. When it got something wrong, I printed the script and saw why. A closed agent with disk access would just have done it.
-
Swapping models is one flag.
--benchruns the same chore across four local models and prints a table:
| Model (local, via Ollama) | Time | Result (one try, no retries) |
|---|---|---|
| llama3.1:8b-instruct-q4_K_M | 112s | OK, 15 actions |
| mistral:latest | 169s | OK, 15 actions |
| hermes3:3b | 61s | FAIL: broken indentation in its script |
| llama3.2:1b | 21s | OK, 15 actions |
Same chore on a 15-file test folder. "OK" means the script ran and planned all 15 moves. I did not check every destination by hand.
The surprise: the tiny 1B model was about 5x faster than the 8B one and passed this simple chore. The 3B model failed on a plain indentation slip. The bench gives one try, but real Sloth retries up to 3 times and feeds the error back to the model. Single runs include model load time, so treat the times as rough.
- No bill, no internet. It costs nothing per run, and a saved habit does not even need a model.
The honest trade-off: a big closed model would probably have written fewer wrong scripts. What I got in exchange was privacy, a script I can read, and a cage I could build around it. For a tool that touches every file I own, I'll take that trade.
The Lazy Payoff
I ran it on my real Downloads folder today: 151 files sorted from one sentence. I did not time it, and I'll be upfront: building Sloth took far more effort than sorting once by hand. The payoff is the second run, because a saved habit reruns with no model and no typing.
What chore would you hand to a sloth?
AI disclosure: I used Claude to help write and debug the code and to draft this post. The testing, the failures above, and the decisions are from running it on my own machine.


Top comments (0)