agui

package
v0.2.6 Latest Latest
Warning

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

Go to latest
Published: Dec 19, 2025 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

Package agui provides utilities for integrating gains with the AG-UI protocol.

AG-UI (Agent-User Interface) is an open, lightweight, event-based protocol that standardizes how AI agents connect to user-facing applications. This package provides mapping utilities to convert gains events to AG-UI events, enabling easy integration with AG-UI-compatible frontends.

Overview

This package provides:

The package does NOT provide HTTP handlers or transport implementations. Users are responsible for implementing their own server using the AG-UI SDK's SSE writer or their preferred transport mechanism.

Usage

Create a Mapper for each run and use it to convert gains events:

// Create mapper for this run
mapper := agui.NewMapper(threadID, runID)

// Emit run started
writeEvent(mapper.RunStarted())

// Run agent and map events
for event := range myAgent.RunStream(ctx, messages) {
    aguiEvent := mapper.MapEvent(event)
    if aguiEvent != nil {
        writeEvent(aguiEvent)
    }
}

// Emit run finished
writeEvent(mapper.RunFinished())

Event Mapping

The Mapper tracks state to properly emit AG-UI's Start-Content-End sequences:

  • event.MessageDelta → TEXT_MESSAGE_START (on first delta), TEXT_MESSAGE_CONTENT
  • event.StepEnd → TEXT_MESSAGE_END (if message active), STEP_FINISHED
  • event.ToolCallStart → TOOL_CALL_START, TOOL_CALL_ARGS
  • event.ToolCallResult → TOOL_CALL_END, TOOL_CALL_RESULT

Message Conversion

Use ToGainsMessages to convert AG-UI messages to gains messages for input:

messages := agui.ToGainsMessages(aguiMessages)
result := agent.Run(ctx, messages)

Use FromGainsMessages to convert gains messages to AG-UI format for snapshots:

snapshot := events.NewMessagesSnapshotEvent(agui.FromGainsMessages(history))

Shared State

AG-UI supports bidirectional state synchronization between agents and frontends. The frontend can send state with each run via RunAgentInput.State, and agents can emit state updates via STATE_SNAPSHOT and STATE_DELTA events.

Reading frontend state:

type MyState struct {
    Progress int      `json:"progress"`
    Items    []string `json:"items"`
}

prepared, _ := input.Prepare()
state, err := agui.DecodeState[MyState](prepared)
// or: state := agui.MustDecodeState[MyState](prepared)

Emitting state to frontend:

// Full state snapshot
writeEvent(mapper.StateSnapshot(map[string]any{
    "progress": 50,
    "items": []string{"a", "b"},
}))

// Incremental delta (JSON Patch RFC 6902)
writeEvent(mapper.StateDelta(
    event.Replace("/progress", 75),
    event.Add("/items/-", "c"),
))

Or via gains events for integration with RunStream:

events <- event.NewStateSnapshot(state)
events <- event.NewStateDelta(
    event.Replace("/progress", 100),
)

Thread Safety

The Mapper is NOT safe for concurrent use. Each goroutine should have its own Mapper instance. Message conversion functions are stateless and safe for concurrent use.

Index

Constants

View Source
const (
	RoleUser      = "user"
	RoleAssistant = "assistant"
	RoleSystem    = "system"
	RoleTool      = "tool"
)

Role constants matching AG-UI protocol.

Variables

View Source
var ErrNoMessages = errors.New("no messages provided")

ErrNoMessages is returned when the input contains no messages.

Functions

func DecodeState

func DecodeState[T any](input *PreparedInput) (T, error)

DecodeState decodes the raw state into a typed struct. Returns the zero value of T if State is nil.

func FromGainsMessage

func FromGainsMessage(msg ai.Message, index int) events.Message

FromGainsMessage converts a single gains message to an AG-UI message. The index is used to generate a message ID if needed.

func FromGainsMessages

func FromGainsMessages(msgs []ai.Message) []events.Message

FromGainsMessages converts gains messages to AG-UI messages.

func MustDecodeState

func MustDecodeState[T any](input *PreparedInput) T

MustDecodeState is like DecodeState but panics on error.

func ToGainsMessage

func ToGainsMessage(msg events.Message) ai.Message

ToGainsMessage converts a single AG-UI message to a gains message.

func ToGainsMessages

func ToGainsMessages(msgs []events.Message) []ai.Message

ToGainsMessages converts AG-UI messages to gains messages.

func ToGainsTools

func ToGainsTools(tools []Tool) []ai.Tool

ToGainsTools converts a slice of AG-UI tools to gains tools.

func ToolNames

func ToolNames(tools []Tool) []string

ToolNames extracts the names from a slice of tools.

Types

type Mapper

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

Mapper converts gains events to AG-UI events. With the unified event system, this is now a true 1:1 mapping - each gains event maps to exactly one AG-UI event.

Create a new Mapper for each run using NewMapper. The Mapper is not safe for concurrent use - each goroutine should have its own Mapper.

func NewMapper

func NewMapper(threadID, runID string) *Mapper

NewMapper creates a new Mapper for a single run. The threadID and runID are used in lifecycle events (RUN_STARTED, RUN_FINISHED).

func (*Mapper) MapEvent

func (m *Mapper) MapEvent(e event.Event) events.Event

MapEvent converts a unified gains event to an AG-UI event. This is a true 1:1 mapping - each gains event maps to exactly one AG-UI event. Returns nil for events that have no AG-UI equivalent.

func (*Mapper) MapStream

func (m *Mapper) MapStream(input <-chan event.Event) <-chan events.Event

MapStream wraps a gains event channel and yields AG-UI events. Events that have no AG-UI equivalent (returning nil from MapEvent) are filtered out. The returned channel closes when the input channel closes.

func (*Mapper) RunError

func (m *Mapper) RunError(err error) events.Event

RunError returns a RUN_ERROR event.

func (*Mapper) RunFinished

func (m *Mapper) RunFinished() events.Event

RunFinished returns a RUN_FINISHED event.

func (*Mapper) RunID

func (m *Mapper) RunID() string

RunID returns the run ID for this mapper.

func (*Mapper) RunStarted

func (m *Mapper) RunStarted() events.Event

RunStarted returns a RUN_STARTED event.

func (*Mapper) StateDelta

func (m *Mapper) StateDelta(patches ...event.JSONPatch) events.Event

StateDelta returns a STATE_DELTA event with the given JSON Patch operations.

func (*Mapper) StateSnapshot

func (m *Mapper) StateSnapshot(state any) events.Event

StateSnapshot returns a STATE_SNAPSHOT event with the given state.

func (*Mapper) ThreadID

func (m *Mapper) ThreadID() string

ThreadID returns the thread ID for this mapper.

type PreparedInput

type PreparedInput struct {
	ThreadID  string
	RunID     string
	Messages  []ai.Message
	Tools     []Tool   // Parsed frontend tools
	ToolNames []string // Tool names for cleanup tracking
	State     any      // Raw state from frontend
}

PreparedInput contains validated and converted input ready for agent execution.

func (*PreparedInput) GainsTools

func (p *PreparedInput) GainsTools() []ai.Tool

GainsTools converts the parsed frontend tools to gains tools. Returns nil if no tools were parsed.

type RunAgentInput

type RunAgentInput struct {
	ThreadID       string           `json:"thread_id"`
	RunID          string           `json:"run_id"`
	Messages       []events.Message `json:"messages"`
	Tools          []any            `json:"tools,omitempty"`           // Frontend-provided tools
	Context        []any            `json:"context,omitempty"`         // Context items
	State          any              `json:"state,omitempty"`           // State
	ForwardedProps any              `json:"forwarded_props,omitempty"` // Forwarded props
}

RunAgentInput represents the AG-UI protocol request for running an agent. This mirrors the AG-UI protocol specification and is transport-agnostic.

func (*RunAgentInput) Prepare

func (r *RunAgentInput) Prepare() (*PreparedInput, error)

Prepare validates the input and converts it to gains types. Returns ErrNoMessages if Messages is empty. Returns an error if tool parsing fails.

type Tool

type Tool struct {
	Name        string          `json:"name"`
	Description string          `json:"description"`
	Parameters  json.RawMessage `json:"parameters,omitempty"`
}

Tool represents a tool definition from the AG-UI protocol. Frontend applications send these to define capabilities available to agents.

func ParseTools

func ParseTools(raw []any) ([]Tool, error)

ParseTools parses a slice of any (from JSON unmarshaling) into Tool structs. This handles the Tools field from RunAgentInput which is []any.

func (Tool) ToGainsTool

func (t Tool) ToGainsTool() ai.Tool

ToGainsTool converts an AG-UI tool to a gains Tool.

Jump to

Keyboard shortcuts

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