Skip to content

v0.9.0

Choose a tag to compare

@themartto themartto released this 01 Sep 05:38
· 83 commits to main since this release
2dd5fec
  • Four new built-in tools: web_fetch, list_dir, search, edit_file. web_fetch fetches a public http(s) URL and returns its content as text (HTML stripped of markup); it's hardened against SSRF (loopback/private/link-local/cloud-metadata addresses rejected, resolved address pinned against DNS rebinding), doesn't follow redirects automatically, and is bounded by a 20s timeout and a 256 KiB response cap. list_dir lists a directory's immediate contents, capped at 500 entries. search is a regex search across files, ripgrep-style — built on ripgrep's own crates (grep-searcher/grep-regex/ignore) rather than shelling out to an rg binary, so it works regardless of allow_shell and respects .gitignore; capped at 200 matches. edit_file replaces an exact string in a file without rewriting the whole thing (old_string/new_string, must be unique unless replace_all is set). list_dir, search, edit_file are sandboxed to work_dir the same way read_file/write_file are; list_dir and search were also added to architect mode's read-only allowlist alongside read_file. read_file/write_file/edit_file continue to delegate to an ACP client's client_io when available (edit_file uses it for both the read and the write). ACP clients now also get proper ToolKind hints for all four (Read/Search/Fetch/Edit) instead of falling back to Other.
  • Tool calls within a single LLM turn now run concurrently instead of one after another — most usefully, multiple delegate_task subagents batched into one turn now execute in parallel, with permission checks and cancellation handled the same way. Message order in conversation history is unaffected.
  • Tool-call results are now reported to the caller as soon as each one finishes, instead of after the whole batch completes — in an ACP session, a fast tool call among several concurrent ones now shows as Completed/Failed right away instead of waiting behind a slower one. (The TUI's own tool-call list doesn't yet take advantage of this — it isn't wired to match a result back to its originating call by ID — so this mainly benefits ACP clients for now.)
  • Context-size tracking. Every LlmClient provider (Anthropic, OpenAI, OpenAI-compatible, Gemini) now parses token usage off its raw response — streaming included, via Anthropic's message_start/message_delta events, OpenAI's stream_options.include_usage, and Gemini's usageMetadata — and the agent loop keeps a snapshot of the most recent call's usage as AgentResult::context_usage (how full the context window is right now, not a running total, since every call resends the full history as its prompt). It's persisted on ConversationMeta.context_usage, updated only when a provider reports usage and otherwise retaining its previous snapshot (including when cancellation follows a reported LLM call), and readable without an active session via GET /api/sessions/{id} or OpenheimClient::get_session. SessionHandle::context_usage() gives embedders a direct read. The TUI shows it live in the input bar footer (e.g. 8.4k ctx), refreshed after each turn and on session switch.