Skip to content

Research: features to learn from OpenHands, Open Interpreter, and OpenCode #43

Description

@zjshen14

Overview

Competitive research across three open-source coding agents to identify features worth adopting in OpenCLI. Findings are grouped by source tool, then by implementation priority.


OpenHands (All-Hands-AI/OpenHands)

OpenHands' thesis is event sourcing + optional isolation = production-ready agents. It solves long-horizon problems that CLI agents mostly sidestep.

Architecture

  • Event-sourced state: every interaction is an immutable event appended to an EventLog. Enables deterministic replay, cost analysis, and fault recovery without special-case logic.
  • Three-component model: Agent (stateless, emits Actions from history) + Conversation (stateful, drives loop, persists EventLog) + Workspace (executes Actions, returns Observations).
  • Workspace abstraction: LocalWorkspace / DockerWorkspace / RemoteWorkspace are swappable — the same agent code runs locally or in a container without modification.

Stuck Detection (5 semantic patterns)

OpenHands detects loops semantically (ignoring timestamps/IDs), not just by retry count:

  1. Repeating cycles — same action-observation pair 4+ times
  2. Error loops — identical action fails 3+ times
  3. Agent monologues — 3+ consecutive model messages without user input
  4. Alternating ping-pong — two action-observation pairs alternate 6+ times
  5. Context window errors — memory pressure triggers its own recovery path

OpenCLI currently aborts after 3 identical consecutive call signatures (core.ts:STUCK_THRESHOLD). Adopting patterns 2–5 would catch loops the current check misses.

Context Compression

Pluggable condenser strategies (relevant to issue #26):

Strategy Behaviour
NoOpCondenser No compression (testing)
LLMSummarizingCondenser Summarises the middle of the event log when event count > threshold (default: 120)
LLMAttentionCondenser Ranks events by importance, keeps top-N without generating a summary
PipelineCondenser Chains multiple condensers sequentially

Key differentiator: the model can call a request_condensation tool itself when it senses context pressure — rather than waiting for a hard external threshold. Result: ~2× per-turn cost reduction after compaction activates; 54% SWE-bench solve rate maintained.

Skill System

Two skill types not present in OpenCLI:

  • Knowledge agents (keyword-triggered): activate when specific keywords appear anywhere in the conversation — no slash command needed. Examples: git.md activates on "git", docker.md on "docker", pr_review.md on "pull request".
  • Repository agents (always-loaded): project-specific guidelines in .openhands/skills/; loaded automatically for every session in that project.

Security

Risk assessment is separated from enforcement:

  • LLMSecurityAnalyzer — annotates actions with risk level (LOW / MEDIUM / HIGH / UNKNOWN)
  • PatternSecurityAnalyzer — deterministic pattern matching for known threat signatures
  • EnsembleSecurityAnalyzer — combines multiple analyzers, takes the highest risk rating
  • ConfirmationPolicy — separate from analyzers; AlwaysConfirm, NeverConfirm, ConfirmRisky

OpenCLI has the HITL gate (executor layer) but no risk classification layer upstream of it.


Open Interpreter (OpenInterpreter/open-interpreter)

Open Interpreter treats the agent as a local computational agent with maximal capabilities and transparency, prioritising user control over safety constraints.

Edit-Before-Run Confirmation

Three-choice HITL prompt before every code execution:

  • y — execute immediately
  • n — decline; sends refusal back to LLM so it can try something else
  • e — open code in $EDITOR before execution (user modifies, then runs)

The e path is the standout: users can inspect and correct agent-generated code without breaking the agent loop. OpenCLI's current HITL is binary (allow / deny).

Loop Breaker Strings

Configurable list of phrases that signal task completion:

"The task is done."
"The task is impossible."
"Let me know what you'd like to do next."

The agent runs until one of these strings appears in LLM output. Cleaner termination contract than relying on the model producing no tool calls.

Magic Commands (session control without interrupting the loop)

Command Effect
%undo Remove last user message and model response
%reset Clear session history
%tokens Estimate API cost for the current session
%jupyter Export session as a Jupyter notebook
%markdown Save session as markdown
%%[shell] Direct shell access (double percent)
%verbose Show current message state
%info System and interpreter details

OpenCLI has /plan, /help; no session-control commands.

Budget Cap

--max_budget <USD> — hard cost ceiling that stops the agent before it exhausts budget. Pairs naturally with a cost-tracking command to show running spend.

Profile System

YAML/JSON/Python profiles at ~/.oi/profiles/ (default: default.yaml). Users switch profiles with --profile. Profiles encode model, temperature, system message, auto_run, etc. A version field triggers migration prompts for older profiles.

Auto-Saved Conversation History

Every conversation automatically dumped to a timestamped JSON file in ~/.oi/conversations/. OpenCLI has JSONL session logs but requires an explicit --resume flag to use them.


OpenCode (opencode.ai / sst/opencode)

OpenCode is the most directly comparable to OpenCLI — a TypeScript CLI agent. Its thesis is persistent server + multi-model routing = flexible, remote-controllable agent.

Persistent Server Architecture

opencode serve starts a local HTTP server; TUI, web, IDE extensions, and the SDK all connect as clients. Enables:

  • Close the terminal and reconnect later without losing state
  • Control the agent from a phone/tablet via the web UI
  • Multiple clients (TUI + IDE) watching the same session simultaneously
  • Headless execution in CI

Multi-Model Routing Per Phase

Five specialised model roles, each optionally mapped to a different LLM:

Role Purpose
Normal Standard tool execution
Thinking Planning and complex reasoning
Self-critique Reflection before acting
Vision Image/screenshot analysis
Compaction Context summarisation

Using a cheap fast model for simple tool calls and an expensive model only for planning cuts costs without sacrificing quality.

Self-Critique Phase in the Agentic Loop

Extended ReAct loop: Think → Critique → Act rather than just Think → Act. The critique phase runs a reflection pass on the proposed plan before executing it, catching obvious mistakes early.

Event-Driven System Reminders

Context-aware behavioral guidance injected at decision points to counteract instruction fade-out (models forgetting earlier constraints in long sessions). OpenCLI has basic reminders after edit/write; OpenCode applies this pattern more broadly across the loop.

Context Compaction

Auto-compaction triggers at 95% of context window using a dedicated compaction agent. OpenCLI currently hard-drops history at maxHistoryMessages. OpenCode's approach preserves semantic continuity.

Dual-memory architecture: episodic memory (conversation history) and working memory (current reasoning state) managed separately — working memory is never pruned.

LSP Integration

20+ Language Server Protocol servers (TypeScript, Python, Go, Rust, Ruby, C/C++, C#, Elixir, Zig, Java, Vue, Svelte) auto-downloaded on first use. Provides:

  • Go-to-definition
  • Find references
  • Call hierarchy
  • Diagnostics (type errors, lint)
  • Hover info

Navigation via grep is O(n) and syntactically blind; LSP is O(1) and semantically correct.

5-Layer Defense in Depth

Layer Mechanism
1 Prompt-level guardrails (security policies in system instruction)
2 Schema-level restrictions (Plan Mode tool whitelist, per-subagent filtering)
3 Runtime approval system with persistent permissions
4 Tool-level validation (dangerous pattern detection, timeouts)
5 User-defined lifecycle hooks

OpenCLI has Layer 3 (HITL gate). Layers 1, 2, 4, 5 are absent or partial.

GitHub Actions Integration

Mentioning /opencode in a GitHub issue or PR comment triggers an automated agent workflow via GitHub Actions — triage, fix, or code review — without a local session. The agent posts results back as a comment.

Plugin Hook System

Plugins are JS/TS modules in .opencode/plugins/ or ~/.config/opencode/plugins/. They receive lifecycle hooks:

  • onToolExecution — intercept/modify tool calls
  • onFileOperation — react to file reads/writes
  • onMessage / onSession — session lifecycle
  • onPermission — custom permission logic
  • onShellOperation — shell command interception

Hooks are more powerful than skills — they run code, not just inject prompts.


Priority Feature Backlog

Ordered by value-to-effort ratio for OpenCLI specifically:

Quick wins (low effort, high value)

  • /undo command — remove last user message + model response from history
  • Cost tracking + budget cap — running token/cost estimate per session; hard --max-budget ceiling
  • Improved stuck detection — add OpenHands' 5 semantic patterns to complement the current signature check in core.ts

Medium effort, high value

  • Keyword-triggered skill activation — activate skills when keywords appear in conversation, not only on explicit /skill invocation (OpenHands knowledge agents)
  • LLM-triggered context compactionrequest_condensation tool so the model decides when to summarise (feeds into Feature: context compaction via LLM summarization instead of hard-dropping history #26)
  • Edit-before-run in HITL — add e (edit in $EDITOR) as a third HITL choice alongside allow/deny
  • Profile system — named YAML configs switching model, temperature, system message per use case

High effort, high value

  • Self-critique phase — add a reflection pass before tool execution in the agentic loop
  • Multi-model routing — map different agent phases (thinking, compaction, execution) to different models
  • LSP integration — semantic code navigation (go-to-definition, find-references, diagnostics)
  • GitHub Actions integration/opencli in issue/PR comments triggers an agent workflow

Sources

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentation

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions