✨ Add skill toolset to agent orchestrator

This commit is contained in:
OpenWaygate committed 2026-08-27 23:37:33 +08:00
1 parent 8186963135
commit 25164b0ee0
5 files changed
+40 -9

No files matched your search

+6
View File
@@ -11,6 +11,10 @@ go_library(
"INSTRUCTION_MODIFIER.md",
"INSTRUCTION_ORCHESTRATOR.md",
"INSTRUCTION_RETRIEVAL.md",
"INSTRUCTION.md",
"skills/youtube/SKILL.md",
"skills/youtube/references/seo-guide.md",
"skills/youtube/references/workflows.md",
],
importpath = "github.com/eat-pray-ai/yutu/cmd/agent",
visibility = ["//visibility:public"],
@@ -29,6 +33,8 @@ go_library(
"@org_golang_google_adk_v2//tool",
"@org_golang_google_adk_v2//tool/geminitool",
"@org_golang_google_adk_v2//tool/mcptoolset",
"@org_golang_google_adk_v2//tool/skilltoolset",
"@org_golang_google_adk_v2//tool/skilltoolset/skill",
"@org_golang_google_genai//:genai",
],
)
+1 -1
View File
@@ -3,7 +3,7 @@ user. You are transferred to by the orchestrator with a task description.
You have access to both read and write tools. You can look up channels, search for videos, list comments, list
playlists, list playlist items, list captions, and list subscriptions to gather any context you need — then use write
tools to create or update content. You are self-sufficient for multi-step tasks that involve both data gathering and
tools to create or update content. You are self-sufficient for multistep tasks that involve both data gathering and
content modification.
## Workflow
+4 -4
View File
@@ -9,7 +9,7 @@ You coordinate a multi-agent system with three specialized agents, all invoked v
channel or YouTube in general.
- **Modifier**: Transfer for creating or updating content — posting comments, uploading videos, creating playlists,
updating metadata, setting thumbnails. This agent can also look up channels, videos, comments, and playlists to
gather any context it needs before making modifications. For multi-step tasks that involve both reading and writing,
gather any context it needs before making modifications. For multistep tasks that involve both reading and writing,
transfer directly to Modifier — it is self-sufficient.
- **Destroyer**: Transfer for deleting content — removing videos, playlists, comments, captions, subscriptions. This
agent can verify targets before deletion. Always confirm with the user before transferring to Destroyer.
@@ -18,8 +18,8 @@ You coordinate a multi-agent system with three specialized agents, all invoked v
For every user request, follow this process:
1. **Classify**: Is this a read-only query, a modification, a deletion, or a multi-step workflow?
2. **Plan**: For multi-step tasks, break them into numbered steps and state which agent handles each.
1. **Classify**: Is this a read-only query, a modification, a deletion, or a multistep workflow?
2. **Plan**: For multistep tasks, break them into numbered steps and state which agent handles each.
3. **Route**: Transfer to the appropriate agent with a clear, complete description of the full task. The sub-agent will
respond directly to the user — you do not need to summarize or verify their output.
@@ -29,7 +29,7 @@ For every user request, follow this process:
- Create or update content → Transfer to **Modifier**
- Delete content → Confirm with user first, then transfer to **Destroyer**
### Multi-Step Workflows
### multistep Workflows
When a task requires both reading and writing, **transfer to Modifier directly** with the full task description.
The Modifier agent has read tools and can gather data then act on it in a single flow. Do NOT try to gather data
+7 -1
View File
@@ -156,7 +156,13 @@ func launch(ctx context.Context, writer io.Writer, args []string) {
os.Exit(1)
}
orchestrator, err := buildOrchestrator(advancedModel, liteModel, mcpToolSet)
skillToolset, err := newSkillToolset(ctx)
if err != nil {
slog.ErrorContext(ctx, "failed to create skill toolset", "error", err)
os.Exit(1)
}
orchestrator, err := buildOrchestrator(advancedModel, liteModel, mcpToolSet, skillToolset)
if err != nil {
slog.ErrorContext(ctx, "failed to build orchestrator agent", "error", err)
os.Exit(1)
+22 -3
View File
@@ -4,7 +4,8 @@
package agent
import (
_ "embed"
"context"
"embed"
"fmt"
"os"
@@ -13,9 +14,14 @@ import (
"google.golang.org/adk/v2/model"
"google.golang.org/adk/v2/tool"
"google.golang.org/adk/v2/tool/geminitool"
"google.golang.org/adk/v2/tool/skilltoolset"
"google.golang.org/adk/v2/tool/skilltoolset/skill"
)
var (
//go:embed INSTRUCTION.md
instruction string
//go:embed INSTRUCTION_ORCHESTRATOR.md
orchestratorInstruction string
@@ -27,6 +33,9 @@ var (
//go:embed INSTRUCTION_DESTROYER.md
destroyerInstruction string
//go:embed skills
skillsFS embed.FS
)
type agentDef struct {
@@ -40,7 +49,7 @@ type agentDef struct {
var agentDefs = map[string]agentDef{
"Nina": {
name: "YouTube Copilot",
description: "Orchestrates YouTube workflows by planning multi-step tasks and delegating to specialized agents.",
description: "Orchestrates YouTube workflows by planning multistep tasks and delegating to specialized agents.",
instruction: &orchestratorInstruction,
envKey: "YUTU_AGENT_INSTRUCTION",
},
@@ -170,8 +179,17 @@ func init() {
}
}
func newSkillToolset(ctx context.Context) (tool.Toolset, error) {
source := skill.NewFileSystemSource(skillsFS)
source, _, err := skill.WithCompletePreloadSource(ctx, source)
if err != nil {
return nil, fmt.Errorf("preload skills: %w", err)
}
return skilltoolset.New(ctx, skilltoolset.Config{Source: source})
}
func buildOrchestrator(
advancedModel, liteModel model.LLM, mcpToolSet tool.Toolset,
advancedModel, liteModel model.LLM, mcpToolSet, skillToolset tool.Toolset,
) (
agent.Agent, error,
) {
@@ -210,6 +228,7 @@ func buildOrchestrator(
Description: oDef.description,
Instruction: *oDef.instruction,
Tools: []tool.Tool{geminitool.GoogleSearch{}},
Toolsets: []tool.Toolset{skillToolset},
SubAgents: subAgents,
},
)