DEV Community

Sai Sri Madhav K
Sai Sri Madhav K

Posted on

sloth-sort: a lazy file tidier that runs on a local Gemma model

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

What I Built

My Downloads folder is a graveyard. Invoices called Document (3) final FINAL.txt, installers I ran once and forgot, notes named scan0007. Every weekend I promise myself I'll clean it up, and every weekend I don't.

So I built sloth-sort, a small command-line tool that does the cleaning for me. Point it at a folder and it will:

  1. Read each file's name and, when possible, the first bit of its content.
  2. Ask a local AI model for a clean file name and a category folder (Invoices, Study, Photos, Installers, Misc).
  3. Show me the plan as a table and wait. Nothing moves until I confirm.
  4. Move the files and save an undo log, so one command puts everything back.

It never deletes anything, never overwrites a file, and never touches anything outside the folder you give it. All of it runs on my own laptop.

Demo

A dry run on my test folder:

Code

sloth-sort

A small command-line tool that tidies a messy folder (like your Downloads directory) using a local open-weight model, so you never have to sort files by hand.

It reads the first few paragraphs of readable files (or just the file name and extension for binaries and images), asks a local model running on your machine to suggest a clean filename and a folder category, shows you a dry-run plan, and moves the files only when you tell it to.

Every operation is logged and can be completely reverted with one command.

Built for the DEV Hacktoberfest Open-Source AI Challenge (Week 3: Slow and Steady).


Why a local model?

Most file organizers either rely on hardcoded extension rules (dumping all PDFs into one folder regardless of whether they are tax returns, research papers, or appliance manuals) or send file names and contents to third-party cloud APIs.

sloth-sort runs entirely on…

How I Built It

Stack: Python, Ollama for local inference, and Gemma 3 as the model. I tested with gemma3:1b and gemma3:4b. The model is just a config value, so anything Ollama can run will work.

The pipeline is deliberately boring:

  • Scanner: lists files and skips hidden files, partial downloads (.crdownload, .part) and anything modified in the last few minutes.
  • Reader: takes the first ~1000 characters of text-like files (txt, md, pdf, docx, csv). For binaries and images, the model only sees the name and extension.
  • Model call: asks Gemma for strict JSON with new_name and folder. The allowed categories are a fixed list, so the model can't invent 40 different folders. Bad JSON gets one retry, then the file is skipped and left alone.
  • Planner: builds the table and saves it to plan.json.
  • Mover: applies the plan, adds a number when a name collides, and writes undo_log.json.
sloth-sort plan <folder>    # dry run, nothing moves
sloth-sort apply            # apply the last plan after confirmation
sloth-sort undo             # put everything back
Enter fullscreen mode Exit fullscreen mode

I used Antigravity as my coding agent and wrote a detailed spec first: safety rules, exact commands, and a list of things I did not want (no dashboard, no extra features).

What the small model got wrong: in my first run, setup_app_installer.exe was renamed to installer.exe. For a binary, the model only has the file name to go on, so a rename just throws information away. I changed the rule: binaries and images get a category folder but keep their original name. A small model is good at sorting, but it shouldn't rewrite names it can't verify.

To measure accuracy instead of eyeballing it, I built a test folder of 40 ugly files and wrote the correct category for each one before running anything.

Why Does Open Innovation Matter?

A file tidier sees everything: invoices, ID scans, personal notes, whatever lands in Downloads. I didn't want to upload any of that to a server I don't control just to rename a file.

An open-weight model running locally gave me things a closed API wouldn't:

  • Privacy by default. File contents never leave my machine.
  • It works offline. After the one-time model download, no network is involved.
  • No running cost. Sorting 500 files costs the same as sorting 5: no money at all.
  • The model is swappable. Moving from gemma3:1b to gemma3:4b was a one-line config change, so I could measure speed against quality on my own hardware.

The honest tradeoff is quality. The 1B model got confused by installers and receipts without explicit headers, dumping .dmg files and coffee receipts into Misc, while the 4B model correctly recognized them as Installers and Invoices. Both models struggled with informal household notes: a grocery list and an apple pie recipe went to Misc with the 1B model and to the formal Documents category with the 4B model. I didn't test a large cloud model, but I'd expect one to do better at telling casual notes from business documents, and at reading tabular CSV data to tell bank transactions from general reports.

Top comments (0)