-
Notifications
You must be signed in to change notification settings - Fork 158
Context
bub allows external harness agents (e.g. Codex, Kimi Copilot) to be plugged in via the run_model hook, replacing the default built-in agent. This is a great extension point.
As I understand it, bub's plugin system provides a set of tools (e.g. tape.handoff, schedule.add) that are currently only callable by the built-in agent. When an external harness is used, these capabilities appear to be unavailable.
Similarly, bub's tape records fine-grained execution details for the built-in agent, but the internal execution of an external harness is opaque to the framework -- tape has no visibility into what happens inside the harness session.
I don't think bub's goal is to have everyone use the built-in agent, nor to require harness implementors to reimplement the framework's internals from scratch. So I'd like to discuss two aspects:
1. Exposing framework tools to external harnesses
How can an external harness discover and invoke framework-provided tools (schedule, tape operations, etc.) after being plugged in?
One possible direction: expose these tools via a remote call interface (e.g. HTTP or MCP), allowing harnesses to call them through a standard protocol without needing to understand bub's internals.
2. Tape integration with external harnesses
External harnesses have their own internal loop (session). How can their execution be represented in the tape?
A possible starting point: record at a coarse granularity at the run_model level, where a tape anchor corresponds to a harness session. This could be refined over time, allowing implementors to report more detail as needed.
Not sure if this aligns with bub's current design direction -- putting it out there for discussion.
All reactions
Replies: 4 comments 6 replies
Here's the approach I've been using when integrating Codex:
I wrote a channel plugin that allows external processes to deliver messages to a specified session via HTTP. This enables Codex, combined with a handoff skill, to invoke framework commands through the , prefix convention — for example, posting ,tape.handoff ... via the channel plugin to trigger the framework command.
Additionally, my approach maps one anchor to one Codex session (thread) lifecycle. Codex triggers ,tape.handoff through the channel plugin to create a new anchor, signaling that the current session has ended and the next turn should start a new session. (A codex.thread event is appended after the anchor, storing the thread ID internally.)
The entire solution is implemented through hooks, with no modifications to bub core.
All reactions
Another benefit of this channel plugin is that it allows message delivery outside of the run_model loop. For example, I can use cron + HTTP calls to the channel plugin to implement scheduled tasks. The motivation here is that Codex cannot directly call APScheduler — but with the channel plugin, any process that can make an HTTP request can trigger framework actions, making cron a viable alternative for scheduling.
All reactions
@frostming @PsiACE Hi, would appreciate your input on this when you get a chance. 🙏
All reactions
Sorry that I only got time to look into this discussion today.
I think you have thought this through carefully, and I also checked your previous work on bub-contrib. Overall, I think the direction makes sense. For integrating external harness agents with bub, there are probably a few layers we can support, depending on how tightly the harness wants to integrate.
For exposing bub’s internal tools to other agents, I see a few typical approaches:
- For a specific framework or harness, expose bub capabilities as the tool definitions that framework already understands.
- Add a
servecapability tobub-mcp, so built-in bub tools can be exposed through MCP. - Use comma commands, just like how a human would invoke them. Your current channel-plugin approach is a good example of this path.
For tape integration, I think there are also a few possible shapes:
- Treat tape as an index/memory: record key thread/session IDs and metadata, then use
xurlor similar mechanisms to guide the agent to read the original external context when needed. - Use a 1:1 mapping between an external session/thread and a tape anchor, which is close to what you described with Codex.
- For deeper integration, external tools/frameworks can transcribe their internal events into tape through observability hooks or event handlers.
So I don’t think bub needs to force one single model here. The lightweight version is "external harness + comma command + coarse tape anchor"; the more integrated version is "framework-native tools/MCP + structured event transcription into tape".
All reactions
Thanks for the thoughtful reply!
Through my recent work adapting external harnesses, I've come to appreciate how flexible bub's hook system is — it lets me do a lot without touching bub core.
This discussion mainly came from questions I had while exploring external harness integration. The existing plugin reference for this is still relatively minimal and doesn't fully leverage bub and tape's capabilities (e.g., being limited to communicating within a single fixed Codex thread).
I haven't explored the MCP plugin much yet — finding a good way to expose tools through it is something I still need to dig into. Tape integration feels more flexible with more room to experiment.
Once I've done some more validation and debugging, I'd be happy to contribute this as a reference integration approach if the community finds it useful.
All reactions
-
👍 1
On a side note — for your own daily usage, do you stick with the built-in run_model implementation, or do you have a custom one plugged in?
All reactions
builtin most of the time. I’ve been trying to work with LangChain and ACP (experimental). and I noticed visual-base work with bub-kimi , ref https://github.com/oilbeater/visual-base
All reactions
-
👍 1
I agree to make bub a MCP server. But how do external harness record internal events into the tape?
All reactions
I agree to make bub a MCP server. But how do external harness record internal events into the tape?
If tape could serve as a harness-agnostic neutral event format, that would be very appealing — in theory it would allow switching between different harness implementations on the same tape. But I'm not sure about the feasibility and cost of integrating fine-grained events from each harness.
After seeing projects like xurl, I think "tape as session index + xurl for on-demand context retrieval" could also work.
To be honest, I haven't fully figured out what tape's role should be for external harnesses. Is it just audit/replay? A portability layer for switching harnesses? The complication is that things like compaction and session lifecycle are controlled by the external harness, outside bub's governance.
All reactions
(There are so many agent/harness implementations out there now. For me, I'd rather use bub to quickly piece them together like building blocks for experimentation, instead of writing yet another one myself. Beyond Codex, I'm also looking to integrate pi-core into bub. But how does tape remain a first-class citizen in this model? And how should tools integrate with other harnesses? I guess that's really been my underlying question all along....)