The tts tool previously returned a fixed "Generated audio reply."
string in its content, so session transcripts lost what was actually
spoken. Across every channel, a voice-only reply left no text record
for future turns, forcing users to recover transcripts from the
provider's API. Echo the synthesized text back in the tool result
content (audio still delivered via details.media).
Sanitize the transcript before embedding so crafted utterances cannot
inject reply directives when tool output is rendered in verbose mode:
MEDIA: at line start and [[…]] markers are interrupted with a
zero-width word joiner (U+2060) that defuses parseReplyDirectives
without altering the visible text.
Replace full-table scan via vec_distance_cosine() + ORDER BY LIMIT with
sqlite-vec's native MATCH + k = ? KNN operator. Keep vec_distance_cosine()
in the SELECT so score = 1 - dist preserves the existing cosine [0,1]
semantics the downstream merge pipeline depends on.
Fixes#69666.
Benchmark on 10,827 chunks, 4096-dim embeddings:
- Before (full scan): ~8490 ms/query
- After (KNN + join): ~50 ms/query
No behavioral changes: returned ids and ordering are identical to the
previous query on all tested queries. The LIMIT ? binding is replaced by
k = ? which caps sqlite-vec's candidate set to the same count.
Address adversarial review finding on #70295: the prior swallow-on-benign
fix silently dropped short replies to Slack Connect users. The SDK's
ChatStreamer buffers text locally until buffer_size (256 default), so
short replies never trigger chat.startStream via append(). streamer.stop()
then issues startStream internally; on Slack Connect recipients this
throws user_not_found. With the prior fix that error was swallowed and
the dispatcher marked the turn delivered - user saw 'done' reaction but
no message.
SlackStreamSession now tracks delivered (true once any Slack API call
returned a response) and pendingText (accumulation of every append +
final-stop text). stopSlackStream:
- swallows the benign code when delivered=true (prior append flushed;
text is visible; same behavior as before)
- throws a new SlackStreamNotDeliveredError carrying pendingText when
delivered=false (nothing reached Slack)
dispatch.ts catches SlackStreamNotDeliveredError and posts pendingText
via a rename-bound chat.postMessage (to dodge the unicorn lint rule),
and flips streamFallbackDelivered so anyReplyDelivered stays correct.
Fixes#70295
When Slack's chat.stopStream fails with user_not_found (Slack Connect DM
recipients), team_not_found (cross-workspace shared channels), or
missing_recipient_user_id (DM closed mid-stream), the text already
delivered via append() is still visible to the user. Swallow those
specific codes and mark the session stopped rather than surfacing a
spurious 'slack-stream: failed to stop stream' error in dispatch. Other
Slack API errors still propagate.
Fixes#70295
Reworks the Codex app-server Guardian change into the final landing shape:
- keep YOLO as the default local app-server mode
- add explicit `appServer.mode: "guardian"`
- remove the legacy `OPENCLAW_CODEX_APP_SERVER_GUARDIAN` shortcut
- document Guardian configuration and behavior
- add Guardian event projection and Docker live probes for approved/ask-back decisions
Co-authored-by: pashpashpash <nik@vault77.ai>