Commit Graph

14737 Commits

Author SHA1 Message Date
Dallin Romney
84c9f05513 Allow alternate Zalo Bot API roots (#98768)
* Allow alternate Zalo Bot API roots

* Normalize Zalo provider timestamps
2026-07-02 18:44:15 -07:00
Ayaan Zaidi
8ca6a6f8ef fix(memory-wiki): fail closed on source page read errors 2026-07-02 18:42:00 -07:00
Dallin Romney
aae57adc80 fix(qa): stagger isolated worker startup (#99294) 2026-07-02 18:39:02 -07:00
Peter Lindsey
dae86e6bec fix(telegram): guard the normal collapse-bar fallback send too
ClawSweeper review finding: F3 only wrapped the cleanup-fallback bar send.
The normal path applyProgressCollapseSummary awaited an unguarded durable
send when finalizeToPreview could not edit in place, and sendPayload throws
durable.error on delivery failure — so a cosmetic summary-bar flood-wait
could propagate and fail an otherwise-complete turn (merge-risk:
message-delivery).

Route BOTH cosmetic-bar sends through one shared guarded helper
postCosmeticSummaryBar (swallow + logVerbose), so neither the cleanup path
nor the finalizeToPreview-miss path can fail turn delivery. Add the missing
regression: no-live-message fallback bar send throwing keeps the turn alive
and the final answer delivered.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 18:38:39 -07:00
Peter Lindsey
b43687d0b5 fix(telegram): align progress-window tests with rebased core types
Post-rebase onto main, check-test-types/lint failed on our touched test
files (runtime unaffected):
- core's onVerboseProgressVisibility now takes a thunk (isActive: () =>
  boolean); the dispatch test passed a bare boolean. Pass () => true.
- our TelegramDraftStream additions (finalizeToPreview,
  rotateToNewMessageDeferringDelete) are required members; the QA-e2e
  mock streams omitted them. Add both to every mock stream.
- drop a redundant 'as string' cast (oxlint no-unnecessary-type-assertion).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 18:38:39 -07:00
Peter Lindsey
9dfa7dc87a fix(telegram): red-team hardening for the progress collapse bar
Addresses five codex red-team findings on the streamed progress-window
collapse bar. Channel-side only; no core src/** changes.

F1 (transcript pollution): the collapse bar went through
sendPayload({durable:true}), which unconditionally passed the transcript
mirror to the deliverReplies fallback, writing the cosmetic digest
("💬 1 note · 🛠️ 1 tool call · ⏱️ 4s") into the session transcript so the
model read it back as its own prior turn. Added a mirrorTranscript option to
sendPayload; the bar now sends durably with mirrorTranscript:false. Discord
parity: its summary bar (monitor/reply-delivery.ts deliverDiscordReply →
sendDurableMessageBatch) has no transcript-mirror seam at all. Real finals
keep mirroring.

F4 (tool overcount): progressSummary.noteToolCall() fired for ANY start-phase
tool, but the compositor renders a line only for work tools
(isChannelProgressDraftWorkToolName) and only when toolProgress is on, so
codex/message_tool_only turns showed "🛠️ 1 tool call" with no tool line. The
count is now gated by the same public work-tool-name check plus
streamToolProgressEnabled; non-counting tool starts still close the
reasoning/commentary bursts as a boundary.

F2 (silent collapse drop): finalizeToPreview ignored a false return from the
in-place edit (flood-wait 429 / terminal error), so applyProgressCollapseSummary
assumed "edited", cleared state, posted no bar, and left the tall window.
finalizeToPreview now returns undefined when the edit did not apply, so the
dispatch falls back to the existing durable-post path.

F3 (cosmetic send fails the turn): the cleanup-time deliverProgressCollapseSummary
could throw (429/network) and propagate out of dispatch after the real final
already delivered. The bar send is now wrapped: failures log via logVerbose and
never fail the turn; the once-guard is preserved.

F5 (ghost-preview race): rotateToNewMessageDeferringDelete rewound while a FIRST
send was still in flight; the late send landed as superseded {retain:true}, which
the dispatch handler kept as an orphaned stale bubble. A reposition now records
the in-flight generation and deletes its late-landing message (deferred), while
forceNewMessage's retain-as-durable-chunk contract is unchanged.

Tests: added unit tests for each invariant (bar delivered but absent from the
transcript mirror; message-tool start → no 🛠️ count and toolProgress-off → no
count; failed edit → undefined; bar send throw → turn still succeeds; reposition
race → superseded send deleted not retained). Telegram suites green
(bot-message-dispatch 165, draft-stream 58, progress-summary 16); extensions
tsgo clean for telegram.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 18:38:39 -07:00
Peter Lindsey
21c63be655 fix(telegram): keep interim answer blocks out of the progress window
Progress mode's streaming window is a pure activity log (Discord parity): it
carries only 🧠/💬/🛠️ progress lines, and the answer appears once, as the final
message below the collapsed bar. Answer PARTIALS were already suppressed
(updateDraftFromPartial early-returns for the answer lane), but intermediate
answer BLOCKS (info.kind === "block", before the final) still streamed into the
window via deliverLaneText, so interim assistant prose flashed inside the
working bubble mid-turn.

Fix: in the deliver() answer-block branch, suppress plain interim answer blocks
in progress mode — buffer them (like the existing skipTextOnlyBlock path) so they
still feed the final/collapse, and skip the draft-stream delivery. Media,
approval, and button blocks are not plain interim prose and fall through to
normal delivery. With plain blocks now suppressed upstream, the block-branch's
progress rotation guard only guards those remaining media/button blocks; comment
updated to say so.

This is the product decision Peter approved (interim answer-block visibility in
the window); it completes the single-message model so the window truly only ever
shows progress lines.

Tests: added "never streams an interim answer block into the progress window
(Discord parity)" — an interim block never reaches update/updatePreview and never
appears in delivered replies, while the final answer is delivered below. 233
green across bot-message-dispatch, draft-stream, progress-summary;
extensions/telegram typechecks clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 18:38:39 -07:00
Peter Lindsey
5d59338254 fix(telegram): single stationary progress window (no mid-turn rotation churn)
Progress mode now keeps ONE window message per turn, edited through every lane
handover and edited into the bar only at collapse — matching Discord's
single-message model. Previously the tool-progress window was rotated/repositioned
to a fresh bubble on every interim answer chunk and on the tools->text handover,
even though progress mode never renders interim answer text into the window
(updateDraftFromPartial already returns early for the answer lane). Each rotation
spawned a new message; that churn was the on-off jump's underlying source.

Fix — progress-mode-gated so the rotation branches fire only where they must
(block/partial); block/partial and finalized-rotation paths are untouched:
- prepareAnswerLaneForText returns early in progress mode — no rotate/reposition
  for interim answer text that never displays. (bot-message-dispatch.ts:1288)
- prepareAnswerLaneForToolProgress no longer rotates in progress mode; the tool
  lane always edits the same message (rotate stays for block/partial where answer
  text streamed first). (bot-message-dispatch.ts:1064)
- the interim answer-block path no longer rotates the window to a new bubble in
  progress mode. (bot-message-dispatch.ts:2356)

Rotation/delete paths REMAIN (all post-first / deferred-delete per cc9c2b13a9)
only for: block mode, forceNewMessage after a finalized answer (new turn), error
teardown with nothing to summarize, and superseded-generation cleanup. Collapse
uses task-9 order (final first, then edit the one window into the bar in place);
zero deleteMessage in the happy path. The end-of-turn forceNewMessage-after-
collapse is unchanged (end-of-turn, not mid-turn churn).

LOC: net +~24 prod lines, all justified — three small streamMode==="progress"
guards plus the invariant comments AGENTS.md requires for intentional caller
differences. The rotation branches are shared with block/partial and cannot be
deleted, only gated.

Tests: removed the now-obsolete task-8 "repositions the tool-progress window"
test (that path no longer runs in progress mode); added "keeps a single
stationary window when text follows durable reasoning" and a multi-boundary turn
"uses one stationary window message across a multi-boundary turn
(commentary->tool->commentary->tool->final)" asserting one window message id used
throughout, edited N times, zero deletes, one bar edit last, final posted before
the bar edit. 231 green across bot-message-dispatch, draft-stream, progress-summary;
extensions/telegram typechecks clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 18:38:39 -07:00
Peter Lindsey
d1a24ba8cc fix(telegram): send final before collapsing the window (edit-shrink anchor loss)
Live off-off finding (no reposition involved): the final answer posted below the
viewport. Cause: collapseProgressWindowIntoSummary edited the tall window bubble
DOWN to a one-line bar BEFORE the final was sent; shrinking content under the
viewport breaks the Telegram client's at-bottom follow, so the freshly sent final
landed off-screen.

Fix — swap the order in deliverProgressModeFinalAnswer:
- Snapshot the bar line (resolveProgressCollapseSummaryLine, which also consumes
  the once-guard) BEFORE the final send, so the final's own delivery cannot
  perturb the counts/timer.
- Send the final answer FIRST (it lands at the bottom of the anchored viewport),
  THEN collapse the window above it. The bar is an edit of an already-posted
  message that sits above the final, so shrinking it is harmless.
- Failure path: if the final send skips/fails, still collapse to the bar (or tear
  the window down when there is nothing to summarize) so no stale window lingers.
- Mark answerLane.finalized / markProgressFinalDelivered LAST, after the collapse
  resets lane state, so end-of-turn cleanup sees a finalized lane (stop(), not a
  spurious clear()).

Renamed collapseProgressWindowIntoSummary -> applyProgressCollapseSummary (takes
the pre-resolved line; "edited" | "posted").

Tests: updated the collapse tests to assert the new order (final delivered before
finalizeToPreview); added "sends the final answer before collapsing the window
into the bar" (order + counter snapshot) and "still collapses the window when the
final answer send is skipped". 230 green across bot-message-dispatch, draft-stream,
progress-summary; extensions/telegram typechecks clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 18:38:39 -07:00
Peter Lindsey
3932f4abb4 fix(telegram): reposition streaming window post-first, delete-old-deferred
Peter isolated the on-off focus-jump precisely: when a durable 🧠 posts BELOW
the streaming window, the window (now above the reasoning) is repositioned to
stay newest by DELETING it and reposting below. Telegram cannot move messages,
so the delete-then-repost order scroll-jumps the client.

Root cause: rotateAnswerLaneAfterToolProgress rewound the tool-progress window
with stream.clear(), which deletes the old message IMMEDIATELY when it has been
on screen past the dwell — before the replacement message is sent. Delete-first,
post-second.

Fix — invert the order, preserving arrival order:
- draft-stream: new rotateToNewMessageDeferringDelete() rewinds the stream so the
  NEXT update creates a fresh message, and schedules the superseded message's
  delete for AFTER it (detached, floored at 1.5s so the new message lands first).
  Extracted the shared deferred-delete scheduler (scheduleDetachedDelete) used by
  both clear() and the reposition. (draft-stream.ts)
- dispatch: rotateAnswerLaneAfterToolProgress now repositions via that method
  instead of clear()+forceNewMessage, so no window reposition deletes before the
  replacement lands. (bot-message-dispatch.ts:1259)

Tests: draft-stream unit tests prove the sequencing (new message sent before the
old is deleted; delete deferred; no-op with no live message). Added a dispatch
repro (durable 🧠 then answer text mid-turn -> reposition, no clear). Updated the
predating tool-progress-rotation tests to assert the deferred-delete reposition
and that any deliverer-cleanup clear() runs only AFTER the rewind. 228 green
across bot-message-dispatch, draft-stream, progress-summary; extensions/telegram
typechecks clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 18:38:39 -07:00
Peter Lindsey
7933c8cdea fix(telegram): make progress-window collapse consistent across all modes
Live on-off finding: the collapse path was inconsistent. Edit-in-place worked
in off-off/stream-off, but in on-off (tool-progress-only window, reasoning
durable) finalizeToPreview returned undefined and the caller fell into a bare
clear() -> deleteMessage -> Telegram focus-jump; a sibling sub-branch dropped
the bar entirely. Two divergent outcomes from one fallback.

Root cause: a throttled tool-progress preview could still be pending (coalesced,
never sent) when the turn ended, so the window had no message id even though it
had "rendered". finalizeToPreview gave up and the dispatch fallback deleted the
(late-landing) window.

Fixes:
- draft-stream finalizeToPreview: settle the stream, then MATERIALIZE a still-
  pending preview (send it, as a final flush would) so the window message exists
  and can be edited in place. Only when no message could be established does it
  return undefined. (draft-stream.ts:597)
- dispatch collapse: one deterministic path returning "edited" | "posted" |
  "none". A bar is ALWAYS surfaced when one exists — edited in place, or posted
  durably with ZERO deleteMessage. clear()/delete now runs ONLY for the "none"
  case (error final or nothing to summarize), never when a bar exists, so no
  collapse path can focus-jump. Split into resolveProgressCollapseSummaryLine /
  collapseProgressWindowIntoSummary / resetAnswerLaneAfterCollapse /
  teardownProgressWindow for a readable branch. (bot-message-dispatch.ts:1949)

Tests: added on-off dispatch repro (tool-progress-only + durable reasoning +
mid-turn rotation + final -> edits into bar, no clear, exactly one bar), the
no-live-message durable-bar-without-delete case, and three draft-stream
finalizeToPreview cases (edit-in-place, pending-materialize, no-window).
225 green across bot-message-dispatch, draft-stream, progress-summary;
extensions/telegram typechecks clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 18:38:39 -07:00
Peter Lindsey
af0477b61d fix(telegram): mode-gate corrections, collapse-by-edit, durable 🧠 marker
Five progress-window fixes for the Telegram streaming lane, aligning it with
the Discord reference surface:

- FIX 2: /reasoning on + /verbose off no longer kills the progress window.
  forceBlockStreamingForReasoning is now scoped to non-progress modes, so
  durable reasoning removes only the 🧠 lane; commentary/tools still stream and
  the collapse bar still posts.
- FIX 3: durable thoughts render behind the 🧠 marker instead of the literal
  "Thinking" header. The core formatReasoningMessage output is rewritten
  channel-side in reasoning-lane-coordinator (no core change), keeping the
  italic body.
- FIX 4: /verbose on no longer duplicates tool calls. canPushStreamToolProgress
  now yields under verbose so the durable verbose lane owns every progress
  surface (invariant: persistent message XOR window).
- FIX 1: the progress window collapses by EDITING the existing message in place
  into the summary bar (draft-stream finalizeToPreview), then posts the final
  below — no delete + repost, which scroll-jumped the client. Falls back to
  clearing the window when there is no bar to collapse into.
- FIX 5: message_tool_only/codex finals that bypass the in-band answer path now
  post the collapse bar from a cleanup-time fallback (sawProgressFinal from the
  dispatch counts).

Tests: adapted predating dispatch/reasoning tests to the new 🧠 marker and
collapse-by-edit behavior; added coverage for FIX 2 (window alive under
/reasoning on), FIX 4 (no window tool dup under verbose), and FIX 5
(message_tool_only collapse bar). 220 green across bot-message-dispatch,
draft-stream, progress-summary.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 18:38:39 -07:00
Peter Lindsey
16a07774a9 feat(telegram): collapse summary bar + multi-line lane rendering
Port the dev-beta2 progress-summary work onto the compositor-era dispatch:

- Post a one-line activity digest (🧠 N thoughts · 💬 N notes · 🛠️ N tool
  calls · ⏱️ Ns, Discord parity) as a durable message when the progress
  window collapses at end-of-turn, before the final answer. Counted
  per-burst channel-side; only window-streamed activity feeds the bar
  (durable rv/verbose items never do — persistent message XOR bar count),
  no bar for error finals or turns where the window never rendered.
- Render multi-line commentary with its line structure intact (per-line
  markdown conversion, joined as line breaks) instead of collapsing to
  one run-on line; per-line conversion also keeps block markdown (setext
  headings) from forming across lines.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 18:38:39 -07:00
Peter Lindsey
b95fe7f00f fix(telegram): keep the streaming preview on screen >=4s before deleting
The streaming "gerund" progress box was deleteMessage'd immediately at
teardown, so on fast turns it flashed and vanished before it could be read,
and the delete could race a just-persisted message (intermittently dropping
the first verbose commentary). Add MIN_PREVIEW_DWELL_MS (4000ms) and schedule
the delete DETACHED via setTimeout for max(0, 4000 - timeVisible), measured
from when the box first appeared. The delete never awaits, so turn teardown
is never stalled.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 18:38:39 -07:00
Peter Lindsey
f5f3a2a571 fix(telegram): convert <br> joins to newlines for parse_mode=HTML previews
Progress drafts join their rendered lines with <br>, but the Bot API
parse_mode=HTML entity set has no <br> tag — line breaks must be literal
newlines. Telegram therefore rejected every multi-line preview edit with
"can't parse entities", and the parse-error fallback silently downgraded
the whole streamed progress draft (all lanes) to unformatted plain text.
Convert <br> to newlines in the parse-mode transport branch, matching what
the rich-message branch already does.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 18:38:39 -07:00
Peter Lindsey
0ccc3b986b fix(telegram): distinguish and render streamed reasoning/commentary lanes
Streamed progress on Telegram rendered reasoning and commentary
indistinguishably and leaked the model's raw markdown: the compositor
refactor dropped the per-channel lane markers and the markdown rendering
that the pre-compositor path had.

- Pass the 🧠/💬 lane prefixes and commentaryItalics:false to the shared
  progress-draft compositor (mirroring Discord), so reasoning renders
  italic and commentary plain, each behind its own marker.
- Render lane bodies through renderTelegramHtmlText — the parse_mode=HTML
  safe converter — so **bold**, inline code, and _italic_ render as
  intended rather than leaking raw markers. Lane lines collapse to one
  line first: multi-line commentary otherwise forms block markdown (a
  `\n\n---\n\n` separator turns the paragraph above it into a setext
  <h2>), which Telegram rejects, dropping the whole preview (all lanes)
  to unformatted plain text.
- Clip long lane lines INSIDE the whole-line _…_ wrapper: clipping the
  assembled line chopped the closing underscore, silently degrading every
  long reasoning line (the common case) from italic to plain text.

Generic item payloads keep their monospace styling. Matters most for
deepseek, which narrates progress almost entirely through its
markdown-heavy reasoning lane.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 18:38:39 -07:00
Suhruth Vuppala
4440226d52 test(discord): clarify and guardrail gateway proxy selection (#99126)
* feat(discord): add HTTP_PROXY/HTTPS_PROXY env fallback for gateway WebSocket

Discord Gateway WebSocket connections now honor HTTP_PROXY/HTTPS_PROXY
environment variables as fallback before direct connection, matching the
existing pattern from Discord REST API and WhatsApp.

This enables Discord channel deployment in Kubernetes/OpenShift environments
with network policy egress restrictions, removing the need for broad :443
egress as a workaround.

- Add createEnvProxyDiscordGatewayAgent() helper (mirrors rest-fetch.ts pattern)
- Try env proxy before direct HttpsAgent in createDiscordGatewayPlugin()
- Explicit channels.discord.proxy still overrides env proxy
- Add formatErrorMessage and resolveEnvHttpProxyAgentOptions imports

Fixes #98266

* test(discord): keep gateway proxy explicit

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

* fix(discord): allow explicit remote proxy URLs

---------

Signed-off-by: sallyom <somalley@redhat.com>
Co-authored-by: sallyom <somalley@redhat.com>
Co-authored-by: joshavant <830519+joshavant@users.noreply.github.com>
2026-07-02 20:27:19 -05:00
Dallin Romney
381b44a9fc Match native Zalo bot identity fields (#99274) 2026-07-02 18:06:44 -07:00
Dallin Romney
ae9de77665 test(qa): cover Crabline Matrix sends (#99265)
* test(qa): cover Crabline Signal sends

* test(qa): cover Crabline Mattermost sends

* test(qa): cover Crabline Matrix sends
2026-07-02 17:38:06 -07:00
Dallin Romney
6432808ad2 test(qa): cover Crabline Mattermost sends (#99264)
* test(qa): cover Crabline Signal sends

* test(qa): cover Crabline Mattermost sends
2026-07-02 17:25:24 -07:00
Dallin Romney
d61bf80fde test(qa): cover Crabline Signal sends (#99262) 2026-07-02 17:18:15 -07:00
Dallin Romney
537b8a2516 test(qa): cover expanded Crabline bindings (#98779) 2026-07-02 17:07:12 -07:00
Dallin Romney
e701dc76b0 test(qa): prove native command targeting across QA transports (#98751)
* QA: prove native command session targeting

* QA: remove superseded native stop e2e

* test(qa): run native commands through Crabline Telegram

* chore(deps): scope Crabline release exception

* test(qa): retain native stop queue cleanup regression
2026-07-02 16:51:30 -07:00
Ayaan Zaidi
3380d3b345 fix(copilot): align extra context header 2026-07-02 16:05:49 -07:00
Ayaan Zaidi
63cbb35056 fix(telegram): unify group history prompt context
Move Telegram group history out of the message body fold and into the structured chat-window context used by the inbound metadata renderer. Preserve outbound self entries, post-self watermarks, recovered forum-topic routing, and richer cached reply/media fields while dropping stale recovered-topic windows.\n\nFixes #99218
2026-07-02 16:05:49 -07:00
Ted Li
b67df3797a fix(telegram): explain disabled plugin approval failures (#95973)
* fix: explain disabled Telegram plugin approvals

* fix: handle disabled Telegram native plugin approvals

* fix: resolve exec approval surface independently

* fix: tie plugin approval setup guidance to plugin surface

* Revert "fix: tie plugin approval setup guidance to plugin surface"

This reverts commit 34e3c10e23.

* fix: gate plugin approval setup guidance

* fix: gate plugin approval availability by delivery

* fix: preserve plugin approval approver auth

* fix: make plugin setup guidance explicit

* test: trim approval guidance proof radius

* Avoid setup guidance on routed approval timeout

* Carry plugin approval delivery route into timeouts

* Keep turn-source approval route visible

* fix(approvals): prefer delivered approval clients

* fix(approvals): prefer delivered approval clients

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-02 14:15:25 -07:00
Allen Hurff
968aa51b80 [codex] fix(memory-lancedb): align apache arrow peer dependency (#99118)
* fix(memory-lancedb): align apache arrow peer dependency

* fix(memory-lancedb): refresh arrow dependency graph

---------

Co-authored-by: joshavant <830519+joshavant@users.noreply.github.com>
2026-07-02 15:59:13 -05:00
Peter Lee
2d764dd8fe fix(feishu): preserve button command values in fallback text and add Feishu comment guidance with callback privacy (#94385)
* fix(interactive): preserve button command values in fallback text for degraded approval UX

* fix(interactive): keep callback values private in fallback text and narrow Feishu interactive detection

- P1: Skip rendering action.type === "callback" values in
  renderMessagePresentationFallbackText to avoid leaking opaque
  channel/plugin data into user-visible text. Command and legacy
  values are still rendered.
- P2: Replace hasMessagePresentationBlocks/hasInteractiveReplyBlocks
  with isMessagePresentationInteractiveBlock so Feishu comment
  guidance only appears when the presentation actually contains
  buttons or selects, not for text-only blocks.
- Update tests: callback button now shows label-only; all 137 tests pass.

* fix(interactive): only render typed command values in fallback text, keep legacy value private

* fix(feishu): gate document-comment command guidance on actual command action

* docs(message-presentation): document command/callback value fallback visibility

* fix(feishu): omit command guidance when URL overrides fallback command text

* docs: regenerate docs_map.md

* fix(interactive): exclude disabled buttons from fallback command rendering and guidance

* fix(interactive): extract hasRenderedCommandAction, exclude disabled buttons from command fallback

* fix(feishu): preserve command guidance marker through core presentation rendering

* fix(feishu): type-narrow channelData.feishu with isRecord before reading rendered-command marker

* fix(feishu): move hasRenderedCommandAction from public SDK into Feishu plugin as local helper

Keep the helper local to the only caller (Feishu outbound) instead of
adding a new public plugin SDK API contract. The shared fallback renderer
in renderMessagePresentationFallbackText already inlines the same
command-visibility logic; a local helper is sufficient for the Feishu
comment-thread guidance gate.

* refactor(feishu): tighten fallback command marker

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-02 12:42:31 -07:00
Ayaan Zaidi
dad7768da8 docs(telegram): document group history removal 2026-07-02 09:22:59 -07:00
Ayaan Zaidi
b07fd6f1b4 fix(telegram): keep group history always on 2026-07-02 09:22:59 -07:00
Ayaan Zaidi
5fc9b20d24 fix(gemini): stage CLI auth inside run queue
Fixes #98945
2026-07-02 08:49:40 -07:00
Pavan Kumar Gondhi
5bcd25f0fb fix(discord): gate guild metadata reads [AI] (#98966)
* fix(discord): gate guild metadata reads

* fix(discord): require guild-wide active thread reads
2026-07-02 15:26:36 +05:30
areslp
22d686d13e fix(feishu): include video upload duration (#98235) 2026-07-02 02:28:21 -07:00
qingminlong
a741956448 fix(mattermost): paginate peer directory members (#98877) 2026-07-02 00:40:24 -07:00
Peter Steinberger
2913d3aee9 fix(anthropic): restore Fable 5 Vertex simple completions (#98932)
* fix(anthropic): restore Fable 5 Vertex simple completions

* test(agents): satisfy custom API model types

* test(ci): route reliability test from temp helper

* test(agents): satisfy custom API model types
2026-07-02 07:16:39 +01:00
Vincent Koc
4d7d34e6a5 fix(qa-matrix): accept final command preview edits 2026-07-01 23:15:33 -07:00
Vincent Koc
75240f4385 fix(qa-matrix): read account state from sqlite 2026-07-01 22:56:12 -07:00
rabsef-bicrym
c8dba85b5d fix: keep Telegram outbound context on transcript time (#98769) 2026-07-01 22:15:10 -07:00
Omar Shahine
8c7ac9b9b9 fix(imessage): native poll vote-cue, echo suppression, and same-sender comment fold
Makes native iMessage polls behave correctly end to end.

What changed:
- Inbound polls render with a numbered-options vote cue so the agent casts a native vote instead of answering the poll in prose.
- poll-vote resolves the poll reference from pollId/pollGuid/messageId and now defaults to the current inbound poll message when the model omits it; still errors when no reference exists.
- poll-vote echo suppression is session-scoped, so the redundant spoken answer is dropped across the separate poll and comment runs.
- A poll's inline-reply caption is folded (not delivered as a standalone question) only when the poll creator and reply sender are both known and equal; unknown/mismatched sender falls through to the normal inbound decision gate, so no inbound reply is silently dropped.

Evidence:
- 64 passing tests in the poll suites (poll-comment, poll-render, actions), incl. sender fail-closed regressions; pnpm build clean.
- Two Codex autoreviews clean (patch is correct); ClawSweeper re-review rated it platinum hermit.
- Live-verified on macOS 26.4.1 on the deployed gateway: poll "What color pill?" -> native vote delivered with a 7333-byte payload, caption folded, zero echo.

Note: vote delivery also depends on the imsg vote-stamp fix (openclaw/imsg#150); OpenClaw ships ahead of imsg per owner decision.
2026-07-01 21:30:29 -07:00
Dave Nicoll
6e79ca3cbc fix(fal): route grok-imagine and nano-banana-2-lite edits to correct endpoints (#98688)
* fix(fal): route grok-imagine and nano-banana-2-lite edits to correct endpoints

The fal image-generation provider appends '/image-to-image' to any model
that isn't 'openai/gpt-image-*' or 'fal-ai/nano-banana-*' when reference
images are supplied. That's wrong for two models fal serves:

- `xai/grok-imagine-image`: fal 404s on '/image-to-image'. The real edit
  endpoint is '/quality/edit'. The endpoint also expects lowercase
  resolution values ('1k'/'2k' only) and a distinct aspect_ratio enum.

- `google/nano-banana-2-lite`: fal 404s on '/image-to-image'. The real
  edit endpoint is '/edit'. The endpoint does not accept a 'resolution'
  parameter.

Add schema entries for both models so ensureFalModelPath and
applyFalImageGeometry pick the right suffix and body shape. Introduce
resolution allowlist support ('resolutions: readonly string[]') and
lowercase transform ('resolutionCase: "lower"') on the schema; existing
schemas keep their behaviour (nb2 still forwards uppercase resolution
unchanged; flux/gpt-image/nb2/krea untouched). Refactor
ensureFalModelPath to consult schema.appendEditPath instead of hardcoded
prefix checks so future models only need a schema entry.

Tested:
- Existing 49 fal unit tests still pass; added 9 new tests covering the
  two new endpoints and their guard conditions (32 -> 34 tests in the
  image-generation-provider suite).
- Live fal.ai calls confirm both endpoints return 200 with real
  reference images; the buggy old URLs still return 404.

* fix(fal): preserve standard edit routing

* fix(image): apply inferred resolution per model

* fix(image): preserve provider reference limits

* fix(image): resolve reference limits per model

* fix(fal): preserve nano banana family limits

* test(ios): stub generated file list helper

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-01 20:42:25 -07:00
Ayaan Zaidi
6a96bbc7ad fix(telegram): keep timed-out webhook lanes guarded (#98806) 2026-07-01 20:33:38 -07:00
Ayaan Zaidi
2643c8cbfb fix(telegram): stop rate-limiting authenticated webhook traffic 2026-07-01 20:33:38 -07:00
Ayaan Zaidi
ac10e6bff5 fix(telegram): close webhook and evicted probe transports 2026-07-01 20:33:38 -07:00
Ayaan Zaidi
b23500a935 fix(telegram): retry transient webhook startup init errors 2026-07-01 20:33:38 -07:00
Ayaan Zaidi
b7ec2851f3 fix(telegram): spool webhook updates durably before acking Telegram 2026-07-01 20:33:38 -07:00
Ayaan Zaidi
13613ecaf1 fix(telegram): align account inspection default routing 2026-07-01 20:29:18 -07:00
yetval
85771aec05 fix(telegram): honor configured defaultAccount for omitted-account sends and actions
When no accountId was provided, resolveTelegramAccount and resolveTelegramToken
resolved the implicit default account first. Any leftover TELEGRAM_BOT_TOKEN or
top-level channels.telegram.botToken then shadowed the configured
channels.telegram.defaultAccount and default-agent binding, so gateway sends,
heartbeats, and message actions went out through the wrong bot and typically
failed with chat not found in groups the stale bot never joined. Message
actions could also fail with a missing-token error when only the named default
account had a token.

Resolve the configured default account id up front in both optional-account
entry points, matching the nextcloud-talk resolver and createTelegramActionGate.
2026-07-01 20:29:18 -07:00
Vincent Koc
1f38396239 test(memory): align dreaming corpus promotion expectations 2026-07-01 20:26:18 -07:00
Vincent Koc
1fcce9f1ee test(vercel-ai-gateway): complete guarded fetch fixtures 2026-07-01 19:49:38 -07:00
Vincent Koc
76db9a3376 fix(memory-wiki): preserve guarded collision handling 2026-07-01 19:49:38 -07:00