Skip to content

cron: infer payload kind for model-only update patches#15664

Merged
Takhoffman merged 4 commits into
openclaw:mainfrom
rodrigouroz:fix/cron-update-payload-kind-inference
Feb 15, 2026
Merged

cron: infer payload kind for model-only update patches#15664
Takhoffman merged 4 commits into
openclaw:mainfrom
rodrigouroz:fix/cron-update-payload-kind-inference

Conversation

@rodrigouroz

@rodrigouroz rodrigouroz commented Feb 13, 2026

Copy link
Copy Markdown
Contributor

Summary

  • fix cron.update compatibility for payload patches that include agent-turn fields (for example payload.model) without an explicit payload.kind
  • infer payload.kind = "agentTurn" during cron patch normalization when agent-turn-only hints are present
  • add regression coverage in both normalization unit tests and gateway cron e2e flow

Problem

cron.update can receive partial payload patches from clients/tools. When a patch contains only agent-turn fields (like model) and omits kind, request validation rejects
it because payload.kind is required by schema.

Root Cause

Cron patch normalization inferred payload kind for message/text cases, but did not infer kind for model/thinking/timeout/delivery-only agent-turn patches.

Fix

  • extend normalizeCronJobPatch path (normalizeCronJobInput -> coercePayload) to infer kind: "agentTurn" when kind is missing and payload contains agent-turn-specific
    fields
  • preserve existing behavior for requests that already include kind

Changes

  • src/cron/normalize.ts
    • infer agent-turn kind for payload patches containing agent-turn hints
  • src/cron/normalize.test.ts
    • add unit regression: model-only payload patch infers kind: "agentTurn"
  • src/gateway/server.cron.e2e.test.ts
    • add e2e regression: cron.update accepts model-only payload patch, keeps existing message, updates model

Safety

  • inference is applied only when payload.kind is missing
  • no behavior change for valid explicit-kind requests
  • strict schema validation remains unchanged

Testing

  • pnpm test src/cron/normalize.test.ts
  • pnpm vitest run --config vitest.e2e.config.ts src/gateway/server.cron.e2e.test.ts

Greptile Overview

Greptile Summary

This PR extends cron patch normalization so cron.update can accept payload patches that only include agent-turn fields (e.g. payload.model) without explicitly providing payload.kind. The core change is in src/cron/normalize.ts where coercePayload infers kind: "agentTurn" when certain agent-turn “hints” are present, and new unit + e2e tests cover the model-only patch scenario through the gateway handler.

Confidence Score: 4/5

  • Mostly safe to merge, but kind inference logic may be too permissive for delivery-only payload patches.
  • Change is small and covered by new unit + e2e tests, but the new agentTurn inference triggers on legacy delivery fields (channel/to/deliver/bestEffortDeliver) which can unintentionally coerce otherwise-invalid/ambiguous patches into agentTurn payloads. If that broadening is unintended, it should be tightened before merging.
  • src/cron/normalize.ts

Last reviewed commit: bc3d639

@greptile-apps greptile-apps 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.

3 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment thread src/cron/normalize.ts Outdated
Comment on lines +77 to +85
const hasAgentTurnHint =
typeof next.model === "string" ||
typeof next.thinking === "string" ||
typeof next.timeoutSeconds === "number" ||
typeof next.allowUnsafeExternalContent === "boolean" ||
typeof next.deliver === "boolean" ||
typeof next.channel === "string" ||
typeof next.to === "string" ||
typeof next.bestEffortDeliver === "boolean";

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.

Over-broad kind inference

coercePayload now infers payload.kind = "agentTurn" when any of channel, to, deliver, or bestEffortDeliver are present. Those are legacy delivery hints and can plausibly appear on non-agentTurn patches (or accidental/unknown fields) and will now force the patch down the agentTurn schema path. This can cause previously-rejected payload patches to be accepted as agentTurn even when the caller didn’t intend to set/patch an agentTurn payload. Consider narrowing the inference to truly agent-turn-only fields (e.g. model/thinking/timeoutSeconds/allowUnsafeExternalContent) or otherwise gate it so delivery-only hints don’t flip the payload kind by themselves.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/cron/normalize.ts
Line: 77:85

Comment:
**Over-broad kind inference**

`coercePayload` now infers `payload.kind = "agentTurn"` when *any* of `channel`, `to`, `deliver`, or `bestEffortDeliver` are present. Those are legacy delivery hints and can plausibly appear on non-agentTurn patches (or accidental/unknown fields) and will now force the patch down the agentTurn schema path. This can cause previously-rejected payload patches to be accepted as `agentTurn` even when the caller didn’t intend to set/patch an agentTurn payload. Consider narrowing the inference to truly agent-turn-only fields (e.g. `model`/`thinking`/`timeoutSeconds`/`allowUnsafeExternalContent`) or otherwise gate it so delivery-only hints don’t flip the payload kind by themselves.

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

@openclaw-barnacle openclaw-barnacle Bot added gateway Gateway runtime size: S trusted-contributor agents Agent runtime and tooling labels Feb 13, 2026
@rodrigouroz
rodrigouroz force-pushed the fix/cron-update-payload-kind-inference branch from 00f37c2 to aa14356 Compare February 15, 2026 14:12
@Takhoffman
Takhoffman force-pushed the fix/cron-update-payload-kind-inference branch from aa14356 to bb4cc9d Compare February 15, 2026 15:12
@Takhoffman
Takhoffman merged commit 89dccc7 into openclaw:main Feb 15, 2026
8 of 9 checks passed
@Takhoffman

Takhoffman commented Feb 15, 2026

Copy link
Copy Markdown
Contributor

PR #15664 - cron: infer payload kind for model-only update patches (#15664)

Merged via squash.

  • Merge commit: 89dccc7
  • Verified: pnpm install --frozen-lockfile, pnpm build, pnpm check (fails on current origin/main in src/memory/embedding-manager.test-harness.ts; unchanged by this PR)
  • Changes made:
    M CHANGELOG.md
    A src/agents/pi-embedded-subscribe.handlers.tools.test.ts
    M src/agents/pi-embedded-subscribe.handlers.tools.ts
    M src/cron/normalize.test.ts
    M src/cron/normalize.ts
    M src/gateway/server.cron.e2e.test.ts

Summary

  • Changelog: CHANGELOG.md updated=true required=true opt_out=false

Thanks @rodrigouroz!

lovewanwan pushed a commit to lovewanwan/openclaw that referenced this pull request Apr 28, 2026
… thanks @rodrigouroz

Verified:
- pnpm install --frozen-lockfile
- pnpm build
- pnpm check (fails on current origin/main in src/memory/embedding-manager.test-harness.ts; unchanged by this PR)

Co-authored-by: rodrigouroz <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
ogt-redknie pushed a commit to ogt-redknie/OPENX that referenced this pull request May 2, 2026
… thanks @rodrigouroz

Verified:
- pnpm install --frozen-lockfile
- pnpm build
- pnpm check (fails on current origin/main in src/memory/embedding-manager.test-harness.ts; unchanged by this PR)

Co-authored-by: rodrigouroz <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 9, 2026
… thanks @rodrigouroz

Verified:
- pnpm install --frozen-lockfile
- pnpm build
- pnpm check (fails on current origin/main in src/memory/embedding-manager.test-harness.ts; unchanged by this PR)

Co-authored-by: rodrigouroz <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling gateway Gateway runtime size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants