dsl

package
v0.2.1 Latest Latest
Warning

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

Go to latest
Published: Feb 24, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package dsl provides a YAML-based domain-specific language for defining AI agent teams and workflows without writing Go code.

DSL Overview

The DSL uses YAML files (typically named *.vega.yaml) to define:

  • Agents: AI assistants with specific roles and capabilities
  • Workflows: Multi-step processes that coordinate agents
  • Tools: Custom tool definitions with various implementations
  • Settings: Global configuration like rate limits and budgets

Basic Example

A simple .vega.yaml file:

name: My Team

agents:
  assistant:
    model: claude-sonnet-4-20250514
    system: You are a helpful assistant.

workflows:
  greet:
    inputs:
      name:
        type: string
        required: true
    steps:
      - assistant:
          send: "Hello, {{name}}!"
          save: greeting
    output: "{{greeting}}"

Using the DSL

Parse and execute a DSL file:

parser := dsl.NewParser()
doc, err := parser.ParseFile("team.vega.yaml")
if err != nil {
    log.Fatal(err)
}

interp, err := dsl.NewInterpreter(doc)
if err != nil {
    log.Fatal(err)
}
defer interp.Shutdown()

result, err := interp.Execute(ctx, "greet", map[string]any{
    "name": "World",
})

Expression Syntax

The DSL supports {{expression}} interpolation:

{{variable}}           - Simple variable reference
{{step1.field}}        - Nested field access
{{value | upper}}      - Filter/transform
{{name | default:anon}} - Filter with argument

Available filters: upper, lower, trim, default, lines, words, truncate, join

Control Flow

The DSL supports various control structures:

# Conditionals
- if: "{{approved}}"
  then:
    - agent: ...
  else:
    - agent: ...

# Loops
- for: item in items
  steps:
    - agent:
        send: "Process {{item}}"

# Repeat until condition
- repeat:
    max: 5
    until: "'done' in result"
    steps:
      - agent: ...

# Parallel execution
- parallel:
    - agent1: ...
    - agent2: ...

See the examples/ directory in the repository for complete examples.

Package dsl provides the Vega DSL parser and interpreter.

Index

Constants

View Source
const HermesAgentName = hermesAgentName

HermesAgentName is the canonical name for the Hermes meta-agent.

Variables

This section is empty.

Functions

func BuildTeamPrompt

func BuildTeamPrompt(system string, team []string, agentDescriptions map[string]string, blackboardEnabled bool) string

BuildTeamPrompt appends team delegation instructions to a system prompt. agentDescriptions is optional — if a member has a description it is shown. When blackboardEnabled is true, instructions about bb_read/bb_write/bb_list tools are appended.

func ContainsExpression

func ContainsExpression(s string) bool

ContainsExpression checks if a string contains expressions.

func ExtractExpressions

func ExtractExpressions(s string) []string

ExtractExpressions finds all {{...}} expressions in a string.

func FormatDelegationContext

func FormatDelegationContext(dc *DelegationContext, message string) string

FormatDelegationContext wraps the original message with caller context as XML.

func InjectHermes

func InjectHermes(interp *Interpreter, extraTools ...string) error

InjectHermes adds Hermes to the interpreter. extraTools are additional tool names (e.g. memory tools) to include in Hermes's tool list. They must already be registered on the interpreter.

func InjectMother

func InjectMother(interp *Interpreter, cb *MotherCallbacks, extraTools ...string) error

InjectMother adds the Mother agent to the interpreter. It registers the meta-tools and then adds Mother as an agent. extraTools are additional tool names (e.g. scheduler tools) to include in Mother's tool list. They must already be registered on the interpreter.

func IsHermesTool

func IsHermesTool(name string) bool

IsHermesTool reports whether a tool name is one of Hermes's tools.

func IsMotherTool

func IsMotherTool(name string) bool

IsMotherTool reports whether a tool name is one of Mother's meta-tools.

func NewBlackboardListTool

func NewBlackboardListTool(getGroup GroupResolver) tools.ToolDef

NewBlackboardListTool creates a tool that lists all keys on the team blackboard.

func NewBlackboardReadTool

func NewBlackboardReadTool(getGroup GroupResolver) tools.ToolDef

NewBlackboardReadTool creates a tool that reads a key from the team blackboard.

func NewBlackboardWriteTool

func NewBlackboardWriteTool(getGroup GroupResolver) tools.ToolDef

NewBlackboardWriteTool creates a tool that writes a key/value pair to the team blackboard.

func NewDelegateTool

func NewDelegateTool(sendFn SendFunc, team []string) tools.ToolDef

NewDelegateTool returns a tools.ToolDef for the delegate tool. sendFn is called when the tool is invoked to relay a message to another agent. team constrains which agents can be delegated to; if empty, any agent name is accepted.

func RegisterDelegateTool

func RegisterDelegateTool(t *tools.Tools, sendFn SendFunc, team []string) bool

RegisterDelegateTool registers the delegate tool on the given Tools instance if it is not already registered. team constrains which agents can be delegated to. Returns true if registration happened.

func RegisterHermesTools

func RegisterHermesTools(interp *Interpreter)

RegisterHermesTools registers Hermes's tools on the interpreter's global tool collection. list_agents is registered only if not already present (Mother registers it when she's injected).

func RegisterMotherTools

func RegisterMotherTools(interp *Interpreter, cb *MotherCallbacks)

RegisterMotherTools registers Mother's meta-tools on the interpreter's global tool collection. The callbacks are optional — when nil, no persistence hooks fire.

func RegisterSchedulerTools

func RegisterSchedulerTools(interp *Interpreter, backend SchedulerBackend)

RegisterSchedulerTools registers the four schedule-management tools on Mother's interpreter. Call this after InjectMother so the tools exist before Mother's tool list is finalised.

Types

type Agent

type Agent struct {
	Name          string          `yaml:"name"`
	Extends       string          `yaml:"extends"`
	Model         string          `yaml:"model"`
	FallbackModel string          `yaml:"fallback_model"`
	System        string          `yaml:"system"`
	Temperature   *float64        `yaml:"temperature"`
	Budget        string          `yaml:"budget"` // e.g., "$0.50"
	Tools         []string        `yaml:"tools"`
	Knowledge     []string        `yaml:"knowledge"`
	Team          []string        `yaml:"team"`
	Supervision   *SupervisionDef `yaml:"supervision"`
	Retry         *RetryDef       `yaml:"retry"`
	Skills        *SkillsDef      `yaml:"skills"`
	Delegation    *DelegationDef  `yaml:"delegation"`
}

Agent represents an agent definition in the DSL.

func HermesAgent

func HermesAgent(defaultModel string) *Agent

HermesAgent returns the DSL agent definition for Hermes.

func MotherAgent

func MotherAgent(defaultModel string) *Agent

MotherAgent returns the DSL agent definition for Mother.

type DelegationContext

type DelegationContext struct {
	CallerAgent string
	Messages    []llm.Message
}

DelegationContext holds extracted caller context for enriched delegation.

func ExtractCallerContext

func ExtractCallerContext(callerProc *vega.Process, config *DelegationDef) *DelegationContext

ExtractCallerContext reads the last N messages from the caller process, optionally filtering by role. Returns nil if no messages match.

type DelegationDef

type DelegationDef struct {
	ContextWindow int      `yaml:"context_window"` // number of recent messages to forward
	IncludeRoles  []string `yaml:"include_roles"`  // filter by role (user, assistant, system)
	Blackboard    bool     `yaml:"blackboard"`     // enable shared blackboard for team
}

DelegationDef configures context-aware delegation for an agent.

type Document

type Document struct {
	Name        string               `yaml:"name"`
	Description string               `yaml:"description"`
	Agents      map[string]*Agent    `yaml:"agents"`
	Workflows   map[string]*Workflow `yaml:"workflows"`
	Tools       map[string]*ToolDef  `yaml:"tools"`
	Settings    *Settings            `yaml:"settings"`
}

Document represents a parsed .vega.yaml file.

type ExecutionContext

type ExecutionContext struct {
	// Inputs are the workflow input values
	Inputs map[string]any

	// Variables holds step outputs and set values
	Variables map[string]any

	// CurrentStep is the index of the executing step
	CurrentStep int

	// LoopState for loop iterations
	LoopState *LoopState

	// StartTime is when execution began
	StartTime time.Time

	// Timeout for the entire workflow
	Timeout time.Duration
}

ExecutionContext holds state during workflow execution.

type GlobalSkillsDef

type GlobalSkillsDef struct {
	Directories []string `yaml:"directories"`
}

GlobalSkillsDef configures global skill settings.

type GroupResolver

type GroupResolver func(ctx context.Context) *vega.ProcessGroup

GroupResolver returns the team ProcessGroup for the calling process.

type Input

type Input struct {
	Type        string   `yaml:"type"`
	Description string   `yaml:"description"`
	Required    bool     `yaml:"required"`
	Default     any      `yaml:"default"`
	Enum        []string `yaml:"enum"`
	Min         *float64 `yaml:"min"`
	Max         *float64 `yaml:"max"`
}

Input defines a workflow input parameter.

type Interpreter

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

Interpreter executes DSL workflows.

func NewInterpreter

func NewInterpreter(doc *Document, opts ...InterpreterOption) (*Interpreter, error)

NewInterpreter creates a new interpreter for a document.

func (*Interpreter) AddAgent

func (i *Interpreter) AddAgent(name string, def *Agent) error

AddAgent adds and spawns a new agent at runtime.

func (*Interpreter) Agents

func (i *Interpreter) Agents() map[string]*vega.Process

Agents returns a copy of the active agent processes map.

func (*Interpreter) Document

func (i *Interpreter) Document() *Document

Document returns the parsed DSL document.

func (*Interpreter) EnsureAgent

func (i *Interpreter) EnsureAgent(name string) (*vega.Process, error)

EnsureAgent ensures the named agent process is spawned and returns it. If the process already exists it is returned immediately; otherwise the agent is lazily spawned from its definition.

func (*Interpreter) Execute

func (i *Interpreter) Execute(ctx context.Context, name string, inputs map[string]any) (any, error)

Execute runs a workflow by name (alias for RunWorkflow).

func (*Interpreter) Orchestrator

func (i *Interpreter) Orchestrator() *vega.Orchestrator

Orchestrator returns the underlying orchestrator.

func (*Interpreter) RemoveAgent

func (i *Interpreter) RemoveAgent(name string) error

RemoveAgent stops and removes an agent at runtime.

func (*Interpreter) ResetAgent

func (i *Interpreter) ResetAgent(name string) error

ResetAgent kills the agent process and removes it from the active map, but preserves the agent definition so it respawns fresh on next use.

func (*Interpreter) RunWorkflow

func (i *Interpreter) RunWorkflow(ctx context.Context, name string, inputs map[string]any) (any, error)

RunWorkflow executes a workflow by name.

func (*Interpreter) SendToAgent

func (i *Interpreter) SendToAgent(ctx context.Context, agentName string, message string) (string, error)

SendToAgent sends a message to a specific agent and returns the response. If the calling context carries an event sink (from a streaming parent), SendToAgent uses streaming and forwards nested tool_start/tool_end events to the parent sink so the UI can display sub-agent activity in real time.

func (*Interpreter) Shutdown

func (i *Interpreter) Shutdown()

Shutdown stops all agents and disconnects MCP servers.

func (*Interpreter) SkillsLoader

func (i *Interpreter) SkillsLoader() *skills.Loader

SkillsLoader returns the global skills loader, or nil if none is configured.

func (*Interpreter) StreamToAgent

func (i *Interpreter) StreamToAgent(ctx context.Context, agentName string, message string) (*vega.ChatStream, error)

StreamToAgent sends a message to a specific agent and returns a ChatStream with structured events for real-time streaming and tool call visibility.

func (*Interpreter) Tools

func (i *Interpreter) Tools() *tools.Tools

Tools returns the tool registry.

type InterpreterOption

type InterpreterOption func(*Interpreter)

InterpreterOption configures the interpreter.

func WithLazySpawn

func WithLazySpawn() InterpreterOption

WithLazySpawn defers agent process creation until first use. Useful for serve mode where agents are only needed when workflows run.

type LoggingDef

type LoggingDef struct {
	Level string `yaml:"level"` // debug, info, warn, error
	File  string `yaml:"file"`
}

LoggingDef is DSL logging configuration.

type LoopState

type LoopState struct {
	Index int
	Count int
	Item  any
	First bool
	Last  bool
}

LoopState tracks loop iteration state.

type MCPDef

type MCPDef struct {
	Servers []MCPServerDef `yaml:"servers"`
}

MCPDef configures MCP servers.

type MCPServerDef

type MCPServerDef struct {
	Name         string            `yaml:"name"`
	Transport    string            `yaml:"transport"`
	Command      string            `yaml:"command"`
	Args         []string          `yaml:"args"`
	Env          map[string]string `yaml:"env"`
	URL          string            `yaml:"url"`
	Headers      map[string]string `yaml:"headers"`
	Timeout      string            `yaml:"timeout"`
	FromRegistry bool              `yaml:"-"` // resolved from registry, not serialized
}

MCPServerDef configures an individual MCP server.

type MotherCallbacks

type MotherCallbacks struct {
	OnAgentCreated func(agent *Agent) error
	OnAgentDeleted func(name string)
}

MotherCallbacks receives notifications when Mother creates or deletes agents. Serve mode uses this to persist composed agents to the database.

type Parser

type Parser struct {
	// BaseDir for resolving relative paths
	BaseDir string
}

Parser parses .vega.yaml files.

func NewParser

func NewParser() *Parser

NewParser creates a new parser.

func (*Parser) Parse

func (p *Parser) Parse(data []byte) (*Document, error)

Parse parses YAML content into a Document.

func (*Parser) ParseFile

func (p *Parser) ParseFile(path string) (*Document, error)

ParseFile parses a .vega.yaml file.

type RateLimitDef

type RateLimitDef struct {
	RequestsPerMinute int `yaml:"requests_per_minute"`
	TokensPerMinute   int `yaml:"tokens_per_minute"`
}

RateLimitDef is DSL rate limit configuration.

type Repeat

type Repeat struct {
	Steps []Step `yaml:"steps"`
	Until string `yaml:"until"`
	Max   int    `yaml:"max"`
}

Repeat defines a repeat-until loop.

type RetryDef

type RetryDef struct {
	MaxAttempts int    `yaml:"max_attempts"`
	Backoff     string `yaml:"backoff"` // linear, exponential, constant
}

RetryDef is DSL retry configuration.

type ScheduledJob

type ScheduledJob struct {
	Name      string `json:"name"`
	Cron      string `json:"cron"`    // standard 5-field cron expression
	AgentName string `json:"agent"`   // agent to message on schedule
	Message   string `json:"message"` // message to send
	Enabled   bool   `json:"enabled"`
}

ScheduledJob describes a recurring agent trigger.

type SchedulerBackend

type SchedulerBackend interface {
	AddJob(job ScheduledJob) error
	RemoveJob(name string) error
	ListJobs() []ScheduledJob
}

SchedulerBackend is the interface that serve.Scheduler implements. Defined here so dsl/ does not import serve/.

type SendFunc

type SendFunc func(ctx context.Context, agent string, message string) (string, error)

SendFunc sends a message to a named agent and returns the response.

type Settings

type Settings struct {
	DefaultModel       string           `yaml:"default_model"`
	DefaultTemperature *float64         `yaml:"default_temperature"`
	Sandbox            string           `yaml:"sandbox"`
	Budget             string           `yaml:"budget"`
	Supervision        *SupervisionDef  `yaml:"supervision"`
	RateLimit          *RateLimitDef    `yaml:"rate_limit"`
	Logging            *LoggingDef      `yaml:"logging"`
	Tracing            *TracingDef      `yaml:"tracing"`
	MCP                *MCPDef          `yaml:"mcp"`
	Skills             *GlobalSkillsDef `yaml:"skills"`
}

Settings are global configuration.

type SkillsDef

type SkillsDef struct {
	Directories []string `yaml:"directories"`
	Include     []string `yaml:"include"`
	Exclude     []string `yaml:"exclude"`
	MaxActive   int      `yaml:"max_active"`
}

SkillsDef configures skills for an agent.

type Step

type Step struct {
	// Agent step fields
	Agent           string `yaml:"-"` // Extracted from key
	Action          string `yaml:"-"` // Extracted from key
	Send            string `yaml:"send"`
	Save            string `yaml:"save"`
	Timeout         string `yaml:"timeout"`
	Budget          string `yaml:"budget"`
	Retry           int    `yaml:"retry"`
	If              string `yaml:"if"`
	ContinueOnError bool   `yaml:"continue_on_error"`
	Format          string `yaml:"format"` // json, yaml, etc.

	// Control flow fields
	Condition string `yaml:"-"` // For if steps
	Then      []Step `yaml:"then"`
	Else      []Step `yaml:"else"`

	// Loop fields
	ForEach string  `yaml:"for"` // "item in items"
	Repeat  *Repeat `yaml:"repeat"`

	// Parallel fields
	Parallel []Step `yaml:"parallel"`

	// Sub-workflow fields
	Workflow string         `yaml:"workflow"`
	With     map[string]any `yaml:"with"`

	// Special fields
	Set    map[string]any `yaml:"set"`
	Return string         `yaml:"return"`
	Try    []Step         `yaml:"try"`
	Catch  []Step         `yaml:"catch"`

	// Raw for flexible parsing
	Raw map[string]any `yaml:"-"`
}

Step is a workflow step (can be various types). This uses a flexible structure to handle the natural language format.

type SupervisionDef

type SupervisionDef struct {
	Strategy    string `yaml:"strategy"` // restart, stop, escalate
	MaxRestarts int    `yaml:"max_restarts"`
	Window      string `yaml:"window"` // e.g., "10m"
}

SupervisionDef is DSL supervision configuration.

type ToolDef

type ToolDef struct {
	Name           string      `yaml:"name"`
	Description    string      `yaml:"description"`
	Params         []ToolParam `yaml:"params"`
	Implementation *ToolImpl   `yaml:"implementation"`
	Include        []string    `yaml:"include"` // For loading from files
}

ToolDef is a DSL tool definition.

type ToolImpl

type ToolImpl struct {
	Type    string            `yaml:"type"` // http, exec, file_read, file_write, builtin
	Method  string            `yaml:"method"`
	URL     string            `yaml:"url"`
	Headers map[string]string `yaml:"headers"`
	Query   map[string]string `yaml:"query"`
	Body    any               `yaml:"body"`
	Command string            `yaml:"command"`
	Timeout string            `yaml:"timeout"`
}

ToolImpl defines tool implementation.

type ToolParam

type ToolParam struct {
	Name        string   `yaml:"name"`
	Type        string   `yaml:"type"`
	Description string   `yaml:"description"`
	Required    bool     `yaml:"required"`
	Default     any      `yaml:"default"`
	Enum        []string `yaml:"enum"`
}

ToolParam defines a tool parameter.

type TracingDef

type TracingDef struct {
	Enabled  bool   `yaml:"enabled"`
	Exporter string `yaml:"exporter"` // otlp, jaeger, json
	Endpoint string `yaml:"endpoint"`
}

TracingDef is DSL tracing configuration.

type ValidationError

type ValidationError struct {
	File    string
	Line    int
	Column  int
	Field   string
	Message string
	Hint    string
}

ValidationError provides detailed DSL validation errors.

func (*ValidationError) Error

func (e *ValidationError) Error() string

type Workflow

type Workflow struct {
	Description string            `yaml:"description"`
	Inputs      map[string]*Input `yaml:"inputs"`
	Steps       []Step            `yaml:"steps"`
	Output      any               `yaml:"output"` // string or map
}

Workflow represents a workflow definition in the DSL.

Jump to

Keyboard shortcuts

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