Files
template-go-agent/internal/agent/agent.go
T
mathiasandClaude Opus 4.7 b9c64c2694
CD / Lint / Test / Vet (push) Failing after 4s
CD / Build & Import (push) Has been skipped
CD / Deploy via GitOps (push) Has been skipped
feat: add agent boundaries, network policy, agent stub, dockerfile, CI
- 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>
2026-05-28 20:54:04 +02:00

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 }