backends.conf now supports a top-level 'backend = name' line that
selects the default backend for new sessions. Lookup order:
1. backends.conf 'backend = ...'
2. OLLIE_BACKEND env var (fallback)
3. session-level backend= parameter (override)
No env file needed for backend/model config anymore.
Each backend is now configured via ~/.config/ollie/backends.conf:
[openrouter]
key = sk-or-v1-...
model = qwen/qwen3-235b-a22b
[anthropic]
key = sk-ant-...
Each backend knows its own default URL (openrouter → openrouter.ai/api,
anthropic → api.anthropic.com, etc). Only key and optional model needed.
Env vars (OLLIE_OPENAI_KEY, OLLIE_ANTHROPIC_KEY, etc) still work as
fallback for backward compatibility, but backends.conf is the canonical
config path going forward.
- Delete openAIName() (URL no longer determines backend identity)
- Delete geminiKey() (config handles fallback)
- Install template with mode 600 (contains API keys)
- Only install template if user hasn't created their own
The previous commit (3b83b9d) replaced globalRootState with
ctx.Root.Data.(*RootState), but ctx.Root is nil inside closures
captured by BuildTree (Root is set *after* the tree is built).
Fix: add RootState field to HandlerCtx and create it before BuildTree
so all closures capture the live pointer directly.
toolsrv:
- Merge rpc.go into conn.go (wire types already there)
- Merge tools.go + discover.go into registry.go
- Merge accessors.go into server.go
- 4 files eliminated
fs:
- HandlerCtx.Context now carries the session context (set via
sessionBindings Applier). Previously it was the daemon context
which never cancels — handlers checking ctx.Done() now properly
detect session kill/pause.
- Session-scoped blocking handlers (streamAgentChat, blockAgentStateWait)
merge session context with per-read timeout via mergeCtx(). A session
kill now immediately unblocks readers without waiting for the 5s timeout.
- Remove redundant manual AfterFunc in blockAgentStateWait.
session:
- Remove unused _ string parameter from WaitEvent
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.
The system prompt tool listing now refreshes immediately on tool_load
instead of only on file-watcher events. buildToolListing helper added
to format the listing in the same format BuildPreamble uses.
Also updates kde submodule: GUI auto-switches to newly created agent,
removes remote field from agent dialog.
- 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).
Add ollie9p_open, ollie9p_read_fid, ollie9p_close_fid for streaming
file reads. This allows the KDE GUI to read chat/statewait/eventwait
files natively without spawning subprocesses.
Switch from 'read -e' to plain 'read' so multi-line paste can be
captured. Readline was consuming pasted lines individually.
Increase drain timeout to 100ms.
- Add 'o log [-n N]' to read last N lines from agent log (default 1000)
- Rename 'o tail' to 'o chatstream' for clarity
- Update TUI to show log history before streaming chat
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)