package agentrouter import ( "context" "errors" "fmt" ) // Dispatcher 是 Agent 的统一分发器。 type Dispatcher struct { resolver Resolver handlers map[Action]SkillHandler } // NewDispatcher 创建统一分发器。 func NewDispatcher(resolver Resolver) *Dispatcher { return &Dispatcher{ resolver: resolver, handlers: make(map[Action]SkillHandler), } } // Register 注册某个动作的处理函数。 func (d *Dispatcher) Register(action Action, handler SkillHandler) error { if d == nil { return errors.New("dispatcher is nil") } if action == "" { return errors.New("route action is empty") } if handler == nil { return fmt.Errorf("handler for action %s is nil", action) } if _, exists := d.handlers[action]; exists { return fmt.Errorf("handler for action %s already registered", action) } d.handlers[action] = handler return nil } // Dispatch 执行“分流 -> skill handler”完整入口。 func (d *Dispatcher) Dispatch(ctx context.Context, req *AgentRequest) (*AgentResponse, error) { if d == nil || d.resolver == nil { return nil, errors.New("route dispatcher is not ready") } if req == nil { return nil, errors.New("agent request is nil") } // 1. 调用目的:统一先走一级路由,让入口层只关心“请求来了”, // 不需要提前知道这是普通聊天、随口记、任务查询还是后续排程。 decision, err := d.resolver.Resolve(ctx, req) if err != nil { return nil, err } if decision == nil { return nil, errors.New("route decision is nil") } // 2. 路由结果出来后,只根据 action 查找对应 handler。 // 这里故意不做 skill 级 fallback,避免路由层和 skill 内部职责再次缠在一起。 handler, exists := d.handlers[decision.Action] if !exists { return nil, fmt.Errorf("no handler registered for action %s", decision.Action) } return handler(ctx, req) }