Documentation
¶
Overview ¶
Package agentic provides shared types for the SemStreams agentic processing system.
Overview ¶
The agentic package defines the foundational types used by the agentic component family: agentic-loop (orchestration), agentic-model (LLM integration), and agentic-tools (tool execution). These components work together to enable autonomous, tool-using AI agents that can execute complex multi-step tasks.
This package provides:
- Request/Response types for agent communication (AgentRequest, AgentResponse)
- State machine types for loop lifecycle (LoopState, LoopEntity)
- Tool system types (ToolDefinition, ToolCall, ToolResult)
- Trajectory tracking for observability (Trajectory, TrajectoryStep)
Architecture Context ¶
The agentic system uses a three-component architecture communicating over NATS JetStream:
┌─────────────────┐
│ agentic-loop │ Orchestrates the agent lifecycle
│ (state machine)│ Manages state, routes messages, captures trajectory
└────────┬────────┘
│
┌────┴────┐
│ │
▼ ▼
┌────────┐ ┌────────────┐
│agentic-│ │agentic- │
│model │ │tools │
│(LLM) │ │(execution) │
└────────┘ └────────────┘
All three components share the types defined in this package, ensuring consistent serialization and validation across the system.
Request/Response Types ¶
AgentRequest encapsulates a request to an LLM endpoint:
request := agentic.AgentRequest{
RequestID: "req_001",
LoopID: "loop_123",
Role: "general", // or "architect", "editor"
Model: "gpt-4",
Messages: []agentic.ChatMessage{
{Role: "system", Content: "You are a helpful assistant."},
{Role: "user", Content: "Analyze this code for bugs."},
},
Tools: []agentic.ToolDefinition{
{Name: "read_file", Description: "Read file contents", Parameters: schema},
},
}
AgentResponse captures the LLM's response:
response := agentic.AgentResponse{
RequestID: "req_001",
Status: "complete", // or "tool_call", "error"
Message: agentic.ChatMessage{
Role: "assistant",
Content: "I found 3 potential issues...",
},
TokenUsage: agentic.TokenUsage{
PromptTokens: 150,
CompletionTokens: 200,
},
}
ChatMessage Roles ¶
The ChatMessage type supports four roles following the OpenAI convention:
- "system": System instructions that shape agent behavior
- "user": User input or task descriptions
- "assistant": Agent responses (from the LLM)
- "tool": Results from tool execution
Messages with tool calls use the ToolCalls field instead of Content:
assistantMessage := agentic.ChatMessage{
Role: "assistant",
ToolCalls: []agentic.ToolCall{
{ID: "call_001", Name: "read_file", Arguments: map[string]any{"path": "main.go"}},
},
}
Agent Roles ¶
The agentic system supports three agent roles for different task patterns:
- "general": Standard single-agent execution for most tasks
- "architect": High-level planning and design (used with editor split)
- "editor": Implementation based on architect's plan
The architect/editor split enables complex tasks where planning and execution benefit from separation. The loop orchestrator handles spawning editor loops when an architect completes.
State Machine ¶
LoopState represents the lifecycle of an agentic loop with seven states:
exploring → planning → architecting → executing → reviewing → complete
↘ failed
States are fluid checkpoints, not gates. The loop can move backward (e.g., from executing back to exploring if the agent needs to rethink). Only the terminal states (complete, failed) prevent further transitions.
Create and manage loop entities:
entity := agentic.NewLoopEntity("loop_123", "task_456", "general", "gpt-4")
// State transitions
entity.TransitionTo(agentic.LoopStatePlanning)
entity.TransitionTo(agentic.LoopStateExecuting)
// Iteration tracking (with guard)
if err := entity.IncrementIteration(); err != nil {
// Max iterations reached
}
// Check terminal state
if entity.State.IsTerminal() {
// Loop has finished
}
Tool System ¶
The tool system enables agents to interact with external systems through a well-defined interface.
ToolDefinition describes an available tool:
toolDef := agentic.ToolDefinition{
Name: "read_file",
Description: "Read the contents of a file",
Parameters: map[string]any{
"type": "object",
"properties": map[string]any{
"path": map[string]any{"type": "string", "description": "File path"},
},
"required": []string{"path"},
},
}
ToolCall represents a request from the LLM to execute a tool:
call := agentic.ToolCall{
ID: "call_001",
Name: "read_file",
Arguments: map[string]any{"path": "/etc/hosts"},
}
ToolResult returns the outcome of tool execution:
result := agentic.ToolResult{
CallID: "call_001",
Content: "127.0.0.1 localhost\n...",
// Or on error:
// Error: "file not found",
}
Tool Validation ¶
The ValidateToolsAllowed function checks tool calls against an allowlist:
allowed := []string{"read_file", "write_file", "list_dir"}
calls := []agentic.ToolCall{{ID: "1", Name: "delete_file"}}
if err := agentic.ValidateToolsAllowed(calls, allowed); err != nil {
// Error: "disallowed tools: delete_file"
}
Trajectory Tracking ¶
Trajectories capture the complete execution path of an agentic loop for observability, debugging, and compliance.
Create and populate a trajectory:
trajectory := agentic.NewTrajectory("loop_123")
// Record a model call
trajectory.AddStep(agentic.TrajectoryStep{
Timestamp: time.Now(),
StepType: "model_call",
RequestID: "req_001",
Prompt: "Analyze this code...",
Response: "I found 3 issues...",
TokensIn: 150,
TokensOut: 200,
Duration: 1250, // milliseconds
})
// Record a tool call
trajectory.AddStep(agentic.TrajectoryStep{
Timestamp: time.Now(),
StepType: "tool_call",
ToolName: "read_file",
ToolArguments: map[string]any{"path": "main.go"},
ToolResult: "package main...",
Duration: 50,
})
// Complete the trajectory
trajectory.Complete("complete")
Trajectories automatically track:
- Total input/output tokens across all model calls
- Cumulative duration of all steps
- Start and end times with final outcome
Token Usage ¶
TokenUsage tracks token consumption for cost monitoring and rate limiting:
usage := agentic.TokenUsage{
PromptTokens: 500,
CompletionTokens: 250,
}
total := usage.Total() // 750
Model Configuration ¶
ModelConfig provides default values for LLM parameters:
config := agentic.ModelConfig{
Temperature: 0.7,
MaxTokens: 2048,
}
// Apply defaults (Temperature: 0.2, MaxTokens: 4096)
config = config.WithDefaults()
Validation ¶
All types include Validate() methods for input validation:
request := agentic.AgentRequest{...}
if err := request.Validate(); err != nil {
// Handle validation error
}
Validation rules:
- AgentRequest: requires request_id, at least one message, valid role
- AgentResponse: requires valid status (complete, tool_call, error)
- ChatMessage: requires valid role, either content, reasoning_content, or tool_calls
- ToolDefinition: requires name and parameters
- ToolCall: requires id and name
- ToolResult: requires call_id
- TrajectoryStep: requires valid step_type and timestamp
- LoopEntity: requires id, valid state, positive max_iterations
Integration with NATS ¶
The agentic components communicate via NATS JetStream using these subject patterns:
agent.task.* - Task requests (external → loop) agent.request.* - Model requests (loop → model) agent.response.* - Model responses (model → loop) tool.execute.* - Tool execution (loop → tools) tool.result.* - Tool results (tools → loop) agent.complete.* - Completions (loop → external)
All subjects use the AGENT stream for reliable delivery.
KV Storage ¶
Loop state and trajectories are persisted to NATS KV buckets:
- AGENT_LOOPS: LoopEntity per loop ID
- AGENT_TRAJECTORIES: Trajectory per loop ID
This enables recovery after restarts and provides queryable execution history.
Thread Safety ¶
Types in this package are not inherently thread-safe. When used concurrently, external synchronization is required. The agentic-loop component provides thread-safe managers (LoopManager, TrajectoryManager) that wrap these types.
Error Handling ¶
Validation errors are returned as standard Go errors with descriptive messages. Tool execution errors are captured in ToolResult.Error rather than returned as Go errors, allowing the agent to handle them gracefully.
Limitations ¶
Current limitations of the agentic type system:
- No streaming support (responses are complete documents)
- Tool parameters use map[string]any (no strong typing)
- Trajectory steps are append-only (no editing)
- Maximum trajectory size limited by NATS KV (1MB default)
See Also ¶
Related packages:
- processor/agentic-loop: Loop orchestration and state management
- processor/agentic-model: LLM endpoint integration
- processor/agentic-tools: Tool execution framework
Package agentic provides shared types for the agentic components system. This includes loop state management, tool execution interfaces, and trajectory tracking.
Index ¶
- Constants
- func LoopExecutionEntityID(org, platform, loopID string) string
- func ModelEndpointEntityID(org, platform, endpointName string) string
- func TrajectoryStepEntityID(org, platform, loopID string, stepIndex int) string
- func ValidateToolsAllowed(calls []ToolCall, allowed []string) error
- type AgentRequest
- type AgentResponse
- type Attachment
- type ChatMessage
- type ConstructedContext
- type ContextEvent
- type ContextSource
- type GraphContextSpec
- type LoopCancelledEvent
- type LoopCompletedEvent
- type LoopCreatedEvent
- type LoopEntity
- type LoopFailedEvent
- type LoopState
- type ModelConfig
- type ResponseAction
- type ResponseBlock
- type TaskMessage
- type TokenUsage
- type ToolCall
- type ToolCallFilter
- type ToolCallFilterResult
- type ToolCallRejection
- type ToolChoice
- type ToolDefinition
- type ToolResult
- type Trajectory
- type TrajectoryStep
- type TrajectoryStepEntity
- func (e *TrajectoryStepEntity) ContentFields() map[string]string
- func (e *TrajectoryStepEntity) EntityID() string
- func (e *TrajectoryStepEntity) RawContent() map[string]string
- func (e *TrajectoryStepEntity) SetStorageRef(ref *message.StorageReference)
- func (e *TrajectoryStepEntity) StorageRef() *message.StorageReference
- func (e *TrajectoryStepEntity) Triples() []message.Triple
- type UserMessage
- type UserResponse
- type UserSignal
Constants ¶
const ( Domain = "agentic" SchemaVersion = "v1" )
Domain and version constants for message type identification.
const ( CategoryTask = "task" CategoryUserMessage = "user_message" CategorySignal = "signal" CategoryUserResponse = "user_response" CategoryRequest = "request" CategoryResponse = "response" CategoryToolCall = "tool_call" CategoryToolResult = "tool_result" CategoryLoopCreated = "loop_created" CategoryLoopCompleted = "loop_completed" CategoryLoopFailed = "loop_failed" CategoryLoopCancelled = "loop_cancelled" CategoryContextEvent = "context_event" CategorySignalMessage = "signal_message" )
Category constants for message types.
const ( OutcomeSuccess = "success" OutcomeFailed = "failed" OutcomeCancelled = "cancelled" )
Outcome values for loop completion events.
const ( StatusComplete = "complete" StatusToolCall = "tool_call" StatusError = "error" )
Response status values from model responses.
const ( ContextEventCompactionStarting = "compaction_starting" ContextEventCompactionComplete = "compaction_complete" ContextEventGCComplete = "gc_complete" )
ContextEvent type values.
const ( RoleArchitect = "architect" RoleEditor = "editor" RoleGeneral = "general" RoleQualifier = "qualifier" RoleDeveloper = "developer" RoleReviewer = "reviewer" )
Role values for agent loops.
const ( SignalCancel = "cancel" // Stop execution immediately SignalPause = "pause" // Pause at next checkpoint SignalResume = "resume" // Continue paused loop SignalApprove = "approve" // Approve pending result SignalReject = "reject" // Reject with optional reason SignalFeedback = "feedback" // Add feedback without decision SignalRetry = "retry" // Retry failed loop )
Signal type constants for user control signals
const ( ResponseTypeText = "text" // Plain text response ResponseTypeStatus = "status" // Status update ResponseTypeResult = "result" // Final result ResponseTypeError = "error" // Error message ResponseTypePrompt = "prompt" // Awaiting user input (approval, etc.) ResponseTypeStream = "stream" // Streaming partial content )
Response type constants
Variables ¶
This section is empty.
Functions ¶
func LoopExecutionEntityID ¶
LoopExecutionEntityID constructs a 6-part entity ID for an agentic loop execution. Format: {org}.{platform}.agent.agentic-loop.execution.{loopID}
Example: LoopExecutionEntityID("c360", "ops", "abc123") Returns: "c360.ops.agent.agentic-loop.execution.abc123"
Panics if any input part is empty or contains a dot, as these represent programming errors — the caller is responsible for supplying well-formed identifiers.
func ModelEndpointEntityID ¶
ModelEndpointEntityID constructs a 6-part entity ID for a model registry endpoint. Format: {org}.{platform}.agent.model-registry.endpoint.{endpointName}
Example: ModelEndpointEntityID("c360", "ops", "claude-sonnet") Returns: "c360.ops.agent.model-registry.endpoint.claude-sonnet"
Panics if any input part is empty or contains a dot, as these represent programming errors — the caller is responsible for supplying well-formed identifiers.
func TrajectoryStepEntityID ¶
TrajectoryStepEntityID constructs a 6-part entity ID for a trajectory step. Format: {org}.{platform}.agent.agentic-loop.step.{loopID}-{stepIndex}
Example: TrajectoryStepEntityID("c360", "ops", "abc123", 0) Returns: "c360.ops.agent.agentic-loop.step.abc123-0"
Panics if any input part is empty or contains a dot, as these represent programming errors — the caller is responsible for supplying well-formed identifiers.
func ValidateToolsAllowed ¶
ValidateToolsAllowed validates that all tool calls are in the allowed list
Types ¶
type AgentRequest ¶
type AgentRequest struct {
RequestID string `json:"request_id"`
LoopID string `json:"loop_id"`
Role string `json:"role"`
Messages []ChatMessage `json:"messages"`
Model string `json:"model"`
MaxTokens int `json:"max_tokens,omitempty"`
Temperature float64 `json:"temperature,omitempty"`
Tools []ToolDefinition `json:"tools,omitempty"`
ToolChoice *ToolChoice `json:"tool_choice,omitempty"`
}
AgentRequest represents a request to an agentic service
func (*AgentRequest) MarshalJSON ¶
func (r *AgentRequest) MarshalJSON() ([]byte, error)
MarshalJSON implements json.Marshaler
func (*AgentRequest) Schema ¶
func (r *AgentRequest) Schema() message.Type
Schema implements message.Payload
func (*AgentRequest) UnmarshalJSON ¶
func (r *AgentRequest) UnmarshalJSON(data []byte) error
UnmarshalJSON implements json.Unmarshaler
func (AgentRequest) Validate ¶
func (r AgentRequest) Validate() error
Validate checks if the AgentRequest is valid
type AgentResponse ¶
type AgentResponse struct {
RequestID string `json:"request_id"`
Status string `json:"status"`
Message ChatMessage `json:"message,omitempty"`
Error string `json:"error,omitempty"`
TokenUsage TokenUsage `json:"token_usage,omitempty"`
}
AgentResponse represents a response from an agentic service
func (*AgentResponse) MarshalJSON ¶
func (r *AgentResponse) MarshalJSON() ([]byte, error)
MarshalJSON implements json.Marshaler
func (*AgentResponse) Schema ¶
func (r *AgentResponse) Schema() message.Type
Schema implements message.Payload
func (*AgentResponse) UnmarshalJSON ¶
func (r *AgentResponse) UnmarshalJSON(data []byte) error
UnmarshalJSON implements json.Unmarshaler
func (AgentResponse) Validate ¶
func (r AgentResponse) Validate() error
Validate checks if the AgentResponse is valid
type Attachment ¶
type Attachment struct {
Type string `json:"type"` // file, image, code, url
Name string `json:"name"` // filename or title
URL string `json:"url,omitempty"` // URL to fetch content
Content string `json:"content,omitempty"` // inline content if small
MimeType string `json:"mime_type,omitempty"`
Size int64 `json:"size,omitempty"`
}
Attachment represents a file or other media attached to a message
type ChatMessage ¶
type ChatMessage struct {
Role string `json:"role"`
Content string `json:"content,omitempty"`
Name string `json:"name,omitempty"` // Function name for tool role messages (required by Gemini)
ReasoningContent string `json:"reasoning_content,omitempty"` // Thinking model chain-of-thought
ToolCalls []ToolCall `json:"tool_calls,omitempty"`
ToolCallID string `json:"tool_call_id,omitempty"` // Required for tool role messages
IsError bool `json:"is_error,omitempty"` // Tool result contains an error — preserved during context GC
}
ChatMessage represents a message in a conversation
func (*ChatMessage) UnmarshalJSON ¶
func (m *ChatMessage) UnmarshalJSON(data []byte) error
UnmarshalJSON accepts both "reasoning" (Ollama) and "reasoning_content" (DeepSeek/canonical). If both are present, reasoning_content wins.
func (ChatMessage) Validate ¶
func (m ChatMessage) Validate() error
Validate checks if the ChatMessage is valid
type ConstructedContext ¶
type ConstructedContext = types.ConstructedContext
ConstructedContext is an alias for types.ConstructedContext. The canonical type is defined in pkg/types/context.go.
type ContextEvent ¶
type ContextEvent struct {
Type string `json:"type"` // ContextEventCompactionStarting, ContextEventCompactionComplete, ContextEventGCComplete
LoopID string `json:"loop_id"`
Iteration int `json:"iteration"`
Utilization float64 `json:"utilization,omitempty"`
TokensSaved int `json:"tokens_saved,omitempty"`
Summary string `json:"summary,omitempty"`
}
ContextEvent represents a context management event (compaction, GC).
func (*ContextEvent) MarshalJSON ¶
func (e *ContextEvent) MarshalJSON() ([]byte, error)
MarshalJSON implements json.Marshaler
func (*ContextEvent) Schema ¶
func (e *ContextEvent) Schema() message.Type
Schema implements message.Payload
func (*ContextEvent) UnmarshalJSON ¶
func (e *ContextEvent) UnmarshalJSON(data []byte) error
UnmarshalJSON implements json.Unmarshaler
func (*ContextEvent) Validate ¶
func (e *ContextEvent) Validate() error
Validate implements message.Payload
type ContextSource ¶
type ContextSource = types.ContextSource
ContextSource is an alias for types.ContextSource. The canonical type is defined in pkg/types/context.go.
type GraphContextSpec ¶
type GraphContextSpec = types.GraphContextSpec
GraphContextSpec is an alias for types.GraphContextSpec. The canonical type is defined in pkg/types/context.go.
type LoopCancelledEvent ¶
type LoopCancelledEvent struct {
LoopID string `json:"loop_id"`
TaskID string `json:"task_id"`
Outcome string `json:"outcome"` // OutcomeCancelled
CancelledBy string `json:"cancelled_by"`
WorkflowSlug string `json:"workflow_slug,omitempty"`
WorkflowStep string `json:"workflow_step,omitempty"`
CancelledAt time.Time `json:"cancelled_at"`
}
LoopCancelledEvent is published when a loop is cancelled by user action.
func (*LoopCancelledEvent) MarshalJSON ¶
func (e *LoopCancelledEvent) MarshalJSON() ([]byte, error)
MarshalJSON implements json.Marshaler
func (*LoopCancelledEvent) Schema ¶
func (e *LoopCancelledEvent) Schema() message.Type
Schema implements message.Payload
func (*LoopCancelledEvent) UnmarshalJSON ¶
func (e *LoopCancelledEvent) UnmarshalJSON(data []byte) error
UnmarshalJSON implements json.Unmarshaler
func (*LoopCancelledEvent) Validate ¶
func (e *LoopCancelledEvent) Validate() error
Validate implements message.Payload
type LoopCompletedEvent ¶
type LoopCompletedEvent struct {
LoopID string `json:"loop_id"`
TaskID string `json:"task_id"`
Outcome string `json:"outcome"` // OutcomeSuccess
Role string `json:"role"`
Result string `json:"result"`
Model string `json:"model"`
Iterations int `json:"iterations"`
TokensIn int `json:"tokens_in"`
TokensOut int `json:"tokens_out"`
ParentLoopID string `json:"parent_loop,omitempty"`
WorkflowSlug string `json:"workflow_slug,omitempty"`
WorkflowStep string `json:"workflow_step,omitempty"`
CompletedAt time.Time `json:"completed_at"`
// User routing info for response delivery
ChannelType string `json:"channel_type,omitempty"`
ChannelID string `json:"channel_id,omitempty"`
UserID string `json:"user_id,omitempty"`
}
LoopCompletedEvent is published when a loop completes successfully.
func (*LoopCompletedEvent) MarshalJSON ¶
func (e *LoopCompletedEvent) MarshalJSON() ([]byte, error)
MarshalJSON implements json.Marshaler
func (*LoopCompletedEvent) Schema ¶
func (e *LoopCompletedEvent) Schema() message.Type
Schema implements message.Payload
func (*LoopCompletedEvent) UnmarshalJSON ¶
func (e *LoopCompletedEvent) UnmarshalJSON(data []byte) error
UnmarshalJSON implements json.Unmarshaler
func (*LoopCompletedEvent) Validate ¶
func (e *LoopCompletedEvent) Validate() error
Validate implements message.Payload
type LoopCreatedEvent ¶
type LoopCreatedEvent struct {
LoopID string `json:"loop_id"`
TaskID string `json:"task_id"`
Role string `json:"role"`
Model string `json:"model"`
WorkflowSlug string `json:"workflow_slug,omitempty"`
WorkflowStep string `json:"workflow_step,omitempty"`
ContextRequestID string `json:"context_request_id,omitempty"`
MaxIterations int `json:"max_iterations"`
CreatedAt time.Time `json:"created_at"`
}
LoopCreatedEvent is published when a new agentic loop is created.
func (*LoopCreatedEvent) MarshalJSON ¶
func (e *LoopCreatedEvent) MarshalJSON() ([]byte, error)
MarshalJSON implements json.Marshaler
func (*LoopCreatedEvent) Schema ¶
func (e *LoopCreatedEvent) Schema() message.Type
Schema implements message.Payload
func (*LoopCreatedEvent) UnmarshalJSON ¶
func (e *LoopCreatedEvent) UnmarshalJSON(data []byte) error
UnmarshalJSON implements json.Unmarshaler
func (*LoopCreatedEvent) Validate ¶
func (e *LoopCreatedEvent) Validate() error
Validate implements message.Payload
type LoopEntity ¶
type LoopEntity struct {
ID string `json:"id"`
TaskID string `json:"task_id"`
State LoopState `json:"state"`
Role string `json:"role"`
Model string `json:"model"`
Iterations int `json:"iterations"`
MaxIterations int `json:"max_iterations"`
PendingToolResults map[string]ToolResult `json:"pending_tool_results,omitempty"` // Accumulated tool results by call ID
StartedAt time.Time `json:"started_at,omitempty"` // When the loop was created
TimeoutAt time.Time `json:"timeout_at,omitempty"` // When the loop should timeout
ParentLoopID string `json:"parent_loop_id,omitempty"` // Parent loop ID for architect->editor relationship
// Multi-agent depth tracking
Depth int `json:"depth,omitempty"` // Current depth in agent tree (0 = root)
MaxDepth int `json:"max_depth,omitempty"` // Maximum allowed depth for spawned agents
// Signal support fields
PauseRequested bool `json:"pause_requested,omitempty"` // Pause requested, will pause at next checkpoint
PauseRequestedBy string `json:"pause_requested_by,omitempty"` // User who requested pause
StateBeforePause LoopState `json:"state_before_pause,omitempty"` // State before pause (for resume)
CancelledBy string `json:"cancelled_by,omitempty"` // User who cancelled the loop
CancelledAt time.Time `json:"cancelled_at,omitempty"` // When the loop was cancelled
// User context (for routing responses)
UserID string `json:"user_id,omitempty"` // User who initiated the loop
ChannelType string `json:"channel_type,omitempty"` // cli, slack, discord, web
ChannelID string `json:"channel_id,omitempty"` // Channel/session ID for routing responses
// Workflow context (for loops created by workflow commands)
WorkflowSlug string `json:"workflow_slug,omitempty"` // e.g., "add-user-auth"
WorkflowStep string `json:"workflow_step,omitempty"` // e.g., "design"
// Completion data (populated when loop completes)
// These fields enable SSE delivery of results via KV watch
Outcome string `json:"outcome,omitempty"` // success, failed, cancelled
Result string `json:"result,omitempty"` // LLM response content
Error string `json:"error,omitempty"` // Error message on failure
CompletedAt time.Time `json:"completed_at,omitempty"` // When the loop completed
// AGNTCY identity (Phase 2 AGNTCY integration)
// When set, provides DID-based cryptographic identity for this agent loop.
Identity *identity.AgentIdentity `json:"identity,omitempty"`
}
LoopEntity represents an agentic loop instance
func NewLoopEntity ¶
func NewLoopEntity(id, taskID, role, model string, maxIterations ...int) LoopEntity
NewLoopEntity creates a new LoopEntity with default values
func (*LoopEntity) IncrementIteration ¶
func (e *LoopEntity) IncrementIteration() error
IncrementIteration increments the iteration counter
func (*LoopEntity) TransitionTo ¶
func (e *LoopEntity) TransitionTo(newState LoopState) error
TransitionTo transitions the entity to a new state
func (*LoopEntity) Validate ¶
func (e *LoopEntity) Validate() error
Validate checks if the LoopEntity is valid
type LoopFailedEvent ¶
type LoopFailedEvent struct {
LoopID string `json:"loop_id"`
TaskID string `json:"task_id"`
Outcome string `json:"outcome"` // OutcomeFailed
Reason string `json:"reason"`
Error string `json:"error"`
Role string `json:"role"`
Model string `json:"model"`
Iterations int `json:"iterations"`
TokensIn int `json:"tokens_in"`
TokensOut int `json:"tokens_out"`
WorkflowSlug string `json:"workflow_slug,omitempty"`
WorkflowStep string `json:"workflow_step,omitempty"`
FailedAt time.Time `json:"failed_at"`
// User routing info for error notifications
ChannelType string `json:"channel_type,omitempty"`
ChannelID string `json:"channel_id,omitempty"`
UserID string `json:"user_id,omitempty"`
}
LoopFailedEvent is published when a loop fails.
func (*LoopFailedEvent) MarshalJSON ¶
func (e *LoopFailedEvent) MarshalJSON() ([]byte, error)
MarshalJSON implements json.Marshaler
func (*LoopFailedEvent) Schema ¶
func (e *LoopFailedEvent) Schema() message.Type
Schema implements message.Payload
func (*LoopFailedEvent) UnmarshalJSON ¶
func (e *LoopFailedEvent) UnmarshalJSON(data []byte) error
UnmarshalJSON implements json.Unmarshaler
func (*LoopFailedEvent) Validate ¶
func (e *LoopFailedEvent) Validate() error
Validate implements message.Payload
type LoopState ¶
type LoopState string
LoopState represents the current state of an agentic loop
const ( // Standard workflow states LoopStateExploring LoopState = "exploring" LoopStatePlanning LoopState = "planning" LoopStateArchitecting LoopState = "architecting" LoopStateExecuting LoopState = "executing" LoopStateReviewing LoopState = "reviewing" // Terminal states LoopStateComplete LoopState = "complete" LoopStateFailed LoopState = "failed" LoopStateCancelled LoopState = "cancelled" // Cancelled by user signal // Signal-related states LoopStatePaused LoopState = "paused" // Paused by user signal LoopStateAwaitingApproval LoopState = "awaiting_approval" // Waiting for user approval )
Loop states for the agentic state machine. The state machine supports fluid transitions (can move backward) except from terminal states.
func (LoopState) IsTerminal ¶
IsTerminal returns true if the state is a terminal state
type ModelConfig ¶
type ModelConfig struct {
Temperature float64 `json:"temperature,omitempty"`
MaxTokens int `json:"max_tokens,omitempty"`
}
ModelConfig represents configuration for a language model
func (ModelConfig) WithDefaults ¶
func (c ModelConfig) WithDefaults() ModelConfig
WithDefaults returns a copy of the config with default values applied
type ResponseAction ¶
type ResponseAction struct {
ID string `json:"id"`
Type string `json:"type"` // button, reaction
Label string `json:"label"`
Signal string `json:"signal"` // signal to send if clicked
Style string `json:"style"` // primary, danger, secondary
}
ResponseAction represents an interactive action in a response
type ResponseBlock ¶
type ResponseBlock struct {
Type string `json:"type"` // text, code, diff, file, progress
Content string `json:"content"`
Lang string `json:"lang,omitempty"` // for code blocks
}
ResponseBlock represents a block of content in a rich response
type TaskMessage ¶
type TaskMessage struct {
LoopID string `json:"loop_id,omitempty"` // loop to continue, or empty for new
TaskID string `json:"task_id"`
Role string `json:"role"`
Model string `json:"model"`
Prompt string `json:"prompt"`
// Workflow context (optional, set by workflow commands)
WorkflowSlug string `json:"workflow_slug,omitempty"` // e.g., "add-user-auth"
WorkflowStep string `json:"workflow_step,omitempty"` // e.g., "design"
// User routing info (optional, for error notifications)
ChannelType string `json:"channel_type,omitempty"` // e.g., "http", "cli", "slack"
ChannelID string `json:"channel_id,omitempty"` // session/channel identifier
UserID string `json:"user_id,omitempty"` // user who initiated the request
// Multi-agent hierarchy (optional, for parallel/nested agents)
ParentLoopID string `json:"parent_loop_id,omitempty"` // Parent loop ID for nested agents
Depth int `json:"depth,omitempty"` // Current depth in agent tree (0 = root)
MaxDepth int `json:"max_depth,omitempty"` // Maximum allowed depth
// Pre-constructed context (optional, skips discovery if present)
// When set, the agent loop uses this context directly instead of hydrating
Context *types.ConstructedContext `json:"context,omitempty"`
// Context assembly reference (links to assembled context)
ContextRequestID string `json:"context_request_id,omitempty"`
// Per-task tool override (optional, skips global discovery if present)
Tools []ToolDefinition `json:"tools,omitempty"`
// ToolChoice controls how the model selects tools for this task.
// Nil means "auto" (model decides). Cached for all iterations in the loop.
ToolChoice *ToolChoice `json:"tool_choice,omitempty"`
// Domain context propagated to all tool calls in this loop
Metadata map[string]any `json:"metadata,omitempty"`
}
TaskMessage represents a task to be executed by an agentic loop
func (*TaskMessage) MarshalJSON ¶
func (t *TaskMessage) MarshalJSON() ([]byte, error)
MarshalJSON implements json.Marshaler
func (*TaskMessage) Schema ¶
func (t *TaskMessage) Schema() message.Type
Schema implements message.Payload
func (*TaskMessage) UnmarshalJSON ¶
func (t *TaskMessage) UnmarshalJSON(data []byte) error
UnmarshalJSON implements json.Unmarshaler
func (TaskMessage) Validate ¶
func (t TaskMessage) Validate() error
Validate checks if the TaskMessage is valid
type TokenUsage ¶
type TokenUsage struct {
PromptTokens int `json:"prompt_tokens"`
CompletionTokens int `json:"completion_tokens"`
}
TokenUsage tracks token consumption for a request
func (TokenUsage) Total ¶
func (u TokenUsage) Total() int
Total returns the total number of tokens used
type ToolCall ¶
type ToolCall struct {
ID string `json:"id"`
Name string `json:"name"`
Arguments map[string]any `json:"arguments,omitempty"`
Metadata map[string]any `json:"metadata,omitempty"` // Domain context, propagated from task
LoopID string `json:"loop_id,omitempty"`
TraceID string `json:"trace_id,omitempty"`
}
ToolCall represents a request to call a tool
func (*ToolCall) MarshalJSON ¶
MarshalJSON implements json.Marshaler
func (*ToolCall) UnmarshalJSON ¶
UnmarshalJSON implements json.Unmarshaler
type ToolCallFilter ¶
type ToolCallFilter interface {
FilterToolCalls(loopID string, calls []ToolCall) (ToolCallFilterResult, error)
}
ToolCallFilter intercepts tool calls before execution. Implementations can approve, reject, or modify calls for authorization, rate limiting, or domain-scoped access control.
type ToolCallFilterResult ¶
type ToolCallFilterResult struct {
Approved []ToolCall
Rejected []ToolCallRejection
}
ToolCallFilterResult contains the outcome of filtering tool calls.
type ToolCallRejection ¶
ToolCallRejection pairs a rejected tool call with the reason it was denied.
type ToolChoice ¶
type ToolChoice struct {
Mode string `json:"mode"` // "auto", "required", "none", "function"
FunctionName string `json:"function_name,omitempty"` // required when Mode is "function"
}
ToolChoice controls how the model selects tools. Mode is one of: "auto" (default), "required", "none", or "function". When Mode is "function", FunctionName specifies which function to call.
func (ToolChoice) Validate ¶
func (tc ToolChoice) Validate() error
Validate checks if the ToolChoice has a valid mode and required fields.
type ToolDefinition ¶
type ToolDefinition struct {
Name string `json:"name"`
Description string `json:"description"`
Parameters map[string]any `json:"parameters"`
}
ToolDefinition represents the definition of a tool that can be called
func (ToolDefinition) Validate ¶
func (t ToolDefinition) Validate() error
Validate checks if the ToolDefinition is valid
type ToolResult ¶
type ToolResult struct {
CallID string `json:"call_id"`
Name string `json:"name,omitempty"` // Tool function name (required by Gemini on tool result messages)
Content string `json:"content,omitempty"`
Error string `json:"error,omitempty"`
Metadata map[string]any `json:"metadata,omitempty"`
LoopID string `json:"loop_id,omitempty"`
TraceID string `json:"trace_id,omitempty"`
StopLoop bool `json:"stop_loop,omitempty"` // Signal loop termination; Content becomes the completion result
}
ToolResult represents the result of a tool call
func (*ToolResult) MarshalJSON ¶
func (t *ToolResult) MarshalJSON() ([]byte, error)
MarshalJSON implements json.Marshaler
func (*ToolResult) Schema ¶
func (t *ToolResult) Schema() message.Type
Schema implements message.Payload
func (*ToolResult) UnmarshalJSON ¶
func (t *ToolResult) UnmarshalJSON(data []byte) error
UnmarshalJSON implements json.Unmarshaler
func (ToolResult) Validate ¶
func (t ToolResult) Validate() error
Validate checks if the ToolResult is valid
type Trajectory ¶
type Trajectory struct {
LoopID string `json:"loop_id"`
StartTime time.Time `json:"start_time"`
EndTime *time.Time `json:"end_time,omitempty"`
Steps []TrajectoryStep `json:"steps"`
Outcome string `json:"outcome,omitempty"`
TotalTokensIn int `json:"total_tokens_in"`
TotalTokensOut int `json:"total_tokens_out"`
Duration int64 `json:"duration"` // milliseconds
}
Trajectory represents the complete execution path of an agentic loop
func NewTrajectory ¶
func NewTrajectory(loopID string) Trajectory
NewTrajectory creates a new Trajectory with initialized values
func (*Trajectory) AddStep ¶
func (t *Trajectory) AddStep(step TrajectoryStep)
AddStep adds a step to the trajectory and updates totals
func (*Trajectory) Complete ¶
func (t *Trajectory) Complete(outcome string)
Complete marks the trajectory as complete and calculates final duration
type TrajectoryStep ¶
type TrajectoryStep struct {
Timestamp time.Time `json:"timestamp"`
StepType string `json:"step_type"`
RequestID string `json:"request_id,omitempty"`
Prompt string `json:"prompt,omitempty"`
Response string `json:"response,omitempty"`
TokensIn int `json:"tokens_in,omitempty"`
TokensOut int `json:"tokens_out,omitempty"`
ToolName string `json:"tool_name,omitempty"`
ToolArguments map[string]any `json:"tool_arguments,omitempty"`
ToolResult string `json:"tool_result,omitempty"`
Duration int64 `json:"duration"` // milliseconds
Messages []ChatMessage `json:"messages,omitempty"` // Full request messages (detail=full)
ToolCalls []ToolCall `json:"tool_calls,omitempty"` // Assistant tool calls (detail=full)
Model string `json:"model,omitempty"` // Model used
}
TrajectoryStep represents a single step in an agentic trajectory
func (TrajectoryStep) Validate ¶
func (s TrajectoryStep) Validate() error
Validate checks if the TrajectoryStep is valid
type TrajectoryStepEntity ¶
type TrajectoryStepEntity struct {
Step TrajectoryStep
Org string
Platform string
LoopID string
StepIndex int
// contains filtered or unexported fields
}
TrajectoryStepEntity wraps a TrajectoryStep with the context needed to produce a graph entity. It implements message.ContentStorable so that large content (tool results, model responses) is stored in ObjectStore while metadata-only triples go into the graph.
func (*TrajectoryStepEntity) ContentFields ¶
func (e *TrajectoryStepEntity) ContentFields() map[string]string
ContentFields returns the semantic role to field name mapping. This tells embedding workers which fields to use for text extraction.
func (*TrajectoryStepEntity) EntityID ¶
func (e *TrajectoryStepEntity) EntityID() string
EntityID returns the 6-part entity ID for this trajectory step.
func (*TrajectoryStepEntity) RawContent ¶
func (e *TrajectoryStepEntity) RawContent() map[string]string
RawContent returns the content to store in ObjectStore. Field names here match the values in ContentFields().
func (*TrajectoryStepEntity) SetStorageRef ¶
func (e *TrajectoryStepEntity) SetStorageRef(ref *message.StorageReference)
SetStorageRef sets the ObjectStore reference after content is stored.
func (*TrajectoryStepEntity) StorageRef ¶
func (e *TrajectoryStepEntity) StorageRef() *message.StorageReference
StorageRef returns the reference to stored content in ObjectStore.
func (*TrajectoryStepEntity) Triples ¶
func (e *TrajectoryStepEntity) Triples() []message.Triple
Triples returns metadata-only triples for this step. Large content (tool args/results, model responses) is NOT included — that goes to ObjectStore via RawContent/ContentFields.
type UserMessage ¶
type UserMessage struct {
// Identity
MessageID string `json:"message_id"`
ChannelType string `json:"channel_type"` // cli, slack, discord, web
ChannelID string `json:"channel_id"` // specific conversation/channel
UserID string `json:"user_id"`
// Content
Content string `json:"content"`
Attachments []Attachment `json:"attachments,omitempty"`
// Context
ReplyTo string `json:"reply_to,omitempty"` // loop_id if continuing
ThreadID string `json:"thread_id,omitempty"` // for threaded channels
Metadata map[string]string `json:"metadata,omitempty"` // channel-specific
ContextRequestID string `json:"context_request_id,omitempty"` // links to assembled context
// Timing
Timestamp time.Time `json:"timestamp"`
}
UserMessage represents normalized input from any channel (CLI, Slack, Discord, web)
func (*UserMessage) MarshalJSON ¶
func (m *UserMessage) MarshalJSON() ([]byte, error)
MarshalJSON implements json.Marshaler
func (*UserMessage) Schema ¶
func (m *UserMessage) Schema() message.Type
Schema implements message.Payload
func (*UserMessage) UnmarshalJSON ¶
func (m *UserMessage) UnmarshalJSON(data []byte) error
UnmarshalJSON implements json.Unmarshaler
func (UserMessage) Validate ¶
func (m UserMessage) Validate() error
Validate checks if the UserMessage is valid
type UserResponse ¶
type UserResponse struct {
ResponseID string `json:"response_id"`
ChannelType string `json:"channel_type"`
ChannelID string `json:"channel_id"`
UserID string `json:"user_id"` // who to respond to
// What we're responding to
InReplyTo string `json:"in_reply_to,omitempty"` // message_id or loop_id
ThreadID string `json:"thread_id,omitempty"`
// Content
Type string `json:"type"` // text, status, result, error, prompt, stream
Content string `json:"content"`
// Rich content (optional)
Blocks []ResponseBlock `json:"blocks,omitempty"`
Actions []ResponseAction `json:"actions,omitempty"`
Timestamp time.Time `json:"timestamp"`
}
UserResponse is sent back to users via their channel
func (*UserResponse) MarshalJSON ¶
func (r *UserResponse) MarshalJSON() ([]byte, error)
MarshalJSON implements json.Marshaler
func (*UserResponse) Schema ¶
func (r *UserResponse) Schema() message.Type
Schema implements message.Payload
func (*UserResponse) UnmarshalJSON ¶
func (r *UserResponse) UnmarshalJSON(data []byte) error
UnmarshalJSON implements json.Unmarshaler
func (UserResponse) Validate ¶
func (r UserResponse) Validate() error
Validate checks if the UserResponse is valid
type UserSignal ¶
type UserSignal struct {
SignalID string `json:"signal_id"`
Type string `json:"type"` // cancel, pause, resume, approve, reject, feedback, retry
LoopID string `json:"loop_id"`
UserID string `json:"user_id"`
ChannelType string `json:"channel_type"`
ChannelID string `json:"channel_id"`
Payload any `json:"payload,omitempty"` // signal-specific data (e.g., rejection reason)
Timestamp time.Time `json:"timestamp"`
}
UserSignal represents a control signal from user to affect loop execution
func (*UserSignal) MarshalJSON ¶
func (s *UserSignal) MarshalJSON() ([]byte, error)
MarshalJSON implements json.Marshaler
func (*UserSignal) Schema ¶
func (s *UserSignal) Schema() message.Type
Schema implements message.Payload
func (*UserSignal) UnmarshalJSON ¶
func (s *UserSignal) UnmarshalJSON(data []byte) error
UnmarshalJSON implements json.Unmarshaler
func (UserSignal) Validate ¶
func (s UserSignal) Validate() error
Validate checks if the UserSignal is valid