|
| 1 | +# Atom++ — Agent Sketch — Design |
| 2 | + |
| 3 | +> **Status:** SK1 skeleton shipped · **Date:** 2026-07-01 · **Owner:** Sergii Demianchuk |
| 4 | +> **Vision:** Sketch a whole agentic system visually, right inside the Atom++ editor — connect |
| 5 | +> specialized agents into flows, watch **tokens burned per step**, and **recalculate the same flow |
| 6 | +> against different models** before committing to one. Chaining in the spirit of |
| 7 | +> [ruflo](https://github.com/ruvnet/ruflo) ("Agent = Model + Harness"; 100+ specialized agents), |
| 8 | +> with the canvas interaction model adapted from the SystemSketch (SysDes) prototype. |
| 9 | +
|
| 10 | +## 0. Why this is a natural Atom++ feature |
| 11 | + |
| 12 | +Everything below sits on the multi-provider layer already shipped: |
| 13 | + |
| 14 | +| Need | Already built | |
| 15 | +|---|---| |
| 16 | +| Run one agent step on ANY provider, BYO-key | P1/P2 — `providers.streamAgentTurn` (Anthropic native + OpenAI-compatible translation) | |
| 17 | +| **Real token usage per step** | P2 — `usage` from `message_start`/`stream_options.include_usage` | |
| 18 | +| Per-model capabilities to pick sensible defaults | P4 — `providers/catalog.js` tiers/caps | |
| 19 | +| Cost math for the meter + what-if | `sketch/pricing.js` ($/MTok table; Anthropic published, others list-price estimates, labeled "est.") | |
| 20 | +| No middle-man backend, keys in the keychain | The Atom++ architecture invariant | |
| 21 | + |
| 22 | +## 1. The SK1 skeleton (shipped) |
| 23 | + |
| 24 | +``` |
| 25 | +extensions/atom-ai/ |
| 26 | + sketch.js controller: panel, persistence, THE RUNNER (reentrancy-guarded, abortable) |
| 27 | + sketch/agentCatalog.js 96 agent archetypes in 13 palette groups (derived from ruflo, MIT © ruvnet — names + one-line roles only) |
| 28 | + sketch/templates.js ready-made topologies — incl. the "Design a Key-Value Store" hero template [unit-tested] |
| 29 | + sketch/graph.js pure DAG logic: validate (cycles/dangling), Kahn topo LEVELS, node-input builder [unit-tested] |
| 30 | + sketch/pricing.js $/MTok table + exact→basename→family matching + costOf() [unit-tested] |
| 31 | + media/sketch.html the canvas webview (vanilla JS, no build step) |
| 32 | +``` |
| 33 | + |
| 34 | +### Templates — drop a whole topology, set the goal, run |
| 35 | +`sketch/templates.js` ships pre-wired flows loadable from the **Templates…** dropdown; each is a full |
| 36 | +sketch (nodes + edges + per-node instructions) laid out on a grid. The hero is **Design a Key-Value |
| 37 | +Store**, a faithful 11-node / 6-level topology of the *System Design Interview* ("Design a Key-Value |
| 38 | +Store" / ByteByteGo) chapter: |
| 39 | + |
| 40 | +``` |
| 41 | +requirements → architecture → [ storage-engine · consistent-hash · replication+quorum · |
| 42 | + vector-clocks · gossip+failover ] (parallel) |
| 43 | + → integrate+server → [ tests · build+validate ] → review+run-guide |
| 44 | +``` |
| 45 | + |
| 46 | +Every node carries a precise task pinning its aspect (WAL/memtable/SSTable/bloom/compaction; |
| 47 | +consistent-hashing ring; N/W/R quorum + read-repair; vector-clock reconciliation; gossip + sloppy |
| 48 | +quorum + hinted handoff + Merkle anti-entropy; coordinator/request routing; cluster tests). The |
| 49 | +flow **goal** (top of the canvas) sets the language — type *"build using C"* and the flow produces a |
| 50 | +C implementation covering every aspect. Other templates: feature-pipeline, research-synthesize, |
| 51 | +code-review-swarm, SPARC, TDD, bug-fix, API-service, security-audit, refactor. |
| 52 | + |
| 53 | +### Hardening (post adversarial review) |
| 54 | +The `Workflow` adversarial review surfaced 31 confirmed findings; the load-bearing ones are fixed: |
| 55 | +- **Reentrancy / unstoppable spend** — `runSketch` claims a run slot *synchronously* before any |
| 56 | + `await` and clears it only if still its own; a double-clicked Run can't orphan the first run, so |
| 57 | + **Stop always aborts** (real BYOK money). |
| 58 | +- **Abort ≠ failure** — a user Stop paints in-flight nodes `stopped`, not red `error`, and `runDone` |
| 59 | + no longer reports `failed`. |
| 60 | +- **Truncation surfaced** — a node that hits the per-node cap is badged `⚠ truncated` and its stored |
| 61 | + output marked incomplete (cap raised 4096 → 8192 so a full module fits). |
| 62 | +- **`uiError` channel** — save/load/clipboard failures no longer masquerade as run errors. |
| 63 | +- **Pricing drift killed** — the webview's hand-rolled matcher is gone; the extension resolves each |
| 64 | + model's price once (authoritative matcher) and sends the map. |
| 65 | +- **Hostile-JSON safe** — loaded sketches are sanitized (array coercion, `__proto__`/dup-id |
| 66 | + rejection, dangling-edge drop); disk-sourced strings are HTML-escaped before `innerHTML`. |
| 67 | +- **Cross-provider guard** — a per-node model override invalid on the active provider falls back to |
| 68 | + the tier default with a note (no stray `gpt-4o` 400 on a Claude key). |
| 69 | +- **UX** — node rename, run-gating of Load/Templates/Clear, catalog descriptions de-truncated. |
| 70 | + |
| 71 | +- **Palette → canvas → connect → Run.** Drag agents (coder, planner, reviewer, security-manager, |
| 72 | + raft-manager, pr-manager, …) onto the canvas; wire output→input ports into a DAG (cycles are |
| 73 | + rejected live). `Run` executes **levels in parallel, chains in sequence** (Kahn levels — ruflo's |
| 74 | + mesh/pipeline hybrid). |
| 75 | +- **Each node = one turn on the active provider** via `streamAgentTurn` (no tools in SK1): system |
| 76 | + prompt = the agent's role from the catalog (+ optional per-node task), user message = flow goal + |
| 77 | + upstream agents' outputs. |
| 78 | +- **Metering:** every node card shows real tokens in/out + estimated cost; the footer totals roll up |
| 79 | + live. The **what-if selector re-prices the whole recorded run on a different model** without |
| 80 | + re-running — the feature that answers "what would this flow cost on Haiku vs Opus?" |
| 81 | +- **Per-node model:** catalog `tier` (fast/balanced/powerful) → provider-specific default |
| 82 | + (`MODEL_TIERS`), overridable per node in the inspector. |
| 83 | +- **Persistence:** named sketches in the workspace at `.atompp/sketches/<name>.json`. |
| 84 | +- Command: **`atompp.ai.sketch`** ("AI: Agent Sketch…"), also in the Customize panel. |
| 85 | + |
| 86 | +### Safety posture (SK1) |
| 87 | +Sketch nodes are **text-only** — no file edits, no commands, no tools. A sketch run cannot touch the |
| 88 | +workspace; it only spends the user's own tokens (BYOK, direct to provider, key never in the sketch |
| 89 | +files). Costs shown are planning estimates from list prices — the provider bills the user directly. |
| 90 | + |
| 91 | +### Canvas UX (SK1.1) |
| 92 | +- **No lost work.** A node runs to completion via `runNodeTurn` auto-continuation: `streamAgentTurn` |
| 93 | + caps a single turn at 8192 tokens, and if the model stops on `max_tokens` the runner feeds its own |
| 94 | + partial back with a "continue where you left off" instruction and keeps going — accumulating text |
| 95 | + and usage across up to 8 turns. A whole code module (or the KV-store integrator's output) is no |
| 96 | + longer truncated. Nodes that needed more than one turn show `⟳n`; only exhausting the 8-turn safety |
| 97 | + cap marks a node truncated. |
| 98 | +- **Zoom + bigger board.** 12000×8000 world; `translate(pan)·scale(zoom)` with wheel-zoom (cursor- |
| 99 | + anchored), +/−/reset/fit controls, ⌘0 / ⌘± shortcuts, and a **Fit** that frames the whole flow. |
| 100 | + All drop/drag/wire math goes through `toWorld()` so it's correct at any zoom. |
| 101 | +- **Board command bar (LLM edits the graph).** Type an instruction — *"add a security-auditor after |
| 102 | + coder"*, *"set every agent to Opus 4.8"*, *"tidy the layout"* — and the active model returns a JSON |
| 103 | + op list (`add`/`connect`/`disconnect`/`remove`/`setModel` scoped all|agent|node/`setTask`/`setGoal`/ |
| 104 | + `layout`) applied deterministically in the webview. Unknown agents/refs are skipped with a note; the |
| 105 | + DAG stays acyclic. |
| 106 | +- **Active-node highlight redesigned.** The marching-ants border is gone (it flickered over the |
| 107 | + connector dots); the running node now has a breathing glow + a header shimmer, and ports sit above |
| 108 | + it (`z-index`) so they never blink. |
| 109 | +- **Palette optimized.** Live search filter, per-agent tier chip (f/b/p), sticky group headers, |
| 110 | + expand/collapse-all. |
| 111 | +- **What-if reworked.** Instead of one dropdown, a row of chips shows what *this exact flow* would cost |
| 112 | + on each candidate model (the active provider's fast/balanced/powerful tiers + any model actually |
| 113 | + used), cheapest first, current run marked. Clicking a chip switches every agent to that model — so |
| 114 | + the comparison is also the action. |
| 115 | +- **Tidy.** One-click `autoLayout` (topological columns) re-arranges the flow left→right by dependency. |
| 116 | + |
| 117 | +## 2. Roadmap |
| 118 | + |
| 119 | +| Phase | Deliverable | |
| 120 | +|---|---| |
| 121 | +| **SK2** | **Tool-using nodes**: a node can run the full `agent.js` loop (read/edit/run with Keep-Undo review + per-run checkpoint) so a sketched flow actually edits the workspace; live streamed output in the inspector; run history. | |
| 122 | +| **SK3** | **Topologies**: coordinator/hierarchical patterns (a queen node that dispatches + collects, ruflo-style), conditional edges, retry/verify loops; per-flow token budgets with early stop. | |
| 123 | +| **SK4** | **Interop**: import/export ruflo swarm configs; publish sketches as shareable templates; sketch → `atompp.ai` chat-agent handoff ("run this flow on the current repo"). | |
| 124 | + |
| 125 | +## 3. Attribution & licensing |
| 126 | +Agent names/roles derived from ruflo's `.claude/agents/` library (MIT © 2024–2026 ruvnet) — metadata |
| 127 | +only (name + one-line role); every node executes on Atom++'s own agent loop and providers. The canvas |
| 128 | +interaction model (palette/nodes/edges/live metrics) is adapted from the internal SysDes prototype. |
0 commit comments