- Split execute_code into execute_code, execute_tool, execute_pipe for
clearer model comprehension, especially on smaller models
- Ollama: accumulate tool calls across all stream chunks (fixes llama3.1
which delivers tool calls only on the done event)
- Ollama: add HTTP 429 / RateLimitError handling
- Ollama: map ToolCallID on outbound messages
- System prompt: inject cwd, current time, available tools
- System prompt: clarify tool usage rules
- Fix spurious spaces in streamed output (remove addStreamingContent heuristic)
- Fix tool output display: preserve newlines, add blank line separation
Each agent config (mcpServers, hooks, prompt) lives in its own file.
'prompt' is injected after the system prompt, allowing per-agent
behaviour without touching the minimal base system prompt.
Startup loads agents/default.json, falling back to the legacy
config.json. The /agent [name] command swaps the active agent at
runtime, rebuilding MCP connections, hooks, tools, and the composed
system prompt, and resetting the session. Agent name is shown in the
status bar.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove use-case-specific instructions (execute_code how-to, planning
workflow, skill discovery) — these dictate behavior inappropriate for a
general-purpose agent and add tokens to every request. Keep only the
terse-output and anti-filler guardrails that directly affect cost and
response quality.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When the model emits a text-only turn containing narration phrases
("let me", "i'll", "i will", etc.) with no tool calls, the loop now
injects an ephemeral "Continue. Act now." user message and runs another
step rather than treating the turn as completion. Capped at 2 nudges
per run to prevent infinite loops. UI shows "[nudge: continuing…]" so
the user can see what happened.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Return RateLimitError from openai backend on HTTP 429, parsing the
Retry-After header (integer seconds or HTTP-date). The agent loop retries
up to 3 times with exponential backoff (5s/10s/20s) when no header is
given, emitting per-second countdown ticks. The status bar renders
"retry {N}s" during the wait.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Re-adds handleCommand (/help, /model, /backend) and wires it into the
enter handler so slash commands are processed without starting an agent.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Five improvements for cost/focus efficiency:
1. Budget now accounts for fixed per-request overhead (system prompt +
tool schemas), which were previously invisible to ContextBuilder and
could silently exceed intended limits by 30-50%.
2. Tail counting now only counts user and plain-assistant (no tool_calls)
messages toward TailMessages quota. Processed tool exchanges between
conversational turns are included but do not crowd out genuine context.
Trailing in-progress exchanges are always preserved and free.
3. BoundedHistory / BoundedHistoryWithNotice deduplicated into a single
buildBounded(injectNotice bool) private helper.
4. O(n²) prepend in the greedy inclusion loop replaced with
append+slices.Reverse.
5. exec.Executor.MaxOutputChars replaces the hardcoded 8000-char const.
Initialised from OLLIE_TOOL_OUTPUT_CHARS env var, defaults to 8000.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Loop struct and New constructor removed; Run is now a package-level
function taking (ctx, Config, State)
- Stop condition de-nested: natural stop (no tool calls → MarkComplete
+ break) and step-limit stop (step >= maxSteps-1 → break) are now
separate, sequential checks instead of a redundant outer/inner pair
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Some backends (DeepInfra, OpenRouter) occasionally emit null or empty
content for whitespace-only tokens, causing adjacent words to fuse
("normaluse" instead of "normal use"). addStreamingContent inserts a
single space at the chunk boundary whenever neither side carries
whitespace. Safe for LLM streaming because BPE tokens are always
whole — they never split mid-word at the API level. Rewritten to use
utf8.DecodeLastRuneInString / utf8.DecodeRuneInString instead of raw
byte indexing so multi-byte UTF-8 is handled correctly.
Also remaps viewport scroll keys: half-page to alt+d/alt+u (avoids
conflicting with terminal line-editing on ctrl+d/u) and per-line
scroll to down/up arrows plus alt+n/alt+p (Emacs-style, safe in xterm
and plain tty alike).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Derive a human-readable backend label from OLLIE_BACKEND and
OLLIE_OPENAI_URL at startup and store it in model.backendName.
For the openai backend, inspect OLLIE_OPENAI_URL to distinguish
known providers (openrouter, together, groq, mistral, anthropic)
from a generic openai-compatible endpoint, so the bar shows e.g.
"openrouter" instead of "openai" when using OpenRouter.
Status bar format changes from:
[model] state | ...
to:
[backend :: model] state | ...
Add a one-line status bar rendered between the viewport and the textarea.
The bar shows:
[model] <state> | last: ↑N ↓N | ctx: ~Nk tokens (N msgs)
Agent state transitions:
idle - no agent running
thinking… - agent is running, no tool call yet this step
tool: foo - agent is executing tool 'foo'
Token usage is updated from the 'usage' agent output event.
Context stats are updated from session.ContextStats() after each agent step.
The 'usage' role no longer appends a display line; it only updates the bar.
Instructs the agent to be terse: no preamble, narration, summaries,
task restatement, hedging, or self-congratulation. Based on
anvillm OUTPUT_PROTOCOL.md.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove os.Environ() inheritance from MCP subprocess. The child
process receives only the vars explicitly listed in mcpServers[].env,
with values expanded from the parent environment via os.ExpandEnv.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
os.ExpandEnv() applied to MCP server env values so \${VAR} syntax
works. Config load errors now appear in the startup display instead
of being silently dropped when using the default config path.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace log.Printf MCP connection messages with entries in the
initial display slice, so connection status and tool counts appear
in the chat pane rather than on stderr.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Bring back ollie/mcp and ollie/tools packages. Config MCPServers
field restored. MCP tools are discovered at startup and added to
the agent tool list alongside execute_code. Dispatch routes by
server name for MCP tools, falls back to built-in execute_code.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add Usage{InputTokens, OutputTokens} to backend.Response. Both
OllamaBackend (prompt_eval_count/eval_count) and OpenAIBackend
(prompt_tokens/completion_tokens) populate it. The loop emits a
'usage' OutputMsg after each Chat call; the UI displays it as
[↑N ↓N tokens].
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Configure viewport keymap to use page-based scroll keys only, leaving
up/down arrows free for textarea cursor movement. Viewport is now
initialized once with the custom keymap and resized (not recreated)
on window resize. Key messages are routed to both viewport and textarea.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Small models were writing markdown code blocks describing what they
would run instead of actually calling the tool. Explicitly forbid
this pattern in the system prompt.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Model was putting discover_skill.sh in the 'code' field and running
it as inline bash. Explicitly state that 'tool' field is required for
discover_skill.sh and load_skill.sh, and that 'code' must not be used
for them.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The previous wording implied execute_code was always required after
planning. Clarified that the model should begin executing immediately,
using execute_code only if the step requires it.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Emit a 'call' message before each tool execution so the UI shows
execute_code(...) with full args before the result. Result lines
are now indented with '= ' to visually pair with the call.
System prompt now explicitly says to call execute_code immediately
after planning, without pausing for confirmation, to prevent smaller
models stalling after the planning step.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace high-level principles with explicit rules: when to call
execute_code, exact invocation syntax for all three modes, and
a numbered sequence (discover skills → plan → execute) that
smaller models can follow without inferring intent.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Agent must discover and load relevant skills before acting on any task,
re-running discovery when domain shifts. Agent must also produce a
numbered plan before executing, and revise it if steps fail.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fall back to the default path silently if the file does not exist.
Only fatal on a missing/invalid config if the path was explicitly
provided as a CLI argument.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Extract renderDisplay() to word-wrap each line at the viewport width
before setting content. Re-wrap on terminal resize. Fixes tool output
and long bot responses being truncated at the viewport edge.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
BeadState duplicated what execute_code already provides via tool scripts.
Removed it entirely. Added SystemPrompt field to agent.Config, prepended
as a system message each loop iteration. Built-in prompt covers
execute_code usage, sandbox behavior, and skill discovery.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Drop ollie/mcp, ollie/tools, ollie/ollama packages. Config now only
carries hooks. main.go wires a single execute_code tool directly to
the agent loop — no MCP discovery or dispatch needed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
main.go now uses backend.New() for LLM selection (OLLIE_BACKEND env),
agent.Loop for observe/decide/act/update/terminate, and ollie/exec for
built-in execute_code. Multi-turn sessions persist across user inputs.
MCP tools route through mcpExecutor; unknown tools fall back to built-in.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>