package multiagent import ( "context" "fmt" "github.com/cloudwego/eino/adk" "github.com/cloudwego/eino/adk/prebuilt/planexecute" "github.com/cloudwego/eino/components/model" "github.com/cloudwego/eino/schema" ) func newPlanExecuteAgenticExecutor( ctx context.Context, cfg *planexecute.ExecutorConfig, agenticModel model.AgenticModel, handlers []adk.TypedChatModelAgentMiddleware[*schema.AgenticMessage], modelRetryCfg *adk.TypedModelRetryConfig[*schema.AgenticMessage], modelFailoverCfg *adk.ModelFailoverConfig[*schema.AgenticMessage], ) (adk.Agent, error) { if cfg == nil { return nil, fmt.Errorf("plan_execute: ExecutorConfig 为空") } if agenticModel == nil { return nil, fmt.Errorf("plan_execute: Executor AgenticModel 为空") } genInputFn := cfg.GenInputFn if genInputFn == nil { genInputFn = planExecuteDefaultGenExecutorInput } genInput := func(ctx context.Context, instruction string, _ *adk.TypedAgentInput[*schema.AgenticMessage]) ([]*schema.AgenticMessage, error) { plan, ok := adk.GetSessionValue(ctx, planexecute.PlanSessionKey) if !ok { return nil, fmt.Errorf("plan_execute executor: session value %q missing (possible session corruption)", planexecute.PlanSessionKey) } plan_, ok := plan.(planexecute.Plan) if !ok { return nil, fmt.Errorf("plan_execute executor: session value %q has invalid type %T", planexecute.PlanSessionKey, plan) } userInput, ok := adk.GetSessionValue(ctx, planexecute.UserInputSessionKey) if !ok { return nil, fmt.Errorf("plan_execute executor: session value %q missing (possible session corruption)", planexecute.UserInputSessionKey) } userInput_, ok := userInput.([]adk.Message) if !ok { return nil, fmt.Errorf("plan_execute executor: session value %q has invalid type %T", planexecute.UserInputSessionKey, userInput) } var executedSteps_ []planexecute.ExecutedStep executedStep, ok := adk.GetSessionValue(ctx, planexecute.ExecutedStepsSessionKey) if ok { executedSteps_, ok = executedStep.([]planexecute.ExecutedStep) if !ok { return nil, fmt.Errorf("plan_execute executor: session value %q has invalid type %T", planexecute.ExecutedStepsSessionKey, executedStep) } } in := &planexecute.ExecutionContext{ UserInput: userInput_, Plan: plan_, ExecutedSteps: executedSteps_, } msgs, err := genInputFn(ctx, in) if err != nil { return nil, err } if instruction != "" { msgs = normalizeSingleLeadingSystemMessage(msgs, instruction) } return EinoMessagesToAgentic(msgs), nil } agentCfg := einoAgenticChatModelAgentConfig{ Name: "executor", Description: "an executor agent", Model: agenticModel, ToolsConfig: cfg.ToolsConfig, GenModelInput: genInput, MaxIterations: cfg.MaxIterations, OutputKey: planexecute.ExecutedStepSessionKey, Handlers: handlers, ModelRetryConfig: modelRetryCfg, ModelFailoverConfig: modelFailoverCfg, } return newEinoAgenticChatModelAgentAdapter(ctx, agentCfg) } // planExecuteDefaultGenExecutorInput 对齐 Eino planexecute.defaultGenExecutorInputFn(包外不可引用默认实现)。 func planExecuteDefaultGenExecutorInput(ctx context.Context, in *planexecute.ExecutionContext) ([]adk.Message, error) { planContent, err := in.Plan.MarshalJSON() if err != nil { return nil, err } return planexecute.ExecutorPrompt.Format(ctx, map[string]any{ "input": planExecuteFormatInput(in.UserInput), "plan": string(planContent), "executed_steps": planExecuteFormatExecutedSteps(in.ExecutedSteps, nil, nil), "step": in.Plan.FirstStep(), }) }