agentml

package module
v0.1.0-beta.5 Latest Latest
Warning

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

Go to latest
Published: Dec 30, 2025 License: MIT Imports: 7 Imported by: 4

README

agentml-go

🚧 Early Alpha - Building in Public

agentml-go is in early alpha and being built openly with the community. The vision is ambitious, the foundation is solid, but many features are still in development. Join us in shaping the future of agent standards.

📋 This Repository: Contains Go implementations of AgentML namespace packages. These packages enable LLM integration, memory operations, I/O handling, and other capabilities for AgentML agents. For the language specification and runtime, see:

  • agentml - AgentML language specification and documentation
  • agentmlx - Reference runtime (Go/WASM) NOT YET RELEASED

📦 Available Namespaces

LLM Integration
  • openai/ - OpenAI LLM integration with GPT-4o and compatible models

    • Multi-model support (GPT-4o, GPT-4o mini, o1, and more)
    • Streaming and structured generation
    • Tools and JSON schema-style output
  • gemini/ - Google Gemini LLM integration with advanced features

    • Multi-model support (Flash, Pro, Thinking)
    • Streaming and structured generation
    • Rate limiting and complexity scoring
    • Tier-based model selection
  • ollama/ - Local LLM integration via Ollama

    • Run models locally
    • Full control over model selection
    • Privacy-first inference
Memory & Storage
  • memory/ - High-performance memory operations
    • Vector similarity search (powered by sqlite-vec)
    • Graph database with Cypher queries (powered by sqlite-graph)
    • Embedding generation
    • Persistent key-value storage
    • Everything in a single SQLite file
I/O & Utilities
  • stdin/ - Standard input/output for console agents
  • env/ - Environment variable and configuration loading
  • prompt/ - Prompt management and snapshot utilities
  • bubbletea/ - Interactive terminal UIs using Bubble Tea, emitting AgentML events
  • slack/ - Send messages to Slack channels/users and receive Slack events as AgentML events
  • mcp/ - Model Context Protocol client for connecting to MCP servers, tools, and resources
  • validate/ - AgentML content validation namespace for AML/SCXML diagnostics

🚀 Installation

Install individual packages as needed:

# OpenAI namespace
go get github.com/agentflare-ai/agentml-go/openai

# Gemini namespace
go get github.com/agentflare-ai/agentml-go/gemini

# Ollama namespace
go get github.com/agentflare-ai/agentml-go/ollama

# Memory namespace
go get github.com/agentflare-ai/agentml-go/memory

# Bubble Tea namespace
go get github.com/agentflare-ai/agentml-go/bubbletea

# Slack namespace
go get github.com/agentflare-ai/agentml-go/slack

# MCP namespace
go get github.com/agentflare-ai/agentml-go/mcp

# Validate namespace
go get github.com/agentflare-ai/agentml-go/validate

# Or install all at once
go get github.com/agentflare-ai/agentml-go/...

📖 Usage

In AgentML Files (.aml)

Reference these namespaces in your AgentML agent files:

<agentml xmlns="github.com/agentflare-ai/agentml"
       datamodel="ecmascript"
       xmlns:openai="github.com/agentflare-ai/agentml-go/openai"
       xmlns:memory="github.com/agentflare-ai/agentml-go/memory">

  <datamodel>
    <data id="user_input" expr="''" />
    <data id="embedding" expr="null" />
  </datamodel>

  <state id="process">
    <onentry>
      <!-- Generate embedding -->
      <memory:embed location="embedding" expr="user_input" />
      
      <!-- Query with OpenAI -->
      <openai:generate
        model="gpt-4o"
        location="_event"
        promptexpr="'Analyze: ' + user_input" />
    </onentry>
    
    <transition event="response.ready" target="complete" />
  </state>
</agentml>
In Go Code

Import and use namespace packages directly in Go:

package main

import (
    "context"
    "github.com/agentflare-ai/agentml-go/gemini"
    "github.com/agentflare-ai/agentml-go/memory"
)

func main() {
    ctx := context.Background()
    
    // Use Gemini client
    client, _ := gemini.NewClient(ctx, "YOUR_API_KEY")
    response, _ := client.Generate(ctx, "gemini-2.0-flash-exp", "Hello!")
    
    // Use memory operations
    db, _ := memory.Open("agent-memory.db")
    defer db.Close()
    
    // Store and search vectors
    embedding := []float32{0.1, 0.2, 0.3}
    db.StoreVector(ctx, "doc1", embedding, map[string]interface{}{
        "content": "Hello world",
    })
}

🏗️ Package Structure

Each namespace package includes:

namespace/
├── namespace.xsd        # XML Schema definition
├── namespace.go         # Namespace registration and core logic
├── executable.go        # Executable actions (AgentML runtime integration)
├── client.go            # Standalone client (optional, for direct Go usage)
├── *_test.go            # Tests
├── go.mod               # Go module definition
└── README.md            # Package-specific documentation

🔧 Development

Prerequisites
  • Go 1.24.5+
  • Make (optional)
  • Git with submodules support
Setup
# Clone the repository
git clone --recurse-submodules https://github.com/agentflare-ai/agentml-go.git
cd agentml-go

# Install dependencies
go mod download

# Run tests
go test ./...

# Run tests for specific package
go test ./gemini/...
Working with Go Workspace

This repository uses Go workspaces to manage multiple modules:

# Add new module to workspace
go work use ./new-namespace

# Sync workspace
go work sync
Running Tests
# All tests
go test ./...

# With coverage
go test -cover ./...

# Specific package
go test -v ./gemini/...

# Integration tests (requires API keys)
GEMINI_API_KEY=your-key go test ./gemini/ -run Integration

📝 Creating Custom Namespaces

To create a new namespace:

  1. Create package directory: mkdir my-namespace
  2. Add XSD schema: Define your namespace schema in my-namespace.xsd
  3. Implement actions: Create executable actions in executable.go
  4. Register namespace: Implement Register() function in namespace.go
  5. Add tests: Create comprehensive tests
  6. Document: Write README.md with examples

See existing namespaces (openai, gemini, ollama, memory, bubbletea, mcp, validate) as reference implementations.

🤝 Contributing

We welcome contributions! Please see CONTRIBUTING.md for guidelines.

Quick Start:

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests
  5. Submit a pull request

📚 Documentation

Package-Specific Docs

🔖 Versioning

This project follows Semantic Versioning:

  • Major: Breaking API changes
  • Minor: New features, backward compatible
  • Patch: Bug fixes, backward compatible

Releases are managed via GitHub Releases.

📄 License

MIT License - see LICENSE for details.

Copyright (c) 2025 AgentFlare AI

🆘 Support


Building the universal language for AI agents, one namespace at a time.

Documentation

Index

Constants

View Source
const (
	EventSystemVariable        = "_event"
	SessionIDSystemVariable    = "_sessionid"
	NameSystemVariable         = "_name"
	IOProcessorsSystemVariable = "_ioprocessors"
	XSystemVariable            = "_x"
)
View Source
const NamespaceURI = "github.com/agentflare-ai/agentml"
View Source
const RuntimeNamespaceURI = "github.com/agentflare-ai/agentmlx"

RuntimeNamespaceURI is the namespace for runtime snapshot elements

Variables

This section is empty.

Functions

This section is empty.

Types

type Assign

type Assign struct {
	xmldom.Element
	Location    string        // Location expression specifying where to assign the value
	Expr        string        // Optional value expression to evaluate and assign
	AssignType  string        // Optional type attribute for XML handling modes
	InlineNodes []xmldom.Node // Inline XML/text content if no expr
	Content     string        // Text content fallback
}

Assign changes the value of a location in the data model (SCXML 5.4)

type Cancel

type Cancel struct {
	xmldom.Element
	SendID     string // The ID of the send element to cancel
	SendIDExpr string // Optional expression to compute the send ID
}

Cancel cancels a previously sent event (SCXML 6.3)

type Clock

type Clock interface {
	// Now returns the current time
	Now() time.Time

	// Since returns the duration since the given time
	Since(t time.Time) time.Duration

	// Sleep pauses the current goroutine for at least the given duration
	Sleep(ctx context.Context, d time.Duration) error

	// After returns a channel that receives the current time after the given duration
	After(d time.Duration) <-chan time.Time

	// NewTimer creates a new timer that will send the current time after the given duration
	NewTimer(d time.Duration) Timer

	// NewTicker creates a new ticker that will send the current time every given duration
	NewTicker(d time.Duration) Ticker

	// TimeScale returns the current time scale (1.0 = real-time, 2.0 = 2x speed, etc.)
	TimeScale() float64

	// SetTimeScale sets the time scale for simulation (only applies to simulation clocks)
	SetTimeScale(scale float64)

	// Advance manually advances time by the given duration (only applies to mock clocks)
	Advance(d time.Duration)

	// Pause pauses time advancement (only applies to mock clocks)
	Pause()

	// Resume resumes time advancement (only applies to mock clocks)
	Resume()

	// IsPaused returns true if the clock is paused
	IsPaused() bool
}

Clock provides an abstraction over time for testing and simulation

type Content

type Content struct {
	xmldom.Element
	Expr string // Optional value expression to evaluate
	Body any    // Optional inline content body (XML, text, etc.)
}

Content represents content for data operations (SCXML 5.6)

type Data

type Data struct {
	xmldom.Element
	ID      string // The data element identifier
	Expr    string // Optional initial value expression
	Src     string // Optional external source URI
	Content any    // Optional XML content (for XPath data model)
}

Data represents a data element defined in the SCXML document.

type DataModel

type DataModel interface {
	// Initialize sets up the data model with initial data elements.
	// This is called when the SCXML document is loaded and should create
	// all data elements defined in <data> elements.
	Initialize(ctx context.Context, dataElements []Data) error

	// EvaluateValue evaluates a value expression and returns the result.
	// Used for <data expr="...">, <assign expr="...">, etc.
	// Returns an error if the expression cannot be evaluated.
	EvaluateValue(ctx context.Context, expression string) (any, error)

	// EvaluateCondition evaluates a conditional expression and returns a boolean.
	// Used for <transition cond="..."> and other conditional logic.
	// Returns an error if the expression cannot be evaluated as a boolean.
	EvaluateCondition(ctx context.Context, expression string) (bool, error)

	// EvaluateLocation evaluates a location expression and returns the value at that location.
	// Used for <param location="..."> and other location-based access.
	// Returns an error if the location is invalid or cannot be accessed.
	EvaluateLocation(ctx context.Context, location string) (any, error)

	// Assign assigns a value to a location in the data model.
	// Used for <assign location="..." expr="..."> operations.
	// Returns an error if the location is invalid or the assignment fails.
	Assign(ctx context.Context, location string, value any) error

	// GetVariable retrieves the value of a data element by ID.
	// Returns an error if the data element doesn't exist.
	GetVariable(ctx context.Context, id string) (any, error)

	// SetVariable sets the value of a data element by ID.
	// Returns an error if the data element doesn't exist or the value is invalid.
	SetVariable(ctx context.Context, id string, value any) error

	// GetSystemVariable retrieves a system variable value.
	// System variables include: _event, _sessionid, _name, _ioprocessors, _x
	// Returns an error if the system variable doesn't exist.
	GetSystemVariable(ctx context.Context, name string) (any, error)

	// SetSystemVariable sets a system variable value.
	// Most system variables are read-only and will return an error if modified.
	// Returns an error if the variable doesn't exist or cannot be modified.
	SetSystemVariable(ctx context.Context, name string, value any) error

	// SetCurrentEvent sets the _event system variable to the current event.
	// This is called by the interpreter when processing events.
	SetCurrentEvent(ctx context.Context, event any) error

	// ExecuteScript executes a script in the data model's context.
	// For ECMAScript data models, this executes JavaScript code with access to all variables.
	// For other data models, this may evaluate the script as an expression.
	// Returns an error if the script cannot be executed.
	ExecuteScript(ctx context.Context, script string) error

	// Clone creates a copy of the data model for use in parallel states.
	// The clone should share system variables but have independent data elements.
	Clone(ctx context.Context) (DataModel, error)

	// ValidateExpression validates that an expression is syntactically correct
	// for this data model. Returns nil if valid, error if invalid.
	ValidateExpression(ctx context.Context, expression string, exprType ExpressionType) error
}

type DataModelLoader

type DataModelLoader func(ctx context.Context, interpreter Interpreter) (DataModel, error)

type Event

type Event struct {
	ID         string    `json:"id"`                   // Unique event ID using MUID
	Name       string    `json:"name"`                 // Event name for matching
	Type       EventType `json:"type"`                 // Internal, external, or platform
	Delay      string    `json:"delay,omitempty"`      // Delay for delayed events
	Data       any       `json:"data"`                 // Event data payload
	Metadata   any       `json:"metadata,omitempty"`   // Metadata for the event
	InvokeID   string    `json:"invokeid,omitempty"`   // For invoked sessions
	Timestamp  time.Time `json:"timestamp"`            // When event was created
	Origin     string    `json:"origin,omitempty"`     // Origin of external events
	OriginType string    `json:"origintype,omitempty"` // Type of origin
	SendID     string    `json:"sendid,omitempty"`     // ID from send element
	Raw        string    `json:"raw,omitempty"`        // Raw data for HTTP events
	Target     string    `json:"target,omitempty"`     // Target URI from original send
	TargetType string    `json:"targettype,omitempty"` // I/O processor type URI from send
}

Event represents an SCXML event as defined in the W3C specification

type EventType

type EventType string

EventType represents the type of SCXML event

const (
	EventTypeInternal EventType = "internal"
	EventTypeExternal EventType = "external"
	EventTypePlatform EventType = "platform"
)

type ExecutionError

type ExecutionError struct {
	Message string
	Element xmldom.Element
}

ExecutionError represents an error that occurred during agentml execution

func (*ExecutionError) Error

func (e *ExecutionError) Error() string

type Executor

type Executor interface {
	xmldom.Element
	// Execute runs the executable content
	Execute(ctx context.Context, interpreter Interpreter) error
}

Executor represents any executable content that can be executed

type ExpressionType

type ExpressionType string

ExpressionType defines the type of expression being evaluated.

const (
	ValueExpression     ExpressionType = "value"
	ConditionExpression ExpressionType = "condition"
	LocationExpression  ExpressionType = "location"
)

type Filesystem

type Filesystem interface {
	Close() error
	Create(name string) (*os.File, error)
	FS() fs.FS
	Lstat(name string) (os.FileInfo, error)
	Mkdir(name string, perm os.FileMode) error
	Name() string
	Open(name string) (*os.File, error)
	OpenFile(name string, flag int, perm os.FileMode) (*os.File, error)
	Remove(name string) error
	Stat(name string) (os.FileInfo, error)
}

Filesystem provides sandboxed filesystem access for interpreters. It extends fs.FS with additional file operations needed for SCXML execution.

type Finalize

type Finalize struct {
	xmldom.Element
}

Finalize finalizes the session (SCXML 6.5)

type Foreach

type Foreach struct {
	xmldom.Element
	Array string // Value expression that evaluates to an iterable collection
	Item  string // Variable name to store each item during iteration
	Index string // Optional variable name to store iteration index
}

Foreach iterates over a collection in the data model (SCXML 4.6)

type IOProcessor

type IOProcessor interface {
	// Handle processes a fully-formed event using this I/O processor
	// This is the preferred method for I/O processor implementations.
	// The event contains all pre-evaluated data from the interpreter's data model.
	// IOProcessors should focus only on transport/communication logic.
	// ctx: context for tracing and cancellation
	// event: the event to handle (all data model evaluation already completed)
	// Returns error if transport/communication fails (e.g., error.communication)
	Handle(ctx context.Context, event *Event) error

	// Location returns the location/URI that external entities can use
	// to communicate with this SCXML session via this I/O processor
	// This is used to populate the _ioprocessors system variable
	Location(ctx context.Context) (string, error)

	// Type returns the I/O processor type URI (e.g., "github.com/agentflare-ai/agentml/ioprocessor/scxml")
	Type() string

	// Shutdown cleans up resources used by this I/O processor
	Shutdown(ctx context.Context) error
}

IOProcessor defines the interface that all I/O processors must implement according to W3C SCXML specification sections C.1 and C.2

type IOProcessorLoader

type IOProcessorLoader func(ctx context.Context, interpreter Interpreter) (IOProcessor, error)

type If

type If struct {
	xmldom.Element
	Cond        string      // Boolean condition expression
	Interpreter Interpreter // Reference to interpreter for recursive execution
}

If provides conditional execution with elseif and else branches (SCXML 4.3)

type Interpreter

type Interpreter interface {
	IOProcessor
	SessionID() string
	Configuration() []string
	In(ctx context.Context, stateId string) bool
	Raise(ctx context.Context, event *Event)
	Send(ctx context.Context, event *Event) error
	Cancel(ctx context.Context, sendId string) error
	Log(ctx context.Context, label, message string)
	Context() context.Context
	Clock() Clock
	DataModel() DataModel
	ExecuteElement(ctx context.Context, element xmldom.Element) error
	SendMessage(ctx context.Context, data SendData) error
	ScheduleMessage(ctx context.Context, data SendData) (string, error)
	InvokedSessions() map[string]Interpreter
	Tracer() Tracer
	Snapshot(ctx context.Context, maybeConfig ...SnapshotConfig) (xmldom.Document, error)
	// Root returns the sandboxed filesystem for this interpreter, if available.
	// Returns nil if no sandboxed filesystem is configured.
	Root() Filesystem
	// AfterFunc registers a function to be called when the provided context is cancelled
	// Returns a stop function that can be called to unregister the callback
	// This enables cross-language context cancellation for WASM/WIT components
	AfterFunc(ctx context.Context, fn func()) func() bool
}

Interpreter interface for SCXML interpretation

type InvokeLoader

type InvokeLoader func(ctx context.Context, interpreter Interpreter) (Invoker, error)

InvokeLoader creates an Invoker instance bound to an interpreter This factory pattern allows invokers to access the interpreter for sending events

type Invoker

type Invoker interface {
	// Handle is called once when the invoke starts and runs until context is cancelled
	// The event contains invoke parameters in event.Data (from <param> elements)
	// This method should block until:
	//   - Context is cancelled (parent state exited)
	//   - An unrecoverable error occurs
	//   - The service naturally completes
	// ctx: context that will be cancelled when the parent state exits
	// event: initial invoke event with parameters
	// Returns error if service fails (generates error.execution event)
	Handle(ctx context.Context, event *Event) error
}

Invoker defines the interface for long-running invoked services Invokers are created when <invoke> elements are processed and run until cancelled

type Log

type Log struct {
	xmldom.Element
	Label string // Optional label for the log message
	Expr  string // Expression to evaluate and log
}

Log generates a logging or debug message (SCXML 5.11)

type Namespace

type Namespace interface {
	URI() string
	Handle(ctx context.Context, element xmldom.Element) (bool, error)
	Unload(ctx context.Context) error
}

type NamespaceLoader

type NamespaceLoader func(ctx context.Context, interpreter Interpreter, doc xmldom.Document) (Namespace, error)

type Option

type Option func(*Trace)

type Param

type Param struct {
	xmldom.Element
	Name     string // The name of the parameter key
	Expr     string // Optional value expression to evaluate
	Location string // Optional location expression to retrieve value from
}

Param represents a parameter for data operations (SCXML 5.7)

type PlatformError

type PlatformError struct {
	EventName string         // The error event name (e.g., "error.execution")
	Message   string         // Error message
	Data      map[string]any // Additional error data (element, line, etc.)
	Cause     error          // Wrapped underlying error
}

PlatformError represents an error that should generate a platform error event

func (*PlatformError) Error

func (e *PlatformError) Error() string

func (*PlatformError) Unwrap

func (e *PlatformError) Unwrap() error

type Position

type Position struct {
	File   string `json:"file"`
	Line   int    `json:"line"`
	Column int    `json:"column"`
	Offset int64  `json:"offset"`
}

Position contains source position information for a diagnostic

type Raise

type Raise struct {
	xmldom.Element
	Event     string // Event name to raise
	EventExpr string // Optional dynamic event name expression
}

Raise raises an internal event (SCXML 6.4)

type Script

type Script struct {
	xmldom.Element
	Src     string // Optional URI of external script to load
	Content string // Inline script content
}

Script provides scripting capabilities (SCXML 5.8)

type Send

type Send struct {
	xmldom.Element
	Event      string   // Optional event name to send
	EventExpr  string   // Optional dynamic event name expression
	Target     string   // Optional target URI
	TargetExpr string   // Optional dynamic target expression
	TypeURI    string   // Optional I/O processor type URI
	TypeExpr   string   // Optional dynamic type expression
	SendID     string   // Optional send identifier
	IdLocation string   // Optional location to store generated ID
	Delay      string   // Optional delay duration (CSS2 format)
	DelayExpr  string   // Optional dynamic delay expression
	NameList   []string // Optional list of data model locations to include
	Params     []Param  // Optional parameter key-value pairs
	Content    *Content // Optional content payload
}

Send sends an event to a specified destination (SCXML 6.2)

type SendData

type SendData struct {
	Event    string   // Event name to send
	Target   string   // Target URI for the message
	Type     string   // I/O processor type URI
	ID       string   // Send identifier
	Delay    string   // Delay duration (CSS2 format)
	NameList []string // List of data model locations to include
	Params   []Param  // Parameter key-value pairs
	Content  *Content // Content payload (nil if not present)
}

SendData encapsulates all data needed for a send operation

type SnapshotConfig

type SnapshotConfig struct {
	// ExcludeAll acts as a master switch: when true, disables all sections
	ExcludeAll bool
	// Specific sections to exclude (opt-out pattern)
	ExcludeConfiguration bool // exclude state configuration
	ExcludeData          bool // exclude datamodel values
	ExcludeQueue         bool // exclude internal/external queues
	ExcludeServices      bool // exclude invoked child services recursively
	ExcludeRaise         bool // exclude available raise (internal) transitions
	ExcludeSend          bool // exclude available send (external) transitions
	ExcludeCancel        bool // exclude cancelable delayed events
}

SnapshotConfig controls what the snapshot excludes when embedding into the document. By default, all sections are included. Use Exclude fields to opt-out of specific sections.

type Snapshotter

type Snapshotter interface {
	// Snapshot returns a custom snapshot element for this namespace.
	// The returned element will be appended to the runtime snapshot.
	// Returns nil element if the namespace has no custom snapshot data.
	Snapshot(ctx context.Context, config SnapshotConfig) (xmldom.Element, error)
}

Snapshotter is an optional interface that namespaces can implement to provide custom snapshot functionality. When a namespace implements this interface, the interpreter will call Snapshot during snapshot generation to allow the namespace to contribute custom state to the runtime snapshot.

type Ticker

type Ticker interface {
	C() <-chan time.Time
	Stop()
	Reset(d time.Duration)
}

Ticker interface abstracts time.Ticker

type Timer

type Timer interface {
	C() <-chan time.Time
	Stop() bool
	Reset(d time.Duration) bool
}

Timer interface abstracts time.Timer

type Trace

type Trace struct {
	Level     slog.Level `json:"level"`
	Code      string     `json:"code"`
	Message   string     `json:"message"`
	Position  Position   `json:"position"`
	Tag       string     `json:"tag,omitempty"`
	Attribute string     `json:"attribute,omitempty"`
	Hints     []string   `json:"hints,omitempty"`
}

Trace describes an issue found during validation or runtime execution

type Tracer

type Tracer interface {
	Error(code, message string, element xmldom.Element, opts ...Option)
	Warn(code, message string, element xmldom.Element, opts ...Option)
	Info(code, message string, element xmldom.Element, opts ...Option)

	Diagnostics() []Trace
	HasErrors() bool
	Clear()
}

Tracer interface for collecting diagnostics

type Variable

type Variable struct {
	Name string
}

Directories

Path Synopsis
cmd/validate command

Jump to

Keyboard shortcuts

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