Wire LLMs like resistors. Built on Cloudflare Workers + Workers AI, with an Astro front-end and a React Flow canvas.
| Refusal-tolerant vote | Physics-mode token-budget split |
|---|---|
![]() |
![]() |
Screenshots live in
public/screenshots/. See the capture guide.
- Voltage — your prompt
- Resistor — a model (resistance ∝ parameter count)
- Capacitor — a memory slot. Holds text across runs; can inject into the next prompt and/or absorb the next output. Seeded from markdown files, persisted per-node in localStorage, editable in the UI.
- Inductor — resists change. Runs the next model N times on the same input and judge-votes for the most consistent answer.
- Diode — one-way gate. Regex- or judge-LLM-based pass/fail check. Blocks the branch on failure (or annotates and passes through).
- Transformer — branch-local reformat node. A small instructed model that translates / summarises / reshapes its branch's text without changing topology.
- Ground — refusal sink. A grounded branch silently drops out of the parallel join.
- Series — chain of components
- Parallel — fan-out of models that converge at a join node
refine-vote(default) — series asks each next model to refine the prior answer; parallel branches vote for consensus via a judge LLM.chain-ensemble— series chains raw output; parallel branches synthesize via a judge LLM.physics— series sums R; parallel splits a token budget by conductance (1/R) and runs each branch with that budget; surfaces Rtotal.
inject— prepend the capacitor's stored text to the next stage's prompt as### CONTEXT … ### END CONTEXT. State is unchanged.absorb— overwrite the capacitor's stored text with the next stage's output.both— inject, run, then absorb (mirrors an RC step).
State is keyed by node id in browser localStorage. The first time a capacitor is touched, it seeds from its associated markdown file under src/content/capacitors/. The "✎ edit" button on the node opens an inline editor; "reset to seed" wipes the per-node state.
- Every change debounces (400 ms) into the URL hash (
#c=…) and localStorage autosave. - "🔗 Copy share link" puts the current URL on the clipboard — open it anywhere and the canvas rebuilds.
- "⟲ Reset" wipes both the autosave and the hash.
- Capacitor contents are intentionally local-only — share links transport the topology, not your stored memory.
- 2 LLMs in series — basic chain.
- 2 LLMs in parallel — fork/join through a judge.
- Capacitor — style inject —
style-guidecapacitor in inject-only mode shapes every answer. - Capacitor — scratchpad memory — empty scratchpad in
bothmode; two consecutive runs build conversational memory. - Inductor — stabilize a small LLM — inductor ×3 in front of a small model resists noise on ambiguous prompts.
- Diode — guarded chain — judge-mode diode gates a small model's output; failures block the pipeline.
- Transformer — translate then judge — parallel branches answer, a transformer converts each to a common format, judge picks the best.
- Ground — refusal-tolerant vote — three reviewer branches; any branch whose diode fails grounds out, vote proceeds with the survivors.
Everything runs on Cloudflare's free tier. No Durable Objects, no KV, no paid Workers plan required. Workers AI free quota (10k neurons/day) covers ordinary demo traffic. Optional integrations are documented but commented-out by default — see the blog post for the design.
- AI Gateway — set
AI_GATEWAY_IDenv var; calls through Workers AI are cached + logged. Per-call telemetry surfaces in the result panel. - Durable Objects (globally-shared capacitors) — uncomment the
[[durable_objects.bindings]]block. The DO class is shipped inworker/Capacitor.tsand the proxy route insrc/pages/api/cap/[id].ts. With the binding off (default),/api/cap/*returns501cleanly and the rest of the app keeps usinglocalStorage. With it on, capacitors become per-slug, single-writer, strongly-consistent shared memory across browsers.
A health-probe endpoint (/api/cap/_health) reports whether DO is bound, so the frontend can light up the "share globally" toggle automatically.
Astro · React · React Flow · Tailwind · Cloudflare Workers · Workers AI binding.
npm install
npm run dev # local Astro dev (no AI binding — UI only)
npm run wrangler:remote # build + wrangler dev (Workers AI via remote bindings)Workers AI runs against the real Cloudflare backend; wrangler.toml marks the AI binding remote = true, so even a local wrangler dev calls real models.
npm run deployBuilds Astro to dist/ and runs wrangler deploy to publish a single Worker that serves the static assets and exposes /api/run and /api/capacitors.
src/
pages/index.astro playground
pages/api/run.ts Worker route — dispatches to env.AI, handles cap state
pages/api/capacitors.ts serves the seed library to the React island
pages/blog/[...slug].astro blog renderer
components/CircuitCanvas.tsx main canvas, sidebar palette, persistence
components/ModelNode.tsx resistor (LLM) node
components/CapacitorNode.tsx memory node with in-place editor
components/InductorNode.tsx self-vote stabilizer
components/DiodeNode.tsx regex/judge gate
components/TransformerNode.tsx instructed-reformat node
components/GroundNode.tsx refusal sink
lib/models.ts Workers AI model IDs + R values
lib/graph.ts discriminated CircuitNode union + topology validation
lib/presets.ts the five starter circuits
lib/execute.ts three-mode dispatcher + capacitor inject/absorb + inductor self-vote
lib/runner.ts client → /api/run
lib/persist.ts URL-hash + localStorage encode/decode + cap state
content/blog/blogpost.md writeup (stub)
content/capacitors/*.md seed library (style-guide, math-context, scratchpad)

