mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-17 14:01:18 +00:00
feat(coding-agent): add event bus for tool/hook communication (#431)
* feat(coding-agent): add event bus for tool/hook communication Adds pi.events API enabling custom tools and hooks to communicate via pub/sub. Tools can emit events, hooks can listen. Shared EventBus instance created per session in createAgentSession(). - EventBus interface with emit() and on() methods - on() returns unsubscribe function - Threaded through hook and tool loaders - Documented in hooks.md and custom-tools.md * fix(coding-agent): wrap event handlers to catch errors * docs: note async handler error handling for event bus * feat(coding-agent): add sendMessage to tools, nextTurn delivery mode - Custom tools now have pi.sendMessage() for direct agent notifications - New deliverAs: 'nextTurn' queues messages for next user prompt - Fix: hooks and tools now share the same eventBus (was isolated before) * fix(coding-agent): nextTurn delivery should always queue, even when streaming
This commit is contained in:
parent
12805f61bd
commit
9c9e6822e3
13 changed files with 293 additions and 33 deletions
|
|
@ -159,6 +159,8 @@ interface CustomToolAPI {
|
|||
exec(command: string, args: string[], options?: ExecOptions): Promise<ExecResult>;
|
||||
ui: ToolUIContext;
|
||||
hasUI: boolean; // false in --print or --mode rpc
|
||||
events: EventBus; // Shared event bus for tool/hook communication
|
||||
sendMessage(message, options?): void; // Send messages to the agent session
|
||||
}
|
||||
|
||||
interface ToolUIContext {
|
||||
|
|
@ -184,6 +186,52 @@ interface ExecResult {
|
|||
|
||||
Always check `pi.hasUI` before using UI methods.
|
||||
|
||||
### Event Bus
|
||||
|
||||
Tools can emit events that hooks (or other tools) listen for via `pi.events`:
|
||||
|
||||
```typescript
|
||||
// Emit an event
|
||||
pi.events.emit("mytool:completed", { result: "success", itemCount: 42 });
|
||||
|
||||
// Listen for events (tools can also subscribe)
|
||||
const unsubscribe = pi.events.on("other:event", (data) => {
|
||||
console.log("Received:", data);
|
||||
});
|
||||
```
|
||||
|
||||
Events are session-scoped. Use namespaced channel names like `"toolname:event"` to avoid collisions.
|
||||
|
||||
Handler errors are caught and logged. For async handlers, handle errors internally:
|
||||
|
||||
```typescript
|
||||
pi.events.on("mytool:event", async (data) => {
|
||||
try {
|
||||
await doSomething(data);
|
||||
} catch (err) {
|
||||
console.error("Handler failed:", err);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### Sending Messages
|
||||
|
||||
Tools can send messages to the agent session via `pi.sendMessage()`:
|
||||
|
||||
```typescript
|
||||
pi.sendMessage({
|
||||
customType: "mytool-notify",
|
||||
content: "Configuration was updated",
|
||||
display: true,
|
||||
}, {
|
||||
deliverAs: "nextTurn",
|
||||
});
|
||||
```
|
||||
|
||||
**Delivery modes:** `"steer"` (default) interrupts streaming, `"followUp"` waits for completion, `"nextTurn"` queues for next user message. Use `triggerTurn: true` to wake an idle agent immediately.
|
||||
|
||||
See [hooks documentation](hooks.md#pisendmessagemessage-options) for full details.
|
||||
|
||||
### Cancellation Example
|
||||
|
||||
Pass the `signal` from `execute` to `pi.exec` to support cancellation:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue