All files / renderer/village agentLabels.ts

100% Statements 16/16
100% Branches 8/8
100% Functions 2/2
100% Lines 16/16

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46                                            1x 6x 6x 6x 15x 4x 15x 11x 11x 11x 15x 6x 6x               1x 4x 4x  
/**
 * Compute readable display names for every agent in a session.
 *
 * The raw `agent.id` is either the session id (for the main agent, which is
 * a UUID in production) or `${sessionId}:${tool_use_id}` for subagents. Neither
 * is pleasant to read above a character's head. This helper turns them into
 * short stable labels:
 *
 *   - main  agent -> "Mayor"
 *   - subagents  -> "Agent 1", "Agent 2", ...  (1-based, ordered by first
 *     appearance in the agents Map - `Map` preserves insertion order, and the
 *     session store adds subagents exactly once each, so the ordering is
 *     stable for the lifetime of the session).
 *
 * The function is pure: same input Map -> same output Map. It never mutates
 * the input. Callers pass the result down to the `Character`/tooltip
 * components so the naming logic lives in one place.
 */
import type { AgentState } from "../../shared/types";
 
export type AgentLabelMap = Map<string, string>;
 
export function buildAgentLabels(agents: Iterable<AgentState>): AgentLabelMap {
  const labels: AgentLabelMap = new Map();
  let subagentIndex = 0;
  for (const agent of agents) {
    if (agent.kind === "main") {
      labels.set(agent.id, "Mayor");
    } else {
      subagentIndex += 1;
      labels.set(agent.id, `Agent ${subagentIndex}`);
    }
  }
  return labels;
}
 
/**
 * Convenience lookup with a readable fallback. Used by components that may
 * render before the labels map has been recomputed (e.g. during a transient
 * mid-frame state). Falls back to "Agent" so the UI never shows an empty
 * bubble.
 */
export function labelFor(labels: AgentLabelMap, agent: AgentState): string {
  return labels.get(agent.id) ?? (agent.kind === "main" ? "Mayor" : "Agent");
}