SlothSort 馃Ε: The Zero-Effort, Local AI File Organizer
What I Built I built SlothSort , a background digital butler that rewards peak laziness. Like most developers, my Downloads folder is a chaotic graveyard of files named Screenshot_10222026.png, invoice_final_v2_FINAL.pdf, and asdfasdf.jpg. I am simply too lazy to rename and organize them manually.

I built SlothSort, a background digital butler that rewards peak laziness.
Like most developers, my Downloads folder is a chaotic graveyard of files named Screenshot_10222026.png, invoice_final_v2_FINAL.pdf, and asdfasdf.jpg. I am simply too lazy to rename and organize them manually.
SlothSort is a lightweight Python agent that monitors your messy folders. Channeling true International Sloth Day energy, it waits exactly 24 hours before acting on any new file. Once a file hits the "sloth threshold," the script wakes up, analyzes the file using a local open-weight model to determine context, generates a clean, descriptive file name, and moves it to a neatly categorized directory (like /Invoices, /Work_Docs, or /Images). You do absolutely nothing while your computer does the housekeeping.
(Note: I am running this entirely offline via my terminal. The script detects old files on startup, processes them silently through the local LLM, and prints the new mapped destinations.)
SlothSort started. Watching /Users/harsh/Downloads for files older than 24 hours... SlothSort awakening to process: IMG_9921_rec.jpg Moved: IMG_9921_rec.jpg -> /Users/dev/Documents/SlothSorted/Images/receipt_scan.jpg SlothSort awakening to process: Q3_tax_est.pdf Moved: Q3_tax_est.pdf -> /Users/dev/Documents/SlothSorted/Financials/Q3_tax_estimate.pdf
import os import time import shutil import json from pathlib import Path from watchdog.observers import Observer from watchdog.events import FileSystemEventHandler import ollama WATCH_DIR = os. path. expanduser ( " ~/Downloads " ) BASE_SORT_DIR = os. path. expanduser ( " ~/Documents/SlothSorted " ) SLOTH_THRESHOLD_SECONDS = 86400 # 24 hours class SlothHandler ( FileSystemEventHandler ): def process_file ( self, file_path ): file_name = os. path. basename ( file_path ) # Skip hidden files or already processing files if file_name. startswith ( '. ' ): return # Get file age file_stat = os. stat ( file_path ) file_age = time. time () - file_stat. st_mtime if file_age > SLOTH_THRESHOLD_SECONDS: print ( f " SlothSort awakening to process: { file_name } " ) new_name, category = self. ask_local_llm ( file_name ) if new_name and category: self. move_and_rename ( file_path, new_name, category ) def ask_local_llm ( self, filename ): prompt = f """ You are a highly efficient file organizer. I have a file named ' { filename } '. Based ONLY on this file name, provide a clean, descriptive file name (keeping the original extension) and a broad folder category for it (e.g., Invoices, Images, Documents, Installers, Code).
Respond ONLY in strict JSON format like this: {{ " new_name ": " clean_name.ext ", " category ": " CategoryName " }} """ try: response = ollama. chat ( model = ' llama3.1 ', messages = [ { ' role ': ' user ', ' content ': prompt } ]) result = json. loads ( response [ ' message ' ][ ' content ' ]) return result. get ( ' new_name ' ), result. get ( ' category ' ) except Exception as e: print ( f " Failed to process { filename } via Ollama: { e } " ) return None, None def move_and_rename ( self, old_path, new_name, category ): target_dir = os. path. join ( BASE_SORT_DIR, category ) os. makedirs ( target_dir, exist_ok = True ) new_path = os. path. join ( target_dir, new_name ) # Avoid overwriting existing files counter = 1 while os. path. exists ( new_path ): name, ext = os. path. splitext ( new_name ) new_path = os. path. join ( target_dir, f " { name } _ { counter }{ ext } " ) counter += 1 shutil. move ( old_path, new_path ) print ( f " Moved: { os. path. basename ( old_path ) } -> { new_path } " ) def on_modified ( self, event ): if not event. is_directory: self. process_file ( event. src_path ) if __name__ == " __main__ ": print ( f " SlothSort started. Watching { WATCH_DIR } for files older than 24 hours... " ) os. makedirs ( BASE_SORT_DIR, exist_ok = True ) event_handler = SlothHandler () observer = Observer () observer. schedule ( event_handler, WATCH_DIR, recursive = False ) observer. start () # Run an initial scan on startup for file in os. listdir ( WATCH_DIR ): event_handler. process_file ( os. path. join ( WATCH_DIR, file )) try: while True: time. sleep ( 3600 ) # Sleep for an hour, peak sloth behavior except KeyboardInterrupt: observer. stop () observer. join () Enter fullscreen mode Exit fullscreen mode How I Built It SlothSort is built entirely on open-source AI and local inference:
The Brain: Llama-3.1 (open-weight model) running completely locally via Ollama. I configured the prompt to force strict JSON outputs containing new_name and category keys. The Harness: Python utilizing the watchdog library to monitor the file system for changes and track file age (os.stat().st_mtime). The Workflow: When a file crosses the 24-hour threshold, the script sends the file context to the local Ollama API. Upon receiving the parsed JSON response, shutil safely moves and renames the file into the new structured directory tree, automatically handling any name collisions. Enter fullscreen mode Exit fullscreen mode Why Does Open Innovation Matter? For a personal file-sorting tool, open innovation is non-negotiable due to privacy and cost.
A closed API approach would require me to upload my personal bank statements, medical PDFs, and private photos to a third-party server just to generate a file name. That is an unacceptable privacy risk for basic desktop utility. By utilizing an open-weight model via Ollama, my data physically never leaves my machine.
Additionally, running this locally means I set it up once and never pay a subscription fee or worry about API token limits. Whether I download 10 files or 10,000, open-source AI makes this background automation completely free, private, and capable of running without a Wi-Fi connection.
The payoff is zero-maintenance organization. I ran the initial startup script today and SlothSort processed over 200 neglected files from my Downloads folder. For the first time in years, my Downloads directory is completely empty, and everything is neatly filed into /Financials, /Project_Assets, and /Random_Junk. It saved me hours of manual renaming and dragging-and-dropping, allowing me to fully embrace the sloth lifestyle this week.