session.New() had zero callers — all sessions are created via
NewEmpty() + buildAgent(). Remove it along with the Config struct
(20 fields) and the per-session sessionsDir field (always identical
to pkgSessionsDir).
-92 net lines
sync.Cond is the wrong primitive for Go — it requires holding a mutex
during Wait and needs context.AfterFunc hacks to integrate with ctx
cancellation.
Replace with a simple signal channel: notifyChange() closes it and
swaps in a fresh one; WaitChange() selects on the channel and
ctx.Done(). Simpler, idiomatic, no spurious wakeups.
Add JSON tags to backend.GenerationParams and embed it directly in
AgentConfig. The 14 duplicated sampling fields and the field-by-field
copy method disappear. Callers use cfg.GenerationParams directly.
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
All agent configs use the same pattern: JSON array of file paths with
env var expansion. Remove unused features:
- Shell command execution via resolveStringPrompt (the `!cmd` prefix
path is kept as a trivial fallback but the 30s timeout/stderr
capture/cwd probing is gone)
- Prompt directory search (PromptsDirs, resolvePromptFile)
- Shell metacharacter detection guard
- Literal-text-if-contains-newline heuristic
- IsExec flag on Prompt type (both string and array now mean the same
thing: list of file paths)
207 + 49 → 104 + 38 lines (-114)
- Export ID, Uname, Ctx, Cancel, Proc, Keeper, Remote as struct fields
(set-once at creation, not raced during agent loop)
- Keep mutex-protected accessors only for Name, ToolsConn, IsPaused
which are read/written concurrently
- Extract buildAgent() shared helper used by both CreateAgent and
restoreMultiAgentSession — eliminates ~100 lines of duplicated
orchestration (tool server setup, prompt layers, runtime, backend)
- Paused sessions skip tool server entirely during restore (minimal
agent with just history)
- Update fs/session_node.go delegators for exported fields
- 1638 → 1523 lines (-115)
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
Previously, Go binaries and scripts installed to ~/bin while cmake
(KDE) installed to ~/.local/bin. This caused stale binaries in ~/bin
to shadow fresh builds since ~/bin comes first on PATH.
- Change bin variable from ~/bin to ~/.local/bin
- Add migrate-bin target to clean stale ~/bin copies
- Run migrate-bin automatically during install
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.