/* * Copyright 2025 CloudWeGo Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package main import ( "context" "fmt" "github.com/cloudwego/eino/adk" "github.com/cloudwego/eino/adk/prebuilt/supervisor" "github.com/cloudwego/eino/components/tool" "github.com/cloudwego/eino/compose" "github.com/cloudwego/eino-examples/adk/common/model" "github.com/cloudwego/eino-examples/flow/agent/multiagent/plan_execute/tools" ) func buildSearchAgent(ctx context.Context) (adk.Agent, error) { m := model.NewChatModel() type searchReq struct { Query string `json:"query"` } type searchResp struct { Result string `json:"result"` } search := func(ctx context.Context, req *searchReq) (*searchResp, error) { return &searchResp{ Result: "In 2024, the US GDP was $29.18 trillion and New York State's GDP was $2.297 trillion", }, nil } searchTool, err := tools.SafeInferTool("search", "search the internet for info", search) if err != nil { return nil, err } return adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{ Name: "research_agent", Description: "the agent responsible to search the internet for info", Instruction: ` You are a research agent. INSTRUCTIONS: - Assist ONLY with research-related tasks, DO NOT do any math - After you're done with your tasks, respond to the supervisor directly - Respond ONLY with the results of your work, do NOT include ANY other text.`, Model: m, ToolsConfig: adk.ToolsConfig{ ToolsNodeConfig: compose.ToolsNodeConfig{ Tools: []tool.BaseTool{searchTool}, UnknownToolsHandler: func(ctx context.Context, name, input string) (string, error) { return fmt.Sprintf("unknown tool: %s", name), nil }, }, }, }) } func buildMathAgent(ctx context.Context) (adk.Agent, error) { m := model.NewChatModel() type addReq struct { A float64 `json:"a"` B float64 `json:"b"` } type addResp struct { Result float64 } add := func(ctx context.Context, req *addReq) (*addResp, error) { return &addResp{ Result: req.A + req.B, }, nil } addTool, err := tools.SafeInferTool("add", "add two numbers", add) if err != nil { return nil, err } type multiplyReq struct { A float64 `json:"a"` B float64 `json:"b"` } type multiplyResp struct { Result float64 } multiply := func(ctx context.Context, req *multiplyReq) (*multiplyResp, error) { return &multiplyResp{ Result: req.A * req.B, }, nil } multiplyTool, err := tools.SafeInferTool("multiply", "multiply two numbers", multiply) if err != nil { return nil, err } type divideReq struct { A float64 `json:"a"` B float64 `json:"b"` } type divideResp struct { Result float64 } divide := func(ctx context.Context, req *divideReq) (*divideResp, error) { return ÷Resp{ Result: req.A / req.B, }, nil } divideTool, err := tools.SafeInferTool("divide", "divide two numbers", divide) if err != nil { return nil, err } return adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{ Name: "math_agent", Description: "the agent responsible to do math", Instruction: ` You are a math agent. INSTRUCTIONS: - Assist ONLY with math-related tasks - After you're done with your tasks, respond to the supervisor directly - Respond ONLY with the results of your work, do NOT include ANY other text.`, Model: m, ToolsConfig: adk.ToolsConfig{ ToolsNodeConfig: compose.ToolsNodeConfig{ Tools: []tool.BaseTool{addTool, multiplyTool, divideTool}, UnknownToolsHandler: func(ctx context.Context, name, input string) (string, error) { return fmt.Sprintf("unknown tool: %s", name), nil }, }, }, }) } func buildSupervisor(ctx context.Context) (adk.Agent, error) { m := model.NewChatModel() sv, err := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{ Name: "supervisor", Description: "the agent responsible to supervise tasks", Instruction: ` You are a supervisor managing two agents: - a research agent. Assign research-related tasks to this agent - a math agent. Assign math-related tasks to this agent Assign work to one agent at a time, do not call agents in parallel. Do not do any work yourself.`, Model: m, Exit: &adk.ExitTool{}, }) if err != nil { return nil, err } searchAgent, err := buildSearchAgent(ctx) if err != nil { return nil, err } mathAgent, err := buildMathAgent(ctx) if err != nil { return nil, err } return supervisor.New(ctx, &supervisor.Config{ Supervisor: sv, SubAgents: []adk.Agent{searchAgent, mathAgent}, }) }