[plugin sdk] Add session action gateway protocol#75578
Conversation
|
Thanks for the context here. I swept through the related work, and this is now duplicate or superseded. Close as superseded: the author explicitly moved this session-action split into the open Plugin SDK consolidation PR, and that canonical PR now owns the combined implementation, proof, and review thread. So I’m closing this here and keeping the remaining discussion on the canonical linked item. Review detailsBest possible solution: Consolidate review and any remaining fixes in #80229 instead of keeping this older split branch open as a parallel merge candidate. Do we have a high-confidence way to reproduce the issue? Not applicable. This is an additive Plugin SDK/Gateway API PR; current main does not expose Is this the best way to solve the issue? Yes. Closing this PR in favor of #80229 is the narrowest cleanup path because the newer open PR explicitly owns this session-action slice plus its combined proof and review context. Security review: Security review cleared: No concrete supply-chain or secrets-handling concern is unique to this superseded split PR; the sensitive Gateway scope behavior is now owned by the canonical consolidation review. What I checked:
Likely related people:
Codex review notes: model gpt-5.5, reasoning high; reviewed against 24edb8414662. |
6b1fce6 to
80fba14
Compare
f7aa65f to
ce5867c
Compare
|
Fixed in |
ce5867c to
709c69a
Compare
There was a problem hiding this comment.
Pull request overview
Adds a new Plugin SDK/Gateway seam for typed session actions plus plugin-attributed agent event emission, enabling plugins to register actions that trusted Gateway clients can dispatch via plugins.sessionAction, with per-action operator-scope enforcement and payload/result validation.
Changes:
- Extends the Plugin SDK API with
registerSessionAction(...)andemitAgentEvent(...)(plus exported types) and wires these into the plugin registry/loader snapshots. - Implements
plugins.sessionActionGateway handler with request validation, schema validation, per-action scope checks, stale-plugin blocking, and action-result shape validation. - Updates Gateway protocol schemas/types (including generated Swift models) and adds focused contract + method-scope coverage.
Reviewed changes
Copilot reviewed 25 out of 25 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/plugins/types.ts | Exposes new SDK API surface/types (emitAgentEvent, registerSessionAction) via OpenClawPluginApi. |
| src/plugins/registry.ts | Adds session-action registration/validation + wires emitAgentEvent into registry-built plugin APIs. |
| src/plugins/registry-types.ts | Introduces PluginSessionActionRegistryRegistration and adds sessionActions to the registry shape. |
| src/plugins/registry-empty.ts | Initializes sessionActions in the empty registry. |
| src/plugins/loader.ts | Snapshots/restores sessionActions across plugin loader snapshot/restore. |
| src/plugins/host-hooks.ts | Defines session action context/registration/result types and agent-event emit param/result types. |
| src/plugins/contracts/session-actions.contract.test.ts | Adds contract tests for registration validation, dispatch auth/schema checks, result validation, stale plugin blocking, and event emission. |
| src/plugins/captured-registration.ts | Captures session-action registrations and adds a stub emitAgentEvent for captured registrations. |
| src/plugins/api-builder.ts | Extends buildPluginApi wiring with no-op defaults for emitAgentEvent and registerSessionAction. |
| src/plugins/agent-event-emission.ts | Implements plugin-origin-aware agent event emission and reserved-stream restrictions. |
| src/plugin-sdk/plugin-test-api.ts | Adds test API stubs for emitAgentEvent and registerSessionAction. |
| src/plugin-sdk/plugin-entry.ts | Re-exports new session-action types from the plugin entry surface. |
| src/plugin-sdk/core.ts | Re-exports new session-action types from the core SDK surface. |
| src/gateway/server-methods/plugin-host-hooks.ts | Adds plugins.sessionAction Gateway method implementation with validation, auth, schema checks, and result shaping. |
| src/gateway/server-methods-list.ts | Registers plugins.sessionAction as a supported Gateway method. |
| src/gateway/protocol/schema/types.ts | Adds protocol schema type exports for session-action params/result. |
| src/gateway/protocol/schema/protocol-schemas.ts | Registers the new session-action schemas in the protocol schema map. |
| src/gateway/protocol/schema/plugins.ts | Adds session-action schemas and tightens PluginJsonValueSchema to a recursive JSON-value shape. |
| src/gateway/protocol/index.ts | Compiles/exports validator for PluginsSessionActionParams and exports schema/types for session actions. |
| src/gateway/method-scopes.ts | Classifies plugins.sessionAction as dynamically-scoped with a CLI-safe default. |
| src/gateway/method-scopes.test.ts | Tests dynamic classification/authorization behavior for plugins.sessionAction. |
| docs/.generated/plugin-sdk-api-baseline.sha256 | Updates the plugin SDK API baseline hashes to reflect the new public API surface. |
| apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift | Adds generated Swift models for PluginsSessionActionParams/Result. |
| apps/macos/Sources/OpenClawProtocol/GatewayModels.swift | Adds generated Swift models for PluginsSessionActionParams/Result. |
| CHANGELOG.md | Notes the new session-action dispatch and plugin-attributed event emission feature. |
There was a problem hiding this comment.
Pull request overview
This PR introduces a new Plugin SDK ↔ Gateway “session action” seam, allowing plugins to register typed session actions that trusted clients can dispatch via plugins.sessionAction, with operator-scope enforcement at dispatch time. It also adds a plugin API for emitting plugin-attributed agent events for workflow/UI consumers, plus protocol/schema/client updates and focused contract tests.
Changes:
- Add
OpenClawPluginApi.registerSessionAction(...)and registry storage/snapshot support for session actions. - Add Gateway method
plugins.sessionActionwith request validation, payload schema validation, scope checks, and typed success/failure result handling. - Add
OpenClawPluginApi.emitAgentEvent(...)(plugin-attributed event emission) plus supporting types/tests and generated protocol client models.
Reviewed changes
Copilot reviewed 25 out of 25 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/plugins/types.ts | Exports new session-action and agent-event emission types; extends OpenClawPluginApi. |
| src/plugins/registry.ts | Adds session action registration, validation, duplicate detection, and wires emitAgentEvent into plugin API. |
| src/plugins/registry-types.ts | Adds PluginSessionActionRegistryRegistration and registry storage field. |
| src/plugins/registry-empty.ts | Initializes sessionActions to an empty array. |
| src/plugins/loader.ts | Includes sessionActions in registry snapshot/restore. |
| src/plugins/host-hooks.ts | Defines session action context/result/registration types + agent event emit types. |
| src/plugins/contracts/session-actions.contract.test.ts | Contract tests for registration validation, dispatch, payload schema validation, scope enforcement, stale-plugin blocking, and event emission. |
| src/plugins/captured-registration.ts | Captures registerSessionAction calls and stubs emitAgentEvent for test capture. |
| src/plugins/api-builder.ts | Adds emitAgentEvent and registerSessionAction handlers/noops to the plugin API builder. |
| src/plugins/agent-event-emission.ts | Implements plugin-attributed agent event emission with stream restrictions by plugin origin. |
| src/plugin-sdk/plugin-test-api.ts | Extends test plugin API with emitAgentEvent and registerSessionAction. |
| src/plugin-sdk/plugin-entry.ts | Re-exports new session action types from SDK entry surface. |
| src/plugin-sdk/core.ts | Re-exports new session action types from SDK core surface. |
| src/gateway/server-methods/plugin-host-hooks.ts | Implements plugins.sessionAction handler (validation, authZ, schema validation, result shaping). |
| src/gateway/server-methods-list.ts | Registers plugins.sessionAction in the Gateway method list. |
| src/gateway/protocol/schema/types.ts | Adds protocol types for PluginsSessionActionParams/Result. |
| src/gateway/protocol/schema/protocol-schemas.ts | Registers the new session action schemas in ProtocolSchemas. |
| src/gateway/protocol/schema/plugins.ts | Adds JSON-value schema, session action params/result schemas. |
| src/gateway/protocol/index.ts | Exposes schemas/types and compiles validator for PluginsSessionActionParams. |
| src/gateway/method-scopes.ts | Treats plugins.sessionAction as dynamically scoped (CLI-safe default, permissive method-level classification). |
| src/gateway/method-scopes.test.ts | Adds coverage for dynamic classification behavior of plugins.sessionAction. |
| docs/.generated/plugin-sdk-api-baseline.sha256 | Updates SDK API baseline hashes. |
| apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift | Adds generated Swift models for plugins.sessionAction. |
| apps/macos/Sources/OpenClawProtocol/GatewayModels.swift | Adds generated Swift models for plugins.sessionAction (macOS target). |
| CHANGELOG.md | Documents the new plugins.sessionAction and emitAgentEvent support. |
There was a problem hiding this comment.
Pull request overview
Adds the “session action” Gateway seam for the Plugin SDK: plugins can register typed session actions, clients can dispatch them via plugins.sessionAction, and plugins can emit plugin-attributed agent events via emitAgentEvent.
Changes:
- Extend
OpenClawPluginApiwithregisterSessionAction(...)andemitAgentEvent(...), and plumb registrations through the plugin registry/loader (snapshot + restore). - Add
plugins.sessionActionGateway method with request validation, per-action payload schema validation, action-result validation, and per-action scope enforcement. - Add protocol schemas/types + generated Swift models, plus focused contract/unit coverage for registration, validation, auth, and stale-plugin blocking.
Reviewed changes
Copilot reviewed 25 out of 25 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/plugins/types.ts | Exposes new Plugin API methods and re-exports session-action / event-emission types. |
| src/plugins/registry.ts | Adds session action registration + schema validation and wires emitAgentEvent. |
| src/plugins/registry-types.ts | Extends registry types with sessionActions storage. |
| src/plugins/registry-empty.ts | Initializes sessionActions in empty registries. |
| src/plugins/loader.ts | Includes sessionActions in registry snapshot/restore. |
| src/plugins/host-hooks.ts | Introduces session action context/result/registration types and event-emission param/result types. |
| src/plugins/contracts/session-actions.contract.test.ts | Contract coverage for action registration, schema validation, typed results, auth, stale-plugin blocking, and event emission. |
| src/plugins/captured-registration.ts | Captures session action registrations and stubs emitAgentEvent for captured APIs. |
| src/plugins/api-builder.ts | Adds no-op wiring for emitAgentEvent and registerSessionAction in API builder. |
| src/plugins/agent-event-emission.ts | Implements plugin-attributed agent-event emission with stream scoping rules. |
| src/plugin-sdk/plugin-test-api.ts | Extends test plugin API with emitAgentEvent + registerSessionAction. |
| src/plugin-sdk/plugin-entry.ts | Exports session action types for plugin authors via the SDK entry surface. |
| src/plugin-sdk/core.ts | Re-exports session action types via the main plugin-sdk surface. |
| src/gateway/server-methods/plugin-host-hooks.ts | Adds plugins.sessionAction handler: validates params, enforces scopes, validates payload/results, dispatches handler. |
| src/gateway/server-methods-list.ts | Registers plugins.sessionAction as a gateway method. |
| src/gateway/protocol/schema/types.ts | Adds protocol type aliases for session action params/result. |
| src/gateway/protocol/schema/protocol-schemas.ts | Adds session action schemas to the protocol schema map. |
| src/gateway/protocol/schema/plugins.ts | Defines PluginsSessionAction* schemas and refines PluginJsonValueSchema. |
| src/gateway/protocol/index.ts | Compiles validator for PluginsSessionActionParams and exports new protocol types/schemas. |
| src/gateway/method-scopes.ts | Treats plugins.sessionAction as dynamically scoped with CLI-safe defaults and runtime enforcement. |
| src/gateway/method-scopes.test.ts | Tests dynamic classification/authorization behavior for plugins.sessionAction. |
| docs/.generated/plugin-sdk-api-baseline.sha256 | Updates SDK API baseline hashes. |
| apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift | Adds generated Swift models for session action params/result. |
| apps/macos/Sources/OpenClawProtocol/GatewayModels.swift | Adds generated Swift models for session action params/result. |
| CHANGELOG.md | Documents the new session action dispatch + emitAgentEvent capability. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c59c3dad98
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Audit follow-up fixed in |
|
@clawsweeper re-review Follow-up fix on head |
84d38f1 to
faae398
Compare
|
Superseded by #80229, which now carries the combined proof and merge-ready consolidation branch. |
Why this matters
OpenClaw plugins increasingly need typed actions that the host can expose and dispatch: approve a workflow, reopen a case, accept extracted data, retry a run, continue an agent after a human decision, or branch a workflow from a structured operator choice.
Without a generic seam, plugin authors end up with two bad options:
This PR adds the missing middle layer: plugins register typed session actions once, the Gateway exposes one stable dispatch method, and OpenClaw keeps ownership of schema validation, scope enforcement, stale-plugin safety, and client protocol/codegen.
What kinds of plugins this could support
This seam is intentionally generic. It can support many plugin families without adding plugin-specific action routes to core:
The important part: the plugin defines the action semantics. OpenClaw owns dispatch, auth, and transport-level enforcement.
New SDK seam
This PR adds:
OpenClawPluginApi.registerSessionAction(...)continueAgentplugins.sessionActionon the Gateway protocol plus regenerated Swift modelsrequiredScopesExample plugin usage:
Runtime architecture
The action is registered once inside the plugin runtime and can then be dispatched from any client surface that speaks the Gateway protocol.
Safety and boundaries
This stays intentionally narrow:
requiredScopesinstead of treating every action like the same write laneoperator.writeupstream/mainstay preserved in this sliceThis is a bounded typed action protocol, not arbitrary plugin-owned gateway method injection.
What changed
OpenClawPluginApi.registerSessionActionplus SDK exports for action registration, context, and result types.plugins.sessionActiondispatch.operator.write.runtime.tsmodule instances do not double-dispatch pinned/active registry subscriptions.upstream/main; this slice stays narrowly focused on typed session-action registration, dispatch, and scope enforcement.Relationship to adjacent seams
This is narrower than attachments, scheduled turns, SessionEntry projection, or run-context lifecycle. It only adds the typed session-action registration/dispatch protocol plus the host scope enforcement that makes it safe to call.
Non-goals
Stack context
Real behavior proof
Behavior or issue addressed:
This fixes the under-scoped least-privilege path for
plugins.sessionActionwithout broadening the seam beyond the session-action protocol. Before this patch, out-of-process callers that could not resolve a local plugin registry entry fell back tooperator.write, so actions that correctly declared scopes likeoperator.approvalsfailed before reaching the handler. After this patch, known actions still use their declared scopes, unresolved callers fall back to the standard operator scope bundle instead of under-scoping, dispatch still enforcesrequiredScopes, and typed payload/result validation still rejects malformed traffic.Real environment tested:
Fresh loopback Gateway started from
/Users/lume/openclaw-review-worktrees/pr-75578-rebasewith a workspace-loaded proof plugin at/tmp/openclaw-pr75578-proof.4VP2Yu/workspace/.openclaw/extensions/session-action-proof. The runtime usedHOME=/tmp/openclaw-pr75578-proof.4VP2Yu/home,OPENCLAW_WORKSPACE_DIR=/tmp/openclaw-pr75578-proof.4VP2Yu/workspace,OPENCLAW_STATE_DIR=/tmp/openclaw-pr75578-proof.4VP2Yu/state, andOPENCLAW_CONFIG_PATH=/tmp/openclaw-pr75578-proof.4VP2Yu/config/openclaw.json.Exact steps or command run after this patch:
Evidence after fix:
Observed result after fix:
The paired CLI flow no longer under-scopes
plugins.sessionActiontooperator.write; it now requests the broader operator scope bundle and hits the existing scope-upgrade approval gate, which preserves pairing/approval enforcement instead of failing with a misleading handler-level missing-scope error. An authorized backend/token caller successfully dispatches the typed session action and receives the typed success payload. A malformed payload is rejected before handler execution with the expected schema error.What was not tested:
This proof did not run a full end-to-end Control UI or native Apple client invocation against the regenerated Swift models. The Swift surface was regenerated and covered at the protocol/codegen layer in this patch, but the live proof here is intentionally limited to real Gateway registration/dispatch/scope enforcement and typed payload validation.
Validation
pnpm protocol:genpnpm protocol:gen:swiftpnpm test src/gateway/method-scopes.test.ts src/gateway/call.test.ts src/agents/tools/gateway.test.ts src/plugins/contracts/session-actions.contract.test.tspnpm test src/plugins/runtime.channel-pin.test.tsOPENCLAW_VITEST_MAX_WORKERS=1 pnpm test src/plugins/runtime.test.ts src/plugins/runtime.channel-pin.test.tsgit diff --check