Problem statement
Plugins that need to observe tool execution events (tool start/end/persist, with the agent context) currently have to patch src/agents/pi-embedded-subscribe.handlers.tools.ts to add a hook callout. The file is the host's tool-execution dispatcher; modifying it requires re-baselining on every host version that touches it.
Smarter-Claw maintains installer/patches/core/pi-embedded-subscribe-exit-plan-mode-emit.diff for this exact purpose — to wire plan-mode tool emission events to the plugin so it can persist plan archetype markdown, drain injection queues, etc.
Proposed change
Add before_tool_call_persist and after_tool_call_persist lifecycle events to the plugin SDK, callable via the existing api.on(...) pattern.
SDK contract (additive)
// In existing plugin-sdk/lifecycle types
export type ToolCallPersistEvent = {
sessionKey: string;
agentId: string;
toolName: string;
toolCallId: string;
toolInput: unknown; // raw tool input
toolResult: unknown; // raw tool output (after_ only)
messageId: string; // upstream message id
};
// Plugins subscribe:
api.on("before_tool_call_persist", async (event: ToolCallPersistEvent) => {
// observe; return modifications via api.runtime.* if needed
});
api.on("after_tool_call_persist", async (event: ToolCallPersistEvent) => {
// observe persisted result
});
Host dispatch (gateway-side, ~30 LOC)
In the existing pi-embedded-subscribe.handlers.tools.ts:persistToolCall flow:
await pluginRegistry.dispatch("before_tool_call_persist", { sessionKey, agentId, toolName, ... });
const persisted = await persistToolResult(...);
await pluginRegistry.dispatch("after_tool_call_persist", { sessionKey, agentId, toolName, toolResult: persisted, ... });
Backward compatibility
Fully additive. Existing plugins that don't subscribe see no change.
What this saves Smarter-Claw
- Delete
installer/patches/core/pi-embedded-subscribe-exit-plan-mode-emit.diff (~80 LOC)
- Move tool-event subscription out of host patch into typed plugin code
- Eliminate version-bump fragility for this seam
The two events together cover the same surface area as our current patch (which observes tool persist transitions for plan-mode state changes).
Tests proposed
- Plugin subscribes to before_tool_call_persist; verify event dispatched with all fields populated for any tool call
- Plugin subscribes to after_tool_call_persist; verify dispatched after persist completes with toolResult populated
- Plugin handler throws → host logs and continues (best-effort observer pattern)
- Multiple plugins subscribed → all dispatched (registration order)
Cross-link
Smarter-Claw filing: this is RFC #3 of a series pushing the plugin/host seam upstream. Sister RFCs:
Problem statement
Plugins that need to observe tool execution events (tool start/end/persist, with the agent context) currently have to patch
src/agents/pi-embedded-subscribe.handlers.tools.tsto add a hook callout. The file is the host's tool-execution dispatcher; modifying it requires re-baselining on every host version that touches it.Smarter-Claw maintains
installer/patches/core/pi-embedded-subscribe-exit-plan-mode-emit.difffor this exact purpose — to wire plan-mode tool emission events to the plugin so it can persist plan archetype markdown, drain injection queues, etc.Proposed change
Add
before_tool_call_persistandafter_tool_call_persistlifecycle events to the plugin SDK, callable via the existingapi.on(...)pattern.SDK contract (additive)
Host dispatch (gateway-side, ~30 LOC)
In the existing
pi-embedded-subscribe.handlers.tools.ts:persistToolCallflow:Backward compatibility
Fully additive. Existing plugins that don't subscribe see no change.
What this saves Smarter-Claw
installer/patches/core/pi-embedded-subscribe-exit-plan-mode-emit.diff(~80 LOC)The two events together cover the same surface area as our current patch (which observes tool persist transitions for plan-mode state changes).
Tests proposed
Cross-link
Smarter-Claw filing: this is RFC #3 of a series pushing the plugin/host seam upstream. Sister RFCs: