90 Commits
Author SHA1 Message Date
Wynne668andGitHub 72f77364b3 fix(google): keep embedding batch waits within timeout (#111674) 2026-07-20 11:46:06 +03:00
cacd98304e fix(sandbox): cancel CDP probe response bodies (#109767)
* fix(sandbox): cancel unsuccessful CDP probe responses

Release unread response bodies when sandbox CDP startup probes receive
non-success statuses so retry loops do not retain transport resources.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(sandbox): cancel all CDP probe responses

* test(sandbox): simplify CDP probe cleanup coverage

Signed-off-by: sallyom <somalley@redhat.com>

---------

Signed-off-by: sallyom <somalley@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: sallyom <somalley@redhat.com>
2026-07-19 23:12:27 -04:00
Wynne668andGitHub 27f05c8993 fix(inworld): reject malformed base64 TTS audio (#111197) 2026-07-19 20:48:46 -04:00
Wynne668andGitHub 0074270056 fix(xai): reject malformed streamed TTS base64 (#111201) 2026-07-19 20:40:53 -04:00
Wynne668andGitHub 8a858c9c65 fix(openai): reject malformed Codex image base64 (#111235)
* fix(openai): reject malformed Codex image base64

* fix(openai): align Codex image base64 trimming

* fix(openai): match Codex base64 decoding
2026-07-19 20:40:18 -04:00
Wynne668andGitHub 491b87c936 fix(openrouter): preserve completed music when stream cleanup fails (#111056)
* fix(openrouter): preserve completed music when stream cleanup fails

* test(openrouter): clarify stream cleanup authority

* test(openrouter): propagate stream cancellation
2026-07-18 19:49:59 -07:00
5bb969f7de fix(tlon): preserve shutdown when body cancellation fails (#111106)
* fix(tlon): observe shutdown body cancellation failures

* test(tlon): streamline shutdown cleanup proof

* test(tlon): narrow shutdown fixtures

---------

Co-authored-by: ZengWen-DT <290981215+ZengWen-DT@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 19:32:04 -07:00
ead8f691ea fix(matrix): preserve redirects when body cancellation fails (#111105)
* fix(matrix): observe redirect body cancellation failures

* test(matrix): verify rejection listener cleanup

---------

Co-authored-by: ZengWen-DT <290981215+ZengWen-DT@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 19:06:46 -07:00
7e4a76a6d0 fix(amazon-bedrock): ignore blank region env overrides (#110676)
* fix(amazon-bedrock): ignore blank region env overrides

* fix(amazon-bedrock): normalize region envs across runtimes

Co-authored-by: ZengWen-DT <ceng.wen@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 22:38:51 +01:00
d5b2749fd8 fix(ai): skip blank environment credentials during provider auth (#109691)
* fix(ai): ignore blank environment API keys

* test(ai): avoid credential-shaped fixture assignments

Co-authored-by: ZengWen-DT <ceng.wen@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 22:33:54 +01:00
Wynne668andGitHub 21c341d548 fix(push): ignore blank timeout env overrides (#110677) 2026-07-18 21:54:33 +01:00
Wynne668andGitHub 6646719c05 fix(thread-ownership): ignore blank forwarder URL env overrides (#110675) 2026-07-18 21:45:35 +01:00
Wynne668andGitHub a9fb5b4e3f fix(diagnostics-otel): ignore blank protocol env overrides (#110674) 2026-07-18 21:38:44 +01:00
37b0b12eb7 fix(tlon): release failed upload response bodies (#110442)
* fix(tlon): release failed upload response bodies

* fix(tlon): settle guarded upload responses

Co-authored-by: ZengWen-DT <ceng.wen@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 21:19:03 +01:00
1dedaea994 fix(nextcloud-talk): release failed room info response bodies (#110441)
* fix(nextcloud-talk): release failed room info response bodies

* test(nextcloud-talk): satisfy room info lint

* fix(nextcloud-talk): settle guarded response bodies

Co-authored-by: ZengWen-DT <ceng.wen@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 18:45:45 +01:00
c1eba30949 fix(qa): discard ignored guarded response bodies (#110443)
* fix(qa-lab): release failed suite gateway response bodies

* fix(qa): discard ignored guarded response bodies

Co-authored-by: ZengWen-DT <ceng.wen@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 18:08:16 +01:00
83da9500ae fix(node-host): guard Claude CLI pipe errors (#109794)
* fix(node-host): guard Claude CLI stdout/stderr pipe errors

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(node-host): make request mock generic to fix test-types CI failure

* test(node-host): harden child pipe regression

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 02:24:02 +01:00
bcc44ba1b1 fix(whatsapp): resolve abortPromise when stop signal already fired (#109903)
* fix(whatsapp): resolve abortPromise when stop signal already fired

waitForClose() races on abortPromise, but a pre-aborted gateway stop
signal never settled that promise because the abort listener was skipped.
Resolve abortPromise immediately when abortSignal.aborted is already true.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(whatsapp): resolve tsgo TS18048 and test mock in pre-aborted abortPromise fix

- Extract params.abortSignal to local const so tsgo can narrow the type
  through else-if control flow, fixing TS18048: possibly undefined
- Remove setupAbortController/ownerAcquireAbortController.abort() from
  the constructor's pre-aborted branch so openConnection() still works
  when the stop signal was already fired at construction time
- Use createSocketWithTransportEmitter() mock in the new test so
  shutdown() cleanup has sock.end() and ws.removeListener() available

* fix(whatsapp): preserve pre-aborted setup cancellation

* fix(whatsapp): unify connection abort handling

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 02:04:59 +01:00
f104c51e85 fix(clawhub): reject calendar-invalid feed timestamps (#106942)
* fix(clawhub): reject calendar-invalid feed timestamps

* fix(clawhub): preserve strict feed timestamps

* fix(test): avoid promise executor return in clack prompter test

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(clawhub): preserve feed timestamp semantics

* fix(clawhub): strengthen feed timestamp validation

Co-authored-by: ZengWen-DT <ceng.wen@xydigit.com>

* fix(time): validate full end-of-day fractions

Co-authored-by: ZengWen-DT <ceng.wen@xydigit.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-17 19:02:43 +01:00
708d2020d8 fix(reef): prevent blank guard keys from denying every message (#109667)
* fix(reef): reject blank guard credentials

* fix(reef): type fetch mock in guard credential test

Co-authored-by: Cursor <cursoragent@cursor.com>

* refactor: normalize Reef guard credentials canonically

Co-authored-by: ZengWen-DT <ceng.wen@xydigit.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-17 10:19:21 +01:00
68c4cb31d2 fix(google-meet): report blank Twilio setup credentials as missing (#109674)
* fix(google-meet): reject blank Twilio setup credentials

* fix: centralize Google Meet voice setup values

Co-authored-by: ZengWen-DT <ceng.wen@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-17 01:54:43 -07:00
07a36f6eda fix(config): preserve Unicode in validation received values (#109664)
* fix(config): preserve Unicode in validation received values

* test: tighten config diagnostic truncation proof

Co-authored-by: ZengWen-DT <ceng.wen@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-17 01:53:19 -07:00
1573c78f5b fix(lmstudio): cancel model discovery response body on non-ok (#109718)
* fix(lmstudio): cancel model discovery response body on non-ok

Wire the direct-fetch release hook to cancel unread bodies so failed
model discovery releases the TCP connection instead of leaving it open.

Co-authored-by: Cursor <cursoragent@cursor.com>

* refactor(lmstudio): unify response cleanup

Co-authored-by: Zeng Wen <27948732+ZengWen-DT@users.noreply.github.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Zeng Wen <27948732+ZengWen-DT@users.noreply.github.com>
2026-07-17 01:12:23 -07:00
9ac2f77487 fix(cli): force-stop stalled root-help renderers (#109417)
Co-authored-by: wahaha1223 <0668001153@xydigit.com>
2026-07-16 23:30:02 -07:00
f63ea72f28 fix(github-copilot): prevent failed usage checks from holding connections (#109540)
* fix(github-copilot): release failed usage responses

* test(github-copilot): preserve usage HTTP errors

Co-authored-by: ZengWen-DT <ceng.wen@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 22:09:53 -07:00
7b6c6a0802 fix(acpx): preserve Unicode in catalog tool arguments (#109589)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 21:21:04 -07:00
5f56a541d3 fix(opencode): preserve Unicode in catalog tool input (#109591)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 21:10:18 -07:00
0bb2ed321c fix(doctor): preserve Unicode in migration issue reports (#109592)
* fix(doctor): preserve Unicode in migration issue reports

* fix(doctor): preserve migration report Unicode boundaries

* test(doctor): stabilize migration Unicode boundary fixture

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 21:03:52 -07:00
54f1800d2a fix(matrix): bound recovery key stdin input (#108120)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 18:14:33 -07:00
ccb251c570 fix(process): report actual elapsed time for early lane timeouts (#109287)
* fix(process): clarify command lane timeout cause

* fix(process): complete timeout cause formatting

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 17:03:43 -07:00
Wynne668andGitHub 13ca829e2e fix(sessions): preserve lifecycle headers across short reads (#109205) 2026-07-16 15:09:06 -07:00
Wynne668andGitHub 6c8ab16158 fix(trajectory): clean up runtime files across short reads (#109206) 2026-07-16 15:02:08 -07:00
38448750eb fix(openai): stop realtime voice reconnects promptly on close (#108209)
* fix(openai): cancel realtime reconnect backoff on close

* test(openai): cover reconnect after bridge close

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 08:27:36 -07:00
83d17e34dd fix(hooks): do not load hooks with blank required env values (#108928)
* fix(hooks): reject blank required env values

* test(hooks): isolate required env cases

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 08:01:46 -07:00
dd58667be8 fix(ui): avoid usage reloads on websocket reconnect (#108726)
* fix(ui): reuse usage data across reconnects

* test(ui): use valid profile cost summaries

* test(ui): prove usage reconnect lifecycle

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 04:40:13 -07:00
f1f4b8ae8d fix: keep image attachments when steering active runs (#107657)
* fix: preserve images during active-run steering

* fix(codex): preserve steering fallback order

Co-authored-by: ZengWen-DT <ceng.wen@xydigit.com>

* test(codex): satisfy strict steering assertions

Co-authored-by: ZengWen-DT <ceng.wen@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 04:23:03 -07:00
Wynne668andGitHub 7241b2bc80 fix(vault): reject oversized credential files (#108761)
* fix(vault): bound token and JWT file reads

* fix(vault): remove awaits from synchronous credential reads
2026-07-16 04:02:44 -07:00
b7e099d36e fix(gateway): agent model overrides cannot be cleared (#108734)
* fix(gateway): allow clearing agent model overrides

* fix(protocol): preserve Swift agent model compatibility

* fix(protocol): preserve null when Swift decodes agent updates

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 03:46:37 -07:00
Wynne668andGitHub d55772ce91 fix(wizard): reject invalid plugin number inputs (#107346) 2026-07-16 00:13:16 -07:00
61b85aa1d1 fix(clickclack): stop promptly during reconnect delay (#108145)
* fix(clickclack): cancel reconnect delay on gateway abort

* fix(clickclack): clean up failed websocket cycles

Co-authored-by: ZengWen-DT <ceng.wen@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-15 01:59:58 -07:00
b01c7619cc fix(media): handle uploads with conflicting MIME metadata (#107863)
* fix(media): prefer attachment bytes for MIME detection

* fix(media): honor detected MIME in explicit image paths

Co-authored-by: ZengWen-DT <ceng.wen@xydigit.com>

* fix(media): preserve ambiguous audio container hints

Co-authored-by: ZengWen-DT <ceng.wen@xydigit.com>

* fix(media): narrow ambiguous MIME overrides

Co-authored-by: ZengWen-DT <ceng.wen@xydigit.com>

* fix(media): reconcile fetched MIME hints

Co-authored-by: ZengWen-DT <ceng.wen@xydigit.com>

* fix(media): refine generic ZIP MIME metadata

Co-authored-by: ZengWen-DT <ceng.wen@xydigit.com>

* fix(media): preserve compatible ZIP MIME hints

Co-authored-by: ZengWen-DT <ceng.wen@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-14 23:57:56 -07:00
Wynne668andGitHub f0bcf899c0 fix(imessage): preserve split Full Disk Access errors (#107393) 2026-07-14 22:52:49 -07:00
73cb408565 fix(google-meet): reject nondecimal transcript cursors (#106384)
* fix(google-meet): reject nondecimal transcript cursors

Use parseStrictNonNegativeInteger for --since validation so hex,
exponent, and fractional spellings are rejected at the CLI boundary
instead of silently coercing to different cursor offsets.

Remove the redundant file header comment to stay within the
oversized-file LOC ratchet.

* test(google-meet): harden transcript cursor coverage

* style(google-meet): format cursor tests

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-13 22:28:18 -07:00
78305b65b1 fix(commitments): reject calendar-invalid due timestamps (#106236)
* fix(commitments): reject calendar-invalid due timestamps

* test(commitments): fix calendar validation clock

* fix(commitments): preserve timestamp interpretation

* fix(commitments): preserve valid RFC 3339 dates

* chore(commitments): remove contributor changelog edit

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-13 17:08:53 -07:00
dd265e2c2a fix(skills): skill workshop apply hangs despite auto approval (#102530)
* fix: honor skill workshop auto approval without hook config

* test(skills): cover workshop config read failures

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-10 17:10:23 +01:00
a1c16f0a3d fix(usage-bar): cap warnedTemplateOverrides warn-once dedupe cache (#102659)
* fix(usage-bar): cap warnedTemplateOverrides warn-once dedupe cache

Replace unbounded warnedTemplateOverrides Set with createDedupeCache(maxSize=256)
for consistency with the bounded fileCache Map (MAX_CACHED_TEMPLATE_FILES=64)
already present in the same file.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(usage-bar): bound invalid-template warnings

Co-authored-by: ZengWen-DT <ceng.wen@xydigit.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-09 22:29:12 +01:00
baa009e26f fix(imessage): cap per-chat group-allowlist warn-once cache (#102658)
* fix(imessage): cap per-chat group-allowlist warn-once cache

Replace unbounded perChatWarned Set with createDedupeCache(maxSize=512)
to keep long-running iMessage monitor memory stable. The cache grows
with every distinct group chat the gateway sees; without a cap it can
accumulate entries indefinitely.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(imessage): prove warning cache eviction

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-09 16:16:03 +01:00
Wynne668andGitHub 6db0506474 fix: lower successful agent stop completion logs (#101703) 2026-07-07 16:29:10 -07:00
Wynne668andGitHub cd0d570164 fix(gateway): keep session history stream errors handled (#101571) 2026-07-07 04:54:38 -07:00
Wynne668andGitHub 55fa22b482 fix(process): handle taskkill spawn errors (#101392) 2026-07-07 08:06:31 +01:00
78e4672d65 fix: pace delivery recovery after startup outages (#101118)
* fix: pace delivery recovery replays

* fix: preserve paced delivery recovery budget

* fix(delivery): preserve recovery deadline while pacing

* fix(delivery): coordinate recovery replay pacing

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-07 05:58:12 +01:00
1ef4544871 fix(mattermost): strip internal tool-trace banners from outbound text (#98693)
* fix(mattermost): strip internal tool-trace banners from outbound text

Co-authored-by: Cursor <cursoragent@cursor.com>

* test(mattermost): prove outbound sanitizer send path

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-07 05:48:41 +01:00
3dd5339a53 fix(openai): stop double-prefixing SSE bodies mislabeled as JSON (#96503)
* fix(openai): stop double-prefixing SSE bodies mislabeled as JSON

OpenAI-compatible gateways that stream real SSE (data: {...}) but label the
response application/json hit the streaming JSON-wrap fallback, which re-prefixed
each frame as 'data: data: {...}' and broke JSON.parse in the OpenAI SDK. Sniff
JSON-labeled streaming bodies and relabel genuine SSE as text/event-stream so the
SSE sanitizer parses them verbatim.

* test(openai): prove mislabeled SSE stays streaming

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-06 18:49:45 +01:00
bffecbff1d fix: unblock replies after multi-agent room reset (#99091)
* fix: release stale reply work during reset cleanup

* fix: release archived reply runs during reset

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-06 11:58:33 +01:00
8380667bd0 fix(agents): keep bounded exec output UTF-16 safe (#98721)
* fix(agents): keep background exec exit notifications UTF-16 safe at the snippet cut

Background exec exit notifications truncate the command's tail output with a
raw String.slice, which can split a UTF-16 surrogate pair when an emoji lands
at the cut. Use the existing truncateUtf16Safe helper so the message delivered
to the channel never ends with a dangling surrogate half.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(agents): protect exec notify tail boundaries

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(agents): protect node exec follow-up tails

Co-authored-by: Cursor <cursoragent@cursor.com>

* test(agents): type node exec follow-up assertions

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(agents): keep bounded exec output Unicode-safe

* docs(changelog): note exec output Unicode safety

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-06 08:36:40 +01:00
6378d5efcc fix(feishu): strip internal tool-trace banners from outbound text (#98705)
Part of #90684

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 06:33:16 +00:00
Wynne668andGitHub 7e81f15961 fix: keep heredoc exec bodies out of command summaries (#99379) 2026-07-06 05:41:29 +00:00
f36f3f30ea fix(ui): recover from stale Control UI bundles (#99111)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-06 05:26:49 +01:00
d405cda95a fix(browser): resolve act targetId aliases before mismatch check (#96178)
* fix(browser): resolve act targetId aliases before mismatch check

The /act top-level and batch targetId guards compared the caller-supplied
targetId against the resolved canonical tab.targetId with raw string
equality. Any supported alias form (tabId, label, suggestedTargetId, or a
unique id prefix) resolves to a different canonical id, so act requests that
followed the documented 'prefer suggestedTargetId/tabId/label' guidance were
rejected with 403 ACT_TARGET_ID_MISMATCH even though they named the correct
tab. snapshot/open/close/tabs lack this guard and kept working, matching the
reported symptom matrix.

Resolve the action targetId through the same tab alias resolution the route
used and reject only ids that resolve to a different tab.

* fix(browser): canonicalize act targetId aliases before Playwright dispatch

The /act gate accepted tabId/label/suggested/prefix aliases of the request
tab but left them on action.targetId. The managed executor reads
action.targetId ?? targetId for an exact page lookup (executeSingleAction ->
getPageForTargetId), so an alias missed the lookup and broke the action at
runtime whenever more than one page was open (single-page masked it via the
pages.length===1 fallback). Canonicalize the action targetId (top-level and
nested batch sub-actions) to the resolved tab id before dispatch; reject ids
that resolve to a different tab. Replace the mock-masked contract assertions
with executor-action assertions plus direct canonicalizer unit tests.

* test(browser): brace act-targetId guard clauses for curly lint

* docs(changelog): note browser target alias fix

* docs(changelog): note browser target alias fix

* fix(browser): reject ambiguous batch target aliases

* test(browser): type targetless act fixture

* docs(changelog): move browser alias fix to unreleased

* chore: drop nonessential browser changelog entry

---------

Co-authored-by: Peter Steinberger <peter@steipete.me>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-05 21:12:13 +01:00
Wynne668andGitHub 61564f2d2e fix(ui): copy workspace file paths over plain HTTP (#98764) 2026-07-03 17:10:20 -07:00
e0970cfec5 fix: backup skips volatile cache paths (#98879)
* fix: skip volatile backup cache paths

* fix(backup): tolerate disappearing volatile files

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-01 23:05:37 -07:00
Wynne668andGitHub d9d6108086 fix(agents): preserve UTF-16 tool summary truncation (#98644) 2026-07-01 08:56:40 -07:00
Wynne668andGitHub eb87566334 fix(qa-lab): bound convex broker response bodies (#98619) 2026-07-01 08:30:34 -07:00
b6ad30625d fix(status): bound systemd service probes so status cannot hang on a wedged systemctl (#84698) (#94149)
* fix(status): bound systemd service probes so status cannot hang on a wedged systemctl (#84698)

* test(daemon): assert readRuntime receives the threaded status timeout opts (#84698)

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-01 06:52:14 -07:00
cb1e822f7a fix(cron): preserve provider/model on isolated-run timeout row (#95943)
* fix(cron): preserve provider/model on isolated-run timeout row

* fix(cron): carry provider/model/session into timer-built timeout rows

The reporter's blank cron_run_logs row (cron: job execution timed out
(last phase: ...)) comes from the wall-clock/cancel outcome built in
executeJobCoreWithTimeout, not the inner run catch the prior commit
patched (that catch result loses the Promise.race). Carry the
already-resolved attribution from watchdog-visible execution state into
the timer-built timeout and post-runner cancel outcomes so the persisted
row keeps provider/model/session. Pre-runner setup timeouts stay blank.

Refs #95873

* fix(cron): attribute timeout-disabled isolated-run operator-cancel rows

The timeoutSeconds:0 branch in executeJobCoreWithTimeout has no watchdog,
so it returned createOperatorCancellationOutcome() with no execution data
and never wired the execution callbacks. An operator-cancelled isolated run
with timeouts disabled still wrote a blank provider/model/session row.
Track the resolved identity locally from the same onExecutionStarted/
onExecutionPhase callbacks and carry it into the cancel outcome, matching
the timed branch. Adds a focused regression with negative control (#95873).

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-01 06:48:46 -07:00
Wynne668andGitHub 06b841fa58 fix(sms): strip internal tool traces from replies 2026-07-01 04:12:55 -07:00
Wynne668andGitHub 2af2eb2dfb fix(message-tool): apply responsePrefix to outbound sends
* fix(message-tool): apply messages.responsePrefix to outbound sends

* fix(message-tool): interpolate responsePrefix templates on sends and skip unresolved model tokens
2026-07-01 03:57:30 -07:00
dff45cae4c fix(code-mode): surface QuickJS error name and message to the model (#95906)
* fix(code-mode): surface QuickJS error name and message to the model

* fix(code-mode): preserve host error diagnostics

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-01 03:07:09 -07:00
Wynne668andGitHub ba3f68030b fix(cron): clear agentTurn thinking override by blanking the field (#96293)
* fix(cron): clear agentTurn thinking override when patched with null

Cron agentTurn patches could clear model/fallbacks/toolsAllow overrides by
sending an explicit null, but thinking had no clear path: the patch schema and
normalizer dropped thinking:null before it reached the merge logic, and the
payload merge only handled string values. Blanking the Thinking/Effort field in
the Cron Control UI therefore silently preserved the old value.

Add thinking:null support across the patch schema, exported type, normalizer,
and payload merge (mirroring model). The Control UI now sends an explicit clear
for model/thinking when an edited job blanks a previously stored override, and
the CLI gains --clear-thinking for parity with --clear-model.

* docs(cron): document --clear-thinking beside sibling clear flags
2026-06-30 17:43:22 -07:00
Wynne668andGitHub ac5af25015 fix: document stream cleanup fallback intent 2026-06-29 00:20:56 -07:00
Wynne668andGitHub 32d117c68b fix(control-ui): persist Set Default agent through config save 2026-06-28 19:15:27 -07:00
Wynne668andGitHub 4932366b92 fix(cli): keep built-in nodes commands off the plugin load path (#96702)
registerNodesCli unconditionally registered plugin CLI commands, so
lightweight built-in commands like `nodes status`/`nodes list` paid the
full plugin CLI/runtime load cost. Only resolve plugin-provided node
subcommands (e.g. `nodes canvas`) when the invoked subcommand is not
already a built-in, keeping the built-in nodes path fast.

Fixes #96697
2026-06-27 08:11:31 +08:00
Wynne668andGitHub c68484acc4 fix(gateway): report omitted chat-history messages in truncation log (#96788)
Summary:
- The PR moves Gateway `chat.history` omission accounting to a whole-pipeline reporter and adds focused helper plus real WebSocket request regression tests.
- PR surface: Source +35, Tests +219. Total +254 across 4 files.
- Reproducibility: yes. Current-main source shows the zero-count keep-last helper branch and the positive-coun ... he PR body includes a negative-control real WebSocket run where the same request test fails before the fix.

Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(gateway): count unique omitted chat-history messages + prove diag…
- PR branch already contained follow-up commit before automerge: test(gateway): prove chat.history request emits omission diagnostic

Validation:
- ClawSweeper review passed for head 414f885880.
- Required merge gates passed before the squash merge.

Prepared head SHA: 414f885880
Review: https://github.com/openclaw/openclaw/pull/96788#issuecomment-4799553366

Co-authored-by: ZengWen-DT <ceng.wen@xydigit.com>
Approved-by: takhoffman
2026-06-25 20:17:27 +00:00
d7dff3cbf4 fix(document-extract): render PDF image fallback per page so multi-page scans don't starve later pages (#96390)
* fix(document-extract): render PDF image fallback per page so multi-page scans don't starve later pages

clawpdf's mode:"images" extract applies a single maxPixels budget across
every page, so the first page consumes it and later pages collapse to ~1x1
PNGs that vision OCR models reject. Render each selected page in its own
extract() call so the pixel budget resets per page and every page yields a
usable image.

* fix(document-extract): preserve aggregate PDF render budget

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-06-25 16:37:47 +08:00
d15e89a83e fix(workboard): hide archived cards in CLI list by default (#94562)
* fix(workboard): hide archived cards in CLI list by default

The `openclaw workboard list` CLI printed soft-archived cards, while the
`workboard_list` agent tool and the `/workboard list` command both hide
cards with `metadata.archivedAt` set unless archives are requested. Users
who archived cards still saw them in CLI output and assumed archive failed.

Filter archived cards by default in the CLI list handler and add an
`--include-archived` flag mirroring the tool's `includeArchived` option, so
all three list surfaces share one default. Docs updated to match.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(workboard): preserve json list archive visibility

* fix(workboard): preserve json list archive visibility

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-06-24 10:57:06 +08:00
Wynne668andGitHub 9fa14ff61a fix(control-ui): exclude disabled cron jobs from failed count (#95723)
Overview surfaces counted any job whose lastRunStatus was "error" as a
current failure, so an intentionally disabled job that previously failed
kept inflating the top-level "failed cron" badge and attention callout.

Add a shared isCronJobActiveFailure predicate that gates the error status
on enabled, matching the adjacent overdue filter, and use it in both the
overview card and the attention items list. Historical status stays
visible in detail views via resolveCronJobLastRunStatus.
2026-06-23 01:13:19 +00:00
f3d92936b5 fix(memory-wiki): retry transient source-page rewrite race (#94443)
A concurrent atomic rewrite (write-temp + rename) of a memory-wiki source
page by the bridge re-export made fs-safe's opened-fd identity check fail
with `path-mismatch`, which the page write rethrew as a fatal "Refusing to
write" error and aborted the whole wiki_status / source-sync call. The race
is transient and benign: the file is replaced under the open handle and the
concurrent writer lands equivalent content.

Retry briefly on `path-mismatch` (the rename window closes sub-ms) and
rethrow unchanged on exhaustion, so persistent failures (directory
collision, not-file) and symlink/path-alias swaps still hard-fail exactly
as before. The identity guard is untouched; only the benign rename race is
retried, matching the sibling read path that already treats path-mismatch
as transient.

Extracts the guarded-write logic duplicated by source-page-shared.ts and
okf.ts into one writeGuardedVaultPage helper so both write paths get the
fix and the copy is removed.

Closes #92134

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 17:22:15 +00:00
1bd85e3cc3 fix(openai-completions): seal native reasoning before the answer under /reasoning on (#95283)
* fix(openai-completions): seal native reasoning before the answer

deepseek-style providers stream reasoning via reasoning_content deltas
then switch to the answer via content deltas with no boundary event.
thinking_end was only emitted by the end-of-stream finishBlock loop, so
it landed after the answer's text_delta and channels merged the answer
into the reasoning block.

Seal the open native thinking block when visible text (or a tool call)
begins so thinking_end precedes the answer; tag-based <think> reasoning
is unaffected (closed by the partitioner). finishBlock is now idempotent
so the end-of-stream loop never re-emits thinking_end.

* fix(openai-completions): preserve co-streamed reasoning

* fix(openai-completions): order co-streamed reasoning

* fix(openai-completions): seal co-streamed reasoning

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-06-22 14:33:44 +08:00
Wynne668andGitHub 99551c499b fix(skills): point gog brew install at homebrew-core gogcli (#95017) (#95019)
Merged via squash.

Prepared head SHA: a4f489c616
Co-authored-by: ZengWen-DT <290981215+ZengWen-DT@users.noreply.github.com>
Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>
Reviewed-by: @vincentkoc
2026-06-22 13:02:26 +08:00
ZengWen-DTandGitHub 73c988a9c8 fix(sessions): reset stale per-channel origin fields on channel switch (#95328)
Merged via squash.

Prepared head SHA: 3a946cb078
Co-authored-by: ZengWen-DT <290981215+ZengWen-DT@users.noreply.github.com>
Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>
Reviewed-by: @jalehman
2026-06-20 18:09:37 -07:00
ZengWen-DTandGitHub 2983edd5a2 docs(browser): clarify networkidle session support (#94020)
Clarify that `networkidle` is supported for managed and raw-CDP browser sessions but rejected for existing-session mode.

Fixes #80587.

Co-authored-by: ZengWen-DT <ceng.wen@xydigit.com>
2026-06-19 11:53:07 +01:00
5f90f08957 fix(feishu): paginate wiki node and space listing (#37626) (#93796)
* fix(feishu): paginate wiki node and space listing (fixes #37626)

client.wiki.spaceNode.list / wiki.space.list return at most one page (max
50 items); the tool ignored has_more/page_token and silently dropped every
node past the first page. Drain both endpoints via a bounded shared helper
that loops on has_more with a 100-page safety cap.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(feishu): expose wiki pagination cursors

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-06-17 09:38:41 +08:00
cfdcd5cdfd fix(qqbot): deliver cron auto-TTS voice by trusting OpenClaw temp root (#92947)
QQBot is the only channel that root-sandboxes outbound local files. Its three
gate sites (resolveOutboundMediaPath, the voice send re-check, and
structured-payload validation) only trusted the QQ Bot media storage roots, so
framework-generated scratch media written under OpenClaw's hardened temp root
(e.g. cron auto-TTS voice files from speech-core) was rejected. The send then
returned a no-identity error, the message was silently lost, yet cron still
recorded it as delivered.

Add one shared resolver (resolveTrustedOutboundMediaPath) that also trusts the
preferred OpenClaw temp root — already a sanctioned media root in core
(buildMediaLocalRoots) — and route all three gates through it so the trust set
agrees everywhere. Fixes #92816.

Co-authored-by: zengwen <zeng_wen@foxmail.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 02:11:52 +08:00
6470bb7625 fix(heartbeat): bootstrap plugin session targets (#93630)
* fix(heartbeat): bootstrap plugin session targets

* fix(heartbeat): reuse bootstrapped route plugin

* fix(heartbeat): preserve active external route plugins

* fix(heartbeat): carry prepared plugin through routing

* fix(heartbeat): canonicalize with prepared route plugin

* fix(heartbeat): preserve explicit route account context

* fix(heartbeat): enforce prepared plugin route policy

* fix(outbound): partition prepared plugin target cache

* test(cron): expect prepared delivery plugin

* test(outbound): use complete plugin fixtures

* fix(outbound): bootstrap direct metadata shells

* fix(outbound): scope external runtime activation

* test(outbound): model activated direct plugins

* fix(heartbeat): keep route policy activation-aware

* fix(heartbeat): preserve prepared plugin policy

---------

Co-authored-by: Vincent Koc <25068+vincentkoc@users.noreply.github.com>
2026-06-17 01:02:49 +08:00
ZengWen-DTandGitHub 9ed9d389e0 fix(feishu): dedupe redelivered text by stable retry identity (#93449)
Merged via squash.

Prepared head SHA: 230266c0ba
Co-authored-by: ZengWen-DT <290981215+ZengWen-DT@users.noreply.github.com>
Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>
Reviewed-by: @vincentkoc
2026-06-16 16:53:29 +08:00
01acb34bdb fix(tui): show activity indicator for system-injected runs (#93427)
* fix(tui): show activity indicator for system-injected runs

System-injected runs (bridge-notify, webhook, cron) never go through the
TUI submit path, so no active/pending run id exists when their lifecycle
"start" event arrives. handleAgentEvent dropped events for untracked runs,
leaving the status bar idle until the response landed.

Adopt an untracked lifecycle "start" for the current session (lifecycle
events always carry sessionKey) so the activity indicator shows work is
happening, mirroring how chat deltas adopt runs in handleChatEvent. Local
side-question (btw) runs never claim the active slot.

Closes #51825

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(tui): preserve concurrent injected run activity

---------

Co-authored-by: zengwen <zeng_wen@foxmail.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Vincent Koc <25068+vincentkoc@users.noreply.github.com>
2026-06-16 08:27:59 +08:00
7208567382 fix(control-ui): respect agents.defaults.timeFormat for timestamps (#93297)
Thread the existing agents.defaults.timeFormat setting through the Control UI
bootstrap config so WebChat/Control UI timestamps render in the configured
12h/24h clock instead of always using the browser locale default. "auto"
keeps the browser default, so existing deployments are unchanged.

Closes #58147

Co-authored-by: zengwen <zeng_wen@foxmail.com>
2026-06-16 00:29:44 +08:00
a42bda5b37 fix(memory): clean stale reindex temp files (#92891)
* fix(memory): clean stale reindex temp files

* fix(memory): harden stale reindex cleanup

* fix(memory): serialize safe reindex cleanup

* fix(memory): satisfy reindex lock lint

---------

Co-authored-by: zengwen <zeng_wen@foxmail.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-06-15 00:40:43 +08:00
6db496b04b fix(tui): keep spinner active when toggling tools (#92909)
* fix(tui): keep spinner active when toggling tools

* fix(tui): preserve finishing status when toggling tools

---------

Co-authored-by: zengwen <zeng_wen@foxmail.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-06-14 22:59:29 +08:00
ZengWen-DTandGitHub c773d8cd8e fix(cron): de-duplicate main-session heartbeat events
Fixes #44922

Preserve heartbeat-owned cron reminders as a single model input during heartbeat runs while keeping normal-turn fallback delivery when a heartbeat is skipped.

Proof: focused local Vitest/oxlint/format, clean autoreview, Crabbox AWS run_67abc286250a, Crabbox AWS check:changed run_bddebf014d58, and exact-head GitHub CI green for 341e807d7a.
2026-06-13 22:49:48 +08:00