bub 0.5.1__tar.gz → 0.6.0a2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. bub-0.6.0a2/PKG-INFO +139 -0
  2. bub-0.6.0a2/README.md +83 -0
  3. {bub-0.5.1 → bub-0.6.0a2}/pyproject.toml +18 -15
  4. bub-0.6.0a2/src/bub/__init__.py +62 -0
  5. bub-0.6.0a2/src/bub/__main__.py +101 -0
  6. {bub-0.5.1 → bub-0.6.0a2}/src/bub/_version.py +2 -2
  7. bub-0.6.0a2/src/bub/builtin/__init__.py +6 -0
  8. bub-0.6.0a2/src/bub/builtin/agent.py +265 -0
  9. bub-0.6.0a2/src/bub/builtin/archive.py +85 -0
  10. bub-0.6.0a2/src/bub/builtin/auth.py +50 -0
  11. {bub-0.5.1 → bub-0.6.0a2}/src/bub/builtin/cli.py +1 -1
  12. {bub-0.5.1 → bub-0.6.0a2}/src/bub/builtin/codemode/__init__.py +186 -22
  13. bub-0.6.0a2/src/bub/builtin/codemode/code_runner_child.py +584 -0
  14. bub-0.6.0a2/src/bub/builtin/codemode/republic_bridge.py +275 -0
  15. {bub-0.5.1 → bub-0.6.0a2}/src/bub/builtin/environment.py +3 -0
  16. {bub-0.5.1 → bub-0.6.0a2}/src/bub/builtin/hook_impl.py +51 -56
  17. bub-0.6.0a2/src/bub/builtin/model.py +150 -0
  18. {bub-0.5.1 → bub-0.6.0a2}/src/bub/builtin/onboarding.py +58 -85
  19. {bub-0.5.1 → bub-0.6.0a2}/src/bub/builtin/settings.py +62 -37
  20. {bub-0.5.1 → bub-0.6.0a2}/src/bub/builtin/spill.py +2 -2
  21. bub-0.6.0a2/src/bub/builtin/store.py +87 -0
  22. {bub-0.5.1 → bub-0.6.0a2}/src/bub/builtin/tools.py +8 -6
  23. {bub-0.5.1 → bub-0.6.0a2}/src/bub/channels/cli/__init__.py +44 -25
  24. {bub-0.5.1 → bub-0.6.0a2}/src/bub/channels/cli/renderer.py +5 -14
  25. {bub-0.5.1 → bub-0.6.0a2}/src/bub/channels/manager.py +1 -1
  26. {bub-0.5.1 → bub-0.6.0a2}/src/bub/channels/message.py +0 -26
  27. {bub-0.5.1 → bub-0.6.0a2}/src/bub/channels/telegram.py +1 -1
  28. {bub-0.5.1 → bub-0.6.0a2}/src/bub/configure.py +5 -0
  29. bub-0.6.0a2/src/bub/core/__init__.py +74 -0
  30. bub-0.6.0a2/src/bub/core/agent.py +778 -0
  31. bub-0.6.0a2/src/bub/core/commands.py +64 -0
  32. bub-0.6.0a2/src/bub/core/context.py +70 -0
  33. bub-0.6.0a2/src/bub/core/events.py +320 -0
  34. bub-0.6.0a2/src/bub/core/model.py +83 -0
  35. bub-0.6.0a2/src/bub/core/recorder.py +92 -0
  36. {bub-0.5.1/src/bub → bub-0.6.0a2/src/bub/core}/store.py +1 -75
  37. bub-0.6.0a2/src/bub/core/system_prompt.py +91 -0
  38. {bub-0.5.1/src/bub → bub-0.6.0a2/src/bub/core}/tape.py +148 -169
  39. {bub-0.5.1/src/bub → bub-0.6.0a2/src/bub/core}/tools.py +93 -107
  40. {bub-0.5.1 → bub-0.6.0a2}/src/bub/environment.py +16 -1
  41. {bub-0.5.1 → bub-0.6.0a2}/src/bub/framework.py +22 -22
  42. {bub-0.5.1 → bub-0.6.0a2}/src/bub/hooks/interception.py +55 -115
  43. {bub-0.5.1 → bub-0.6.0a2}/src/bub/hooks/runtime.py +9 -4
  44. {bub-0.5.1 → bub-0.6.0a2}/src/bub/hooks/specs.py +25 -17
  45. bub-0.6.0a2/src/bub/prompt.py +58 -0
  46. {bub-0.5.1 → bub-0.6.0a2}/src/bub/tracing.py +10 -7
  47. {bub-0.5.1 → bub-0.6.0a2}/src/bub/turn.py +5 -2
  48. {bub-0.5.1 → bub-0.6.0a2}/src/bub/utils.py +1 -1
  49. bub-0.6.0a2/tests/__init__.py +1 -0
  50. bub-0.6.0a2/tests/conftest.py +95 -0
  51. bub-0.6.0a2/tests/model_fakes.py +116 -0
  52. {bub-0.5.1 → bub-0.6.0a2}/tests/test_agent_hooks.py +139 -90
  53. {bub-0.5.1 → bub-0.6.0a2}/tests/test_builtin_agent.py +140 -229
  54. {bub-0.5.1 → bub-0.6.0a2}/tests/test_builtin_cli.py +13 -28
  55. bub-0.6.0a2/tests/test_builtin_codex.py +234 -0
  56. {bub-0.5.1 → bub-0.6.0a2}/tests/test_builtin_hook_impl.py +21 -16
  57. {bub-0.5.1 → bub-0.6.0a2}/tests/test_builtin_tools.py +8 -8
  58. {bub-0.5.1 → bub-0.6.0a2}/tests/test_channels.py +43 -20
  59. bub-0.6.0a2/tests/test_cli_main.py +72 -0
  60. {bub-0.5.1 → bub-0.6.0a2}/tests/test_cli_renderer.py +3 -4
  61. {bub-0.5.1 → bub-0.6.0a2}/tests/test_codemode.py +314 -31
  62. bub-0.6.0a2/tests/test_core_agent.py +390 -0
  63. bub-0.6.0a2/tests/test_core_agent_step.py +460 -0
  64. bub-0.6.0a2/tests/test_core_boundary.py +43 -0
  65. {bub-0.5.1 → bub-0.6.0a2}/tests/test_environment.py +19 -4
  66. {bub-0.5.1 → bub-0.6.0a2}/tests/test_file_tape_store_entry_ids.py +3 -3
  67. {bub-0.5.1 → bub-0.6.0a2}/tests/test_fork_store_merge_back.py +2 -2
  68. {bub-0.5.1 → bub-0.6.0a2}/tests/test_framework.py +23 -2
  69. {bub-0.5.1 → bub-0.6.0a2}/tests/test_hook_runtime.py +25 -0
  70. {bub-0.5.1 → bub-0.6.0a2}/tests/test_image_message.py +40 -66
  71. {bub-0.5.1 → bub-0.6.0a2}/tests/test_install_scripts.py +1 -1
  72. {bub-0.5.1 → bub-0.6.0a2}/tests/test_onboarding.py +127 -143
  73. {bub-0.5.1 → bub-0.6.0a2}/tests/test_otlp.py +1 -1
  74. bub-0.6.0a2/tests/test_provider_messages.py +259 -0
  75. {bub-0.5.1 → bub-0.6.0a2}/tests/test_sdk_isolation.py +77 -40
  76. {bub-0.5.1 → bub-0.6.0a2}/tests/test_session_settings.py +4 -4
  77. bub-0.6.0a2/tests/test_settings.py +381 -0
  78. {bub-0.5.1 → bub-0.6.0a2}/tests/test_spill.py +71 -66
  79. {bub-0.5.1 → bub-0.6.0a2}/tests/test_subagent_tool.py +1 -1
  80. bub-0.6.0a2/tests/test_tape.py +200 -0
  81. {bub-0.5.1 → bub-0.6.0a2}/tests/test_tape_search_output.py +1 -1
  82. {bub-0.5.1 → bub-0.6.0a2}/tests/test_tool_loading.py +52 -73
  83. {bub-0.5.1 → bub-0.6.0a2}/tests/test_tools.py +73 -77
  84. {bub-0.5.1 → bub-0.6.0a2}/tests/test_tracing.py +87 -141
  85. bub-0.5.1/PKG-INFO +0 -221
  86. bub-0.5.1/README.md +0 -176
  87. bub-0.5.1/src/bub/__init__.py +0 -45
  88. bub-0.5.1/src/bub/__main__.py +0 -63
  89. bub-0.5.1/src/bub/builtin/__init__.py +0 -3
  90. bub-0.5.1/src/bub/builtin/agent.py +0 -621
  91. bub-0.5.1/src/bub/builtin/auth.py +0 -537
  92. bub-0.5.1/src/bub/builtin/codemode/code_runner_child.py +0 -176
  93. bub-0.5.1/src/bub/builtin/codex_provider.py +0 -521
  94. bub-0.5.1/src/bub/builtin/commands.py +0 -20
  95. bub-0.5.1/src/bub/builtin/context.py +0 -97
  96. bub-0.5.1/src/bub/builtin/model_runner.py +0 -629
  97. bub-0.5.1/src/bub/types.py +0 -16
  98. bub-0.5.1/tests/conftest.py +0 -39
  99. bub-0.5.1/tests/test_builtin_codex.py +0 -605
  100. bub-0.5.1/tests/test_builtin_model_runner.py +0 -405
  101. bub-0.5.1/tests/test_settings.py +0 -234
  102. bub-0.5.1/tests/test_tape.py +0 -136
  103. bub-0.5.1/tests/test_types.py +0 -20
  104. {bub-0.5.1 → bub-0.6.0a2}/.gitignore +0 -0
  105. {bub-0.5.1 → bub-0.6.0a2}/LICENSE +0 -0
  106. {bub-0.5.1 → bub-0.6.0a2}/src/bub/builtin/codemode/code_runner.py +0 -0
  107. {bub-0.5.1 → bub-0.6.0a2}/src/bub/builtin/shell_manager.py +0 -0
  108. {bub-0.5.1 → bub-0.6.0a2}/src/bub/builtin/steering.py +0 -0
  109. {bub-0.5.1 → bub-0.6.0a2}/src/bub/channels/__init__.py +0 -0
  110. {bub-0.5.1 → bub-0.6.0a2}/src/bub/channels/admission.py +0 -0
  111. {bub-0.5.1 → bub-0.6.0a2}/src/bub/channels/base.py +0 -0
  112. {bub-0.5.1 → bub-0.6.0a2}/src/bub/channels/cli/ansi_bridge.py +0 -0
  113. {bub-0.5.1 → bub-0.6.0a2}/src/bub/channels/cli/terminal_output.py +0 -0
  114. {bub-0.5.1 → bub-0.6.0a2}/src/bub/channels/cli/writers.py +0 -0
  115. {bub-0.5.1 → bub-0.6.0a2}/src/bub/channels/contracts.py +0 -0
  116. {bub-0.5.1 → bub-0.6.0a2}/src/bub/channels/handler.py +0 -0
  117. {bub-0.5.1/src/bub → bub-0.6.0a2/src/bub/core}/sidecars.py +0 -0
  118. {bub-0.5.1 → bub-0.6.0a2}/src/bub/envelope.py +0 -0
  119. {bub-0.5.1 → bub-0.6.0a2}/src/bub/errors.py +0 -0
  120. {bub-0.5.1 → bub-0.6.0a2}/src/bub/gateway_installer.py +0 -0
  121. {bub-0.5.1 → bub-0.6.0a2}/src/bub/hooks/__init__.py +0 -0
  122. {bub-0.5.1 → bub-0.6.0a2}/src/bub/inquirer.py +0 -0
  123. {bub-0.5.1 → bub-0.6.0a2}/src/bub/model_selection.py +0 -0
  124. {bub-0.5.1 → bub-0.6.0a2}/src/bub/skills.py +0 -0
  125. {bub-0.5.1 → bub-0.6.0a2}/src/bub/streaming.py +0 -0
  126. {bub-0.5.1 → bub-0.6.0a2}/src/skills/README.md +0 -0
  127. {bub-0.5.1 → bub-0.6.0a2}/src/skills/gh/SKILL.md +0 -0
  128. {bub-0.5.1 → bub-0.6.0a2}/src/skills/skill-creator/SKILL.md +0 -0
  129. {bub-0.5.1 → bub-0.6.0a2}/src/skills/skill-creator/license.txt +0 -0
  130. {bub-0.5.1 → bub-0.6.0a2}/src/skills/skill-creator/scripts/init_skill.py +0 -0
  131. {bub-0.5.1 → bub-0.6.0a2}/src/skills/skill-creator/scripts/quick_validate.py +0 -0
  132. {bub-0.5.1 → bub-0.6.0a2}/src/skills/telegram/SKILL.md +0 -0
  133. {bub-0.5.1 → bub-0.6.0a2}/src/skills/telegram/scripts/telegram_edit.py +0 -0
  134. {bub-0.5.1 → bub-0.6.0a2}/src/skills/telegram/scripts/telegram_rich.py +0 -0
  135. {bub-0.5.1 → bub-0.6.0a2}/src/skills/telegram/scripts/telegram_send.py +0 -0
  136. {bub-0.5.1 → bub-0.6.0a2}/tests/test_cli_help.py +0 -0
  137. {bub-0.5.1 → bub-0.6.0a2}/tests/test_configure.py +0 -0
  138. {bub-0.5.1 → bub-0.6.0a2}/tests/test_envelope.py +0 -0
  139. {bub-0.5.1 → bub-0.6.0a2}/tests/test_errors.py +0 -0
  140. {bub-0.5.1 → bub-0.6.0a2}/tests/test_gateway_installer.py +0 -0
  141. {bub-0.5.1 → bub-0.6.0a2}/tests/test_shell_manager.py +0 -0
  142. {bub-0.5.1 → bub-0.6.0a2}/tests/test_skills.py +0 -0
  143. {bub-0.5.1 → bub-0.6.0a2}/tests/test_utils.py +0 -0
bub-0.6.0a2/PKG-INFO ADDED
@@ -0,0 +1,139 @@
1
+ Metadata-Version: 2.5
2
+ Name: bub
3
+ Version: 0.6.0a2
4
+ Summary: A tiny agent runtime, composable with plugins.
5
+ Project-URL: Homepage, https://bub.build
6
+ Project-URL: Repository, https://github.com/bubbuild/bub
7
+ Project-URL: Documentation, https://bub.build
8
+ Author-email: Chojan Shang <psiace@apache.org>, Frost Ming <me@frostming.com>, Yihong <zouzou0208@gmail.com>
9
+ License: Apache-2.0
10
+ License-File: LICENSE
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Programming Language :: Python
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
16
+ Classifier: Programming Language :: Python :: 3.14
17
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
18
+ Requires-Python: <4.0,>=3.12
19
+ Requires-Dist: loguru>=0.7.3
20
+ Requires-Dist: pydantic>=2.12.5
21
+ Requires-Dist: republic>=0.6.0a1
22
+ Requires-Dist: typing-extensions>=4.15.0
23
+ Provides-Extra: app
24
+ Requires-Dist: aiohttp>=3.14.3; extra == 'app'
25
+ Requires-Dist: httpx[socks]>=0.28.1; extra == 'app'
26
+ Requires-Dist: inquirer-textual>=0.8.0; extra == 'app'
27
+ Requires-Dist: pluggy>=1.6.0; extra == 'app'
28
+ Requires-Dist: prompt-toolkit>=3.0.52; extra == 'app'
29
+ Requires-Dist: pydantic-settings>=2.14.2; extra == 'app'
30
+ Requires-Dist: python-telegram-bot>=22.7; extra == 'app'
31
+ Requires-Dist: pyyaml>=6.0.3; extra == 'app'
32
+ Requires-Dist: rapidfuzz>=3.14.5; extra == 'app'
33
+ Requires-Dist: rich>=14.3.4; extra == 'app'
34
+ Requires-Dist: typer>=0.24.1; extra == 'app'
35
+ Provides-Extra: logfire
36
+ Requires-Dist: aiohttp>=3.14.3; extra == 'logfire'
37
+ Requires-Dist: httpx[socks]>=0.28.1; extra == 'logfire'
38
+ Requires-Dist: inquirer-textual>=0.8.0; extra == 'logfire'
39
+ Requires-Dist: logfire>=4.32.0; extra == 'logfire'
40
+ Requires-Dist: opentelemetry-api>=1.39.0; extra == 'logfire'
41
+ Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.39.0; extra == 'logfire'
42
+ Requires-Dist: opentelemetry-sdk>=1.39.0; extra == 'logfire'
43
+ Requires-Dist: pluggy>=1.6.0; extra == 'logfire'
44
+ Requires-Dist: prompt-toolkit>=3.0.52; extra == 'logfire'
45
+ Requires-Dist: pydantic-settings>=2.14.2; extra == 'logfire'
46
+ Requires-Dist: python-telegram-bot>=22.7; extra == 'logfire'
47
+ Requires-Dist: pyyaml>=6.0.3; extra == 'logfire'
48
+ Requires-Dist: rapidfuzz>=3.14.5; extra == 'logfire'
49
+ Requires-Dist: rich>=14.3.4; extra == 'logfire'
50
+ Requires-Dist: typer>=0.24.1; extra == 'logfire'
51
+ Provides-Extra: trace
52
+ Requires-Dist: opentelemetry-api>=1.39.0; extra == 'trace'
53
+ Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.39.0; extra == 'trace'
54
+ Requires-Dist: opentelemetry-sdk>=1.39.0; extra == 'trace'
55
+ Description-Content-Type: text/markdown
56
+
57
+ # Bub
58
+
59
+ <div align="center">
60
+
61
+ <picture>
62
+ <source srcset="https://raw.githubusercontent.com/bubbuild/bub/refs/heads/main/website/src/assets/bub-logo-dark.png" media="(prefers-color-scheme: dark)">
63
+ <img alt="Bub logo" src="https://raw.githubusercontent.com/bubbuild/bub/refs/heads/main/website/src/assets/bub-logo.png" width="200">
64
+ </picture>
65
+
66
+ <p><strong>A tiny agent runtime, composable with plugins.</strong></p>
67
+
68
+ [Website](https://bub.build) · [Docs](https://bub.build/docs/getting-started/) · [Hub](https://hub.bub.build)
69
+
70
+ </div>
71
+
72
+ Bub is a small Python runtime for building agents in shared environments. It started in group chats, where multiple humans and agents had to work in the same conversation without hidden state, hand-wavy memory, or framework-specific magic.
73
+
74
+ Built on [agents.md](https://agents.md/) and [Agent Skills](https://agentskills.io/), Bub stays intentionally small. Every turn stage is a [pluggy](https://pluggy.readthedocs.io/) hook, builtins are replaceable, and the same runtime drives CLI, Telegram, and any channel you add.
75
+
76
+ ## Quick Start
77
+
78
+ macOS and Linux:
79
+
80
+ ```bash
81
+ curl -fsSL https://bub.build/install.sh | bash
82
+ ```
83
+
84
+ Windows PowerShell:
85
+
86
+ ```powershell
87
+ powershell -ExecutionPolicy ByPass -c "irm https://bub.build/install.ps1 | iex"
88
+ ```
89
+
90
+ Then:
91
+
92
+ ```bash
93
+ bub chat # interactive session
94
+ bub run "summarize this repo" # one-shot task
95
+ bub gateway # channel listener mode
96
+ ```
97
+
98
+ See [Getting Started](https://bub.build/docs/getting-started/) for installer presets and source installs, and [Configure](https://bub.build/docs/operate/configure/) for model and runtime settings.
99
+
100
+ ## Why Bub
101
+
102
+ - **Composable by design.** Every turn stage is a plugin hook. Override one stage or replace the whole flow without forking the runtime.
103
+ - **Tape context.** Context is rebuilt from append-only records, not carried around as mutable session state. Easier to inspect, replay, and hand off.
104
+ - **One runtime across surfaces.** The same inbound pipeline runs across CLI, Telegram, and custom channels. Adapters change the surface, not the runtime model.
105
+ - **Batteries included.** CLI, Telegram, tools, skills, and model execution ship with the core runtime. Use the defaults first, replace them later.
106
+ - **Operator equivalence.** Humans and agents work inside the same runtime boundaries, with the same evidence trail and handoff model.
107
+ - **Embeddable Python SDK.** `pip install bub` installs only `bub.core`, which exposes the agent loop on its own (the CLI, channels and plugins come with `bub[app]`) — bring your own model, tools, prompts, and tape store, with no settings or plugins required.
108
+
109
+ ## How It Works
110
+
111
+ Every inbound message goes through one turn pipeline. Each stage is a hook.
112
+
113
+ ```
114
+ resolve_session → load_state → build_prompt → run_model
115
+ ↓
116
+ dispatch_outbound ← render_outbound ← save_state
117
+ ```
118
+
119
+ Builtins are registered first and external plugins load after them, so later plugins take precedence. There are no framework-only shortcuts.
120
+
121
+ ## Docs
122
+
123
+ - [Getting Started](https://bub.build/docs/getting-started/) — install Bub and run the first turn
124
+ - [Concepts](https://bub.build/docs/concepts/) — the mental model behind the runtime
125
+ - [Python SDK](https://bub.build/docs/build/sdk/) — embed Bub's agent loop in your own application
126
+ - [Build](https://bub.build/docs/build/) — write plugins, override hooks, ship tools and skills
127
+ - [Bub Hub](https://hub.bub.build) — browse community plugins, skills, and distributions
128
+ - [Channels](https://bub.build/docs/operate/channels/) — run Bub in CLI, Telegram, or your own channel
129
+ - [Deployment](https://bub.build/docs/operate/deploy/) — Docker, environment, upgrades
130
+
131
+ ## Background
132
+
133
+ - [Why We Rewrote Bub](https://bub.build/posts/why-rewrite-bub/)
134
+ - [Socialized Evaluation and Agent Partnership](https://bub.build/posts/socialized-evaluation/)
135
+ - [Context from Tape](https://tape.systems)
136
+
137
+ ## License
138
+
139
+ [Apache-2.0](https://github.com/bubbuild/bub/blob/main/LICENSE)
bub-0.6.0a2/README.md ADDED
@@ -0,0 +1,83 @@
1
+ # Bub
2
+
3
+ <div align="center">
4
+
5
+ <picture>
6
+ <source srcset="https://raw.githubusercontent.com/bubbuild/bub/refs/heads/main/website/src/assets/bub-logo-dark.png" media="(prefers-color-scheme: dark)">
7
+ <img alt="Bub logo" src="https://raw.githubusercontent.com/bubbuild/bub/refs/heads/main/website/src/assets/bub-logo.png" width="200">
8
+ </picture>
9
+
10
+ <p><strong>A tiny agent runtime, composable with plugins.</strong></p>
11
+
12
+ [Website](https://bub.build) · [Docs](https://bub.build/docs/getting-started/) · [Hub](https://hub.bub.build)
13
+
14
+ </div>
15
+
16
+ Bub is a small Python runtime for building agents in shared environments. It started in group chats, where multiple humans and agents had to work in the same conversation without hidden state, hand-wavy memory, or framework-specific magic.
17
+
18
+ Built on [agents.md](https://agents.md/) and [Agent Skills](https://agentskills.io/), Bub stays intentionally small. Every turn stage is a [pluggy](https://pluggy.readthedocs.io/) hook, builtins are replaceable, and the same runtime drives CLI, Telegram, and any channel you add.
19
+
20
+ ## Quick Start
21
+
22
+ macOS and Linux:
23
+
24
+ ```bash
25
+ curl -fsSL https://bub.build/install.sh | bash
26
+ ```
27
+
28
+ Windows PowerShell:
29
+
30
+ ```powershell
31
+ powershell -ExecutionPolicy ByPass -c "irm https://bub.build/install.ps1 | iex"
32
+ ```
33
+
34
+ Then:
35
+
36
+ ```bash
37
+ bub chat # interactive session
38
+ bub run "summarize this repo" # one-shot task
39
+ bub gateway # channel listener mode
40
+ ```
41
+
42
+ See [Getting Started](https://bub.build/docs/getting-started/) for installer presets and source installs, and [Configure](https://bub.build/docs/operate/configure/) for model and runtime settings.
43
+
44
+ ## Why Bub
45
+
46
+ - **Composable by design.** Every turn stage is a plugin hook. Override one stage or replace the whole flow without forking the runtime.
47
+ - **Tape context.** Context is rebuilt from append-only records, not carried around as mutable session state. Easier to inspect, replay, and hand off.
48
+ - **One runtime across surfaces.** The same inbound pipeline runs across CLI, Telegram, and custom channels. Adapters change the surface, not the runtime model.
49
+ - **Batteries included.** CLI, Telegram, tools, skills, and model execution ship with the core runtime. Use the defaults first, replace them later.
50
+ - **Operator equivalence.** Humans and agents work inside the same runtime boundaries, with the same evidence trail and handoff model.
51
+ - **Embeddable Python SDK.** `pip install bub` installs only `bub.core`, which exposes the agent loop on its own (the CLI, channels and plugins come with `bub[app]`) — bring your own model, tools, prompts, and tape store, with no settings or plugins required.
52
+
53
+ ## How It Works
54
+
55
+ Every inbound message goes through one turn pipeline. Each stage is a hook.
56
+
57
+ ```
58
+ resolve_session → load_state → build_prompt → run_model
59
+ ↓
60
+ dispatch_outbound ← render_outbound ← save_state
61
+ ```
62
+
63
+ Builtins are registered first and external plugins load after them, so later plugins take precedence. There are no framework-only shortcuts.
64
+
65
+ ## Docs
66
+
67
+ - [Getting Started](https://bub.build/docs/getting-started/) — install Bub and run the first turn
68
+ - [Concepts](https://bub.build/docs/concepts/) — the mental model behind the runtime
69
+ - [Python SDK](https://bub.build/docs/build/sdk/) — embed Bub's agent loop in your own application
70
+ - [Build](https://bub.build/docs/build/) — write plugins, override hooks, ship tools and skills
71
+ - [Bub Hub](https://hub.bub.build) — browse community plugins, skills, and distributions
72
+ - [Channels](https://bub.build/docs/operate/channels/) — run Bub in CLI, Telegram, or your own channel
73
+ - [Deployment](https://bub.build/docs/operate/deploy/) — Docker, environment, upgrades
74
+
75
+ ## Background
76
+
77
+ - [Why We Rewrote Bub](https://bub.build/posts/why-rewrite-bub/)
78
+ - [Socialized Evaluation and Agent Partnership](https://bub.build/posts/socialized-evaluation/)
79
+ - [Context from Tape](https://tape.systems)
80
+
81
+ ## License
82
+
83
+ [Apache-2.0](https://github.com/bubbuild/bub/blob/main/LICENSE)
@@ -20,22 +20,11 @@ classifiers = [
20
20
  "Topic :: Software Development :: Libraries :: Python Modules",
21
21
  ]
22
22
 
23
+ # The agent kernel, bub.core. Everything else (framework, CLI, channels, builtin agent) is in the `app` extra.
23
24
  dependencies = [
25
+ "republic>=0.6.0a1",
24
26
  "pydantic>=2.12.5",
25
- "pydantic-settings>=2.14.2",
26
- "pyyaml>=6.0.3",
27
- "pluggy>=1.6.0",
28
- "inquirer-textual>=0.8.0",
29
- "typer>=0.24.1",
30
- "authlib>=1.7.2",
31
- "any-llm-sdk[anthropic]>=1.22.1",
32
- "rich>=14.3.4",
33
- "prompt-toolkit>=3.0.52",
34
- "python-telegram-bot>=22.7",
35
27
  "loguru>=0.7.3",
36
- "rapidfuzz>=3.14.5",
37
- "aiohttp>=3.14.3",
38
- "httpx[socks]>=0.28.1",
39
28
  "typing-extensions>=4.15.0",
40
29
  ]
41
30
 
@@ -45,21 +34,35 @@ Repository = "https://github.com/bubbuild/bub"
45
34
  Documentation = "https://bub.build"
46
35
 
47
36
  [project.scripts]
48
- bub = "bub.__main__:app"
37
+ bub = "bub.__main__:main"
49
38
 
50
39
  [project.optional-dependencies]
40
+ app = [
41
+ "pydantic-settings>=2.14.2",
42
+ "pyyaml>=6.0.3",
43
+ "pluggy>=1.6.0",
44
+ "inquirer-textual>=0.8.0",
45
+ "typer>=0.24.1",
46
+ "rich>=14.3.4",
47
+ "prompt-toolkit>=3.0.52",
48
+ "python-telegram-bot>=22.7",
49
+ "rapidfuzz>=3.14.5",
50
+ "aiohttp>=3.14.3",
51
+ "httpx[socks]>=0.28.1",
52
+ ]
51
53
  trace = [
52
54
  "opentelemetry-api>=1.39.0",
53
55
  "opentelemetry-sdk>=1.39.0",
54
56
  "opentelemetry-exporter-otlp-proto-http>=1.39.0",
55
57
  ]
56
58
  logfire = [
57
- "bub[trace]",
59
+ "bub[app,trace]",
58
60
  "logfire>=4.32.0",
59
61
  ]
60
62
 
61
63
  [dependency-groups]
62
64
  dev = [
65
+ "bub[app]",
63
66
  "pytest>=9.0.3",
64
67
  "tox-uv>=1.35.1",
65
68
  "types-PyYAML>=6.0.12.20260408",
@@ -0,0 +1,62 @@
1
+ """Bub framework package.
2
+
3
+ The top-level names are imported on first access, so ``import bub.core`` does not load
4
+ the framework, its settings or the CLI.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import os
10
+ from importlib import import_module
11
+ from importlib.metadata import PackageNotFoundError
12
+ from importlib.metadata import version as metadata_version
13
+ from pathlib import Path
14
+ from typing import TYPE_CHECKING, Any
15
+
16
+ if TYPE_CHECKING:
17
+ from bub.configure import Settings, config, ensure_config
18
+ from bub.core.tools import tool
19
+ from bub.framework import BubFramework
20
+ from bub.hooks import hookimpl
21
+
22
+ home: Path
23
+
24
+ __all__ = [
25
+ "BubFramework",
26
+ "Settings",
27
+ "config",
28
+ "ensure_config",
29
+ "home",
30
+ "hookimpl",
31
+ "tool",
32
+ ]
33
+
34
+ _EXPORTS = {
35
+ "BubFramework": "bub.framework",
36
+ "Settings": "bub.configure",
37
+ "config": "bub.configure",
38
+ "ensure_config": "bub.configure",
39
+ "hookimpl": "bub.hooks",
40
+ "tool": "bub.core.tools",
41
+ }
42
+
43
+ try:
44
+ __version__ = import_module("bub._version").version
45
+ except ModuleNotFoundError:
46
+ try:
47
+ __version__ = metadata_version("bub")
48
+ except PackageNotFoundError:
49
+ __version__ = "0.0.0"
50
+
51
+
52
+ def __getattr__(name: str) -> Any:
53
+ if name == "home":
54
+ # Importing bub.configure loads ``.env``, which may set ``BUB_HOME``.
55
+ from bub.configure import DEFAULT_HOME
56
+
57
+ if "BUB_HOME" in os.environ:
58
+ return Path(os.path.expanduser(os.environ["BUB_HOME"]))
59
+ return DEFAULT_HOME
60
+ if name not in _EXPORTS:
61
+ raise AttributeError(f"module {__name__} has no attribute {name}")
62
+ return getattr(import_module(_EXPORTS[name]), name)
@@ -0,0 +1,101 @@
1
+ """Bub framework CLI bootstrap.
2
+
3
+ The CLI needs the ``app`` extra, so this module imports it only when the command runs:
4
+ ``main`` reports missing requirements instead of failing on an import.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import os
10
+ import re
11
+ import sys
12
+ from importlib.metadata import PackageNotFoundError, distribution, requires
13
+ from typing import TYPE_CHECKING
14
+
15
+ if TYPE_CHECKING:
16
+ import typer
17
+
18
+ LOG_LEVEL = {
19
+ 0: "INFO",
20
+ 1: "DEBUG",
21
+ 2: "TRACE",
22
+ }
23
+
24
+ _APP_REQUIREMENT = re.compile(r"""^([A-Za-z0-9][A-Za-z0-9._-]*).*;.*\bextra\s*==\s*["']app["']""")
25
+
26
+
27
+ def missing_app_requirements() -> list[str]:
28
+ """Return the distributions required by ``bub[app]`` that are not installed."""
29
+ try:
30
+ requirements = requires("bub") or []
31
+ except PackageNotFoundError: # Running from a source tree that is not installed.
32
+ return []
33
+ missing: list[str] = []
34
+ for requirement in requirements:
35
+ if (match := _APP_REQUIREMENT.match(requirement)) is None:
36
+ continue
37
+ try:
38
+ distribution(match.group(1))
39
+ except PackageNotFoundError:
40
+ missing.append(match.group(1))
41
+ return missing
42
+
43
+
44
+ def _instrument_bub(level: str) -> None:
45
+ from loguru import logger
46
+
47
+ logger.remove()
48
+ logger.add(sys.stderr, level=level, colorize=True, diagnose=False)
49
+
50
+ if os.getenv("OTEL_EXPORTER_OTLP_TRACES_ENDPOINT") or os.getenv("OTEL_EXPORTER_OTLP_ENDPOINT"):
51
+ from bub.tracing import configure_otlp
52
+
53
+ try:
54
+ configure_otlp()
55
+ except Exception as exc:
56
+ logger.warning("OTLP instrumentation disabled: {}", exc)
57
+ return
58
+
59
+ try:
60
+ import logfire
61
+ from logfire.integrations.loguru import LogfireHandler
62
+
63
+ logfire.configure()
64
+ logger.add(LogfireHandler(), level=level, format="{message}", diagnose=False)
65
+ except Exception as exc:
66
+ logger.debug("logfire instrumentation disabled: {}", exc)
67
+
68
+
69
+ def create_cli_app() -> typer.Typer:
70
+ import typer
71
+
72
+ from bub.builtin.settings import load_settings
73
+ from bub.framework import BubFramework
74
+
75
+ framework = BubFramework()
76
+ _instrument_bub(LOG_LEVEL[load_settings().verbose])
77
+ framework.load_hooks()
78
+ app = framework.create_cli_app()
79
+
80
+ if not app.registered_commands:
81
+
82
+ @app.command("help")
83
+ def _help() -> None:
84
+ typer.echo("No CLI command loaded.")
85
+
86
+ return app
87
+
88
+
89
+ def main() -> None:
90
+ """Run the ``bub`` command."""
91
+ if missing := missing_app_requirements():
92
+ sys.exit(
93
+ "The bub command needs the 'app' extra, which is not installed "
94
+ f"(missing: {', '.join(missing)}).\n"
95
+ "Install it with: uv tool install 'bub[app]' or pip install 'bub[app]'"
96
+ )
97
+ create_cli_app()()
98
+
99
+
100
+ if __name__ == "__main__":
101
+ main()
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '0.5.1'
22
- __version_tuple__ = version_tuple = (0, 5, 1)
21
+ __version__ = version = '0.6.0a2'
22
+ __version_tuple__ = version_tuple = (0, 6, 0, 'a2')
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -0,0 +1,6 @@
1
+ from .agent import BubAgent
2
+
3
+ Agent = BubAgent
4
+ """Deprecated alias of :class:`BubAgent`."""
5
+
6
+ __all__ = ["Agent", "BubAgent"]