Commit Graph

29 Commits

Author SHA1 Message Date
Levi Neely e2d973fe3f Remove agent stalled feature
Remove MaxSteps limit and associated stalled event emission.
The agent will now run indefinitely until completion or interruption,
eliminating the annoying 'agent stalled' messages.
2026-04-11 15:51:39 +02:00
Levi Neely 5e08beb9bf agent: add dynamic workdir support via /cwd command and SetWorkDir API
- Add WorkDirSetter interface to pkg/tools so servers can receive workdir updates
- Add SetWorkDir on execute.Server with RWMutex-guarded workdir field
- Add WorkDir()/SetWorkDir() to the Core interface and agentCore
- Store agentPrompt in AgentEnv/agentCore so system prompt can be rebuilt on workdir change
- Add /cwd [path] slash command (no args shows current dir, arg changes it)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 14:21:34 +02:00
Levi Neely 7fa952c59f agent: add reasoning_plan, task backend integration, and /mcp command
- Add reasoning_plan built-in tool: decomposes goals into ordered steps
  with dependency edges; persists to task backend when available, falls
  back to in-context plan otherwise.
- Add PlanBackend/PlanBackendSetter interfaces and PlanStep type to
  pkg/tools; add GetServer to Dispatcher.
- Add dispatchPlanBackend in pkg/agent: routes task_create calls through
  the dispatcher to any registered task MCP server.
- BuildAgentEnv auto-wires the task backend to the reasoning server after
  connecting MCP servers; re-wires on every /agent switch.
- Add ListServers() to Core interface: groups all registered tools by
  server, returns formatted text.
- Add /mcp command to handleCommand(); update /help.
- Add doc/PLANNING.md and update ARCHITECTURE.md.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 11:31:41 +02:00
Levi Neely b77aefbe1e agent: add PromptFIFO unit tests
Tests cover FIFO ordering, empty-pop behaviour, and concurrent push safety.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 10:03:47 +02:00
Levi Neely 7b90a459d1 agent: add /usage command, Usage() and ListModels() on Core 2026-04-10 20:37:21 +02:00
Levi Neely 2f68cc1f31 agent: add usage tracking and per-turn token reporting
Emit usage events from the loop when backends report token counts.
Session tracks cumulative input/output tokens and request count.
2026-04-10 20:29:49 +02:00
Levi Neely c49e117489 agent: richer hooks with JSON payloads, blocking, and context injection
Hooks now receive JSON on stdin, can block actions (exit 2), and inject
stdout into the conversation. Stop hooks can continue the agent loop
with stderr as the next prompt. 60s timeout, context-cancellable.
Config format unchanged — existing hooks still work.
2026-04-10 20:19:38 +02:00
Levi Neely a54e5946bb agent: add interrupt injection, prompt FIFO, and queue drain
- Inject(prompt) cancels the running tool and injects the message into
  the conversation as <system-user-interruption>
- Queue/PopQueue FIFO for deferred prompt execution
- Submit() drains FIFO after each turn
- IsRunning() for frontends to choose Submit vs Inject
- TUI: typing during a turn calls Inject; /q queues
- 9P: prompt interrupts if busy; prompt.fifo is push/pop FIFO
2026-04-10 20:11:12 +02:00
Levi Neely 105b56d746 agent: replace rollback with proper interruption recording
Instead of discarding history on interruption, record what happened:
- Partial assistant content and tool calls are preserved
- Skipped tool calls get synthetic cancelled results
- Phase-specific notes (stream/tools/request) tell the model what occurred
- Side effects from already-executed tools are no longer hidden from history
2026-04-10 19:39:02 +02:00
Levi Neely 45a094f46e backend: add ContextLength, Models, and auto-compaction
- Add ContextLength(ctx) int to Backend interface; each backend fetches
  from its API (OpenAI /v1/models, Ollama /api/show, CodeWhisperer
  ListAvailableModels) with caching. Falls back to 128k default.
- Add Models(ctx) []string to Backend interface for model discovery.
- Add /models command to list available models.
- Auto-compact before each turn when estimated tokens >= 75% of context length.
2026-04-10 19:35:44 +02:00
Levi Neely e4c379ab94 agent: replace naive compaction with structured LLM-driven summarization
- Structured compaction prompt asking for progress, decisions, next steps
- Flatten tool call/result sequences to plain text before compaction
- Preserve recent user messages (up to ~20k tokens) in compacted history
- Inject summary as handoff message for the resuming LLM
- Persist pre-compaction snapshots as append-only JSONL for long-term memory
2026-04-10 18:56:17 +02:00
Levi Neely c147c7a7da agent: remove buildFirstPrompt file listing and README injection
The agent discovers files via tools now. No need to stuff git ls-files
and README.md into the first user message.
2026-04-10 18:51:20 +02:00
Levi Neely ade69b0e16 agent: remove character-based context window eviction
Delete context.go and its entire eviction system (contextBuilder,
SoftLimit/HardLimit/TailMessages, buildBounded, sanitizeHistory).
Session now holds a plain []backend.Message with no silent dropping.

/compact still works via LLM-driven summarization. /context still
shows message count and token estimates.
2026-04-10 18:49:38 +02:00
Levi Neely c0436a88d1 agent: replace hardcoded system prompt with runtime-loaded template
Move the system prompt from an inline Go string to prompts/SYSTEM_PROMPT.md,
loaded at runtime from ~/.config/ollie/prompts/ via text/template. The prompt
is now editable without recompilation and focuses on behavioral guidance
rather than token-saving directives.

- Remove systemPromptBase constant and token-efficiency instructions
- Add DefaultPromptsDir() for prompt directory discovery
- Load and render SYSTEM_PROMPT.md with {{.WorkDir}}, {{.Platform}}, etc.
- Update mkfile to install prompts/ to ~/.config/ollie/prompts/
2026-04-10 18:45:01 +02:00
Levi Neely d585125303 agent: fix buildFirstPrompt using process cwd instead of session workdir
buildFirstPrompt was calling os.Getwd() unconditionally, injecting the
server process's working directory into the first turn's file listing
regardless of the session's configured workdir. Now accepts workdir and
falls back to os.Getwd() only when empty.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 09:21:12 +02:00
Levi Neely 23913d0d76 execute, agent: thread workdir through Decl and AgentCoreConfig
execute.Decl is now a function (func(workdir string) func() tools.Server)
rather than a var, making workdir an explicit dependency rather than
an implicit os.Getwd() call. execute.Server stores the workdir and
sets cmd.Dir accordingly; falls back to os.Getwd() if empty.

AgentCoreConfig gains WorkDir string, threaded into BuildAgentEnv and
the system prompt. The /agent switch uses s.workdir so the correct
directory is preserved across agent switches.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 09:04:19 +02:00
Levi Neely 5afe380437 agent: use Unix nanosecond timestamps in NewSessionID
Session IDs are now <unix-nanoseconds>-<random-hex> instead of a
human-readable timestamp. Lexicographic sort = creation order, with
nanosecond granularity ensuring correct ordering even for sessions
created in rapid succession. The random suffix guarantees uniqueness
in the (extremely unlikely) event of a nanosecond collision.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 08:50:48 +02:00
Levi Neely 8496742f14 tools: add Decl vars, NewDispatcherFunc; strip execute logging
- execute.Decl and file.Decl: package-level func() tools.Server factories;
  consumers reference them without calling directly
- tools.NewDispatcherFunc: builds a fresh Dispatcher per call by invoking
  each registered Decl — used as AgentCoreConfig.NewDispatcher
- execute.Server: remove LogDir, WorkspaceBase, MaxOutputChars, and all
  file-based logging (metrics.go deleted); New() takes no args
- Export AgentConfigPath, NewSessionID, DefaultAgentsDir, DefaultSessionsDir
  from pkg/agent so frontends don't duplicate them

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 08:27:56 +02:00
Levi Neely 6ce6e2514d agent/core: decouple from execute and file packages
Replace ExecServer/FileServer fields on AgentCoreConfig with a
NewDispatcher factory func. The /agent handler calls it to rebuild
a fresh dispatcher on agent switches, without core needing to import
execute or file.

Drop ToolsPath from the system prompt template — the path is already
embedded in the execute_tool and execute_pipe tool descriptions by
the execute package itself. Removes the text/template dependency.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 00:03:53 +02:00
Levi Neely f87699ac7d Unify tool servers: dissolve builtin/MCP distinction
All tool servers now implement tools.Server equally. tools.MCPExecutor →
tools.Dispatcher (unexported dispatcher), tools.Executor → tools.Dispatcher
interface, tools.NewMCPServer → tools.NewServer, execute.Executor →
execute.Server, file.Server added. BuildAgentEnv takes a pre-configured
Dispatcher; caller registers execute and file servers before calling.
builtinServer collapsed — no special "builtin" concept remains.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 23:51:10 +02:00
Levi Neely 2e82bb2306 tools: unexport builtinServer, add NewBuiltinServer constructor
Matches the pattern of mcpServer/NewMCPServer — both are unexported
Server implementations created via constructors. No conceptual
difference between the two from the caller's perspective.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 23:19:02 +02:00
Levi Neely 9d1021f129 tools: consolidate builtin server in pkg/tools/
- pkg/tools/builtin.go: BuiltinServer implements tools.Server for all
  built-in tools; ExecuteDefs/FileDefs live here (subpackages can't
  hold them without reintroducing the import cycle)
- pkg/tools/execute/dispatch.go: drop tools.Server implementation;
  export Dispatch method for BuiltinServer to call
- pkg/tools/file/: export Read(path) and Write(path,content,start,end);
  remove server.go
- pkg/agent/core.go: register one tools.BuiltinServer instead of two
  separate servers

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 23:16:29 +02:00
Levi Neely 01c9ac534e tools: move file_read/file_write into pkg/tools/file
- New pkg/tools/file package with read.go, write.go, server.go
- file.Server implements tools.Server; registered as "file" in MCPExecutor
- Remove file_read/file_write from execute/dispatch.go
- Confirm closure shared between builtin and file servers

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 23:03:50 +02:00
Levi Neely 8875bc8377 tools: unify builtin and MCP dispatch through tools.Server
- Add tools.Server interface; MCPExecutor now holds map[string]Server
- execute.Executor implements tools.Server (ListTools/CallTool/Close)
- Built-in tools register as "builtin" server in MCPExecutor
- Remove duplicate dispatch functions from core.go (moved to dispatch.go)
- Remove builtinTools() from core.go (now in dispatch.go)
- Remove invalidateCaches and trustedTools dead code
- All tool calls now route through one mcpExec.Execute() path

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 23:00:23 +02:00
Levi Neely 8e2b8083bb execute_tool: replace 9P mount with filesystem read; drop 9fans dep
ReadTool now reads from OLLIE_TOOLS_PATH (default ~/.local/share/ollie/tools)
as a plain filesystem path, compatible with 9pfuse mounts or symlinks.
ToolsPath() is exported and used to expand tool descriptions and the
system prompt template at runtime.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 22:33:30 +02:00
Levi Neely 97b85e5163 refactor: promote backend/config to pkg/, extract TUI to ollie-tui
Move internal/backend and internal/config to pkg/ so external consumers
can import them. Remove cmd/ollie and internal/tui — they now live in
the separate ollie-tui repo which imports ollie as a library.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 22:05:35 +02:00
Levi Neely a3e1a078c4 refactor: move mcp/tools/execute to pkg/ for external consumability
internal/mcp      → pkg/mcp         (MCP client, concrete)
internal/tools    → pkg/tools        (Executor interface + MCPExecutor)
internal/exec     → pkg/tools/execute (builtin sandbox executor, split by tool)

Split exec.go into executor.go (sandbox runner), pipe.go (BuildPipeline/PipeStep),
tool.go (ReadTool), and code.go (execute_code is Executor.Execute with trusted=false).

All three packages are now importable by consumers outside this module.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 21:59:01 +02:00
Levi Neely ce329bfcc7 backend: internalize model state; remove model param from ChatStream
Each backend now owns its active model via Model()/SetModel(). ChatStream
no longer takes a model string — callers use SetModel to configure it.
AgentCoreConfig.ModelName sets the backend model at construction time via
SetModel, then the field can be dropped from the live agentCore struct.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 21:42:30 +02:00
Levi Neely f280ef17db Make pkg/agent internals private; move app-level utils to cmd/ollie
Everything not part of the agent<->frontend contract is now unexported:
- contextConfig/Builder/Stats, loopConfig, toolExecutor, confirmFn,
  run, state, toolResult — internal loop/session machinery
- buildFirstPrompt, systemPrompt, builtinTools — impl details
- agentCore struct (NewAgentCore returns Core)
- Session methods (saveTo, history, rollback, compact, etc.)
- AgentEnv internal fields (mcpExec, exec, confirm, tools, etc.)

App-level utilities moved from pkg/agent to cmd/ollie:
- resolveBackendName, defaultModelForBackend, newSessionID,
  agentConfigPath

RestoreSession now takes int (ctxOverhead) directly, eliminating
the need for contextConfig to be public.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 21:31:02 +02:00