Tool Dispatch Viz
An interactive walkthrough of the layer that sits between a model's tool-call output and the real-world handler. The dispatch pipeline validates arguments, routes to a registered handler, executes, classifies failures, retries with exponential backoff when appropriate, falls back to alternatives when the retry budget is spent, and finally formats a result back into something the model can read.
Four built-in scenarios cover the canonical paths: happy (no failures), timeout (one transient 503 absorbed by retry), rate-limit (429 walked through exponential backoff), and cascade failure (retry budget exhausted, primary tool dead, fallback chain activates). Two extra modes harden intuition: Predict asks the viewer to pick the next move at branching points; Challenge runs multiple-choice rounds about transient-vs-permanent errors, backoff strategy, and graceful-degradation semantics.
When a model outputs a tool call, a dispatch layer sits between intent and execution. It validates arguments, routes to the right handler, manages retries on failure, and formats the result back into something the model can read. Pick a scenario to see how the pipeline handles success and different failure modes.
Installation
npx shadcn@latest add https://craftbits.dev/r/tool-dispatch-viz.jsonUsage
import { ToolDispatchViz } from "@craft-bits/viz/tool-dispatch-viz";
<ToolDispatchViz />Swap in your own scenarios:
<ToolDispatchViz
scenarios={[
{
id: "happy",
label: "Cache hit",
toolCall: { name: "cache_lookup", arguments: { key: "user:42" } },
steps: [
{ stage: "validate", narration: "Key arg validated." },
{ stage: "route", narration: "Matched cache_lookup handler." },
{ stage: "execute", narration: "Cache returned hit." },
{ stage: "format", narration: "Wrapped as structured result." },
{ stage: "done", narration: "Done — no retries needed." },
],
},
]}
/>Customise the Challenge rounds:
<ToolDispatchViz
challengeRounds={[
{
prompt: "An idempotent POST returns 502. Retry safe?",
options: ["Yes — idempotent + transient", "No — POSTs are never safe to retry"],
correctIdx: 0,
explanation:
"502 is a transient gateway error and the operation is idempotent. The retry is safe and the standard pattern.",
},
]}
/>Understanding the component
- Mode strip. A
role="tablist"switches between Explore / Predict / Challenge witharia-selectedon each tab. - Scenario pills. Each scenario is a pill with
aria-pressed. Selecting one in Explore mode jumps to step 0 of that scenario. Pill colour reflects outcome family (success / warning / failure) so the viewer reads the run's shape at a glance. - Pipeline strip. Four stage boxes (
Validate · Route · Execute · Format) wired with arrows. The current stage carries the accent colour; past stages flip to success; an erroring stage flips to error. A subtle relief glow tints the strip when retries or fallbacks were involved. - Tool-call card. Syntax-highlighted JSON of the incoming tool call. Card opacity tracks whether a scenario is selected.
- Result card. Animates from empty → success on
stage === "done". Thevia {fallbackTool}annotation appears when the dispatch landed via the fallback chain. - Error banner. Shown for any error stage (
error-classify,retry,backoff,fallback-activate,fallback-execute). Renders the error code + classification chip, a retry counter, a live backoff timer, and a primary→fallback handoff label for the fallback stages. - Step indicator. A dot + label below the strip names the current stage. Includes a "(after N retries)" suffix when the active step is past the retry phase.
- BackoffTimer. A 50ms-tick progress bar that auto-advances the step on completion. Under reduced motion, it skips its countdown and fires
onCompleteimmediately. - Predict mode. Rounds at canonical branching points (503 received → classify; 429 received → backoff; budget exhausted → fallback; 401 received → don't retry; backoff sum).
- Challenge mode. Shorter rounds about permanent-vs-transient errors, why-backoff, graceful-degradation, and counting attempts. A
ScoreDotsrow tracks correctness. - Reduced motion. Every entrance collapses to
{ duration: 0 }; theBackoffTimerskips its countdown and immediately advances; the perfect-score bounce on summary degrades to a snap.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
scenarios | readonly ToolDispatchVizScenario[] | 4 default scenarios | Scenarios available in Explore mode. |
predictRounds | readonly ToolDispatchVizPredictRound[] | 5 default rounds | Multiple-choice rounds for Predict mode. |
challengeRounds | readonly ToolDispatchVizChallengeRound[] | 4 default rounds | Multiple-choice rounds for Challenge mode. |
transition | Transition | SPRINGS.snap | Override entrance spring for rows and panels. |
className | string | — | Merged onto the root via cn(). |
Accessibility
- The root is
role="figure"with anaria-labelsummarising the visualisation. - The mode strip is a real
role="tablist"witharia-selectedon each tab; the scenario pills carryaria-pressedto mirror the active scenario. - An
sr-onlypolite live region announces stage / round transitions via the narration string. - Every interactive control has a visible focus ring and a ≥ 36px hit area.
ScoreDotsrows in Predict / Challenge mode arerole="status"witharia-label.- Stage, error type, and pass / fail signals are paired with a non-colour cue (numeric badge, error code text, ✓ / ✗ glyph,
via fallbacklabel). - Motion respects
prefers-reduced-motion: reduce— every entrance collapses to instant and theBackoffTimeradvances immediately.
Credits
- Extracted from:
craftingattention(app/src/lessons/primitives/systems/ToolDispatchViz.tsx). The source was a lesson primitive built on theWidget/useWidgetHistory/ModeStrip/ChallengeBtn/FeedbackBadge/ScoreDotslesson-chrome stack and carried the CA palette tokens (--color-ink-*,--color-surface-elevated,--color-accent-400,--color-warn-400,--color-success-400,--color-fail-400) plus theca-narrationbanner class. The extract strips all lesson chrome and rebuilds a self-contained mode-tablist + scenario-pill + pipeline-strip + body + narration shell, remapping every palette reference to semanticcb-*tokens. The four hard-coded scenarios, five Predict rounds, and four Challenge rounds are lifted intoscenarios/predictRounds/challengeRoundsprops with defaults preserved (DEFAULT_TOOL_DISPATCH_VIZ_SCENARIOS/DEFAULT_TOOL_DISPATCH_VIZ_PREDICT_ROUNDS/DEFAULT_TOOL_DISPATCH_VIZ_CHALLENGE_ROUNDS). Re-architected toforwardRef+cn()+...propsspread. InlineSPRINGS.snappy/SPRINGS.gentle/MICRO.tap/STAGGER.tight/TIMING.*re-key to canonicalSPRINGS.snap/SPRINGS.bouncy/TAP_SCALE/STAGGERfrom@craft-bits/core/motion.lessonId, the inlineSvgLabelhelper, theChallengeBtnchrome button, and the undo/redouseWidgetHistorywere stripped.