Skip to content

feat: add --session-key support to system wake/event#35231

Closed
BrennerSpear wants to merge 1 commit into
openclaw:mainfrom
BrennerSpear:feat/session-key-wake-v6
Closed

feat: add --session-key support to system wake/event#35231
BrennerSpear wants to merge 1 commit into
openclaw:mainfrom
BrennerSpear:feat/session-key-wake-v6

Conversation

@BrennerSpear

Copy link
Copy Markdown
Contributor

What

Add optional --session-key parameter to all wake/system-event entry points so callers can deliver events to a specific agent session instead of default fan-out.

Supersedes #35125 and #34944.

Entry Points

  • CLI: openclaw system event "text" --session-key <key>
  • WS wake: { method: "wake", params: { text, mode, sessionKey } }
  • WS system-event: { method: "system-event", params: { text, sessionKey, ... } }
  • HTTP /hooks/wake: POST { text, mode, sessionKey } — gated by policy
  • HTTP hook mappings: { action: "wake", sessionKey: "hook:{{payload.id}}" }

Core Behavior

  • With sessionKey: Canonicalize, validate, enqueue event to that session, requestHeartbeatNow to wake it
  • Without sessionKey: Preserve existing fan-out (no behavioral change)

Safety

  • Cross-agent keys throw (never silently reroute)
  • Malformed agent-scoped keys (< 3 segments) rejected
  • HTTP hook sessionKey gated by hooks.allowRequestSessionKey + prefix allowlist
  • dispatchWakeHook returns result object (errors propagated)
  • State mutation only after validation

Changes since v5 (#35125)

  • Fixed: system-event WS handler now calls requestHeartbeatNow for targeted sessions — previously events to non-main sessions would silently stall (same bug that was fixed in wake and hooks paths in v5, but missed in system-event)
  • Audited: All three targeted-session paths (cron.ts, server/hooks.ts, system.ts) verified to have requestHeartbeatNow after enqueueSystemEvent

Testing

  • 23 files changed, ~1306 insertions
  • 103 tests pass across 9 test files
  • All 9 anti-patterns verified

Closes #35125, closes #34944

@openclaw-barnacle openclaw-barnacle Bot added app: macos App: macos app: web-ui App: web-ui gateway Gateway runtime cli CLI command changes size: XL labels Mar 5, 2026
@greptile-apps

greptile-apps Bot commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds an optional --session-key parameter to all wake/system-event entry points (CLI, WebSocket, HTTP hooks, hook mappings), allowing callers to deliver events to a specific agent session rather than relying on the default fan-out. The implementation is thorough: cross-agent targeting is rejected, malformed keys are caught early, all three targeted-session paths (cron.ts, server/hooks.ts, system.ts) call requestHeartbeatNow after enqueue (fixing a prior stall bug), and the HTTP hook path gates session key use behind hooks.allowRequestSessionKey + prefix allowlist policies.

Two minor style/UX concerns were identified:

  1. Swift naming: The WakeParams.sessionkey property (and related structs) use all-lowercase, violating Swift camelCase conventions and affecting the public API surface.
  2. Node presence routing: When system-event receives text starting with "Node:", the sessionKey parameter is silently ignored (intentionally routed to mainSessionKey). Callers receive success responses with no indication their routing hint was disregarded.

The core logic is sound and well-tested (103 tests across 9 files), with proper validation ordering and no security issues detected. These findings are non-blocking style/UX concerns, not correctness bugs.

Confidence Score: 4/5

  • Safe to merge. No logic bugs, security issues, or correctness problems. Two minor style/UX concerns identified.
  • The PR implements session-key routing safely with proper validation, cross-agent safety checks, and comprehensive tests (103 across 9 files). The core functionality is sound. The two identified issues are non-blocking style concerns: Swift naming conventions and a UX clarity gap for Node presence events. Neither affects correctness, security, or data integrity.
  • apps/macos/Sources/OpenClawProtocol/GatewayModels.swift and apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift for Swift naming convention improvements.

Last reviewed commit: 84a7b17

Comment on lines +49 to +58
const isNodePresenceLine = text.startsWith("Node:");
let targetSessionKey: string | undefined;
if (!isNodePresenceLine && rawSessionKey) {
try {
targetSessionKey = canonicalizeWakeSessionKey(rawSessionKey);
} catch (err) {
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, (err as Error).message));
return;
}
}

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.

When the event text starts with "Node:", any provided sessionKey parameter is not validated and has no effect — the handler always routes Node presence events to mainSessionKey (line 137). The caller receives { ok: true } with no indication their routing hint was ignored.

While this behavior appears intentional (Node presence events are system-generated and should go to the main session), callers expecting targeted dispatch may be confused. Consider either:

  1. Explicitly reject sessionKey for Node presence lines with a descriptive error message
  2. Document that Node presence events always route to the main session, so callers understand the exception

This would improve clarity for future maintainers and callers reading the API.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/gateway/server-methods/system.ts
Line: 49-58

Comment:
When the event text starts with `"Node:"`, any provided `sessionKey` parameter is not validated and has no effect — the handler always routes Node presence events to `mainSessionKey` (line 137). The caller receives `{ ok: true }` with no indication their routing hint was ignored.

While this behavior appears intentional (Node presence events are system-generated and should go to the main session), callers expecting targeted dispatch may be confused. Consider either:

1. **Explicitly reject** `sessionKey` for Node presence lines with a descriptive error message
2. **Document** that Node presence events always route to the main session, so callers understand the exception

This would improve clarity for future maintainers and callers reading the API.

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

public struct WakeParams: Codable, Sendable {
public let mode: AnyCodable
public let text: String
public let sessionkey: String?

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.

The property sessionkey uses all-lowercase naming, which violates Swift camelCase conventions. The public API exposes this as wakeParams.sessionkey instead of the idiomatic wakeParams.sessionKey. Since CodingKeys is already explicitly defined, renaming is safe and straightforward. Rename the property to follow Swift conventions. This same naming issue appears throughout both GatewayModels.swift files — consider updating all affected structs for consistency.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/macos/Sources/OpenClawProtocol/GatewayModels.swift
Line: 694

Comment:
The property `sessionkey` uses all-lowercase naming, which violates Swift camelCase conventions. The public API exposes this as `wakeParams.sessionkey` instead of the idiomatic `wakeParams.sessionKey`. Since `CodingKeys` is already explicitly defined, renaming is safe and straightforward. Rename the property to follow Swift conventions. This same naming issue appears throughout both GatewayModels.swift files — consider updating all affected structs for consistency.

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

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@BrennerSpear

Copy link
Copy Markdown
Contributor Author

@Takhoffman Would you be willing to review this? It touches the gateway session-key routing, hooks dispatch, and heartbeat wake paths — areas you've been active in recently (custom session key inheritance, session delivery invariants, cron hardening).

TL;DR: adds an optional --session-key param to all wake/system-event entry points so callers can target a specific agent session instead of fan-out. All three targeted paths (cron, hooks, system-event) call requestHeartbeatNow after enqueue. 103 tests, Greptile 4/5.

@BrennerSpear

Copy link
Copy Markdown
Contributor Author

@vincentkoc Would love your review on this — it touches hooks dispatch, gateway wake paths, and session key routing, which fall under your ownership area. Summary in the PR description. All tests pass, Greptile 4/5. Thanks!

@openclaw-barnacle

Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label Apr 15, 2026
@openclaw-barnacle

Copy link
Copy Markdown

Closing due to inactivity.
If you believe this PR should be revived, post in #pr-thunderdome-dangerzone on Discord to talk to a maintainer.
That channel is the escape hatch for high-quality PRs that get auto-closed.

@prtags

prtags Bot commented Apr 23, 2026

Copy link
Copy Markdown

Related work from PRtags group obliging-seahorse-7nmd

Title: Open PR duplicate: wake hooks ignore explicit session targets

Number Title
#35231* feat: add --session-key support to system wake/event
#70268 fix: route wake hooks to explicit sessions

* This PR

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

Labels

app: macos App: macos app: web-ui App: web-ui cli CLI command changes gateway Gateway runtime size: XL stale Marked as stale due to inactivity

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant