Address Greptile review feedback:
1. Add anyChanged guard so the function returns the original input
array when no messages were modified, matching the pattern used
by downgradeOpenAIFunctionCallReasoningPairs. This preserves the
early-exit fast path in the stream wrapper.
2. Align call order with google.ts: reasoning blocks first, then
function-call pairs.
Wire downgradeOpenAIReasoningBlocks into the openai-responses stream
wrapper alongside the existing function-call pairing sanitizer. This
prevents 400 errors when conversation history contains reasoning items
without their required following content block (e.g. after compaction,
error recovery, or session restore).
The function already existed and was tested but was only called in the
Google provider path, not the OpenAI responses path.
Fixes#54534.
* fix(cron): stop persisting "last" as literal delivery channel value
The UI controller writes the sentinel value "last" into jobs.json when
the delivery channel field is empty. This overwrites user-configured
channels (e.g. "telegram") because the form populates with "last" as
the default fallback, and saving the form materializes it as a literal
persisted value.
"last" is a runtime-only sentinel meaning "use whatever channel was
last used in the session" and should never be written to jobs.json.
When the channel field is empty, write `undefined` instead so the
runtime delivery plan resolver applies the "last" fallback at
execution time without polluting the persisted state.
Fixes#68760
* fix(cron): keep last delivery sentinel runtime-only
* fix: keep cron last delivery sentinel runtime-only (#68829) (thanks @tianhaocui)
* fix: preserve clear-to-last cron updates (#68829) (thanks @tianhaocui)
---------
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
* fix(agents): preserve session totalTokens when provider omits usage data
Fixes#67667
When a provider (e.g. MiniMax via Anthropic endpoint) does not return
usage data in its API response, hasNonzeroUsage() is false and the
entire totalTokens update block in persistSessionAfterRun is skipped.
This resets totalTokens to undefined, causing /status to show 0%
context usage even after compaction has calculated real token counts.
The fix preserves the previous totalTokens value when the current run
has no usage data, marking it as stale (totalTokensFresh: false) so
display layers know it is from a prior run. This is strictly better
than null — the user sees the last known context usage instead of 0%.
* ci: retrigger after flaky gateway shutdown test
* test(agents): port totalTokens regression test to withTempSessionStore helper post-rebase
* fix(status): surface preserved stale session totals
* fix: surface preserved stale session totals (#67695) (thanks @stainlu)
---------
Co-authored-by: Ayaan Zaidi <hi@obviy.us>