Skip to content

[plugin sdk] Add generic plugin host-hook SDK contracts#72082

Closed
100yenadmin wants to merge 11 commits into
openclaw:mainfrom
electricsheephq:feature/plan-plugin-host-hooks
Closed

[plugin sdk] Add generic plugin host-hook SDK contracts#72082
100yenadmin wants to merge 11 commits into
openclaw:mainfrom
electricsheephq:feature/plan-plugin-host-hooks

Conversation

@100yenadmin

@100yenadmin 100yenadmin commented Apr 26, 2026

Copy link
Copy Markdown
Contributor

Summary

This is the focused generic host-hook implementation PR for RFC #71731. It adds the SDK, host, Gateway, cleanup, and contract-test seams needed before Plan Mode can be packaged as a bundled plugin and audited against #71676 parity.

This PR intentionally does not include Plan Mode product code. #71676 is used only as a parity oracle for host entry-point classes.

Current head: bacfde0f13 fix: observe unexpected projection promises

Related artifacts:

Maintainer Decision This PR Is Asking For

If maintainers accept RFC #71731, review this as the complete generic host-hook contract implementation. After this lands, Plan Mode packaging should be plugin work plus a parity audit, not more host patching.

The success bar is: the SDK and host expose all generic lifecycle, state, Gateway, command, UI descriptor, policy, scheduler ownership, metadata, event, run-context, and cleanup seams needed by Plan Mode and other workflow plugins.

What This Implements

1. Plugin Session Extensions And Patch Actions (#71732)

  • Adds plugin-owned JSON-compatible session extension state.
  • Projects registered plugin extension state into Gateway session rows as pluginExtensions.
  • Adds typed sessions.pluginPatch protocol schema and validator coverage.
  • Regenerates Swift protocol models for the additive Gateway protocol surface.
  • Rejects unknown plugin / namespace state patches instead of exposing arbitrary session fields.
  • Clears plugin-owned persistent session state and pending next-turn injections on reset, delete, disable, and restart cleanup paths.
  • Hardens JSON-compatible validation to reject non-plain objects such as Date / Map values.

2. Durable Next-Turn Injections And Agent-Turn Preparation (#71733)

  • Adds api.enqueueNextTurnInjection(...) for durable plugin-owned queued context.
  • Drains queued injections exactly once for a session before prompt hooks.
  • Adds typed agent_turn_prepare hook support and preserves legacy prompt-hook ordering.
  • Supports prepend / append placement, idempotency keys, TTL expiry, and JSON metadata validation.
  • Verifies pending injections are removed during plugin cleanup.

3. Trusted Tool Policy And Tool Metadata (#71734)

  • Adds bundled-only api.registerTrustedToolPolicy(...) that runs before normal plugin before_tool_call hooks.
  • Keeps external / workspace plugins on the normal hook path and blocks them from registering trusted policy.
  • Adds api.registerToolMetadata(...) and projects risk / tags into tool catalog and effective tool inventory.
  • Verifies trusted-policy ordering, enforcement, and metadata projection.

4. Scoped Commands, Reserved Ownership, And Continuation (#71735)

  • Extends plugin command definitions with host-enforced requiredScopes.
  • Adds bundled-only reserved command ownership.
  • Adds continueAgent: true command result support so command-side state changes can resume the agent path.
  • Verifies text-command continuation behavior and reserved ownership rejection for non-bundled plugins.

5. Control UI Contribution Descriptors (#71736)

  • Adds api.registerControlUiDescriptor(...) for data-driven UI descriptors.
  • Adds typed plugins.uiDescriptors Gateway protocol schema and validator coverage.
  • Projects descriptor metadata from the active plugin registry.
  • Keeps Control UI support descriptor-based and safe: no arbitrary browser JavaScript, no Plan Mode cards, no Plan Mode CSS.
  • Validates descriptor schemas through the same JSON-compatible value gate.

6. Agent Events, Run Context, Scheduler Ownership, Heartbeat Contributions, Cleanup (#71737)

  • Adds api.registerAgentEventSubscription(...) for sanitized lifecycle-owned event subscriptions.
  • Adds plugin run-context helpers: setRunContext, getRunContext, and clearRunContext.
  • Clears plugin run context on terminal lifecycle events.
  • Adds plugin-owned session scheduler job records and deterministic cleanup over the existing scheduler access.
  • Adds heartbeat_prompt_contribution for heartbeat-only context.
  • Wires cleanup through session state, queued injections, runtime lifecycle callbacks, scheduler records, and run context.

#71676 Entry-Point Parity Map

#71676 Plan Mode entry-point class Generic seam in this PR
Session state and sessions.patch behavior Session extensions and sessions.pluginPatch
Pending injections, approval resumes, revision / question continuations Durable next-turn injections and agent_turn_prepare
Tool mutation gates while approval is pending Bundled trusted tool policy before normal before_tool_call
Slash / native command continuation requiredScopes, bundled reserved ownership, continueAgent
Control UI modes / cards / status Descriptor projection through plugins.uiDescriptors
Snapshots, nudges, subagent follow-ups, heartbeat Event subscriptions, run context, scheduler ownership cleanup, heartbeat contribution
Tool catalog / display metadata Plugin risk / tags projection into catalog and effective inventory
Disable / reset / delete / restart cleanup Host cleanup for plugin-owned session, runtime, scheduler, injection, and run-context state

Expected result after merge: Plan Mode plugin packaging should not require new core host patches. It will still require moving product-specific Plan Mode prompts, tools, commands, descriptors, and channel behavior into a bundled plugin, followed by parity auditing against #71676.

Generic Fixture Coverage

The host-hook-fixture is a generic SDK contract fixture, not a Plan Mode fixture. It now exercises:

  • session extension registration and projection
  • typed sessions.pluginPatch protocol validation
  • durable next-turn injection context and cleanup
  • agent_turn_prepare and heartbeat_prompt_contribution
  • trusted tool policy ordering and external-plugin rejection
  • tool metadata projection into catalog and effective inventory
  • scoped command continuation and reserved command ownership
  • Control UI descriptor registration, schema validation, and projection
  • agent event subscription and run-context cleanup
  • session scheduler job ownership cleanup
  • lifecycle cleanup on reset, delete, disable, and restart paths

Fixture archetypes covered:

  • Approval workflow: session extension, command continuation, next-turn injection, UI descriptor.
  • Budget / workspace policy gate: trusted policy, tool metadata, session projection.
  • Background lifecycle monitor: event subscription, scheduler cleanup, heartbeat contribution.

Important Non-Scope

This PR does not add Plan Mode product code:

  • no Plan Mode prompts
  • no Plan Mode tools
  • no /plan command copy
  • no Plan Mode CSS or product cards
  • no Telegram-specific Plan Mode behavior
  • no Smarter-Claw compatibility shim
  • no local installer patch logic
  • no Plan Mode scheduler nudge logic

Those belong in the bundled Plan Mode plugin after this host-hook PR lands.

Validation

Completed locally before the final rebase / review-response pass:

  • pnpm docs:list
  • pnpm test src/plugins/contracts/host-hooks.contract.test.ts src/agents/pi-embedded-runner/run/attempt.test.ts
  • pnpm tsgo:all
  • pnpm lint
  • pnpm check:import-cycles
  • pnpm plugin-sdk:api:check
  • pnpm build

Completed locally after rebasing onto current upstream/main (e672b61417) and before force-pushing current head bacfde0f13:

  • git diff --check upstream/main..HEAD
  • pnpm docs:list
  • pnpm check:import-cycles
  • pnpm plugin-sdk:api:check
  • OPENCLAW_TEST_HEAVY_CHECK_LOCK_HELD=1 pnpm test src/plugins/contracts/host-hooks.contract.test.ts src/agents/pi-tools.before-tool-call.embedded-mode.test.ts src/auto-reply/reply/commands-plugin.test.ts (host-hook contract tests: 25 passed)
  • pnpm lint:core
  • OPENCLAW_TSGO_HEAVY_CHECK_LOCK_HELD=1 pnpm tsgo:all
  • pnpm build

Review-thread status after reviewer/bot triage:

Notes:

  • The local lock flags were used only because another checkout was already holding the shared local heavy-check lock; they do not skip assertions.
  • The reviewer-response commits regenerated the plugin SDK API baseline because the public session-extension projector contract was intentionally tightened to synchronous projection.
  • pnpm check:changed was not rerun to completion after the reviewer-response commits in this local environment. The default base points at stale origin/main, and the upstream-base path previously reached app lint before local SwiftLint / full-Xcode availability blocked completion. Exact-head CI is the source of truth for the full changed-check gate.

Commit Stack

  • 27215fe3c7 feat: add plugin host hook contracts
  • 9893ce5f28 feat: complete plugin host lifecycle seams
  • a744660913 feat: harden plugin host hook contracts
  • adaeca6bfd chore: refresh plugin host hook rebase baseline
  • 1ae7e094b0 fix: refresh generated host hook contracts
  • 09c9d347e8 fix: address host hook review feedback
  • 0f25f68229 fix: filter stale plugin injections
  • 15181569e0 fix: harden plugin session contracts
  • bacfde0f13 fix: observe unexpected projection promises

RFC Resolution Status

If accepted, this PR implements the SDK / host-hook level contract for:

Important nuance: implemented here means the generic host / SDK contract exists. It does not mean the Plan Mode plugin has been packaged yet.

@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation gateway Gateway runtime agents Agent runtime and tooling size: XL app: web-ui App: web-ui labels Apr 26, 2026
@100yenadmin

Copy link
Copy Markdown
Contributor Author

Implementation/handoff update pushed in 7a20bf755d and the draft PR body has been replaced with the full maintainer narrative.\n\nKey correction from the first draft: #72082 is now framed as the focused host-hook implementation PR, not as a vague prelude. The body maps the implementation to #71732-#71737, includes a #71676 entry-point parity table, lists non-Plan plugin consumers for each hook family, and calls out next-agent validation/risk items explicitly.\n\nValidation after the second commit: pnpm tsgo:all passed. Still to rerun before ready-for-review: pnpm lint, pnpm check:import-cycles, focused host-hook tests, and ideally pnpm check:changed.

@100yenadmin
100yenadmin marked this pull request as ready for review April 26, 2026 11:20
Copilot AI review requested due to automatic review settings April 26, 2026 11:20
@greptile-apps

greptile-apps Bot commented Apr 26, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR introduces the generic plugin host-hook SDK contracts (session extensions, next-turn injections, trusted tool policies, tool metadata, Control UI descriptors, agent event subscriptions, run context, scheduler job ownership, and lifecycle cleanup) that are prerequisites for bundling Plan Mode as a plugin. The implementation is large and mostly sound, but two logic gaps stand out.

  • requireApproval dropped for trusted policies (src/agents/pi-tools.before-tool-call.ts): after runTrustedToolPolicies returns, only trustedPolicyResult?.block is checked. A trusted policy returning { requireApproval: { title, description } } has that approval requirement silently discarded; the equivalent path for normal hook results at line 284 correctly handles it.
  • enqueued: true returned on dedup-match (src/plugins/host-hook-state.ts): enqueuePluginNextTurnInjection always returns { enqueued: true } even when the dedup check inside updateSessionStore prevents inserting the record, making the result flag unreliable for callers that need to distinguish newly-added from already-present injections.

Confidence Score: 3/5

Two P1 logic bugs should be resolved before merging: a dropped requireApproval approval-gate in the trusted tool policy path, and a misleading enqueued: true return on dedup collisions.

Two P1 findings on core changed paths (tool-call approval gate, next-turn injection enqueue result) prevent a clean merge. The rest of the changes are structurally well-organised and the negative-enforcement tests for reserved commands and external trusted policies add good coverage.

src/agents/pi-tools.before-tool-call.ts (trusted policy approval handling) and src/plugins/host-hook-state.ts (enqueue return value on dedup-match).

Comments Outside Diff (1)

  1. src/agents/pi-tools.before-tool-call.ts, line 252-265 (link)

    P1 requireApproval from trusted tool policy is silently dropped

    runBeforeToolCallHook only checks trustedPolicyResult?.block before moving on. PluginHookBeforeToolCallResult also carries requireApproval, and runTrustedToolPolicies can return the full result (the "requireApproval" in decision branch in runTrustedToolPolicies). When a trusted policy returns { requireApproval: { title, description } } without block: true, the approval requirement is never surfaced — the code extracts only trustedPolicyResult?.params and proceeds as if the policy had no objection. The equivalent code path for the normal hook runner at line 284 correctly handles hookResult?.requireApproval.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: src/agents/pi-tools.before-tool-call.ts
    Line: 252-265
    
    Comment:
    **`requireApproval` from trusted tool policy is silently dropped**
    
    `runBeforeToolCallHook` only checks `trustedPolicyResult?.block` before moving on. `PluginHookBeforeToolCallResult` also carries `requireApproval`, and `runTrustedToolPolicies` can return the full result (the `"requireApproval" in decision` branch in `runTrustedToolPolicies`). When a trusted policy returns `{ requireApproval: { title, description } }` without `block: true`, the approval requirement is never surfaced — the code extracts only `trustedPolicyResult?.params` and proceeds as if the policy had no objection. The equivalent code path for the normal hook runner at line 284 correctly handles `hookResult?.requireApproval`.
    
    How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/agents/pi-tools.before-tool-call.ts
Line: 252-265

Comment:
**`requireApproval` from trusted tool policy is silently dropped**

`runBeforeToolCallHook` only checks `trustedPolicyResult?.block` before moving on. `PluginHookBeforeToolCallResult` also carries `requireApproval`, and `runTrustedToolPolicies` can return the full result (the `"requireApproval" in decision` branch in `runTrustedToolPolicies`). When a trusted policy returns `{ requireApproval: { title, description } }` without `block: true`, the approval requirement is never surfaced — the code extracts only `trustedPolicyResult?.params` and proceeds as if the policy had no objection. The equivalent code path for the normal hook runner at line 284 correctly handles `hookResult?.requireApproval`.

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: src/plugins/host-hook-state.ts
Line: 240-268

Comment:
**`enqueued: true` returned on dedup-match path**

When the duplicate-check inside the `updateSessionStore` callback finds a matching dedup key, it returns early without appending the new record. The outer function then unconditionally returns `{ enqueued: true, ... }`. A caller relying on `result.enqueued === false` to detect that no new work was queued will never observe that signal — every call appears as a successful enqueue regardless of whether the record was actually inserted.

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: src/plugins/host-hook-state.ts
Line: 280-283

Comment:
**Dead `canonicalKey` variable in `drainPluginNextTurnInjections`**

`canonicalKey` is assigned on this line but is never read again in the function — the return value comes directly from `updateSessionStore`. Remove the assignment or use the variable if it was meant to be part of the return type (similar to how `enqueuePluginNextTurnInjection` returns `canonicalKey`).

```suggestion
  const now = params.now ?? Date.now();
  return await updateSessionStore(loaded.storePath, (store) => {
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: src/plugins/host-hook-runtime.ts
Line: 163

Comment:
**Subscription handler errors silently swallowed**

`void Promise.resolve(registration.subscription.handle(...))` is fire-and-forget with no error handler attached. Any exception or rejection from a subscription handler is lost without a log trace. Consider adding `.catch(err => log.warn(...))` so failures from misbehaving plugins surface in diagnostics, matching the pattern used elsewhere (e.g. `pi-tools.before-tool-call.ts` line 292).

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: src/plugins/host-hook-cleanup.ts
Line: 100-120

Comment:
**Scheduler job deleted from state even when `cleanup` callback throws**

`cleanupPluginSessionSchedulerJobs` calls `jobs.delete(jobId)` unconditionally after the `try/catch` block. A failed cleanup that was supposed to cancel a real background job will be deregistered from the in-process map despite potentially still running. If cleanup is idempotent this is fine, but if not the job may leak. Consider keeping the record in the map on failure to allow a retry, or document the "delete-on-failure" contract explicitly.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "feat: complete plugin host lifecycle sea..." | Re-trigger Greptile

Comment thread src/plugins/host-hook-state.ts
Comment thread src/plugins/host-hook-state.ts
Comment thread src/plugins/host-hook-runtime.ts
Comment thread src/plugins/host-hook-cleanup.ts

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Implements the generic “host-hook” SDK contracts and runtime seams needed to move workflow features (notably Plan Mode) out of core and into bundled plugins, including lifecycle cleanup, session state extensions, durable next-turn context, trusted tool policy, scoped commands with continuation, control UI descriptors, and agent event/run-context support.

Changes:

  • Add new host-hook types and plugin API surface (session extensions, next-turn injections, trusted tool policy, tool metadata, UI descriptors, runtime lifecycle, agent event subscriptions, run context, scheduler-job ownership).
  • Wire host behavior: gateway protocol methods (sessions.pluginPatch, plugins.uiDescriptors), session row projection, tool catalog/effective inventory metadata projection, trusted policy execution before before_tool_call, prompt assembly integration (agent_turn_prepare, heartbeat_prompt_contribution), and cleanup on session reset/delete and registry replacement.
  • Add contract fixture + tests covering registration, protocol validation, ordering/enforcement, projection, and cleanup behavior.

Reviewed changes

Copilot reviewed 50 out of 50 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
test/helpers/plugins/plugin-api.ts Extends test plugin API stub with new host-hook methods.
src/plugins/types.ts Exposes new host-hook types; extends command result with continueAgent; adds requiredScopes/ownership to command definition; extends OpenClawPluginApi.
src/plugins/trusted-tool-policy.ts Adds trusted tool policy runner that executes before normal hooks.
src/plugins/status.test-helpers.ts Updates plugin load result helper to include new registry arrays.
src/plugins/runtime.ts Adds agent-event bridge setup/teardown + registry replacement cleanup hook.
src/plugins/registry.ts Adds host-hook registration capture/validation and exposes via plugin API builder.
src/plugins/registry-types.ts Adds registry registration record types + new optional registry arrays.
src/plugins/registry-empty.ts Initializes new registry arrays in the empty registry.
src/plugins/host-hooks.ts Introduces host-hook type contracts + JSON compatibility helpers + prompt-context builder.
src/plugins/host-hook-state.ts Implements durable next-turn injections + session extension patch/projection helpers.
src/plugins/host-hook-runtime.ts Implements run-context store + event subscription dispatch + scheduler-job ownership tracking/cleanup.
src/plugins/host-hook-cleanup.ts Implements host-hook cleanup orchestration + helper to clear plugin-owned session state fields.
src/plugins/hooks.ts Adds hook runner support for agent_turn_prepare and heartbeat_prompt_contribution with merge semantics.
src/plugins/hook-types.ts Adds new hook names and handler types; includes them in prompt-injection set.
src/plugins/hook-before-agent-start.types.ts Adds appendContext to prompt build result and mutation field list.
src/plugins/contracts/host-hooks.contract.test.ts Adds contract tests covering registration, ordering, protocol validation, event dispatch, and cleanup.
src/plugins/contracts/host-hook-fixture.ts Adds a generic fixture plugin exercising the new seams.
src/plugins/commands.ts Enforces requiredScopes for plugin commands; supports scope-based rejection messaging.
src/plugins/command-registration.ts Adds reserved-name override option for bundled reserved command ownership.
src/plugins/captured-registration.ts Captures new host-hook registrations during registration capture/testing.
src/plugins/api-builder.ts Adds no-op implementations + handler wiring for new OpenClawPluginApi methods.
src/plugin-sdk/plugin-entry.ts Re-exports new host-hook types via plugin SDK entry surface.
src/plugin-sdk/core.ts Re-exports new host-hook types via core plugin SDK surface.
src/gateway/test-helpers.plugin-registry.ts Updates gateway stub plugin registry to include new arrays.
src/gateway/session-utils.types.ts Adds pluginExtensions projection field to GatewaySessionRow.
src/gateway/session-utils.ts Projects registered plugin session extension state into session rows (sync path).
src/gateway/session-reset-service.ts Runs plugin host-hook cleanup on session reset/delete before mutation.
src/gateway/server-methods/tools-catalog.ts Projects plugin tool metadata (risk, tags, display/description) into tool catalog.
src/gateway/server-methods/sessions.ts Adds sessions.pluginPatch handler + emits updated session rows including pluginExtensions.
src/gateway/server-methods/plugin-host-hooks.ts Adds plugins.uiDescriptors gateway method for UI descriptor projection.
src/gateway/server-methods.ts Registers new gateway handler module.
src/gateway/server-methods-list.ts Adds plugins.uiDescriptors and sessions.pluginPatch to allowed method list.
src/gateway/protocol/schema/types.ts Exposes schema-derived TS types for new methods/descriptors.
src/gateway/protocol/schema/sessions.ts Adds schemas for sessions.pluginPatch params/result.
src/gateway/protocol/schema/protocol-schemas.ts Registers new schemas (sessions pluginPatch + UI descriptor schemas).
src/gateway/protocol/schema/plugins.ts Adds schema for UI descriptors + plugin JSON value placeholder schema.
src/gateway/protocol/schema/agents-models-skills.ts Adds risk/tags to tool catalog and effective tools schemas.
src/gateway/protocol/schema.ts Re-exports plugin schema module.
src/gateway/protocol/index.ts Adds AJV validators for new methods and exports schema types.
src/gateway/method-scopes.ts Assigns operator scopes to new gateway methods.
src/config/sessions/types.ts Adds session-store fields for plugin extensions + queued injections.
src/auto-reply/reply/commands-plugin.ts Supports command continuation via continueAgent and avoids returning empty replies.
src/agents/tools-effective-inventory.types.ts Adds risk/tags fields to effective tool inventory entries.
src/agents/tools-effective-inventory.ts Projects plugin tool metadata into effective tool inventory labels/descriptions/risk/tags.
src/agents/pi-tools.before-tool-call.ts Runs trusted tool policies before normal before_tool_call hooks and applies param rewrites.
src/agents/pi-embedded-runner/run/attempt.ts Applies appendContext to the effective prompt during attempts.
src/agents/pi-embedded-runner/run/attempt.test.ts Updates tests for appendContext and heartbeat-only prompt contributions.
src/agents/pi-embedded-runner/run/attempt.prompt-helpers.ts Drains next-turn injections, runs agent_turn_prepare, and applies heartbeat-only contributions into prompt build result.
docs/plugins/sdk-overview.md Documents new host-hook SDK methods and intended trust/authority split.
docs/plugins/hooks.md Documents new hooks and session extensions/next-turn injection behavior.

Comment thread src/agents/pi-tools.before-tool-call.ts
Comment thread src/plugins/commands.ts
Comment thread src/plugins/registry.ts
Comment thread src/plugins/registry.ts
Comment thread src/plugins/registry.ts Outdated
Comment thread src/plugins/registry.ts
Comment thread src/gateway/session-utils.ts Outdated
Comment thread src/plugins/host-hook-runtime.ts
Comment thread src/plugins/host-hooks.ts Outdated
Comment thread src/plugins/registry.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7a20bf755d

ℹ️ 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".

Comment thread src/agents/pi-tools.before-tool-call.ts
Comment thread src/gateway/session-utils.ts Outdated
Comment thread src/plugins/commands.ts
@100yenadmin 100yenadmin changed the title Add generic plugin host-hook SDK contracts [plugin SKD] Add generic plugin host-hook SDK contracts Apr 26, 2026
@100yenadmin 100yenadmin changed the title [plugin SKD] Add generic plugin host-hook SDK contracts [plugin SDK\] Add generic plugin host-hook SDK contracts Apr 26, 2026
@100yenadmin 100yenadmin changed the title [plugin SDK\] Add generic plugin host-hook SDK contracts [plugin SDK] Add generic plugin host-hook SDK contracts Apr 26, 2026
@100yenadmin 100yenadmin changed the title [plugin SDK] Add generic plugin host-hook SDK contracts [plugin sdk] Add generic plugin host-hook SDK contracts Apr 26, 2026
@100yenadmin
100yenadmin force-pushed the feature/plan-plugin-host-hooks branch from 7a20bf7 to 7b0b14e Compare April 26, 2026 13:10
@openclaw-barnacle openclaw-barnacle Bot added channel: bluebubbles Channel integration: bluebubbles cli CLI command changes commands Command implementations channel: feishu Channel integration: feishu labels Apr 26, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7b0b14e1ee

ℹ️ 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".

Comment thread src/plugins/host-hook-runtime.ts Outdated
@100yenadmin
100yenadmin force-pushed the feature/plan-plugin-host-hooks branch from 7b0b14e to 676e6d0 Compare April 26, 2026 13:37
@openclaw-barnacle openclaw-barnacle Bot removed cli CLI command changes commands Command implementations labels Apr 26, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a generic “host-hook” contract surface for workflow-style plugins (session extensions, durable next-turn injections, trusted tool policy tier, tool metadata, command continuation/scopes, UI descriptors, agent events/run-context, scheduler ownership, and cleanup) and wires those seams through the host, Gateway protocol, SDK exports, and fixture contract tests—intended as the generic substrate needed before Plan Mode can ship as a bundled plugin.

Changes:

  • Add new host-hook runtime/state/cleanup modules and extend plugin registry + plugin SDK types/APIs to support host-owned lifecycle seams.
  • Extend Gateway protocol and server methods for sessions.pluginPatch and plugins.uiDescriptors, plus session-row/tool-catalog projections for the new metadata.
  • Add/adjust contract tests and fixups across existing tests to account for the new surfaces.

Reviewed changes

Copilot reviewed 72 out of 72 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
test/scripts/lint-suppressions.test.ts Add lint suppression entries
test/helpers/plugins/plugin-api.ts Stub new plugin API methods
src/wizard/setup.plugin-config.test.ts Mock plugin-registry seam
src/plugins/update.test.ts Reset modules for dynamic import
src/plugins/types.ts Export host-hook types + command continuation
src/plugins/trusted-tool-policy.ts Trusted policy runner
src/plugins/synthetic-auth.runtime.test.ts Adjust synthetic auth typing
src/plugins/status.ts Include syntheticAuthRefs in status
src/plugins/status.test-helpers.ts Extend plugin load result fixtures
src/plugins/runtime.ts Bridge agent events + cleanup replaced registries
src/plugins/registry.ts Register host-hook contracts into registry
src/plugins/registry-types.ts Add registry registration types/fields
src/plugins/registry-empty.ts Initialize new registry arrays
src/plugins/public-surface-loader.test.ts Reset modules for isolation
src/plugins/provider-auth-choices.test.ts Mock plugin registry + dynamic imports
src/plugins/loader.ts Propagate syntheticAuthRefs from manifest
src/plugins/installed-plugin-index.ts Clone syntheticAuthRefs into index
src/plugins/install.npm-spec.test.ts Dynamic import after resetModules
src/plugins/host-hooks.ts New host-hook public types/helpers
src/plugins/host-hook-turn-types.ts New turn/injection hook types
src/plugins/host-hook-state.ts Persistent session extension + injection state
src/plugins/host-hook-runtime.ts Run context + scheduler ownership + event dispatch
src/plugins/host-hook-json.ts JSON-compatibility validator
src/plugins/host-hook-cleanup.ts Cleanup for persistent/runtime plugin-owned state
src/plugins/hooks.ts Add agent_turn_prepare + heartbeat hook runner
src/plugins/hook-types.ts Add hook names + handler typings
src/plugins/hook-before-agent-start.types.ts Add appendContext field
src/plugins/contracts/host-hooks.contract.test.ts Contract fixture coverage for seams
src/plugins/contracts/host-hook-fixture.ts Generic fixture plugin registration
src/plugins/commands.ts Enforce requiredScopes for commands
src/plugins/command-registration.ts Allow bundled reserved command ownership
src/plugins/channel-plugin-ids.test.ts Expand manifest/registry mocks
src/plugins/captured-registration.ts Capture new host-hook registrations
src/plugins/bundled-runtime-deps.test.ts Fix mocking + dynamic import order
src/plugins/api-builder.ts Add no-op implementations for new API methods
src/plugin-sdk/plugin-entry.ts Re-export new host-hook types
src/plugin-sdk/core.ts Re-export new host-hook types
src/gateway/test-helpers.plugin-registry.ts Stub new registry fields
src/gateway/session-utils.types.ts Add pluginExtensions to session row type
src/gateway/session-utils.ts Project plugin session extensions into rows
src/gateway/session-reset-service.ts Run plugin host cleanup on reset/delete
src/gateway/server-methods/tools-catalog.ts Project tool metadata (risk/tags/display)
src/gateway/server-methods/sessions.ts Add sessions.pluginPatch handler
src/gateway/server-methods/plugin-host-hooks.ts Add plugins.uiDescriptors handler
src/gateway/server-methods.ts Register new gateway handlers
src/gateway/server-methods-list.ts Add new gateway method names
src/gateway/protocol/schema/types.ts Add new schema type exports
src/gateway/protocol/schema/sessions.ts Add SessionsPluginPatch* schemas
src/gateway/protocol/schema/protocol-schemas.ts Register schemas in protocol map
src/gateway/protocol/schema/plugins.ts Add UI descriptor + json value schemas
src/gateway/protocol/schema/agents-models-skills.ts Add risk/tags to tool schemas
src/gateway/protocol/schema.ts Export new plugins schema module
src/gateway/protocol/index.ts Compile validators for new methods
src/gateway/method-scopes.ts Add scopes for new gateway methods
src/config/sessions/types.ts Add persistent plugin session fields
src/auto-reply/reply/commands-plugin.ts Support continueAgent without leaking field
src/auto-reply/reply/commands-plugin.test.ts Test continuation behavior
src/agents/tools-effective-inventory.types.ts Add risk/tags to inventory entry
src/agents/tools-effective-inventory.ts Project tool metadata into inventory
src/agents/tools-effective-inventory.test.ts Test tool metadata projection
src/agents/pi-tools.before-tool-call.ts Add trusted policy stage before hooks
src/agents/pi-tool-definition-adapter.ts Normalize params record before hooks
src/agents/pi-embedded-runner/run/attempt.ts Apply appended prompt context
src/agents/pi-embedded-runner/run/attempt.test.ts Cover append + heartbeat contribution paths
src/agents/pi-embedded-runner/run/attempt.prompt-helpers.ts Drain injections + run new hooks
extensions/feishu/src/directory.test.ts Remove query-string import indirection
extensions/bluebubbles/src/actions.test.ts Remove query-string import indirection
docs/plugins/sdk-overview.md Document new host-hook APIs
docs/plugins/hooks.md Document new hook stages + host hooks
docs/.generated/plugin-sdk-api-baseline.sha256 Refresh SDK API baseline hashes
apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift Regenerate Swift gateway models
apps/macos/Sources/OpenClawProtocol/GatewayModels.swift Regenerate Swift gateway models

Comment thread src/plugins/host-hook-state.ts
Comment thread src/plugins/registry.ts
Comment thread docs/plugins/sdk-overview.md Outdated
Comment thread src/gateway/session-utils.ts Outdated
Comment thread src/agents/pi-tools.before-tool-call.ts
@chatgpt-codex-connector

Copy link
Copy Markdown
Contributor

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Implements the generic “plugin host-hook” contract layer (SDK + host runtime + Gateway protocol seams + cleanup + fixture contract tests) required to support workflow-style bundled plugins (per RFC #71731) without embedding product-specific Plan Mode behavior in core.

Changes:

  • Adds new plugin host-hook SDK APIs (session extensions, next-turn injections, trusted tool policy, tool metadata, control UI descriptors, runtime lifecycle cleanup, agent event subscriptions, run context, session scheduler job ownership) plus new hooks (agent_turn_prepare, heartbeat_prompt_contribution) and command continuation (continueAgent) + requiredScopes/reserved ownership.
  • Extends Gateway protocol with sessions.pluginPatch and plugins.uiDescriptors, projects plugin session extensions into gateway session rows, and projects plugin tool metadata into tool catalogs/inventories.
  • Adds host-owned state/runtime/cleanup plumbing (durable injection queue, run-context store, registry replacement cleanup) and a comprehensive contract fixture test suite.

Reviewed changes

Copilot reviewed 73 out of 73 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
test/scripts/lint-suppressions.test.ts Adds lint-suppression entries for new host-hook files/types.
test/helpers/plugins/plugin-api.ts Extends test plugin API stub with new host-hook methods.
src/wizard/setup.plugin-config.test.ts Updates mocks for plugin-registry/manifest registry interactions.
src/plugins/update.test.ts Resets modules before dynamic import to stabilize mocking.
src/plugins/types.ts Exposes new host-hook types + extends command result/definition and plugin API surface.
src/plugins/trusted-tool-policy.ts Adds trusted-policy runner to execute bundled-only pre-hook tool policy.
src/plugins/synthetic-auth.runtime.test.ts Adjusts typing for synthetic auth refs in snapshot fixtures.
src/plugins/status.ts Includes syntheticAuthRefs in plugin status records.
src/plugins/status.test-helpers.ts Adds new host-hook registration arrays to plugin load result helper.
src/plugins/runtime.ts Bridges agent events to plugin subscriptions + triggers cleanup on registry replacement/reset.
src/plugins/registry.ts Registers/validates host-hook registrations; enforces reserved command ownership rules.
src/plugins/registry-types.ts Adds registry record types/slots for new host-hook registrations and syntheticAuthRefs.
src/plugins/registry-empty.ts Initializes empty registry with new host-hook slots.
src/plugins/public-surface-loader.test.ts Adds module resets to isolate platform/mocking behavior.
src/plugins/provider-auth-choices.test.ts Switches to dynamic imports + expands mocks and cache resets.
src/plugins/loader.ts Threads syntheticAuthRefs from manifest into plugin records.
src/plugins/installed-plugin-index.ts Ensures syntheticAuthRefs are copied into installed index when present.
src/plugins/install.npm-spec.test.ts Switches to dynamic import after vi.resetModules().
src/plugins/host-hooks.ts Defines core host-hook contract types and helpers (IDs, projections, descriptors, etc.).
src/plugins/host-hook-turn-types.ts Adds types for next-turn injection records + new hook payload/result shapes.
src/plugins/host-hook-state.ts Implements durable injection queue + session extension patching/projection.
src/plugins/host-hook-runtime.ts Implements run-context store, agent-event dispatch wrapper, and scheduler job ownership tracking/cleanup.
src/plugins/host-hook-json.ts Adds JSON-compatibility type + runtime validator for host-hook values.
src/plugins/host-hook-cleanup.ts Implements deterministic cleanup across session store state + runtime resources + registry replacement.
src/plugins/hooks.ts Adds runner support for agent_turn_prepare + heartbeat_prompt_contribution and merging behavior.
src/plugins/hook-types.ts Adds new hook names + handler typings; updates prompt-injection hook list.
src/plugins/hook-before-agent-start.types.ts Adds appendContext support to prompt build result typing.
src/plugins/contracts/host-hooks.contract.test.ts Adds contract fixture coverage for all new seams and cleanup semantics.
src/plugins/contracts/host-hook-fixture.ts Adds a generic fixture plugin registering all host-hook contracts (non-Plan-specific).
src/plugins/commands.ts Enforces requiredScopes for gateway-invoked plugin commands (with admin bypass).
src/plugins/command-registration.ts Allows bundled plugins to claim reserved command names when permitted.
src/plugins/channel-plugin-ids.test.ts Updates mocks/fixtures for manifest/installed index/plugin registry integration.
src/plugins/captured-registration.ts Captures host-hook registrations in test harness registration capture.
src/plugins/bundled-runtime-deps.test.ts Refactors mocking to use hoisted spawnSync mock + dynamic import.
src/plugins/api-builder.ts Extends built plugin API with new host-hook methods and no-op defaults.
src/plugin-sdk/plugin-entry.ts Re-exports new host-hook types through plugin-sdk entrypoint.
src/plugin-sdk/core.ts Re-exports new host-hook types through plugin-sdk core.
src/gateway/test-helpers.plugin-registry.ts Updates gateway stub plugin registry to include new host-hook slots.
src/gateway/session-utils.types.ts Adds pluginExtensions projection field to gateway session row type.
src/gateway/session-utils.ts Projects plugin session extensions into session rows via sync projection helper.
src/gateway/session-reset-service.ts Runs plugin host cleanup during session reset/delete paths.
src/gateway/server-methods/tools-catalog.ts Projects plugin tool metadata (risk, tags, display fields) into tool catalog entries.
src/gateway/server-methods/sessions.ts Adds sessions.pluginPatch handler + includes pluginExtensions in session change broadcasts.
src/gateway/server-methods/plugin-host-hooks.ts Adds plugins.uiDescriptors handler returning projected Control UI descriptors.
src/gateway/server-methods.ts Registers the new plugin host-hook gateway handlers.
src/gateway/server-methods-list.ts Adds new gateway method names to method list.
src/gateway/protocol/schema/types.ts Adds schema type exports for new gateway protocol messages.
src/gateway/protocol/schema/sessions.ts Adds TypeBox schemas for sessions.pluginPatch params/result.
src/gateway/protocol/schema/protocol-schemas.ts Registers new schemas in the protocol schema map.
src/gateway/protocol/schema/plugins.ts Adds schemas for plugin UI descriptors and params/result.
src/gateway/protocol/schema/agents-models-skills.ts Extends tool catalog/effective tool schemas with risk/tags.
src/gateway/protocol/schema.ts Re-exports new plugin protocol schemas.
src/gateway/protocol/index.ts Adds AJV validators and exports for new schemas.
src/gateway/method-scopes.ts Adds scope mapping for new gateway methods (plugins.uiDescriptors, sessions.pluginPatch).
src/config/sessions/types.ts Adds persisted session fields for plugin extensions + next-turn injection queue record types.
src/auto-reply/reply/commands-plugin.ts Supports continueAgent command results without leaking into reply payload.
src/auto-reply/reply/commands-plugin.test.ts Adds test ensuring continuation + payload sanitization behavior.
src/agents/tools-effective-inventory.types.ts Extends effective tool inventory entries with risk/tags.
src/agents/tools-effective-inventory.ts Projects plugin tool metadata into effective tool inventory entries.
src/agents/tools-effective-inventory.test.ts Adds coverage for metadata projection into effective inventory.
src/agents/pi-tools.before-tool-call.ts Runs trusted tool policies before normal hooks + unifies approval request handling.
src/agents/pi-tools.before-tool-call.embedded-mode.test.ts Adds tests covering trusted policy approval + param behavior; resets plugin registry per test.
src/agents/pi-tool-definition-adapter.ts Ensures tool params are coerced before before_tool_call processing.
src/agents/pi-embedded-runner/run/attempt.ts Appends prompt hook appendContext into effective prompt.
src/agents/pi-embedded-runner/run/attempt.test.ts Expands prompt hook result tests for appendContext + heartbeat-only contributions.
src/agents/pi-embedded-runner/run/attempt.prompt-helpers.ts Drains queued injections, runs new hooks, and merges prepend/append context consistently.
extensions/feishu/src/directory.test.ts Removes query-string module path hack; imports module directly.
extensions/bluebubbles/src/actions.test.ts Removes query-string module path hack; imports module directly.
docs/plugins/sdk-overview.md Documents new host-hook workflow plugin APIs at a high level.
docs/plugins/hooks.md Documents new hooks, tool-policy behavior, and session extension/injection semantics.
docs/.generated/plugin-sdk-api-baseline.sha256 Updates SDK API baseline hashes for the expanded surface.
apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift Regenerates Swift protocol models for new gateway schemas + tool metadata fields.
apps/macos/Sources/OpenClawProtocol/GatewayModels.swift Regenerates Swift protocol models for new gateway schemas + tool metadata fields.

Comment thread src/config/sessions/types.ts Outdated
Comment thread test/helpers/plugins/plugin-api.ts
Comment thread src/gateway/session-utils.ts
Comment thread src/plugins/contracts/host-hooks.contract.test.ts Outdated
Comment thread src/plugins/host-hook-state.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 66a360dce4

ℹ️ 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".

Comment thread src/plugins/host-hook-state.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 44c0ea7131

ℹ️ 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".

Comment thread src/plugins/host-hook-state.ts
Comment thread src/plugins/host-hook-state.ts Outdated
@100yenadmin
100yenadmin force-pushed the feature/plan-plugin-host-hooks branch from 44c0ea7 to bacfde0 Compare April 26, 2026 17:04
@openclaw-barnacle openclaw-barnacle Bot removed channel: bluebubbles Channel integration: bluebubbles channel: feishu Channel integration: feishu labels Apr 26, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bacfde0f13

ℹ️ 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".

Comment on lines +303 to +307
await record.job.cleanup?.({
reason: params.reason,
sessionKey,
jobId,
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Skip callbacks for preserved scheduler jobs

When cleanupReplacedPluginHostRegistry passes preserveSchedulerJobIds for restarted plugins, this branch still executes record.job.cleanup(...) even for preserved IDs and only skips deletion. That means a preserved job can still have its teardown callback run, which can cancel timers or clear state that the replacement registry is actively reusing under the same job id, breaking scheduler-driven behavior immediately after restart. Preserved jobs should bypass cleanup callbacks as well as deletion.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector

Copy link
Copy Markdown
Contributor

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@100yenadmin

Copy link
Copy Markdown
Contributor Author

Closing in favor of #72287. This PR accumulated noisy iterative automated review history while we were hardening the generic host-hook implementation, so the successor PR gives maintainers a clean review surface.\n\n#72287 is a single-commit refile from current upstream/main, tree-identical to the final implementation state here, and its PR body adds the requested maintainer diagrams plus a per-hook matrix of non-Plan-Mode plugin use cases. Please use #72287 for further review.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9b3614e94c

ℹ️ 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".

for (const failure of schedulerFailures) {
failures.push(failure);
}
clearPluginRunContext({ pluginId: params.pluginId, runId: params.runId });

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Avoid wiping all run context during session-scoped cleanup

runPluginHostCleanup is invoked from cleanupSessionBeforeMutation with only sessionKey (src/gateway/session-reset-service.ts:417-421), but this line always calls clearPluginRunContext with potentially both pluginId and runId undefined. In that case clearPluginRunContext iterates every run and every plugin namespace, so resetting/deleting one session can erase in-memory run context for unrelated active runs, breaking plugins that rely on per-run state during tool/lifecycle handling.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling app: macos App: macos app: web-ui App: web-ui docs Improvements or additions to documentation gateway Gateway runtime size: XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants