<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Hitesh Chouhan</title>
    <description>The latest articles on DEV Community by Hitesh Chouhan (@hitesh_chouhan).</description>
    <link>https://dev.to/hitesh_chouhan</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F898707%2Ffd30dfe2-5afb-4e52-810a-a86665018c4b.jpeg</url>
      <title>DEV Community: Hitesh Chouhan</title>
      <link>https://dev.to/hitesh_chouhan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hitesh_chouhan"/>
    <language>en</language>
    <item>
      <title>SlothSort: I built a tiny agent harness from scratch, then taught it to tidy my Downloads folder so I never have to</title>
      <dc:creator>Hitesh Chouhan</dc:creator>
      <pubDate>Sun, 25 Oct 2026 08:42:11 +0000</pubDate>
      <link>https://dev.to/hitesh_chouhan/slothsort-i-built-a-tiny-agent-harness-from-scratch-then-taught-it-to-tidy-my-downloads-folder-so-2037</link>
      <guid>https://dev.to/hitesh_chouhan/slothsort-i-built-a-tiny-agent-harness-from-scratch-then-taught-it-to-tidy-my-downloads-folder-so-2037</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week3-2026-10-19"&gt;Hacktoberfest Open-Source AI Challenge: Week 3&lt;/a&gt; — theme: **Slow and Steady&lt;/em&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I built
&lt;/h2&gt;

&lt;p&gt;Two things, really:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. A small agent harness, written from scratch.&lt;/strong&gt; About 350 lines of standard-library Python, zero dependencies. It runs a model↔tools loop over a local open-weight model: the model never touches the filesystem — it can only reply with JSON tool calls (&lt;code&gt;list_files&lt;/code&gt;, &lt;code&gt;classify_file&lt;/code&gt;, &lt;code&gt;finish_plan&lt;/code&gt;, &lt;code&gt;apply_plan&lt;/code&gt;, &lt;code&gt;undo_last_run&lt;/code&gt;). The harness validates every call, executes it, feeds the result back, retries malformed replies with feedback, and writes a &lt;strong&gt;full session trace (JSONL)&lt;/strong&gt; of every model decision, tool call, refusal and fallback. If the model fumbles a step, the harness says so in the trace — nothing is silently faked.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. SlothSort, the harness's job: a file tidier that rewards laziness.&lt;/strong&gt; Point it at a messy folder. The agent lists the files, classifies each one into a category with a cleaner filename and a one-line reason, and shows you a plan. It is the "Slow and Steady" deal: the sloth does the filing, slowly and carefully; you keep your energy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python demo/make_mess.py                 &lt;span class="c"&gt;# a folder with 12 sad files&lt;/span&gt;
python &lt;span class="nt"&gt;-m&lt;/span&gt; slothsort demo/messy           &lt;span class="c"&gt;# dry run: plan only&lt;/span&gt;
python &lt;span class="nt"&gt;-m&lt;/span&gt; slothsort demo/messy &lt;span class="nt"&gt;--apply&lt;/span&gt;   &lt;span class="c"&gt;# confirmed? then it moves&lt;/span&gt;
python &lt;span class="nt"&gt;-m&lt;/span&gt; slothsort undo demo/messy      &lt;span class="c"&gt;# regret? fully reversible&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The brain is &lt;strong&gt;Gemma 3 (&lt;code&gt;gemma3:1b&lt;/code&gt;)&lt;/strong&gt;, Google's open-weight model, served locally by Ollama. The harness is model-agnostic — Gemma is a component, not a landlord (more on that below).&lt;/p&gt;

&lt;h2&gt;
  
  
  How it saves effort (the lazy payoff)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;I never sort a Downloads folder by hand again. The agent does the boring classification pass — including renaming &lt;code&gt;invoice_final_FINAL_v3.pdf&lt;/code&gt; into something a human would choose.&lt;/li&gt;
&lt;li&gt;It is careful precisely because I am lazy: &lt;strong&gt;dry-run by default&lt;/strong&gt;, an interactive confirmation before anything moves, &lt;strong&gt;never overwrite&lt;/strong&gt; (collisions get a &lt;code&gt;-1&lt;/code&gt; suffix), and an &lt;strong&gt;undo log&lt;/strong&gt; that reverses the last run exactly. A lazy tool you can't trust is just more work.&lt;/li&gt;
&lt;li&gt;It skips hidden files and its own logs. Even its mistakes are auditable through the trace.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Repo: &lt;a href="https://github.com/hiteshchouhan22/slothsort" rel="noopener noreferrer"&gt;https://github.com/hiteshchouhan22/slothsort&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Live demo (GitHub Actions, one click, real model): the repo ships a &lt;code&gt;demo.yml&lt;/code&gt; workflow that installs Ollama, pulls &lt;code&gt;gemma3:1b&lt;/code&gt;, runs the agent against the sample messy folder — plan, apply, undo — and uploads the &lt;strong&gt;full transcript and session trace&lt;/strong&gt; as artifacts. No staging, no mocked model.&lt;/li&gt;
&lt;li&gt;A local run transcript and instructions are also in the repo under &lt;code&gt;demo/&lt;/code&gt; (&lt;a href="https://github.com/hiteshchouhan22/slothsort" rel="noopener noreferrer"&gt;https://github.com/hiteshchouhan22/slothsort&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why open innovation matters here
&lt;/h2&gt;

&lt;p&gt;This project only makes sense with open-weight models:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Privacy by architecture.&lt;/strong&gt; Filenames are personal — tax returns, ID scans, salary letters. With a local open model, they never leave the machine. A cloud API would make the whole tool a bad idea.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Offline and free forever.&lt;/strong&gt; No API key, no per-token bill, no rate limits. It runs on a plane.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Swappable models.&lt;/strong&gt; Because Gemma is open weight and served behind a plain local API, I can swap in &lt;code&gt;qwen2.5:0.5b&lt;/code&gt; or &lt;code&gt;llama3.2:1b&lt;/code&gt; with one environment variable and the harness doesn't change a line. Open weights turn "the model" into a replaceable part — which is exactly what made a from-scratch harness worth building: the loop, the tools, the safety gates and the trace are mine; the brain is interchangeable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Small models are enough — if the harness is honest.&lt;/strong&gt; A 1B model will not reliably one-shot a 40-file JSON plan. But guided one file at a time, with validation and retries, it does the job. That gap between "demo-ware" and "works on my machine" is where open tooling lets you experiment for free until it clicks.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prize categories
&lt;/h2&gt;

&lt;p&gt;I'm entering:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Gemma&lt;/strong&gt; — Gemma 3 (&lt;code&gt;gemma3:1b&lt;/code&gt;, open weight, via Ollama) is SlothSort's default and demoed model: it makes every classification decision inside the harness's tool loop, and the full session trace of its decisions ships with the demo.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Stack
&lt;/h2&gt;

&lt;p&gt;Python 3 (standard library only), Ollama, Gemma 3. Tests: 17, using scripted fake model clients — plan parsing, collision handling, dry-run safety, harness apply-gate refusal, and apply+undo round-trips, all green without needing a model installed.&lt;/p&gt;

&lt;p&gt;— Hitesh Chouhan&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>opensource</category>
      <category>python</category>
    </item>
  </channel>
</rss>
