Remove entire TaskState machinery:
- TaskState struct, render(), taskState()/updateTaskState() on History
- inferTaskStateUpdate() — heuristic plan tracking
- Replan gate (replanGate const, roundsWithoutPlan counter)
- Stall detection (stallThreshold, stallRounds, lastAction)
- Plan reinject (planReinjectInterval, periodic re-injection)
- ReadPlanStep plumbing (AgentCfg → Agent → TurnCtx → loop)
None of this worked in practice — the model ignores the nudges,
ReadPlanStep was never wired to a non-nil value, and TaskState
fields were only populated by inferTaskStateUpdate (which depends
on ReadPlanStep being set).
Compaction now uses plain summary text in the cold zone instead
of serialized TaskState JSON.
Also remove:
- Verbosity field (declared, threaded, never read by any backend)
- DisallowTools (config field never wired to session)
- Session.listHandlers, plan, prevPrompt (never read)
- Config.Output, Config.ListHandlers, Config.ReadPlanStep (never set)
-246 net lines
Replace the monolithic preamble string with Preamble struct — an
ordered list of named sections joined on demand. Updates are simple
Set() calls; no marker-based string splicing.
Changes:
- Delete prompts/tool_discovery.md (content already in system_prompt.md)
- Reduce prompts/ package to just the embed + ResolveSystemPrompt
- Replace buildPreamble() with direct section construction
- Replace refreshToolListing() 90-line string surgery with one Set()
- Replace SetCWD string.ReplaceAll with env section rebuild
- Remove RenamePreamble (was a no-op; session ID is a template var)
- Export EnvironmentBlock() for session setup
- All callers use PreambleString() instead of raw string field
The entire classifier indirection (interfaces, type assertions, RPC
methods for classification, closure wrappers in BuildRuntime) is replaced
by a simple map[string]ToolInfo on Runtime.
The .meta file is read once into ToolInfo. The loop reads fields directly:
rt.ToolMeta[name].ReadOnly (was: rt.CanParallelize(name))
rt.ToolMeta[name].Tier (was: rt.MemoryTier(name, args))
rt.ToolMeta[name].OutputFormat (was: rt.OutputFormat(name))
rt.ToolMeta[name].ResetsCounter (was: rt.ResetsCounter(name))
Removed: ParallelClassifier, MemoryTierClassifier, OutputFormatClassifier
interfaces, toolClassifier type, and all closure-wrapping in BuildRuntime.
The RPC methods on Server/Conn stay (used by ollie-remote) but the agent
no longer routes through them.
run() signature is now run(rt *Runtime, ctx TurnCtx, state state).
The ctx parameter carries both the cancellation context and per-turn
closures — no more separate ctx + tc parameters.
emit() and retryCountdown() also take TurnCtx directly.
- Kill agentConfig struct. run() takes (*Runtime, TurnCtx, state) directly.
TurnCtx holds only 7 per-turn closures; stable config reads come from Runtime.
- Lazy tool refresh: toolsNeedRefresh() checks ToolRegistryRevision() on the
tool server. Skips ListTools IPC when registry hasn't changed. Remote Conn
falls back to always-refetch (same as before).
- AgentConfig.GenParams() method replaces the 16-line manual field copy in
BuildRuntime.
- Remove CfgBackend/CfgModel from Runtime. Callers read cfg.Backend/cfg.Model
directly since they already have the AgentConfig in scope.
Standardize all system messages to use xml-like tags matching the
pattern used by user interruptions:
- <system-consecutive-errors>
- <system-repeated-error>
- <system-replan-required>
- <system-stall-detected>
- <system-task-state-review>
- <system-step-budget-warning>
- <system-step-budget-stop>
Nudge the agent at 50% of step budget to encourage taking action
rather than looping on research. The warning explains that action
tools (file_write, file_edit, shell) reset the counter.
Tools like file_write, file_edit, and shell now reset the agent's step
counter when called successfully. This allows the agent to continue
working without hitting the soft step-budget guardrail as long as it's
making active progress (writing files, running commands) rather than
looping on research/reading.
Changes:
- Add ResetsCounter bool to ToolInfo and MetaFile structs
- Parse resetsCounter from .meta JSON files
- Reset step counter in agent loop when ResetsCounter tool succeeds
- Add resetsCounter: true to file_write, file_edit, shell
- Reduce maxSteps from 50 to 25 (resetsCounter makes this safe)
Replace the blanket cache invalidation (cleared on any file_write/edit)
with per-entry staleness detection based on file mtime and size. On cache
hit, stat the file and compare against the metadata stored at cache time.
If the file changed (user edited externally, git checkout, etc), the
stale entry is discarded and the tool re-executes.
This fixes the case where a user is coding alongside the agent — external
file changes are now detected instead of serving stale cached reads.
- Rename AgentCfg.SaveSession/FlushSave to Save/Flush for brevity
- Remove restoreLegacySession — all sessions now use multi-agent format
- Pass Save/Flush callbacks to agents in CreateAgent and restore paths
- Add AuditLog fallback warning in NewAgent
When a streaming tool completes, emit a final empty-Content event so the
log handler always closes the markdown source fence. In the handler,
emit [[[end]]] directly instead of a blank line, so the GUI block parser
transitions back to BlockStart regardless of what follows.