preset

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Oct 8, 2026 License: MIT Imports: 12 Imported by: 0

README

preset

Composition, not a capability. This package has no plugin of its own — it assembles the others.

preset.Plugins(cfg) returns the plugin list that reproduces agentcore.New(cfg), and preset_test.go proves the two agree field by field via Describe(). If the plugin surface ever drifts from Config, that test fails.

preset.Full(cfg, opts) is that list plus the capabilities Config has no field for: spill, jobs, repeat_guard, session_query, plus opt-in todo, subagents, advisor, ask and finish guards. The split is load-bearing — Plugins is pinned to agentcore.New parity and must stay a pure mirror of Config, so the capabilities that answer to no Config field live one layer up. Full is where a deployment starts; Plugins is where the parity proof lives.

Every Options field degrades to off, never to wrong. A nil Spill leaves the loop's own head+tail truncation in place rather than minting locators into a store that dies with the process — the locator is written to the durable session log, so an in-memory store would make a resumed run read its own spill back as not-found.

Model Experience

None. Composition happens before any model call.

Impact on the agent

It is the starting point for a custom agent. Take the default list, drop or replace what you want to change, append your own, and build:

ps := preset.Plugins(cfg)
ps = preset.Replace(ps, agentcore.PolicyDenyAll()) // replace the permission policy
ps = append(ps, myCapability{})                  // add a capability
agent, err := agentcore.Build(ps...)

The engine owns turn scheduling. Plugins configure capabilities through registry setters, hooks and per-run extensions; they cannot replace the loop.

Two tests here carry the architectural claims:

  • TestPluginCompositionMatchesNew — the two entry points cannot drift.
  • TestEjectRemovesEveryTrace — building the same agent with and without a capability leaves no sign of it in the one without: no tool, no name in the extension list. This is the test that fails if someone re-couples the loop to a plugin by name, because the loop would keep doing the work with the plugin gone.

Known limitations and deferred work

  • Parity is checked through Describe(), so a Config field that Describe does not report could drift undetected. The test guards against a vacuous pass by asserting the dump is not thin, but that is a proxy, not a proof.
  • Replace appends. A replacement lands at the end of the list rather than in the original position. Seams are keyed and hooks are prioritized, but extension stop guards run in registration order. Preserve that order when replacing guards. Full replaces its goal/memory options in place.

Tracing is supplied through NativeRun.Telemetry or telemetry.WithContext; there is no observer plugin or provider-decorator registration. Native recovery validates checkpoints and effect receipts directly.

Full additionally accepts GoalLifecycle (an opt-in goal plugin configuration), AdvisorOptions (cadence/caps for NativeAdvisor), and ConsolidateMemory (native rollout distillation when the configured store implements the optional durable consolidation contract). Zero values preserve the earlier composition behavior.

Documentation

Overview

Package preset composes agentcore's default agent out of the plugin packages.

This is the "build agentcore from its own plugins" step made literal: Plugins(cfg) returns the plugin list that reproduces agentcore.New(cfg), and preset_test.go proves the two agree field by field. If the plugin surface ever drifts from Config, that test fails.

Full(cfg, opts) is that same list plus the capabilities Config has no field for — spill, jobs, the repeat guard, session retrieval, telemetry supplied by the host — and is what a real deployment composes.

Use either as the starting point for a custom agent. Take the list, drop or replace the entries you want to change, append your own, and hand the result to agentcore.Build:

ps := preset.Full(cfg, preset.Options{Spill: myStore})
ps = append(ps, myCapability{})
agent, err := agentcore.Build(ps...)

Plugins configure the native engine through hooks and extensions.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Full

func Full(cfg agentcore.Config, o Options) []agentcore.Plugin

Full is the default agent plus the capabilities that agentcore.Config has no field for: retrieval over the run's own history, background work, oversized output, the repeat-loop nudge, and native lifecycle hooks.

The split from Plugins is the point. Plugins is pinned to agentcore.New(cfg) parity — every entry there answers to a Config field, and preset_test proves the two cannot drift. The five below answer to no Config field at all; they are plugins in the sense the architecture means, added to a list. Full is where a real deployment starts; Plugins is where the parity proof lives.

Everything here is still ejectable: preset.Without(preset.Full(cfg, o), "spill") is a complete agent minus spilling, with no trace of it left.

func New

func New(cfg agentcore.Config) (*agentcore.Agent, error)

New builds an agent from the default plugin set. It is agentcore.New spelled through the plugin packages.

func Plugins

func Plugins(cfg agentcore.Config) []agentcore.Plugin

Plugins returns the plugin set that reproduces agentcore.New(cfg).

Core seams are provided by agentcore.*Plugin adapters in seams.go; capabilities and extensions come from their respective plugin packages.

func Replace

func Replace(list []agentcore.Plugin, p agentcore.Plugin) []agentcore.Plugin

Replace swaps the plugin with the same name as p, appending it when no such plugin is present. Use it to change one seam and keep the rest of a composition intact.

func Without

func Without(list []agentcore.Plugin, names ...string) []agentcore.Plugin

Without removes the named plugins from a list, so a caller can replace one without rebuilding the rest by hand. Names that are not present are ignored — dropping something already absent is not an error.

Types

type Options

type Options struct {
	// Plan pins and checkpoints this run's checklist; forks get an isolated plan.
	Plan *todo.Store
	// Subagents enables governed delegation with these host-selected bounds.
	Subagents *subagent.Plugin
	// NativeAdvisor reviews finished work with cfg.NativeProvider and accounts usage.
	NativeAdvisor  bool
	AdvisorOptions advisor.Plugin
	// GoalLifecycle opts into durable lifecycle controls; optional budgets are absolute.
	GoalLifecycle *goal.Plugin
	// ConsolidateMemory enables native distillation when Memory supports ConsolidationStore.
	ConsolidateMemory bool
	// MemoryWorker moves consolidation off the primary run when supplied.
	MemoryWorker *memory.ConsolidationWorker
	// Interactive exposes ask; the host must publish questions and resume answers.
	Interactive bool
	// NativeHistory enables retrieval from opaque native checkpoints.
	NativeHistory bool
	// FinishGuard supplies the host's completion evidence rule, if any.
	FinishGuard finishguard.Guard
	// Spill persists an oversized tool result and hands the model a locator for
	// the rest. nil leaves spilling OFF (the loop's head+tail truncation stands),
	// which is the honest default: the locator is written to the durable session
	// log, so a store that cannot outlive the process would mint locators that a
	// resumed run reads back as not-found. Supply a durable store to turn it on.
	Spill spill.SpillStore
	// Jobs owns background work. nil uses a fresh in-process store per run —
	// correct for a single server, since a job cannot outlive the run that
	// started it anyway.
	Jobs jobs.JobStore
	// SessionQuery backs the session_query tool. nil searches the run's OWN
	// durable log, which needs no external index.
	SessionQuery sessionquery.SessionQuery
}

Options configures the capabilities Full adds on top of Plugins. Every field is optional and every zero value degrades to "that capability is not installed" rather than to a broken one — a partially wired composition must lose a feature, never gain a silently wrong one.

Jump to

Keyboard shortcuts

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