Template
- AGENT_BOUNDARIES.md: egress allow-list, FS scope, approved/forbidden ops - agent-policy.yaml: k8s NetworkPolicy scoping egress to LiteLLM/brain-mcp/ gitea-mcp/OTLP + default-deny baseline - internal/agent/agent.go: thin ADK runner wrapper (Config + Run) - Dockerfile: distroless multi-stage build, entrypoint cmd/__PROJECT_NAME__ - .gitea/workflows/cd.yml: check → buildah build/push → GitOps deploy Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
75 lines
2.0 KiB
Go
75 lines
2.0 KiB
Go
// Package agent wraps the ADK runner with the project's defaults.
|
|
//
|
|
// Keep this thin: construction, defaults, and the Run loop. Tool wiring,
|
|
// callbacks, and any business logic belong in sibling packages.
|
|
package agent
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"iter"
|
|
|
|
"google.golang.org/adk/agent"
|
|
"google.golang.org/adk/agent/llmagent"
|
|
"google.golang.org/adk/model"
|
|
"google.golang.org/adk/runner"
|
|
"google.golang.org/adk/session"
|
|
"google.golang.org/genai"
|
|
)
|
|
|
|
// Config holds the minimum needed to spin up an agent + runner.
|
|
type Config struct {
|
|
Name string
|
|
Description string
|
|
Instruction string
|
|
Model model.LLM
|
|
}
|
|
|
|
// Agent is the runnable unit. Construct with New, drive with Run.
|
|
type Agent struct {
|
|
name string
|
|
runner *runner.Runner
|
|
}
|
|
|
|
// New builds an llmagent and an in-memory-session runner around it.
|
|
func New(cfg Config) (*Agent, error) {
|
|
if cfg.Name == "" {
|
|
return nil, fmt.Errorf("agent: Name required")
|
|
}
|
|
if cfg.Model == nil {
|
|
return nil, fmt.Errorf("agent: Model required")
|
|
}
|
|
|
|
ag, err := llmagent.New(llmagent.Config{
|
|
Name: cfg.Name,
|
|
Description: cfg.Description,
|
|
Model: cfg.Model,
|
|
Instruction: cfg.Instruction,
|
|
})
|
|
if err != nil {
|
|
return nil, fmt.Errorf("agent: build llmagent: %w", err)
|
|
}
|
|
|
|
r, err := runner.New(runner.Config{
|
|
AppName: cfg.Name,
|
|
Agent: ag,
|
|
SessionService: session.InMemoryService(),
|
|
AutoCreateSession: true,
|
|
})
|
|
if err != nil {
|
|
return nil, fmt.Errorf("agent: build runner: %w", err)
|
|
}
|
|
|
|
return &Agent{name: cfg.Name, runner: r}, nil
|
|
}
|
|
|
|
// Run dispatches a single user turn and returns the event iterator.
|
|
// The caller is responsible for draining it and handling errors.
|
|
func (a *Agent) Run(ctx context.Context, userID, sessionID, text string) iter.Seq2[*session.Event, error] {
|
|
msg := genai.NewContentFromText(text, "user")
|
|
return a.runner.Run(ctx, userID, sessionID, msg, agent.RunConfig{})
|
|
}
|
|
|
|
// Name returns the registered agent name (also used as ADK AppName).
|
|
func (a *Agent) Name() string { return a.name }
|