fix: auto-create agent bead when bd agent state called on non-existent agent
Previously, `bd agent state <agent> <state>` would fail if the agent bead didn't exist in the database. This caused issues when `gt sling` tried to update agent state for newly spawned polecats. Now when the agent doesn't exist: 1. Parse role_type and rig from the agent ID (e.g., gt-gastown-polecat-nux) 2. Auto-create the agent bead with type=agent 3. Add role_type and rig labels for filtering (bd list --label=role_type:polecat) 4. Continue with the state update This enables: - Work history accumulation per polecat name - Skill/success tracking over time - `bd list --type=agent` to see all agents 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -48,3 +48,95 @@ func TestFormatTimeOrNil(t *testing.T) {
|
||||
t.Errorf("expected nil for nil time, got %v", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseAgentIDFields(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
agentID string
|
||||
wantRoleType string
|
||||
wantRig string
|
||||
}{
|
||||
// Town-level roles
|
||||
{
|
||||
name: "town-level mayor",
|
||||
agentID: "gt-mayor",
|
||||
wantRoleType: "mayor",
|
||||
wantRig: "",
|
||||
},
|
||||
{
|
||||
name: "town-level deacon",
|
||||
agentID: "bd-deacon",
|
||||
wantRoleType: "deacon",
|
||||
wantRig: "",
|
||||
},
|
||||
// Per-rig singleton roles
|
||||
{
|
||||
name: "rig-level witness",
|
||||
agentID: "gt-gastown-witness",
|
||||
wantRoleType: "witness",
|
||||
wantRig: "gastown",
|
||||
},
|
||||
{
|
||||
name: "rig-level refinery",
|
||||
agentID: "bd-beads-refinery",
|
||||
wantRoleType: "refinery",
|
||||
wantRig: "beads",
|
||||
},
|
||||
// Per-rig named roles
|
||||
{
|
||||
name: "named polecat",
|
||||
agentID: "gt-gastown-polecat-nux",
|
||||
wantRoleType: "polecat",
|
||||
wantRig: "gastown",
|
||||
},
|
||||
{
|
||||
name: "named crew",
|
||||
agentID: "bd-beads-crew-dave",
|
||||
wantRoleType: "crew",
|
||||
wantRig: "beads",
|
||||
},
|
||||
{
|
||||
name: "polecat with hyphenated name",
|
||||
agentID: "gt-gastown-polecat-nux-123",
|
||||
wantRoleType: "polecat",
|
||||
wantRig: "gastown",
|
||||
},
|
||||
// Edge cases
|
||||
{
|
||||
name: "no hyphen",
|
||||
agentID: "invalid",
|
||||
wantRoleType: "",
|
||||
wantRig: "",
|
||||
},
|
||||
{
|
||||
name: "empty string",
|
||||
agentID: "",
|
||||
wantRoleType: "",
|
||||
wantRig: "",
|
||||
},
|
||||
{
|
||||
name: "unknown role",
|
||||
agentID: "gt-gastown-unknown",
|
||||
wantRoleType: "",
|
||||
wantRig: "",
|
||||
},
|
||||
{
|
||||
name: "prefix only",
|
||||
agentID: "gt-",
|
||||
wantRoleType: "",
|
||||
wantRig: "",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
gotRoleType, gotRig := parseAgentIDFields(tt.agentID)
|
||||
if gotRoleType != tt.wantRoleType {
|
||||
t.Errorf("parseAgentIDFields(%q) roleType = %q, want %q", tt.agentID, gotRoleType, tt.wantRoleType)
|
||||
}
|
||||
if gotRig != tt.wantRig {
|
||||
t.Errorf("parseAgentIDFields(%q) rig = %q, want %q", tt.agentID, gotRig, tt.wantRig)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user