* fix(reasoning-tags): accept MiniMax mm: prefix in silent-detection and stream gates
PR #93767 added MiniMax `mm:`-namespaced reasoning-tag support across the
shared sanitizer and Telegram lane coordinator, but two production reasoning-tag
recognizers were missed and still only matched the `antml:` namespace:
- src/auto-reply/tokens.ts: `taggedReasoningPrefixRe` / `openReasoningPrefixRe`
drive `stripLeadingReasoningBlocks` and `isSilentReplyPayloadText`, which 14+
call sites use to detect NO_REPLY silent payloads. A `<mm:think>…</mm:think>NO_REPLY`
reply was not recognized as silent, leaking the wrapper into delivery.
- src/agents/embedded-agent-subscribe.handlers.messages.ts: `REASONING_TAG_RE`
gates `shouldRecomputeFullStream`. A `<mm:think>` streaming chunk failed the
test, so the visible stream was not recomputed and the hidden reasoning leaked.
Add the `mm:` alternative alongside `antml:` in all three regexes, matching the
exact `(?:antml:|mm:)?` form used by #93767. Identification-only change, no other
regex logic touched.
* test(agents): cover MiniMax reasoning regressions
---------
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
* fix(browser): use openTab return value to prevent wsUrl race in ensureTabAvailable
When ensureTabAvailable opens a new tab on empty list, the return value
from openTab was discarded. A subsequent listTabs() call may return tabs
without webSocketDebuggerUrl populated yet, causing the wsUrl filter to
eliminate the newly opened tab and throw BrowserTabNotFoundError.
Fix: capture openTab's return value and merge it into candidates if the
wsUrl filter excluded it. openTab's internal discovery loop already
resolves wsUrl, so the returned tab is always valid.
* fix(browser): harden tab selection discovery
---------
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
* 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>
The previous `read_text(encoding="utf-8")` call left the UTF-8 byte
order mark (EF BB BF, three bytes) in the content string if the file
was saved by a tool that emits a BOM. The first line check
(`lines[0].strip() != "---"`) then saw "\ufeff---" and rejected the
file as "Invalid frontmatter format", even though the document was
otherwise valid frontmatter.
Co-authored-by: Zo Bot <github-automation@zo.computer>
When more than maxMissedJobsPerRestart cron jobs are overdue after gateway
downtime, runMissedJobs defers the overflow jobs to a near-future staggered
catch-up slot. start()'s second maintenance pass then recomputed each overflow
cron deferral to its natural schedule slot, because it ran future-slot repair
with the default-enabled flag. For a daily 0 9 * * * job the now+stagger
catch-up was clobbered to the next 09:00, dropping the missed run for a full
period.
Scope the exemption instead of disabling repair wholesale: runMissedJobs now
returns the ids it deferred this startup, recomputeNextRunsForMaintenance gains
skipFutureRepairJobIds to exempt exactly those ids, and start() threads them
into its pass. Overflow catch-up deferrals survive until their staggered tick
while ordinary stale-future cron slots are still repaired on startup.