Documentation
¶
Overview ¶
Package toroid provides an agent kernel with persistence, tool execution, usage accounting, and session history reconstruction.
Index ¶
- Constants
- func ApplyDefaults(cfg any)
- func BboltPath() (string, error)
- func CalculateCost(modelID string, usage Usage, curr string) (float64, error)
- func ConfigPath() (string, error)
- func DeleteSession(id string) error
- func LogDebug(msg string, args ...any)
- func LogError(msg string, args ...any)
- func LogInfo(msg string, args ...any)
- func NewProviderFromLLMId(llmID, apiKey string) (fantasy.Provider, error)
- func NewSessionID() string
- func PrettyPrintHistory(kernel *Kernel)
- func ReconstructHistory(traceID, spanID, systemPrompt string) ([]fantasy.Message, error)
- func RunnerDir(cwd, traceID string) (string, error)
- func SqlitePath() (string, error)
- func StorageDir() (string, error)
- func TracesDir() (string, error)
- type AssistantTurnPayload
- type CompactPayload
- type CompactSummaryPayload
- type Config
- type CostEvent
- type Event
- type EventKind
- type HookFn
- type HookRegistry
- type Kernel
- func (k *Kernel) Compact(ctx context.Context) error
- func (k *Kernel) ContextUsage() (int, int)
- func (k *Kernel) Fire(ctx context.Context, kind string, payload any) error
- func (k *Kernel) FireTraceLog(ctx context.Context, logType, message string) error
- func (k *Kernel) LogErr(msg string, args ...any)
- func (k *Kernel) Logf(msg string, args ...any)
- func (k *Kernel) Model() string
- func (k *Kernel) On(kind EventKind, fn HookFn)
- func (k *Kernel) OnAll(fn HookFn)
- func (k *Kernel) Run(ctx context.Context, prompt string) (string, UsagePayload, error)
- func (k *Kernel) RunSubagent(ctx context.Context, task string) (string, error)
- func (k *Kernel) RunningCostUSD() float64
- func (k *Kernel) SessionID() string
- func (k *Kernel) Stream(ctx context.Context, prompt string, w io.Writer) error
- func (k *Kernel) UpdateUse(u Usage, key string)
- func (k *Kernel) WorkDir() string
- type ModelPricing
- type NotificationPayload
- type PermissionPayload
- type ReasoningPayload
- type SessionInfo
- type SpanData
- type SpanMeta
- type StopPayload
- type Store
- func (s *Store) AppendCost(traceID, spanID string, turnUSD, totalUSD float64) error
- func (s *Store) AppendEvent(traceID, spanID string, event Event) error
- func (s *Store) LoadLastTotalUSD(traceID, spanID string) float64
- func (s *Store) LoadMemories(spanID string) (map[string]any, error)
- func (s *Store) LoadTraceMeta(traceID string) (TraceMeta, error)
- func (s *Store) LoadTraceTotal(traceID string) float64
- func (s *Store) SaveMemories(spanID string, mem map[string]any) error
- func (s *Store) SaveSpanMeta(meta SpanMeta) error
- func (s *Store) SaveTraceMeta(meta TraceMeta) error
- func (s *Store) UpdateTraceTitle(traceID, title string) error
- type SubagentPayload
- type TaskPayload
- type Thinking
- type TitlePayload
- type TokenPayload
- type ToolUsePayload
- type ToolUseResultPayload
- type TraceData
- type TraceLogPayload
- type TraceMeta
- type TurnCostPayload
- type USDToLocalCurrency
- type Usage
- type UsagePayload
- type UserPromptPayload
Constants ¶
const ( TraceLogInfo = "info" TraceLogWarning = "warning" TraceLogError = "error" )
Variables ¶
This section is empty.
Functions ¶
func ApplyDefaults ¶
func ApplyDefaults(cfg any)
func CalculateCost ¶
CalculateCost computes the total cost for a usage breakdown using default pricing.
func DeleteSession ¶
DeleteSession removes all data associated with a trace ID.
func NewProviderFromLLMId ¶
NewProviderFromLLMId creates a fantasy.Provider from an LLM ID of the form "provider/model-name" (matching the keys in pricing.json). Supported prefixes: google, anthropic, openai.
func NewSessionID ¶
func NewSessionID() string
NewSessionID generates a monotonic, human-readable session ID. Format: <unix_seconds>-<4char_random>
func PrettyPrintHistory ¶
func PrettyPrintHistory(kernel *Kernel)
func ReconstructHistory ¶
ReconstructHistory rebuilds a []fantasy.Message from the events stored in bbolt for a trace. Only events after the last compaction are replayed, so the returned history is exactly what the kernel would have in memory for a resumed session.
systemPrompt is prepended as a system message when non-empty. If spanID is non-empty only events from that span are used; otherwise events from all spans under the trace are combined in span order (useful for subagent traces).
func StorageDir ¶
StorageDir returns ~/.swarmbuddy/storage/, creating it if needed.
Types ¶
type AssistantTurnPayload ¶
type AssistantTurnPayload struct {
Messages json.RawMessage `json:"messages"`
}
AssistantTurnPayload is attached to EventAssistantTurn. Messages is a JSON-serialized []fantasy.Message containing the full structured content blocks (thinking, text, tool_use, tool_result) from all steps of the turn.
type CompactPayload ¶
type CompactSummaryPayload ¶
type CompactSummaryPayload struct {
Summary string `json:"summary"`
}
CompactSummaryPayload is attached to EventPostCompact. It contains the LLM-generated summary of the conversation before the context was reset.
type Config ¶
type Config struct {
Provider fantasy.Provider `json:"provider,omitempty" description:"llm provider"`
Model string `json:"model" description:"llm model name" default:"gemini-3-flash-preview"`
APIKey string `json:"api_key,omitempty" description:"API key for the provider"`
SessionID string `json:"session_id,omitempty" description:"unique identifier for the session"`
WorkDir string `json:"work_dir" description:"working directory" default:"current directory"`
MaxIter int `json:"max_iter" description:"max tool-call iterations" default:"50"`
Thinking Thinking `json:"thinking" description:"thinking budget: none | low | high" default:"none"`
ThinkingWriter io.Writer `json:"-"`
// Trace/span hierarchy
TraceID string `json:"trace_id,omitempty"` // inherited from parent; root sets TraceID = SessionID
ParentSpanID string `json:"parent_span_id,omitempty"` // parent kernel's SessionID
// Persistence
Save bool `json:"save" description:"persist events, costs and metadata to the bbolt store" default:"false"`
// Session management
Resume bool `json:"resume" description:"if true, load existing session history and continue" default:"false"`
GenerateTitle bool `json:"generate_title" description:"if true, generate title for the session" default:"false"`
// compaction
CompactionBufferSize int `json:"compaction_buffer_size" description:"buffer size for history compaction" default:"30000"`
ToolCallPrunedSize int `json:"tool_call_prune" description:"token limit for tool call after pruning" default:"40000"`
TotalContextSize int `json:"total_context_size" description:"total context window size" default:"300000"`
// logging flags
AttachLoggerHooks *bool `json:"attach_logger_hooks,omitempty" description:"automatically attach logger hooks" default:"false"`
ShowHistory *bool `json:"show_history" description:"print history" default:"false"`
}
Config holds all options for creating a Kernel.
type CostEvent ¶
type CostEvent struct {
TS int64 `json:"ts"` // UnixNano (from bucket key)
TurnUSD float64 `json:"turn_usd"`
TotalUSD float64 `json:"total_usd"`
}
CostEvent is a single turn cost record stored under a span.
type Event ¶
type Event struct {
Kind EventKind `json:"kind"`
SessionID string `json:"session_id"`
TraceID string `json:"trace_id"`
SpanID string `json:"span_id"`
EmitTS int64 `json:"emit_ts"` // UnixNano wall clock
Seq uint64 `json:"seq"` // monotonic counter within a span
Payload any `json:"payload,omitempty"`
}
type EventKind ¶
type EventKind string
const ( EventTraceLog EventKind = "TraceLog" // structured log entry stored in the trace; visible in UI and readable by follow-on agents EventSessionStart EventKind = "SessionStart" EventUserPromptSubmit EventKind = "UserPromptSubmit" EventToken EventKind = "Token" // each streamed text chunk (display only, not stored) EventPermissionRequest EventKind = "PermissionRequest" // before a tool is called, if permission is required EventPreToolUse EventKind = "PreToolUse" // before a tool is called EventPostToolUse EventKind = "PostToolUse" // after a tool call is completed EventPostToolUseFailure EventKind = "PostToolUseFailure" // after a tool call fails EventSubagentStart EventKind = "SubagentStart" // before the subagent is started EventSubagentStop EventKind = "SubagentStop" // before the subagent is stopped EventMasterIdle EventKind = "MasterIdle" // after the main agent is idle EventNotification EventKind = "Notification" // before the notification is sent EventTaskCompleted EventKind = "TaskCompleted" // before the task is completed EventTitle EventKind = "Title" // fired async when session title is ready EventReasoning EventKind = "Reasoning" // streamed reasoning/thinking tokens (display only, not stored) EventAssistantTurn EventKind = "AssistantTurn" // full structured content blocks for the turn (thinking+text+tool_use) EventTurnCost EventKind = "TurnCost" // after each LLM turn, with incremental cost EventStop EventKind = "Stop" // when the agent is stopped EventPreCompact EventKind = "PreCompact" // before compacting the memory EventPostCompact EventKind = "PostCompact" // after compaction; payload contains the LLM-generated summary EventSessionEnd EventKind = "SessionEnd" // after the session ends )
type HookRegistry ¶
type HookRegistry struct {
// contains filtered or unexported fields
}
func (*HookRegistry) Fire ¶
func (r *HookRegistry) Fire(ctx context.Context, e Event) error
Fire runs all registered hooks for the event kind in order. A non-nil error from any hook aborts the chain and is returned.
func (*HookRegistry) On ¶
func (r *HookRegistry) On(kind EventKind, fn HookFn)
type Kernel ¶
type Kernel struct {
// contains filtered or unexported fields
}
Kernel is the agentic orchestrator powered by Fantasy.
func (*Kernel) ContextUsage ¶
ContextUsage returns (used tokens, total context window size).
func (*Kernel) FireTraceLog ¶
FireTraceLog emits an EventTraceLog with the given severity and message.
func (*Kernel) RunSubagent ¶
RunSubagent runs a subagent synchronously and returns its output.
func (*Kernel) RunningCostUSD ¶
RunningCostUSD returns the cumulative LLM cost so far in this session.
type ModelPricing ¶
type ModelPricing struct {
Prompt float64 `json:"Prompt"`
Completion float64 `json:"Completion"`
Reasoning float64 `json:"Reasoning"`
CacheRead float64 `json:"CacheRead"`
CacheWrite float64 `json:"CacheWrite"`
}
ModelPricing defines the cost per token for an LLM.
func GetModelPricing ¶
func GetModelPricing(modelID string) (ModelPricing, error)
GetModelPricing returns the singleton pricing instance.
type NotificationPayload ¶
type PermissionPayload ¶
type ReasoningPayload ¶
type ReasoningPayload struct {
Text string `json:"text"`
}
type SessionInfo ¶
type SessionInfo struct {
ID string // trace ID (root span ID)
Title string
StartedAt int64 // UnixNano
DurationNs int64 // last cost event ts - started_at (wall time)
AgentTimeNs int64 // wall time minus total tool execution time
TotalUSD float64 // sum of all turn_usd across all spans
}
SessionInfo holds metadata for listing traces/sessions.
func ListSessions ¶
func ListSessions() ([]SessionInfo, error)
ListSessions returns all traces sorted newest first.
func (SessionInfo) AgentTimeFmt ¶
func (s SessionInfo) AgentTimeFmt() string
func (SessionInfo) DurationFmt ¶
func (s SessionInfo) DurationFmt() string
func (SessionInfo) StartedAtFmt ¶
func (s SessionInfo) StartedAtFmt() string
type SpanMeta ¶
type SpanMeta struct {
SpanID string `json:"span_id"`
TraceID string `json:"trace_id"`
ParentSpanID string `json:"parent_span_id,omitempty"`
Model string `json:"model,omitempty"`
Title string `json:"title,omitempty"`
StartedAt int64 `json:"started_at"` // UnixNano
EndedAt int64 `json:"ended_at,omitempty"`
}
SpanMeta is stored per span (kernel session, including subagents).
type StopPayload ¶
type StopPayload struct {
Reason string `json:"reason"`
}
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store wraps a bbolt database for all persistence needs.
func NewStore ¶
NewStore opens (or reuses) the singleton bbolt database (~/.swarmbuddy/traces.bbolt.db).
func NewStoreReadWrite ¶
NewStoreReadWrite is an alias for NewStore. Both CLI and server share one file. Only one process should hold the lock at a time.
func (*Store) AppendCost ¶
AppendCost records a turn cost under a span's cost bucket.
func (*Store) AppendEvent ¶
AppendEvent records a session event under a span's event bucket.
func (*Store) LoadLastTotalUSD ¶
LoadLastTotalUSD returns the total_usd from the most recent cost entry for a span, or 0 if none.
func (*Store) LoadMemories ¶
LoadMemories reads the agent's persistent memory JSON blob for a span.
func (*Store) LoadTraceMeta ¶
LoadTraceMeta reads trace metadata by trace ID.
func (*Store) LoadTraceTotal ¶
LoadTraceTotal returns the sum of the last total_usd across all spans for a trace. This represents the cumulative cost of all previous runs under this trace ID.
func (*Store) SaveMemories ¶
SaveMemories writes the agent's persistent memory JSON blob for a span.
func (*Store) SaveSpanMeta ¶
SaveSpanMeta writes or updates span metadata.
func (*Store) SaveTraceMeta ¶
SaveTraceMeta writes or updates trace metadata.
func (*Store) UpdateTraceTitle ¶
UpdateTraceTitle patches only the title field of an existing TraceMeta, preserving StartedAt.
type SubagentPayload ¶
type SubagentPayload struct {
SessionID string `json:"session_id"`
Prompt string `json:"prompt"`
Output string `json:"output,omitempty"`
UsagePayload UsagePayload `json:"usage,omitempty"`
}
type TaskPayload ¶
type TitlePayload ¶
type TitlePayload struct {
Title string `json:"title"`
}
type TokenPayload ¶
type TokenPayload struct {
Text string `json:"text"`
}
type ToolUsePayload ¶
type ToolUseResultPayload ¶
type TraceData ¶
TraceData is the full trace for visualization.
func LoadTraceData ¶
LoadTraceData reads the full trace + all spans + costs for a given trace ID.
type TraceLogPayload ¶
TraceLogPayload is attached to EventTraceLog.
type TraceMeta ¶
type TraceMeta struct {
TraceID string `json:"trace_id"`
Title string `json:"title,omitempty"`
StartedAt int64 `json:"started_at"` // UnixNano
EndedAt int64 `json:"ended_at,omitempty"`
}
TraceMeta is stored per trace (root kernel run).
type TurnCostPayload ¶
type TurnCostPayload struct {
TurnUsage Usage `json:"turn_usage"` // tokens consumed in this single turn
TurnCostUSD float64 `json:"turn_cost_usd"` // cost of this turn in USD
TotalCostUSD float64 `json:"total_cost_usd"` // cumulative cost so far in USD
}
TurnCostPayload is attached to EventTurnCost, fired after each LLM turn.
type USDToLocalCurrency ¶
type USDToLocalCurrency struct {
Name string `json:"name"`
Rate float64 `json:"rate"`
Date string `json:"date"`
}
LLM endpoint returns cost in USD, for local currency calculation we need to create a map
func GetCurrencyMultiplier ¶
func GetCurrencyMultiplier(curr string) (USDToLocalCurrency, error)
type Usage ¶
type UsagePayload ¶
type UsagePayload struct {
Tokens map[string]Usage `json:"tokens"` // sessionID -> token breakdown
}
UsagePayload is attached to EventStop and contains the total token usage across the session and all subagents it spawned, keyed by session ID.
type UserPromptPayload ¶
type UserPromptPayload struct {
Prompt string `json:"prompt"`
}