subagent

package
v1.7.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 26, 2026 License: Apache-2.0 Imports: 12 Imported by: 0

Documentation

Overview

Package subagent implements a Tool that delegates work to specialized sub-agents with isolated contexts. Four execution modes are supported: single, parallel, chain, and background.

Index

Constants

View Source
const (
	ModeSingle     = "single"
	ModeParallel   = "parallel"
	ModeChain      = "chain"
	ModeBackground = "background"
)

Run modes — the authoritative set of values for RunMeta.Mode. Observers should compare against these rather than string literals.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	Name        string
	Description string
	// Model is resolved when each sub-agent run starts. Wrappers that swap the
	// underlying model at runtime (e.g. agentcore.SwappableModel) take effect
	// on the next sub-agent run.
	Model        agentcore.ChatModel
	SystemPrompt string
	// SystemPromptMode is a host-interpreted hint controlling how
	// SystemPrompt composes with the host's base prompt. agentcore does
	// NOT consume this field — the team spawner / executor on the host
	// side reads it to assemble AgentContext.SystemBlocks. Kept as a
	// plain string at the boundary so agentcore stays agnostic to enum
	// values that only matter inside one host; empty / unrecognized
	// values fall back to the host's default mode.
	SystemPromptMode string
	Tools            []agentcore.Tool
	MaxTurns         int

	// ThinkingLevel sets the reasoning depth for this sub-agent's runs.
	// Empty ("") leaves it unspecified (model/provider default). Mirrors
	// agentcore.WithThinkingLevel for top-level agents. A runtime override
	// installed via Tool.SetThinkingLevel takes precedence over this baseline.
	ThinkingLevel agentcore.ThinkingLevel

	// MaxRetries caps the LLM call retry count for retryable errors within
	// this sub-agent's loop. 0 (default) disables retry entirely.
	MaxRetries int

	// ToolsAreIdempotent declares this sub-agent's tools are safe to
	// re-execute. See agentcore.WithToolsAreIdempotent for full rationale.
	ToolsAreIdempotent bool

	// StopAfterTools lists tool names that trigger early loop exit after
	// successful execution.
	StopAfterTools []string

	// StopAfterToolResult is the result-aware variant of StopAfterTools.
	StopAfterToolResult func(toolName string, result json.RawMessage) bool

	// OnMessage, if non-nil, is called after each message is appended to
	// context. The agentName and task are provided for session routing.
	OnMessage func(agentName, task string, msg agentcore.AgentMessage)

	// Optional context lifecycle hooks for long-running sub-agents.
	ContextManager        agentcore.ContextManager
	ContextManagerFactory func(model agentcore.ChatModel) agentcore.ContextManager
	ConvertToLLM          func(msgs []agentcore.AgentMessage) []agentcore.Message

	// StopGuardFactory, if non-nil, creates a fresh StopGuard for each run.
	StopGuardFactory func(agentName, task string) agentcore.StopGuard
}

Config defines a sub-agent's identity and capabilities.

type RunMeta added in v1.7.0

type RunMeta struct {
	Agent      string
	InstanceID string
	Mode       string
}

RunMeta identifies one sub-agent run (one runAgent invocation) for an external event observer. It lets a harness route a run's raw AgentLoop events to a per-run sink (e.g. a live-preview transcript) without the subagent tool knowing anything about that sink.

  • Agent: the agent definition/type name (e.g. "explore"). Not unique when the same type runs more than once concurrently (parallel mode).
  • InstanceID: unique per runAgent invocation within this Tool's lifetime. Use this — not Agent — as the routing key.
  • Mode: one of the Mode* constants below.

type TeamSpawnRequest added in v1.6.10

type TeamSpawnRequest struct {
	// Config is the resolved sub-agent definition the teammate runs as.
	// Spawner reads SystemPrompt, Tools, Model, MaxTurns etc. from here.
	Config Config

	// Name is the teammate's identifier inside the team (routing key for
	// send_message). May equal Config.Name when the LLM did not specify one.
	Name string

	// TeamName is the active team's name; spawner validates against registry.
	TeamName string

	// InitialPrompt is the leader's first message to the teammate.
	InitialPrompt string

	// Description is an optional one-line summary for transcripts/UI.
	Description string

	// Color is an optional UI color assigned to this teammate.
	Color string

	// Model is non-nil when the LLM requested an override; nil means the
	// spawner should fall back to Config.Model.
	Model agentcore.ChatModel

	// History, if non-empty, seeds the teammate's conversation before its
	// first turn — the spawner forwards it to team.SpawnConfig.History. The
	// LLM never sets this; a harness populates it when resuming a teammate
	// with its prior transcript after a restart. nil ⇒ fresh teammate.
	History []agentcore.AgentMessage
}

TeamSpawnRequest is the contract between the subagent tool and the codebot-side team spawner. The subagent tool builds this from its params after validating the requested agent definition exists; the spawner is responsible for the actual goroutine launch, tool augmentation (e.g. injecting send_message), and team registry bookkeeping.

type TeamSpawnResult added in v1.6.10

type TeamSpawnResult struct {
	TaskID  string
	AgentID string // "name@team"
}

TeamSpawnResult is what the spawner returns synchronously. The teammate itself runs in the background; callers terminate it via task.Runtime.Stop (by TaskID) or by the team's shutdown protocol.

type TeamSpawner added in v1.6.10

type TeamSpawner func(ctx context.Context, req TeamSpawnRequest) (*TeamSpawnResult, error)

TeamSpawner is the function shape codebot installs via SetTeamSpawner. Kept as a function rather than an interface because the subagent tool only needs one method and call sites are simpler with a closure.

type Tool

type Tool struct {
	// contains filtered or unexported fields
}

Tool implements agentcore.Tool. The main agent calls this tool to delegate tasks to specialized sub-agents with isolated contexts.

func New

func New(agents ...Config) *Tool

New creates a subagent tool from a set of agent configs.

func (*Tool) AgentConfig added in v1.6.11

func (t *Tool) AgentConfig(name string) (Config, bool)

AgentConfig returns the registered sub-agent definition for name, or (zero, false) if none is registered. Exposed read-only so a harness can rebuild a TeamSpawnRequest when resuming a teammate by its agent type without re-deriving the config from scratch.

func (*Tool) Description

func (t *Tool) Description() string

func (*Tool) Execute

func (t *Tool) Execute(ctx context.Context, args json.RawMessage) (json.RawMessage, error)

func (*Tool) Label

func (t *Tool) Label() string

func (*Tool) Name

func (t *Tool) Name() string

func (*Tool) Schema

func (t *Tool) Schema() map[string]any

func (*Tool) SetBgOutputFactory

func (t *Tool) SetBgOutputFactory(fn func(taskID, agentName string) (io.WriteCloser, string, error))

SetBgOutputFactory sets the factory that creates output writers for background tasks. The factory receives the task ID and agent name and returns a writer, file path, and error.

func (*Tool) SetCreateModel

func (t *Tool) SetCreateModel(fn func(name string) (agentcore.ChatModel, error))

SetCreateModel sets the factory for resolving model names to ChatModel instances at runtime. Enables LLM to override the default model per call.

func (*Tool) SetEventObserver added in v1.7.0

func (t *Tool) SetEventObserver(fn func(meta RunMeta, ev agentcore.Event))

SetEventObserver installs a callback that receives every raw AgentLoop event produced by any sub-agent run (single/parallel/chain/background), tagged with a RunMeta carrying a unique per-run InstanceID. A harness uses this to drive a live preview of sub-agent work — symmetric to how a teammate executor fans its loop events out. nil (the default) disables observation with zero cost.

The callback MUST be non-blocking: it runs inline on the sub-agent's execution goroutine (and on parallel/background goroutines concurrently), so a slow observer stalls the run. Sinks that may block should buffer + drop.

func (*Tool) SetNotifyFn

func (t *Tool) SetNotifyFn(fn func(agentcore.AgentMessage))

SetNotifyFn sets the callback invoked when a background task completes. Typically bound to Agent.FollowUp so the main agent receives the result as a follow-up message.

func (*Tool) SetTaskRuntime

func (t *Tool) SetTaskRuntime(rt *task.Runtime)

SetTaskRuntime sets the shared task runtime for background task registration. Required for background mode.

func (*Tool) SetTeamSpawner added in v1.6.10

func (t *Tool) SetTeamSpawner(fn TeamSpawner)

SetTeamSpawner installs the closure that handles team-spawn mode. Without it, calls that set team_name are rejected with a clear error so the LLM learns the feature is unavailable rather than silently downgrading to a regular subagent run.

func (*Tool) SetThinkingLevel added in v1.7.1

func (t *Tool) SetThinkingLevel(agentName string, level agentcore.ThinkingLevel)

SetThinkingLevel overrides a sub-agent's reasoning depth at runtime, keyed by agent name. It takes effect on the next run of that agent (mirroring how a SwappableModel swap takes effect on the next run) and overrides the agent's Config.ThinkingLevel baseline. Safe to call concurrently with running agents: the override lives in an isolated map and never mutates the immutable agents config map. Empty level ("") means model/provider default.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL