πŸ“„ File detail

utils/agentId.ts

🧩 .tsπŸ“ 100 linesπŸ’Ύ 2,805 bytesπŸ“ text
← Back to All Files

🎯 Use case

This file lives under β€œutils/”, which covers cross-cutting helpers (shell, tempfiles, settings, messages, process input, …). On the API surface it exposes formatAgentId, parseAgentId, generateRequestId, and parseRequestId β€” mainly functions, hooks, or classes. What the file header says: Deterministic Agent ID System This module provides helper functions for formatting and parsing deterministic agent IDs used in the swarm/teammate system. ## ID Formats **Agent IDs**: `agentName@teamName` - Example: `team-lead@my-project`, `researcher@my-project` - The @ symbol ac.

Generated from folder role, exports, dependency roots, and inline comments β€” not hand-reviewed for every path.

🧠 Inline summary

Deterministic Agent ID System This module provides helper functions for formatting and parsing deterministic agent IDs used in the swarm/teammate system. ## ID Formats **Agent IDs**: `agentName@teamName` - Example: `team-lead@my-project`, `researcher@my-project` - The @ symbol acts as a separator between agent name and team name **Request IDs**: `{requestType}-{timestamp}@{agentId}` - Example: `shutdown-1702500000000@researcher@my-project` - Used for shutdown requests, plan approvals, etc. ## Why Deterministic IDs? Deterministic IDs provide several benefits: 1. **Reproducibility**: The same agent spawned with the same name in the same team always gets the same ID, enabling reconnection after crashes/restarts. 2. **Human-readable**: IDs are meaningful and debuggable (e.g., `tester@my-project`). 3. **Predictable**: Team leads can compute a teammate's ID without looking it up, simplifying message routing and task assignment. ## Constraints - Agent names must NOT contain `@` (it's used as the separator) - Use `sanitizeAgentName()` from TeammateTool.ts to strip @ from names

πŸ“€ Exports (heuristic)

  • formatAgentId
  • parseAgentId
  • generateRequestId
  • parseRequestId

πŸ–₯️ Source preview

/**
 * Deterministic Agent ID System
 *
 * This module provides helper functions for formatting and parsing deterministic
 * agent IDs used in the swarm/teammate system.
 *
 * ## ID Formats
 *
 * **Agent IDs**: `agentName@teamName`
 * - Example: `team-lead@my-project`, `researcher@my-project`
 * - The @ symbol acts as a separator between agent name and team name
 *
 * **Request IDs**: `{requestType}-{timestamp}@{agentId}`
 * - Example: `shutdown-1702500000000@researcher@my-project`
 * - Used for shutdown requests, plan approvals, etc.
 *
 * ## Why Deterministic IDs?
 *
 * Deterministic IDs provide several benefits:
 *
 * 1. **Reproducibility**: The same agent spawned with the same name in the same team
 *    always gets the same ID, enabling reconnection after crashes/restarts.
 *
 * 2. **Human-readable**: IDs are meaningful and debuggable (e.g., `tester@my-project`).
 *
 * 3. **Predictable**: Team leads can compute a teammate's ID without looking it up,
 *    simplifying message routing and task assignment.
 *
 * ## Constraints
 *
 * - Agent names must NOT contain `@` (it's used as the separator)
 * - Use `sanitizeAgentName()` from TeammateTool.ts to strip @ from names
 */

/**
 * Formats an agent ID in the format `agentName@teamName`.
 */
export function formatAgentId(agentName: string, teamName: string): string {
  return `${agentName}@${teamName}`
}

/**
 * Parses an agent ID into its components.
 * Returns null if the ID doesn't contain the @ separator.
 */
export function parseAgentId(
  agentId: string,
): { agentName: string; teamName: string } | null {
  const atIndex = agentId.indexOf('@')
  if (atIndex === -1) {
    return null
  }
  return {
    agentName: agentId.slice(0, atIndex),
    teamName: agentId.slice(atIndex + 1),
  }
}

/**
 * Formats a request ID in the format `{requestType}-{timestamp}@{agentId}`.
 */
export function generateRequestId(
  requestType: string,
  agentId: string,
): string {
  const timestamp = Date.now()
  return `${requestType}-${timestamp}@${agentId}`
}

/**
 * Parses a request ID into its components.
 * Returns null if the request ID doesn't match the expected format.
 */
export function parseRequestId(
  requestId: string,
): { requestType: string; timestamp: number; agentId: string } | null {
  const atIndex = requestId.indexOf('@')
  if (atIndex === -1) {
    return null
  }

  const prefix = requestId.slice(0, atIndex)
  const agentId = requestId.slice(atIndex + 1)

  const lastDashIndex = prefix.lastIndexOf('-')
  if (lastDashIndex === -1) {
    return null
  }

  const requestType = prefix.slice(0, lastDashIndex)
  const timestampStr = prefix.slice(lastDashIndex + 1)
  const timestamp = parseInt(timestampStr, 10)

  if (isNaN(timestamp)) {
    return null
  }

  return { requestType, timestamp, agentId }
}