Bub is a tiny runtime for agents that live alongside people.
~200 lines of core code. Hooks reshape every turn stage. Tapes record every decision. Channels adapt to any surface — CLI, Telegram, or your own.
import bub
@bub.hookimpl
def build_prompt(session, tape):
"""Reconstruct context from tape records."""
messages = [{"role": "system", "content": session.system}]
for record in tape.entries:
messages.append({
"role": record.role,
"content": record.content,
})
return messages
@bub.hookimpl
def run_model(messages, config):
"""Call the LLM — override to swap providers."""
return litellm.completion(
model=config.model,
messages=messages,
) Features
Every decision has a reason.
Bub was designed for real multi-agent collaboration from day one — not retrofitted for it.
Hook-First
~200-line core. Every turn stage is a pluggy hook. Builtins are just default plugins — override any stage without forking the runtime.
Tape Context
Context is reconstructed from append-only tape records, not accumulated in session state. No lossy summaries, no phantom memory.
Channel-Agnostic
The same process_inbound() pipeline drives CLI, Telegram, and any channel you add. Hooks never know which surface they're on.
Batteries Included
CLI, chat, gateway, comma commands, and the default agent runtime all ship as ordinary plugins. Useful on day one, replaceable when you need control.
Operator Equivalence
Humans and agents share the same operator model: same boundaries, same evidence trails, same handoff semantics. No special cases.
Plugin System
Python entry-points under group="bub". Later-registered plugins run first and override earlier ones. No framework privilege.
Architecture
Hooks define every turn stage.
Every stage in a Bub turn is a pluggy hook. The built-in implementation is just another plugin.
Override any stage by registering your own. Later plugins take priority. No forking, no framework privilege.
| time | op | key | payload | |
|---|---|---|---|---|
| 14:32:01 | user_msg | e_101 | "explain hooks" | |
| 14:32:02 | build_prompt | e_102 | system + 12 msgs | |
| 14:32:04 | model_reply | e_103 | "Hooks are pluggy…" | |
| 14:32:04 | tool_call | e_104 | read_docs("hooks") | |
| 14:32:05 | tool_result | e_105 | {ok: true, lines: 47} | |
| handoff phase → correction, owner: agent | ||||
| 14:32:06 | correction | e_106 | ← e_103 supersedes e_103 | |
| 14:32:07 | model_reply | e_107 | "Updated: Hooks use pluggy…" | |
| 14:32:08 | save_state | e_108 | tape flushed ✓ | |
Context model
Tape: a unified fact model.
Context isn't accumulated in session state. It's reconstructed from an append-only tape — a sequence of immutable facts. Entries record what happened; anchors mark phase boundaries and carry structured state.
Corrections append new facts that supersede old ones — never overwrite. Views are assembled from anchors forward, not inherited wholesale. Every decision is auditable, replayable, and forkable.
Community
What people are saying.
使用 bub 作为一个 build block 构建你自己的 agent 产品、服务你的业务,而不是学习复杂的概念然后无从下手。
PsiACE
@repsiace
再强烈推荐一遍 LLM 时代难得的这么优雅的代码了
yihong
@yihong0618
我一直想要有一个类似于 Cloud Code 一样的通用 Agent 框架,但我一直有点懒得自己开始去做这件事情。然后看到了 bub,感觉完美符合了心中所想的一个 Agent 框架。
earayu
@earayu
bub是属于短小精悍,里面有很多思考精神,值得学习
卡比卡比
@jakevin7
使用 bub 作为一个 build block 构建你自己的 agent 产品、服务你的业务,而不是学习复杂的概念然后无从下手。
PsiACE
@repsiace
再强烈推荐一遍 LLM 时代难得的这么优雅的代码了
yihong
@yihong0618
我一直想要有一个类似于 Cloud Code 一样的通用 Agent 框架,但我一直有点懒得自己开始去做这件事情。然后看到了 bub,感觉完美符合了心中所想的一个 Agent 框架。
earayu
@earayu
bub是属于短小精悍,里面有很多思考精神,值得学习
卡比卡比
@jakevin7