Skip to content

[plugin sdk] Add workflow action, outbound, scheduler, and retry host seams#72383

Closed
100yenadmin wants to merge 29 commits intoopenclaw:mainfrom
electricsheephq:feature/plugin-sdk-workflow-seams
Closed

[plugin sdk] Add workflow action, outbound, scheduler, and retry host seams#72383
100yenadmin wants to merge 29 commits intoopenclaw:mainfrom
electricsheephq:feature/plugin-sdk-workflow-seams

Conversation

@100yenadmin
Copy link
Copy Markdown
Contributor

@100yenadmin 100yenadmin commented Apr 26, 2026

Summary

Follow-up to #72287 that adds the generic workflow seams needed by plugins that coordinate multi-step host workflows: typed Control UI actions, outbound session attachments, host-mediated session wakeups, trusted policy reads, priority next-turn injections, and bounded finalize retry preservation.

This remains generic plugin infrastructure. It does not add Plan Mode product logic, prompts, /plan behavior, Telegram behavior, or bundled Plan Mode UI. The point is to make workflow plugins possible through host contracts instead of one-off core patches.

Current update: the earlier long-form maintainer explanation was accidentally compressed during stack-status cleanup. This body restores/reconstructs that explanation and keeps later status updates as comments rather than replacing the PR description.

Expansion note: This follow-up grew during the final hardening pass from workflow affordances into production-safe host-mediated actions, attachments, scheduling, retry, and cleanup semantics. The added detail is intentional: maintainers should see both the unique workflow-seam scope and the inherited lower-stack diff noise.

Stack Position

flowchart LR
  A["#72287 host-hook foundation"] --> B["#72383 workflow seams"]
  B --> C["#72384 advanced executable fixtures"]
  C --> D["#72333 recipes and diagrams"]
Loading

Review this PR after #72287 conceptually. It depends on the foundation contracts, then adds the host workflow operations that real plugins need once they can own state, descriptors, policy, and next-turn context.

What This Adds

Seam Generic contract Non-Plan plugin examples enabled
plugins.sessionAction Gateway action dispatch into registered plugin session actions with typed params/results. Deploy approval buttons, onboarding wizard steps, incident acknowledge/escalate actions, review retry selection.
Session action validation Action outputs, error details, and params stay JSON-compatible and bounded. Clients can render errors/results safely; invalid plugin payloads cannot crash host/session paths.
sendSessionAttachment Host-mediated outbound session attachment delivery. Report generator sends a PDF; review plugin posts a patch bundle; incident plugin attaches a timeline export.
scheduleSessionTurn Host-mediated scheduled session wakeup for bundled/trusted workflow plugins. SLA monitor schedules a follow-up; quiet-hours plugin resumes later; deploy timeout watcher wakes the agent when a decision expires.
Trusted policy session reads Trusted policy can read plugin-owned session state while evaluating tool calls. Budget guard checks current spend; compliance policy checks selected workspace profile; deploy policy checks approval state.
Priority next-turn injections Queued context can be ordered so action results or resumes land before lower-priority context. Approval result context comes before a generic monitor note; review retry target comes before background status.
before_agent_finalize retry preservation Plugins can request one bounded finalize retry without losing host finalization semantics. Review assistant asks for a final repair pass; release plugin asks for a final checklist correction; incident plugin asks for a missing summary.
CLI prompt preparation integration Queued injections and agent_turn_prepare apply in CLI prompt assembly too. The same plugin continuation works in CLI sessions and Control UI sessions.
Runtime scheduler cleanup Scheduled-turn records are owned by plugin/session cleanup. Disabling a monitor cancels its future wakeups; reset/delete clears plugin-owned schedule records.

Workflow Diagram

sequenceDiagram
  autonumber
  participant UI as Control UI
  participant GW as Gateway
  participant Plugin
  participant State as Plugin Session State
  participant Queue as Next-turn Queue
  participant Scheduler
  participant Runner

  UI->>GW: plugins.sessionAction({pluginId, actionId, sessionKey, params})
  GW->>Plugin: validate and dispatch action
  Plugin->>State: update plugin-owned JSON state
  Plugin->>Queue: enqueue priority next-turn injection
  Plugin-->>GW: typed JSON result
  GW-->>UI: render action result
  Plugin->>Scheduler: scheduleSessionTurn for follow-up if needed
  Scheduler->>Runner: wake session at due time
  Runner->>Queue: drain priority injections
  Runner->>Plugin: agent_turn_prepare / finalization hooks
Loading

Why This Is Separate From #72287

#72287 creates the foundation: state, descriptors, trusted policy, events, scheduler ownership, run context, cleanup, metadata, and prompt injection. This PR adds the higher-level workflow operations that use those foundations:

  • UI can invoke a plugin action instead of only patching state.
  • Plugins can send artifacts through the host instead of depending on channel-specific code.
  • Plugins can schedule a future session wakeup instead of leaving ambient cron work behind.
  • Finalization retry becomes a bounded SDK contract instead of product-specific runner behavior.

That split keeps the foundation reviewable while still proving that the host-hook model can support real workflows.

What This Enables Beyond Plan Mode

flowchart TB
  Actions["plugins.sessionAction"] --> Approval["deploy approval cards"]
  Actions --> Wizard["setup/onboarding wizard steps"]
  Actions --> Incident["incident acknowledge/escalate"]
  Attach["sendSessionAttachment"] --> Reports["artifact/report delivery"]
  Attach --> ReviewBundles["review patch bundles"]
  Scheduler["scheduleSessionTurn"] --> Monitors["background status checks"]
  Scheduler --> QuietHours["quiet-hours resume"]
  Retry["before_agent_finalize retry"] --> Review["review assistant final pass"]
  Policy["trusted policy session reads"] --> Guard["budget/compliance lock"]
Loading

Concrete plugin classes:

  • Approval and release plugins can dispatch scoped UI actions and resume the agent.
  • Artifact/report plugins can send host-mediated session attachments without direct channel coupling.
  • Background monitor plugins can schedule session wakeups and clean those jobs on disable/reset/delete.
  • Review assistant plugins can request one bounded finalize retry.
  • Compliance/budget plugins can read plugin-owned session state when evaluating trusted tool policy.
  • Onboarding/setup plugins can advance wizard state from UI actions and use continuation context to keep the agent aligned.

Safety And Production Boundaries

  • Admin-scoped scheduling and attachment sending are bundled-only/trusted host operations.
  • Invalid schedules resolve non-fatally instead of throwing through runner paths.
  • Outbound delivery failures return typed ok:false results rather than crashing the workflow.
  • Scheduled-turn jobs are recorded in runtime cleanup state and cleaned by plugin/session cleanup.
  • Session action outputs, params, and error details are JSON-validated.
  • Retry budgets are bounded and cleared by run.
  • CLI prompt drain caches are cleaned up after prompt preparation.
  • The global plugin event bridge is stored in global registry state so reloads do not create duplicate event delivery.
  • Swift protocol models are regenerated for descriptor/session-action wire fields.

Non-Scope

This PR does not implement a Plan Mode product plugin. It intentionally avoids:

  • Plan Mode prompts or command copy
  • /plan command behavior
  • Telegram-specific behavior
  • Plan Mode cards, CSS, or product UI
  • Smarter-Claw compatibility shims
  • local installer patching

Those should be built on top of these generic seams after the host contracts are accepted.

Validation

Focused validation run for this branch/stack:

  • pnpm test src/plugins/contracts/host-hooks.contract.test.ts src/agents/harness/lifecycle-hook-helpers.test.ts src/plugins/hooks.before-agent-finalize.test.ts
  • pnpm plugin-sdk:api:check
  • git diff --check

Additional inherited/follow-up validation from the stack is tracked in PR comments so the body stays focused on what this PR contributes.

@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation app: macos App: macos app: web-ui App: web-ui gateway Gateway runtime agents Agent runtime and tooling size: XL labels Apr 26, 2026
@100yenadmin 100yenadmin marked this pull request as ready for review April 26, 2026 22:18
Copilot AI review requested due to automatic review settings April 26, 2026 22:18
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 26, 2026

Greptile Summary

This PR adds the runtime seams for advanced workflow plugins: plugin-attributed agent event emission (emitAgentEvent), host-mediated file delivery (sendSessionAttachment), cron-backed session wake-ups (scheduleSessionTurn), typed gateway session actions (plugins.sessionAction), hot-path session extension reads (ctx.getSessionExtension), priority-sorted durable turn injections, and a bounded finalize/retry path. The trusted-policy and reserved-surface gating is well-considered, input validation is thorough across all new registration paths, and the new test coverage (host-hooks.contract.test.ts) is extensive.

Two minor issues worth addressing: the finalize retry budget map accumulates entries without cleanup, and resolveSchedule can throw an unhandled RangeError for invalid at date strings.

Confidence Score: 4/5

Safe to merge; the two P2 findings are non-blocking and don't affect correctness on the happy path.

No P0 or P1 issues found. Two P2 issues: (1) the finalize retry budget map is never pruned, causing gradual memory growth in long-running processes; (2) an invalid at date string in scheduleSessionTurn throws an unhandled RangeError instead of returning undefined. Neither affects normal operation.

src/agents/harness/lifecycle-hook-helpers.ts (retry budget leak) and src/plugins/host-hook-workflow.ts (invalid date handling in resolveSchedule)

Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/agents/harness/lifecycle-hook-helpers.ts
Line: 95-113

Comment:
**Retry budget map grows without bound**

The `FINALIZE_RETRY_BUDGET_KEY` singleton `Map<string, number>` is written on every finalize retry invocation but never pruned. Each unique `(runId + instruction)` pair adds a permanent entry that survives for the life of the process. Since `runId` changes every agent run, a long-running server that regularly triggers finalize retries will accumulate one entry per retry-eligible run indefinitely.

The budget map should be cleared when a run terminates — either by hooking into the terminal lifecycle event in `dispatchPluginAgentEventSubscriptions` (which already clears `runContextByRunId` on end/error) or by adding a cleanup step to `clearPluginHostRuntimeState`.

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-workflow.ts
Line: 147-148

Comment:
**Invalid `at` date throws unhandled `RangeError`**

If a plugin passes an invalid date string as `params.at`, `new Date(params.at)` produces an `Invalid Date` object and the immediately following `.toISOString()` call throws `RangeError: Invalid time value`. Because there is no `try/catch` in `schedulePluginSessionTurn`, this propagates as a rejected Promise rather than the documented `undefined` return. A `isNaN(at.getTime())` guard before calling `toISOString()` would fix this.

```suggestion
  const at = params.at instanceof Date ? params.at : new Date(params.at);
  if (isNaN(at.getTime())) {
    return undefined;
  }
  return { kind: "at", at: at.toISOString() };
```

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

Reviews (1): Last reviewed commit: "fix(plugin-sdk): type priority next-turn..." | Re-trigger Greptile

Comment thread src/agents/harness/lifecycle-hook-helpers.ts
Comment thread src/plugins/host-hook-workflow.ts
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 extends the Plugin SDK + runtime with “workflow host seams” that let advanced plugins coordinate durable session state, UI descriptors, outbound events/attachments, scheduler-driven wakeups, and bounded finalize retries—without embedding any product-specific workflow implementation.

Changes:

  • Add new host-hook contracts/types and registry plumbing for session extensions, next-turn injections (incl. priority), trusted tool policies, tool metadata, control UI descriptors, agent event subscriptions, run context, session scheduler jobs, and session actions.
  • Wire new seams through the gateway (new RPC methods + schemas), session row projection, cleanup paths (reset/delete/reload), and tool policy enforcement.
  • Update embedded runner prompt-building to drain next-turn injections once per run (cache) and support new hook types (agent_turn_prepare, heartbeat_prompt_contribution) + appendContext.

Reviewed changes

Copilot reviewed 80 out of 80 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
test/scripts/lint-suppressions.test.ts Adds lint suppression entries for new host-hook-related files.
test/helpers/plugins/plugin-api.ts Extends test plugin API stub with new host-hook seam methods.
src/wizard/setup.plugin-config.test.ts Adjusts mocks for plugin-registry/manifest interactions.
src/plugins/update.test.ts Resets modules before dynamic import to avoid mock/module leakage.
src/plugins/types.ts Re-exports host-hook types; extends plugin command result and command definition fields; adds new OpenClawPluginApi methods.
src/plugins/trusted-tool-policy.ts Implements bundled-only trusted tool policy evaluation chain.
src/plugins/synthetic-auth.runtime.test.ts Updates test typing for syntheticAuthRefs field.
src/plugins/status.ts Propagates syntheticAuthRefs into plugin status records.
src/plugins/status.test-helpers.ts Extends plugin load result helper with host-hook registry arrays.
src/plugins/runtime.ts Adds agent-event bridge subscription lifecycle + cleanup on registry swap/reset.
src/plugins/registry.ts Adds registration/validation + API wiring for host-hook seams; adds reserved-command ownership handling; adds operator-scope validation helpers.
src/plugins/registry-types.ts Extends PluginRegistry/PluginRecord types to include host-hook registrations and syntheticAuthRefs.
src/plugins/registry-empty.ts Initializes empty registry with new host-hook arrays.
src/plugins/public-surface-loader.test.ts Adds vi.resetModules() to stabilize module/mocking behavior across tests.
src/plugins/provider-auth-choices.test.ts Switches to dynamic imports + module resets; adds manifest-registry mock; resets provider-auth alias cache.
src/plugins/loader.ts Threads syntheticAuthRefs into plugin record creation and load paths.
src/plugins/installed-plugin-index-record-builder.ts Copies syntheticAuthRefs defensively when building installed index records.
src/plugins/install.npm-spec.test.ts Uses dynamic import after vi.resetModules() for stable module state in tests.
src/plugins/host-hooks.ts Defines host-hook public types (session extensions/actions, UI descriptors, events, scheduler, run context, attachments, etc.) + injection context builder.
src/plugins/host-hook-workflow.ts Implements emitAgentEvent, session attachment send, and session turn scheduling via cron.
src/plugins/host-hook-turn-types.ts Defines next-turn injection types + new hook event/result types for turn prepare and heartbeat prompt contributions.
src/plugins/host-hook-state.ts Implements durable session extension storage, enqueue/drain for next-turn injections (incl. TTL/priority), and projection logic.
src/plugins/host-hook-runtime.ts Implements run-scoped plugin context store + agent event dispatch + scheduler job tracking/cleanup.
src/plugins/host-hook-json.ts Defines JSON-compat types and runtime validation helper isPluginJsonValue.
src/plugins/host-hook-cleanup.ts Implements deterministic cleanup for plugin-owned session state, runtime lifecycles, scheduler jobs, and run context.
src/plugins/hooks.ts Adds agent_turn_prepare and heartbeat_prompt_contribution hook runners; adds context mapping to inject getSessionExtension into tool-hook contexts; preserves finalize retry merge behavior.
src/plugins/hook-types.ts Extends hook name set + handler map; adds new hook types and appendContext; adds retry option to before_agent_finalize results; adds getSessionExtension to tool hook context.
src/plugins/hook-before-agent-start.types.ts Adds appendContext to before_prompt_build result and prompt mutation field list.
src/plugins/contracts/host-hook-fixture.ts Adds a generic fixture plugin registering the new host-hook seams.
src/plugins/commands.ts Enforces requiredScopes for gateway-invoked plugin commands, with admin override.
src/plugins/commands.test.ts Adds coverage for reserved-command bypass not applying to native aliases.
src/plugins/command-registration.ts Adds reserved-command checks and optional bypass for bundled plugins claiming reserved ownership.
src/plugins/channel-plugin-ids.test.ts Expands mocks/fixtures for manifest registry split loads and installed index snapshot integration.
src/plugins/captured-registration.ts Captures registrations for the new host-hook seam methods in test harness.
src/plugins/bundled-runtime-deps.test.ts Refactors child_process mocking + dynamic import for stable module state.
src/plugins/api-builder.ts Extends API builder with no-op implementations for new seam methods.
src/plugin-sdk/plugin-entry.ts Re-exports new host-hook types through plugin SDK entry surface.
src/plugin-sdk/core.ts Re-exports new host-hook types through plugin SDK core surface.
src/hooks/install.test.ts Refactors to dynamic imports + stable exec mocking across tests.
src/gateway/test-helpers.plugin-registry.ts Extends stub registry with host-hook arrays.
src/gateway/session-utils.types.ts Adds pluginExtensions projection field to GatewaySessionRow.
src/gateway/session-utils.ts Projects registered plugin session extensions into gateway session rows.
src/gateway/session-reset-service.ts Runs plugin host cleanup on session reset/delete paths.
src/gateway/server-methods/tools-catalog.ts Projects plugin tool metadata (displayName/description/risk/tags) into tools.catalog response.
src/gateway/server-methods/sessions.ts Adds sessions.pluginPatch handler to mutate registered plugin session extension namespaces.
src/gateway/server-methods/plugin-host-hooks.ts Adds gateway handlers for plugins.uiDescriptors and plugins.sessionAction.
src/gateway/server-methods.ts Registers new plugin host hook gateway handlers.
src/gateway/server-methods-list.ts Adds method names for new gateway RPC methods.
src/gateway/protocol/schema/types.ts Exposes new schema-derived protocol types for plugin host hook methods.
src/gateway/protocol/schema/sessions.ts Adds schemas for sessions.pluginPatch params/results.
src/gateway/protocol/schema/protocol-schemas.ts Registers new schemas for plugin-related gateway methods and sessions.pluginPatch.
src/gateway/protocol/schema/plugins.ts Adds schema definitions for plugin UI descriptors and session action RPC.
src/gateway/protocol/schema/agents-models-skills.ts Extends tool catalog/effective tool schemas with risk/tags fields.
src/gateway/protocol/schema.ts Re-exports plugin schemas.
src/gateway/protocol/index.ts Adds AJV validators for new gateway methods and re-exports schemas.
src/gateway/operator-scopes.ts Adds KNOWN_OPERATOR_SCOPES and isOperatorScope validator.
src/gateway/method-scopes.ts Adds method-to-scope mappings for the new plugin gateway methods and sessions.pluginPatch.
src/config/sessions/types.ts Adds persisted session fields for plugin extensions and next-turn injection queue records.
src/auto-reply/reply/commands-plugin.ts Strips continueAgent from reply payload and sets shouldContinue accordingly.
src/auto-reply/reply/commands-plugin.test.ts Adds test to ensure continueAgent doesn’t leak into reply payload.
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 inventory entries.
src/agents/tools-effective-inventory.test.ts Adds coverage for projecting plugin tool metadata into effective inventory.
src/agents/pi-tools.before-tool-call.ts Runs trusted tool policies before normal hooks; unifies approval flow; preserves trusted-policy param rewrites.
src/agents/pi-tools.before-tool-call.integration.e2e.test.ts Adds assertion that tool execute path still runs after policy/hook integration.
src/agents/pi-tools.before-tool-call.embedded-mode.test.ts Adds tests for trusted-policy approval routing and param preservation; ensures plugin registry reset.
src/agents/pi-tool-definition-adapter.ts Ensures before_tool_call receives normalized params record.
src/agents/pi-embedded-runner/run/attempt.ts Applies appendContext during prompt construction.
src/agents/pi-embedded-runner/run/attempt.test.ts Updates prompt hook result expectations for appendContext and new hook names.
src/agents/pi-embedded-runner/run/attempt.prompt-helpers.ts Drains next-turn injections, runs new hooks, adds run-scoped drain cache and appendContext composition; supports heartbeat-only contributions.
src/agents/pi-embedded-runner/run/attempt.prompt-helpers.test.ts Adds tests for drain cache behavior and re-drain after eviction/forget.
src/agents/pi-embedded-runner/run.ts Clears per-run drain cache on run termination.
src/agents/harness/lifecycle-hook-helpers.ts Adds bounded finalize retry handling using a global retry budget keyed by run/idempotency.
docs/plugins/sdk-overview.md Documents new workflow host hook seams at the SDK level.
docs/plugins/hooks.md Documents new hook names, trusted tool policy behavior, session extensions/injections, and cleanup semantics.
docs/.generated/plugin-sdk-api-baseline.sha256 Updates generated SDK API baseline hashes.
apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift Updates Swift gateway models for new protocol types and fields (pluginPatch, tool risk/tags, UI descriptors).
apps/macos/Sources/OpenClawProtocol/GatewayModels.swift Same Swift protocol model updates for macOS target.
CHANGELOG.md Adds changelog entry for the new Plugin SDK host hooks.

Comment thread src/agents/tools-effective-inventory.ts Outdated
Comment thread src/plugins/host-hook-workflow.ts
Comment thread src/agents/harness/lifecycle-hook-helpers.ts
Copy link
Copy Markdown

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

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: 881a0ee4c0

ℹ️ 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/runtime.ts Outdated
Comment thread src/agents/harness/lifecycle-hook-helpers.ts
@clawsweeper
Copy link
Copy Markdown
Contributor

clawsweeper Bot commented Apr 26, 2026

Codex automated review: keeping this open.

Keep this PR open. Current main contains the merged #72287 host-hook foundation, but it still does not implement this PR’s workflow action dispatch, host-mediated outbound attachments, scheduled session wakeups, priority next-turn ordering, plugin-emitted workflow events through OpenClawPluginApi, or bounded finalize-retry contract. The PR is an active public SDK/Gateway contract change with security-sensitive review threads, not conservative cleanup.

Best possible solution:

Keep this PR open as the workflow-seam implementation layer above #72287. Maintainers should review or reject the proposed SDK/Gateway contracts explicitly, resolve the remaining security-sensitive review threads, and require protocol/API generation plus focused host-hook contract tests before landing. If the APIs are accepted, this PR or an equivalent implementation should add typed session actions, host-mediated attachments, scheduled session turns, priority next-turn injections, trusted session reads, and bounded finalize retry semantics on top of the already-merged foundation.

What I checked:

  • current-main-sdk-foundation-only: OpenClawPluginApi exposes foundation host hooks such as registerSessionExtension, enqueueNextTurnInjection, registerTrustedToolPolicy, registerControlUiDescriptor, registerAgentEventSubscription, run context helpers, and registerSessionSchedulerJob. It does not expose registerSessionAction, sendSessionAttachment, scheduleSessionTurn, or an OpenClawPluginApi emitAgentEvent seam. (src/plugins/types.ts:2337, ad57a6d61658)
  • gateway-method-missing: The Gateway server method list includes plugins.uiDescriptors, but there is no plugins.sessionAction method on current main. (src/gateway/server-methods-list.ts:48, ad57a6d61658)
  • gateway-handler-ui-only: The plugin host-hook Gateway handler only implements plugins.uiDescriptors. Current main has no session-action dispatch, action result validation, or scoped action permission path. (src/gateway/server-methods/plugin-host-hooks.ts:10, ad57a6d61658)
  • protocol-schema-lacks-session-action: The plugin protocol schema defines PluginJsonValue as Type.Unknown plus UI descriptor params/result only. It has no PluginsSessionActionParams or PluginsSessionActionResult schema. (src/gateway/protocol/schema/plugins.ts:4, ad57a6d61658)
  • priority-next-turn-not-implemented: Persisted next-turn injection records have no priority field, and drain ordering is chronological by createdAt rather than priority-aware. (src/config/sessions/types.ts:123, ad57a6d61658)
  • bounded-finalize-retry-not-implemented: before_agent_finalize results support only action and reason, and the harness normalizer only maps continue/revise/finalize. There is no retry payload, retry budget, or cleanup contract on current main. (src/plugins/hook-types.ts:292, ad57a6d61658)

Remaining risk / open question:

  • This PR adds public SDK and Gateway protocol authority around session actions, outbound attachments, scheduled wakeups, and plugin-emitted events; those surfaces need exact-head trust-tier, schema, ownership, cleanup, quota, and file/path-boundary review before merge.
  • The latest provided review context still has security/contract-sensitive open threads: blocking plugin-emitted terminal lifecycle streams and enforcing registered session-action payload schemas before dispatch.
  • Because this PR is paired with open follow-up stack PRs [plugin sdk] Add advanced workflow plugin contract fixtures #72384 and [plugin sdk] Add host-hook examples and recipes (#72287 follow-up) #72333 by the same author, closing only this layer would likely strand dependent fixture and docs work.

Codex Review notes: model gpt-5.5, reasoning high; reviewed against ad57a6d61658.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 80 out of 80 changed files in this pull request and generated 1 comment.

Comment thread src/plugins/host-hook-workflow.ts Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

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

Comment thread src/agents/tools-effective-inventory.ts Outdated
Comment thread src/plugins/host-hook-workflow.ts
Comment thread src/plugins/host-hook-workflow.ts
Comment thread apps/macos/Sources/OpenClawProtocol/GatewayModels.swift
@100yenadmin 100yenadmin force-pushed the feature/plugin-sdk-workflow-seams branch from 881a0ee to 812b52e Compare April 27, 2026 07:47
Copy link
Copy Markdown

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

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: 812b52e6ec

ℹ️ 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/registry.ts Outdated
@chatgpt-codex-connector
Copy link
Copy Markdown

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.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 83 out of 83 changed files in this pull request and generated 3 comments.

Comment thread src/gateway/server-methods/plugin-host-hooks.ts
Comment thread src/gateway/server-methods/plugin-host-hooks.ts Outdated
Comment thread src/agents/harness/lifecycle-hook-helpers.ts
Eva added 9 commits April 28, 2026 12:42
…gisterToolMetadata doc

Address Copilot review threads on PR openclaw#72383:

1. schema/plugins.ts: PluginJsonValueSchema used Type.This() inside a
   Type.Union without a recursive scope, which produces an invalid
   schema (unresolved $ref) at AJV compile time. Wrap the union in
   Type.Cyclic({...}, "PluginJsonValue") with explicit Type.Ref.
   Targeted vitest passes 54/54 across src/gateway/protocol.

2. plugins/types.ts: registerToolMetadata docstring claimed it
   applies to "plugin-owned or core tool", but the registry +
   projection logic intentionally scopes to (pluginId, toolName) so
   plugins cannot decorate other plugins' tools or core tools.
   Updated the doc to match.
…cy params + correct CHANGELOG PR ref

Address Copilot review threads on PR openclaw#72383:

1. protocol/schema/plugins.ts + server-methods/plugin-host-hooks.ts:
   plugin session-action failures (`{ ok: false, error, code?, details? }`)
   are now returned as a successful RPC with `ok: false` + typed error
   fields, not as transport-level errorShape. Schema now declares
   `error?`, `code?`, `details?` on the result. Distinguishes plugin-
   declared failures from transport-level RPC failures (validation,
   schema mismatch, dispatch error).

2. trusted-tool-policy.ts: `decision.params` is validated as a plain
   object via `isPlainObject` before being applied. A buggy trusted
   policy returning a non-object (string/array/primitive) no longer
   propagates into the tool runtime / `before_tool_call` hooks. Fixes
   the matching pi-tools.before-tool-call.ts:446 concern at the source.

3. CHANGELOG.md: corrected the entry to describe THIS PR's content
   (workflow action, outbound, scheduler, retry host seams + protocol
   surfaces) and reference (openclaw#72383) instead of (openclaw#72287).
…ionActionResultSchema

Per copilot review on plugins.ts:69 — `plugins.sessionAction` returns plugin-
declared failures as a successful RPC with `{ ok: false, error, code?, details? }`
(see server-methods/plugin-host-hooks.ts:119), but the schema only allowed
`{ ok, result?, continueAgent?, reply? }` with `additionalProperties: false`.
Generated clients (Swift, etc.) would either drop the failure fields or fail to
decode the response. The previous commit (89444ba1) updated the server but the
schema patch was missed; this completes the contract by adding optional
`error`, `code`, `details` to the result so the wire shape and the schema agree.
…ompt hooks present

Per chatgpt-codex P2 review on prepare.ts:331 — eagerly invoking
`loadOpenClawHistoryMessages()` on every CLI run forces avoidable disk read
+ JSON parse latency even when the registered hook set never reads
`messages`. The previous (pre-PR) call site had a `hasHooks(...)` guard;
restore the equivalent gate at the callsite by checking whether the
registered hooks include any of the message-consuming hooks
(`agent_turn_prepare`, `before_prompt_build`, `before_agent_start`) before
loading. `heartbeat_prompt_contribution` does not consume messages and is
intentionally excluded.
@100yenadmin 100yenadmin force-pushed the feature/plugin-sdk-workflow-seams branch from 1a27d30 to c082aa3 Compare April 28, 2026 05:47
Copy link
Copy Markdown

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

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: f7e3cd4f1f

ℹ️ 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-workflow.ts Outdated
Copy link
Copy Markdown

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

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: f87a9f1a29

ℹ️ 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-cleanup.ts Outdated
Copy link
Copy Markdown

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

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: 99c09bd962

ℹ️ 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-cleanup.ts
Copy link
Copy Markdown

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

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: f3902bec88

ℹ️ 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-workflow.ts
Comment thread src/gateway/server-methods/plugin-host-hooks.ts
Copy link
Copy Markdown

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

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: c5512d062b

ℹ️ 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-workflow.ts Outdated
Copy link
Copy Markdown

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

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: f90a6f400b

ℹ️ 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/registry.ts
Comment on lines +1866 to +1872
if (action.schema !== undefined && !isPluginJsonValue(action.schema)) {
pushDiagnostic({
level: "error",
pluginId: record.id,
source: record.source,
message: `session action schema must be JSON-compatible: ${id}`,
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Reject invalid session action schemas during registration

registerSessionAction only checks action.schema for JSON compatibility, so non-object or malformed JSON Schema values can be accepted into the registry and only fail later at request time (plugins.sessionAction checks object shape and then compiles/uses the schema). In practice, a JS plugin can register an action that appears valid at load time but will always return request/dispatch errors when invoked, which turns a registration contract issue into a runtime failure path. Validate schema shape/compilability when registering the action so broken schemas are surfaced as diagnostics before the plugin is activated.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

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

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: ddc7ff033e

ℹ️ 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 +263 to +267
return registerPluginSessionSchedulerJob({
pluginId: params.pluginId,
pluginName: params.pluginName,
job: {
id: jobId,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Prune completed session-turn jobs from runtime registry

schedulePluginSessionTurn always registers each created cron job in runtime state, and the default name path generates unique IDs (randomUUID) so repeated one-shot scheduling continuously adds new entries. Those entries are only removed during explicit host cleanup (disable/reset/delete), not when deleteAfterRun jobs fire and disappear, so long-lived plugins that schedule many wakeups will accumulate stale scheduler records and growing in-memory state.

Useful? React with 👍 / 👎.

Comment on lines +158 to +160
if (result && result.ok === false) {
if (typeof result.error !== "string" || !result.error.trim()) {
respond(
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Reject failure-shaped action results without ok=false

The failure path is only selected when result.ok === false, so untyped/JS plugin handlers that return { error: "..." } (or code/details) without an explicit ok: false fall through to the success response and are returned as { ok: true }. This silently hides plugin-declared failures from clients and can make UI/automation treat failed actions as successful; these failure fields should be rejected unless ok is explicitly false.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

Superseded by #73384 now that #72287 has merged.\n\nThis PR's workflow action, outbound attachment, scheduler, finalize-retry, validation, and cleanup work has been preserved in the consolidated follow-up branch with the original commit history retained for review order. Please move review and CI attention to #73384 so maintainers have one current main comparison instead of this stale stacked diff.

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