Commit Graph

11 Commits

Author SHA1 Message Date
Levi Neely c2cbc3e806 split execute_code into three tools; improve ollama backend and system prompt
- 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
2026-04-04 17:57:55 +02:00
Levi Neely ab575ee385 backend,agent,main: retry on HTTP 429 with live countdown
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>
2026-04-04 11:25:05 +02:00
Levi Neely 474eb84e2d agent,backend: drop non-streaming path
Both backends already implement streaming; the non-streaming fallback
was dead code that added complexity.

- Backend interface now requires only ChatStream; the separate
  StreamingBackend interface and Chat method are removed
- Both OpenAIBackend and OllamaBackend lose their Chat methods and the
  stream=bool parameter on their internal doChat helpers
- Loop.Run is simplified: one streaming path, no streamed flag, no
  skippedCalls map, no shouldStop helper, no runStreamStep indirection
- "call" events are now emitted solely in the act phase, not in the
  stream phase, so dedup tracking is no longer needed

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 20:11:10 +02:00
Levi Neely cd95e2f065 backend/openai: fix streaming token counts always zero
OpenAI sends usage in a separate trailing SSE chunk, not in the same
chunk that carries finish_reason. The previous code read wire.Usage
from the finish_reason chunk (where it is always zero) and discarded
all subsequent chunks.

Fixes:
- Add stream_options:{include_usage:true} to the request so OpenAI
  actually includes usage in the stream at all.
- Accumulate usage across every chunk instead of reading it once at
  finish_reason time.
- On the Done event, use the accumulated usage rather than the
  (always-zero) usage from the finish_reason chunk.
- Keep processing chunks after finish_reason until data:[DONE] so
  the trailing usage chunk is not silently dropped.
2026-04-01 13:16:31 +02:00
Levi Neely d60a1b9215 Add streaming support for bot output and tool execution
- backend: StreamingBackend interface + StreamEvent type
- backend/ollama: ChatStream with line-by-line JSON-LD decoder
- backend/openai: ChatStream with SSE delta parser + tool arg accumulation
- agent/loop: runStreamStep reads deltas, emits OutputMsg per chunk,
  deduplicates call/tool display between stream and outer loop
- main: agentMsg tea type streams incremental updates to the TUI;
  plain string buf replaces strings.Builder (avoids copy-by-value panic);
  drainAgent cancels in-flight goroutines cleanly on user interrupt
2026-04-01 12:52:58 +02:00
Levi Neely 2286ebded5 Remove openrouter backend alias
openrouter is OpenAI-compatible; just set OLLIE_OPENAI_URL to the
OpenRouter endpoint. No separate backend case needed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 00:57:18 +02:00
Levi Neely f9ba6c8bce Track and display token usage per request
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>
2026-04-01 00:31:03 +02:00
Levi Neely b529c23d75 Rename OLLIE_API_KEY to OLLIE_OPENAI_KEY
Consistent with OLLIE_OPENAI_URL; makes it clear the key only applies
to openai/openrouter backends.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 23:51:01 +02:00
Levi Neely ebb726e384 Split OLLIE_API_URL into backend-specific vars
OLLIE_API_URL was shared across backends, causing the ollama backend
to use the OpenRouter URL when OLLIE_BACKEND was overridden on the
command line while the env file still set OLLIE_API_URL.

Replace with OLLIE_OLLAMA_URL and OLLIE_OPENAI_URL so each backend
only reads its own URL setting.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 23:50:05 +02:00
Levi Neely 463457cd14 Load ~/.config/ollie/env before reading backend env vars
Env file is optional; existing environment variables take precedence.
Supports KEY=VALUE format with # comments and blank lines ignored.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 23:32:36 +02:00
Levi Neely 127f428620 Add backend package: common LLM interface for ollama and OpenAI-compatible APIs
Defines a Backend interface with shared Message/Tool/ToolCall types.
OllamaBackend wraps /api/chat; OpenAIBackend covers OpenAI, OpenRouter,
and any compatible API. Factory reads OLLIE_BACKEND, OLLIE_API_URL,
OLLIE_API_KEY.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 22:40:42 +02:00