agentreg

package
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Aug 24, 2026 License: AGPL-3.0 Imports: 24 Imported by: 0

Documentation

Overview

Package agentreg provides subagent infrastructure for jungi.

A subagent is an independent session with its own context window, model, and system prompt. It shares the parent session's sandbox but maintains separate conversation state, logging, and usage tracking. When a subagent completes its task, only its final text response and accumulated costs are folded back into the parent session.

Storage, merge, frontmatter splitting, and directory loading are shared with promptreg and skillreg via internal/core/mdreg; this package supplies only the Definition value type, its YAML frontmatter shape, and an AGENT.md subdir directory layout.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func LoadFromFS

func LoadFromFS(fsys fs.FS, dir string) (*Registry, []LoadWarning, error)

LoadFromFS reads agent definitions from an fs.FS-rooted tree. dir is the directory inside the FS whose immediate children are treated as agent directories, each containing an AGENT.md file with YAML frontmatter.

Invalid files produce a LoadWarning and are skipped without aborting the load. A non-existent dir is not an error — the Registry is empty.

func LoadRegistry

func LoadRegistry(dir string) (*Registry, []LoadWarning, error)

LoadRegistry scans dir for agent subdirectories and returns a Registry plus any warnings about skipped entries.

Each direct subdirectory of dir containing an AGENT.md file is treated as an agent directory. Subdirectories with valid frontmatter (required name and description fields) are registered under the name given in the frontmatter. Invalid entries — missing AGENT.md, missing fences, malformed YAML, missing required fields, invalid names, or duplicate names — produce a LoadWarning and are skipped without aborting the load. Symlinks are skipped with a warning regardless of their target.

A non-existent dir is not an error: the returned Registry is empty and no warnings are generated. Other I/O errors (permissions, etc.) are returned.

func MergeRegistries

func MergeRegistries(regs ...*Registry) (*Registry, []LoadWarning)

MergeRegistries returns a new Registry combining definitions from each input in order, with first-wins semantics on name collision. nil registries are tolerated and treated as empty.

func NewID added in v0.2.0

func NewID() (string, error)

NewID generates a 6-character hex string for agent instance identification. It is the canonical agent-instance ID generator: callers that need to reference an agent before Run starts (e.g. to emit a start event) call this themselves and pass the resulting ID to Run.

Types

type Definition

type Definition struct {
	Name           string
	Description    string
	Model          model.ID
	FallbackModels []model.ID
	Body           string
	Tools          []string
}

Definition describes a subagent's identity and configuration.

The Body field serves as the subagent's system prompt. It is the equivalent of the markdown body in a Claude Code agent file.

Tools is the optional list of tool names the agent is permitted to use. An empty slice means the caller decides which tools to enable.

type LoadWarning

type LoadWarning = mdreg.Warning

LoadWarning describes an AGENT.md file that was skipped during registry construction. Warnings are returned alongside the registry so callers can surface them without the agent package taking a logger dependency.

type ParallelError

type ParallelError struct {
	AgentID   string
	AgentName string
	Err       error
}

ParallelError captures a single agent failure during parallel execution. Err is always non-nil: ParallelError is only ever constructed in the error branch of the parallel run loop below, where err is known non-nil.

type ParallelResult

type ParallelResult struct {
	Results []RunResult
	Errors  []ParallelError
}

ParallelResult holds results and errors from concurrent agent execution.

type ParallelTask

type ParallelTask struct {
	Def          Definition
	Instructions string
}

ParallelTask pairs a definition with its instructions for batch execution.

type ProgressEvent

type ProgressEvent struct {
	AgentID   string
	AgentName string
	Started   bool           // true for start events
	Result    *RunResult     // non-nil on successful completion
	Error     *ParallelError // non-nil on failure
}

ProgressEvent is sent when an agent starts or finishes during parallel execution.

type Registry

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

Registry holds the set of agent definitions available for the lifetime of a session. It is built once at startup; subsequent filesystem changes are ignored.

func EmptyRegistry

func EmptyRegistry() *Registry

EmptyRegistry returns a Registry with no agents. Use it when no agents directory is present, so callers avoid nil checks.

func MustLoadEmbedded

func MustLoadEmbedded(fsys fs.FS, dir string) *Registry

MustLoadEmbedded loads agent definitions from an embedded fs.FS via LoadFromFS and panics on any load error or warning. Meant for jungi's bundled agent package (internal/agents) whose //go:embed'd files are static: any failure to parse them is a build defect, not a runtime condition.

func (*Registry) Get

func (r *Registry) Get(name string) (Definition, bool)

Get returns the Definition for the named agent and a boolean indicating whether it was found.

func (*Registry) List

func (r *Registry) List() []Definition

List returns the registered agent definitions in load order. The returned slice is freshly allocated and safe to mutate.

type RunResult

type RunResult struct {
	AgentID   string
	AgentName string
	Content   string
	Usage     usage.SessionUsage
	Events    []toolexec.ToolEvent
}

RunResult holds the outcome of a subagent execution.

type Runner

type Runner struct {

	// ClientFactory overrides client construction for testing. Production
	// (newDefaultAgentClient) resolves each agent's credential from its own
	// model's provider, so a test factory need not receive an API key at
	// all — doing so previously let injected factories mask cross-provider
	// misrouting. If nil, newDefaultAgentClient is used.
	ClientFactory func(log *logger.Logger, prompt string, m model.ID, tools []tooldef.Definition) client.Client
	// contains filtered or unexported fields
}

Runner holds the shared dependencies needed to launch subagents. It is constructed once and reused across agent invocations within a parent session.

func NewRunner

func NewRunner(sb sandbox.Sandbox, logDir, parentSessionID string, skills *skillreg.Registry, agents *Registry, lspMgr *corelsp.Manager) *Runner

NewRunner creates a Runner bound to the parent session's sandbox and log directory. The parentSessionID is used to name agent log files for correlation.

Each subagent's credential is resolved from its own model's provider at client-construction time (see newDefaultAgentClient), so NewRunner takes no credential of its own.

skills is the registry threaded into each subagent's executor and system prompt. It may be nil; in that case subagents see no skills.

agents is the registry of agent definitions the runner can look up by name. It may be nil; callers that always pass a Definition directly can omit it.

lspMgr is the parent session's language-server manager. Subagents share it read-only (diagnostics/hover/references); Manager is concurrency-safe. May be nil or disabled — subagents simply omit the lsp tool in that case.

func (*Runner) Agents

func (r *Runner) Agents() *Registry

Agents returns the runner's agent registry, which may be nil if the runner was constructed without one.

func (*Runner) GetAgent

func (r *Runner) GetAgent(name string) (Definition, bool)

GetAgent looks up a named agent definition from the runner's registry. Returns the Definition and true if found, zero value and false otherwise. Callers that always construct a Definition themselves may ignore this.

func (*Runner) Run

func (r *Runner) Run(ctx context.Context, def Definition, instructions string, agentID string) (RunResult, error)

Run executes a subagent with the given instructions in an independent session. It creates its own client, executor, and logger, runs the instruction through the agent's tool loop, and returns the result.

The agentID parameter identifies this agent instance. If empty, a random ID is generated.

The parent's sandbox is shared (same working directory restrictions). All other state—conversation history, token usage, log file—is isolated.

func (*Runner) RunParallel

func (r *Runner) RunParallel(ctx context.Context, tasks []ParallelTask, onProgress func(ProgressEvent)) ParallelResult

RunParallel executes multiple agents concurrently and collects results. It always waits for all agents to finish. Successful results and errors are collected separately; partial success is not treated as failure.

If onProgress is non-nil, it is called each time an individual agent completes (success or failure), enabling progressive UI updates.

func (*Runner) SetProviderPreferences added in v0.4.0

func (r *Runner) SetProviderPreferences(prefs settings.ProviderSettings)

SetProviderPreferences configures OpenRouter provider routing preferences for subagents spawned by this runner.

Source Files

  • definition.go
  • registry.go
  • runner.go

Jump to

Keyboard shortcuts

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