neo

neo logo

neo is a Rust coding-agent harness for long-running autonomous software work.

Core Capabilities

Build

$HOME/.cargo/bin/cargo test
$HOME/.cargo/bin/cargo build

Install

One-line installer for the current private repo:

gh api -H "Accept: application/vnd.github.raw" repos/AgentsLabs/neo/contents/install.sh | bash

This requires gh auth login first.

If the repository is later made public, the raw curl form also works:

curl -fsSL https://raw.githubusercontent.com/AgentsLabs/neo/main/install.sh | bash

Manual install with Cargo:

$HOME/.cargo/bin/cargo install --git https://github.com/AgentsLabs/neo.git --branch main --locked --force

Useful installer overrides:

REPO_URL=https://github.com/AgentsLabs/neo.git BRANCH=main INSTALL_ROOT=$HOME/.local curl -fsSL https://raw.githubusercontent.com/AgentsLabs/neo/main/install.sh | bash

After install, ensure your path includes the install root:

export PATH="$HOME/.local/bin:$PATH"

Quick Start

$HOME/.local/bin/neo

Run from source:

$HOME/.cargo/bin/cargo run

Useful commands:

TUI behavior:

Feature flags:

Help

Show built-in help:

neo --help
neo --version

Inside the interactive shell:

Common startup options:

neo --config-file neo_config.json
neo --workspace .
neo --provider ollama --model lfm
neo --provider ollama-cloud
neo --provider openai-codex --model gpt-5.3-codex
neo --cdp --cdp-discovery-url http://127.0.0.1:9222 --search
neo --tui
neo --ralph
neo --resume-session <session-id>
neo --gateway-daemon --gateway-bind 127.0.0.1:8787

Config

neo loads neo_config.json from the workspace when present. Fallback order is:

  1. neo_config.json
  2. config.json

Example:

{
  "provider": "ollama",
  "model": "lfm",
  "workspace": ".",
  "autonomous": true,
  "max_tool_rounds": 12,
  "search_enabled": true,
  "ralph": true,
  "ralph_max_iterations": 8,
  "ralph_fresh_session": true,
  "ralph_verify_commands": ["cargo test"],
  "gateway_bind": "127.0.0.1:8787",
  "gateway_autorun": false,
  "gateway": {
    "enabled": true,
    "default_agent": "main",
    "bindings": [
      {
        "agent_id": "support",
        "channel": "slack",
        "peer_kind": "group",
        "peer_id": "C123"
      }
    ]
  },
  "browser": {
    "enabled": true,
    "discovery_url": "http://127.0.0.1:9222",
    "default_timeout_ms": 15000
  }
}

Gateway Model

The gateway layer is host-controlled. neo includes:

Gateway daemon:

neo --gateway-daemon --gateway-bind 127.0.0.1:8787

HTTP endpoints:

Example ingest:

curl -X POST http://127.0.0.1:8787/ingest \
  -H 'Content-Type: application/json' \
  -d '{
    "envelope": {
      "channel": "slack",
      "account_id": "workspace-1",
      "peer_kind": "group",
      "peer_id": "C123",
      "thread_id": "T456"
    },
    "message": "hello from gateway daemon",
    "autorun": false
  }'

Persistence:

Channel Config

Channel routing is configured under gateway.bindings in neo_config.json.

Binding fields:

Supported peer_kind values:

Matching rules:

Session-key behavior:

Minimal example:

{
  "gateway": {
    "enabled": true,
    "default_agent": "main",
    "bindings": [
      {
        "agent_id": "support",
        "channel": "slack",
        "peer_kind": "group",
        "peer_id": "C123"
      }
    ]
  }
}

Multi-channel example:

{
  "gateway": {
    "enabled": true,
    "default_agent": "main",
    "bindings": [
      {
        "agent_id": "ops",
        "channel": "slack",
        "account_id": "workspace-1",
        "peer_kind": "group",
        "peer_id": "COPS"
      },
      {
        "agent_id": "support",
        "channel": "discord",
        "peer_kind": "channel",
        "peer_id": "998877"
      },
      {
        "agent_id": "dm",
        "channel": "telegram",
        "peer_kind": "direct"
      }
    ]
  }
}

How to think about each peer_kind:

Ingress example by peer kind:

{
  "envelope": {
    "channel": "slack",
    "account_id": "workspace-1",
    "peer_kind": "group",
    "peer_id": "C123",
    "thread_id": "T456"
  },
  "message": "hello from channel config docs",
  "autorun": false
}

Recommended pattern:

  1. Set default_agent to main.
  2. Add the most specific bindings first.
  3. Use account_id when one transport serves multiple tenants.
  4. Use group or channel for any surface where context must stay isolated per room.
  5. Leave autorun off until you trust the routing and session isolation behavior.

Browser Control

The browser runtime is CDP-backed and enabled with --cdp or browser.enabled=true. It currently supports:

Ralph Loop

The Ralph supervisor loop is an outer loop around the inner tool loop.

Run the local loop wrapper:

scripts/ralph-loop.sh prd.json

If prd.json has a features array, the script runs one feature per Ralph invocation; otherwise it uses objective.

What it does:

Relevant config keys:

Worker Model

Workers run in isolated worktrees:

Harness Review

Strengths:

Gaps:

Recommended next steps:

  1. Add an append-only Ralph run ledger with per-iteration summaries and artifacts.
  2. Add transport adapters and a richer control plane on top of the daemon.
  3. Upgrade browser targeting from coordinates to snapshot/reference-based interactions.
  4. Add run leases, heartbeats, and cancellation semantics.
  5. Add compaction and memory-budget policies between Ralph iterations.
  6. Add queueing and lane controls for concurrent routed sessions.

Validation

$HOME/.cargo/bin/cargo test