fix(gateway): accept heartbeat/cron/webhook channel hints in agent params (#73237)#73282
Conversation
Greptile SummaryThis PR fixes a validation bug in Confidence Score: 5/5This PR is safe to merge — the change is a narrow, additive fix with clear tests and no impact on existing delivery-channel logic. The fix is minimal and additive: a new constant, a typed predicate, and a single || in the validation guard. isGatewayMessageChannel is unchanged, so existing delivery-channel paths are unaffected. The normalization pipeline (normalizeMessageChannel lowercases before the predicate is called) is consistent with the new constants being lowercase, and the unit tests explicitly cover the direct-predicate no-case-folding behavior. No security or data-integrity concerns identified. No files require special attention. Reviews (1): Last reviewed commit: "fix(gateway): accept heartbeat/cron/webh..." | Re-trigger Greptile |
|
The two failing checks (
Same job names, same failures, on main run 25034307683 at commit Per CONTRIBUTING.md:
Happy to rebase once main is green if that helps the merge queue. |
8199fc8 to
debb238
Compare
|
Rebased onto current main ( No code changes — same 5-file diff (+86/-1). |
9af755a to
f07489e
Compare
|
Codex automated review: keeping this open. Keep this PR open. Current main still rejects heartbeat, cron, and webhook channel hints in the gateway agent handler, while the linked bug remains open. The PR is a focused implementation candidate: it widens validation only for named internal non-delivery hints, keeps unknown channels fail-closed, and adds regression coverage for both channel and replyChannel. Best possible solution: Keep this PR open and review or land it, or land an equivalent main-branch fix. The implementation should accept heartbeat, cron, and webhook only as internal non-delivery agent channel hints, preserve isGatewayMessageChannel semantics for actual delivery decisions, and keep regression tests for channel and replyChannel acceptance plus genuine unknown-channel rejection. What I checked:
Remaining risk / open question:
Codex Review notes: model gpt-5.5, reasoning high; reviewed against c3c8d66acf95. |
5757de8 to
ec288e3
Compare
453ed6a to
543cf25
Compare
…rams (openclaw#73237) (openclaw#73282) * fix(gateway): accept heartbeat/cron/webhook channel hints in agent params (openclaw#73237) * test(gateway): cover internal reply channel hints * test(openai): include codex mini catalog expectation * test(openai): follow codex catalog fixture split --------- Co-authored-by: Ke Wang <ke@pika.art> Co-authored-by: Peter Steinberger <steipete@gmail.com>
…rams (openclaw#73237) (openclaw#73282) * fix(gateway): accept heartbeat/cron/webhook channel hints in agent params (openclaw#73237) * test(gateway): cover internal reply channel hints * test(openai): include codex mini catalog expectation * test(openai): follow codex catalog fixture split --------- Co-authored-by: Ke Wang <ke@pika.art> Co-authored-by: Peter Steinberger <steipete@gmail.com>
…rams (openclaw#73237) (openclaw#73282) * fix(gateway): accept heartbeat/cron/webhook channel hints in agent params (openclaw#73237) * test(gateway): cover internal reply channel hints * test(openai): include codex mini catalog expectation * test(openai): follow codex catalog fixture split --------- Co-authored-by: Ke Wang <ke@pika.art> Co-authored-by: Peter Steinberger <steipete@gmail.com>
…rams (openclaw#73237) (openclaw#73282) * fix(gateway): accept heartbeat/cron/webhook channel hints in agent params (openclaw#73237) * test(gateway): cover internal reply channel hints * test(openai): include codex mini catalog expectation * test(openai): follow codex catalog fixture split --------- Co-authored-by: Ke Wang <ke@pika.art> Co-authored-by: Peter Steinberger <steipete@gmail.com>
…rams (openclaw#73237) (openclaw#73282) * fix(gateway): accept heartbeat/cron/webhook channel hints in agent params (openclaw#73237) * test(gateway): cover internal reply channel hints * test(openai): include codex mini catalog expectation * test(openai): follow codex catalog fixture split --------- Co-authored-by: Ke Wang <ke@pika.art> Co-authored-by: Peter Steinberger <steipete@gmail.com>
…rams (openclaw#73237) (openclaw#73282) * fix(gateway): accept heartbeat/cron/webhook channel hints in agent params (openclaw#73237) * test(gateway): cover internal reply channel hints * test(openai): include codex mini catalog expectation * test(openai): follow codex catalog fixture split --------- Co-authored-by: Ke Wang <ke@pika.art> Co-authored-by: Peter Steinberger <steipete@gmail.com>
Summary
Fixes #73237.
agentHandlers.agentrejectedrequest.channel/request.replyChannelvalues likeheartbeat,cron, andwebhookwithinvalid agent params: unknown channel: ..., blockingsessions_spawncalls from agent runs triggered by non-delivery sources. The validation only acceptedisGatewayMessageChannel(value)(deliverable channels + plugins +webchat).This PR adds an explicit
INTERNAL_NON_DELIVERY_CHANNELSset (heartbeat,cron,webhook) and a typedisInternalNonDeliveryChannelpredicate, then composes it into the channel-hint check insrc/gateway/server-methods/agent.tsso internal-source parent runs can spawn subagents without hitting validation.Changes
src/utils/message-channel-constants.tsINTERNAL_NON_DELIVERY_CHANNELS,InternalNonDeliveryChannel,isInternalNonDeliveryChannelsrc/utils/message-channel.tssrc/utils/message-channel.test.tsisInternalNonDeliveryChannel(members accepted, others rejected, no implicit case-folding)src/gateway/server-methods/agent.tsisKnownGatewayChannelto also acceptisInternalNonDeliveryChannelsrc/gateway/server-methods/agent.test.tsheartbeat/cron/webhook+ a regression test that genuine unknown channels still 400Tests
pnpm test src/utils/message-channel.test.ts— 4 pass (1 new)pnpm test src/gateway/server-methods/agent.test.ts— 64 pass (4 new)pnpm exec oxfmt --check— cleanpnpm exec oxlint— 0 warnings, 0 errorspnpm tsgo— cleanContext
Closes #73237.
Subagent spawning is intentionally channel-agnostic — the parent channel identity isn't relevant to child session creation. The reporter offered two fix options; this implements the second (expand the accepted-channel set with an explicit, named constant) because it keeps the existing validation a single boolean predicate and makes the new accepted values searchable / testable as a typed union, rather than scattering "skip validation for these strings" branches.
isGatewayMessageChannelis intentionally unchanged: the new constants are a separate, narrower category (non-delivery sources), not deliverable channels — anything that callsisGatewayMessageChannelto decide where to send output keeps the same behavior.