openclaw - ✅(Solved) Fix RFC: pi-embedded plugin tool-event subscription \u2014 stable seam for tool-call observation [1 pull requests, 1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#71427Fetched 2026-04-26 05:12:51
View on GitHub
Comments
1
Participants
2
Timeline
10
Reactions
0
Timeline (top)
cross-referenced ×8closed ×1commented ×1

Fix Action

Fix / Workaround

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.

Host dispatch (gateway-side, ~30 LOC)

PR fix notes

PR #71731: docs: add Plan Mode plugin host hook RFC

Description (problem / solution / changelog)

Summary

This PR is a maintainer RFC package for making Plan Mode a first-class bundled plugin without merging the large host patch from #71676.

  • Problem: #71676 proves Plan Mode behavior, but it embeds the feature across session state, gateway patching, agent turn preparation, pending injections, tool policy, commands, Control UI, agent events, scheduler/cron, heartbeat prompts, docs, QA, and channel flows.
  • Why it matters: maintainers prefer a plugin path. A plugin port cannot reach 100% parity unless OpenClaw first exposes generic host seams in the plugin SDK.
  • What changed: added an RFC packet, public index page, six issue-sized RFC threads, current-SDK gap research, reusable plugin matrices, a #71676 entry-point coverage map, and fixture-test expectations for a future implementation PR.
  • What did NOT change: this PR intentionally does not implement hooks, Plan Mode behavior, prompts, tools, UI cards, session fields, scheduler changes, or runtime SDK APIs.

RFC Status Warning

This is proposed SDK design, not implemented SDK reference. The docs now include explicit warning callouts, and the public page has been moved out of SDK reference into a dedicated Plugin design RFCs nav group.

RFC Decision Threads

  • #71732 — Plugin session extensions and patch actions
  • #71733 — Durable next-turn injections and agent turn preparation hooks
  • #71734 — Trusted tool policy stage and plugin tool metadata
  • #71735 — Scoped plugin commands, trusted command ownership, and continuation
  • #71736 — Control UI plugin contribution slots
  • #71737 — Agent events, run context, scheduler lifecycle, and heartbeat contributions

The issue bodies have been expanded so each thread includes: proposed/not-implemented status, current SDK surface, missing host seam, Plan Mode parity use, reusable non-Plan plugin examples, decisions needed, and fixture acceptance criteria.

RFC Contents

The full RFC packet covers:

  • current SDK research against existing hooks, using #71427 as the comparison bar
  • reusable SDK capability matrix across public SDK, trusted/bundled SDK, gateway protocol, UI descriptors, runner boundary, lifecycle cleanup, and fixture tests
  • plugin archetype matrix for approval workflows, deploy/release, budget guards, memory/context, review/CI, incidents/tickets, channel integrations, workspace policy, telemetry/exporters, and long-running jobs
  • #71676 entry-point coverage map for Plan Mode parity
  • per-hook TypeScript-shaped API sketches
  • expected host files for each implementation slice
  • authorization, trust-tier, disablement, cleanup, and failure semantics
  • fixture-plugin acceptance tests for the future hook implementation PR
  • Plan Mode migration sequence and parity checklist

Change Type

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • Related #71676
  • Related #71732
  • Related #71733
  • Related #71734
  • Related #71735
  • Related #71736
  • Related #71737
  • This PR fixes a bug or regression

Verification

Verified locally:

  • pnpm format:docs:check
  • pnpm lint:docs
  • pnpm docs:check-mdx
  • pnpm docs:check-links

Human Verification

  • Confirmed the docs nav no longer places the proposal under stable SDK reference.
  • Confirmed both docs pages warn that the named APIs are proposed, not implemented.
  • Confirmed the RFC packet includes a #71676 entry-point coverage map.
  • Confirmed all six live issue bodies are expanded beyond Plan Mode-only examples.
  • Did not run runtime Plan Mode behavior because this PR is docs/RFC-only and implements no hooks.

Compatibility / Migration

  • Backward compatible? Yes, docs-only.
  • Config/env changes? No.
  • Migration needed? No.

Risks and Mitigations

  • Risk: reviewers mistake the RFC for implemented SDK reference.
    • Mitigation: warning callouts plus Plugin design RFCs nav placement.
  • Risk: proposal appears Plan Mode-specific.
    • Mitigation: reusable SDK matrices, non-Plan plugin examples, and expanded issue bodies.
  • Risk: proposal overclaims parity.
    • Mitigation: #71676 entry-point coverage map and explicit note that actual parity requires the future hook implementation PR plus fixture tests.

Next Step After This PR

If maintainers accept the RFC direction, the next PR should implement the generic host hooks with a tiny fixture plugin. Only after that should Plan Mode itself move into a bundled plugin and be audited against #71676 for parity.

Changed files

  • docs/docs.json (modified, +4/-0)
  • docs/plan/plan-mode-plugin-host-hooks-rfc.md (added, +1289/-0)
  • docs/plugins/plan-mode-plugin-host-hooks.md (added, +492/-0)

Code Example

// 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
});

---

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, ... });
RAW_BUFFERClick to expand / collapse

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:

  • openclaw/openclaw#71260 (mergeSessionEntryWithPolicy)
  • openclaw/openclaw#71426 (sessions.patch extension hook)

extent analysis

TL;DR

Add before_tool_call_persist and after_tool_call_persist lifecycle events to the plugin SDK to allow plugins to observe tool execution events without modifying the host's tool-execution dispatcher.

Guidance

  • Introduce the two new lifecycle events in the plugin SDK, before_tool_call_persist and after_tool_call_persist, with the proposed ToolCallPersistEvent type.
  • Update the pi-embedded-subscribe.handlers.tools.ts file to dispatch these events at the corresponding points in the persistToolCall flow.
  • Verify that plugins can subscribe to these events and receive the expected data by writing tests for event dispatch and plugin subscription.
  • Ensure backward compatibility by making the changes additive, allowing existing plugins to continue functioning without modification.

Example

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
});

Notes

The proposed changes aim to eliminate the need for patching the host's tool-execution dispatcher, reducing version-bump fragility and allowing for a more maintainable plugin/host seam.

Recommendation

Apply the proposed workaround by adding the before_tool_call_persist and after_tool_call_persist lifecycle events to the plugin SDK, as it provides a more elegant and maintainable solution for plugins to observe tool execution events.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - ✅(Solved) Fix RFC: pi-embedded plugin tool-event subscription \u2014 stable seam for tool-call observation [1 pull requests, 1 comments, 2 participants]