Skip to content

megagonlabs/abra

Repository files navigation

ABRA: Agent-Bound, Readable Interactions over Reusable Views

EMNLP 2026 demo submission. This README covers running and configuring the prototype; the interaction model itself is described in the paper.

ABRA is a reference prototype of Agent-Bound UI: agents and users collaborate over a fixed catalogue of interactive views (graph, table, text, display), with agents binding task meaning onto the views and publishing it as shared canvas state. In this codebase, a Node.js hub (apps/hub/) holds canvas state and synchronizes it; a Vite + React client (apps/demo/) renders the views and a chat panel; Python adapters (adapters/) run the agents. The view implementations, canvas schema, and shared state-reduction are the three packages/ (abra-views, abra-spec, abra-reducer).

🚀 Quickstart

Prerequisites. Node.js ≥ 24 (with corepack for pnpm) and Python ≥ 3.11 (with uv).

# 1. Install the JS workspace and the Python adapters
corepack enable && pnpm install
uv venv && uv pip install -e ".[dev,agent]"

# 2. Configure (the default cast runs on Anthropic; see "API Keys" below)
export ANTHROPIC_API_KEY="sk-ant-..."

# 3. Run the whole demo from one command (Ctrl-C stops all three processes)
pnpm demo

pnpm demo starts the hub (ws://localhost:8787), the agent host, and the UI, then prints the UI's URL. Open it in your browser.

🖥️ Using it

  • A browser tab is one session. Its id is the ?s=… in the URL. The agent host spawns the default cast (Mapper, Analyst, Media, Editor) into each session automatically.
  • Open another tab for a separate, isolated session (its own cast, its own canvases). Share a tab's URL to collaborate in the same session, or use Start fresh in the top bar to mint a clean session in the current tab.
  • Type in the chat panel. The agents answer you, reply when you @mention them, and create canvases on request. On a canvas you can act directly (on a graph: reposition, connect, drag-to-merge; on a table: edit cells); hover a canvas's info affordance to read what each action does. If an agent adds controls to a canvas (buttons, toggles), they appear in that canvas's header.
  • Follow the links between views. Hovering an element highlights the same entity across the other open canvases (brushing-and-linking); an agent's chat message can carry {ref} chips that, on hover, light up the exact element they point to.
  • Change the cast live. The participants popover lists who is in the session (with each agent's status: online, working, or crashed); you can remove an agent, restart a crashed one, or add any agent that is defined in adapters/roster.toml but not in the default cast.
  • Arrange the canvases. A side rail lists the live canvases; toggle each one's visibility (the eye) and reorder them with ↑/↓. This is your own view only (client-local): hiding a canvas does not close it, and the owning agent is unaffected.

To run the three processes separately instead of via pnpm demo:

pnpm --filter hub start                       # the hub
pnpm --filter demo dev                        # the UI
.venv/bin/python -m adapters.host             # the agent host (the whole roster)

🔑 API Keys

Set as environment variables before launching. A .env file at the repository root is also read by pnpm demo.

  • ANTHROPIC_API_KEY: required by the default cast (the four agents are Anthropic-backed). Get one at https://console.anthropic.com/.
  • OPENAI_API_KEY / FIREWORKS_API_KEY: only if you enlist OpenAI- or Fireworks-backed agents (see below).
  • GOOGLE_API_KEY + GOOGLE_CSE_ID: only for the web_search custom tool (Google Programmable Search).

No Anthropic key, only OpenAI? Switch the cast to OpenAI-backed agents in adapters/roster.toml: give the custom agents provider = "openai" (install .[custom-openai]), or enlist the openai_agents_sdk agent (install .[openai]). Set OPENAI_API_KEY and run pnpm demo as usual.

No web-search key? The demo still runs, and you do not need to disable anything. web_search is not auto-removed: it stays offered to the agents, and a call without the keys returns an error that the agent recovers from (it falls back to the keyless tools). The other custom tools (Wikipedia, geocoding, calculator, Python, datetime) need no key, and the SDK-based agents (claude_agent_sdk, openai_agents_sdk) have their own hosted web search that does not use the Google key. To hide it entirely, drop "web_search" from the agents' tools in adapters/roster.toml.

🧩 Configuring the cast

The roster lives in adapters/roster.toml. Define agents under [agents.<key>] (type, model, prompt, tools, provider, optional one-line blurb) and list which of them run in active. Defining an agent does not enlist it: only the keys in active spawn, so you can keep a library and switch the subset freely. Four agent frameworks ship, each driving the same shared canvases through the tool interface:

Type Framework Extra to install
custom a hand-rolled loop, across providers (anthropic / openai / fireworks) .[agent] (Anthropic) or .[custom-openai] (OpenAI-format)
claude_agent_sdk the Claude Agent SDK (also needs the Claude Code CLI on $PATH) .[claude-sdk]
langgraph LangGraph 1.x on a hand-built StateGraph .[langgraph]
openai_agents_sdk the OpenAI Agents SDK .[openai]

To run a single agent against one session by hand (the --session id is the ?s=… value from the UI's URL):

.venv/bin/python -m adapters.run --type custom --name Bob --session <session-id>

🗂️ Repository Layout

abra-release/
├── package.json                  pnpm workspace root (Node ≥ 24)
├── pyproject.toml                Python adapters (uv pip install -e ".[dev,agent]")
├── packages/
│   ├── abra-views/               React view implementations + manifests (graph, table, text, display)
│   ├── abra-spec/                canvas + message JSON-Schema + generated JS/Python types
│   └── abra-reducer/             shared canvas-state reduction (hub + client replica)
├── apps/
│   ├── hub/                      Node.js canvas hub (sessions + state sync)
│   ├── demo/                     Vite + React client + one-command launcher
│   └── playground/               in-process views + reduction bench (no hub)
├── adapters/                     Python agents (four frameworks) + multi-session host
│   ├── host.py · run.py          run the whole roster · run a single agent
│   ├── roster.toml               the cast
│   ├── agents/ · common/ · tools/  agent types · bridge/reduction/tools · custom tools
└── scripts/                      demo launcher + codegen

🛠️ Development

pnpm gen              # regenerate the JS/Python types from the JSON-Schema source (committed)
pnpm gen:check        # verify the committed mirrors match the schema
pnpm typecheck        # tsc --noEmit over the typed packages
pnpm lint             # biome
pnpm playground       # views + reduction bench, no hub

Tested environment. macOS 15 (Darwin 24.4) on Apple Silicon with Node.js 24 and Python 3.11. No GPU required. Internet access is required for the agents' LLM calls and for tools that reach the web.

📄 License

This project is licensed under the BSD 3-Clause License. See the LICENSE file for details.

Disclosures:

This software may include, incorporate, or access open source software (OSS) components, datasets and other third party components, including those identified below. The license terms respectively governing the datasets and third-party components continue to govern those portions, and you agree to those license terms may limit any distribution, use, and copying. You may use any OSS components under the terms of their respective licenses, which may include BSD 3, Apache 2.0, and other licenses. In the event of conflicts between Megagon Labs, Inc. ("Megagon") license conditions and the OSS license conditions, the applicable OSS conditions governing the corresponding OSS components shall prevail. You agree not to, and are not permitted to, distribute actual datasets used with the OSS components listed below. You agree and are limited to distribute only links to datasets from known sources by listing them in the datasets overview table below. You agree that any right to modify datasets originating from parties other than Megagon are governed by the respective third party's license conditions. You agree that Megagon grants no license as to any of its intellectual property and patent rights. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS (INCLUDING MEGAGON) "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. You agree to cease using, incorporating, and distributing any part of the provided materials if you do not agree with the terms or the lack of any warranty herein. While Megagon makes commercially reasonable efforts to ensure that citations in this document are complete and accurate, errors may occur. If you see any error or omission, please help us improve this document by sending information to contact_oss@megagon.ai.

Datasets

No third-party datasets are bundled in this release. Third-party software dependencies are declared in package.json and pyproject.toml and remain governed by their respective OSS licenses.

About

Code for ABRA: Agent-Bound, Readable Interactions over Reusable Views (EMNLP 2026 Demo Submission)

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages