Naalya Handbook
Recipes

Label an AI Tool Call

Make an AI tool call show a friendly line in Rover's activity timeline by registering its name, states and icon in one map.

When Rover does real work, it does it by calling toolslist_staff, create_department, get_current_date. As each call runs, the activity timeline should narrate it: "Looking through staff…" while it works, then "Listed staff" when it lands. That narration isn't automatic. It comes from one map that turns a raw tool name into a human sentence and an icon.

That map is src/components/rover/activity/tool-labels.ts, and adding a row to it is the whole Hub-side recipe. The backend how-to that should run first is Adding an RPC tool (or a local tool).

Unregistered tools still render — badly for some verbs

Unlike the old chat map, an unlabelled tool is not invisible. describeActivity falls back to verb derivation (list_dormitories → "Listing dormitories…"). That is fine for list/get/create. Verbs like upsert, publish, and recompute read as "Ran upsert…". Treat a row as mandatory for those.

How the key is built

The map is keyed by the tool name from the API definition — create_department, not the RPC event create.department, and not a tool- prefix.

src/components/rover/activity/tool-labels.ts
type ToolLabel = {
  running: string
  done: string
  icon: IconSvgElement
}

const TOOL_LABELS: Record<string, ToolLabel> = {
  list_staff: {
    running: 'Looking through staff…',
    done: 'Listed staff',
    icon: UserGroupIcon,
  },
  // ...one row per tool
}

There is no error string. Failed calls are hidden from the timeline; Rover explains them in the reply.

Step 1: Get the tool's name

Copy name from defineAgentTool({ name: 'create_department', … }) or from the local tool({ name: 'get_current_date', … }). If the tool is create_department, the key is create_department.

Trigger it once in chat if you are unsure — the activity line's fallback text is derived from that same name.

Step 2: Add the entry

src/components/rover/activity/tool-labels.ts
create_department: {
  running: 'Creating a department…',
  done: 'Created a department',
  icon: PlusSignIcon,
},

Keep the house tense — running is present-continuous and ends in an ellipsis, done is past tense. Add the Hugeicon to the import at the top of the file.

Step 3: Pick the icon by verb

Match neighbours in the same file so the timeline stays legible at a glance.

The tool…Typical icon
Lists / searchesUserGroupIcon, DatabaseLightningIcon, Search02Icon
Reads oneNote01Icon
Creates / addsPlusSignIcon
UpdatesEdit02Icon
RemovesDelete02Icon

Write the sentence for the person, not the API

The done string is what a school admin actually reads — "Created a department", not "create.department ok". The tool name is plumbing; the label is product copy.

Where to go next

On this page