Assistant message panels now use Markdown() instead of raw strings, so
bold/italic/lists render properly. Also nudge the model immediately after
tool errors instead of wasting 2 retry iterations in reasoning-only mode.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
push_screen_wait requires a worker context, but on_mount is a plain
lifecycle callback. Extract session resume logic into a @work-decorated
method so the modal can be awaited without triggering NoActiveWorker.
The streaming widget shows content during streaming then hides on
completion, but nobody was writing the final response to the RichLog.
The assistant message flashed briefly then disappeared.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The App base class uses _registry (WeakSet) for DOM node tracking.
Our _registry attribute for the tool registry was shadowing it with None,
causing a TypeError during shutdown.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implement 6 new agent tools — write_file, make_dir, delete_file,
str_replace, patch_apply, run_command — bringing the agent from
read-only observer to active code modifier. All write/shell operations
are gated through the existing permissions service.
Also fix a bug where qwen3.5 thinking mode produces reasoning tokens
but no content after tool results, causing the agent to silently exit.
The loop now detects reasoning-only responses, retries twice, then
injects a nudge message to break the model out of its thinking loop.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
resolve_safe_path now detects when the LLM passes the workspace root as
a relative path (e.g. "home/user/project/file.py") and strips the prefix
before joining. Also updated the system prompt to explicitly instruct the
model to use relative paths for all tool arguments.
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>
Wire the REPL to a local Ollama instance via streaming HTTP (SSE).
LLMClient handles async streaming chat, StreamHandler renders live
Markdown via Rich and accumulates tool call fragments. Startup now
runs a preflight check that verifies Ollama is reachable and the
configured model is pulled, exiting with a clear message on failure.
Also adds .gitignore and updates config to use qwen3.5.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>