Two fixes from latest Codex review:
1. Truncation dedup: compare lastSentText against the truncated text (not the full
rawText) in both schedulePatch and flushPendingPatch. Previously, once a reply
grew past textLimit the guard compared the growing rawText against the stored
rawText, so the post would be patched every 200 ms with the same truncated body
— running into avoidable Mattermost rate limiting on long responses.
2. Orphan cleanup order: in the final-edit fallback path, deliver the replacement
message first and only delete the orphaned stream post afterward. If the fallback
send also fails, the user keeps the partial preview instead of losing all visible
output.
Three fixes addressing Codex review feedback:
1. Streaming opt-in: change streamingEnabled from (blockStreaming !== false) to
(blockStreaming === true) so accounts without an explicit blockStreaming setting
preserve their agent blockStreamingDefault instead of having edit-in-place
streaming silently enabled.
2. Text limit: apply textLimit truncation in schedulePatch and flushPendingPatch
before sending/patching. Intermediate preview posts only need the first chunk;
final delivery goes through deliverMattermostReplyPayload which applies full
chunking. This prevents oversize patch loops when responses exceed the limit.
3. Reply target divergence: when the final payload carries an explicit replyToId
that resolves to a different root than the streaming post was created under
(e.g. a [[reply_to_current]] directive), skip the in-place patch and fall
through to normal delivery so the reply lands in the correct thread. Any
orphaned stream post is deleted before the correct reply is sent.
Race condition: lastSentText was set synchronously before the async send/patch
completed, so a failed request was treated as delivered and subsequent ticks
skipped retrying. flushPendingPatch also didn't wait for in-flight interval ticks,
causing it to exit early (text === lastSentText guard) when a tick had just fired
but hadn't resolved yet, leaving streamMessageId null and forcing final delivery
to send a new post instead of patching the streamed one.
Fixes:
- schedulePatch interval: set lastSentText only after successful send/patch
- flushPendingPatch: wait up to 2s for in-flight patchSending before proceeding
- flushPendingPatch: set lastSentText after network success, not before
Both functions called the global fetch directly, bypassing the fetchImpl
stored in the client closure. This silently ignored any custom fetch
implementation passed to createMattermostClient (test mocks, proxy-aware
fetchers, SSRF guards).
Switch both to client.request<void>() which uses fetchImpl, auto-injects
the Authorization header, handles Content-Type for JSON bodies, and
propagates errors consistently with every other client function.
uploadMattermostFile retains its direct fetch call (multipart/form-data
conflicts with request's automatic Content-Type injection).
Addresses Greptile review: 'New functions bypass client.request,
ignoring custom fetchImpl'.
When account.blockStreaming is unset, pass undefined instead of false for
disableBlockStreaming so downstream get-reply-directives inherits the
agent-level default rather than forcing block streaming on.
Affected paths: button-click interactions (handleInteractiveMenuInteraction)
and model picker confirmations (handleModelPickerInteraction).
slash-http.ts already used undefined correctly; this brings monitor.ts
into alignment.
Addresses Codex P2 review: 'Preserve inherited block-streaming default
for model picker replies' and 'Preserve default block-streaming behavior
for button replies'.
Rebased onto v3.12 main. Upstream extracted deliver logic to reply-delivery.ts,
so streaming now wraps deliverMattermostReplyPayload() instead of replacing
the inline deliver body.
Changes:
- client.ts: add patchMattermostPost() + deleteMattermostPost() API helpers
- monitor.ts: inject streaming state (schedulePatch, flushPendingPatch, setInterval)
before main inbound createReplyDispatcherWithTyping only (3 dispatch paths exist,
only main handler gets streaming via unique humanDelay+typingCallbacks anchor)
- monitor.ts: upgrade deliver signature to (payload, info) for isFinal detection
- monitor.ts: wrap deliverMattermostReplyPayload() with isFinal streaming logic
(final+streaming: patch in-place or fallback; non-streaming: delegate to helper)
- monitor.ts: add onPartialReply + disableBlockStreaming override in replyOptions
pnpm check: no new errors introduced (pre-existing errors on main unrelated to this PR)
Fixes: https://github.com/openclaw/openclaw/issues/XXXX
PR: https://github.com/openclaw/openclaw/pull/33506
Add GLIBC_TUNABLES, MAVEN_OPTS, SBT_OPTS, GRADLE_OPTS, ANT_OPTS,
DOTNET_ADDITIONAL_DEPS to blockedKeys and GRADLE_USER_HOME to
blockedOverrideKeys in the host exec security policy.
Closes#22681
Channel tests were always using process forks, missing the shared
transform cache that vmForks provides. This caused ~138s import
overhead per file. Now uses vmForks when available, matching the
pattern already used by unit-fast and extensions suites.
Delete all experiment plans, proposals, research docs, and the
kilo-gateway-integration design doc. These are internal planning
docs that do not belong on the public docs site.
- 12 English experiment files
- 5 zh-CN experiment translations
- 1 design doc (kilo-gateway-integration)
- Remove nav groups from docs.json (English + zh-CN)
- Remove 3 redirects pointing to deleted experiment pages
- Remove dead experiment links from hubs.md
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Delete all 7 refactor design docs and the zh-CN translations.
Remove the zh-CN nav group from docs.json.
These were orphaned from English nav and accessible only by
direct URL. Internal design docs do not belong on the public
docs site.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace "seam" with clearer terms throughout:
- "surface" for public API/extension boundaries
- "boundary" for plugin/module interfaces
- "interface" for runtime connection points
- "hook" for test injection points
- "palette" for the lobster palette reference
Also delete experiments/acp-pluginification-architecture-plan.md
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace robotic prose with a scannable table and plain-language
summary. Same information, less stiff.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Redirects:
- /cron now goes directly to /automation/cron-jobs (was chaining via /cron-jobs)
- /model and /model/ now go directly to /concepts/models (was chaining via /models)
Duplicate titles disambiguated (6 of 7 - Logging is orphaned):
- Health Checks (macOS), Skills (macOS), Voice Wake (macOS), WebChat (macOS)
- General Troubleshooting (help/ vs gateway/)
- Provider Directory (providers/index vs concepts/model-providers)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>