Skip to content

v0.5.0

Choose a tag to compare

@themartto themartto released this 06 Jul 07:00
· 168 commits to main since this release
f5ce4da

Security

  • /ws filesystem sidecar is now sandboxed to work_dir — previously any connected WebSocket client could read/write/delete arbitrary directories by choosing its own root in watch, bypassing the agent's sandbox. All fs operations now validate against work_dir using the same path validator (with symlink canonicalization) as the built-in file tools.
  • Subagents (delegate_task) no longer bypass session/request_permission. Subagents previously ran with a hardcoded always-allow gate — an unconditional permission bypass in interactive ACP sessions. They now inherit the parent turn's real permission gate and cancellation token.
  • "Allow Always" on a shell command no longer approves every future shell command. Remembered decisions were keyed by tool name only, so approving git status once silently pre-approved any later execute_command, including destructive ones. Shell approvals are now scoped by the command's program name.

Changed (WS protocol)

  • watch no longer sets the fs validation root — it only enables fs_event notifications; the watched directory must be within work_dir.
  • fs operations no longer require a prior watch — they work immediately, validated against work_dir.
  • fs error messages now return the validator's descriptive message instead of a generic one.

Added

  • Tool-call permission requests via session/request_permission, with remembered Allow/Reject Always decisions.
  • TUI permission prompts — the terminal UI now asks before running any tool call (execute_command included) instead of auto-allowing.
  • SessionHandle::permission_gate / .client_io — embedders can supply a custom permission gate and client-side file I/O per session.
  • SessionHandle::cancel() — cancel an in-flight turn from the library facade.
  • OpenheimBuilder::tool(...) — register custom in-process tools when embedding openheim as a library.
  • session/cancel actually cancels a running turn — prompt turns now run in a spawned task with cancellation checked between iterations and before tool calls.
  • Session modessession/set_mode supports code (full access) and architect (read-only).
  • Client-side filesystem delegationread_file/write_file delegate to the ACP client's fs/* methods when advertised.
  • GET /acp WebSocket endpoint — bare ACP JSON-RPC endpoint alongside /ws.
  • Image content in prompts — vision support for Anthropic, OpenAI, and Gemini; ResourceLink blocks become text hints; Audio/embedded Resource now error clearly instead of being dropped.
  • New public APIs: StreamEvent::MessageAppended, HistoryManager::append_message, AppConfig::resolve_provider_default.

Fixed

  • openheim run could hang or falsely deny every tool call due to a response-routing bug in the ACP dispatch handler.
  • Anthropic extended thinking was effectively broken end-to-end (wrong beta-header gating + budget_tokens 400s on current-gen models) — switched to adaptive thinking.
  • Thinking blocks were never replayed back to Anthropic, breaking the required tool-call round trip.
  • session/cancel no longer waits out an in-flight LLM request.
  • Exhausting max_iterations was misreported to ACP clients as a normal EndTurn.
  • Overlapping session/prompt calls on the same session could race and corrupt history/cancellation state.
  • Non-streaming Anthropic calls (subagents) never got extended thinking.
  • GET /api/sessions/{id} could 404 for the wrong reason.
  • TUI discarded the real startup error, flattening typed errors into opaque strings.
  • openheim init shipped stale default models, drifted from the programmatic defaults.
  • session/load restored sessions with an unvalidated, hand-assembled provider config.
  • GET /api/sessions endpoints did blocking file I/O on the async runtime.
  • History durability — a crash mid-turn no longer loses the whole turn; a crash mid-save can no longer corrupt previously-saved conversations (append-only .jsonl log + atomic writes).

Breaking changes (library)

  • SandboxedExecutor::new takes an additional client_io: Arc<dyn ClientIo> argument.
  • run_agent_with_history / run_agent_streaming_with_history take a &TurnContext.
  • TurnContext moved from core::agent to core::turn.
  • tools::ToolExecutor::execute gained a turn: &TurnContext<'_> parameter; DelegateTool no longer implements ToolHandler.
  • acp::AgentState::new takes an additional custom_tools argument.
  • StreamEvent::ToolCall/ToolResult gained an id field.
  • core::models::Message redesigned around content blocks (Vec<ContentBlock> replaces the flat fields); ChatRequest/ChatResponse/ToolCall/FunctionCall removed from core::models.
  • AgentResult gained stop_reason: StopReason.
  • acp_prompt returns Result<StopReason>; AgentState::is_session_cancelled removed.
  • SessionState gained prompt_lock.
  • No migration path for existing history — pre-upgrade ~/.openheim/history/*.json files fail to load.
  • `{WsRequest,