agent

package
v0.11.0-beta.2 Latest Latest
Warning

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

Go to latest
Published: Oct 23, 2026 License: Apache-2.0, MIT Imports: 55 Imported by: 0

Documentation

Overview

Package agent — Caveman Mode + prompt compression (master plan §4.4).

As the token budget approaches its cap, escalate the system prompt with a directive to be progressively terser. Three tiers — chatty (default), curt (50% budget), caveman (80%+) — so the agent voluntarily compresses its own output before it forces a hard compaction.

The mutation is purely additive: we append a directive to the existing system prompt rather than replace it. Callers with no budget estimator get the original prompt unchanged.

Package agent — adapter that lets a contract-driven AutonomousRunner drive a real *agent.Agent.

Each StepDriver.Step is one full Agent.Run turn (assistant response + any internal tool calls until the model is done with that turn). The AutonomousRunner owns the iteration; the driver only handles one turn.

Package agent — Task Flow checkpoint machine (master plan §7.1 Layer 7). When the agent loop hits maxSteps mid-task, we save the in-flight state and exit with TaskTimedOut so a follow-up alarm can fire a sub-agent that resumes from step N+1.

The mental model: an interrupted task is a *recoverable* failure, not a permanent one. We can't just retry the last step in isolation because LLM context drives the next action — we need the full history. The flow record captures everything the resume sub-agent needs to continue: history, original user input, model, where we were in the step loop, and a small reason payload for the user.

State corruption is treated as a hard abort: a malformed JSON blob in the session store shouldn't trigger an infinite retry loop. The resume path inspects the blob and either resumes cleanly or reports "checkpoint corrupted, won't retry" to the alarm dispatcher.

Package agent — flow resume entrypoint. Called from the alarm dispatcher when an alarm whose prompt encodes a flow ID fires. The resume path:

  1. Loads the persisted FlowState
  2. Bumps Resumes (gated by MaxResumes — three strikes and stop)
  3. Restores the agent's history from the checkpoint
  4. Re-enters Stream with the original user input
  5. On clean completion, Delete the flow record so it doesn't keep showing up in `alarm_list`. On another timeout, the next CheckpointFlow overwrites the same record.

The resume contract is "complete this task from where it stopped" — no human in the loop. Errors are non-recoverable: a corrupt checkpoint, an exhausted flow, or a missing record all return without retrying. The alarm dispatcher logs and moves on.

Package agent — PostgreSQL-backed FlowStore for the daemon.

Package agent — hallucination scanner integration (Batch G3).

Sits between the streamed response assembly and the response filter. After the model finishes a turn we hand the assembled content + the session's evidence corpus to the scanner; if the scanner annotates anything, the annotated content goes into history instead of the raw text. The model reads the [?] markers on its next turn and learns to re-ground.

The interface lives here so internal/agent doesn't import the concrete internal/halluscan package — same separation we use for the post-write verifier and memory orchestrator.

Package agent — @path mention pre-loader.

When a user message contains tokens like `@README.md` or `@internal/foo.go`, we pre-fetch the file contents (best effort, capped per file and total) and inject them into the conversation as a system message before the model is asked to respond.

Package agent — DeepPlanner: autonomous codebase analysis + plan generation.

DeepPlanner runs a silent subagent that reads the codebase for 5-15 minutes, builds a mental model, and produces three artifacts:

  • plan.md — phased implementation plan for the build agent
  • architecture.mmd — Mermaid architecture diagram
  • plan.html — DeepWiki-style rendered plan for human review

Inspired by Amp Code's Oracle + Deep mode pattern: the planner "goes dark" while reading/analysing, then surfaces everything at once.

Package agent's provenance.go tags every message flowing into the agent loop with its origin. When messages flow between sessions (sub-agent → parent, cron → main agent), the receiving agent can distinguish "the user said this" from "another agent computed this." This is a security boundary.

Stolen from OpenClaw's src/sessions/input-provenance.ts.

Package agent — interactive question API.

Mirrors the approval bridge: tools (or other code) can call AskQuestion to pause the agent and surface a prompt to the user via QuestionFunc.

Package agent — cryptographic tool receipts (master plan §7.1 Emergency Controls). Every tool call the agent makes produces one receipt; receipts form a hash chain so any single tampered entry invalidates the rest. The chain is what makes a post-incident audit trustworthy: if the receipt for "shell rm -rf /important" exists, the agent actually ran it; if someone edits the ledger to hide it, Verify() catches the break.

Implementation notes:

  • SHA-256 used for the chain hash. Not "speed at any cost" — we only chain on completion of each tool call, so the cost is negligible compared to the LLM call that produced it.
  • PrevHash of the first receipt is the empty string by design, not a random nonce. Replaying a chain from scratch should be bit-identical to its original creation so VerifyChain can be run by any auditor with the same receipts.
  • Receipts capture INPUT + OUTPUT hashes, not the bodies. Bodies can be huge (file contents); hashes give us tamper detection without bloating the chain. If a user wants the bodies they can also persist a separate journal — receipts are the verifiable index.

Package agent — Reflexion wiring (paper #51 AlphaGRPO recipe).

The agent keeps a tiny Reflector interface so internal/reflect can own the actual reflection logic without internal/agent picking up a hard import. After each tool batch, stream.go classifies failed results, asks the reflector for a structured note, and injects that note as a system message before the next model turn.

Budgeted: max N reflections per turn (default 2). Multiple concurrent failures don't drown the next prompt; the agent sees the most salient ones and the rest still surface via raw error.

Package agent — post-write verifier integration.

The agent holds a PostWriteVerifier interface. After each tool dispatch in either execution loop, if the tool succeeded AND the verifier is wired, we extract write paths from the tool input and run them through the verifier. Failures land as an extra system message in history so the model sees them on the next turn.

The interface lives in package agent (not internal/verify) so the agent doesn't import internal/verify directly — the wiring layer in cmd/overkill plugs the concrete registry in via SetPostWriteVerifier. Keeps internal/agent dependency-free of the actual verifier implementations.

Index

Constants

View Source
const (
	BeatFirstFailure  = "first_failure"
	BeatFirstSuccess  = "first_success"
	BeatFirstRollback = "first_rollback"
)

Known beat types — string-typed so the agent doesn't need to import personality's enum. The recorder adapter on the personality side translates these to typed BeatType values.

View Source
const FlowResumePrefix = "overkill:flow:resume:"

FlowResumePrefix is the prompt prefix the alarm dispatcher looks for to recognise a resume alarm. Set when CheckpointFlow's caller schedules the alarm; checked when the alarm fires.

View Source
const MaxPlanBytes = 2 * 1024 * 1024
View Source
const MaxResumes = 3

MaxResumes is the cap on how many times a single flow can be resumed. Three is generous — most "stuck on max_steps" timeouts finish on the first or second resume. Beyond that, the task is genuinely too large for the configured budget and the user should see "give up" rather than the agent pinging itself forever.

Variables

View Source
var (
	ErrGoalBudget     = errors.New("agent: goal budget exhausted")
	ErrGoalTurnActive = errors.New("agent: another turn is already using this goal")
	ErrGoalChanged    = errors.New("agent: goal changed during the turn; start a new turn")
)
View Source
var ErrFlowCorrupt = errors.New("flow: checkpoint corrupt")

ErrFlowCorrupt signals "the persisted checkpoint can't be parsed". Resume callers MUST treat this as terminal — DO NOT retry, because retrying corrupt state is what produces infinite loops.

View Source
var ErrFlowExhausted = errors.New("flow: max resumes exceeded")

ErrFlowExhausted signals "this flow has been resumed MaxResumes times". The task is too large for the agent's budget; the user should see the final state instead of another resume attempt.

Functions

func BuildSystemPrompt

func BuildSystemPrompt(base string, registry *tools.Registry) string

func ExtractFlowID

func ExtractFlowID(prompt string) string

ExtractFlowID inspects a prompt and returns the embedded flow ID, or "" when this isn't a resume prompt. Lets the dispatcher cheaply branch on prompt shape without committing to a richer payload.

func FindPlanFiles

func FindPlanFiles() []string

FindPlanFiles discovers plan files in common locations.

func FormatConfidence

func FormatConfidence(ca *ConfidenceAssessment) string

func FormatResumePrompt

func FormatResumePrompt(flowID string) string

FormatResumePrompt builds the alarm prompt that triggers resume. Use this everywhere the daemon constructs a resume alarm so the prefix stays in one place.

func GoalSteeringProvider

func GoalSteeringProvider(store *GoalStore, sessionID string) func(ctx context.Context, sessionID string) string

GoalSteeringProvider returns a contextProviderFn that injects a steering message into the system prompt when the goal status requires it.

If the goal status is "budget_limited", the agent is told to wrap up and report completion.

If the goal status is "blocked", the agent is told the task is blocked and should not continue.

func IsDangerousTool

func IsDangerousTool(command string) bool

IsDangerousTool checks a command string against the dangerous pattern list.

func IsRisky

func IsRisky(toolName string) bool

IsRisky returns true when toolName is a destructive tool that should trigger an auto-snapshot before execution.

func StartVerification

func StartVerification(ctx context.Context, name, path string) func(status, note string)

StartVerification is called by the wiring adapter immediately before an actual checker invocation. The returned callback must be called exactly once.

func ValidateRuntimeStatus

func ValidateRuntimeStatus(snapshot RuntimeStatusSnapshot, sessionID string) error

func VerifyChain

func VerifyChain(receipts []Receipt) (int, error)

VerifyChain walks receipts in order and reports the first index where the chain is broken — either a hash mismatch on the receipt itself OR a PrevHash that doesn't match the prior receipt's Hash. Returns (-1, nil) when the chain is intact, (idx, err) when broken. An empty chain is intact by definition.

Types

type Agent

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

func New

func New(cfg Config) *Agent

func (*Agent) AskQuestion

func (a *Agent) AskQuestion(ctx context.Context, q Question) Answer

AskQuestion bridges a tool/agent call into the user-facing question UI. Blocks until the user answers.

func (*Agent) AuditAndRetry

func (a *Agent) AuditAndRetry(ctx context.Context, pre *audit.Snapshot, claims []audit.Claim, input string) (*audit.Report, error)

AuditAndRetry runs the completion audit and, if it fails, compacts the conversation, injects the audit findings as revision context, and retries agent.Run(). Returns the audit report + any retry error. Max 3 retries to prevent infinite loops.

func (*Agent) AutoMode

func (a *Agent) AutoMode() *AutoMode

AutoMode returns the current auto-mode controller, or nil if disabled.

func (*Agent) BudgetReport

func (a *Agent) BudgetReport() *BudgetReport

func (*Agent) Bus

func (a *Agent) Bus() *EventBus

Bus returns the agent's internal event bus. Subscribers receive structured lifecycle events (tool_impact, budget_warning, recovery, confidence). Returns nil only if the agent itself is nil.

func (*Agent) ClassifyInput

func (a *Agent) ClassifyInput(raw string) InputKind

ClassifyInput runs the installed classifier against raw input. When no classifier is set, returns InputKindNL (everything is natural language).

func (*Agent) ClearGoal

func (a *Agent) ClearGoal(ctx context.Context) error

ClearGoal removes the goal for the current session.

func (*Agent) ClearHistory

func (a *Agent) ClearHistory()

func (*Agent) Compact

func (a *Agent) Compact(ctx context.Context) (compactResult *CompactResult, compactErr error)

Compact summarizes the current conversation history into a single message, drastically reducing token usage while preserving key decisions and state.

func (*Agent) ContinueStream

func (a *Agent) ContinueStream(ctx context.Context, state *FlowState) (<-chan StreamEvent, error)

ContinueStream resumes a trusted application's admitted durable checkpoint. It does not append the original user input or invoke slash-command handlers. Callers must verify session/workspace/model and own exclusive turn admission.

func (*Agent) DiscardSpeculation

func (a *Agent) DiscardSpeculation()

DiscardSpeculation cancels any running speculation (called when the user sends a new message).

func (*Agent) EStop

func (a *Agent) EStop()

EStop broadcasts an emergency-stop to every in-flight run loop on this agent. The streaming/react paths select on the channel and abort within the next loop iteration (typically <1s for tool calls, instantaneous for token streaming). Idempotent — subsequent calls after the channel is closed are no-ops.

func (*Agent) EvolutionEngine

func (a *Agent) EvolutionEngine() *learning.Engine

func (*Agent) ExportHistory

func (a *Agent) ExportHistory(path string) (string, error)

ExportHistory writes the current session's message history to a markdown file at the given path. Creates parent directories as needed. Returns the absolute path written.

func (*Agent) FireSessionEnd

func (a *Agent) FireSessionEnd(ctx context.Context)

FireSessionEnd fires on_session_end once per agent lifetime. Shutdown gives user-defined cleanup scripts a bounded context independent of a cancelled turn.

func (*Agent) FireSessionStart

func (a *Agent) FireSessionStart(ctx context.Context)

FireSessionStart fires the on_session_start hook (master plan §6.3). Safe to call repeatedly; Run and Stream fire it on the first admitted turn.

func (*Agent) Fork

func (a *Agent) Fork(name string) (string, error)

Fork creates a new session branched from the current one with an optional display name. The child inherits the full message history and the parent is linked via ParentID. Returns the new session ID. Returns an error when no forker is configured or no session is active.

func (*Agent) GenerateTitle

func (a *Agent) GenerateTitle(ctx context.Context) (title string, titleErr error)

GenerateTitle asks the provider for a short, descriptive session title based on the current conversation history. Used by the TUI immediately after the first user-assistant exchange to replace the placeholder "session 2026-01-01 12:34" with something useful (master plan §4.6).

Best-effort: a provider error returns ("", err) and the caller falls back to the placeholder. Capped at 80 output tokens and a single completion call — this should not be a hot-path cost.

func (*Agent) GetGoal

func (a *Agent) GetGoal(ctx context.Context) (string, error)

GetGoal returns the current goal text or empty string if none.

func (*Agent) History

func (a *Agent) History() []providers.Message

func (*Agent) Inject

func (a *Agent) Inject(msg providers.Message) error

func (*Agent) InjectSteer

func (a *Agent) InjectSteer(content, role string)

InjectSteer pushes a steered message into the agent's steering queue so it arrives mid-task on the next tool-iteration drain. If no steering queue is configured this is a no-op.

func (*Agent) Interrupt

func (a *Agent) Interrupt()

Interrupt cancels the currently running stream for this agent by cancelling the per-stream context. Safe to call from any goroutine. No-op if no stream is running. Unlike EStop (which halts ALL future runs), Interrupt only cancels the in-flight turn — subsequent runs proceed normally.

func (*Agent) IsBusy

func (a *Agent) IsBusy() bool

IsBusy returns true when the agent loop is actively running or history is non-empty (a turn was started). Used by gateway dispatch to guard against commands that would interrupt a running agent.

func (*Agent) IsRunning

func (a *Agent) IsRunning() bool

IsRunning is an alias for IsBusy — returns true when Run() is executing.

func (*Agent) Mode

func (a *Agent) Mode() string

Mode returns the current plan/build mode. Defaults to "build" if unset.

func (*Agent) Model

func (a *Agent) Model() string

func (*Agent) PauseGoal

func (a *Agent) PauseGoal(ctx context.Context) error

PauseGoal pauses the goal (sets active=false) for the current session.

func (*Agent) PermissionLog

func (a *Agent) PermissionLog() []security.LedgerEntry

PermissionLog returns a snapshot of decisions for the active session. Returns nil if no ledger is attached.

func (*Agent) PopLastExchange

func (a *Agent) PopLastExchange() string

PopLastExchange removes the last user→assistant exchange from history. It walks backwards from the end, finds the last "user" message, and truncates everything from that point onward. Returns the text of the removed user message ("" if nothing was removed).

func (*Agent) PrivilegeMode

func (a *Agent) PrivilegeMode() security.PrivilegeMode

PrivilegeMode returns the effective mode, or empty when no gate is wired.

func (*Agent) QueueSnapshot

func (a *Agent) QueueSnapshot() QueueState

QueueSnapshot returns the current sequential processing queue state for the TUI Queue pane. Thread-safe.

func (*Agent) ReadCache

func (a *Agent) ReadCache() *speculative.ReadCache

ReadCache returns the speculative read cache, or nil when unset.

func (*Agent) Receipts

func (a *Agent) Receipts() []Receipt

Receipts returns the cryptographic tool-call audit chain. Snapshot is a copy — safe for external persistence or display.

func (*Agent) ResetStop

func (a *Agent) ResetStop()

ResetStop replaces the stop channel after an estop, so the agent can resume serving new runs. Called by Shutdown / Reconfigure paths when the wiring layer decides the agent is healthy again.

func (*Agent) RestoreHistory

func (a *Agent) RestoreHistory(history []providers.Message)

RestoreHistory replaces the agent's in-memory history with the supplied messages. Used by flow resume to re-hydrate the conversation before continuing from a checkpoint. Caller owns the slice; we copy to avoid sharing the underlying array with the resume orchestrator.

func (*Agent) ResumeGoal

func (a *Agent) ResumeGoal(ctx context.Context) error

ResumeGoal resumes the goal (sets active=true) for the current session.

func (*Agent) Retry

func (a *Agent) Retry(ctx context.Context) (string, error)

Retry replays the last user message. It removes the last exchange from history then re-runs the agent loop with the recovered user text, so the model gets a fresh shot at the same prompt.

func (*Agent) Rollback

func (a *Agent) Rollback(n int) (string, error)

Rollback rolls back to the Nth most recent checkpoint (0 = latest). Requires SetCheckpointManager to have been called first.

func (*Agent) Run

func (a *Agent) Run(ctx context.Context, userInput string) (runResult *RunResult, runErr error)

func (*Agent) RunCompletionAudit

func (a *Agent) RunCompletionAudit(ctx context.Context, pre *audit.Snapshot, claims []audit.Claim) *audit.Report

RunCompletionAudit takes a pre-task snapshot and a set of claims about what the agent accomplished, and verifies them against the current repo state. Returns nil when no auditor is wired.

func (*Agent) RunVariants

func (a *Agent) RunVariants(ctx context.Context, prompt string, models []string) (results []VariantResult, variantErr error)

RunVariants runs the same prompt against each model in parallel using the agent's existing provider, sharing the current history but not mutating it.

Tools are intentionally not invoked — variants are for model output comparison, not for diverging tool execution.

func (*Agent) RuntimeStatusSnapshot

func (a *Agent) RuntimeStatusSnapshot() RuntimeStatusSnapshot

func (*Agent) SessionID

func (a *Agent) SessionID() string

func (*Agent) SessionMetrics

func (a *Agent) SessionMetrics() (toolCalls int, errors int, recoveries int, turns int, totalTurnDuration time.Duration)

SessionMetrics returns a snapshot of the current session's metrics.

func (*Agent) SetApprovalFunc

func (a *Agent) SetApprovalFunc(fn ApprovalFunc)

SetApprovalFunc installs a callback to gate risky tool calls. Pass nil to disable approval prompts.

func (*Agent) SetAutoMemory

func (a *Agent) SetAutoMemory(e *automemory.Extractor)

SetAutoMemory enables post-turn memory extraction.

func (*Agent) SetAutoMode

func (a *Agent) SetAutoMode(level string)

SetAutoMode configures autonomous execution behavior. Pass a level string ("safe", "yolo", "auto") to enable; pass "" or "supervised" for legacy behavior. Auto mode loads plan files, batches upfront questions, and chains phases without human input. "readonly" independently denies mutating tool calls; other levels do not install an approval policy or OS sandbox.

func (*Agent) SetBeatRecorder

func (a *Agent) SetBeatRecorder(r BeatRecorder)

SetBeatRecorder wires the recorder. Pass nil to disable.

func (*Agent) SetCheckpointManager

func (a *Agent) SetCheckpointManager(cm *CheckpointManager)

SetCheckpointManager wires the git-based checkpoint manager for user-facing /snapshot, /rollback, and /snapshots slash commands. Pass nil to disable.

func (*Agent) SetCheckpointSnapshotter

func (a *Agent) SetCheckpointSnapshotter(s CheckpointSnapshotter)

SetCheckpointSnapshotter installs the auto-snapshot hook. Pass nil to disable.

func (*Agent) SetChipManager

func (a *Agent) SetChipManager(cm interface {
	Render(ctx context.Context) string
	ContextProvider() func(ctx context.Context, sessionID string) string
})

SetChipManager wires a prompt.ChipManager as the agent's context provider. The manager's Render method is called each turn to produce per-turn context from all registered chips (directory, git branch, git diff, etc.). This replaces any previously installed contextProviderFn. Pass nil to disable chip-based context injection.

func (*Agent) SetCompactor

func (a *Agent) SetCompactor(c HistoryCompactor, use bool)

SetCompactor installs a compaction strategy. When use is false the agent keeps its in-built ad-hoc compaction path even if c is non-nil — handy as a kill switch. Pass (nil, false) to revert to the legacy path.

func (*Agent) SetCompletionAuditor

func (a *Agent) SetCompletionAuditor(aud *audit.Auditor)

SetCompletionAuditor wires the anti-lazy-LLM completion auditor. Pass nil to disable. The auditor is invoked after Run() completes in auto/build mode to verify the agent actually did what it claimed.

func (*Agent) SetCompletionEmitter

func (a *Agent) SetCompletionEmitter(e *events.Emitter, tracker cost.Tracker)

SetCompletionEmitter wires the completion-event emitter (§8.7.2). When set, the emitter is called once at the end of every Run() with a populated CompletionEvent. Pass nil to disable. costTracker is optional; pass nil if per-session cost data is not available.

func (*Agent) SetContextProvider

func (a *Agent) SetContextProvider(fn func(ctx context.Context, sessionID string) string)

SetContextProvider installs a callback that returns extra system-prompt text to inject before each turn. Used by the TUI to bridge plugin context providers without the agent depending on the plugin package. Empty return means "nothing to add". The callback should respect ctx for cancellation.

func (*Agent) SetEventFn

func (a *Agent) SetEventFn(fn func(event string, payload map[string]any))

SetEventFn installs a fire-and-forget event callback used to notify subscribers (plugins, journal, telemetry) about lifecycle moments. Known events: "tool_call", "compact", "error", "chat_message".

func (*Agent) SetEvolutionEngine

func (a *Agent) SetEvolutionEngine(engine *learning.Engine)

SetEvolutionEngine binds recording and reviewed guidance to this workspace. The model has no tool for approving or installing generated guidance.

func (*Agent) SetExtensionsManager

func (a *Agent) SetExtensionsManager(em ExtensionsManager)

SetExtensionsManager wires the extensions manager (P2). When set, the agent renders enabled extensions into the system prompt. Pass nil to disable.

func (*Agent) SetFeatureManager

func (a *Agent) SetFeatureManager(fm *features.Manager)

SetFeatureManager wires the feature-flag manager (P1). When set, the agent gates prompt sections behind feature flags. Pass nil to disable.

func (*Agent) SetFlightRecorder

func (a *Agent) SetFlightRecorder(fr *journal.FlightRecorder)

SetFlightRecorder wires the journal flight recorder (§4.19). When set, every user input, agent reply, and tool call is written to ~/.overkill/journal/raw/ as append-only JSONL. Nil-safe — pass nil to disable flight recording.

func (*Agent) SetFlowStore

func (a *Agent) SetFlowStore(store FlowStore, alarmSink func(*FlowState))

SetFlowStore wires durable flow checkpointing. When set, hitting maxSteps mid-stream saves the agent's state via the store and invokes the alarm sink (if also configured) so a follow-up alarm can resume the task. Pass nil to disable — max-steps exits as EventError, no checkpoint persisted.

func (*Agent) SetForker

func (a *Agent) SetForker(fn func(ctx context.Context, parentID, name string) (string, error))

SetForker wires the session forking backend. Pass nil to disable.

func (*Agent) SetGoal

func (a *Agent) SetGoal(ctx context.Context, text string) error

SetGoal sets or updates the standing goal for the current session.

func (*Agent) SetGoalStore

func (a *Agent) SetGoalStore(gs *GoalStore)

SetGoalStore wires the goal store. When set, the active goal is injected into the system prompt every turn. Pass nil to disable goal features.

func (*Agent) SetHallucinationScanner

func (a *Agent) SetHallucinationScanner(s HallucinationScanner)

SetHallucinationScanner wires the scanner. nil disables. Safe to call at any time; affects the NEXT turn's post-stream pass.

func (*Agent) SetHistory

func (a *Agent) SetHistory(messages []providers.Message)

func (*Agent) SetInputClassifier

func (a *Agent) SetInputClassifier(fn func(string) InputKind)

SetInputClassifier wires a function that classifies raw user input into shell vs NL vs ambiguous. Pass nil to clear (all input treated as NL).

func (*Agent) SetInstructionSource

func (a *Agent) SetInstructionSource(source *instructions.Source)

SetInstructionSource installs explicitly authorized guidance. Passing nil revokes it for subsequent requests without retaining contents in history.

func (*Agent) SetLearningRecorder

func (a *Agent) SetLearningRecorder(r LearningRecorder)

SetLearningRecorder installs the recovery-success recorder. Pass nil to disable.

func (*Agent) SetLearningStore

func (a *Agent) SetLearningStore(store *learning.Store)

SetLearningStore wires the correction learning store (§6.5). When set, the agent queries for relevant past corrections before each Run() and records new corrections after successful turns. Pass nil to disable.

func (*Agent) SetMemoryArchiver

func (a *Agent) SetMemoryArchiver(ar MemoryArchiver)

SetMemoryArchiver wires the archiver consulted during compaction. Pass nil to disable. Per-message size filter applied internally so callers don't need to pre-filter.

func (*Agent) SetMemoryRetriever

func (a *Agent) SetMemoryRetriever(r MemoryRetriever)

SetMemoryRetriever installs (or clears) the retriever consulted each turn to enrich the system prompt with relevant memories. Pass nil to disable.

func (*Agent) SetMode

func (a *Agent) SetMode(m string)

SetMode sets the agent's plan/build mode.

func (*Agent) SetModel

func (a *Agent) SetModel(modelID string)

func (*Agent) SetModelRouter

func (a *Agent) SetModelRouter(r ModelRouter)

SetModelRouter wires a per-turn model picker. Pass nil to disable.

func (*Agent) SetPermissionLedger

func (a *Agent) SetPermissionLedger(l *security.Ledger)

SetPermissionLedger attaches a ledger that records every approval decision for the /permissions overlay.

func (*Agent) SetPersonalityProvider

func (a *Agent) SetPersonalityProvider(fn func() string)

SetPersonalityProvider installs a callback that returns the personality directive appended to the system prompt each turn (§4.16). Pass nil to disable. The callback is recovered: a panic returns "" silently.

func (*Agent) SetPostWriteVerifier

func (a *Agent) SetPostWriteVerifier(v PostWriteVerifier)

SetPostWriteVerifier wires the verifier. nil disables. The agent is safe to use either way — when nil, the verifier hook is a no-op and the loop proceeds exactly as before.

func (*Agent) SetPrivilegeGate

func (a *Agent) SetPrivilegeGate(g *security.PrivilegeGate)

SetPrivilegeGate wires a privilege gate that pre-checks every tool call. Pass nil to disable (default). When wired in ReaderMode, write-like calls return security.ErrWriteDenied without ever reaching the tool.

func (*Agent) SetPrivilegeMode

func (a *Agent) SetPrivilegeMode(m security.PrivilegeMode)

SetPrivilegeMode flips the optional gate's mode. Configured readonly still takes precedence; only a trusted SetAutoMode configuration change clears it.

func (*Agent) SetPromptCompressor

func (a *Agent) SetPromptCompressor(c PromptCompressor, threshold float64)

SetPromptCompressor wires the compressor + trigger threshold (utilization fraction). threshold <= 0 defaults to 0.7. Pass nil to disable.

func (*Agent) SetQuestionFunc

func (a *Agent) SetQuestionFunc(fn QuestionFunc)

SetQuestionFunc installs the callback. Pass nil to disable interactive questions.

func (*Agent) SetReadCache

func (a *Agent) SetReadCache(c *speculative.ReadCache)

SetReadCache wires the speculative read cache (P2). When set, file-read tool paths check the cache before hitting disk. Pass nil to disable.

func (*Agent) SetRecoveryAlertSink

func (a *Agent) SetRecoveryAlertSink(s AlertSink, sessionID string)

SetRecoveryAlertSink wires an AlertSink onto the active ErrorRecovery so emitRecovery fires AlertTaskDeferred. Safe to call multiple times.

func (*Agent) SetRecoveryWriter

func (a *Agent) SetRecoveryWriter(w JournalEntryWriter)

SetRecoveryWriter installs a journal writer used by the error-recovery pipeline to persist lessons learned. Pass nil to disable persistence; the in-memory recovery report still flows through events either way.

func (*Agent) SetReflectionBudget

func (a *Agent) SetReflectionBudget(n int)

SetReflectionBudget overrides the per-turn reflection note cap. 0 disables reflection even if a reflector is wired.

func (*Agent) SetReflector

func (a *Agent) SetReflector(r Reflector)

SetReflector wires the reflector. Pass nil to disable. Setting a non-nil reflector implicitly enables a 2-note-per-turn budget; override with SetReflectionBudget if you need a different cap.

func (*Agent) SetResponseFilter

func (a *Agent) SetResponseFilter(f ResponseFilter)

SetResponseFilter installs the post-stream content cleaner. Pass nil to disable.

func (*Agent) SetRewriter

func (a *Agent) SetRewriter(r PromptRewriter)

SetRewriter installs the prompt rewriter middleware. Pass nil to disable.

func (*Agent) SetRuntimeStatusPersistence

func (a *Agent) SetRuntimeStatusPersistence(restored *RuntimeStatusSnapshot, persist func(context.Context, RuntimeStatusSnapshot) error) error

func (*Agent) SetSessionBookmarkStore

func (a *Agent) SetSessionBookmarkStore(s SessionBookmarkStore)

SetSessionBookmarkStore wires a bookmark store for session bookmarking. nil disables. Safe to call at any time.

func (*Agent) SetSessionID

func (a *Agent) SetSessionID(id string)

SetSessionID assigns the active session id. Used after the agent is wired to associate streaming events and ledger entries with the right session.

func (*Agent) SetSkillRegistry

func (a *Agent) SetSkillRegistry(r *skills.Registry)

SetSkillRegistry installs (or clears) the skill registry whose enabled + matching entries are rendered into the system prompt each turn. Pass nil to disable. The registry is consulted twice per turn: once for trigger-matched skills against the latest user input, and once for always-on skills (those with no triggers declared but Enabled=true).

func (*Agent) SetSpeculation

func (a *Agent) SetSpeculation(e *speculation.Engine)

SetSpeculation enables idle-time speculative execution.

func (*Agent) SetSubagentManager

func (a *Agent) SetSubagentManager(sm SubagentManager)

SetSubagentManager wires the sub-agent manager so the agent can list active sub-agents (for the TUI subagent panel). Pass nil to disable.

func (*Agent) SetThinkConfig

func (a *Agent) SetThinkConfig(cfg ThinkConfig)

SetThinkConfig toggles preamble streaming. Safe to call from any goroutine; takes the agent mutex. Pass cfg with Enabled=false to disable.

func (*Agent) SetThinkingLevel

func (a *Agent) SetThinkingLevel(level string)

SetThinkingLevel sets the extended thinking budget for the model. Valid values: off, minimal, low, medium, high, x-high. The value is passed through to the provider's request builder; providers that don't support thinking silently ignore it.

func (*Agent) SetUsageObserver

func (a *Agent) SetUsageObserver(fn func(modelID string, usage providers.Usage))

SetUsageObserver wires a callback fired after every step with the per-step token usage. Pass nil to clear.

func (*Agent) SetUserInputObserver

func (a *Agent) SetUserInputObserver(fn func(input string))

SetUserInputObserver wires a callback fired once per Run with the user's raw text. Pass nil to clear.

func (*Agent) Shutdown

func (a *Agent) Shutdown()

Shutdown cancels the agent's session-scoped context so background goroutines (auto-compaction etc.) wind down. Safe to call multiple times. Session-end hooks receive at most five seconds in total.

func (*Agent) Snapshot

func (a *Agent) Snapshot(name string) (string, error)

Snapshot creates a git-based filesystem checkpoint with the given name. Returns the new commit hash. Requires SetCheckpointManager to have been called first.

func (*Agent) Snapshots

func (a *Agent) Snapshots() (string, error)

Snapshots returns a human-readable listing of saved checkpoints. Requires SetCheckpointManager to have been called first.

func (*Agent) Steer

func (a *Agent) Steer(msg string) string

Steer queues a guidance message for mid-run injection into the agent loop. The message is appended to the SteeringQueue and will be drained into history between tool iterations. Returns a confirmation string.

func (*Agent) StopCh

func (a *Agent) StopCh() <-chan struct{}

StopCh exposes the estop channel for the streaming loop. Receiving on the returned channel signals "stop now"; the channel is closed on EStop.

func (*Agent) Stream

func (a *Agent) Stream(ctx context.Context, userInput string) (<-chan StreamEvent, error)

func (*Agent) StreamWithAttachments

func (a *Agent) StreamWithAttachments(ctx context.Context, userInput string, attachments []providers.Attachment) (<-chan StreamEvent, error)

StreamWithAttachments is the attachment-aware entry point. The plain Stream() delegates here with no attachments so existing call sites are untouched. Attachments are scanned-against the text input only — the bytes themselves bypass the text command scanners since they wouldn't produce meaningful matches against image data.

func (*Agent) StreamWithProvenance

func (a *Agent) StreamWithProvenance(ctx context.Context, userInput string, attachments []providers.Attachment, provenance *Provenance) (<-chan StreamEvent, error)

StreamWithProvenance is the full entry point. Provenance tags the message origin (§7.1.9) so the agent knows whether this came from a user, sub-agent, or cron job. Callers that don't set provenance get the default (user-originated).

func (*Agent) ThinkConfig

func (a *Agent) ThinkConfig() ThinkConfig

ThinkConfig returns the current think configuration. Safe for concurrent reads.

func (*Agent) ThinkingLevel

func (a *Agent) ThinkingLevel() string

ThinkingLevel returns the current thinking level setting.

func (*Agent) ToolNames

func (a *Agent) ToolNames() []string

ToolNames returns the names of registered tools, used by the TUI status dialog. Returns an empty slice if no registry is wired.

func (*Agent) Undo

func (a *Agent) Undo() (string, error)

Undo removes the last exchange from session history. If the last message is an assistant response, it removes that AND the user message before it. If the last message is a lone user message (no assistant reply yet), only that one is removed. Returns an error when history is too short to undo.

func (*Agent) VerificationSnapshot

func (a *Agent) VerificationSnapshot() VerificationStatus

type AgentSettings

type AgentSettings struct {
	// MaxToolOutputChars is the universal safety-net truncation limit
	// applied to every tool output before it enters history. See the
	// Agent Config's MaxToolOutputChars field for runtime wiring.
	// Default 8000; set to 0 to disable universal truncation.
	MaxToolOutputChars int `` /* 135-byte string literal not displayed */
}

AgentSettings are runtime-tunable agent parameters surfaced via the settings registry (~/.overkill/settings.toml). Each field has a TOML key, default value, and validation bounds declared via struct tags.

type AlertSink

type AlertSink interface {
	Create(alertType, message, sessionID string) error
}

AlertSink receives structured alerts surfaced at next session boot. The agent does not depend on the journal package directly — a tiny interface here keeps the import graph clean.

type Answer

type Answer struct {
	Text   string // free text or selected choice
	Index  int    // index into Choices, -1 if free text or no selection
	Cancel bool   // user dismissed
}

Answer carries the user's response.

type Approval

type Approval struct {
	Allow   bool
	Persist bool // remember choice for the rest of the session
}

Approval represents a user decision on a tool execution request.

type ApprovalFunc

type ApprovalFunc func(toolName string, args string, risk string) Approval

ApprovalFunc is invoked by the agent before executing a risky tool. It must block until the user decides. If nil, the agent auto-allows.

type AutoMode

type AutoMode struct {
	RequirePhaseEvaluation bool // durable continuations retain evaluation without raising tool authority
	Level                  AutonomyLevel
	Plan                   *Plan
	CurrentPhase           int
	Questions              []string // batched clarifying questions
	QuestionsDone          bool
	ContextBudget          int // token budget for auto-compress

	// SelfEval ties Reflector + ErrorRecovery + ConfidenceAssessment into
	// the L4 closed-loop self-revision pattern (§7.4). When non-nil and
	// Level == AutonomyAuto, each phase is run through the self-evaluate
	// loop instead of single-shot execution. Nil degrades to legacy
	// single-shot behavior with no auto-revision.
	SelfEval *SelfEvaluateLoop

	// CompletionFn, if set, fires when all plan phases complete (success
	// or failure). The caller can use this to notify the user via their
	// connected gateway (Telegram, Discord, etc.). Best-effort: panics
	// recovered, never blocks phase execution.
	CompletionFn func(result *SelfEvalResult)
}

AutoMode manages autonomous plan execution state.

func NewAutoMode

func NewAutoMode(level string) *AutoMode

NewAutoMode creates an auto-mode controller from config settings.

func (*AutoMode) BuildAutoPrompt

func (am *AutoMode) BuildAutoPrompt() string

BuildAutoPrompt constructs the system prompt extension for auto mode.

func (*AutoMode) FireCompletion

func (am *AutoMode) FireCompletion(result *SelfEvalResult)

FireCompletion calls the completion callback if all phases are done. Best-effort: panics are recovered, nil fn is a no-op.

func (*AutoMode) GenerateQuestions

func (am *AutoMode) GenerateQuestions() []string

GenerateQuestions analyzes the plan and generates batched clarifying questions. In auto mode these are asked upfront before any execution.

func (*AutoMode) HasFailed

func (am *AutoMode) HasFailed() bool

HasFailed reports whether any phase failed.

func (*AutoMode) IsAuto

func (am *AutoMode) IsAuto() bool

IsAuto reports whether we're in fully-autonomous mode.

func (*AutoMode) IsComplete

func (am *AutoMode) IsComplete() bool

IsComplete reports whether all phases are done or skipped.

func (*AutoMode) IsSafe

func (am *AutoMode) IsSafe() bool

IsSafe reports whether we're in safe mode.

func (*AutoMode) IsYolo

func (am *AutoMode) IsYolo() bool

IsYolo reports whether we're in yolo mode.

func (*AutoMode) MarkPhaseDone

func (am *AutoMode) MarkPhaseDone()

MarkPhaseDone marks the current phase as complete.

func (*AutoMode) MarkPhaseFailed

func (am *AutoMode) MarkPhaseFailed()

MarkPhaseFailed marks the current phase as failed.

func (*AutoMode) NextPhase

func (am *AutoMode) NextPhase() *PlanPhase

NextPhase returns the next pending phase and marks it running.

func (*AutoMode) PhasePrompt

func (am *AutoMode) PhasePrompt(phase *PlanPhase) string

PhasePrompt builds the prompt for a specific phase execution.

func (*AutoMode) Progress

func (am *AutoMode) Progress() string

Progress returns a formatted progress string.

func (*AutoMode) SetCompletionFn

func (am *AutoMode) SetCompletionFn(fn func(result *SelfEvalResult))

SetCompletionFn wires a callback that fires when all phases complete. Pass nil to disable. The callback receives the final SelfEvalResult.

func (*AutoMode) SetSelfEval

func (am *AutoMode) SetSelfEval(sel *SelfEvaluateLoop)

SetSelfEval wires the self-evaluate loop. Pass nil to disable.

func (*AutoMode) ShouldSelfEvaluate

func (am *AutoMode) ShouldSelfEvaluate() bool

ShouldSelfEvaluate reports whether this AutoMode configuration should use the L4 self-evaluate loop. True when SelfEval is wired AND level is AutonomyAuto (fully autonomous).

type AutonomyLevel

type AutonomyLevel string

AutonomyLevel maps config strings to behavior.

const (
	AutonomyReadonly   AutonomyLevel = "readonly"
	AutonomySupervised AutonomyLevel = "supervised"
	AutonomyFull       AutonomyLevel = "full"
	AutonomySafe       AutonomyLevel = "safe"
	AutonomyYolo       AutonomyLevel = "yolo"
	AutonomyAuto       AutonomyLevel = "auto"
)

func (AutonomyLevel) NeedsApproval

func (l AutonomyLevel) NeedsApproval(isDangerous bool) bool

NeedsApproval reports whether a tool call should trigger the approval dialog.

type BeatRecorder

type BeatRecorder interface {
	// RecordBeat fires a single beat of the given type with a short
	// context string. SessionID lets persistence track which session
	// each beat came from. Errors are intentionally absent — beat
	// recording is fire-and-forget; failures must not block the agent.
	RecordBeat(beatType string, contextText string, sessionID string)
}

BeatRecorder is the tiny interface the agent uses to fire relationship milestones (master plan §6.3 beat detection hooks). Implemented by personality.RelationshipTracker via a small adapter in cmd/overkill.

The agent doesn't import internal/personality directly — keeps the dependency one-way (agent ← personality, never agent → personality).

type BudgetEstimator

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

func NewBudgetEstimator

func NewBudgetEstimator(est *tokenizer.Estimator, maxTokens int) *BudgetEstimator

func NewBudgetEstimatorWithThresholds

func NewBudgetEstimatorWithThresholds(est *tokenizer.Estimator, maxTokens int, softPct, hardPct int) *BudgetEstimator

NewBudgetEstimatorWithThresholds allows callers to override the default soft/hard trigger percentages (e.g. from config).

func (*BudgetEstimator) CheckAndWarn

func (be *BudgetEstimator) CheckAndWarn(report *BudgetReport) string

func (*BudgetEstimator) Estimate

func (be *BudgetEstimator) Estimate(history []providers.Message, systemPrompt string, toolDefs []providers.Tool) *BudgetReport

func (*BudgetEstimator) EstimateWithIncoming

func (be *BudgetEstimator) EstimateWithIncoming(history []providers.Message, systemPrompt string, toolDefs []providers.Tool, incomingMessage string) *BudgetReport

EstimateWithIncoming produces a budget report that includes the estimated token cost of an incoming message before it is added to history. This allows ShouldCompact to trigger before a large single message pushes context from 40% → 95%+ in one turn (M3).

type BudgetReport

type BudgetReport struct {
	SystemPromptTokens    int     `json:"system_prompt_tokens"`
	HistoryTokens         int     `json:"history_tokens"`
	ToolDefTokens         int     `json:"tool_def_tokens"`
	EstimatedResponse     int     `json:"estimated_response_tokens"`
	IncomingMessageTokens int     `json:"incoming_message_tokens"` // M3: estimated incoming message size
	TotalEstimate         int     `json:"total_estimate"`
	MaxTokens             int     `json:"max_tokens"`
	Utilization           float64 `json:"utilization"`
	ShouldCompact         bool    `json:"should_compact"`
	ShouldWarn            bool    `json:"should_warn"`
	HardExceeded          bool    `json:"hard_exceeded"` // utilization >= hardThreshold
}

type BusEvent

type BusEvent struct {
	Kind    EventKind
	Payload interface{}
}

type CavemanLevel

type CavemanLevel int

CavemanLevel reports the current bluntness tier.

const (
	CavemanOff   CavemanLevel = iota // no mutation
	CavemanCurt                      // utilization >= 0.50
	CavemanBlunt                     // utilization >= 0.65
	CavemanFull                      // utilization >= 0.80
)

func LevelFromUtilization

func LevelFromUtilization(u float64) CavemanLevel

LevelFromUtilization maps a utilization fraction to a CavemanLevel.

func (CavemanLevel) Directive

func (l CavemanLevel) Directive() string

Directive is the line appended to the system prompt for a given level. Returns empty for CavemanOff so callers can skip the append.

func (CavemanLevel) String

func (l CavemanLevel) String() string

String returns a short label.

type CheckpointManager

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

CheckpointManager uses git to create, list, and roll back filesystem snapshots in a working directory. It's wired into the agent for the /snapshot and /rollback slash commands, and optionally for automatic pre-tool checkpoints.

func NewCheckpointManager

func NewCheckpointManager(workDir string) *CheckpointManager

NewCheckpointManager returns a CheckpointManager rooted at workDir. No git operations are performed until Snapshot/Rollback/ListSnapshots is called.

func (*CheckpointManager) FormatSnapshots

func (cm *CheckpointManager) FormatSnapshots() (string, error)

FormatSnapshots returns a human-readable listing suitable for display in chat. Returns an empty string with no error when there are no checkpoints.

func (*CheckpointManager) ListSnapshots

func (cm *CheckpointManager) ListSnapshots() ([]Snapshot, error)

ListSnapshots returns checkpoint commits reachable from HEAD, newest first. Only a subject beginning with "checkpoint: " identifies a checkpoint.

func (*CheckpointManager) Rollback

func (cm *CheckpointManager) Rollback(n int) (string, error)

Rollback restores the Nth listed checkpoint (zero is the latest). Both the original HEAD and dirty index/worktree are retained for recovery.

func (*CheckpointManager) RollbackContext

func (cm *CheckpointManager) RollbackContext(ctx context.Context, n int) (string, error)

RollbackContext observes cancellation before resetting. Once preservation or reset starts, Git is allowed to finish so cancellation cannot kill it halfway through an index/worktree update. Recovery artifacts are deliberately retained.

func (*CheckpointManager) Snapshot

func (cm *CheckpointManager) Snapshot(name string) (string, error)

Snapshot stages all changes (git add -A) and commits them with the message "checkpoint: <name>". Returns the new commit hash.

func (*CheckpointManager) WorkDir

func (cm *CheckpointManager) WorkDir() string

WorkDir returns the working directory this manager operates on.

type CheckpointReceipt

type CheckpointReceipt struct {
	ID      string `json:"id"`
	Scope   string `json:"scope"`
	Entries int    `json:"entries"`
	Notice  string `json:"notice"`
}

CheckpointReceipt exposes the actual recovery scope to user-facing clients.

type CheckpointSnapshotter

type CheckpointSnapshotter interface {
	// Snapshot captures the listed paths under sessionID with a one-line
	// reason. Returning an error blocks the tool call when recovery is enabled.
	// A missing snapshotter is a no-op for embedding/test callers.
	Snapshot(sessionID, reason string, paths []string) error
}

CheckpointSnapshotter is the tiny interface the agent uses to take a filesystem snapshot before a destructive tool call (master plan §4.8: "Filesystem checkpoints before destructive operations" — should be automatic, not at the LLM's discretion).

internal/checkpoint.Manager satisfies this via a thin cmd/overkill adapter so the agent doesn't import internal/checkpoint directly.

type Classification

type Classification struct {
	Type       ContentType
	Confidence float64 // 0.0–1.0, heuristic confidence
	Reason     string  // why this classification
	ItemCount  int     // if MultiItem, how many items detected
}

Classification is the result of content classification.

type CompactResult

type CompactResult struct {
	TokensBefore   int    `json:"tokens_before"`
	TokensAfter    int    `json:"tokens_after"`
	Summary        string `json:"summary"`
	MessagesBefore int    `json:"messages_before"`
	MessagesAfter  int    `json:"messages_after"`
}

CompactResult summarizes the outcome of a Compact call.

type ConfidenceAssessment

type ConfidenceAssessment struct {
	Level     ConfidenceLevel
	Score     float64
	Reasoning string
	TaskType  string
}

func AssessConfidence

func AssessConfidence(taskType string, history []providers.Message, model string) *ConfidenceAssessment

type ConfidenceFunc

type ConfidenceFunc func(taskType string, history []providers.Message, model string) *ConfidenceAssessment

ConfidenceFunc produces a confidence assessment for a completed task. Matches the signature of AssessConfidence in confidence.go.

type ConfidenceLevel

type ConfidenceLevel int
const (
	ConfidenceHigh ConfidenceLevel = iota
	ConfidenceMedium
	ConfidenceLow
	ConfidenceUnknown
)

func (ConfidenceLevel) String

func (cl ConfidenceLevel) String() string

type ConfidenceObservation

type ConfidenceObservation struct {
	Source      string   `json:"source"`
	Status      string   `json:"status"`
	StartedAt   string   `json:"started_at"`
	CompletedAt string   `json:"completed_at,omitempty"`
	Level       string   `json:"level,omitempty"`
	Score       *float64 `json:"score,omitempty"`
	Reasoning   string   `json:"reasoning,omitempty"`
}

ConfidenceObservation is a real heuristic computation, not a test pass or evidence that the optional iterative SelfEvaluateLoop ever executed.

type Config

type Config struct {
	Provider    providers.Provider
	Tools       *tools.Registry
	Compressors *tools.CompressorRegistry
	Hooks       *hooks.Registry
	Scanners    []security.Scanner
	Tokenizer   *tokenizer.Estimator
	Forethinker *Forethinker
	Steering    *SteeringQueue
	SpecDriver  *SpecDriver
	Model       string
	MaxTokens   int
	// ContextWindow is the total model context capacity; MaxTokens caps output.
	// Zero keeps the legacy MaxTokens-based budget estimator behavior.
	TokenLimits           providers.TokenLimitResolver
	ContextWindow         int
	SystemPrompt          string
	InstructionSource     *instructions.Source
	SystemPromptOverrides map[string]string // model ID → custom system prompt
	MaxSteps              int
	// DisableAtMentions requires all file reads to go through contained tools.
	DisableAtMentions bool
	// Workspace anchors @path reads; empty disables automatic file preload.
	Workspace string
	SessionID string
	// MaxToolOutputChars is the safety-net truncation limit applied to
	// every tool output before it enters history. Compressors run first;
	// if output still exceeds this limit, it is truncated with a
	// "[...truncated N chars, showing first X...]" marker. Default 8000.
	// Set to 0 to disable universal truncation.
	MaxToolOutputChars int
}

type ContentClassifier

type ContentClassifier struct {
	// ResearchSignals — words strongly correlated with academic/research content.
	ResearchSignals []string
	// EmotionalSignals — words correlated with emotional content.
	EmotionalSignals []string
	// CodeSignals — words correlated with code/engineering content.
	CodeSignals []string
	// MultiItemSeparators — patterns that split multi-item dumps.
	MultiItemSeparators []string
	// MinItemLength for multi-item detection — items shorter than this
	// are not counted as separate work items.
	MinItemLength int
}

ContentClassifier classifies user input into content types using lightweight keyword + pattern heuristics. Designed to be cheap enough to run on every turn (no LLM call). Can be extended with an optional LLM-based classifier for higher accuracy.

func NewContentClassifier

func NewContentClassifier() *ContentClassifier

NewContentClassifier returns a classifier with sensible defaults.

func (*ContentClassifier) Classify

func (cc *ContentClassifier) Classify(input string) Classification

Classify runs the classifier on user input. Returns the best-matching type with a confidence score and reason.

type ContentType

type ContentType int

ContentType classifies what kind of content the user is sending.

const (
	ContentUnknown       ContentType = iota
	ContentResearchDense             // papers, long-form technical, academic
	ContentEmotionalVent             // frustration, sadness, vulnerability
	ContentCodeReview                // PRs, diffs, bugs, architecture
	ContentCasualChat                // small talk, jokes, low-stakes
	ContentMultiItem                 // 3+ distinct requests in one message
	ContentInstruction               // single clear directive
	ContentNewsDigest                // summaries, digests, briefing
)

func (ContentType) String

func (ct ContentType) String() string

String returns the content type name.

type ContractDriver

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

ContractDriver adapts *Agent to subagent.StepDriver.

func NewContractDriver

func NewContractDriver(a *Agent, c *subagent.Contract, workdir string) *ContractDriver

NewContractDriver builds an adapter. workdir is the directory used to resolve relative OutFile specs; defaults to CWD.

func (*ContractDriver) Budget

Budget reads the agent's live budget estimate.

func (*ContractDriver) CheckOutput

func (d *ContractDriver) CheckOutput(ctx context.Context, outputs []subagent.Output) []string

CheckOutput satisfies OutFile by stat'ing the file under workdir. Other kinds are not auto-verifiable here — they're checked later via Acceptance.

func (*ContractDriver) Compact

Compact delegates to the agent's compaction pipeline.

func (*ContractDriver) Step

Step runs one agent turn. The first call seeds the agent with the contract bootstrap prompt; subsequent calls nudge it with "continue".

type Decomposer

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

Decomposer extracts discrete work items from natural language multi-item dumps. Uses separator patterns and heuristics — no LLM call.

func NewDecomposer

func NewDecomposer() *Decomposer

NewDecomposer returns a decomposer with sensible defaults.

func (*Decomposer) Decompose

func (d *Decomposer) Decompose(input string) []WorkItem

Decompose splits user input into discrete work items. Returns nil if fewer than 2 items are found (single-item input doesn't need sequential processing).

type DeepPlanner

type DeepPlanner struct {

	// ProjectRoot is the directory to analyse.
	ProjectRoot string
	// Timeout bounds the entire planning run (default 15 min).
	Timeout time.Duration
	// ModelOverride pins a specific model for planning (empty = SmartRouter).
	ModelOverride string
	// contains filtered or unexported fields
}

DeepPlanner orchestrates the plan-generation workflow.

func NewDeepPlanner

func NewDeepPlanner(a *Agent, projectRoot string) *DeepPlanner

NewDeepPlanner creates a planner bound to an agent.

func (*DeepPlanner) Run

func (dp *DeepPlanner) Run(ctx context.Context) (*PlanOutput, error)

Run executes the full deep-planning workflow. It reads the codebase, generates artifacts, and returns the output paths.

type ErrorRecovery

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

func NewErrorRecovery

func NewErrorRecovery(writer JournalEntryWriter) *ErrorRecovery

func (*ErrorRecovery) Analyze

func (er *ErrorRecovery) Analyze(err error, history []providers.Message) *RecoveryReport

func (*ErrorRecovery) FireDeferralAlert

func (er *ErrorRecovery) FireDeferralAlert(report *RecoveryReport)

FireDeferralAlert pushes a TaskDeferred alert through the sink. Best-effort; sink errors are intentionally swallowed so recovery never aborts on them.

func (*ErrorRecovery) FormatRecovery

func (er *ErrorRecovery) FormatRecovery(report *RecoveryReport) string

func (*ErrorRecovery) RecordLesson

func (er *ErrorRecovery) RecordLesson(report *RecoveryReport) error

func (*ErrorRecovery) SetAlertSink

func (er *ErrorRecovery) SetAlertSink(s AlertSink, sessionID string)

SetAlertSink attaches an alert sink so recovery reports can fire AlertTaskDeferred at the next session boot. Pass nil to disable.

type EventBus

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

func NewEventBus

func NewEventBus(opts ...EventBusOption) *EventBus

func (*EventBus) Close

func (b *EventBus) Close()

func (*EventBus) Dropped

func (b *EventBus) Dropped() map[EventKind]int64

func (*EventBus) Emit

func (b *EventBus) Emit(kind EventKind, payload interface{})

func (*EventBus) Subscribe

func (b *EventBus) Subscribe(kind EventKind, bufSize int) *Subscriber

func (*EventBus) Unsubscribe

func (b *EventBus) Unsubscribe(sub *Subscriber)

type EventBusOption

type EventBusOption func(*EventBus)

func WithBufferSize

func WithBufferSize(n int) EventBusOption

type EventKind

type EventKind string

type EventType

type EventType int
const (
	EventToken EventType = iota
	EventToolStart
	EventToolOutput
	EventDone
	EventError
	EventStatus
	EventReasoning
)

type ExtensionMeta

type ExtensionMeta struct {
	ID          string
	Name        string
	Kind        string
	Description string
}

ExtensionMeta is the minimal metadata for one extension, used in prompt rendering. Kept simple to avoid importing the extensions package.

type ExtensionsManager

type ExtensionsManager interface {
	ListEnabled() []ExtensionMeta
}

ExtensionsManager is satisfied by extensions.Manager. Tiny interface so agent doesn't depend on the extensions package for listing.

type Failure

type Failure struct {
	ToolName string
	Input    string
	Output   string
	Error    string
}

Failure mirrors internal/reflect.Failure so the agent doesn't have to import that package. The cmd/overkill wiring layer adapts between the two — same shape, separated by an interface.

type FlowJobStatus

type FlowJobStatus struct {
	ID         string    `json:"id"`
	SessionID  string    `json:"session_id"`
	Status     string    `json:"status"`
	DueAt      time.Time `json:"due_at"`
	Detail     string    `json:"detail"`
	Generation int64     `json:"generation"`
}

type FlowLease

type FlowLease struct {
	State      *FlowState
	Generation int64
	// contains filtered or unexported fields
}

func (*FlowLease) Close

func (l *FlowLease) Close()

func (*FlowLease) Finish

func (l *FlowLease) Finish(ctx context.Context, status, detail string) error

type FlowQueue

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

func NewFlowQueue

func NewFlowQueue(db *sql.DB, delay time.Duration) (*FlowQueue, error)

func (*FlowQueue) Bind

func (q *FlowQueue) Bind(sessionID, workspace, model, provider string) *SessionFlowStore

func (*FlowQueue) Claim

func (q *FlowQueue) Claim(ctx context.Context, id string) (*FlowLease, error)

Claim retains a dedicated database advisory lock until Close. Other app or daemon processes cannot execute this flow concurrently; process death releases the lock, allowing the next owner to classify a running job as ambiguous.

func (*FlowQueue) DeferBusy

func (q *FlowQueue) DeferBusy(ctx context.Context, id string)

func (*FlowQueue) Due

func (q *FlowQueue) Due(ctx context.Context) ([]string, error)

func (*FlowQueue) ListSession

func (q *FlowQueue) ListSession(ctx context.Context, sessionID string) ([]FlowJobStatus, error)

func (*FlowQueue) PauseAll

func (q *FlowQueue) PauseAll(ctx context.Context) error

func (*FlowQueue) PauseSession

func (q *FlowQueue) PauseSession(ctx context.Context, sessionID string) error

PauseSession is a durable stop latch. Even a late checkpoint from an older in-flight operation cannot queue work after the user explicitly stopped it.

func (*FlowQueue) Session

func (q *FlowQueue) Session(ctx context.Context, id string) (string, error)

func (*FlowQueue) TrySessionOperation

func (q *FlowQueue) TrySessionOperation(ctx context.Context, sessionID string) (func(), bool, error)

TrySessionOperation shares ordinary human/API and background admission across application processes. The connection lock spans execution and persistence.

func (*FlowQueue) Wake

func (q *FlowQueue) Wake(ctx context.Context, id string) error

type FlowState

type FlowState struct {
	Sequential   *SequentialCheckpoint `json:"sequential,omitempty"`
	LoadedPlan   *LoadedFlowPlan       `json:"loaded_plan,omitempty"`
	ResumeStatus string                `json:"resume_status,omitempty"`
	CancelEpoch  int64                 `json:"cancel_epoch,omitempty"`
	Workspace    string                `json:"workspace,omitempty"`
	ReadOnly     bool                  `json:"read_only,omitempty"`
	// ID is the flow's persistence key. Multiple resume attempts share
	// the same ID so the audit trail is linear.
	ID string `json:"id"`
	// SessionID anchors the flow to a session. Resume builds an agent
	// scoped to this session so cost/usage tracking stays correct.
	SessionID string `json:"session_id"`
	// UserInput is the original user prompt that kicked off the task.
	// Sub-agent resume includes this verbatim in the resume prompt so
	// the model has the original intent, not just the partial history.
	UserInput string `json:"user_input"`
	// Model + Provider pin the resume to the same backend the task
	// started on. Cross-model resume would muddy the audit trail and
	// confuse pricing.
	Model    string `json:"model"`
	Provider string `json:"provider,omitempty"`
	// History is the full conversation up to and including the last
	// completed step's tool result. Resume restores this into the
	// agent before continuing.
	History []providers.Message `json:"history"`
	// Step is the loop iteration index at which the task timed out.
	// Resume starts at Step (i.e. retry the step that ran out of
	// budget) — the saved history already contains all turns BEFORE
	// Step, so this is "where to continue from".
	Step int `json:"step"`
	// Reason is the human-readable cause of the timeout for the user
	// (e.g. "exceeded max steps (50) during auth refactor").
	Reason string `json:"reason"`
	// CreatedAt + ResumedAt give an audit trail: when did the task
	// first time out, when did it resume.
	CreatedAt time.Time   `json:"created_at"`
	ResumedAt []time.Time `json:"resumed_at,omitempty"`
	// Resumes counts how many times this flow was resumed. Used to
	// stop runaway resume loops — three resume attempts and we mark
	// the flow `failed` instead of saving another checkpoint.
	Resumes int `json:"resumes"`
}

FlowState is what gets persisted when a task times out. The struct is the on-wire JSON shape — keep fields stable.

func CheckpointFlow

func CheckpointFlow(store FlowStore, flowID, sessionID, userInput, model, provider string, history []providers.Message, step int, reason string, options ...func(*FlowState)) (*FlowState, error)

CheckpointFlow saves the in-flight state when the agent loop hits maxSteps. Called from stream.go's exit path. Idempotent — calling twice with the same flowID overwrites (last write wins; the more recent state has more history).

Returns the persisted FlowState so the caller can emit it on the stream's final event (which lets the TUI surface "timed out, will resume in N minutes" instead of an opaque error).

func MarkResumed

func MarkResumed(store FlowStore, flowID string) (*FlowState, error)

MarkResumed bumps the resume counter and stamps ResumedAt. Returns ErrFlowExhausted when the flow has already been resumed MaxResumes times — callers should NOT proceed with another resume; the task is too large for the configured budget.

func ResumeFlow

func ResumeFlow(ctx context.Context, store FlowStore, flowID string, a *Agent) (string, *FlowState, error)

ResumeFlow re-hydrates the agent from a persisted checkpoint and re-enters the streaming loop. The caller (typically the daemon's alarm dispatcher) provides an agent built fresh for this resume — we do NOT mutate the original agent that timed out, because it has already shut down with the TUI session.

Returns the assembled response text and the final FlowState. On ErrFlowExhausted the agent is NOT invoked; the caller should surface "task too large, gave up after N resumes" instead.

type FlowStore

type FlowStore interface {
	Save(state *FlowState) error
	Load(id string) (*FlowState, error)
	Delete(id string) error
	List() ([]*FlowState, error)
}

FlowStore is the persistence surface. Save is idempotent (overwrite by ID). Load returns ErrFlowCorrupt for blobs that can't be parsed so the caller doesn't have to guess.

type Forethinker

type Forethinker struct{}

func NewForethinker

func NewForethinker() *Forethinker

func (*Forethinker) Assess

func (f *Forethinker) Assess(toolName string, input json.RawMessage) *ImpactAssessment

type Goal

type Goal struct {
	ID                  string    `json:"id"`
	TimeUsedNanoseconds int64     `json:"time_used_nanoseconds"`
	Text                string    `json:"text"`
	Active              bool      `json:"active"`
	CreatedAt           time.Time `json:"created_at"`
	UpdatedAt           time.Time `json:"updated_at"`
	TokenBudget         int       `json:"token_budget"`
	TokensUsed          int       `json:"tokens_used"`
	TimeBudgetSeconds   int       `json:"time_budget_seconds"`
	TimeUsedSeconds     int       `json:"time_used_seconds"`
	Status              string    `json:"status"`
}

Goal is a standing objective that is injected into the system prompt every turn until paused or cleared.

type GoalAccountingState

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

GoalAccountingState belongs to one admitted turn, not to the Agent. Actual provider usage is incremental; persisted goal totals are never subtracted from per-turn totals. A durable turn ledger retains attribution after replacement.

func NewGoalAccountingState

func NewGoalAccountingState(store *GoalStore, sessionID string) *GoalAccountingState

func (*GoalAccountingState) Check

func (s *GoalAccountingState) Check(ctx context.Context) error

func (*GoalAccountingState) RecordTurnEnd

func (s *GoalAccountingState) RecordTurnEnd(_ context.Context, tokensUsed int) error

RecordTurnEnd accepts a cumulative total for this turn (legacy callers), persists only the unreported delta, and releases admission exactly once.

func (*GoalAccountingState) RecordTurnStart

func (s *GoalAccountingState) RecordTurnStart(ctx context.Context) error

func (*GoalAccountingState) RecordUsage

func (s *GoalAccountingState) RecordUsage(_ context.Context, usage providers.Usage) error

type GoalStore

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

GoalStore persists goals per session in PostgreSQL.

func NewGoalStore

func NewGoalStore(db *sql.DB) (*GoalStore, error)

NewGoalStore returns a GoalStore backed by the given *sql.DB.

func (*GoalStore) Clear

func (gs *GoalStore) Clear(ctx context.Context, sessionID string) error

Clear removes the goal for a session entirely.

func (*GoalStore) Get

func (gs *GoalStore) Get(ctx context.Context, sessionID string) (*Goal, error)

Get returns the current goal for a session, or nil if none exists.

func (*GoalStore) GetJSON

func (gs *GoalStore) GetJSON(ctx context.Context, sessionID string) (json.RawMessage, error)

GetJSON returns the current goal marshaled as JSON, or nil if none exists. Used by tools to bridge the GoalStore → GoalQuerier interface.

func (*GoalStore) Pause

func (gs *GoalStore) Pause(ctx context.Context, sessionID string) error

Pause sets the goal's active flag to false.

func (*GoalStore) Resume

func (gs *GoalStore) Resume(ctx context.Context, sessionID string) error

Resume sets the goal's active flag to true.

func (*GoalStore) Set

func (gs *GoalStore) Set(ctx context.Context, sessionID, text string) error

Set creates or updates the goal for a session.

func (*GoalStore) SetStatus

func (gs *GoalStore) SetStatus(ctx context.Context, sessionID, status string) error

SetStatus updates the goal's status field.

func (*GoalStore) SetWithBudgets

func (gs *GoalStore) SetWithBudgets(ctx context.Context, sessionID, text string, tokenBudget, timeBudget int) error

SetWithBudgets creates or updates the goal with optional token/time budgets.

func (*GoalStore) UpdateUsageAtomic

func (gs *GoalStore) UpdateUsageAtomic(ctx context.Context, sessionID string, tokens int, seconds int) (newTokens int, newSeconds int, budgetExceeded bool, err error)

UpdateUsageAtomic increments actual usage and marks either exhausted budget in the same SQL update. A zero budget is unlimited; equality exhausts a budget.

type HallucinationScanner

type HallucinationScanner interface {
	// Scan inspects content against the supplied evidence corpus
	// (concatenated session history + tool outputs) and returns
	// content annotated with [?] markers after unverified
	// references. When nothing was flagged, returns content
	// unchanged.
	Scan(content, evidence string) string
}

HallucinationScanner is the minimal surface the agent calls after each assistant turn. The wiring layer (cmd/overkill) plugs in the concrete scanner from internal/halluscan.

type HistoryCompactor

type HistoryCompactor interface {
	Compact(ctx context.Context, msgs []providers.Message, model string, maxTokens int) (compactedMsgs []providers.Message, summary string, err error)
}

HistoryCompactor abstracts the compaction strategy used by Agent.Compact. Tiny on purpose — keeps the agent free of the compaction package import.

type ImpactAssessment

type ImpactAssessment struct {
	ToolName      string
	AffectedPaths []string
	RiskLevel     RiskLevel
	Reasoning     string
	Protected     bool
}

type InputKind

type InputKind int

InputKind classifies user input routing (shell vs NL).

const (
	InputKindNL InputKind = iota
	InputKindShell
	InputKindAmbiguous
)

type ItemContext

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

ItemContext maps a work item to relevant files based on keywords. This is intentionally simple — a full implementation would use the codebase index or embeddings. For now, keyword matching on the item description finds likely-relevant paths.

func NewItemContext

func NewItemContext() *ItemContext

NewItemContext creates an empty item context mapper.

func (*ItemContext) FormatItemPrompt

func (ic *ItemContext) FormatItemPrompt(item WorkItem, totalItems int) string

FormatItemPrompt builds the prompt for a single work item, including relevant file context.

func (*ItemContext) IndexPath

func (ic *ItemContext) IndexPath(path string)

IndexPath registers a file path under relevant keywords.

func (*ItemContext) RelevantFiles

func (ic *ItemContext) RelevantFiles(item WorkItem) []string

RelevantFiles returns file paths relevant to a work item description. Matches keywords in the description against the indexed paths.

type ItemProcessor

type ItemProcessor func(ctx context.Context, item WorkItem) (result string, err error)

ItemProcessor is the callback that processes one work item. It receives the item context and should return the result text or an error. The processor is called once per item.

type IterationOutcome

type IterationOutcome int

IterationOutcome classifies what happened after one self-evaluate attempt.

const (
	IterAccepted IterationOutcome = iota // confidence met threshold — done
	IterRevised                          // revised and retried (next iteration)
	IterDeferred                         // exhausted iterations — escalate
)

func (IterationOutcome) String

func (o IterationOutcome) String() string

type IterativeEvaluationObservation

type IterativeEvaluationObservation struct {
	Source        string `json:"source"`
	Status        string `json:"status"`
	Phase         string `json:"phase"`
	Iteration     int    `json:"iteration"`
	MaxIterations int    `json:"max_iterations"`
	StartedAt     string `json:"started_at"`
	CompletedAt   string `json:"completed_at,omitempty"`
	Note          string `json:"note,omitempty"`
}

IterativeEvaluationObservation describes an actually invoked optional loop. Acceptance means the loop's confidence policy accepted, not that tests passed.

type JournalEntryWriter

type JournalEntryWriter interface {
	WriteEntry(entryType string, content string) error
}

type LearningCapture

type LearningCapture struct {
	ErrorClass   string
	Iterations   int
	WasRecovered bool
}

LearningCapture records metadata about a self-revision recovery event. Feeds into the learning pipeline via LearningRecorder.

type LearningRecorder

type LearningRecorder interface {
	RecordSuccess(class string) bool
}

LearningRecorder is the tiny interface the agent uses to feed recovered-from-error events into a self-learning pipeline (master plan §6.2). The real implementation lives in internal/skills/learn_trigger.go — defined here as an interface so the agent doesn't take a dep on skills just for this hook.

Semantics:

  • The agent calls RecordSuccess(class) only on the NEXT successful Run that follows a Run which failed with that class. This is the "recovered from X" signal — exactly what self-learning wants to count, not arbitrary task completions.
  • class is the diagnostic ladder error class ("compile", "test", "runtime", "lint", "network", "unknown") — same key the escalator uses (§4.13). Same class keys = aligned learning across the two systems.

type LoadedFlowPlan

type LoadedFlowPlan struct {
	RequireEvaluation bool    `json:"require_evaluation,omitempty"`
	MinConfidence     float64 `json:"min_confidence,omitempty"`
	MaxIterations     int     `json:"max_iterations,omitempty"`
	MaxRevisionDepth  int     `json:"max_revision_depth,omitempty"`
	Plan              Plan    `json:"plan"`
	CurrentPhase      int     `json:"current_phase"`
	Started           bool    `json:"started"`
}

LoadedFlowPlan contains scheduler data only. It carries no tool callbacks, approval capability, provider credential, or grant of autonomous authority.

type MemoryArchiver

type MemoryArchiver interface {
	Archive(ctx context.Context, sessionID, role, content string) error
}

MemoryArchiver is the tiny interface the agent uses to push evicted conversation turns into cold storage (master plan §6.1 hot/cold paging). The real implementation embeds + stores via the Python bridge; tests inject a no-op.

Best-effort semantics: errors are emitted as events, not surfaced as compaction failures. Losing one archival write is preferable to blocking the agent on a flaky vector store.

type MemoryFlowStore

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

MemoryFlowStore is the test/no-persistence implementation. Safe for concurrent use.

func NewMemoryFlowStore

func NewMemoryFlowStore() *MemoryFlowStore

NewMemoryFlowStore returns an empty in-memory store.

func (*MemoryFlowStore) Delete

func (s *MemoryFlowStore) Delete(id string) error

Delete removes a flow record. Missing IDs are no-ops.

func (*MemoryFlowStore) List

func (s *MemoryFlowStore) List() ([]*FlowState, error)

List returns every parseable flow. Corrupt entries are dropped from the list AND from the store so a follow-up call doesn't keep rediscovering them. (Tests can also use saveRaw to seed corrupt blobs intentionally.)

func (*MemoryFlowStore) Load

func (s *MemoryFlowStore) Load(id string) (*FlowState, error)

Load returns the parsed state or ErrFlowCorrupt for unparseable blobs. Missing IDs return (nil, nil) so callers can distinguish "not found" from "found but broken".

func (*MemoryFlowStore) Save

func (s *MemoryFlowStore) Save(state *FlowState) error

Save serializes the state and stores it under state.ID.

type MemoryHit

type MemoryHit struct {
	ID    string
	Text  string
	Score float64
}

MemoryHit is a single retrieved memory excerpt returned by a MemoryRetriever. Defined locally on purpose: the agent must NOT import internal/memory. Adapters in cmd/overkill bridge the public memory orchestrator into this shape.

type MemoryRetriever

type MemoryRetriever interface {
	Search(ctx context.Context, query string, k int) ([]MemoryHit, error)
}

MemoryRetriever is the tiny interface the agent calls each turn to fetch relevant memories for the latest user input. Implementations should be fast and best-effort — failures and panics must not block the turn.

type ModalityHint

type ModalityHint int

ModalityHint is the agent's recommendation for how to respond.

const (
	ModalityDefault      ModalityHint = iota // text only, standard format
	ModalityOfferAudio                       // offer TTS/audio alongside text
	ModalityMinimalText                      // short, acknowledgment-style
	ModalityStructured                       // structured with diffs, line refs
	ModalityAudioPrimary                     // audio-first with text summary
)

func (ModalityHint) String

func (mh ModalityHint) String() string

String returns the modality hint name.

type ModelRouter

type ModelRouter interface {
	// PickModel returns the model ID to use for this turn given a routing
	// snapshot. Implementations should be fast (<10ms) — they sit on the
	// hot path of every user message.
	PickModel(snap RouteSnapshot) (modelID string, reason string, ok bool)
}

ModelRouter is the small interface the agent calls into to pick a model. SmartRouter (internal/routing) satisfies a thin adapter; tests inject a fake.

type PhaseStatus

type PhaseStatus int
const (
	PhasePending PhaseStatus = iota
	PhaseRunning
	PhaseDone
	PhaseFailed
	PhaseSkipped
	PhaseDeferred
)

func (PhaseStatus) String

func (s PhaseStatus) String() string

type Plan

type Plan struct {
	Title  string
	Phases []PlanPhase
	Source string // file path
}

Plan represents a parsed execution plan with sequential phases.

func LoadPlan

func LoadPlan(path string) (*Plan, error)

LoadPlan reads a plan from a markdown file. Plans use ## headings for phases. Format:

# Plan Title
## Phase 1: Description
Details here...

## Phase 2: Description
Details...

type PlanExecutionObservation

type PlanExecutionObservation struct {
	Current bool                   `json:"current"`
	Source  string                 `json:"source"`
	Title   string                 `json:"title"`
	Status  string                 `json:"status"`
	Phases  []PlanPhaseObservation `json:"phases"`
}

PlanExecutionObservation records scheduler outcomes. A done phase means its configured completion policy accepted; it is not independent proof of success. Snapshots are persisted with runtime status, never used to auto-resume work.

type PlanOutput

type PlanOutput struct {
	PlanPath    string // ~/.overkill/plans/<name>.md
	HTMLPath    string // ~/.overkill/plans/<name>.html
	DiagramPath string // ~/.overkill/plans/<name>.mmd
	DiagramSVG  string // inline SVG or HTML wrapper
	Phases      []PlanPhase
	Title       string
}

PlanOutput holds the artifacts produced by the planner.

type PlanPhase

type PlanPhase struct {
	Index       int
	Title       string
	Description string
	Status      PhaseStatus
}

PlanPhase is one phase/step in an execution plan.

type PlanPhaseObservation

type PlanPhaseObservation struct {
	Title  string `json:"title"`
	Status string `json:"status"`
	Note   string `json:"note,omitempty"`
}

type PostWriteVerifier

type PostWriteVerifier interface {
	// IsWriteTool reports whether toolName is a tool whose calls
	// should be verified. Lets the agent skip cheaply when the
	// tool isn't a write (no JSON parse, no registry lookup).
	IsWriteTool(toolName string) bool

	// VerifyToolCall runs verifiers against the paths named by the
	// tool's input. Returns a non-empty string when ANY verifier
	// failed — the string is the tool-message body the agent should
	// append to history. Empty string = nothing to surface.
	VerifyToolCall(ctx context.Context, toolName string, input json.RawMessage) string

	// ExtractWritePaths returns the absolute (or cwd-relative) paths
	// the tool wrote to. Used by the end-of-turn reward-hack audit
	// to collect every path touched across all write tools in this
	// turn, then run a cross-file check ('test changed without
	// code'). Empty when the tool isn't a write or the input has no
	// recognizable path keys.
	ExtractWritePaths(toolName string, input json.RawMessage) []string

	// AuditTurnPaths takes the deduplicated list of every path
	// written by every write-class tool call in a single agent turn
	// and returns a tool-message body summarising any reward-hack
	// findings (test files modified without their code). Empty
	// string = nothing to surface.
	AuditTurnPaths(paths []string) string
}

PostWriteVerifier is the minimal surface the agent calls after a successful write-class tool. The wiring layer (cmd/overkill) implements this in terms of internal/verify.

type PostgresFlowStore

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

PostgresFlowStore persists FlowState to PostgreSQL under the table "flow_states". DB lifecycle is owned by the caller (the daemon).

func NewPostgresFlowStore

func NewPostgresFlowStore(db *sql.DB) (*PostgresFlowStore, error)

NewPostgresFlowStore wires a store to an open *sql.DB.

func (*PostgresFlowStore) Delete

func (s *PostgresFlowStore) Delete(id string) error

Delete removes a flow record. Missing keys are no-ops.

func (*PostgresFlowStore) List

func (s *PostgresFlowStore) List() ([]*FlowState, error)

List returns every parseable flow.

func (*PostgresFlowStore) Load

func (s *PostgresFlowStore) Load(id string) (*FlowState, error)

Load returns the state or (nil, nil) when the ID is missing.

func (*PostgresFlowStore) Save

func (s *PostgresFlowStore) Save(state *FlowState) error

Save serializes state and writes it. Overwrites existing rows.

type ProjectMap

type ProjectMap struct {
	Name        string
	Language    string   // go, typescript, python, rust, mixed
	Entrypoints []string // relative paths
	Directories []string
	KeyFiles    []string // AGENTS.md, go.mod, etc.
	Interfaces  []string // key interfaces found
	DepGraph    string   // human-readable dependency description
	FileTree    string   // tree output
}

ProjectMap captures the codebase structure for planning.

type PromptCompressor

type PromptCompressor interface {
	Compress(ctx context.Context, prompt string) (compressed string, savedTokens int, err error)
}

PromptCompressor is the small interface the agent calls before assembling each turn's system prompt. compaction.PromptCompressor satisfies this via a thin shim defined in cmd/overkill (kept here so the agent stays free of the compaction → providers import chain on this code path).

type PromptRewriter

type PromptRewriter interface {
	RewritePrompt(ctx context.Context, text string) (string, error)
}

PromptRewriter is implemented by anything that can transform a user prompt before the agent ships it to the model. The agent itself does not depend on the rewriter package — a tiny interface here keeps the import graph clean.

type Provenance

type Provenance struct {
	// Kind is the origin category.
	Kind ProvenanceKind `json:"kind"`

	// OriginSessionID is the session that produced this message (when
	// Kind is sub_agent or cron).
	OriginSessionID string `json:"originSessionId,omitempty"`

	// SourceChannel is the messaging channel this came through (when
	// Kind is user). E.g. "telegram", "discord", "tui".
	SourceChannel string `json:"sourceChannel,omitempty"`

	// SourceTool is the tool that produced this message (when Kind is
	// sub_agent or system). E.g. "code_review", "journal_summarize".
	SourceTool string `json:"sourceTool,omitempty"`
}

Provenance tags a user message with its origin metadata. Every message that enters the agent loop carries one of these. The agent's system prompt includes provenance-aware instructions.

func (Provenance) MarshalJSON

func (p Provenance) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaler.

func (Provenance) Prefix

func (p Provenance) Prefix() string

Prefix returns the provenance tag that should be prepended to the message before it enters the agent's context. User messages get an empty prefix (no noise). Inter-session messages get a bracketed tag so the agent knows to adjust trust.

func (*Provenance) UnmarshalJSON

func (p *Provenance) UnmarshalJSON(data []byte) error

UnmarshalJSON implements json.Unmarshaler.

type ProvenanceKind

type ProvenanceKind string

ProvenanceKind categorizes where a message came from.

const (
	// ProvenanceUser means the message came directly from a human user
	// through a messaging channel or the TUI.
	ProvenanceUser ProvenanceKind = "user"

	// ProvenanceSubAgent means the message was produced by a sub-agent
	// spawned by Overkill. The agent should verify claims from sub-agents
	// rather than accepting them at face value.
	ProvenanceSubAgent ProvenanceKind = "sub_agent"

	// ProvenanceCron means the message was triggered by a cron job.
	ProvenanceCron ProvenanceKind = "cron"

	// ProvenanceSystem means the message was generated internally (e.g.
	// session compaction summary, journal alert, auto-compaction
	// checkpoint). These are informational and should not drive action.
	ProvenanceSystem ProvenanceKind = "system"
)

type Question

type Question struct {
	Prompt  string
	Choices []string // free-text if empty
}

Question describes a question to ask the user.

type QuestionFunc

type QuestionFunc func(ctx context.Context, q Question) Answer

QuestionFunc is the callback invoked to surface a question. If unset, the agent returns Answer{Cancel:true}.

type QueueItem

type QueueItem struct {
	Index       int    `json:"index"`
	Description string `json:"description"`
	Status      string `json:"status"`
	Error       string `json:"error,omitempty"`
	ElapsedMs   int64  `json:"elapsed_ms"`
}

QueueItem mirrors WorkItem for the API boundary.

type QueueState

type QueueState struct {
	Active bool        // true while processing
	Total  int         // total items
	Done   int         // completed items
	Failed int         // failed items
	Items  []QueueItem // current items with status
	// contains filtered or unexported fields
}

QueueState is the live state of the sequential processing queue, exposed to the TUI Queue pane via the API.

func (*QueueState) Finish

func (qs *QueueState) Finish()

Finish marks the queue as complete.

func (*QueueState) Reset

func (qs *QueueState) Reset()

Reset clears the queue for a new run.

func (*QueueState) SetItems

func (qs *QueueState) SetItems(items []WorkItem)

SetItems initializes the queue with work items.

func (*QueueState) Snapshot

func (qs *QueueState) Snapshot() QueueState

Snapshot returns a copy of the current queue state for safe concurrent reads.

func (*QueueState) UpdateItem

func (qs *QueueState) UpdateItem(index int, status string, err string, elapsed time.Duration)

UpdateItem updates a single item's status in the queue.

type Receipt

type Receipt struct {
	Seq        int       `json:"seq"`
	SessionID  string    `json:"session_id"`
	ToolName   string    `json:"tool_name"`
	InputHash  string    `json:"input_hash"`
	OutputHash string    `json:"output_hash"`
	Err        string    `json:"error,omitempty"`
	Timestamp  time.Time `json:"timestamp"`
	PrevHash   string    `json:"prev_hash"`
	Hash       string    `json:"hash"`
}

Receipt is one row in the tool-call audit chain. Hash is over the canonicalized JSON of every other field, including PrevHash. The chain invariant: Receipt[N].PrevHash == Receipt[N-1].Hash.

type ReceiptChain

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

ReceiptChain is the append-only ledger. The first receipt has PrevHash = "" by convention; every subsequent receipt's PrevHash equals the previous receipt's Hash. Safe for concurrent Append calls — internal mutex serializes hash computation.

func NewReceiptChain

func NewReceiptChain() *ReceiptChain

NewReceiptChain returns an empty chain. The first Append starts the hash chain with PrevHash="".

func (*ReceiptChain) Append

func (c *ReceiptChain) Append(sessionID, toolName string, input, output []byte, err error) Receipt

Append records one tool call. Input/output payloads are hashed (SHA-256) so the chain captures their identity without their bulk. Returns the appended receipt so callers can persist it externally (e.g. to a journal) or display it.

Thread-safe: chain mutations serialize under an internal mutex. Hashing is fast enough that the lock-hold time is microseconds even for large input/output blobs.

func (*ReceiptChain) Len

func (c *ReceiptChain) Len() int

Len reports the current chain length.

func (*ReceiptChain) Snapshot

func (c *ReceiptChain) Snapshot() []Receipt

Snapshot returns a copy of the chain. The receipts slice is copied so the caller can iterate without holding the lock.

type RecoveryReport

type RecoveryReport struct {
	WhatWentWrong string
	RootCause     string
	FaultChain    []string
	LearningPlan  string
	ImmediateFix  string
	Apology       string
}

type RedTeamConfig

type RedTeamConfig struct {
	// Enabled toggles red-team test generation. When false, phases
	// skip this gate (legacy behavior).
	Enabled bool

	// Provider is the LLM used for test generation. SHOULD be a
	// separate provider from the build agent — the build agent writes
	// code, the red-team agent tries to break it.
	Provider providers.Provider

	// Model for test generation. Use a capable but cost-effective
	// model (e.g., deepseek-v4-flash, claude-haiku).
	Model string

	// MaxTestsPerFile caps the number of adversarial tests generated
	// per changed file to prevent token blowout.
	MaxTestsPerFile int

	// SystemPrompt overrides the default adversarial test generator
	// prompt. When empty, the built-in prompt is used.
	SystemPrompt string

	// RunTests executes the generated tests and returns results.
	// Injectable for testing; default uses the project's test runner.
	RunTests func(ctx context.Context, workdir string, testFiles map[string]string) (*TestRunResult, error)
}

RedTeamConfig wires the red-team test generation engine.

type RedTeamResult

type RedTeamResult struct {
	Passed      bool              `json:"passed"`
	TestsRun    int               `json:"tests_run"`
	TestsFailed int               `json:"tests_failed"`
	Failures    []string          `json:"failures,omitempty"`
	TestFiles   map[string]string `json:"-"` // filename → content, for revision
	Output      string            `json:"output"`
}

RedTeamResult is the output of one red-team phase gate check.

type RedTeamTestGen

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

RedTeamTestGen generates and runs adversarial tests.

func NewRedTeamTestGen

func NewRedTeamTestGen(cfg RedTeamConfig) *RedTeamTestGen

NewRedTeamTestGen creates a red-team test generator.

func (*RedTeamTestGen) BuildRevisionContext

func (rt *RedTeamTestGen) BuildRevisionContext(result *RedTeamResult) string

BuildRevisionContext produces a prompt snippet that feeds red-team test failures back into the self-evaluate loop. The build agent sees exactly which tests failed and why, so it can fix the issues.

func (*RedTeamTestGen) GenerateAndRun

func (rt *RedTeamTestGen) GenerateAndRun(
	ctx context.Context,
	history []providers.Message,
	workdir string,
	spec string,
) (*RedTeamResult, error)

GenerateAndRun is the main entry point. It extracts changed files from the agent's tool-call history, generates adversarial tests, runs them, and returns the result.

Returns (nil, nil) when disabled — caller treats this as "gate passed, no tests needed." Returns a populated RedTeamResult otherwise.

type Reflection

type Reflection struct {
	Mode       string // string-typed at this boundary; internal/reflect owns the enum
	RootCause  string
	Hypothesis string
	Confidence float64
}

Reflection mirrors internal/reflect.Reflection at the agent boundary. Only the fields the agent needs to inject the note.

type Reflector

type Reflector interface {
	// IsFailure decides whether this tool result warrants a
	// reflection. Cheaper than calling Reflect on every result —
	// most tool calls succeed and don't need this path.
	IsFailure(toolName, output, err string) bool

	// Reflect produces the structured reflection for one failure.
	// Must be fast (the agent calls this on the hot path) — heavy
	// LLM reflectors should cap their own latency.
	Reflect(f Failure) Reflection

	// FormatNote renders the prose injected into history as a
	// system message. Separate from Reflect so the agent can
	// dedupe or rate-limit before paying the rendering cost.
	FormatNote(toolName string, r Reflection) string
}

Reflector is the minimal hook the agent calls. The wiring layer implements this in terms of internal/reflect.

type ResponseFilter

type ResponseFilter interface {
	Filter(content string) string
}

ResponseFilter is the tiny interface the agent uses to transform the assistant's content before it's committed to history (master plan §4.10 sycophancy reducer wire-up).

Filters run AFTER the stream finishes assembling — they can't peek at chunks mid-stream, only at the final content. This preserves the streaming UX (tokens flow to the TUI as they arrive) while still cleaning the canonical record the LLM sees on its next turn.

Filters MUST be safe to call on an empty string, and SHOULD be idempotent (filter(filter(s)) == filter(s)) so a request that flows through twice isn't double-stripped.

type RevisionEntry

type RevisionEntry struct {
	Iteration  int
	RootCause  string
	Hypothesis string
	Confidence float64
}

RevisionEntry records one self-revision attempt for the history chain.

type RiskLevel

type RiskLevel int
const (
	RiskLow RiskLevel = iota
	RiskMedium
	RiskHigh
)

type RouteSnapshot

type RouteSnapshot struct {
	UserInput      string
	HistoryLen     int
	ToolCallCount  int
	HasAttachments bool
}

RouteSnapshot is the data the router sees per Run. Kept tiny so we can avoid importing the routing package from agent (one-way deps).

type RunResult

type RunResult struct {
	Plan        *PlanExecutionObservation `json:"plan,omitempty"`
	Response    string                    `json:"response"`
	ToolCalls   int                       `json:"tool_calls"`
	TotalTokens int                       `json:"total_tokens"`
	Steps       int                       `json:"steps"`
	Model       string                    `json:"model"`
	Blocked     bool                      `json:"blocked"`
	BlockReason string                    `json:"block_reason,omitempty"`
	Confidence  *ConfidenceAssessment     `json:"confidence,omitempty"`
	// contains filtered or unexported fields
}

type RuntimeStatusSnapshot

type RuntimeStatusSnapshot struct {
	Plan                 *PlanExecutionObservation       `json:"plan,omitempty"`
	Iterative            *IterativeEvaluationObservation `json:"iterative,omitempty"`
	Version              int                             `json:"version"`
	SessionID            string                          `json:"session_id"`
	Verification         VerificationStatus              `json:"verification"`
	Evaluation           *ConfidenceObservation          `json:"evaluation"`
	PersistenceAvailable bool                            `json:"persistence_available"`
	PersistenceFailed    bool                            `json:"persistence_failed"`
}

func RecoverRuntimeStatus

func RecoverRuntimeStatus(snapshot RuntimeStatusSnapshot) RuntimeStatusSnapshot

RecoverRuntimeStatus never represents old process work as still running.

type SelfEvalResult

type SelfEvalResult struct {
	Accepted   bool        // true if confidence met threshold
	Iterations int         // total iterations consumed
	FinalNote  string      // human-readable summary
	Reflection *Reflection // last reflection (nil if accepted on first try)
	FaultChain []string    // from ErrorRecovery (nil if no faults)
}

SelfEvalResult is the final result from a self-evaluate loop.

type SelfEvaluateLoop

type SelfEvaluateLoop struct {

	// MaxIterations caps self-revision attempts per phase/task.
	// Default 6 (matching the Deli Chen paper's 6-iteration experiment).
	MaxIterations int

	// MinConfidence is the float threshold for acceptance.
	// Default 0.7 (matches ConfidenceHigh in confidence.go).
	MinConfidence float64

	// MaxRevisionDepth caps how many prior iterations of recovery context
	// we inject into subsequent prompts. Prevents context bloat.
	MaxRevisionDepth int
	// contains filtered or unexported fields
}

SelfEvaluateLoop wires Reflector + ErrorRecovery + ConfidenceAssessment into the L4 closed-loop self-revision pattern. Zero-value is usable after calling NewSelfEvaluateLoop or setting fields manually.

func NewSelfEvaluateLoop

func NewSelfEvaluateLoop(reflector Reflector, recovery *ErrorRecovery, learning LearningRecorder) *SelfEvaluateLoop

NewSelfEvaluateLoop creates a ready-to-use loop. All parameters may be nil; the loop degrades gracefully — without a reflector it skips reflection, without recovery it skips fault-chain injection.

func (*SelfEvaluateLoop) BuildRevisionContext

func (s *SelfEvaluateLoop) BuildRevisionContext(
	reflection *Reflection,
	faultChain []string,
	revisionHistory []RevisionEntry,
) string

BuildRevisionContext constructs the prompt snippet to inject before the next agent.Run() call. Includes reflection notes and recovery context from prior failed iterations.

revisionHistory is the accumulated reflections + fault chains from prior iterations in this loop. It's truncated to MaxRevisionDepth entries to prevent context bloat.

func (*SelfEvaluateLoop) Evaluate

func (s *SelfEvaluateLoop) Evaluate(
	taskType string,
	history []providers.Message,
	model string,
	iteration int,
) (IterationOutcome, *Reflection, []string)

Evaluate runs the self-evaluate loop for a completed task. Call this AFTER agent.Run() returns successfully — it evaluates the output and returns a result. If the result is not Accepted, the caller should inject the revision context and re-invoke agent.Run().

taskType is a short label for the task (e.g., "compile", "refactor", "test") — used by confidence assessment. history is the conversation after agent.Run() completed (user message + assistant response + tool results). model is the model name for confidence scoring.

Returns IterAccepted when confidence >= threshold. Returns IterRevised when iterations remain and revision is warranted. Returns IterDeferred when MaxIterations is exhausted.

func (*SelfEvaluateLoop) RecordLearning

func (s *SelfEvaluateLoop) RecordLearning(errorClass string)

RecordLearning captures a successful-recovery learning event. Called after a phase transitions from IterRevised → IterAccepted.

func (*SelfEvaluateLoop) RevisionPrompt

func (s *SelfEvaluateLoop) RevisionPrompt(
	iteration int,
	maxIter int,
	reflection *Reflection,
) string

RevisionPrompt builds a compact inline revision prompt for the agent's system message when in a self-revision loop. Less verbose than BuildRevisionContext — intended for injection into the system prompt alongside the phase description.

func (*SelfEvaluateLoop) RunPhase

func (s *SelfEvaluateLoop) RunPhase(
	ctx context.Context,
	phase *PlanPhase,
	model string,
	runner func(ctx context.Context, prompt string, revisionContext string) ([]providers.Message, error),
) (*SelfEvalResult, []providers.Message, error)

RunPhase executes one AutoMode phase within the self-evaluate loop. It calls agent.Run() with the phase prompt, evaluates the output, and auto-iterates up to MaxIterations times.

The runner callback executes the actual agent.Run() call. Decoupled so SelfEvaluateLoop doesn't depend on Agent's internal Run signature. runner receives the prompt + any revision context and returns the resulting conversation history.

Returns the final result and the accumulated history.

func (*SelfEvaluateLoop) SetConfidenceFn

func (s *SelfEvaluateLoop) SetConfidenceFn(fn ConfidenceFunc)

SetConfidenceFn overrides the default heuristic confidence scorer. Pass nil to restore the default.

func (*SelfEvaluateLoop) SetLearningRecorder

func (s *SelfEvaluateLoop) SetLearningRecorder(lr LearningRecorder)

SetLearningRecorder replaces the learning recorder at runtime.

func (*SelfEvaluateLoop) SetRedTeam

func (s *SelfEvaluateLoop) SetRedTeam(rt *RedTeamTestGen)

SetRedTeam wires the red-team test generator. Pass nil to disable adversarial test generation for this loop.

func (*SelfEvaluateLoop) SetReflector

func (s *SelfEvaluateLoop) SetReflector(r Reflector)

SetReflector replaces the reflector at runtime.

func (*SelfEvaluateLoop) Stats

func (s *SelfEvaluateLoop) Stats() (accepted, revised, deferred int64)

Stats returns accepted/revised/deferred counters.

type SequentialCheckpoint

type SequentialCheckpoint struct {
	Input            string              `json:"input"`
	Items            []WorkItem          `json:"items"`
	Current          int                 `json:"current"`
	Scope            string              `json:"scope"`
	Started          bool                `json:"started"`
	CompletedHistory []providers.Message `json:"completed_history"`
	RawItemHistory   []providers.Message `json:"raw_item_history"`
	ActiveHistory    []providers.Message `json:"active_history"`
}

SequentialCheckpoint is scheduler data, never tool/provider authority. Full transcript and active model view are separate so compaction cannot erase the original actions and prior-item text cannot leak into another item's prompt.

type SequentialProcessor

type SequentialProcessor struct {
	Decomposer *Decomposer
	MaxPerItem time.Duration // max time per item (default: 5 min)
	Verbose    bool          // if true, emit progress per item
}

SequentialProcessor iterates through work items, processing each one independently via the provided ItemProcessor.

func NewSequentialProcessor

func NewSequentialProcessor() *SequentialProcessor

NewSequentialProcessor creates a processor with defaults.

func (*SequentialProcessor) Process

func (sp *SequentialProcessor) Process(
	ctx context.Context,
	input string,
	processor ItemProcessor,
) (*SequentialResult, error)

Process decomposes input into items and processes them sequentially. Returns the aggregated result. If decomposition yields < 2 items, returns nil — caller should fall back to normal single-item processing.

type SequentialResult

type SequentialResult struct {
	Items       []WorkItem
	TotalItems  int
	DoneCount   int
	FailedCount int
	TotalTime   time.Duration
	Summary     string
}

SequentialResult is the aggregated output of processing all items.

type SessionBookmarkStore

type SessionBookmarkStore interface {
	Save(sessionID, label string) error
}

SessionBookmarkStore is the minimal surface the agent needs to persist user bookmarks (§7.4). Wired by cmd/overkill with a gateway.BookmarkStore adapter when a PostgreSQL connection is available.

type SessionFlowStore

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

func (*SessionFlowStore) BeginHumanTurn

func (s *SessionFlowStore) BeginHumanTurn(ctx context.Context) error

func (*SessionFlowStore) BeginTurn

func (s *SessionFlowStore) BeginTurn(ctx context.Context) error

BeginTurn refreshes the cancellation fence only for a new human turn.

func (*SessionFlowStore) ContinueTurn

func (s *SessionFlowStore) ContinueTurn(epoch int64)

func (*SessionFlowStore) Delete

func (s *SessionFlowStore) Delete(id string) error

func (*SessionFlowStore) List

func (s *SessionFlowStore) List() ([]*FlowState, error)

func (*SessionFlowStore) Load

func (s *SessionFlowStore) Load(id string) (*FlowState, error)

func (*SessionFlowStore) Save

func (s *SessionFlowStore) Save(state *FlowState) error

type SituationalReflection

type SituationalReflection struct {
	Classification  Classification   // what kind of content
	UserModel       UserModel        // who we're talking to
	AvailableTools  []ToolAffordance // tools that match this content type
	ModalityHint    ModalityHint     // recommended modality
	Reasoning       string           // human-readable chain of reasoning
	ShouldDecompose bool             // if true, trigger sequential processing
}

SituationalReflection is the output of the pre-action reflection pass. Cheap enough to run on every turn, rich enough to change behavior.

func ReflectBeforeAction

func ReflectBeforeAction(input string, user UserModel, inventory *ToolInventory) SituationalReflection

ReflectBeforeAction runs the full pre-action reflection pipeline. This is designed to be called from Run() before the main agent loop.

Cost: zero LLM calls — purely heuristic. The classifier runs O(n) keyword matching and the tool inventory is a map lookup. Designed to be cheap enough for every turn.

func (SituationalReflection) ModalitySystemHint

func (sr SituationalReflection) ModalitySystemHint() string

ModalitySystemHint formats the reflection as a concise system-prompt injection that guides the model's response style without bloating the prompt. Designed to be appended to the system prompt.

Cost: typically 30–80 chars. Negligible token impact.

func (SituationalReflection) PromptPrefix

func (sr SituationalReflection) PromptPrefix() string

PromptPrefix returns a one-line prefix for the user message that signals sequential processing mode to the model.

type SlashCommand

type SlashCommand struct {
	Command string // "safe", "auto", "yolo", "plan", "build"
	SubCmd  string // e.g. "view" for "/plan view"
	Args    string // remaining args after subcommand
	Raw     string // original input
}

SlashCommand represents a parsed slash command.

func ParseSlashCommand

func ParseSlashCommand(input string) *SlashCommand

ParseSlashCommand checks if a message is a slash command and returns it. Returns nil for normal messages.

type Snapshot

type Snapshot struct {
	Hash    string
	Message string
	Time    time.Time
}

Snapshot represents one git-based filesystem checkpoint.

type SpecDriver

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

func NewSpecDriver

func NewSpecDriver() *SpecDriver

func (*SpecDriver) BuildSpecPrompt

func (sd *SpecDriver) BuildSpecPrompt(userInput string) string

func (*SpecDriver) IsEnabled

func (sd *SpecDriver) IsEnabled() bool

func (*SpecDriver) SetEnabled

func (sd *SpecDriver) SetEnabled(enabled bool)

func (*SpecDriver) SetThreshold

func (sd *SpecDriver) SetThreshold(threshold float64)

func (*SpecDriver) ShouldSpec

func (sd *SpecDriver) ShouldSpec(userInput string) bool

type SteeredMessage

type SteeredMessage struct {
	Content  string
	Role     string
	Priority int
}

type SteeringMode

type SteeringMode int
const (
	SteeringOneAtATime SteeringMode = iota
	SteeringDrainAll
)

type SteeringQueue

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

func NewSteeringQueue

func NewSteeringQueue(mode SteeringMode) *SteeringQueue

func (*SteeringQueue) Append

func (sq *SteeringQueue) Append(msg string)

Append adds a simple string steering message to the queue. The message is stored with Role="system" and Priority=0.

func (*SteeringQueue) Clear

func (sq *SteeringQueue) Clear()

func (*SteeringQueue) Close

func (sq *SteeringQueue) Close()

func (*SteeringQueue) Drain

func (sq *SteeringQueue) Drain() string

Drain returns the oldest message as a plain string (FIFO) and removes it from the queue. Returns empty string if the queue is empty.

func (*SteeringQueue) DrainAll

func (sq *SteeringQueue) DrainAll() string

DrainAll returns all queued messages combined into a single newline-separated string, then empties the queue. Returns empty string if the queue is empty.

func (*SteeringQueue) Drained

func (sq *SteeringQueue) Drained() []SteeredMessage

func (*SteeringQueue) Inject

func (sq *SteeringQueue) Inject(msg SteeredMessage)

func (*SteeringQueue) Pending

func (sq *SteeringQueue) Pending() int

func (*SteeringQueue) Wait

func (sq *SteeringQueue) Wait(ctx context.Context) error

type StepResult

type StepResult struct {
	Thought             string
	Action              string
	Observation         string
	ToolCalls           []providers.ToolCall
	ToolResults         []ToolResult
	Tokens              providers.Usage
	VerificationFailure string
	Done                bool
}

type StreamEvent

type StreamEvent struct {
	Type     EventType              `json:"type"`
	Content  string                 `json:"content,omitempty"`
	ToolCall *providers.ToolCall    `json:"tool_call,omitempty"`
	Result   *RunResult             `json:"result,omitempty"`
	Error    error                  `json:"-"`
	Metadata map[string]interface{} `json:"metadata,omitempty"`

	// Plan-aligned wire fields for SSE streaming.
	Phase      string      `json:"phase,omitempty"`       // for status events
	ToolName   string      `json:"tool_name,omitempty"`   // for tool_call events
	ToolInput  interface{} `json:"tool_input,omitempty"`  // for tool_call events
	ToolOutput string      `json:"tool_output,omitempty"` // for tool_call events
	Model      string      `json:"model,omitempty"`       // for done events
	Tokens     int         `json:"tokens,omitempty"`      // for done events

	// Provenance tags where this message came from (§7.1.9).
	// Set by the gateway/cron/subagent before streaming.
	Provenance *Provenance `json:"provenance,omitempty"`
}

type SubagentChild

type SubagentChild struct {
	ID        string
	Goal      string
	Model     string
	Status    string
	StartedAt string
}

SubagentChild is a live sub-agent handle returned by the manager.

type SubagentManager

type SubagentManager interface {
	ActiveCount() int
	ActiveChildren() []SubagentChild
}

SubagentManager is the subset of subagent.Manager that the agent needs. Defined here to avoid import cycles (agent ← subagent → providers ✗).

type Subscriber

type Subscriber struct {
	ID   string
	Kind EventKind
	Ch   chan BusEvent
	// contains filtered or unexported fields
}

type SuspendedApprover

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

SuspendedApprover is an ApprovalFunc implementation for remote/async sessions.

func NewSuspendedApprover

func NewSuspendedApprover(
	db *sql.DB,
	ledger *security.Ledger,
	sessionID string,
	emitFn func(string, map[string]any),
) (*SuspendedApprover, error)

NewSuspendedApprover wires all required dependencies. db and sessionID are required; ledger and emitFn may be nil (degraded mode).

func (*SuspendedApprover) Approve

func (s *SuspendedApprover) Approve(toolName, args, risk string) Approval

Approve is the ApprovalFunc — it persists the request and parks until resolved or timed out.

func (*SuspendedApprover) Close

func (s *SuspendedApprover) Close()

Close unblocks all in-flight Approve calls so shutdown doesn't leak goroutines. After Close, future Approve calls still work but are not cancellable (new sessions get a fresh SuspendedApprover).

func (*SuspendedApprover) ResumeApproval

func (s *SuspendedApprover) ResumeApproval(callID string, allow bool, approverID string) error

ResumeApproval is called by the gateway bridge when the user replies "approve <callID>" or "deny <callID>".

type SuspendedCall

type SuspendedCall struct {
	CallID    string    `json:"call_id"`
	ToolName  string    `json:"tool_name"`
	Args      string    `json:"args"`
	Risk      string    `json:"risk"`
	SessionID string    `json:"session_id"`
	Timestamp time.Time `json:"timestamp"`
}

SuspendedCall is the persisted record for a pending approval.

func ListPendingSuspensions

func ListPendingSuspensions(db *sql.DB, sessionID string) ([]SuspendedCall, error)

ListPendingSuspensions returns all persisted pending calls for sessionID.

type TestFileResult

type TestFileResult struct {
	File   string `json:"file"`
	Passed bool   `json:"passed"`
	Output string `json:"output"`
}

TestFileResult describes one test file's outcome.

type TestRunResult

type TestRunResult struct {
	Passed  bool             `json:"passed"`
	Total   int              `json:"total"`
	Failed  int              `json:"failed"`
	Output  string           `json:"output"`
	Details []TestFileResult `json:"details,omitempty"`
}

TestRunResult summarizes a red-team test run.

type ThinkConfig

type ThinkConfig struct {
	Enabled bool
	Verbose bool // reserved for future verbosity levels
}

ThinkConfig governs preamble streaming before tool calls. When Enabled is true, the agent emits a brief natural-language preamble via the event callback before every tool execution, mimicking Codex's "thinking" messages.

type ToolAffordance

type ToolAffordance struct {
	Name    string   // tool name (e.g. "edge_tts", "vision", "browser")
	BestFor []string // content types it excels at
	NotFor  []string // content types it should avoid
	Reason  string   // why this mapping exists
}

ToolAffordance describes what a tool is best used for and what it should NOT be used for. Used by the modality decider.

type ToolInventory

type ToolInventory struct {
	Affordances map[string]ToolAffordance
}

ToolInventory tracks available tools and their affordances.

func NewEnabledToolInventory

func NewEnabledToolInventory(names []string) *ToolInventory

NewEnabledToolInventory maps affordance knowledge onto the actual enabled registry. Knowledge of a tool never establishes that it is installed.

func NewToolInventory

func NewToolInventory() *ToolInventory

NewToolInventory creates an inventory with built-in affordance knowledge.

func (*ToolInventory) BestForType

func (ti *ToolInventory) BestForType(ct ContentType) []ToolAffordance

BestForType returns tools best suited for a given content type.

func (*ToolInventory) IsAvailable

func (ti *ToolInventory) IsAvailable(toolName string) bool

IsAvailable checks whether a tool is registered in the inventory.

type ToolResult

type ToolResult struct {
	ToolCallID string          `json:"tool_call_id"`
	ToolName   string          `json:"tool_name"`
	Output     json.RawMessage `json:"output"`
	Error      error           `json:"-"`
}

type UserModel

type UserModel struct {
	HasADHD            bool          // neurodivergent — affects modality choices
	IsLateNight        bool          // local time is late (reduced attention, emotional)
	IsOnMobile         bool          // Telegram/mobile = shorter attention span
	PreferredModality  string        // "text", "audio", "both" — learned over time
	SessionCount       int           // how many sessions with this user
	LastInteractionAge time.Duration // time since last interaction
}

UserModel captures the agent's understanding of the current user state. Populated from personality engine, relationship tracking, and session context.

type VariantResult

type VariantResult struct {
	Model     string  `json:"model"`
	Response  string  `json:"response"`
	Tokens    int     `json:"tokens"`
	CostUSD   float64 `json:"cost_usd"`
	Err       string  `json:"error,omitempty"`
	DurationS float64 `json:"duration_s"`
	// Note carries an out-of-band human-readable annotation about this
	// result. Currently used to flag variants where pricing data is missing
	// (so the dialog can show "no pricing data" instead of "$0.0000").
	Note string `json:"note,omitempty"`
}

VariantResult captures one variant's response.

type VerificationCheck

type VerificationCheck struct {
	ID              string `json:"id"`
	Name            string `json:"name"`
	File            string `json:"file"`
	Status          string `json:"status"`
	Passed          bool   `json:"passed"`
	Error           string `json:"error,omitempty"`
	DurationMS      int64  `json:"duration_ms"`
	Category        string `json:"category"`
	StartedAt       string `json:"started_at"`
	OutputTruncated bool   `json:"output_truncated"`
}

VerificationCheck records an actually invoked verifier, never an inferred success from empty feedback. Skipped and canceled checks are not passes.

type VerificationStatus

type VerificationStatus struct {
	Source      string              `json:"source"`
	Running     bool                `json:"running"`
	Tests       []VerificationCheck `json:"tests"`
	Total       int                 `json:"total"`
	Passed      int                 `json:"passed"`
	Failed      int                 `json:"failed"`
	Skipped     int                 `json:"skipped"`
	Canceled    int                 `json:"canceled"`
	Unconfirmed int                 `json:"unconfirmed"`
	Dropped     int                 `json:"dropped"`
}

type WorkItem

type WorkItem struct {
	Index       int    // 1-based position in original message
	Description string // the extracted task description
	Status      WorkItemStatus
	Result      string // output from processing this item
	Error       string // if failed, the error message
	StartedAt   time.Time
	CompletedAt time.Time
}

WorkItem is one discrete task extracted from a multi-item user dump.

type WorkItemStatus

type WorkItemStatus int

WorkItemStatus tracks progress through the sequential processor.

const (
	WorkItemPending WorkItemStatus = iota
	WorkItemActive
	WorkItemDone
	WorkItemFailed
	WorkItemSkipped
)

func (WorkItemStatus) String

func (s WorkItemStatus) String() string

Jump to

Keyboard shortcuts

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