affectUI › Components › Agents

Tool Access Map

An agent in the middle with every tool it can reach around it – which ones it used, which failed and which it calls right now; open a tool for its calls and replay one on its own.

Part of affectUI Pro. Install: npx shadcn@latest add https://www.affectui.com/r/tool-access-map.json · Import from @/components/ui/tool-access-map

When to use

  • Seeing at a glance which tools of the run an agent can reach, which it actually used – and which one it calls right now
  • Debugging a tool call: read its input and output, then replay it on its own, with the same input or a changed one
  • Runs with several agents, each with its own set of tools – switch between them with the tabs on top

When not to use

  • Who started whom – use Agent Tree
  • Agents calling each other and their tools as one network – use Agent Graph
  • A single call with its arguments and result in a chat – use Tool Call Card

Usage

import { ToolAccessMap, type MapAgent } from "@/components/ui/tool-access-map";

const agents: MapAgent[] = [
  {
    id: "coder",
    name: "Coder",
    model: "GPT-6 Sol",
    status: "running",
    task: "Build the pricing page",
    tools: [
      { id: "github", name: "GitHub", calls: [{ id: "c1", status: "done", input: { branch: "pricing-page" }, output: { ref: "refs/heads/pricing-page" }, duration: 450 }] },
      { id: "terminal", name: "Terminal", calls: [{ id: "c2", status: "running", input: { cmd: "npm test" } }] },
      // A tool it can use but hasn't yet
      { id: "stripe", name: "Stripe" },
    ],
  },
];

// Every tool of the run – the ones an agent can't reach are grayed out on its map, with a dashed line
const tools = [
  { id: "github", name: "GitHub" },
  { id: "terminal", name: "Terminal" },
  { id: "stripe", name: "Stripe" },
  { id: "slack", name: "Slack" },
];

export function Tools() {
  return <ToolAccessMap agents={agents} tools={tools} onReplay={(call, input, tool) => agent.call(tool.id, input)} />;
}

Props

NameTypeDefaultDescription
agentsMapAgent[]{ id, name, model?, avatar?, status, task?, tools } – pass them again whenever a call starts or comes back
toolsAccessTool[]the tools of all agents togetherEvery tool of the run, { id, name, icon?, description? }, in the order they're laid out – the first half on the left
agent.toolsAgentTool[]Per agent: { id, calls? } for every tool it has access to – name and icon come from tools; one without calls shows as not used yet, one that isn't listed as no access
callsToolCall[]Per tool, oldest first: { id, status, input, output?, error?, at?, duration?, replay? } – a running call turns its line blue
status"queued" | "running" | "waiting" | "done" | "failed"Per agent – shown as a badge on its card; waiting reads "Needs you"
agentstringControlled id of the agent on the map
defaultAgentstringthe first agentThe agent on the map at first, uncontrolled
onAgentChange(id: string) => voidA tab was picked
onReplay(call, input, tool, agent) => voidReplay was pressed – input is the call's own, or the one it was changed to (parsed from JSON when the original was an object)
formatTime(ms: number) => string0:42Formats when a call was made
titlestring"Tool access"Heading of the bar
classNamestringExtra class on the root

Keyboard

  • ← / →: Moves between the agent tabs
  • Tab: Moves through the tools; Enter opens the calls of one
  • ↑ / ↓: Moves through the calls of a tool and shows each – the list is one tab stop
  • Esc: Back from the calls to the map – focus returns to the tool
  • ⌘ / Enter: Runs the changed input

Accessibility

  • The agents are tabs; the map is their tab panel and says whose tools it shows
  • Every tool it can reach is a button that says its name, how it stands and how many calls it got; one without access says so and can't be opened
  • Opening a tool moves focus into its calls; going back returns it to the tool, and the map underneath is inert meanwhile
  • Status is never color alone: running and failed are badges with words, unused tools say "Not used yet", the others "No access"
  • The counts in the bar on top are announced politely when they change; each keeps its width, and the blue running tag sits to their left so nothing shifts

Responsive

  • Every tool card has a fixed size, so nothing moves when a call starts, finishes or fails
  • The map lays itself out from its own width; below 540px the tools sit in a grid under the agent and the lines give way
  • In the calls view, narrow puts the list above the call
  • Dark mode built in: switches when an ancestor (usually <html>) has the class dark or data-theme="dark"

Requirements

  • React 19

Related

  • Agent Tree – Who started whom – an orchestrator and its sub-agents as a live tree, with status, cost and time on every card, costs rolling up each branch, and branches that fold to one line
  • Agent Graph – Agents and the tools they call as a living network – a pulse along the link for every call and its answer, busy links growing thicker, agents that breathe while they work and turn amber when they need you
  • Tool Call Card – An agent's tool call in one line – live timer, status and summary, folds open to highlighted arguments and result with copy, retry on errors and a group that sums them up
  • Agent Checkpoints – An agent's run as a line of checkpoints, like git for agents – rewind to any of them and a new attempt branches out of it, while the one it left fades back but stays