Choose an extension point
Start with the behavior you want to add. A new action needs a tool; a new place to receive messages needs a channel. You can combine these capabilities without giving them the same job.
| You want to | Use | Where it belongs |
|---|---|---|
| Let the agent query or change something | A tool. | Shared core capability. Pass it to Agent, or register it with the app. |
| Observe or intercept a model or tool call | An event handler. | Core EventBus; app plugins can use the corresponding interception hooks. |
| Change which history becomes model messages | A TapeContext. | Pass it to Agent, or provide it through an app hook. |
| Teach a reusable procedure | A skill. | Discovered and loaded by the Bub application. |
| Change application setup or message processing | A plugin. | BubFramework and its hooks. |
| Connect a messaging service | A channel. | The application’s inbound and outbound routing. |
Actions and instructions
Section titled “Actions and instructions”A tool executes Python and returns a result. A skill is a directory containing SKILL.md and optional supporting files. Its instructions can tell the agent how to use tools. You supply the Python implementations those instructions refer to separately.
Plain Agent uses the tools and prompt sections you supply. The Bub application discovers skills and reads AGENTS.md; see Skills and Application tools.
A tool can also be called by a text command or by generated Python through CodeMode. These invocation paths share the same tool implementation.
Messages and application state
Section titled “Messages and application state”Channels deliver an inbound envelope and send outbound envelopes. The application uses these envelopes for content, routing, and session identity. Its hooks share a mutable TurnState dictionary for the current turn.
The application turn pipeline prepares that state and prompt before it calls the agent. Direct SDK callers supply their prompt and state to Agent themselves.
Choose dependencies for the capabilities you need, and choose the calling interface for your host. A Python service can reuse application plugins while retaining its own request handling and streams. Reuse plugins in your agent shows direct component reuse and how framework hooks fit into an embedded host.