// Package agents provides a global registry for agent rule factories. // // Each agent package self-registers via init() using Register. // The launcher retrieves rules via GetRules without importing agent // packages explicitly (only blank imports are needed). package devagents import ( "sync" "github.com/enmanuel/agents/pkg/decision" ) // RulesFunc is a factory that returns the decision rules for an agent. type RulesFunc func() []decision.Rule var ( registryMu sync.RWMutex registry = make(map[string]RulesFunc) ) // Register adds a rule factory for the given agent ID. // Intended to be called from init() in each agent package. // Panics if the same ID is registered twice (catches copy-paste errors early). func Register(id string, fn RulesFunc) { registryMu.Lock() defer registryMu.Unlock() if _, exists := registry[id]; exists { panic("agents.Register: duplicate agent id: " + id) } registry[id] = fn } // GetRules returns the rule factory for the given agent ID. // Returns nil if no rules are registered (the agent is command-only). func GetRules(id string) RulesFunc { registryMu.RLock() defer registryMu.RUnlock() return registry[id] } // RegisteredIDs returns a sorted list of all registered agent IDs. // Useful for debugging and diagnostics. func RegisteredIDs() []string { registryMu.RLock() defer registryMu.RUnlock() ids := make([]string, 0, len(registry)) for id := range registry { ids = append(ids, id) } return ids } // resetRegistry clears all registrations (for testing only). func resetRegistry() { registryMu.Lock() defer registryMu.Unlock() registry = make(map[string]RulesFunc) }