fix: pass session context to plugin tool hooks in toToolDefinitions#19422
fix: pass session context to plugin tool hooks in toToolDefinitions#19422namabile wants to merge 1 commit intoopenclaw:mainfrom
Conversation
Additional Comments (1)
The success path passes the raw (un-normalized) A plugin hook that keys on The regression tests don't expose this because Consider using Prompt To Fix With AIThis is a comment left during a code review.
Path: src/agents/pi-tool-definition-adapter.ts
Line: 129:137
Comment:
**Inconsistent `toolName` between success and error `after_tool_call` contexts**
The success path passes the raw (un-normalized) `name` as `toolName` in both the event and context objects (lines 129, 134), while the error path passes `normalizedName` (lowercased/aliased) at lines 179 and 184.
A plugin hook that keys on `toolName` for per-session access control — the primary use case this PR enables — will receive different values for the same tool depending on whether execution succeeded or failed. For example, a tool named `"MyPluginTool"` would appear as `"MyPluginTool"` on success but as `"mypluginTool"` (or its alias) on error.
The regression tests don't expose this because `"my_plugin_tool"` and `"failing_tool"` are already lowercase and unchanged by normalization.
Consider using `normalizedName` consistently on the success path to match the error path.
How can I resolve this? If you propose a fix, please make it concise. |
4ec8a93 to
0c6e4b8
Compare
…penclaw#19381) Plugin-registered tools that go through toToolDefinitions without being wrapped by wrapToolWithBeforeToolCallHook received undefined agentId and sessionKey in their before_tool_call and after_tool_call hooks, breaking per-session access control in plugin hooks. Thread hookContext (agentId, sessionKey) through toToolDefinitions → splitSdkTools → embedded runner callers so the adapter passes session identity to runBeforeToolCallHook and runAfterToolCall for all tools. Closes openclaw#19381
0c6e4b8 to
16dd9d6
Compare
|
This pull request has been automatically marked as stale due to inactivity. |
|
Closing as superseded/obsolete. Why:
Keeping this as historical reference: |
Summary
Fixes #19381
Plugin-registered tools that go through
toToolDefinitionswithout being pre-wrapped bywrapToolWithBeforeToolCallHookreceiveundefinedfor bothagentIdandsessionKeyin theirbefore_tool_callandafter_tool_callhooks, making per-session access control impossible.Root cause
toToolDefinitionshas a fallback path (line 103-108) for unwrapped tools that callsrunBeforeToolCallHookwithout passingctx. Additionally,after_tool_callhooks (both success and error paths) only pass{ toolName }as context, neveragentId/sessionKey.Changes
src/agents/pi-tool-definition-adapter.ts: Accept optionalhookContextparameter intoToolDefinitions. Pass it torunBeforeToolCallHookfor unwrapped tools and includeagentId/sessionKeyin allafter_tool_callhook contexts.src/agents/pi-embedded-runner/tool-split.ts: ForwardhookContextthroughsplitSdkToolstotoToolDefinitions.src/agents/pi-embedded-runner/run/attempt.ts: PasssessionAgentId/sessionKeyas hook context tosplitSdkTools.src/agents/pi-embedded-runner/compact.ts: PasssessionAgentId/sessionKeyas hook context tosplitSdkTools.src/agents/pi-tool-definition-adapter.hook-context.test.ts: 4 regression tests covering:before_tool_callreceivesagentId/sessionKeyfor unwrapped toolsafter_tool_callreceives context on successafter_tool_callreceives context on errorhookContextis providedTest plan
pnpm format:check— cleanpnpm tsgo— cleanpnpm lint— 0 warnings, 0 errorsGreptile Summary
This PR correctly fixes the root cause described in issue #19381: plugin tools processed through
toToolDefinitionswithout being pre-wrapped bywrapToolWithBeforeToolCallHookwere receivingundefinedforagentIdandsessionKeyin theirbefore_tool_callandafter_tool_callhooks, making per-session access control impossible. The fix threads an optionalhookContextparameter throughsplitSdkTools→toToolDefinitionsand wires it into all three hook invocation sites. Both call sites (attempt.tsandcompact.ts) are updated consistently.Key observations:
undefinedfallback).after_tool_callsuccess path passes the raw, un-normalized toolnameastoolNamein both event payload and context (lines 129, 134), while the error path passesnormalizedName(lines 179, 184). Since plugins can now rely ontoolNamein the hook context for access control routing, receiving different values for the same tool depending on success vs. failure is a correctness hazard."my_plugin_tool","failing_tool"), which are unchanged bynormalizeToolName, so thenamevs.normalizedNamediscrepancy is not caught.Confidence Score: 3/5
Last reviewed commit: 4ec8a93