Documentation
¶
Overview ¶
Package domain contains the core domain models and business logic for the Trellis engine.
It defines the fundamental entities of the state machine, such as Nodes, Transitions, and the Execution State. This package is kept pure and free of external dependencies like I/O or persistence, following Hexagonal Architecture principles.
Key Entities ¶
- Node: Represents a point in the graph (Text, Input, or Tool/Action).
- Transition: Defines the rules for moving from one node to another.
- State: Captures the runtime snapshot of a session (Current Node, Context, History).
- ActionRequest: A structural representation of what the host should render or execute.
Index ¶
- Constants
- Variables
- type ActionRequest
- type ActionResponse
- type EventBase
- type EventType
- type ExecutionStatus
- type FormatItem
- type HistoryDelta
- type InputRequest
- type InputType
- type LifecycleHooks
- type Node
- type NodeEvent
- type State
- type StateDiff
- type Tool
- type ToolCall
- type ToolEvent
- type ToolResult
- type Transition
Constants ¶
const ( // ActionRenderContent requests the host to display content to the user. // Payload: string (the content) ActionRenderContent = "RENDER_CONTENT" // ActionRequestInput requests the host to collect input from the user. // Payload: InputRequest ActionRequestInput = "REQUEST_INPUT" // ActionCallTool requests the host to execute a side-effect (tool). // Payload: ToolCall ActionCallTool = "CALL_TOOL" // ActionSystemMessage represents a meta-message from the system (log, status, etc). // Payload: string (the message) ActionSystemMessage = "SYSTEM_MESSAGE" )
Standard Action Types
const ( // KeyIdempotency is the metadata key used to store the deterministic idempotency key. // It is also the JSON field name in the ToolCall struct. KeyIdempotency = "idempotency_key" // Signal constants representing global events. SignalInterrupt = "interrupt" // CTRL+C or explicit cancellation SignalShutdown = "shutdown" // System termination request (SIGTERM) SignalTimeout = "timeout" // Node execution deadline exceeded )
Field constants for mapstructure and JSON standardization.
const ( // NodeTypeText displays content and continues immediately (soft step). NodeTypeText = "text" // NodeTypeQuestion displays content and halts waiting for input (hard step). // It is the standard primitive for capturing user data. NodeTypeQuestion = "question" // NodeTypeTool executes an external side-effect (tool). NodeTypeTool = "tool" // NodeTypeFormat handles structured content with i18n and conditional logic. NodeTypeFormat = "format" // NodeTypeStart indicates the entry point (typically convention-based, but can be explicit). NodeTypeStart = "start" )
NodeType constants define the control flow behavior.
const ( // DefaultStartNodeID is the standard entry point for a flow. DefaultStartNodeID = "start" // DefaultErrorNodeID is the standard fallback for tool errors and denials. DefaultErrorNodeID = "error" )
Standard Node ID Conventions
Variables ¶
var ErrSessionNotFound = errors.New("session not found")
ErrSessionNotFound is returned when a session ID cannot be found in the store.
var ErrUnhandledSignal = errors.New("unhandled signal")
ErrUnhandledSignal is returned when a signal is received but no handler is defined for it.
Functions ¶
This section is empty.
Types ¶
type ActionRequest ¶
type ActionRequest struct {
Type string // e.g., "CLI_PRINT", "HTTP_GET"
Payload any // The data needed to perform the action
}
ActionRequest represents a side-effect that the engine requests the host to perform.
type ActionResponse ¶
ActionResponse represents the result of an ActionRequest.
type EventBase ¶ added in v0.5.1
type EventBase struct {
Timestamp time.Time `json:"timestamp"`
Type EventType `json:"type"`
StateID string `json:"state_id"` // Optional execution ID/Correlation ID? For now just keep it simple.
}
EventBase contains common fields for all events.
type ExecutionStatus ¶ added in v0.4.0
type ExecutionStatus string
ExecutionStatus defines the current mode of the engine mechanics.
const ( StatusActive ExecutionStatus = "active" // Normal operation StatusWaitingForTool ExecutionStatus = "waiting_for_tool" // Engine is paused, waiting for Host result StatusRollingBack ExecutionStatus = "rolling_back" // Engine is unwinding history (SAGA) StatusTerminated ExecutionStatus = "terminated" // Sink state reached )
type FormatItem ¶ added in v0.7.17
type FormatItem struct {
Text string `json:"text" yaml:"text" mapstructure:"text"`
Condition string `json:"condition,omitempty" yaml:"condition,omitempty" mapstructure:"condition"`
}
FormatItem represents a single piece of content within a "format" node.
type HistoryDelta ¶ added in v0.7.9
type HistoryDelta struct {
Appended []string `json:"appended"`
}
HistoryDelta represents changes to the history stack.
type InputRequest ¶ added in v0.3.2
type InputRequest struct {
Type InputType `json:"type"`
Options []string `json:"options,omitempty"`
Default string `json:"default,omitempty"`
Timeout time.Duration `json:"timeout,omitempty"` // Parsed duration (e.g. 5s)
}
InputRequest describes the constraints and type of input needed.
type InputType ¶ added in v0.3.2
type InputType string
InputType defines the kind of input requested.
type LifecycleHooks ¶ added in v0.5.1
type LifecycleHooks struct {
OnNodeEnter func(context.Context, *NodeEvent)
OnNodeLeave func(context.Context, *NodeEvent)
OnToolCall func(context.Context, *ToolEvent)
OnToolReturn func(context.Context, *ToolEvent)
}
LifecycleHooks defines callbacks for engine observability.
type Node ¶
type Node struct {
ID string `json:"id" yaml:"id"`
Type string `json:"type" yaml:"type"` // e.g., "text", "question", "logic", "tool"
// Wait indicates if the engine should pause for input after rendering.
Wait bool `json:"wait" yaml:"wait"`
// SaveTo indicates the variable name in Context where input should be stored.
SaveTo string `json:"save_to,omitempty" yaml:"save_to,omitempty"`
// RequiredContext lists keys that MUST exist in the context for this node to execute.
RequiredContext []string `json:"required_context,omitempty" yaml:"required_context,omitempty"`
// DefaultContext provides fallback values for context keys
DefaultContext map[string]any `json:"default_context,omitempty" yaml:"default_context,omitempty"`
// ContextSchema defines expected types for context values
ContextSchema schema.Schema `json:"context_schema,omitempty" yaml:"context_schema,omitempty"`
// Content holds the raw data for this node.
// For a text node, it might be the markdown content.
// For a logic node, it might be the script or parameters.
Content []byte `json:"content" yaml:"content"`
// Metadata allows for extensible key-value pairs.
Metadata map[string]string `json:"metadata,omitempty" yaml:"metadata,omitempty"`
// Transitions defines the possible paths from this node.
Transitions []Transition `json:"transitions" yaml:"transitions"`
// OnError defines the node ID to transition to if a Tool returns an error.
OnError string `json:"on_error,omitempty" yaml:"on_error,omitempty"`
// OnDenied defines the node ID to transition to if a Tool execution is denied by policy.
OnDenied string `json:"on_denied,omitempty" yaml:"on_denied,omitempty"`
// OnSignal defines transitions triggered by global signals (e.g., "interrupt").
OnSignal map[string]string `json:"on_signal,omitempty" yaml:"on_signal,omitempty"`
// OnSignalDefault defines global signal handlers (usually defined only on the root/entry node).
OnSignalDefault map[string]string `json:"on_signal_default,omitempty" yaml:"on_signal_default,omitempty"`
// Input Configuration (Optional)
InputType string `json:"input_type,omitempty" yaml:"input_type,omitempty"`
InputOptions []string `json:"input_options,omitempty" yaml:"input_options,omitempty"`
InputDefault string `json:"input_default,omitempty" yaml:"input_default,omitempty"`
// Tool Configuration (Optional, used if Type == "tool")
// Do defines the primary action to execute.
Do *ToolCall `json:"do,omitempty" yaml:"do,omitempty"`
// Tools defined within this node (e.g. for LLM context)
Tools []Tool `json:"tools,omitempty" yaml:"tools,omitempty"`
// Undo defines the compensating action (SAGA pattern) to revert this node's effect.
// It is triggered if the engine enters rollback mode.
Undo *ToolCall `json:"undo,omitempty" yaml:"undo,omitempty"`
// Messages provides a dictionary of content by locale for i18n support.
// Used when Type == "format".
Messages map[string][]FormatItem `json:"messages,omitempty" yaml:"messages,omitempty"`
// Timeout defines the maximum duration (e.g. "30s") to wait for input.
Timeout string `json:"timeout,omitempty" yaml:"timeout,omitempty"`
}
Node represents a logical unit in the graph. It can contain text content (for Wiki-style) or logic instructions (for Logic-style).
type NodeEvent ¶ added in v0.5.1
type NodeEvent struct {
EventBase
NodeID string `json:"node_id"`
NodeType string `json:"node_type"`
}
NodeEvent represents entry or exit from a node.
type State ¶
type State struct {
// SessionID uniquely identifies the session this state belongs to.
SessionID string `json:"session_id"`
// CurrentNodeID is the identifier of the active node.
CurrentNodeID string `json:"current_node_id"`
// Status indicates if the engine is running, waiting, or done.
Status ExecutionStatus `json:"status"`
// PendingToolCall holds the ID of the tool call we are waiting for (if Status == WaitingForTool).
PendingToolCall string `json:"pending_tool_call,omitempty"`
// Context holds variable state for the session (User space).
Context map[string]any `json:"context"`
// SystemContext holds system-level state (Read-only for templates, Host-writable).
// Reserved namespace: "sys".
SystemContext map[string]any `json:"system_context"`
// Locale identifies the preferred language for the session (e.g., "en", "pt-BR").
Locale string `json:"locale,omitempty"`
// History could track the path taken (optional for now, but good for debugging)
History []string `json:"history,omitempty"`
// Terminated indicates if the execution has reached a sink state (no transitions).
// Deprecated: Use Status == StatusTerminated instead. Kept for backward compat.
Terminated bool `json:"terminated,omitempty"`
}
State represents the current snapshot of the execution.
type StateDiff ¶ added in v0.7.9
type StateDiff struct {
// SessionID is always present to identify the target.
SessionID string `json:"session_id"`
// OldNodeID needed? Maybe not. NewNodeID is enough.
CurrentNodeID *string `json:"current_node_id,omitempty"`
// Status changed?
Status *ExecutionStatus `json:"status,omitempty"`
// ContextDelta contains only changed, added or deleted keys.
// For deletions, the key is present with a nil value.
// Clients should merge these updates into their local state.
Context map[string]any `json:"context,omitempty"`
// HistoryDelta contains *new* items appended to history.
// If history was rewritten (rare), we might send the whole list?
// Let's optimize for append-only.
HistoryParams *HistoryDelta `json:"history,omitempty"`
// Terminated changed?
Terminated *bool `json:"terminated,omitempty"`
}
StateDiff represents the changes between two states. It is designed to be serialized to JSON for partial updates on the client.
type Tool ¶ added in v0.4.0
type Tool struct {
Name string `json:"name" yaml:"name" mapstructure:"name"`
Description string `json:"description" yaml:"description" mapstructure:"description"`
Parameters map[string]any `json:"parameters,omitempty" yaml:"parameters,omitempty" mapstructure:"parameters"`
}
Tool defines metadata about a tool available to the engine. This is used for generating schemas/prompts.
type ToolCall ¶ added in v0.4.0
type ToolCall struct {
ID string `json:"id" yaml:"id" mapstructure:"id"` // Unique ID for this specific call (e.g. from LLM or generated)
Name string `json:"name" yaml:"name" mapstructure:"name"` // Function name to call
Args map[string]any `json:"args,omitempty" yaml:"args,omitempty" mapstructure:"args"` // Arguments for the function
Metadata map[string]string `json:"metadata,omitempty" yaml:"metadata,omitempty" mapstructure:"metadata"` // Context/Safety metadata from the Node
IdempotencyKey string `json:"idempotency_key,omitempty" yaml:"idempotency_key,omitempty" mapstructure:"idempotency_key"`
}
ToolCall represents a request from the Engine to the Host to perform a side-effect. Ideally compatible with OpenAI/MCP tool call schemas.
type ToolEvent ¶ added in v0.5.1
type ToolEvent struct {
EventBase
NodeID string `json:"node_id"`
ToolName string `json:"tool_name"`
Input any `json:"input,omitempty"`
Output any `json:"output,omitempty"`
IsError bool `json:"is_error,omitempty"`
}
ToolEvent represents a tool execution.
type ToolResult ¶ added in v0.4.0
type ToolResult struct {
ID string `json:"id"` // Must match the ToolCall.ID
Result any `json:"result,omitempty"`
IsError bool `json:"is_error,omitempty"`
IsDenied bool `json:"is_denied,omitempty"`
Error string `json:"error,omitempty"`
}
ToolResult represents the output of a side-effect returned by the Host.
type Transition ¶
type Transition struct {
FromNodeID string `json:"from_node_id,omitempty" yaml:"from,omitempty"`
ToNodeID string `json:"to_node_id" yaml:"to,omitempty"`
// Condition is a simple expression string that must evaluate to true
// for this transition to be valid. e.g., "user_age >= 18"
// If empty, it's considered an "always" transition (default).
Condition string `json:"condition,omitempty" yaml:"condition,omitempty"`
}
Transition defines a rule to move from one node to another.