Not a chatbot. A colleague with tools.

An open-source LLM workspace: channels, schedules, answers that render. Ask one agent directly, or watch the team work — same agents, two surfaces.

Give it real tools

A tool is an async function with a decorator. The agent queries your systems rather than describing how it would.

Write a tool

MCP UI: answers, not paragraphs

Replies render as components — charts, tables, KPI cards — so a number arrives as a number, not a sentence about one.

See the blocks

A desk, not a browser tab

Shared channels with threads and history, and routines that file the morning read before anyone asks.

Serve a workspace

The same agents answer in Telegram, Slack and WhatsApp, and one line of config picks who does the thinking.

One install, either half

Runspace’s core is four dependencies. Everything else — a database, document rendering, Redis, a scheduler — is an extra you opt into.

Agents running in-process, with channels, routines and a UI around them.

$ pip install "runspace[agentino,workspace,server]"

The distribution is agentino-framework because the agentino name on PyPI belongs to an unrelated project. Both import under their own name.

Agentino

YAML for shape, Python for behaviour.

The things you change while tuning an agent — its prompt, its model, how many turns it gets — are configuration, and a colleague who does not write Python can own them. The things you change while building a capability are functions.

  • Tools are @tool-decorated async functions — no BaseTool ceremony
  • The docstring and type hints become the schema the model sees
  • ${VAR:-default} expands at load, so one file runs everywhere
Configuration reference
agents.yml
agents:
reviewer:
model: gpt-5.5
instructions_file: prompts/reviewer.md
tools: [read_file, grep, shell] # auto-discovered
knowledge:
dir: ./knowledge # TF-IDF + embeddings
$ agentino run agents.yml -m "Review PR #42"
Runspace

An LLM workspace in one file.

Declare the agents and Runspace gives you the room they work in: channels with threads and mentions, streaming chat, attachments, an activity feed and a scheduler. It starts with no database — SQLite on disk — and moves to Postgres by setting two variables.

  • Many agents in shared channels, reached by @mention
  • Threads, reactions, unread counts, soft deletes
  • Tenant-scoped throughout — one process serves many
Every workspace.yml field
workspace.yml
name: Acme Back Office
icon: 🗂
brand_color: '#2F5D62'
apps:
analyst:
name: Ada
soul: agents/analyst/SOUL.md
tools: agents/analyst/tools/
model: gpt-5.5
$ python -m runspace.workspace.serve workspace.yml
Framework-agnostic workspaces

Bring the harness you already use.

Runspace is not tied to Agentino. Five harnesses ship — Agentino, Claude Code, Codex, OpenClaw and pi — and an app picks one with a single line of config. The four CLI adapters shell out to a binary you install, so Runspace depends on none of them, and the workspace never learns which one answered.

  • A test reads the registry's source and fails if a runtime import appears
  • A sixth adapter is a new file, not a refactor
  • Same channels, same history, same UI, whichever runs the turn
Writing an adapter
runtimes
type: agentino # in-process
type: codex # codex exec --json
type: claude_code # claude -p --output-format stream-json
type: pi # pi --print
type: openclaw # openclaw agent --local --json
apps:
reviewer:
name: Rev
type: claude_code # the only line that changes
MCP UI

Answers that render as components.

MCP UI is the idea that a model should be able to answer with a component, not only with text. Runspace implements it as a small block vocabulary: the agent emits a fenced block naming a component and supplying the data, and the frontend — which the model never sees — renders a chart, a sortable table, KPI cards or a callout. A block with the wrong keys renders as a visible error rather than failing quietly, so the mistake shows up in development instead of in front of someone.

  • chart — ten types, from bar and line to sankey and treemap
  • datatable — with row links, expandable detail and per-row actions
  • kpi and insight — headline numbers and the one finding worth flagging
Block schemas
what the agent writes
```insight
{"kind": "insight",
"headline": "Most of the catalogue is unmeasured on latency",
"body": "339 of 396 listings publish no time to"
" first token. Unmeasured, not fast."}
```
```kpi
[{"title": "Models listed", "value": "396"},
{"title": "Latency measured", "value": "14%"}]
```
what the reader sees
Most of the catalogue is unmeasured on latency
339 of 396 listings publish no time to first token. Unmeasured, not fast.
Models listed
396
on OpenRouter
Latency measured
14%
57 have a published TTFT

Use it

Install both halves, serve a workspace, point an agent at your own tools. Apache-2.0, no hosted plan, nothing to sign up for.

Install

Build on it

Both repositories are public and both packages are on PyPI. The demo's source is public too, so you can read the whole thing before deciding whether the shape fits.