forked from sanbuphy/learn-coding-agent
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathagentId.ts
More file actions
99 lines (90 loc) · 2.74 KB
/
agentId.ts
File metadata and controls
99 lines (90 loc) · 2.74 KB
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/**
* 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 }
}