The audit logger was never a separate destination — it was always
log.Sub("audit"), writing to the same sink with a prefix. The
fallback in NewAgent even warned 'deriving from Log' every time.
Replace ag.auditLog.Debug() calls with ag.log.Debug() directly.
Remove the field, AgentCfg.AuditLog, and all session plumbing.
The agent always talks to a *Conn (never a *Server directly).
Replace the Runner interface with the concrete type throughout:
- Runtime.ToolServer is now *toolsrv.Conn
- BuildRuntime takes *toolsrv.Conn
- session.Config, SessionInfra, InfraConfig use *toolsrv.Conn
- All inline type assertions in agent.go deleted — methods called
directly on *Conn (SetEnv, SetCWD, Close, Detach, ListDetachedRaw,
SignalDetached, GetDetachedOutput, DismissDetached, SetAllowTools,
SetOnToolsChanged, Ping, ToolRegistryRevision)
- Added Conn.ToolRegistryRevision() that returns 0 (remote connections
don't support revision tracking; use push-based OnToolsChanged instead)
- Deleted the Runner interface and its test
- Renamed LoadToolOnRunner → LoadToolOnConn
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.
- Extract hardcoded tool sections into prompts.ToolSections() function
- Replace template system with simple Go code for better maintainability
- Fix refreshToolListing to preserve tool documentation and discovery sections
- Add comprehensive unit tests for prompts and agent packages
- Remove unnecessary tool_sections.md template file
The refactoring simplifies the preamble construction while maintaining
all functionality. Tool listing updates dynamically via refreshToolListing,
while tool documentation requires agent reload (full BuildPreamble call).
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)
- Move FormatEvent to format/ package for reuse by both live handler
and replay
- Move LoadConfig to agent/ package where it belongs
- Remove log validator (was noisy, not essential)
- Update replay to use FormatEvent for consistent output format
- Update kde submodule with GUI streaming fix
- HandlerCtx now embeds context.Context for per-operation cancellation/deadline
- Reverted fsedsl signatures back to simple (ctx Ctx) since context is embedded
- requestGenerate handler uses ctx instead of context.Background()
- cmdInject propagates its context parameter instead of using Background
- Delete agent/complete.go (110 lines) and its requestComplete handler
- Remove /complete 9P file from fs/spec.go
- Update KDE kate plugin to build the completion prompt inline and call
ollie-9p rdwr generate instead of ollie-9p rdwr complete
- StripCompletionNoise and stripPrefixEcho moved into C++ helpers
- Remove all OLLIE_*_PATH vars (TOOLS_PATH, CFG_PATH, DATA_PATH, etc.)
Use XDG_CONFIG_HOME/ollie/* and XDG_DATA_HOME/ollie/* instead
- Replace OLLIE_<TAG>_LOG per-component logging with single OLLIE_LOG={level}
- Replace OLLIE_USAGE_LOG with XDG_DATA_HOME-based path
- Replace OLLIE_OLLAMA_URL with standard OLLAMA_HOST (or omit entirely)
- Rename protocol markers: OLLIE_LISTEN_READY → ListenReady, OLLIE_9P_OPEN → Open
- Remove freeloader hooks from agent configs
- Update sandbox YAMLs to use XDG paths instead of OLLIE_*_PATH tokens
- Update shell tools to use $(dirname "$0") fallback instead of OLLIE_TOOLS_PATH
- Update docs and prompts accordingly
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.
- Stripped OLLIE_TOOLS_PATH, OLLIE_AGENTS_PATH, OLLIE_SKILLS_PATH,
OLLIE_PROMPTS_PATH, OLLIE_MEMORY_PATH, OLLIE_TMP_PATH from managed
list and defaults in env.go
- ToolsPath(), SkillsPath(), PromptsDirs(), AgentsDirs(), ollieTmpDir()
now derive from paths.CfgDir()/paths.DataDir() directly
- Removed shell-exec fallback from resolveExecPrompt() — only file
resolution remains
- Cleaned up env_test.go to match reduced managed set
- Updated stale comments referencing /home/lkn/.config/ollie/tools
- Skip SetupToolServer for paused sessions during restore
- Pause() and Resume() now persist state to disk
- Resume() sets up tool server from scratch for sessions restored paused
- IsConnected() returns false when paused
- Add SetPaused(), SetToolServer() methods
- ProcessKeeper.SetContext() for resume after pause
- Session index sorts active-first, paused-last
- CreateAgent accepts name= parameter
- Remove duplicate SetCwd method
- 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
After the fs/session refactor, NewEventHandler was defined but never
called. Agents created via session restore or CreateAgent had nil
output handlers, so emit() was a no-op and the chat stream stayed empty.
- Add Agent.SetOutput() to allow setting the event handler post-creation
- Wire up SetOutput(NewEventHandler(al)) in fs/newroot.go for restored sessions
- Wire up SetOutput(NewEventHandler(al)) in fs/handlers.go for new agents
- Also includes expanded UsageStats fields and TaskState persistence
session/persist.go:
- New multi-agent format: PersistedSession with []PersistedAgent
- PersistSession saves ALL agents, not just first
- RestoreAllSessions returns []RestoredSession with []RestoredAgent
- Backward compatible: restores legacy single-agent format
fs/persist.go:
- Thin wrapper that creates AgentLogs for each restored agent
- Delegates to session.PersistSession/RestoreAllSessions
agent/agent.go:
- Added Messages() to get conversation history
- Added Usage() to get token/cost stats
agent/history.go:
- Added RestoreHistoryFromMessages for multi-agent restore
session/session.go:
- Added Remote() getter
- Use github.com/simonfxr/pubsub for topic-based event routing
- Topic format: session.{id}.{action}, agent.{id}.{action}
- Wildcard subscriptions: *, session.*, agent.*
- PublishEvent routes to exact topic + wildcards
- WaitEvent maintains backwards compatibility for eventwait
- Add agent.SetOnStateChange callback for state change events
- Extend session/idx format with paused, connected, agent list
Events now published:
- session.{id}.new/kill/pause/resume/rename
- agent.{id}.new/kill/state
This enables efficient selective subscriptions - GUI can subscribe
to specific sessions/agents instead of receiving all events.
The OutputFormat function was set once at runtime build time and stored
in ag.runtime.OutputFormat. When tools were dynamically loaded via
tool_load, the tool definitions were refreshed but the OutputFormat
lookup still used the stale runtime version that didn't know about
newly loaded tools.
Build the outputFormats map from the fresh tool list on each turn,
just like we already do for the tool definitions. This ensures
outputFormat (e.g., 'diff' for file_edit) is available immediately
after loading a tool.
ToolServer is vital infrastructure — it must never be nil. If the
initial dial fails, retry via ProcessKeeper (which respawns
ollie-remote). If still unavailable, fail agent creation with a
clear error asking the user to try again.
Reverted the nil-check band-aid in turn.go — ToolServer is now
guaranteed non-nil for any running agent.
Prevents nil pointer dereference when a newly created agent's
tool server connection failed to establish (keeper.Dial returned
nil, or session was restored with a dead toolsConn).
Models that ignore native tool schemas (via the API tools parameter)
now see full tool documentation in-context: usage docs, argument
definitions, examples, and the JSON schema.
This is appended as a '# Tool Documentation' section in the system
prompt, below the compact '# Available Tools' listing.
The agent's 12-char hex uname was not persisted. On restore,
fs/persist.go incorrectly used ps.ID (session UUID) as the uname,
making OLLIE_UNAME identical to OLLIE_SESSION_ID.
Fix: add Uname field to PersistedAgent, persist ag.id in SaveFull,
restore from ps.Uname (falls back to nextUname for old files).
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.