Skip to the content.

Agent Reference

Embercore is built around five specialised agents, each named after a Greek deity. They work together in a pipeline: Athena creates the plan, Hermes orchestrates execution, Apollo writes copy, Hephaestus assembles deliverables, and Hestia manages persistence.

Brief → Athena (plan) → Hermes (execute) → Apollo / Hephaestus → Artifacts
                              ↕
                        Hestia (persist)

All agents live under packages/engine/agents/.


Athena — The Planner

Package: agents/athena

Athena takes a product brief or campaign goal and generates a structured YAML plan that orchestrates the other agents. Each plan contains checkpoints with dependency ordering, agent assignments, and expected outputs.

API

// New creates an Athena planner. Pass nil for h to disable persistence.
func New(p provider.Provider, h *hestia.Hestia) *Athena

// GeneratePlan takes a product brief and generates a structured plan.
// Calls the LLM with a planning prompt, parses YAML, validates, and
// optionally persists via Hestia.
func (a *Athena) GeneratePlan(ctx context.Context, brief string, opts PlanOpts) (*PlanSpec, error)

// ParsePlan unmarshals raw YAML bytes into a PlanSpec and validates it.
func ParsePlan(yamlBytes []byte) (*PlanSpec, error)

// ValidatePlan checks structural invariants: at least one checkpoint,
// no duplicate IDs, valid dependency references, no circular dependencies,
// and all agents are in the known set.
func ValidatePlan(plan *PlanSpec) error

// ExtractYAML pulls the YAML block out of an LLM response.
func ExtractYAML(raw string) ([]byte, error)

// ToYAML marshals a PlanSpec back to YAML bytes.
func ToYAML(plan *PlanSpec) ([]byte, error)

Options

type PlanOpts struct {
    Name     string   // plan name (default: "untitled-plan")
    Workflow string   // "launch-announcement", "weekly-newsletter", or "custom"
    Agents   []string // which agents to include (default: all five)
    MaxSteps int      // max checkpoints (default: 10)
    Persist  bool     // save to Hestia (default: true if hestia != nil)
}

Types

PlanSpec

The top-level plan schema matching the YAML format used across all Embercore plans.

Field Type Description
Name string Human-readable plan name
Version string Schema version
Description string What this plan does
AgentsUsed []string Agents referenced in checkpoints
Inputs []InputSpec Runtime parameters the plan requires
Checkpoints []StepSpec Ordered execution steps

InputSpec

Field Type Description
Name string Parameter name
Type string Data type (e.g. "string", "file")
Required bool Whether the input is mandatory
Description string What this input is for

StepSpec

Field Type Description
ID string Unique step identifier
Agent string Agent name (must be in KnownAgents)
Action string What the agent should do
DependsOn []string IDs of steps that must complete first
Outputs []string Expected output artifacts

KnownAgents

var KnownAgents = map[string]bool{
    "Athena": true, "Apollo": true, "Hephaestus": true,
    "Hestia": true, "Hermes": true,
}

Example

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/embercore-labs/embercore/packages/engine/agents/athena"
    "github.com/embercore-labs/embercore/packages/engine/internal/provider"
)

func main() {
    p, err := provider.NewFromEnv()
    if err != nil {
        log.Fatal(err)
    }

    a := athena.New(p, nil) // nil hestia = no persistence
    spec, err := a.GeneratePlan(context.Background(), "Launch a developer newsletter", athena.PlanOpts{
        Name:     "dev-newsletter-launch",
        MaxSteps: 8,
    })
    if err != nil {
        log.Fatal(err)
    }

    yamlBytes, _ := athena.ToYAML(spec)
    fmt.Println(string(yamlBytes))
}

CLI

# Generate a plan
embercore plan "Launch a SaaS product for project management"

# Save to file
embercore plan "Weekly newsletter campaign" -o newsletter.yaml

# Use a specific provider
embercore plan "Product launch" --provider openai --model gpt-4o

Hermes — The Executor

Package: agents/hermes

Hermes is the execution orchestrator. It takes a parsed plan and runs each step in topological order, pausing at checkpoints for human approval when a handler is configured. Hermes manages run lifecycle via Hestia and supports resume-from-checkpoint for interrupted runs.

API

// New creates a Hermes engine instance.
func New(p provider.Provider, h *hestia.Hestia, logger *slog.Logger) *Hermes

// ExecutePlan runs a plan from the beginning. Creates a Run via Hestia,
// then walks topologically-sorted layers, executing steps and pausing
// at checkpoints when required.
func (h *Hermes) ExecutePlan(ctx context.Context, spec *plan.Spec, opts ExecOpts) (*ExecResult, error)

// ResumePlan resumes a paused run from the last completed checkpoint.
func (h *Hermes) ResumePlan(ctx context.Context, runID string) (*ExecResult, error)

// WithCheckpointHandler sets a custom handler for checkpoint pauses.
// If not set, ExecutePlan pauses the run and returns status "paused".
func (h *Hermes) WithCheckpointHandler(handler CheckpointHandler) *Hermes

Types

ExecOpts

Field Type Description
AutoApprove bool Skip checkpoint approval prompts
PlanID string Existing plan ID (if already persisted)
InputData map[string]interface{} Runtime inputs for plan parameters

ExecResult

Field Type Description
RunID string UUID of this execution run
Status string "completed", "paused", or "failed"
Steps []StepResult Per-step results
Error error Error details if failed

StepResult

Field Type Description
StepID string ID of the executed step
Agent string Agent that ran the step
Status string "completed", "failed", or "skipped"
Output string Agent output content
Elapsed time.Duration Wall-clock execution time

CheckpointHandler

// Called at each checkpoint pause.
// Return true to approve and continue, false to reject/pause.
type CheckpointHandler func(step plan.Step, output string) (approved bool, feedback string, err error)

Example

package main

import (
    "context"
    "fmt"
    "log"
    "log/slog"
    "os"

    "github.com/embercore-labs/embercore/packages/engine/agents/hermes"
    "github.com/embercore-labs/embercore/packages/engine/agents/hestia"
    "github.com/embercore-labs/embercore/packages/engine/internal/provider"
    "github.com/embercore-labs/embercore/packages/engine/plan"
)

func main() {
    p, _ := provider.NewFromEnv()
    h, _ := hestia.New("data.db")

    spec, _ := plan.Parse([]byte(`
name: demo
version: "1"
description: Demo plan
agents_used: [Athena]
checkpoints:
  - id: step1
    agent: Athena
    action: "Generate outline"
    outputs: [outline.md]
`))

    herm := hermes.New(p, h, slog.Default())

    // Auto-approve all checkpoints
    result, err := herm.ExecutePlan(context.Background(), spec, hermes.ExecOpts{
        AutoApprove: true,
    })
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("Run %s: %s (%d steps)\n", result.RunID, result.Status, len(result.Steps))
}

CLI

# Run by plan ID
embercore run <plan-id>

# Run from a YAML file
embercore run my-plan.yaml

# Auto-approve all checkpoints
embercore run <plan-id> --auto-approve

# Resume a paused run
embercore resume <run-id>

Apollo — The Copywriter

Package: agents/apollo

Apollo generates marketing copy across seven content types: blog posts, emails, social media posts, headlines, ads, landing pages, and newsletters. It supports tone control, audience targeting, word count constraints, SEO keyword integration, and iterative refinement.

API

// New creates an Apollo agent with the given options.
func New(opts ...Option) *Apollo

// GenerateCopy produces marketing content based on the request.
// Builds a specialised prompt, calls the LLM, and parses the response
// into a structured CopyResult with metadata and optional variants.
func (a *Apollo) GenerateCopy(ctx context.Context, req CopyRequest) (*CopyResult, error)

// Refine takes existing copy and feedback, then generates an improved version.
// The original result is preserved; a new CopyResult is returned.
func (a *Apollo) Refine(ctx context.Context, original *CopyResult, feedback string) (*CopyResult, error)

Options

// WithProvider sets the LLM provider.
func WithProvider(p provider.Provider) Option

// WithHestia enables persistence via Hestia.
func WithHestia(h *hestia.Hestia) Option

// WithModel overrides the default model for completions.
func WithModel(m string) Option

Types

ContentType

Constant Value Description
TypeBlog "blog" Blog post
TypeEmail "email" Email body
TypeSocial "social" Social media post
TypeHeadline "headline" Headline / tagline
TypeAd "ad" Advertisement copy
TypeLanding "landing-page" Landing page content
TypeNewsletter "newsletter" Newsletter edition

CopyRequest

Field Type Description
Type ContentType Kind of content to generate
Brief string What to write about
Tone string "professional", "casual", "playful", "urgent", "inspirational"
Audience string Target audience description
Constraints Constraints Word count, format, platform, SEO
Context []string Additional context or reference material

Constraints

Field Type Description
MaxWords int Maximum word count
MinWords int Minimum word count
Platform string "twitter", "linkedin", "instagram", "facebook"
Format string "markdown", "html", "plain"
Keywords []string SEO keywords to include
CTAText string Call-to-action text

CopyResult

Field Type Description
Content string Generated copy
Type ContentType Content type used
WordCount int Word count of output
Metadata CopyMetadata Quality signals
Variants []Variant Alternative versions (social/ad types)

CopyMetadata

Field Type Description
Tone string Detected tone
ReadingLevel string "easy", "moderate", "advanced"
SEOScore int 0–100 based on keyword inclusion
Suggestions []string Improvement suggestions

Variant

Field Type Description
Label string e.g. "shorter", "more casual", "with emoji"
Content string Alternative content

Example

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/embercore-labs/embercore/packages/engine/agents/apollo"
    "github.com/embercore-labs/embercore/packages/engine/internal/provider"
)

func main() {
    p, _ := provider.NewFromEnv()

    a := apollo.New(
        apollo.WithProvider(p),
        apollo.WithModel("claude-sonnet-4-20250514"),
    )

    result, err := a.GenerateCopy(context.Background(), apollo.CopyRequest{
        Type:     apollo.TypeBlog,
        Brief:    "Write a blog post about the benefits of local-first AI tools for solo founders",
        Tone:     "professional",
        Audience: "indie hackers and solo SaaS founders",
        Constraints: apollo.Constraints{
            MinWords: 800,
            MaxWords: 1500,
            Keywords: []string{"local-first", "AI tools", "solo founder"},
            CTAText:  "Try Embercore today",
        },
    })
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("Word count: %d | SEO Score: %d\n", result.WordCount, result.Metadata.SEOScore)
    fmt.Println(result.Content)

    // Refine based on feedback
    revised, _ := a.Refine(context.Background(), result, "Make it more conversational and add a personal anecdote intro")
    fmt.Println(revised.Content)
}

Hephaestus — The Builder

Package: agents/hephaestus

Hephaestus assembles content from other agents into final deliverables: HTML emails, formatted blog posts, social media packages, campaign kits, landing pages, and newsletters. It supports three assembly strategies: named templates, LLM-enhanced assembly, and deterministic (no-LLM) assembly.

API

// New creates a Hephaestus agent with the given options.
func New(opts ...Option) *Hephaestus

// Build assembles a deliverable from content pieces. It tries in order:
// 1. Named template (if Template is set)
// 2. LLM-enhanced assembly (if provider is available)
// 3. Deterministic assembly using built-in assembler functions
func (h *Hephaestus) Build(ctx context.Context, req BuildRequest) (*BuildResult, error)

// BuildFromTemplate is a convenience method that assembles content
// using a named built-in template.
func (h *Hephaestus) BuildFromTemplate(ctx context.Context, templateName string, data map[string]string) (*BuildResult, error)

Options

// WithProvider sets the LLM provider for enhanced assembly.
func WithProvider(p provider.Provider) Option

// WithHestia enables persistence via Hestia.
func WithHestia(h *hestia.Hestia) Option

// WithModel overrides the default model for completions.
func WithModel(m string) Option

// WithRunID sets the run ID for artifact persistence.
func WithRunID(id string) Option

Types

OutputType

Constant Value Description
TypeEmailHTML "email-html" HTML email
TypeBlogPost "blog-post" Formatted blog post
TypeSocialPack "social-pack" Multi-platform social package
TypeCampaignKit "campaign-kit" Bundle of multiple deliverables
TypeLandingPage "landing-page" Landing page HTML
TypeNewsletterHTML "newsletter-html" Newsletter HTML

OutputFormat

Constant Value
FormatHTML "html"
FormatMarkdown "markdown"
FormatPlaintext "plaintext"
FormatJSON "json"

BuildRequest

Field Type Description
Type OutputType Kind of deliverable to build
Content map[string]string Keyed content pieces (e.g. "headline", "body")
Template string Optional named template
Format OutputFormat Output format override
Assets []Asset Images, attachments, logos
Config BuildConfig Assembly configuration

BuildConfig

Field Type Description
Brand BrandKit Brand identity values
Responsive bool Generate responsive HTML
Inline bool Inline CSS (for email clients)
MinifyHTML bool Minify output HTML

BrandKit

Field Type Description
PrimaryColor string Primary brand colour
SecondaryColor string Secondary brand colour
FontFamily string CSS font family
LogoURL string URL to logo image
CompanyName string Company name for footer
FooterText string Custom footer text

BuildResult

Field Type Description
Output string Assembled content
Format OutputFormat Output format
Type OutputType Deliverable type
Artifacts []ArtifactRef Persisted artifact references
Warnings []string Any issues during assembly

Built-in templates

Template Name Output Type Format
"email-basic" email-html HTML
"blog-standard" blog-post Markdown
"social-thread" social-pack Plaintext

Example

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/embercore-labs/embercore/packages/engine/agents/hephaestus"
    "github.com/embercore-labs/embercore/packages/engine/internal/provider"
)

func main() {
    p, _ := provider.NewFromEnv()

    h := hephaestus.New(
        hephaestus.WithProvider(p),
    )

    // Build an HTML email from content pieces
    result, err := h.Build(context.Background(), hephaestus.BuildRequest{
        Type: hephaestus.TypeEmailHTML,
        Content: map[string]string{
            "headline":      "Introducing Embercore",
            "body":          "Build your marketing engine with AI agents...",
            "cta_text":      "Get Started Free",
            "cta_url":       "https://embercore.dev",
            "email_subject": "Your marketing just got an upgrade",
        },
        Config: hephaestus.BuildConfig{
            Brand: hephaestus.BrandKit{
                PrimaryColor: "#FF6B35",
                CompanyName:  "Embercore Labs",
                FontFamily:   "Inter, sans-serif",
            },
            Inline:     true,
            MinifyHTML: true,
        },
    })
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("Format: %s | Size: %d bytes\n", result.Format, len(result.Output))

    // Or use a template
    tmplResult, _ := h.BuildFromTemplate(context.Background(), "email-basic", map[string]string{
        "headline": "Weekly Update",
        "body":     "Here's what happened this week...",
    })
    fmt.Println(tmplResult.Output)
}

Hestia — The Memory Agent

Package: agents/hestia

Hestia is the persistence layer — a thin wrapper over the SQLite store that composes storage operations into workflow patterns. All other agents use Hestia to save plans, track runs, record checkpoints, persist artifacts, and support resume-from-checkpoint.

API

// New creates a Hestia instance backed by SQLite at dbPath.
func New(dbPath string) (*Hestia, error)

// SavePlan creates a plan with initial metadata. Returns the plan ID.
func (h *Hestia) SavePlan(ctx context.Context, name, yamlContent, brief string) (string, error)

// StartRun creates a new run for the given plan and sets the plan to active.
// Returns the run ID.
func (h *Hestia) StartRun(ctx context.Context, planID string) (string, error)

// RecordCheckpoint creates a completed checkpoint for a run.
func (h *Hestia) RecordCheckpoint(ctx context.Context, runID, stepID, agent, output string) error

// GetRunState returns the full state tree: run, plan, checkpoints, artifacts.
func (h *Hestia) GetRunState(ctx context.Context, runID string) (*store.RunState, error)

// ResumeRun finds the last completed checkpoint and returns the state
// needed to resume execution from that point.
func (h *Hestia) ResumeRun(ctx context.Context, runID string) (*store.RunState, error)

Hestia also embeds *store.Store, exposing these lower-level methods:

// Plans
func (s *Store) CreatePlan(ctx context.Context, p Plan) (string, error)
func (s *Store) GetPlan(ctx context.Context, id string) (*Plan, error)
func (s *Store) ListPlans(ctx context.Context, opts ListOpts) ([]Plan, error)
func (s *Store) UpdatePlanStatus(ctx context.Context, id, status string) error

// Runs
func (s *Store) CreateRun(ctx context.Context, r Run) (string, error)
func (s *Store) GetRun(ctx context.Context, id string) (*Run, error)
func (s *Store) GetLatestRun(ctx context.Context, planID string) (*Run, error)
func (s *Store) UpdateRunStatus(ctx context.Context, id, status, currentStep string) error
func (s *Store) ListRuns(ctx context.Context, planID string, opts ListOpts) ([]Run, error)

// Checkpoints
func (s *Store) CreateCheckpoint(ctx context.Context, cp Checkpoint) (string, error)
func (s *Store) GetCheckpoint(ctx context.Context, id string) (*Checkpoint, error)
func (s *Store) ListCheckpointsByPlan(ctx context.Context, planID string) ([]Checkpoint, error)
func (s *Store) UpdateCheckpointStatus(ctx context.Context, id, status string) error
func (s *Store) ApproveCheckpoint(ctx context.Context, id, approvedBy string) error

// Artifacts
func (s *Store) CreateArtifact(ctx context.Context, a Artifact) (string, error)
func (s *Store) GetArtifact(ctx context.Context, id string) (*Artifact, error)
func (s *Store) ListArtifactsByRun(ctx context.Context, runID string) ([]Artifact, error)

Types

See Architecture Guide — Storage Models for the full Plan, Run, Checkpoint, Artifact, and RunState type definitions.

Example

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/embercore-labs/embercore/packages/engine/agents/hestia"
    "github.com/embercore-labs/embercore/packages/engine/internal/store"
)

func main() {
    h, err := hestia.New("~/.embercore/data.db")
    if err != nil {
        log.Fatal(err)
    }

    ctx := context.Background()

    // Save a plan
    planID, _ := h.SavePlan(ctx, "My Campaign", "<yaml>...</yaml>", "Launch a newsletter")
    fmt.Println("Plan:", planID)

    // Start a run
    runID, _ := h.StartRun(ctx, planID)
    fmt.Println("Run:", runID)

    // Record a checkpoint
    _ = h.RecordCheckpoint(ctx, runID, "step-1", "Athena", "Generated outline")

    // Get full state
    state, _ := h.GetRunState(ctx, runID)
    fmt.Printf("Run status: %s, Checkpoints: %d\n", state.Run.Status, len(state.Checkpoints))

    // List all plans
    plans, _ := h.ListPlans(ctx, store.ListOpts{Limit: 10})
    for _, p := range plans {
        fmt.Printf("  %s: %s (%s)\n", p.ID, p.Name, p.Status)
    }
}

CLI

# List all plans (uses Hestia internally)
embercore status

# Show plan detail with checkpoints
embercore status <plan-id>

Agent Interaction Map

┌──────────────────────────────────────────────────────────┐
│                     User / MCP Client                     │
└──────────────────────────┬───────────────────────────────┘
                           │ Brief
                           ▼
                   ┌───────────────┐
                   │    Athena     │  plan generation
                   │   (planner)   │
                   └───────┬───────┘
                           │ PlanSpec (YAML)
                           ▼
                   ┌───────────────┐
                   │    Hermes     │  topological execution
                   │  (executor)   │◄──── CheckpointHandler
                   └───────┬───────┘
                           │ dispatches steps to:
                  ┌────────┼────────┐
                  ▼        │        ▼
          ┌──────────┐     │  ┌────────────┐
          │  Apollo   │     │  │ Hephaestus │
          │  (copy)   │     │  │  (build)   │
          └────┬─────┘     │  └─────┬──────┘
               │           │        │
               └─────┬─────┘        │
                     │              │
                     ▼              ▼
               ┌──────────────────────┐
               │       Hestia         │  persistence
               │   (SQLite store)     │
               └──────────────────────┘

See Also