agent

package
v0.2.16 Latest Latest
Warning

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

Go to latest
Published: Oct 18, 2026 License: MIT Imports: 30 Imported by: 0

Documentation

Index

Constants

View Source
const (
	DefaultLoopWindowSize = 10
	DefaultLoopMaxRepeats = 4
)

Variables

This section is empty.

Functions

func ComputeInputHash

func ComputeInputHash(toolName, input string) string

ComputeInputHash calculates a stable hex-encoded SHA-256 hash for a tool input.

func ComputeSignature

func ComputeSignature(toolName, input, output string) string

ComputeSignature calculates a stable hex-encoded SHA-256 hash for a tool execution.

func FlattenToolDefinitions

func FlattenToolDefinitions(defs []llm.ToolDefinition) []llm.ToolDefinition

FlattenToolDefinitions normalizes all tool parameter schemas in-place for model tolerance.

func FlattenToolSchema

func FlattenToolSchema(schema map[string]any) map[string]any

FlattenToolSchema inlines $defs, resolves local $ref pointers, and flattens allOf structures so that models (Anthropic, DeepSeek, Ollama, etc.) receive clean, flattened JSON schemas without complex indirection.

func FormatLoopWarning

func FormatLoopWarning(toolName string, repeatCount int) string

FormatLoopWarning creates a descriptive diagnostic message when a loop is detected.

Types

type AgentDefinition

type AgentDefinition struct {
	ID          string     `json:"id"`
	Name        string     `json:"name"`
	Description string     `json:"description,omitempty"`
	Role        RoleFilter `json:"role_filter,omitempty"`
	Model       string     `json:"model,omitempty"`
	Prompt      string     `json:"prompt,omitempty"`
	Rules       string     `json:"rules,omitempty"`
	Color       string     `json:"color,omitempty"`
	AllowBash   bool       `json:"allow_bash"`
	ReadOnly    bool       `json:"read_only"`
	Tools       []string   `json:"tools,omitempty"`       // tool categories or tool names (e.g. "filesystem", "terminal", "git", "web", "browser")
	MCPServers  []string   `json:"mcp_servers,omitempty"` // enabled MCP server names (e.g. "exa", "figma")
	Skills      []string   `json:"skills,omitempty"`      // associated skill IDs
	CreatedAt   time.Time  `json:"created_at"`
	UpdatedAt   time.Time  `json:"updated_at"`
}

AgentDefinition is a pre-configured agent the user defines once (in global settings) and selects in chat.

type AgentMessage

type AgentMessage struct {
	ID        string         `json:"id"`
	Role      string         `json:"role"` // "user", "assistant", "system", "tool"
	Content   []ContentBlock `json:"content"`
	Timestamp time.Time      `json:"timestamp"`
}

AgentMessage is a message in an agent session. Content is block-based.

func (*AgentMessage) Text

func (m *AgentMessage) Text() string

Text returns the concatenated text of all text blocks (used for the LLM message payload and for legacy rendering).

func (*AgentMessage) Thinking

func (m *AgentMessage) Thinking() string

Thinking returns the concatenated thinking blocks (used for the legacy reasoning rendering and for the LLM payload when supported).

func (*AgentMessage) ToolCallBlocks

func (m *AgentMessage) ToolCallBlocks() []ContentBlock

ToolCallBlocks returns all tool_call blocks in the message.

func (*AgentMessage) ToolResultBlocks

func (m *AgentMessage) ToolResultBlocks() []ContentBlock

ToolResultBlocks returns all tool_result blocks in the message.

type AgentSchedule

type AgentSchedule struct {
	ID        string        `json:"id"`
	SessionID string        `json:"session_id"`
	Prompt    string        `json:"prompt"`
	TaskID    string        `json:"task_id,omitempty"`
	Duration  time.Duration `json:"duration,omitempty"`
	CronExpr  string        `json:"cron_expr,omitempty"`
	CreatedAt time.Time     `json:"created_at"`
	NextRun   time.Time     `json:"next_run"`
	Active    bool          `json:"active"`
	// contains filtered or unexported fields
}

func (*AgentSchedule) ToSnapshot

func (s *AgentSchedule) ToSnapshot() map[string]any

type ContentBlock

type ContentBlock struct {
	// Type is one of: "text", "thinking", "tool_call", "tool_result".
	Type string `json:"type"`

	// Text content for "text" and "thinking" blocks.
	Text string `json:"text,omitempty"`

	// Tool-call fields (type == "tool_call").
	ToolCallID string         `json:"tool_call_id,omitempty"`
	Name       string         `json:"name,omitempty"`
	Arguments  map[string]any `json:"arguments,omitempty"`

	// Tool-result fields (type == "tool_result").
	IsError bool `json:"is_error,omitempty"`
}

ContentBlock is a single block in an agent message. AssistantMessage content blocks. A message may carry multiple blocks of the same or different types (text + thinking + tool_call interleaved).

type LoopDetector

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

LoopDetector detects cyclic / spinning tool calls to prevent runaway agent loops and token exhaustion when the model gets stuck repeating failed operations.

func NewLoopDetector

func NewLoopDetector(windowSize, maxRepeats int) *LoopDetector

NewLoopDetector initializes a LoopDetector with configurable sliding window and repeat threshold.

func (*LoopDetector) HasLoop

func (d *LoopDetector) HasLoop() (bool, string, int)

HasLoop checks if a loop has been flagged.

func (*LoopDetector) Record

func (d *LoopDetector) Record(toolName, input, output string) (bool, int, string)

Record adds a tool interaction to the sliding window and evaluates whether the agent has entered a repetitive loop. Returns (isLoop, repeatCount, offendingToolName).

func (*LoopDetector) Reset

func (d *LoopDetector) Reset()

Reset clears the sliding window history.

type Manager

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

func NewManager deprecated

func NewManager(llmClient *llm.LLMClient, toolReg *tools.Registry, skillMgr *skills.Manager, pluginMgr *plugins.Manager, mcpMgr *mcp.Manager, termMgr ShellManager, bus *events.Bus, dataDir string) *Manager

NewManager is the v0.1.x positional constructor.

Deprecated: use NewManagerWithOptions; the positional signature is frozen and gains no new capabilities.

func NewManagerWithOptions added in v0.2.0

func NewManagerWithOptions(opts ManagerOptions) *Manager

NewManagerWithOptions builds the Manager from explicit options. See ManagerOptions for the field contract.

func (*Manager) ApplyDefinitionToSession

func (m *Manager) ApplyDefinitionToSession(sessionID string, defID string) error

ApplyDefinitionToSession re-configures an EXISTING session to use a pre-configured agent definition — changing its context (role, system prompt, custom rules, model) without creating a new session. Re-selecting an agent mode in the UI should switch the current session's behavior, not spawn a new tab.

func (*Manager) CancelSchedule

func (m *Manager) CancelSchedule(scheduleID string) bool

CancelSchedule cancels an active schedule or timer.

func (*Manager) ClearTasks

func (m *Manager) ClearTasks(sessionID string)

func (*Manager) CompactSession

func (m *Manager) CompactSession(sessionID string) (*Session, error)

CompactSession compacts the conversation history of a session by summarizing earlier turns into a structured context summary and keeping the first prompt and recent turns, drastically reducing context window usage.

func (*Manager) ConfigChanged

func (m *Manager) ConfigChanged()

ConfigChanged publishes an event so the frontend can refresh provider/model lists after settings change.

func (*Manager) CreateSession

func (m *Manager) CreateSession(name string, role RoleFilter, folder string) (*Session, error)

func (*Manager) CreateSessionFromDefinition

func (m *Manager) CreateSessionFromDefinition(defID string, folder string) (*Session, error)

CreateSessionFromDefinition creates a chat session from a pre-configured agent definition, scoped to the given project folder.

func (*Manager) DecideSubagentForTask

func (m *Manager) DecideSubagentForTask(task string) (AgentDefinition, *decisions.SubagentDecision)

DecideSubagentForTask uses Jev/Local to select the ideal subagent definition for a task.

func (*Manager) DecideSubagentRole

func (m *Manager) DecideSubagentRole(task string) *decisions.RoleDecision

DecideSubagentRole evaluates a task prompt using Jev/Local to select the optimal sub-agent role.

func (*Manager) DeleteAgentDefinition

func (m *Manager) DeleteAgentDefinition(id string) error

DeleteAgentDefinition removes a pre-configured agent definition.

func (*Manager) DeleteSession

func (m *Manager) DeleteSession(id string)

func (*Manager) FindDefinition

func (m *Manager) FindDefinition(roleOrID string) (AgentDefinition, bool)

FindDefinition returns a configured agent definition by ID, role, or name.

func (*Manager) GetDecisionAdapter added in v0.2.10

func (m *Manager) GetDecisionAdapter() *decisions.FileAdapter

GetDecisionAdapter returns the configured decisions file adapter.

func (*Manager) GetJevRouter

func (m *Manager) GetJevRouter() *decisions.Router

func (*Manager) GetSession

func (m *Manager) GetSession(id string) (*Session, bool)

func (*Manager) GetSubagents

func (m *Manager) GetSubagents(parentID string) []*Session

func (*Manager) GetUsageSummary

func (m *Manager) GetUsageSummary() map[string]interface{}

GetUsageSummary aggregates usage statistics across models, providers, and sessions.

func (*Manager) ListAgentDefinitions

func (m *Manager) ListAgentDefinitions() []AgentDefinition

ListAgentDefinitions returns all pre-configured agent definitions: built-in defaults plus ForgeADE-managed ones.

func (*Manager) ListSchedules

func (m *Manager) ListSchedules(sessionID string) []*AgentSchedule

ListSchedules returns all active or recent schedules for a session.

func (*Manager) ListSessions

func (m *Manager) ListSessions() []*Session

func (*Manager) ListSessionsForFolder

func (m *Manager) ListSessionsForFolder(folder string) []*Session

ListSessionsForFolder returns only the sessions linked to the given project folder (and subfolders). Sessions are project-scoped: opening a workspace shows only the agent sessions that belong to it, not every project's history.

func (*Manager) MemoryManager

func (m *Manager) MemoryManager() *memory.Manager

func (*Manager) RespondApproval

func (m *Manager) RespondApproval(ctx context.Context, sessionID string, approve bool, autoApproveAll bool) error

func (*Manager) RespondAsk

func (m *Manager) RespondAsk(sessionID string, answers map[string]any) error

RespondAsk injects the user's answers to pending `ask` questions back into the conversation as a tool result and resumes the agent turn.

func (*Manager) SaveAgentDefinition

func (m *Manager) SaveAgentDefinition(def AgentDefinition) (AgentDefinition, error)

SaveAgentDefinition creates or updates a pre-configured agent definition.

func (*Manager) ScheduleTimer

func (m *Manager) ScheduleTimer(sessionID string, duration time.Duration, cronExpr string, prompt string, taskID string) (string, error)

ScheduleTimer creates an active timer or cron job for an agent session.

func (*Manager) SendMessage

func (m *Manager) SendMessage(ctx context.Context, sessionID string, userContent string, mentionedPaths []string) error

func (*Manager) SetAutoApprove

func (m *Manager) SetAutoApprove(id string, enabled bool) error

SetAutoApprove toggles "yolo" mode for a session: when enabled, mutating tool calls are approved automatically without pausing for user approval.

func (*Manager) SetDecisionAdapter added in v0.2.10

func (m *Manager) SetDecisionAdapter(adapter *decisions.FileAdapter)

SetDecisionAdapter configures the unified decisions file adapter.

func (*Manager) SetDefaultFolder

func (m *Manager) SetDefaultFolder(folder string)

SetDefaultFolder sets the workspace root that sessions without an explicit folder are scoped to. Called by the app whenever a workspace is opened.

func (*Manager) SetDialect

func (m *Manager) SetDialect(id string, dialect string) error

SetDialect switches a session's tool-calling dialect. "" = native tool calling (default), "xml" = in-band XML tool calling (for providers without reliable native tools, e.g. some DeepSeek/GLM endpoints).

func (*Manager) SetJevRouter

func (m *Manager) SetJevRouter(r *decisions.Router)

func (*Manager) SetMemoryManager

func (m *Manager) SetMemoryManager(memMgr *memory.Manager)

func (*Manager) SetSessionModel added in v0.2.0

func (m *Manager) SetSessionModel(sessionID, model string) error

SetSessionModel pins the LLM model ("provider/model") for one session's subsequent turns without changing the engine-wide active profile. Hosts use it for per-session model switching (chat UIs, the rakit TUI).

func (*Manager) SetSessionName added in v0.2.0

func (m *Manager) SetSessionName(sessionID, name string) error

SetSessionName sets a session's display name (the /name command).

func (*Manager) SteerMessage

func (m *Manager) SteerMessage(sessionID string, instruction string) error

SteerMessage sends a mid-turn instruction directly into the running agent loop, immediately preempting any in-flight LLM stream or tool execution so the agent responds to the steering directive without waiting for the prior process.

func (*Manager) StopTurn

func (m *Manager) StopTurn(sessionID string)

StopTurn cancels the currently running agent turn for a session.

func (*Manager) ToggleTask

func (m *Manager) ToggleTask(sessionID string, taskID string, completed bool)

func (*Manager) ToolRegistry

func (m *Manager) ToolRegistry() *tools.Registry

ToolRegistry exposes the shared tool registry (background tasks, MCP tools).

func (*Manager) UpdateSession

func (m *Manager) UpdateSession(id string, name string, role RoleFilter, customPrompt string, customRules string) (*Session, error)

UpdateSession updates editable agent session fields (name, role, custom prompt, custom rules). The system prompt is rebuilt to include custom content.

func (*Manager) WaitSubagent

func (m *Manager) WaitSubagent(ctx context.Context, subID string, timeout time.Duration) (map[string]any, error)

type ManagerOptions added in v0.2.0

type ManagerOptions struct {
	// LLMClient, ToolRegistry, Skills, Plugins and MCP are required; hosts
	// typically build them via the engine facade, which handles defaults.
	LLMClient    *llm.LLMClient
	ToolRegistry *tools.Registry
	Skills       *skills.Manager
	Plugins      *plugins.Manager
	MCP          *mcp.Manager

	// Shell optionally supplies persistent PTY shells; nil makes shell tools
	// fall back to one-shot subprocesses.
	Shell ShellManager
	// Bus is the shared event bus the Manager publishes agent:* events on.
	Bus *events.Bus
	// DataDir roots session persistence (agent_sessions.json) and the
	// default memory manager.
	DataDir string
	// Memory optionally overrides the default memory manager (which is
	// rooted at DataDir).
	Memory *memory.Manager
}

ManagerOptions composes an agent Manager. It is the stable constructor surface (CONTRACT.md): new harness capabilities land as new optional fields, so hosts that construct with options never break.

type RoleFilter

type RoleFilter string
const (
	RoleCoding   RoleFilter = "coding"
	RolePlanning RoleFilter = "planning"
	RoleResearch RoleFilter = "research"
	RoleCustom   RoleFilter = "custom"
)

type Session

type Session struct {
	ID               string              `json:"id"`
	Name             string              `json:"name"`
	RoleFilter       RoleFilter          `json:"role_filter"`
	State            SessionState        `json:"state"`
	Folder           string              `json:"folder"`
	ProjectName      string              `json:"project_name,omitempty"`
	Model            string              `json:"model,omitempty"`
	AllowBash        bool                `json:"allow_bash,omitempty"`
	ReadOnly         bool                `json:"read_only,omitempty"`
	Tools            []string            `json:"tools,omitempty"`
	MCPServers       []string            `json:"mcp_servers,omitempty"`
	Skills           []string            `json:"skills,omitempty"`
	ParentSessionID  string              `json:"parent_session_id,omitempty"`
	SubagentIDs      []string            `json:"subagent_ids,omitempty"`
	Messages         []AgentMessage      `json:"messages"`
	Tasks            []TaskItem          `json:"tasks"`
	Progress         SessionProgress     `json:"progress,omitempty"`
	TokenUsage       llm.TokenStats      `json:"token_usage"`
	AutoApprove      bool                `json:"auto_approve"`
	PendingTools     []ContentBlock      `json:"pending_tools,omitempty"`
	PendingQuestions []tools.AskQuestion `json:"pending_questions,omitempty"`
	Dialect          string              `json:"dialect,omitempty"` // "" = native tool calling, "xml" = in-band
	// ContextTokens is the provider-reported prompt size of the last request
	// (real context window usage; 0 until the first model call of a session).
	ContextTokens int `json:"contextTokens,omitempty"`
	// CacheHitRate is the session-average prompt-cache hit rate:
	// (cumulative cached tokens) / (cumulative prompt tokens), combining
	// Anthropic-style CachedTokens and DeepSeek-style PromptCacheHitTokens.
	CacheHitRate float64 `json:"cacheHitRate,omitempty"`
	// EstimatedCost is the cumulative estimated cost in USD for the session.
	EstimatedCost float64   `json:"estimated_cost,omitempty"`
	SystemPrompt  string    `json:"system_prompt,omitempty"`
	CustomPrompt  string    `json:"custom_prompt,omitempty"`
	CustomRules   string    `json:"custom_rules,omitempty"`
	CreatedAt     time.Time `json:"created_at,omitempty"`
	UpdatedAt     time.Time `json:"updated_at"`
}

type SessionProgress

type SessionProgress struct {
	CurrentGoal    string   `json:"current_goal,omitempty"`
	CompletedSteps []string `json:"completed_steps,omitempty"`
	ActiveTodos    []string `json:"active_todos,omitempty"`
}

SessionProgress is durable, compact execution state (goal, done, todos) — injected into the system prompt each iteration so the model always knows its current objective instead of inferring it from a long transcript.

type SessionState

type SessionState string
const (
	StateIdle          SessionState = "idle"
	StateThinking      SessionState = "thinking"
	StateExecuting     SessionState = "executing"
	StateAwaiting      SessionState = "awaiting_approval"
	StateAwaitingInput SessionState = "awaiting_input"
)

type ShellManager

type ShellManager interface {
	CreateShell(name, folder string) (ShellSession, error)
	Write(id string, data []byte) (int, error)
	Resize(id string, rows, cols uint16) error
	Exec(id, command string, timeout time.Duration) (string, int, error)
	ExecContext(ctx context.Context, id, command string, timeout time.Duration) (string, int, error)
}

ShellManager is the persistent-shell provider used for bash sessions. The desktop app supplies its PTY terminal manager; nil makes shell tools fall back to one-shot subprocesses.

type ShellSession

type ShellSession interface{ GetID() string }

ShellSession is the minimal handle the engine needs from a created shell.

type SubagentNotification

type SubagentNotification struct {
	ID        string
	Name      string
	Role      string
	Output    string
	Completed time.Time
}

type TaskItem

type TaskItem struct {
	ID         string     `json:"id"`
	Title      string     `json:"title"`
	Status     TaskStatus `json:"status,omitempty"`
	ActiveForm string     `json:"active_form,omitempty"`
	Completed  bool       `json:"completed"`
}

type TaskStatus

type TaskStatus string
const (
	TaskPending    TaskStatus = "pending"
	TaskInProgress TaskStatus = "in_progress"
	TaskCompleted  TaskStatus = "completed"
)

type ToolExecutionSignature

type ToolExecutionSignature struct {
	ToolName string
	Input    string
	Output   string
	Hash     string
}

ToolExecutionSignature represents an observed tool interaction (name, input, and result).

Jump to

Keyboard shortcuts

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