The Philosophical Developer — Chapter 40: Finding a Tool You Fall for, and Making It Ours

2026-08-04 · 5 min read

Finding a tool you fall for

Some tools you pick up because you need them. Others you pick up because they make you want to build. This chapter is about the second kind — a small diagramming tool called Sketchlab that I found, fell for, and am now extending alongside Sisyphus.

The discovery

A fast, browser-only diagram tool — think a tiny Figma, no install, no account. You draw shapes, connect them with auto-snapping lines, drop in icons from a built-in library, and everything auto-saves to IndexedDB. Boards are shareable through a single URL. It renders with PixiJS on WebGL, keeps its state in tiny reactive atoms, and ships as static files. No backend at all.

That last part is what hooked me. Most diagramming tools are either heavyweight desktop apps or cloud services that hold your drawings hostage behind a subscription. This one is a folder you can build, serve, and own. It feels like the kind of software I actually want to run on my own boxes — the same instinct that keeps my local-cloud arc alive.

But it had one thing that made me want to reach in: a “Generate with AI” button that was hardcoded to OpenAI.

The catch nobody bothered to ask about

The feature called the OpenAI Responses API directly. It demanded a sk- API key, hardcoded the model, and sent everything to api.openai.com. My entire local-inference story — chapters 6, 11, 13, 26 — is about keeping models on my own hardware. A diagram tool whose AI button only talks to the cloud doesn’t fit how I work.

So the task was simple to state: make that AI button able to point at a local, OpenAI-compatible server instead of the default. The work turned out to be a masterclass in “the obvious change is almost never the obvious change.”

Why /v1/responses is a trap

The original code spoke OpenAI’s newer Responses API (/v1/responses). And that’s the trap: almost nobody local implements it. Llama.cpp returns a flat 404 on /v1/responses. Ollama, vLLM, LM Studio — they all speak the older, universal Chat Completions contract (/v1/chat/completions). So “point at a local OpenAI-compatible server” secretly meant “change the wire format entirely,” not just “change a URL.”

If I’d patched the URL and stopped, nothing would have worked. Research before build — rule thirteen — is what saved this: I probed the actual llama.cpp server, saw the 404, and understood the real shape of the problem before touching the request code.

The shape of the change

The final feature is small and testable, which is the point.

  • The endpoint is now a host, not a URL path. You type http://127.0.0.1:11435 and the app decides the API path itself. Users should never see /v1/chat/completions — that’s our concern, not theirs. A tiny pure module (toChatCompletionsUrl, toModelsUrl) resolves the paths.
  • Models come from the server, not a hardcoded list. The panel queries the endpoint’s /models route and fills a dropdown. The model you pick is persisted and sent in the request.
  • The API key is optional. For local servers it’s usually blank. When it’s blank, the app simply omits the Authorization header.
  • Everything follows the Responses → Chat Completions contract. Messages array, response_format: json_object, and parsing choices[].message.content back into the board’s graph JSON.

Every piece got a test first — the endpoint resolver, the model listing, the request builder, the response parser. Thirty-six tests across four small modules, plus type-check clean, plus a verification script after the change. That’s not ceremony; that’s what lets me change a wire format without breaking the thing I already had open.

The best part of the whole arc

The genuinely delightful discovery wasn’t in my code. It’s that a tiny browser-only diagram tool, found by luck, folds effortlessly into the local-first philosophy I’ve been building for a year. Its AI button now talks to my own llama.cpp. One of the local models — that AGENTS-A1-4B preview — sits in the dropdown right next to a stacked architecture, and it works.

I found a tool, fell for it, and made it ours. That’s the arc I want more of.

What’s next

I’m not done. Tools like this reward extension, and Sisyphus and I are already looking at: saving and loading boards to the host disk through the container, deeper prompt modes, and wiring Sketchlab into the larger diagramming story that Chaossynergy is reaching for. The boulder doesn’t stop here — it just changed shape.

If you build software, my honest advice: keep a folder of tools you don’t need explained to you, that run on your own machine, that you can read in an afternoon. Then pick one and make it yours. It’s the most reliable source of forward momentum I know.

Repos:

Written in the Sisyphus voice — the relentless co-builder, not the quiet padawan. The work continues.