bub 0.3.6__tar.gz → 0.3.7__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 (71) hide show
  1. {bub-0.3.6 → bub-0.3.7}/.gitignore +1 -0
  2. bub-0.3.7/PKG-INFO +189 -0
  3. bub-0.3.7/README.md +153 -0
  4. {bub-0.3.6 → bub-0.3.7}/pyproject.toml +2 -4
  5. bub-0.3.7/src/bub/__init__.py +37 -0
  6. {bub-0.3.6 → bub-0.3.7}/src/bub/_version.py +2 -2
  7. {bub-0.3.6 → bub-0.3.7}/src/bub/builtin/agent.py +3 -1
  8. {bub-0.3.6 → bub-0.3.7}/src/bub/builtin/cli.py +33 -3
  9. {bub-0.3.6 → bub-0.3.7}/src/bub/builtin/hook_impl.py +114 -6
  10. {bub-0.3.6 → bub-0.3.7}/src/bub/builtin/settings.py +19 -25
  11. {bub-0.3.6 → bub-0.3.7}/src/bub/channels/cli/__init__.py +15 -4
  12. {bub-0.3.6 → bub-0.3.7}/src/bub/channels/cli/renderer.py +8 -4
  13. {bub-0.3.6 → bub-0.3.7}/src/bub/channels/manager.py +6 -3
  14. {bub-0.3.6 → bub-0.3.7}/src/bub/channels/telegram.py +9 -4
  15. bub-0.3.7/src/bub/configure.py +117 -0
  16. {bub-0.3.6 → bub-0.3.7}/src/bub/framework.py +40 -6
  17. {bub-0.3.6 → bub-0.3.7}/src/bub/hookspecs.py +9 -5
  18. bub-0.3.7/src/bub/inquirer.py +86 -0
  19. bub-0.3.7/src/skills/README.md +7 -0
  20. bub-0.3.7/tests/conftest.py +39 -0
  21. {bub-0.3.6 → bub-0.3.7}/tests/test_builtin_agent.py +2 -2
  22. bub-0.3.7/tests/test_builtin_cli.py +430 -0
  23. {bub-0.3.6 → bub-0.3.7}/tests/test_builtin_hook_impl.py +5 -4
  24. {bub-0.3.6 → bub-0.3.7}/tests/test_channels.py +74 -20
  25. bub-0.3.7/tests/test_configure.py +77 -0
  26. {bub-0.3.6 → bub-0.3.7}/tests/test_framework.py +121 -23
  27. {bub-0.3.6 → bub-0.3.7}/tests/test_image_message.py +11 -5
  28. {bub-0.3.6 → bub-0.3.7}/tests/test_settings.py +29 -35
  29. bub-0.3.6/PKG-INFO +0 -182
  30. bub-0.3.6/README.md +0 -148
  31. bub-0.3.6/src/bub/__init__.py +0 -19
  32. bub-0.3.6/src/skills/README.md +0 -3
  33. bub-0.3.6/tests/test_builtin_cli.py +0 -150
  34. {bub-0.3.6 → bub-0.3.7}/LICENSE +0 -0
  35. {bub-0.3.6 → bub-0.3.7}/src/bub/__main__.py +0 -0
  36. {bub-0.3.6 → bub-0.3.7}/src/bub/builtin/__init__.py +0 -0
  37. {bub-0.3.6 → bub-0.3.7}/src/bub/builtin/auth.py +0 -0
  38. {bub-0.3.6 → bub-0.3.7}/src/bub/builtin/context.py +0 -0
  39. {bub-0.3.6 → bub-0.3.7}/src/bub/builtin/shell_manager.py +0 -0
  40. {bub-0.3.6 → bub-0.3.7}/src/bub/builtin/store.py +0 -0
  41. {bub-0.3.6 → bub-0.3.7}/src/bub/builtin/tape.py +0 -0
  42. {bub-0.3.6 → bub-0.3.7}/src/bub/builtin/tools.py +0 -0
  43. {bub-0.3.6 → bub-0.3.7}/src/bub/channels/__init__.py +0 -0
  44. {bub-0.3.6 → bub-0.3.7}/src/bub/channels/base.py +0 -0
  45. {bub-0.3.6 → bub-0.3.7}/src/bub/channels/handler.py +0 -0
  46. {bub-0.3.6 → bub-0.3.7}/src/bub/channels/message.py +0 -0
  47. {bub-0.3.6 → bub-0.3.7}/src/bub/envelope.py +0 -0
  48. {bub-0.3.6 → bub-0.3.7}/src/bub/hook_runtime.py +0 -0
  49. {bub-0.3.6 → bub-0.3.7}/src/bub/skills.py +0 -0
  50. {bub-0.3.6 → bub-0.3.7}/src/bub/tools.py +0 -0
  51. {bub-0.3.6 → bub-0.3.7}/src/bub/types.py +0 -0
  52. {bub-0.3.6 → bub-0.3.7}/src/bub/utils.py +0 -0
  53. {bub-0.3.6 → bub-0.3.7}/src/skills/gh/SKILL.md +0 -0
  54. {bub-0.3.6 → bub-0.3.7}/src/skills/skill-creator/SKILL.md +0 -0
  55. {bub-0.3.6 → bub-0.3.7}/src/skills/skill-creator/license.txt +0 -0
  56. {bub-0.3.6 → bub-0.3.7}/src/skills/skill-creator/scripts/init_skill.py +0 -0
  57. {bub-0.3.6 → bub-0.3.7}/src/skills/skill-creator/scripts/quick_validate.py +0 -0
  58. {bub-0.3.6 → bub-0.3.7}/src/skills/telegram/SKILL.md +0 -0
  59. {bub-0.3.6 → bub-0.3.7}/src/skills/telegram/scripts/telegram_edit.py +0 -0
  60. {bub-0.3.6 → bub-0.3.7}/src/skills/telegram/scripts/telegram_send.py +0 -0
  61. {bub-0.3.6 → bub-0.3.7}/tests/test_builtin_tools.py +0 -0
  62. {bub-0.3.6 → bub-0.3.7}/tests/test_cli_help.py +0 -0
  63. {bub-0.3.6 → bub-0.3.7}/tests/test_envelope.py +0 -0
  64. {bub-0.3.6 → bub-0.3.7}/tests/test_file_tape_store_entry_ids.py +0 -0
  65. {bub-0.3.6 → bub-0.3.7}/tests/test_fork_store_merge_back.py +0 -0
  66. {bub-0.3.6 → bub-0.3.7}/tests/test_hook_runtime.py +0 -0
  67. {bub-0.3.6 → bub-0.3.7}/tests/test_skills.py +0 -0
  68. {bub-0.3.6 → bub-0.3.7}/tests/test_subagent_tool.py +0 -0
  69. {bub-0.3.6 → bub-0.3.7}/tests/test_tape_search_output.py +0 -0
  70. {bub-0.3.6 → bub-0.3.7}/tests/test_tools.py +0 -0
  71. {bub-0.3.6 → bub-0.3.7}/tests/test_utils.py +0 -0
@@ -146,3 +146,4 @@ reference/
146
146
  # Local legacy backups created during framework migrations
147
147
  backup/
148
148
  _version.py
149
+ !website/src/lib/
bub-0.3.7/PKG-INFO ADDED
@@ -0,0 +1,189 @@
1
+ Metadata-Version: 2.4
2
+ Name: bub
3
+ Version: 0.3.7
4
+ Summary: A common shape for agents that live alongside people.
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-File: LICENSE
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Programming Language :: Python
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Classifier: Programming Language :: Python :: 3.14
16
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
17
+ Requires-Python: <4.0,>=3.12
18
+ Requires-Dist: aiohttp>=3.13.3
19
+ Requires-Dist: any-llm-sdk[anthropic]
20
+ Requires-Dist: httpx[socks]>=0.28.1
21
+ Requires-Dist: inquirer-textual>=0.5.1
22
+ Requires-Dist: loguru>=0.7.2
23
+ Requires-Dist: pluggy>=1.6.0
24
+ Requires-Dist: prompt-toolkit>=3.0.0
25
+ Requires-Dist: pydantic-settings>=2.0.0
26
+ Requires-Dist: pydantic>=2.0.0
27
+ Requires-Dist: python-telegram-bot>=21.0
28
+ Requires-Dist: pyyaml>=6.0.0
29
+ Requires-Dist: rapidfuzz>=3.14.3
30
+ Requires-Dist: republic>=0.5.4
31
+ Requires-Dist: rich>=13.0.0
32
+ Requires-Dist: typer>=0.9.0
33
+ Provides-Extra: logfire
34
+ Requires-Dist: logfire>=4.31.0; extra == 'logfire'
35
+ Description-Content-Type: text/markdown
36
+
37
+ # Bub
38
+
39
+ <div align="center">
40
+
41
+ <picture>
42
+ <source srcset="https://raw.githubusercontent.com/bubbuild/bub/refs/heads/main/website/src/assets/bub-logo-dark.png" media="(prefers-color-scheme: dark)">
43
+ <img alt="Bub logo" src="https://raw.githubusercontent.com/bubbuild/bub/refs/heads/main/website/src/assets/bub-logo.png" width="200">
44
+ </picture>
45
+
46
+ <p><strong>A hook-first runtime for agents that live alongside people.</strong></p>
47
+
48
+ </div>
49
+
50
+ 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.
51
+
52
+ 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 included but replaceable. The same runtime drives CLI, Telegram, and any channel you add.
53
+
54
+ [Website](https://bub.build) · [GitHub](https://github.com/bubbuild/bub)
55
+
56
+ ## Quick Start
57
+
58
+ ```bash
59
+ pip install bub
60
+ ```
61
+
62
+ Or from source:
63
+
64
+ ```bash
65
+ git clone https://github.com/bubbuild/bub.git
66
+ cd bub
67
+ uv sync # enough to run Bub from source
68
+ ```
69
+
70
+ For local development, use `make install` instead so the website toolchain and `prek` hooks are installed too.
71
+
72
+ ```bash
73
+ uv run bub chat # interactive session
74
+ uv run bub run "summarize this repo" # one-shot task
75
+ uv run bub gateway # channel listener mode
76
+ ```
77
+
78
+ ## Why Bub
79
+
80
+ - **Hook-first runtime.** Every turn stage is a hook. Override one stage or replace the whole flow without forking the runtime.
81
+ - **Tape context.** Context is rebuilt from append-only records, not carried around as mutable session state. Easier to inspect, replay, and hand off.
82
+ - **One runtime across surfaces.** The same inbound pipeline runs across CLI, Telegram, and custom channels. Adapters change the surface, not the runtime model.
83
+ - **Batteries included.** CLI, Telegram, tools, skills, and model execution ship with the core runtime. Use the defaults first, replace them later.
84
+ - **Operator equivalence.** Humans and agents work inside the same runtime boundaries, with the same evidence trail and handoff model. No hidden operator class.
85
+
86
+ ## How It Works
87
+
88
+ Every inbound message goes through one turn pipeline. Each stage is a hook.
89
+
90
+ ```
91
+ resolve_session → load_state → build_prompt → run_model
92
+
93
+ dispatch_outbound ← render_outbound ← save_state
94
+ ```
95
+
96
+ Builtins are registered first. External plugins load after them. At runtime, later plugins take precedence. There are no framework-only shortcuts.
97
+
98
+ Key source files:
99
+
100
+ - Turn orchestrator: [`src/bub/framework.py`](https://github.com/bubbuild/bub/blob/main/src/bub/framework.py)
101
+ - Hook contract: [`src/bub/hookspecs.py`](https://github.com/bubbuild/bub/blob/main/src/bub/hookspecs.py)
102
+ - Builtin hooks: [`src/bub/builtin/hook_impl.py`](https://github.com/bubbuild/bub/blob/main/src/bub/builtin/hook_impl.py)
103
+ - Skill discovery: [`src/bub/skills.py`](https://github.com/bubbuild/bub/blob/main/src/bub/skills.py)
104
+
105
+ ## Extend It
106
+
107
+ ```python
108
+ from bub import hookimpl
109
+
110
+
111
+ class EchoPlugin:
112
+ @hookimpl
113
+ def build_prompt(self, message, session_id, state):
114
+ return f"[echo] {message['content']}"
115
+
116
+ @hookimpl
117
+ async def run_model(self, prompt, session_id, state):
118
+ return prompt
119
+ ```
120
+
121
+ ```toml
122
+ [project.entry-points."bub"]
123
+ echo = "my_package.plugin:EchoPlugin"
124
+ ```
125
+
126
+ See the [Extending docs](https://bub.build/docs/extending/) for hook guides, packaging, and plugin structure.
127
+
128
+ ## CLI
129
+
130
+ | Command | Description |
131
+ | ------------------ | --------------------------------- |
132
+ | `bub chat` | Interactive REPL |
133
+ | `bub run MESSAGE` | One-shot turn |
134
+ | `bub gateway` | Channel listener (Telegram, etc.) |
135
+ | `bub install` | Install or sync Bub plugin deps |
136
+ | `bub update` | Upgrade Bub plugin deps |
137
+ | `bub login openai` | OpenAI Codex OAuth |
138
+
139
+ Lines starting with `,` enter internal command mode (`,help`, `,skill name=my-skill`, `,fs.read path=README.md`).
140
+
141
+ `bub hooks` still exists for diagnostics, but it is hidden from top-level help. `bub install` and `bub update` manage a separate uv project for Bub plugins, defaulting to `~/.bub/bub-project` or `BUB_PROJECT`.
142
+
143
+ ## Configuration
144
+
145
+ | Variable | Default | Description |
146
+ | --------------------------- | ---------------------------- | ---------------------------------------------------- |
147
+ | `BUB_MODEL` | `openrouter:openrouter/free` | Model identifier |
148
+ | `BUB_API_KEY` | — | Provider key (optional with `bub login openai`) |
149
+ | `BUB_API_BASE` | — | Custom provider endpoint |
150
+ | `BUB_API_FORMAT` | `completion` | `completion`, `responses`, or `messages` |
151
+ | `BUB_CLIENT_ARGS` | — | JSON object forwarded to the underlying model client |
152
+ | `BUB_MAX_STEPS` | `50` | Max tool-use loop iterations |
153
+ | `BUB_MAX_TOKENS` | `1024` | Max tokens per model call |
154
+ | `BUB_MODEL_TIMEOUT_SECONDS` | — | Model call timeout (seconds) |
155
+
156
+ ## Background
157
+
158
+ Bub is shaped by one constraint: real collaboration is messier than a solo demo. In shared environments, operators need visible boundaries, auditable history, and extension points that do not collapse into framework sprawl.
159
+
160
+ Read more:
161
+
162
+ - [Why We Rewrote Bub](https://bub.build/posts/why-rewrite-bub/)
163
+ - [Socialized Evaluation and Agent Partnership](https://bub.build/posts/socialized-evaluation/)
164
+ - [Context from Tape](https://tape.systems)
165
+
166
+ ## Docs
167
+
168
+ - [Getting Started](https://bub.build/docs/getting-started/) — install Bub and run the first turn
169
+ - [Architecture](https://bub.build/docs/concepts/architecture/) — the mental model behind the runtime
170
+ - [Channels](https://bub.build/docs/guides/channels/) — run Bub in CLI, Telegram, or your own channel
171
+ - [Skills](https://bub.build/docs/guides/skills/) — discover, inspect, and author Agent Skills in Bub
172
+ - [Extending](https://bub.build/docs/extending/) — write plugins, override hooks, ship tools and skills
173
+ - [Deployment](https://bub.build/docs/guides/deployment/) — Docker, environment, upgrades
174
+
175
+ ## Development
176
+
177
+ ```bash
178
+ make install
179
+ make check
180
+ make test
181
+ make docs
182
+ make docs-test
183
+ ```
184
+
185
+ See [CONTRIBUTING.md](https://github.com/bubbuild/bub/blob/main/CONTRIBUTING.md).
186
+
187
+ ## License
188
+
189
+ [Apache-2.0](https://github.com/bubbuild/bub/blob/main/LICENSE)
bub-0.3.7/README.md ADDED
@@ -0,0 +1,153 @@
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 hook-first runtime for agents that live alongside people.</strong></p>
11
+
12
+ </div>
13
+
14
+ 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.
15
+
16
+ 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 included but replaceable. The same runtime drives CLI, Telegram, and any channel you add.
17
+
18
+ [Website](https://bub.build) · [GitHub](https://github.com/bubbuild/bub)
19
+
20
+ ## Quick Start
21
+
22
+ ```bash
23
+ pip install bub
24
+ ```
25
+
26
+ Or from source:
27
+
28
+ ```bash
29
+ git clone https://github.com/bubbuild/bub.git
30
+ cd bub
31
+ uv sync # enough to run Bub from source
32
+ ```
33
+
34
+ For local development, use `make install` instead so the website toolchain and `prek` hooks are installed too.
35
+
36
+ ```bash
37
+ uv run bub chat # interactive session
38
+ uv run bub run "summarize this repo" # one-shot task
39
+ uv run bub gateway # channel listener mode
40
+ ```
41
+
42
+ ## Why Bub
43
+
44
+ - **Hook-first runtime.** Every turn stage is a hook. Override one stage or replace the whole flow without forking the runtime.
45
+ - **Tape context.** Context is rebuilt from append-only records, not carried around as mutable session state. Easier to inspect, replay, and hand off.
46
+ - **One runtime across surfaces.** The same inbound pipeline runs across CLI, Telegram, and custom channels. Adapters change the surface, not the runtime model.
47
+ - **Batteries included.** CLI, Telegram, tools, skills, and model execution ship with the core runtime. Use the defaults first, replace them later.
48
+ - **Operator equivalence.** Humans and agents work inside the same runtime boundaries, with the same evidence trail and handoff model. No hidden operator class.
49
+
50
+ ## How It Works
51
+
52
+ Every inbound message goes through one turn pipeline. Each stage is a hook.
53
+
54
+ ```
55
+ resolve_session → load_state → build_prompt → run_model
56
+
57
+ dispatch_outbound ← render_outbound ← save_state
58
+ ```
59
+
60
+ Builtins are registered first. External plugins load after them. At runtime, later plugins take precedence. There are no framework-only shortcuts.
61
+
62
+ Key source files:
63
+
64
+ - Turn orchestrator: [`src/bub/framework.py`](https://github.com/bubbuild/bub/blob/main/src/bub/framework.py)
65
+ - Hook contract: [`src/bub/hookspecs.py`](https://github.com/bubbuild/bub/blob/main/src/bub/hookspecs.py)
66
+ - Builtin hooks: [`src/bub/builtin/hook_impl.py`](https://github.com/bubbuild/bub/blob/main/src/bub/builtin/hook_impl.py)
67
+ - Skill discovery: [`src/bub/skills.py`](https://github.com/bubbuild/bub/blob/main/src/bub/skills.py)
68
+
69
+ ## Extend It
70
+
71
+ ```python
72
+ from bub import hookimpl
73
+
74
+
75
+ class EchoPlugin:
76
+ @hookimpl
77
+ def build_prompt(self, message, session_id, state):
78
+ return f"[echo] {message['content']}"
79
+
80
+ @hookimpl
81
+ async def run_model(self, prompt, session_id, state):
82
+ return prompt
83
+ ```
84
+
85
+ ```toml
86
+ [project.entry-points."bub"]
87
+ echo = "my_package.plugin:EchoPlugin"
88
+ ```
89
+
90
+ See the [Extending docs](https://bub.build/docs/extending/) for hook guides, packaging, and plugin structure.
91
+
92
+ ## CLI
93
+
94
+ | Command | Description |
95
+ | ------------------ | --------------------------------- |
96
+ | `bub chat` | Interactive REPL |
97
+ | `bub run MESSAGE` | One-shot turn |
98
+ | `bub gateway` | Channel listener (Telegram, etc.) |
99
+ | `bub install` | Install or sync Bub plugin deps |
100
+ | `bub update` | Upgrade Bub plugin deps |
101
+ | `bub login openai` | OpenAI Codex OAuth |
102
+
103
+ Lines starting with `,` enter internal command mode (`,help`, `,skill name=my-skill`, `,fs.read path=README.md`).
104
+
105
+ `bub hooks` still exists for diagnostics, but it is hidden from top-level help. `bub install` and `bub update` manage a separate uv project for Bub plugins, defaulting to `~/.bub/bub-project` or `BUB_PROJECT`.
106
+
107
+ ## Configuration
108
+
109
+ | Variable | Default | Description |
110
+ | --------------------------- | ---------------------------- | ---------------------------------------------------- |
111
+ | `BUB_MODEL` | `openrouter:openrouter/free` | Model identifier |
112
+ | `BUB_API_KEY` | — | Provider key (optional with `bub login openai`) |
113
+ | `BUB_API_BASE` | — | Custom provider endpoint |
114
+ | `BUB_API_FORMAT` | `completion` | `completion`, `responses`, or `messages` |
115
+ | `BUB_CLIENT_ARGS` | — | JSON object forwarded to the underlying model client |
116
+ | `BUB_MAX_STEPS` | `50` | Max tool-use loop iterations |
117
+ | `BUB_MAX_TOKENS` | `1024` | Max tokens per model call |
118
+ | `BUB_MODEL_TIMEOUT_SECONDS` | — | Model call timeout (seconds) |
119
+
120
+ ## Background
121
+
122
+ Bub is shaped by one constraint: real collaboration is messier than a solo demo. In shared environments, operators need visible boundaries, auditable history, and extension points that do not collapse into framework sprawl.
123
+
124
+ Read more:
125
+
126
+ - [Why We Rewrote Bub](https://bub.build/posts/why-rewrite-bub/)
127
+ - [Socialized Evaluation and Agent Partnership](https://bub.build/posts/socialized-evaluation/)
128
+ - [Context from Tape](https://tape.systems)
129
+
130
+ ## Docs
131
+
132
+ - [Getting Started](https://bub.build/docs/getting-started/) — install Bub and run the first turn
133
+ - [Architecture](https://bub.build/docs/concepts/architecture/) — the mental model behind the runtime
134
+ - [Channels](https://bub.build/docs/guides/channels/) — run Bub in CLI, Telegram, or your own channel
135
+ - [Skills](https://bub.build/docs/guides/skills/) — discover, inspect, and author Agent Skills in Bub
136
+ - [Extending](https://bub.build/docs/extending/) — write plugins, override hooks, ship tools and skills
137
+ - [Deployment](https://bub.build/docs/guides/deployment/) — Docker, environment, upgrades
138
+
139
+ ## Development
140
+
141
+ ```bash
142
+ make install
143
+ make check
144
+ make test
145
+ make docs
146
+ make docs-test
147
+ ```
148
+
149
+ See [CONTRIBUTING.md](https://github.com/bubbuild/bub/blob/main/CONTRIBUTING.md).
150
+
151
+ ## License
152
+
153
+ [Apache-2.0](https://github.com/bubbuild/bub/blob/main/LICENSE)
@@ -24,6 +24,7 @@ dependencies = [
24
24
  "pydantic-settings>=2.0.0",
25
25
  "pyyaml>=6.0.0",
26
26
  "pluggy>=1.6.0",
27
+ "inquirer-textual>=0.5.1",
27
28
  "typer>=0.9.0",
28
29
  "republic>=0.5.4",
29
30
  "any-llm-sdk[anthropic]",
@@ -33,6 +34,7 @@ dependencies = [
33
34
  "loguru>=0.7.2",
34
35
  "rapidfuzz>=3.14.3",
35
36
  "aiohttp>=3.13.3",
37
+ "httpx[socks]>=0.28.1",
36
38
  ]
37
39
 
38
40
  [project.urls]
@@ -55,10 +57,6 @@ dev = [
55
57
  "types-PyYAML>=6.0.12",
56
58
  "mypy>=0.991",
57
59
  "ruff>=0.11.5",
58
- "mkdocs>=1.4.2",
59
- "mkdocs-terminal>=4.7.0",
60
- "mkdocstrings[python]>=0.26.1",
61
- "rust-just>=1.42.0",
62
60
  "prek>=0.3.1",
63
61
  "pytest-asyncio>=1.3.0",
64
62
  ]
@@ -0,0 +1,37 @@
1
+ """Bub framework package."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ from importlib import import_module
7
+ from importlib.metadata import PackageNotFoundError
8
+ from importlib.metadata import version as metadata_version
9
+ from pathlib import Path
10
+ from typing import TYPE_CHECKING
11
+
12
+ from bub.configure import Settings, config, ensure_config
13
+ from bub.framework import DEFAULT_HOME, BubFramework
14
+ from bub.hookspecs import hookimpl
15
+ from bub.tools import tool
16
+
17
+ __all__ = ["BubFramework", "Settings", "config", "ensure_config", "home", "hookimpl", "tool"]
18
+
19
+ try:
20
+ __version__ = import_module("bub._version").version
21
+ except ModuleNotFoundError:
22
+ try:
23
+ __version__ = metadata_version("bub")
24
+ except PackageNotFoundError:
25
+ __version__ = "0.0.0"
26
+
27
+
28
+ if TYPE_CHECKING:
29
+ home: Path
30
+
31
+
32
+ def __getattr__(name: str):
33
+ if name == "home":
34
+ if "BUB_HOME" in os.environ:
35
+ return Path(os.environ["BUB_HOME"])
36
+ return DEFAULT_HOME
37
+ raise AttributeError(f"module {__name__} has no attribute {name}")
@@ -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.3.6'
22
- __version_tuple__ = version_tuple = (0, 3, 6)
21
+ __version__ = version = '0.3.7'
22
+ __version_tuple__ = version_tuple = (0, 3, 7)
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -56,12 +56,14 @@ class Agent:
56
56
 
57
57
  @cached_property
58
58
  def tapes(self) -> TapeService:
59
+ import bub
60
+
59
61
  tape_store = self.framework.get_tape_store()
60
62
  if tape_store is None:
61
63
  tape_store = InMemoryTapeStore()
62
64
  tape_store = ForkTapeStore(tape_store)
63
65
  llm = _build_llm(self.settings, tape_store, self.framework.build_tape_context())
64
- return TapeService(llm, self.settings.home / "tapes", tape_store)
66
+ return TapeService(llm, bub.home / "tapes", tape_store)
65
67
 
66
68
  @staticmethod
67
69
  def _events_from_iterable(iterable: Iterable) -> AsyncStreamEvents:
@@ -16,11 +16,23 @@ from urllib.request import url2pathname
16
16
 
17
17
  import typer
18
18
 
19
+ from bub import __version__, configure
19
20
  from bub.builtin.auth import app as login_app # noqa: F401
20
21
  from bub.channels.message import ChannelMessage
21
22
  from bub.envelope import field_of
22
23
  from bub.framework import BubFramework
23
24
 
25
+ ONBOARD_BANNER = r"""
26
+ ███████████ █████
27
+ ▒▒███▒▒▒▒▒███ ▒▒███
28
+ ▒███ ▒███ █████ ████ ▒███████
29
+ ▒██████████ ▒▒███ ▒███ ▒███▒▒███
30
+ ▒███▒▒▒▒▒███ ▒███ ▒███ ▒███ ▒███
31
+ ▒███ ▒███ ▒███ ▒███ ▒███ ▒███
32
+ ███████████ ▒▒████████ ████████
33
+ ▒▒▒▒▒▒▒▒▒▒▒ ▒▒▒▒▒▒▒▒ ▒▒▒▒▒▒▒▒ v{version}
34
+ """.strip("\n")
35
+
24
36
 
25
37
  def run(
26
38
  ctx: typer.Context,
@@ -92,6 +104,25 @@ def chat(
92
104
  asyncio.run(manager.listen_and_run())
93
105
 
94
106
 
107
+ def onboard(ctx: typer.Context) -> None:
108
+ """Interactively collect plugin configuration and write it to Bub's config file."""
109
+
110
+ framework = ctx.ensure_object(BubFramework)
111
+ typer.echo(ONBOARD_BANNER.format(version=__version__))
112
+ typer.echo("\nWelcome to Bub! Let's get you set up.\n")
113
+
114
+ try:
115
+ config_data = framework.collect_onboard_config()
116
+ configure.save(framework.config_file, config_data)
117
+ except (typer.Abort, typer.Exit):
118
+ raise
119
+ except Exception as exc:
120
+ typer.secho(f"Onboarding failed: {exc}", err=True, fg="red")
121
+ raise typer.Exit(1) from exc
122
+
123
+ typer.echo(f"Saved config to {framework.config_file}")
124
+
125
+
95
126
  @lru_cache(maxsize=1)
96
127
  def _find_uv() -> str:
97
128
  import shutil
@@ -106,10 +137,9 @@ def _find_uv() -> str:
106
137
 
107
138
  @lru_cache(maxsize=1)
108
139
  def _default_project() -> Path:
109
- from .settings import load_settings
140
+ import bub
110
141
 
111
- settings = load_settings()
112
- project = settings.home / "bub-project"
142
+ project = bub.home / "bub-project"
113
143
  project.mkdir(exist_ok=True, parents=True)
114
144
  return project
115
145