Add agent/context.go with a ContextBuilder that enforces a character budget
(soft + hard) over the assembled history, evicting oldest non-system messages
first and replacing large tool outputs with truncated summaries.
Update agent/session.go to use ContextBuilder in History(), so the loop
always sees a bounded context window regardless of how many steps have run.
The budget defaults are:
- SoftLimit: 24000 chars (~6k tokens at 4 chars/token)
- HardLimit: 96000 chars (~24k tokens)
- MaxToolOutputChars: 2000
- TailMessages: 6 (always keep last N messages verbatim)
All limits are configurable via ContextConfig.
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>
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>
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>
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>
Implements the core agent loop with two state backends:
- Session: ephemeral in-memory, lives for one process lifetime
- BeadState: bead-backed via 9beads tool scripts (claim/read/complete)
Loop is backend-agnostic; takes a ToolExecutor and emits OutputMsgs.
MaxSteps defaults to 1 for simple prompts; callers set higher for tasks.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>