agent

package
v0.2.2-alpha.1 Latest Latest
Warning

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

Go to latest
Published: May 21, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Agent

type Agent interface {
	// Run drives the agent for a single user turn.
	Run(ctx context.Context, prompt string) (string, error)

	// Continue resumes an iter-limit-paused run without appending a new
	// user message.
	Continue(ctx context.Context) (string, error)

	// Session returns a snapshot of the conversation state.
	Session() SessionInfo

	// Logger exposes the agent's structured logger.
	Logger() *slog.Logger

	// Model returns the model id the agent is currently bound to.
	Model() string

	// AgentID returns the agent's unique identifier.
	AgentID() string

	// MaxIterations / SetMaxIterations exposes the loop cap.
	MaxIterations() int
	SetMaxIterations(int)

	// SwitchLLM rebuilds the agent's LLM client with a new (provider, model)
	// pair and clears the conversation history.
	SwitchLLM(provider constant.LLMProvider, model constant.Model) error

	// SwitchProfile reconstructs the agent under a new persona.
	SwitchProfile(name string) error

	// ProfileName returns the active persona's wire identity.
	ProfileName() string

	// ListMainProfiles enumerates the personas available for switching.
	ListMainProfiles() []ProfileChoice

	// Effort returns the current effort level name ("low"|"medium"|"high"|"ultra").
	Effort() string

	// SetEffort updates the effort level at runtime.
	SetEffort(level string) error

	// Skills returns the merged catalog of user-installed skills.
	Skills() []Skill

	// Compact forces an immediate compaction of the current session.
	Compact(ctx context.Context, kind string) error

	// PermissionModeName returns the agent's current permission stance
	// as a string ("default", "accept_edits", "plan", "bypass", "auto").
	PermissionModeName() string

	// CyclePermissionMode advances the mode in Shift+Tab order and
	// returns the new mode name.
	CyclePermissionMode() string

	// RespondPermission delivers the user's approval/denial back to
	// the blocked tool goroutine.
	RespondPermission(id string, decision PermissionDecision) error

	// RespondQuestion delivers the user's answers back to the blocked
	// AskUserQuestion tool goroutine.
	RespondQuestion(id string, resp QuestionResponse) error
}

Agent is the public API for creating and driving an evva agent programmatically. It is implemented by a wrapper around the internal agent.

func New

func New(cfg Config) (Agent, error)

New constructs an Agent ready to call Run. When cfg.AppConfig is nil it loads the process-wide default (config.Get(), which initializes via LoadDefault on first use); pass an explicit *config.Config to target a custom AppHome.

Set API keys via the <app>-config.yml file under cfg.AppHome (or env vars consumed by your own loader for downstream apps).

func NewWithProfile

func NewWithProfile(profile Profile, opts ...Option) (Agent, error)

NewWithProfile is the flexible public constructor a downstream app uses to build an agent against its own profile and option set. Unlike New (which loads the bundled Main persona, memdir, and a non-interactive permission stub) this constructor wires only what the caller supplies — no skill catalog, no memory snapshot, no agent registry by default.

A non-interactive permission broker + question broker are installed internally so async approval / question requests don't park the caller forever; pass agent_impl.WithPermissionBroker / WithQuestionBroker via the variadic opts list to override.

Example:

prof, _ := agent.NewProfile("custom", "you are helpful",
    []tools.ToolName{tools.READ_FILE, tools.BASH},
    "anthropic", "claude-sonnet-4-6",
    agent.ProfileOptions{})

ag, _ := agent.NewWithProfile(prof,
    agent.WithConfig(cfg),
    agent.WithSink(mySink),
    agent.WithMaxIterations(20),
)
resp, _ := ag.Run(ctx, "...")

type Config

type Config struct {
	// Provider is the LLM provider name: "anthropic", "openai", "deepseek", "ollama".
	Provider string
	// Model is the model id, e.g. "claude-sonnet-4-6". When empty, the
	// provider's cheapest model is used.
	Model string
	// MaxIters overrides the default loop iteration cap. Zero means use the
	// default (from <app>-config.yml or 10).
	MaxIters int
	// PermissionMode sets the initial permission stance: "default", "bypass",
	// "accept_edits", "plan". Empty means "bypass" (all tool calls auto-approved).
	PermissionMode string
	// AppConfig is the runtime configuration the agent reads from. Nil falls
	// back to config.LoadDefault() / config.Get() — the historical singleton.
	// Downstream apps that want a non-default AppHome (e.g. ~/.myapp/) pass
	// a *config.Config they built via config.Load(...).
	AppConfig *config.Config
}

Config is the public constructor input for creating an agent. Provider and Model are the only required fields.

type Option

type Option = agent_impl.Option

Option mutates an Agent during construction. Downstream callers build options via the public With* functions in this package; the internal Option type is aliased here so options compose with the bundled cmd/evva wiring without duplicate type definitions.

func WithConfig

func WithConfig(cfg *config.Config) Option

WithConfig installs the runtime configuration the agent reads from. Subagents inherit the parent's config; downstream apps that run multiple agents with different AppHome dirs pass distinct *config.Config pointers per agent.

Omitting WithConfig boots the agent against config.Get() — the historical singleton — so cmd/evva and existing callers don't need to change.

func WithCustomTool

func WithCustomTool(name tools.ToolName, factory pubtoolset.ToolFactory) Option

WithCustomTool registers a downstream-authored tool on the pkg/toolset.DefaultRegistry and adds it to the agent's active list. The factory receives the agent's pkg/tools.State at build time so the tool can read Config() and Workdir().

Registration is idempotent across agents — calling WithCustomTool with the same name in two New calls registers the factory once and reuses it.

func WithMaxIterations

func WithMaxIterations(n int) Option

WithMaxIterations overrides the agent's loop cap. Pass 0 to keep the cfg-derived default. Values in (0, 2) are clamped to 2.

func WithName

func WithName(name string) Option

WithName sets a human-readable label on the agent. Surfaced in logs and in subagent panels.

func WithPermissionMode

func WithPermissionMode(modeName string) Option

WithPermissionMode sets the agent's initial permission stance using the string form ("default" | "accept_edits" | "plan" | "bypass" | "auto"). Unknown values are silently ignored.

func WithSink

func WithSink(s event.Sink) Option

WithSink installs the event consumer the agent emits into. nil sinks become event.Discard at emit time; pass event.Multi{...} to fan out to several consumers (e.g. a TUI plus a JSON-over-stdout bridge).

func WithStream

func WithStream(stream bool) Option

WithStream toggles streaming completions. Overrides the Profile.Stream field; useful for tests and downstream apps that want to force the buffered or chunked path without rebuilding the profile.

type PermissionDecision

type PermissionDecision struct {
	Behavior string // "allow" | "deny"
	Reason   string
	AddRule  *PermissionRuleSeed
}

PermissionDecision is the payload returned through Agent.RespondPermission.

type PermissionRuleSeed

type PermissionRuleSeed struct {
	ToolName string
	Content  string // empty means tool-wide
}

PermissionRuleSeed is the minimum info needed to construct a session-scope allow rule.

type Profile

type Profile = agent_impl.Profile

Profile is the public alias for the internal agent profile. Downstream apps construct one via NewProfile (or via an evva-bundled persona constructor like Main when running inside the evva binary).

The struct's fields are accessible so downstream tests and tools can inspect a profile, but the constructor remains the recommended entry point — it normalizes optional fields and handles the AgentType classification (which is internal evva concept downstream apps don't need to think about).

func NewProfile

func NewProfile(name, systemPrompt string, activeTools []tools.ToolName, providerName, model string, opts ProfileOptions) (Profile, error)

NewProfile builds a Profile a downstream app can pass into NewWithProfile. The system prompt is wrapped into an llm.WithSystem option automatically.

providerName must match a name registered on pkg/llm.DefaultRegistry ("anthropic", "deepseek", "ollama", or a downstream-registered name). model is the model id sent to the provider; empty is allowed but downstream factories typically expect a concrete id.

The profile is classified as GENERAL_PURPOSE — evva's internal type system reserves MAIN/EXPLORE/PLAN for the bundled personas. Downstream apps that want richer behavior (memory injection, skills, plan-mode) should ship an on-disk agent definition under <AppHome>/agents/ instead of constructing a Profile in code.

providerName does not need to be in pkg/constant.GetAllProviders() — downstream apps register their own provider via pkg/llm.DefaultRegistry().Register and pass the same name here. When the name isn't in the bundled constants, an LLMProvider stub is synthesised on the fly so the rest of the agent loop has a value to log + introspect.

type ProfileChoice

type ProfileChoice struct {
	Name      string
	WhenToUse string
}

ProfileChoice is one row in the /profile picker.

type ProfileOptions

type ProfileOptions struct {
	// DeferredTools is the names the LLM sees by description-only; the
	// model must invoke TOOL_SEARCH to fetch their full schemas. Empty
	// means every active tool is eagerly available.
	DeferredTools []tools.ToolName

	// Stream selects the streaming completion path. Defaults to false
	// — most downstream apps want the buffered Complete path until they
	// build a streaming UI.
	Stream bool

	// LLMOptions are forwarded to the LLM client. The system prompt is
	// already supplied via the SystemPrompt argument to NewProfile and
	// does not need to be repeated here.
	LLMOptions []llm.Option
}

ProfileOptions tunes NewProfile. Zero-value fields fall back to sensible defaults: streaming off, no deferred tools, no extra llm options beyond the system prompt.

type QuestionAnnotation

type QuestionAnnotation struct {
	Notes   string
	Preview string
}

QuestionAnnotation captures the preview content (if any) of the option the user selected, plus any free-text notes they added.

type QuestionResponse

type QuestionResponse struct {
	Answers     map[string]string
	Annotations map[string]QuestionAnnotation
}

QuestionResponse is the payload returned through Agent.RespondQuestion.

type SessionInfo

type SessionInfo struct {
	MessageCount    int
	InputTokens     int
	OutputTokens    int
	LastInputTokens int
}

SessionInfo is a snapshot of the agent's conversation state (message count and cumulative token usage). External callers get a point-in-time copy.

type Skill

type Skill struct {
	Name        string
	Description string
}

Skill is the UI-facing view of a user-installed skill.

Jump to

Keyboard shortcuts

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