- Detect empty LLM responses (no content, no tool calls) instead of
silently treating them as task completion. Retries once without tools
before warning the user.
- Gate /no_think system message and chat_template_kwargs to Qwen/QwQ
models only — sending /no_think to llama3.x caused empty responses.
- Add model_profiles config section for per-model overrides (token
budget, thinking, temperature, max_tokens) matched by name prefix.
Applied at startup and on /model switch.
- Update SessionManager on /model switch so session files record the
correct model.
- Add NDJSON fallback in SSE stream parser for Ollama compatibility.
- Improve read_file error to suggest find_files on FileNotFoundError.
- Add diagnostic logging for empty streams and empty results.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Introduces FileCache (OrderedDict LRU, st_mtime_ns validation) to avoid
redundant disk reads and duplicate content in conversation context.
Read tools return a short "[Cached]" message on cache hit instead of
resending unchanged file content, saving tokens. Write/edit/delete tools
invalidate affected paths; str_replace pre-warms the cache after edits.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove cat from allowed_commands to close shell redirect bypass vector
(read_file provides safer alternative). Update display tests to match
render_user_message returning Text instead of Panel, and shell test to
use head instead of cat.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The /no_think directive was appended directly to the user's message text,
causing the LLM to interpret it as user input (e.g., referencing it as a
directory path). Now injected as a separate system message after the last
user message. Also adds which, jq, type, and file to shell allowed_commands
(were mistakenly placed in permissions.auto_approve).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds `llm.thinking` config option (default: true) that when disabled:
- Injects /no_think into the last user message for Qwen 3.x compatibility
- Sends chat_template_kwargs in API payload for backends that support it
- Silently and immediately nudges on reasoning-only responses instead of
showing warnings and wasting retry iterations
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Allows passing arbitrary parameters (e.g., enable_thinking, reasoning_effort)
to the LLM API request body via config.yaml, solving reasoning-only response
loops with models like Qwen 3.x without requiring code changes per model.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implement the core autonomy layer — AgentLoop streams LLM responses,
parses tool calls, executes them with permission checks, feeds results
back, and repeats until the task completes or finish is called.
- Add FinishTool for explicit loop termination
- Add tools parameter to LLMClient.stream_chat() for function calling
- Add compact tool result display (status line, not full output)
- Refactor REPL to delegate to AgentLoop.run_turn()
- Fix Ollama null content rejection (always send content as string)
- Add finish to auto_approve permissions
- 9 unit tests for agent loop (34 total, zero regressions)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>