1 parent
9371d0d6b4
commit
fa3426588a
7 files changed
+190
-64
No files matched your search
@@ -3,7 +3,6 @@
|
||||
*.json
|
||||
*.mp4
|
||||
*.jpg
|
||||
*.md
|
||||
.mcpregistry_github_token
|
||||
.mcpregistry_registry_token
|
||||
.env
|
||||
|
||||
@@ -18,6 +18,7 @@ go_library(
|
||||
deps = [
|
||||
"//cmd",
|
||||
"//cmd/activity",
|
||||
"//cmd/agent",
|
||||
"//cmd/caption",
|
||||
"//cmd/channel",
|
||||
"//cmd/channelBanner",
|
||||
|
||||
@@ -3,13 +3,11 @@ load("@rules_go//go:def.bzl", "go_library")
|
||||
go_library(
|
||||
name = "cmd",
|
||||
srcs = [
|
||||
"agent.go",
|
||||
"auth.go",
|
||||
"mcp.go",
|
||||
"root.go",
|
||||
"version.go",
|
||||
],
|
||||
embedsrcs = ["INSTRUCTION.md"],
|
||||
importpath = "github.com/eat-pray-ai/yutu/cmd",
|
||||
visibility = ["//visibility:public"],
|
||||
x_defs = {
|
||||
@@ -27,13 +25,5 @@ go_library(
|
||||
"@com_github_savioxavier_termlink//:termlink",
|
||||
"@com_github_spf13_cobra//:cobra",
|
||||
"@com_github_spf13_viper//:viper",
|
||||
"@org_golang_google_adk//agent",
|
||||
"@org_golang_google_adk//agent/llmagent",
|
||||
"@org_golang_google_adk//cmd/launcher",
|
||||
"@org_golang_google_adk//cmd/launcher/full",
|
||||
"@org_golang_google_adk//model/gemini",
|
||||
"@org_golang_google_adk//tool",
|
||||
"@org_golang_google_adk//tool/mcptoolset",
|
||||
"@org_golang_google_genai//:genai",
|
||||
],
|
||||
)
|
||||
@@ -0,0 +1,26 @@
|
||||
load("@rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "agent",
|
||||
srcs = [
|
||||
"agent.go",
|
||||
"console.go",
|
||||
"web.go",
|
||||
],
|
||||
embedsrcs = ["INSTRUCTION.md"],
|
||||
importpath = "github.com/eat-pray-ai/yutu/cmd/agent",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//cmd",
|
||||
"@com_github_modelcontextprotocol_go_sdk//mcp",
|
||||
"@com_github_spf13_cobra//:cobra",
|
||||
"@org_golang_google_adk//agent",
|
||||
"@org_golang_google_adk//agent/llmagent",
|
||||
"@org_golang_google_adk//cmd/launcher",
|
||||
"@org_golang_google_adk//cmd/launcher/full",
|
||||
"@org_golang_google_adk//model/gemini",
|
||||
"@org_golang_google_adk//tool",
|
||||
"@org_golang_google_adk//tool/mcptoolset",
|
||||
"@org_golang_google_genai//:genai",
|
||||
],
|
||||
)
|
||||
+69
-53
@@ -4,9 +4,11 @@
|
||||
package agent
|
||||
|
||||
import (
|
||||
"context"
|
||||
_ "embed"
|
||||
"log/slog"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
rootCmd "github.com/eat-pray-ai/yutu/cmd"
|
||||
"github.com/modelcontextprotocol/go-sdk/mcp"
|
||||
@@ -29,74 +31,88 @@ const (
|
||||
var (
|
||||
//go:embed INSTRUCTION.md
|
||||
instruction string
|
||||
|
||||
streamingMode string
|
||||
idleTimeout time.Duration
|
||||
port int
|
||||
readTimeout time.Duration
|
||||
writeTimeout time.Duration
|
||||
sublaunchers []string
|
||||
sseWriteTimeout time.Duration
|
||||
webuiAddress string
|
||||
a2aAgentURL string
|
||||
apiServerAddress string
|
||||
)
|
||||
|
||||
var agentCmd = &cobra.Command{
|
||||
Use: "agent",
|
||||
Short: agentShort,
|
||||
Long: agentLong,
|
||||
PreRun: func(cmd *cobra.Command, args []string) {
|
||||
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
||||
envInstruction, ok := os.LookupEnv("YUTU_AGENT_INSTRUCTION")
|
||||
if ok && envInstruction != "" {
|
||||
instruction = envInstruction
|
||||
}
|
||||
},
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
ctx := cmd.Context()
|
||||
m, err := gemini.NewModel(
|
||||
ctx, os.Getenv("GEMINI_MODEL"), &genai.ClientConfig{
|
||||
APIKey: os.Getenv("GEMINI_API_KEY"),
|
||||
Backend: genai.BackendGeminiAPI,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
slog.ErrorContext(ctx, "failed to create Gemini model", "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
clientTransport, serverTransport := mcp.NewInMemoryTransports()
|
||||
_, err = rootCmd.Server.Connect(ctx, serverTransport, nil)
|
||||
if err != nil {
|
||||
slog.ErrorContext(ctx, "failed to connect to MCP server", "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
mcpToolSet, err := mcptoolset.New(
|
||||
mcptoolset.Config{
|
||||
Transport: clientTransport,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
slog.ErrorContext(ctx, "failed to create MCP tool set", "error", err)
|
||||
}
|
||||
|
||||
a, err := llmagent.New(
|
||||
llmagent.Config{
|
||||
Model: m,
|
||||
Name: "YouTube Copilot",
|
||||
Instruction: instruction,
|
||||
Toolsets: []tool.Toolset{mcpToolSet},
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
slog.ErrorContext(ctx, "failed to create LLM agent", "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
config := &launcher.Config{
|
||||
AgentLoader: agent.NewSingleLoader(a),
|
||||
}
|
||||
l := full.NewLauncher()
|
||||
if err := l.Execute(ctx, config, os.Args[2:]); err != nil {
|
||||
slog.ErrorContext(
|
||||
ctx, "failed to launch agent",
|
||||
"launch", l.CommandLineSyntax(), "error", err,
|
||||
)
|
||||
os.Exit(1)
|
||||
}
|
||||
_ = cmd.Help()
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
rootCmd.RootCmd.AddCommand(agentCmd)
|
||||
}
|
||||
|
||||
func launch(ctx context.Context, args []string) {
|
||||
m, err := gemini.NewModel(
|
||||
ctx, os.Getenv("GEMINI_MODEL"), &genai.ClientConfig{
|
||||
APIKey: os.Getenv("GEMINI_API_KEY"),
|
||||
Backend: genai.BackendGeminiAPI,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
slog.ErrorContext(ctx, "failed to create Gemini model", "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
clientTransport, serverTransport := mcp.NewInMemoryTransports()
|
||||
_, err = rootCmd.Server.Connect(ctx, serverTransport, nil)
|
||||
if err != nil {
|
||||
slog.ErrorContext(ctx, "failed to connect to MCP server", "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
mcpToolSet, err := mcptoolset.New(
|
||||
mcptoolset.Config{
|
||||
Transport: clientTransport,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
slog.ErrorContext(ctx, "failed to create MCP tool set", "error", err)
|
||||
}
|
||||
|
||||
a, err := llmagent.New(
|
||||
llmagent.Config{
|
||||
Model: m,
|
||||
Name: "YouTube Copilot",
|
||||
Instruction: instruction,
|
||||
Toolsets: []tool.Toolset{mcpToolSet},
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
slog.ErrorContext(ctx, "failed to create LLM agent", "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
config := &launcher.Config{
|
||||
AgentLoader: agent.NewSingleLoader(a),
|
||||
}
|
||||
l := full.NewLauncher()
|
||||
if err := l.Execute(ctx, config, args); err != nil {
|
||||
slog.ErrorContext(
|
||||
ctx, "failed to launch agent",
|
||||
"launch", l.CommandLineSyntax(), "error", err,
|
||||
)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
// Copyright 2026 eat-pray-ai & OpenWaygate
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package agent
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
const (
|
||||
consoleShort = "Start agent in console mode"
|
||||
consoleLong = "Start agent in console mode"
|
||||
)
|
||||
|
||||
var consoleCmd = &cobra.Command{
|
||||
Use: "console",
|
||||
Short: consoleShort,
|
||||
Long: consoleLong,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
launcherArgs := []string{"console"}
|
||||
if streamingMode != "" {
|
||||
launcherArgs = append(launcherArgs, "-streaming_mode", streamingMode)
|
||||
}
|
||||
launch(cmd.Context(), launcherArgs)
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
agentCmd.AddCommand(consoleCmd)
|
||||
consoleCmd.Flags().StringVarP(&streamingMode, "streamingMode", "m", "sse", "defines streaming mode: none|sse")
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
// Copyright 2026 eat-pray-ai & OpenWaygate
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package agent
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var webCmd = &cobra.Command{
|
||||
Use: "web",
|
||||
Short: "Start agent in web mode",
|
||||
Long: "start agent in web mode with additional sub-servers specified by sublaunchers",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
launcherArgs := []string{"web"}
|
||||
|
||||
launcherArgs = append(launcherArgs, "-idle-timeout", idleTimeout.String())
|
||||
launcherArgs = append(launcherArgs, "-port", strconv.Itoa(port))
|
||||
launcherArgs = append(launcherArgs, "-read-timeout", readTimeout.String())
|
||||
launcherArgs = append(launcherArgs, "-write-timeout", writeTimeout.String())
|
||||
|
||||
if slices.Contains(sublaunchers, "api") {
|
||||
launcherArgs = append(
|
||||
launcherArgs, "api",
|
||||
"-sse-write-timeout", sseWriteTimeout.String(),
|
||||
"-webui_address", webuiAddress,
|
||||
)
|
||||
}
|
||||
if slices.Contains(sublaunchers, "a2a") {
|
||||
launcherArgs = append(launcherArgs, "a2a", "-a2a_agent_url", a2aAgentURL)
|
||||
}
|
||||
if slices.Contains(sublaunchers, "webui") {
|
||||
launcherArgs = append(launcherArgs, "webui", "-api_server_address", apiServerAddress)
|
||||
}
|
||||
|
||||
launch(cmd.Context(), launcherArgs)
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
agentCmd.AddCommand(webCmd)
|
||||
|
||||
// web flags
|
||||
webCmd.Flags().DurationVarP(&idleTimeout, "idleTimeout", "i", time.Minute, "Server idle timeout")
|
||||
webCmd.Flags().IntVarP(&port, "port", "p", 8080, "Localhost port for the server")
|
||||
webCmd.Flags().DurationVarP(&readTimeout, "readTimeout", "r", 15*time.Second, "Server read timeout")
|
||||
webCmd.Flags().DurationVarP(&writeTimeout, "writeTimeout", "w", 15*time.Second, "Server write timeout")
|
||||
webCmd.Flags().StringSliceVarP(&sublaunchers, "sublaunchers", "l", []string{"api"}, "One or more sublaunchers: api, a2a, and webui")
|
||||
|
||||
// api flags
|
||||
webCmd.Flags().DurationVarP(&sseWriteTimeout, "sseWriteTimeout", "s", 2*time.Minute, "SSE server write timeout")
|
||||
webCmd.Flags().StringVarP(&webuiAddress, "webuiAddress", "W", "localhost:8080", "ADK WebUI address")
|
||||
|
||||
// a2a flags
|
||||
webCmd.Flags().StringVarP(&a2aAgentURL, "a2aAgentUrl", "u", "http://localhost:8080", "A2A host URL")
|
||||
|
||||
// webui flags
|
||||
webCmd.Flags().StringVarP(&apiServerAddress, "apiServerAddress", "U", "http://localhost:8080/api", "ADK REST API server address")
|
||||
}
|
||||
Reference in new issue
Block a user