Skip to content

Allow cron payloads to specify a stable prompt_cache_key independent of per-run sessionId #76218

@curoda

Description

@curoda

Summary

When a cron job runs against an OpenAI responses-API model (e.g. openai/gpt-5.5), OpenClaw sets prompt_cache_key = options.sessionId (provider-stream-CiQISJm-.js:1376). Cron runs are spawned with isolated session ids of the form agent:<agent>:cron:<jobId>:run:<runId>, where <runId> is unique per execution. Result: every cron run gets a fresh prompt_cache_key, OpenAI's prompt cache (24h TTL) never matches across runs, and the same recurring prompt is billed at full input price every time.

By contrast, Anthropic's automatic prefix caching IS hit across runs (because it works on prefix hash, not session id), so the same cron costs ~10% as much on Anthropic vs paid OpenAI.

Concrete impact

In one user's environment, 2 high-frequency crons (*/15 * * * * with lightContext: true) were observed at:

  • Anthropic Opus 4.7: ~9 to 11 input tokens billed per run (rest cached).
  • OpenAI GPT-5.5 (responses API): ~104K to 125K input tokens billed per run, 0% cache reuse.

That is roughly a 10,000x billable-input ratio for the same prompt. Combined with reasoning tokens billed at output rate, this drove ~$70 of unintended OpenAI spend across 2 days from cron jobs that the user expected to be cheap.

Workarounds (each has drawbacks)

  1. sessionTarget: "session:<stable-id>" to keep the sessionId stable across runs. Side effect: conversation history accumulates inside that session over time, defeating the clean-state intent of cron jobs.
  2. Pin every cron to a non-OpenAI provider. Works, but loses the option of using OpenAI for crons that genuinely benefit from it.
  3. Avoid making OpenAI the agent defaults primary while any cron uses it.

Proposed feature

Allow cron payloads (and ideally any agentTurn payload) to set an explicit promptCacheKey (or cacheKey) value that overrides the default sessionId-based key. The intended pattern: a cron job sets promptCacheKey: "cron:<jobId>" once, and every run of that job hits the same OpenAI cache entry as long as the prompt prefix is stable.

This should compose with the existing cacheRetention controls and respect provider compatibility (compat.supportsPromptCacheKey).

Optional second improvement

Consider warning at config-validation time when a cron payload pins a model id that isn't in the registered model catalog. Today such pins silently fall back to agent defaults ([cron] payload.model 'X' not allowed, falling back to agent defaults only appears in gateway.err.log at runtime), which made the cost incident much harder to predict and diagnose.

Environment

  • OpenClaw 2026.4.25
  • macOS 25.3.0 arm64
  • Models involved: openai/gpt-5.5 (responses API), anthropic/claude-opus-4-7, anthropic/claude-sonnet-4-6

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions