Project

airb

0.01
No release in over 3 years
airb is an open-source CLI programming agent that helps developers build software using modern LLMs (OpenAI, Anthropic, Gemini). Built on a clean, composable architecture inspired by Stafford Beer's Viable System Model, it features streaming responses, structured tool calling, built-in file operations, and optional web-based observability. Designed for hackability with small objects, clear seams, and UNIXy ergonomics.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
 Dependencies

Development

~> 3.13

Runtime

~> 0.1
 Project Readme

airb

An open-source, CLI-based programming agent for Rubyists.

🌌 Why use airb?

airb is an open‑source, CLI‑based programming agent for Rubyists. We built it to explore a clean, composable agent architecture grounded in cybernetics—specifically Stafford Beer's Viable System Model (VSM)—and to make a practical tool you can run in your terminal to read, list, and edit files with the help of modern LLMs.

In short:

  • A new spine for agents: Operations, Coordination, Intelligence, Governance, Identity—recursive, inspectable, testable.
  • A minimal, useful CLI that streams responses and uses structured tool calls (no fragile "JSON from text" parsing).
  • A foundation to learn from and extend: add tools, swap models (OpenAI/Anthropic/Gemini), plug in UI/observability, grow sub‑agents.

If you like small objects, clear seams, and UNIXy ergonomics, airb is for you.

🌌 Who benefits from airb?

  • Ruby developers who want a capable, hackable terminal agent that can actually work on a codebase.
  • Framework/tool authors exploring agent design (capsules, tools, sub‑agents) with high cohesion & low coupling.
  • Educators and teams who need a clear, auditable loop to reason about tool calling, streaming, and safety.
  • Researchers playing with agent recursion (sub‑agents, tool‑as‑capsule), budget homeostasis, and observability.

🌌 What does airb do?

A CLI programming agent that:

  • Streams assistant output to your terminal as it thinks.

  • Uses native, structured tool calling across providers:

    • OpenAI "tools" (functions) — streaming + parallel tool calls
    • Anthropic tool_use / tool_result — streaming (input_json_delta)
    • Gemini function calling — non‑streaming MVP (streaming later)
  • Ships with core programming tools (as capsules):

    • list_files(path?) — directory listing (dirs end with /)
    • read_file(path) — read UTF‑8 text files
    • edit_file(path, old_str, new_str) — replace/create with confirmation
  • Runs on a VSM engine (via the vsm gem):

    • Operations — dispatches tool calls; concurrency per tool
    • Coordination — session floor control & turn lifecycle
    • Intelligence — LLM driver + conversation + streaming
    • Governance — workspace sandbox, confirmations, budgets
    • Identity — purpose/invariants & escalation hooks
  • Provides observability from day one:

    • JSONL event ledger (.vsm.log.jsonl)
    • Optional web Lens (local SSE app) for live timelines

High‑level architecture

airb (top capsule)
├─ Identity        – name, invariants
├─ Governance      – sandbox, confirms, budgets
├─ Coordination    – floor control, turn end
├─ Intelligence    – driver(OpenAI/Anthropic/Gemini), streaming, tool loop
├─ Operations      – dispatch tools as child capsules (parallel)
│   ├─ list_files (tool capsule)
│   ├─ read_file  (tool capsule)
│   └─ edit_file  (tool capsule)
└─ Ports           – ChatTTY (CLI), Lens (web)

🌌 How to use it

Install

Requires Ruby 3.4+.

Add to your app or install globally:

# Using Bundler in a project
bundle add airb

# Or install gem globally
gem install airb

airb depends on the vsm gem (the agent runtime & drivers).

Configure a provider

Pick one provider and set env vars:

# OpenAI (streaming + tools)
export AIRB_PROVIDER=openai
export OPENAI_API_KEY=sk-...
export AIRB_MODEL=gpt-5-nano   # default if unset

# Anthropic (streaming + tool_use)
# export AIRB_PROVIDER=anthropic
# export ANTHROPIC_API_KEY=...
# export AIRB_MODEL=claude-sonnet-4-0   # default if unset

# Gemini (MVP: non-streaming tool calls)
# export AIRB_PROVIDER=gemini
# export GEMINI_API_KEY=...
# export AIRB_MODEL=gemini-2.5-flash    # default if unset

Quickstart

From the root of a Git repo:

airb

Sample session:

airb — chat (Ctrl-C to exit)
You: what's in this directory?
<streams…>
airb: README.md
      lib/
      spec/
      tmp/
You: open README.md
<streams…>
airb: (prints file contents)
You: replace the title with "Airb Demo"
<streams…>
confirm? Write to README.md? [y/N] y
<streams…>
airb: OK. Title updated.

Live visualizer (optional)

Start the local Lens web app (SSE):

VSM_LENS=1 airb
# Lens: http://127.0.0.1:9292

See live timeline & sessions: user messages, assistant deltas, tool calls/results, confirms, audits.

Configuration reference

Variable Meaning Default
AIRB_PROVIDER openai | anthropic | gemini openai
AIRB_MODEL Model name for chosen provider see examples above
OPENAI_API_KEY OpenAI auth —
ANTHROPIC_API_KEY Anthropic auth —
GEMINI_API_KEY Gemini auth —
VSM_LENS 1 to enable web Lens off
VSM_LENS_PORT Lens port 9292
VSM_LENS_TOKEN Optional access token (append ?token=...) none

Workspace: airb auto‑detects repo root (git rev-parse). If not a repo, it uses Dir.pwd.

What happens on each turn?

  1. You type text.
  2. Intelligence appends it to the conversation and calls the provider driver.
  3. The driver streams assistant text (assistant_delta).
  4. If the model needs a tool, the driver emits tool_calls → Operations routes to the proper capsule.
  5. The tool runs (in parallel, if multiple) and returns tool_result which is fed back to Intelligence.
  6. The model produces a final assistant message; Coordination marks the turn complete.
  7. Everything is emitted on the bus and logged; the Lens renders it live.

Provider behavior (at a glance)

Capability OpenAI Anthropic Gemini (MVP)
Streaming text âś… SSE âś… SSE (text_delta) âž– (planned)
Structured tool calls âś… tools/tool_calls âś… tool_use/tool_result âś… functionCall/Response
Parallel tool calls âś… supported âś… supported âś… supported
System prompt handling in messages header param (system) in content / safety opts

airb normalizes these differences so your CLI experience is the same.

Advanced Usage

Add your own tool (as a capsule)

Create a class that inherits VSM::ToolCapsule, describe its schema, implement #run.

# lib/airb/tools/search_repo.rb
class SearchRepo < VSM::ToolCapsule
  tool_name "search_repo"
  tool_description "Search files for a regex under optional path"
  tool_schema({
    type: "object",
    properties: { path: {type:"string"}, pattern:{type:"string"} },
    required: ["pattern"]
  })

  # Optional: choose how it executes (fiber/thread/ractor/subprocess)
  def execution_mode = :thread

  def run(args)
    root = governance.send(:safe_path, args["path"] || ".")
    rx   = Regexp.new(args["pattern"])
    matches = Dir.glob("#{root}/**/*", File::FNM_DOTMATCH).
      select { |p| File.file?(p) }.
      filter_map do |file|
        lines = File.readlines(file, chomp:true, encoding:"UTF-8") rescue []
        hits  = lines.each_with_index.filter_map { |line,i| "#{file}:#{i+1}:#{line}" if rx.match?(line) }
        hits unless hits.empty?
      end
    matches.flatten.join("\n")
  end
end

Register it in your organism under Operations:

operations do
  capsule :search_repo, klass: SearchRepo
end

The Intelligence system automatically advertises it to the model as a structured tool (OpenAI/Anthropic/Gemini shapes).

Create a sub‑agent (recursive capsule)

When a "tool" needs multiple steps (plan → read → patch → verify), make it a full capsule with its own 5 systems (Operations/Coordination/Intelligence/Governance/Identity). Expose it as a tool by including VSM::ActsAsTool and implementing #run(args) that orchestrates internally, then returns a summary.

This keeps the parent simple while the sub‑agent stays cohesive and testable.

Concurrency & performance

  • The runtime uses async fibers for orchestration and streaming.
  • Each tool call runs in its own task; set execution_mode to :thread for CPU‑heavier work.
  • Governance can add timeouts and semaphores to limit concurrent tool calls.

Safety & governance

  • airb runs in a workspace sandbox (repo root or CWD).
  • edit_file prompts for confirmation before writing.
  • You can extend Governance to show diffs, enforce allowlists, or budget tokens/time.

Troubleshooting

  • "No streaming" — Gemini driver is MVP (non‑streaming). Use OpenAI/Anthropic for streaming.
  • "Path escapes workspace" — Governance blocked a write; run airb from the repo root or adjust logic.
  • "No tool calls" — Ensure your provider key & model are set; some models require enabling tools.
  • Lens shows nothing — Start with VSM_LENS=1, then open http://127.0.0.1:9292.

Table of Contents

  • Why use airb?
  • Who benefits from airb?
  • What does airb do?
  • How to use it
    • Install
    • Configure a provider
    • Quickstart
    • Live visualizer
    • Configuration reference
    • Provider behavior
  • Advanced Usage
    • Add your own tool
    • Create a sub-agent
    • Concurrency & performance
    • Safety & governance
  • Troubleshooting
  • Roadmap
  • Contributing
  • License
  • Acknowledgements

Roadmap

  • Streaming for Gemini driver
  • Diff previews & undo for edit_file
  • MCP client/server ports (tool ecosystem)
  • "Command mode" (airb -e "…") for one‑shot automation
  • Rich Lens (search, replay, swimlanes, token counters)
  • Additional built‑in capsules (planner, tester, editor)

Contributing

Bug reports, ideas, and PRs welcome!

  • Please keep code SRP‑friendly, name things clearly, and favor composition over inheritance.
  • Tests for drivers should include small fixture streams → expected events.

License

MIT (same as vsm), unless noted otherwise in subdirectories.

Acknowledgements

  • Inspired by Stafford Beer's Viable System Model and the broader cybernetics community.
  • Thanks to the Ruby OSS ecosystem for gems like async that make structured concurrency practical.
  • Early discussions about good agent loops, tool use, and safety shaped this project.