feat: implement multi-bot orchestration system with LLM routing
Implementa el sistema de orquestación para salas Matrix con múltiples bots. El orquestador es un "special agent" sin identidad Matrix que coordina qué bot responde y cuándo, usando LLM (Claude) para routing y evaluación de calidad. Cambios principales: - pkg/orchestration/task.go: tipos puros (TaskEvent, BotResponse, QualityScore, RoutingDecision) - shell/orchestration/: runtime del orquestador (orchestrator.go, router.go, evaluator.go) - agents/specials/orchestrator/: config + prompts (routing, quality, refinement) - internal/config/: SpecialConfig, OrchestrationCfg, LoadSpecial() - shell/bus/bus.go: protocolo request-reply (SendAndWait, Reply) para delegación - shell/matrix/listener.go: InterceptFunc para interceptar eventos en salas orquestadas - agents/runtime.go: SetBus, listenBus, handleTaskEvent para recibir tareas del orquestador - cmd/launcher/main.go: creación de bus compartido, arranque del orquestador antes de bots Incluye deduplicación para evitar que múltiples listeners en la misma sala disparen el orquestador más de una vez por mensaje. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -47,6 +47,42 @@ func LoadMeta(path string) (*AgentConfig, error) {
|
||||
return &cfg, nil
|
||||
}
|
||||
|
||||
// LoadSpecial reads and parses a special agent config file.
|
||||
// Special agents have no Matrix identity so validation is lighter.
|
||||
func LoadSpecial(path string) (*SpecialConfig, error) {
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read special config %s: %w", path, err)
|
||||
}
|
||||
|
||||
expanded := os.ExpandEnv(string(data))
|
||||
|
||||
var cfg SpecialConfig
|
||||
if err := yaml.Unmarshal([]byte(expanded), &cfg); err != nil {
|
||||
return nil, fmt.Errorf("parse special config %s: %w", path, err)
|
||||
}
|
||||
|
||||
if err := validateSpecial(&cfg); err != nil {
|
||||
return nil, fmt.Errorf("invalid special config %s: %w", path, err)
|
||||
}
|
||||
|
||||
return &cfg, nil
|
||||
}
|
||||
|
||||
// validateSpecial applies sanity checks for special agent configs.
|
||||
func validateSpecial(cfg *SpecialConfig) error {
|
||||
if cfg.Special.ID == "" {
|
||||
return fmt.Errorf("special.id is required")
|
||||
}
|
||||
if cfg.Special.Type == "" {
|
||||
return fmt.Errorf("special.type is required")
|
||||
}
|
||||
if cfg.LLM.Primary.Provider == "" {
|
||||
return fmt.Errorf("llm.primary.provider is required")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// validate applies basic sanity checks.
|
||||
func validate(cfg *AgentConfig) error {
|
||||
if cfg.Agent.ID == "" {
|
||||
|
||||
@@ -398,3 +398,34 @@ type MemoryCfg struct {
|
||||
type MemoryToolCfg struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
}
|
||||
|
||||
// ── Special Agents ────────────────────────────────────────────────────────
|
||||
|
||||
// SpecialConfig is the root configuration for a special agent (no Matrix identity).
|
||||
type SpecialConfig struct {
|
||||
Special SpecialMeta `yaml:"special"`
|
||||
LLM LLMCfg `yaml:"llm"`
|
||||
Orchestration OrchestrationCfg `yaml:"orchestration"`
|
||||
}
|
||||
|
||||
// SpecialMeta identifies a special agent.
|
||||
type SpecialMeta struct {
|
||||
ID string `yaml:"id"`
|
||||
Type string `yaml:"type"` // "orchestrator", "scheduler", etc.
|
||||
Enabled bool `yaml:"enabled"`
|
||||
Description string `yaml:"description"`
|
||||
}
|
||||
|
||||
// OrchestrationCfg configures the multi-bot orchestrator.
|
||||
type OrchestrationCfg struct {
|
||||
MaxIterations int `yaml:"max_iterations"`
|
||||
QualityThreshold float64 `yaml:"quality_threshold"`
|
||||
DelegationTimeout time.Duration `yaml:"delegation_timeout"`
|
||||
Rooms []OrchestratedRoomCfg `yaml:"rooms"`
|
||||
}
|
||||
|
||||
// OrchestratedRoomCfg defines a room managed by the orchestrator.
|
||||
type OrchestratedRoomCfg struct {
|
||||
RoomID string `yaml:"room_id"`
|
||||
Participants []string `yaml:"participants"` // bot IDs that participate in this room
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user