sysprompt

package
v0.2.0 Latest Latest
Warning

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

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

Documentation

Overview

Package sysprompt builds the system prompt for each kind of agent evva runs. The package exposes one AgentDefinition per built-in agent (see agent_def.go) whose BuildSystemPrompt function turns a PromptContext into the full prompt string. The Main agent's prompt is composed from shared fragments (identity, environment, memory, skills, dev) plus per-agent harness/tools/planning blocks; subagents (Explore, General) own a single hand-written string mirroring ref/src/tools/AgentTool/built-in/*Agent.ts.

The package is dependency-light on purpose: it imports only stdlib. The caller (cmd/evva/main.go via agent.Main) reads memory files through the memdir package and threads them into PromptContext.ProjectMemory / .UserProfile. The skill registry is similarly flattened by the caller into []SkillRef so sysprompt does not depend on internal/tools/skill.

Tool names interpolated into prompts live in toolnames.go and are drift-checked against internal/tools/name.go by toolnames_link_test.go.

Index

Constants

This section is empty.

Variables

View Source
var (
	MainAgent = AgentDefinition{
		Name:              "evva",
		WhenToUse:         "",
		OmitMemory:        false,
		AdvertiseSkills:   true,
		BuildSystemPrompt: buildMainPrompt,
		As:                []string{"main"},
	}

	ExploreAgent = AgentDefinition{
		Name:              subagentExplore,
		WhenToUse:         exploreWhenToUse,
		OmitMemory:        true,
		AdvertiseSkills:   false,
		BuildSystemPrompt: buildExplorePrompt,
		As:                []string{"subagent"},
	}

	GeneralAgent = AgentDefinition{
		Name:              subagentGeneral,
		WhenToUse:         generalWhenToUse,
		OmitMemory:        true,
		AdvertiseSkills:   false,
		BuildSystemPrompt: buildGeneralPrompt,
		As:                []string{"subagent"},
	}

	PlanAgent = AgentDefinition{
		Name:              subagentPlan,
		WhenToUse:         planWhenToUse,
		OmitMemory:        true,
		AdvertiseSkills:   false,
		BuildSystemPrompt: buildPlanPrompt,
		As:                []string{"subagent"},
	}
)

Built-in agent registry. Phase 11 adds PlanAgent for design-phase work inside plan mode; Phase 6 may add more main-tier personas (nono, noen) as siblings.

Functions

func ComposeDiskMainPrompt

func ComposeDiskMainPrompt(body string, ctx PromptContext, def AgentDefinition) string

ComposeDiskMainPrompt assembles a system prompt for a disk-loaded main-tier persona. body is the verbatim system_prompt.md the loader captured; def carries the OmitMemory / AdvertiseSkills flags from meta.yml. The result is identity + environment + (optional) memory + body + (optional) skills + (optional) dev feedback, joined the same way the built-in evva prompt is composed.

Lives here (in the sysprompt package) so the section builders stay package-private and disk-persona composition has a single seam.

Disk personas DELIBERATELY skip the ref-ported sections (doing-tasks, actions, tone, output-efficiency, system, session-specific-guidance). Those would conflict with the persona's own definition; the persona supplies its own conduct rules in body.

Types

type AgentDefinition

type AgentDefinition struct {
	Name              string
	WhenToUse         string
	OmitMemory        bool
	AdvertiseSkills   bool
	BuildSystemPrompt func(ctx PromptContext) string

	// As controls where this agent appears. Values:
	//   "main"     — selectable via /profile (Phase 6 picker).
	//   "subagent" — invokable via the Agent tool's subagent_type.
	// Both can be set; for built-ins the slice is fixed (Main is main-only;
	// Explore/General are subagent-only). Disk agents declare this via
	// meta.yml's `as:` field.
	As []string

	// ActiveTools / DeferredTools name the tools this agent's profile loads.
	// Empty means "use the built-in constructor's default" (Main, Explore,
	// General supply their own lists in agent.Main/Explore/General). For
	// disk-loaded agents these come from tools.yml.
	ActiveTools   []tools.ToolName
	DeferredTools []tools.ToolName

	// Model is the optional model override declared in meta.yml. Empty
	// means "inherit from parent" (existing built-in behavior).
	Model string
}

AgentDefinition is the Go-side seam for a built-in agent. Phase 2's internal/agent/loader/ will define an AgentRegistry interface that this struct satisfies; for Phase 0 it is a concrete struct since the only agents are built-ins. Disk-authored agents (Phase 2) construct an AgentDefinition where BuildSystemPrompt is a closure that returns the on-disk system_prompt.md body.

Field semantics:

  • Name wire identifier ("evva", "explore", "general-purpose"). Same string the Agent tool's subagent_type enum will accept (Phase 2 unifies these). Lowercase, hyphenated.
  • WhenToUse description shown in the Agent tool's catalog so a parent agent knows what to delegate. Empty for Main (Main is not delegated to).
  • OmitMemory subagents skip <workdir>/EVVA.md and <evvaHome>/USER_PROFILE.md. Matches ref TS omitClaudeMd: true on Explore/Plan.
  • AdvertiseSkills only the Main agent surfaces the skill catalog. Subagents don't (it would bloat their context).
  • BuildSystemPrompt assembles the prompt from ctx. Each built-in closure-captures its own per-agent text fragments.

func (AgentDefinition) IsMain

func (d AgentDefinition) IsMain() bool

IsMain reports whether this agent appears in the /profile picker (Phase 6).

func (AgentDefinition) IsSubagent

func (d AgentDefinition) IsSubagent() bool

IsSubagent reports whether this agent is invokable via the Agent tool's subagent_type parameter.

type DeferredToolSpec

type DeferredToolSpec struct {
	Name        string
	Description string
	Schema      json.RawMessage // raw JSON Schema object; rendered verbatim in the <functions> block
}

DeferredToolSpec is the prompt-side view of one deferred tool. The sysprompt package interpolates these into a <functions> block in the main prompt so the model sees full schemas from turn 1 — no tool_search round trip is required to call a deferred tool.

Mirrors tools.Descriptor's three LLM-facing fields. The caller (agent.Main) flattens the deferred-tool catalog into []DeferredToolSpec so sysprompt does not depend on internal/tools or internal/toolset.

type PromptContext

type PromptContext struct {
	// Identity
	AgentName string    // e.g. "evva" — the name the main agent introduces itself as.
	Today     time.Time // anchors the model in absolute time; zero = use time.Now() at render.

	// Environment
	OS       string // runtime.GOOS — "darwin", "linux", "windows".
	Shell    string // basename of $SHELL — "zsh", "bash", ...
	WorkDir  string // absolute path of the current working directory.
	EvvaHome string // ~/.evva — where skills, memory, and config live.
	Env      string // "dev" | "prod" — dev gates the feedback section.
	Model    string // canonical model id ("claude-opus-4-7", "deepseek-chat", ...). Empty = skip the model line in env block.

	// Catalogs
	Skills        []SkillRef         // advertised skill list; empty = skip the section.
	DeferredTools []DeferredToolSpec // deferred-tool catalog; rendered as a <functions> block in the main prompt. Empty = skip the section.

	// Memory (loaded by internal/memdir)
	ProjectMemory string // contents of <workdir>/EVVA.md; "" = skip.
	UserProfile   string // contents of <evvaHome>/USER_PROFILE.md; "" = skip.
}

PromptContext is the input bundle for every AgentDefinition.BuildSystemPrompt. Build once per agent at construction time and pass by value — builders read-only. Zero values render cleanly: empty environment fields become "(unknown)" / "(unset)"; empty Skills / ProjectMemory / UserProfile suppress their respective sections.

func DetectContext

func DetectContext(agentName, evvaHome, env string) PromptContext

DetectContext returns a PromptContext with the runtime-detectable fields (Today, OS, Shell, WorkDir) populated. Caller fills AgentName, EvvaHome, Env, Skills, and the two memory fields — those live in configs.AppConfig and on the memdir.Snapshot, which the sysprompt module deliberately does not import.

type SkillRef

type SkillRef struct {
	Name        string
	Description string
}

SkillRef is the prompt-side view of a user-installed skill — just the name and description we advertise to the model. The sysprompt package deliberately does not depend on internal/tools/skill; the caller flattens the skill registry into this struct.

Jump to

Keyboard shortcuts

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