Commit Graph

14639 Commits

Author SHA1 Message Date
Sahibzada
90e31be388 fix(memory-core): skip qmd zero-hit search sync 2026-07-01 04:50:59 -07:00
lsr911
badbae77df fix(slack): guard relay frame parsing
* fix(slack): guard relay WebSocket frame JSON.parse against malformed input

Slack Socket Mode relay receives WebSocket frames from external
infrastructure. parseRelayFrame() used bare JSON.parse() which would
throw raw SyntaxError on malformed frames, potentially crashing the
relay connection.

Wrap JSON.parse in try/catch and throw SlackRelayMalformedFrameError
with the original SyntaxError as cause, so callers can distinguish
transport errors from parse errors.

D4 dimension — all competitors have zero coverage.

Signed-off-by: lsr911 <liao.shirong@xydigit.com>

* fix(slack): repair relay frame guard tests

---------

Signed-off-by: lsr911 <liao.shirong@xydigit.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-01 04:50:08 -07:00
Peter Steinberger
60d55a1725 fix: restore main lint after timer repairs
Preserve the Tailscale timeout cleanup from #98134 and the Feishu TDZ fix from #98137 while satisfying the repository lint rules.

Credit: @zhangLei99586 authored both underlying fixes.

Co-authored-by: Peter Steinberger <58493+steipete@users.noreply.github.com>
Co-authored-by: zhangLei99586 <zhang.lei162@xydigit.com>
2026-07-01 04:43:24 -07:00
VectorPeak
1cf6ff3bdc fix(browser): decode CDP URL credentials 2026-07-01 04:14:20 -07:00
Wynne668
06b841fa58 fix(sms): strip internal tool traces from replies 2026-07-01 04:12:55 -07:00
zhangLei99586
8b14321c11 fix(feishu): hoist abortable delay timer binding
The finish() closure referenced timer which was declared with const after
finish was defined. If finish(false) ran via the abort signal check at
line 99 or via the abort event listener before the const timer assignment,
accessing timer in the temporal dead zone would throw a ReferenceError.

Hoist timer as a let binding above finish so it is safely undefined when
finish fires early, and the  guard in finish handles it.
2026-07-01 04:06:33 -07:00
Alix-007
76038c3a62 fix(matrix): bound raw transport response reads
* fix(matrix): bound raw transport response reads to prevent OOM

* test(matrix): add real node:http server proof for bound transport

Two new integration-style tests drive performMatrixRequest against a real
node:http server (no stubRuntimeFetch mock) using real undici + SSRF
dispatcher and ssrfPolicy.allowPrivateNetwork:

- over-cap: server declares Content-Length > MATRIX_SDK_RESPONSE_MAX_BYTES
  with maxBytes omitted → rejects MatrixMediaSizeLimitError (68 ms wall)
- under-cap: server returns small payload with maxBytes omitted → Buffer
  returned correctly (12 ms wall)

Addresses ClawSweeper feedback: previous proof showed only Vitest mock
output; these tests exercise the real Matrix runtime fetch path end-to-end.

* test(matrix): satisfy lint for transport proof

* fix(matrix): preserve encrypted media download limits

* test(matrix): add streaming OOM guard proof via real node:http server without Content-Length

Drive readResponseWithLimit directly by omitting Content-Length so that
enforceDeclaredResponseSize is a no-op and the streaming byte cap is the
sole enforcement path. A 20 MiB chunked server response with a 16 MiB
cap confirms the stream is canceled before full buffering (chunksWritten
< TOTAL_CHUNKS). A second case verifies under-cap payloads pass through.

* test(matrix): fix lint errors in real HTTP server proof (curly)

* test(matrix): add under-cap proof to real HTTP server test
2026-07-01 04:02:13 -07:00
Yuval Dinodia
acb0e8e88d fix(irc): classify host-less nick!user allowlist entries as mutable
An IRC sender mask is nick!user@host where only host is server verified;
nick and user (ident) are client supplied and spoofable. The allowlist
identity classifier treated any entry containing "!" or "@" as a verified
stable identity, so a host-less nick!user entry was classified stable and
matched by the host-less nick!user subject candidate. With
dangerouslyAllowNameMatching at its secure default (off), the mutable
identifier policy only strips entries owned by a dangerous field, so the
host-less entry was never stripped and a remote sender presenting the same
nick and ident was admitted regardless of host.

Require a verified @host component before an entry or subject is classified
stable. Host-less nick and host-less nick!user are now both routed to a
dangerous (mutable) field so they are gated by the same name-matching policy.
The doctor mutable-allowlist detector now also flags host-less nick!user
entries so operators who typed that undocumented shape get a warning. The
documented full nick!user@host mask stays stable and unaffected.
2026-07-01 04:01:05 -07:00
alkor2000
4076ba0bd9 fix(codex): derive terminal-idle watchdog from explicit run timeout (#85296)
* fix(codex): derive terminal-idle watchdog from effective run timeout

Fixes the early-abort half of #85242. The Codex app-server terminal-idle
watchdog used a hardcoded 30-minute default that was not derived from the
effective run timeout, so a scheduled turn configured with a longer
timeoutSeconds could be aborted early at 30 minutes even with budget left.

resolveCodexTurnTerminalIdleTimeoutMs (now in attempt-timeouts.ts after the
upstream split) accepts the effective run timeout and, with no explicit
override, follows the run budget instead of the 30-minute default:
- explicit override always wins (advanced config / tests)
- otherwise terminal-idle = max(30min floor, run budget), so a longer run is
  no longer cut short and existing protection is never shortened
- falls back to the 30min default when no run budget is known

Reuses the existing resolvePositiveIntegerTimeoutMs helper, matching the
neighbouring post-tool resolver. Adds focused unit tests for the derivation.

The diagnostic-wording half of #85242 (naming the terminal-idle watchdog in
the surfaced guidance) is left as a separate follow-up.

* fix(codex): derive terminal-idle watchdog from effective run timeout

* fix(codex): preserve default terminal idle watchdog

---------

Co-authored-by: openclaw-clownfish[bot] <280122609+openclaw-clownfish[bot]@users.noreply.github.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-01 03:25:13 -07:00
Sachintha Bhashitha
5113fbf4cc fix(slack): truncate served arg-menu option labels on a surrogate boundary (#97923) 2026-07-01 03:12:56 -07:00
wings1029
cc0980cb7a fix(browser): bound error body read in fetchHttpJson to prevent OOM (#98455)
* fix(browser): bound error body read in fetchHttpJson to prevent OOM

* fix(browser): enforce strict error response limit

---------

Co-authored-by: Peter Steinberger <58493+steipete@users.noreply.github.com>
2026-07-01 03:05:58 -07:00
qingminlong
aa91c9d4a9 fix(memory-wiki): preserve notes after transient page reads (#98360) 2026-07-01 02:55:05 -07:00
pick-cat
54d2fa240d fix(mattermost): bound null-body error response reads (#97851)
Co-authored-by: Pick-cat <266665499+Pick-cat@users.noreply.github.com>
2026-07-01 02:53:24 -07:00
Omar Shahine
c92c33d108 feat(imessage): native poll support — create, read, vote (#98421)
* feat(imessage): add native poll action

Wire the imsg CLI 'poll send' bridge command into the iMessage channel
message-tool action surface, mirroring the existing Discord poll action.
Adds the 'poll' action (gate: polls), a sendPoll runtime, selector-gated
capability advertisement (pollPayloadMessage), config type + zod schema,
regenerated channel metadata, docs, and tests.

* feat(imessage): read inbound polls, vote, and suppress vote echo

Builds on the native poll send action:

- Inbound polls now render to the agent as a readable line (question +
  numbered options + tallies) instead of the raw 0xFFFD balloon placeholder,
  so a received poll no longer reads as an empty message.
- New `poll-vote` action casts a vote via `imsg poll vote`, resolving a
  1-based option index / text / UUID to the poll's option identifier.
- message_tool_only echo guard: the model tends to narrate its choice in a
  text reply right after voting ("Blue."), which is redundant since the vote
  shows on the poll. A new `poll_vote_echo` suppression reason (alongside
  inbound_metadata_echo / internal_runtime_context_echo) drops a send/reply
  that exactly restates the just-cast vote, using the option label imsg
  returns. Extra content passes through untouched.

* fix(imessage): gate poll-vote on imsg poll.vote rpc capability

Released imsg carries the pollPayloadMessage selector (poll create) but
predates the poll.vote CLI/RPC. Gating both poll and poll-vote on that
selector alone would advertise a vote action the released CLI rejects.
Gate poll-vote additionally on the advertised poll.vote rpc method so this
plugin can ship ahead of the imsg release.

* fix(imessage): enforce poll.vote capability at execution, not just discovery

Codex review flagged the discovery gate as bypassable: a caller that already
knows action=poll-vote skips describeMessageTool and reaches handleAction
directly. Add the same imessageRpcSupportsMethod(status, 'poll.vote') check in
the poll-vote execution path (after assertPrivateApiEnabled), so a direct
dispatch on released imsg fails closed with a clear message instead of an
opaque CLI rejection. Adds a negative handleAction test.

* fix(imessage): harden native poll support

* fix(message): validate targets before channel discovery

* fix(message): validate targets before channel discovery

---------

Co-authored-by: Omar Shahine <lobster@users.noreply.github.com>
Co-authored-by: Omar Shahine <10343873+omarshahine@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-01 10:48:32 +01:00
Josh Avant
ba5244c189 fix: advertise route-aware LAN Control UI links (#98482)
* Route LAN pairing URLs by default route

* Advertise route-aware LAN Control UI links

* Fix route-aware LAN test mocks

* Narrow advertised LAN SDK export
2026-07-01 04:02:12 -05:00
Yzx
39898fe91b test(memory): cover live manager after CLI reindex (#96094) 2026-07-01 01:59:20 -07:00
xydt-tanshanshan
5f80f12a95 [AI] fix(feishu): guard partial channelRuntime in monitor startup (#94013)
* [AI] fix(feishu): guard partial channelRuntime in monitor startup

When the gateway passes a partial channelRuntime (ChannelRuntimeSurface
with only runtimeContexts but no inbound/debounce), the ?? operator in
monitor.account.ts selects it over the full local runtime, causing
monitor startup to crash on channelRuntime.debounce access.

Mirror the same ?.inbound guard pattern from bot.ts:739 (PR #93466)
to monitor.account.ts:487. When the runtime lacks inbound, fall back
to getFeishuRuntime().channel which always has the full surface.

No test: the guard mirrors an already-merged pattern (#93466) and only
affects the partial-runtime edge case that requires a gateway context.

Related to #92595

* [AI] test(feishu): add channelRuntime guard tests for monitorSingleAccount

Three test cases for the channelRuntime guard at
monitor.account.ts:489:
1. Partial channelRuntime (no inbound) → falls back to local runtime
2. Full channelRuntime with inbound → uses provided runtime
3. No channelRuntime (undefined) → falls back to local runtime

Related to #92595
2026-07-01 01:58:58 -07:00
tayoun
5bbd74266d fix(memory): skip raw snippets during promotion (#94636) 2026-07-01 01:57:27 -07:00
sunlit-deng
9bf338f3a1 fix(copilot): guard against undefined runtime.state during cli-metadata registration (#95229)
Co-authored-by: sunlit-deng <sunlit.deng@example.com>
2026-07-01 01:56:51 -07:00
lsr911
4a96c06615 fix(minimax): bound OAuth JSON response via shared provider reader (#96322)
Use readProviderJsonResponse (shared 16 MiB default cap) instead of
unbounded response.json() for MiniMax OAuth authorization code endpoint.

Signed-off-by: lsr911 <liao.shirong@xydigit.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-07-01 01:54:42 -07:00
Spencer Fuller
a9945d1e7d Fix active-memory stale ops summaries (#95888)
Co-authored-by: costaff <costaff-lapclaw-001@efiducian.com>
2026-07-01 00:59:47 -07:00
snowzlmbot
b63e06f68a fix(llm): preserve structured tool result replay
Preserve structured tool-result replay text across provider transports while keeping provider-facing redaction and Anthropic media ordering intact.

Thanks @snowzlmbot!
2026-06-30 23:44:02 -07:00
Peter Steinberger
c52583a022 feat(openai): add GPT-5.6 series support (#98333)
* feat(openai): add GPT-5.6 series support

* docs: refresh map for GPT-5.6

* fix(openai): preserve GPT-5.6 thinking metadata

* fix(codex): sync managed app server version

* fix(codex): sync managed app server version

* fix(openai): account for GPT-5.6 cache writes

---------

Co-authored-by: Peter Steinberger <steipete@golden-gate.local>
2026-07-01 06:48:57 +01:00
Brian Snyder
9f98b6e174 fix(gateway): emit stale exec approval followup diagnostics (#98293)
* fix(gateway): emit stale exec approval followup diagnostics

* fix(gateway): cover approval suppression diagnostics in ci

* fix(logging): preserve approval ids in stability bundles

* docs(exec): document suppression diagnostics

---------

Co-authored-by: BSnizND <199837910+BsnizND@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@golden-gate.local>
2026-07-01 05:20:53 +01:00
Ben Badejo
180a970ac0 fix(heartbeat): scope commitment fan-out prompts (#98169)
* fix(heartbeat): scope commitment fan-out prompts

* fix(heartbeat): isolate commitment fan-out runs

* fix(heartbeat): isolate commitment fan-out runs

---------

Co-authored-by: Benjamin Badejo <ben@benbadejo.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-06-30 20:25:28 -07:00
Marcus Castro
fa3c9de459 test(qa-lab): harden whatsapp qa scenarios (#95622)
* fix(whatsapp): preserve group participant identity in QA driver

* fix(whatsapp): infer same-chat action targets

* test(qa-lab): record whatsapp scenario posture

* test(qa-lab): harden whatsapp live scenario coverage

* docs(qa): describe whatsapp qa lane coverage
2026-07-01 00:01:09 -03:00
lsr911
853a274f14 fix(matrix): guard JSON.parse against malformed homeserver response bodies (#97973)
Wrap JSON.parse(text) in MatrixAuthedHttpClient.requestJson with try/catch to prevent a malformed Matrix homeserver response from throwing an unhandled SyntaxError.

On parse failure, throw an Error with statusCode attached (matching the buildHttpError convention) so callers can handle it like any other Matrix API error.

Signed-off-by: lsr911 <liao.shirong@xydigit.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-06-30 18:15:14 -07:00
lsr911
6e98477ee4 fix(sms): guard Twilio JSON.parse against malformed API response bodies (#97999)
Wrap JSON.parse in parseTwilioListPayload and retrieveTwilioMessagingService with try/catch to prevent a malformed Twilio API response from throwing an unhandled SyntaxError.

- parseTwilioListPayload: return [] on parse failure (fail-safe for phone number listing)
- retrieveTwilioMessagingService: throw descriptive Error on parse failure

Note: parseTwilioApiError and parseTwilioSuccessPayload already had try/catch guards (lines 85-97, 104-121).

Signed-off-by: lsr911 <liao.shirong@xydigit.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-06-30 18:15:08 -07:00
Marvinthebored
b3b51b0c91 fix(anthropic): surface Discord pre-tool commentary
Route Anthropic pre-tool narration through the commentary progress lane, preserve shared channel progress defaults, and keep Discord/Telegram reasoning gates explicit.

Thanks @Marvinthebored!
2026-06-30 18:12:07 -07:00
sunlit-deng
70cc909eea fix(openrouter): send explicit auth headers (#98187)
* fix(openrouter): send explicit auth headers

* test(openrouter): type stream mock calls
2026-06-30 18:03:14 -07:00
Peter Lee
e1724474d6 test(telegram): add regression test for forum topic message_thread_id with streamed reasoning (#94526)
* test(telegram): add regression test for forum topic message_thread_id with streamed reasoning

After thorough code tracing of all delivery paths (draft stream, durable,
non-durable, preview hooks), the current main branch already correctly
passes message_thread_id through all paths for the streaming reasoning +
final answer scenario in forum topics. The bug reported in #89352 may have
been resolved by earlier merged changes (media-path preservation,
draft/progress streaming, etc.).

This commit adds a focused regression test covering the combined
scenario to prevent future regressions.

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

* fix(telegram): assert forum thread at draft-stream boundary for both lanes

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 17:58:00 -07:00
zw-xysk
742f0c9f82 fix(memory): detect unindexed session transcripts in status mode (fixes #97814) (#97857)
* fix(memory): detect unindexed session transcripts in status mode (fixes #97814)

The status-purpose MemoryIndexManager init skips ensureSessionStartupCatchup(),
so openclaw memory status reports dirty=false while unindexed session files
exist on disk. This is a false-clean state: the operator sees no backlog,
but memory search silently misses unindexed transcripts.

Fix: run markSessionStartupCatchupDirtyFiles() in status mode. It checks
for on-disk session files without corresponding memory_index_sources rows
and sets sessionsDirty=true if found, without triggering a full sync.

The full catchup+sync runs on the next non-transient manager cycle (CLI
sync or normal runtime init).

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

* fix(memory): await status dirty detection before status() reads the flag (fixes #97814)

The status-purpose MemoryIndexManager init skips ensureSessionStartupCatchup(),
so openclaw memory status reports dirty=false while unindexed session files
exist on disk. This is a false-clean state: the operator sees no backlog,
but memory search silently misses unindexed transcripts.

Fix: move status-mode markSessionStartupCatchupDirtyFiles() from the
constructor (fire-and-forget via void) into the create() factory method
where it is awaited. This guarantees sessionsDirty is set before any
caller reads manager.status(). The detection does NOT trigger a sync,
so status remains lightweight.

Review: verified manually — unit tests 21/21 pass, compilation 0 errors.

* test(memory): add regression test for status-purpose dirty detection (fixes #97814)

Adds a regression test that exercises the actual purpose:'status' manager
flow: create a session file without index row, create status manager, verify
status().dirty is true. This addresses the ClawSweeper P1 finding requesting
a test that exercises the real status path, not only the protected helper.

Also fixes the timing issue: move dirty detection from constructor (void)
to create() factory (await), guaranteeing sessionsDirty is set before any
caller reads manager.status().

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-06-30 17:47:43 -07:00
llagy009
2b77862b92 fix(irc): guard surrogate-range codepoints in \u literal-escape decoder (#97683)
Two-step decode in decodeLiteralEscapes:
- Step 1: regex anchored to high-surrogate range (U+D800–U+DBFF) so a
  preceding BMP escape (e.g. \u0041) cannot consume the high-surrogate
  half of a valid pair like \uD83D\uDE00 (😀), leaving \uDE00 lone.
- Step 2: decode remaining BMP codepoints; preserve lone surrogates as
  six-character literals instead of corrupting them to U+FFFD in the
  outbound IRC UTF-8 stream.
2026-06-30 17:46:57 -07:00
Alix-007
fca15641db fix(discord): bound requestDiscord happy-path response reads to prevent OOM (#97693)
* fix(discord): bound happy-path API response reads to prevent OOM

Replace the unbounded res.text() call in requestDiscord's success path with
readResponseTextLimited capped at 4 MiB. Discord channel message lists and
attachment payloads can accumulate to large sizes; without a cap the process
can exhaust available memory. The error path already used readResponseTextLimited
with DISCORD_API_ERROR_BODY_LIMIT_BYTES — this applies the same guard to the
happy path using a separate DISCORD_API_RESPONSE_BODY_LIMIT_BYTES constant
sized appropriately for valid API payloads.

* test(discord): upgrade to real HTTP server proof for bound requestDiscord

* fix(discord): remove unnecessary type assertion in bound test
2026-06-30 17:46:51 -07:00
SunnyShu
1289abddcb fix(memory-wiki): gracefully handle unparsable YAML frontmatter in vault scans (#96125) (#97177)
* [AI] fix(memory-wiki): gracefully handle unparsable YAML frontmatter in vault scans (#96125)

toWikiPageSummary now catches YAML parse errors during vault-wide scans
(compile/lint/query/status) and returns a degraded WikiPageSummary with
frontmatterError set instead of letting the error propagate through
readPageSummaries -> compileMemoryWikiVault, which previously caused one
bad page to crash the entire vault.

Edit paths (apply, chatgpt-import) still throw on bad frontmatter to
prevent silent metadata loss on write.

- markdown.ts: add frontmatterError field to WikiPageSummary, extract
  splitWikiFrontmatterBlock, catch YAML.parse in toWikiPageSummary
- lint.ts: add invalid-frontmatter lint code, skip frontmatter-derived
  checks when frontmatterError is present
- markdown.test.ts: test degraded parse preserves body, empty frontmatter
- lint.test.ts: test invalid-frontmatter lint on broken page, healthy
  page unaffected

Related to #96125

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

* fix(memory-wiki): isolate invalid frontmatter scans

* fix(memory-wiki): keep malformed lint reports fail-closed

* fix(memory-wiki): reject non-mapping frontmatter

* fix(memory-wiki): validate generated index targets

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@golden-gate.local>
2026-06-30 17:21:19 -07:00
weiqinl
5e572dcf78 fix(slack): prefer current thread session for inherited outbound replies (#97168)
* fix(slack): prefer current thread session for inherited outbound replies to avoid delivery-mirror session sprawl

* fix(slack): require explicit replyToIsExplicit===false for current-session precedence

* fix(slack): canonicalize inherited thread replies

---------

Co-authored-by: Peter Steinberger <steipete@golden-gate.local>
2026-06-30 16:38:34 -07:00
Vincent Koc
cb00045afc test(qa): make memory channel scenario wait for final answer
(cherry picked from commit cf64cf788e)
2026-06-30 15:54:12 -07:00
Vincent Koc
3e2646a786 fix(release): use workspace host deps in release lockfile
(cherry picked from commit d377c0f910)
2026-06-30 15:54:12 -07:00
Vincent Koc
51e0997c2b test(qa): accept async image fixture coverage
(cherry picked from commit 9b703d0cd6)
2026-06-30 15:54:11 -07:00
Vincent Koc
31f58cd9de test(codex): harden run-attempt temp cleanup
(cherry picked from commit 5f4fa97835)
2026-06-30 15:54:11 -07:00
Vincent Koc
6528912e90 fix(telegram): recover stalled ingress spool claims
Backport of #97118 to release/2026.6.11.

(cherry picked from commit 8346e87808)
2026-06-30 15:54:11 -07:00
Alix-007
076da567f4 fix(imessage): recognize MiniMax mm: reasoning tags in reflection guard (completes #93767) (#93820)
* fix(imessage): detect MiniMax mm: namespaced reasoning tags in reflection guard

The iMessage reflection guard's THINKING_TAG_RE only matched bare
`<think>/<thought>` tags, so MiniMax's `<mm:think>` namespaced reasoning
tags (and Anthropic's `antml:` prefix) were not recognized as reflected
assistant content. When such reasoning leaked back inbound, the guard
treated it as a normal user message instead of dropping it, allowing
recursive echo amplification.

Accept the known reasoning-tag namespace prefixes `(?:antml:|mm:)?` on
the think/thought alternatives, mirroring the shared reasoning-tag
contract in src/shared/text/reasoning-tags.ts (PR #93767). This is the
remaining channel-monitor complement of #93767 for the iMessage path;
the optional prefix is a pure recognition enhancement with no change to
the bare-tag, code-region exemption, or other reflection patterns.

Verified by driving the real detectReflectedContent export:
  <mm:think>secret</mm:think>visible  -> isReflection=true (was false)
  <think>...</think>       -> isReflection=true
  <think>secret</think>                -> isReflection=true (no regression)
  "thinking about minimax algorithms"  -> isReflection=false (no false-positive)
  `<mm:think>x</mm:think>` in code     -> isReflection=false (code exemption kept)

* chore: retrigger CI for real behavior proof check

* refactor(imessage): tighten reflection guard coverage

---------

Co-authored-by: Peter Steinberger <steipete@golden-gate.local>
2026-06-30 12:41:42 -07:00
NIO
765d05c2e4 fix(moonshot): bound video description JSON response reads (#96502)
* fix(moonshot): bound video description JSON response reads

The Moonshot video description endpoint used an unbounded await res.json()
to parse the media understanding response. Route through
readProviderJsonResponse (16 MiB cap) to match the bound already in
place for other media understanding providers (xai, openrouter).

AI-assisted.

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

* test(moonshot): add bounds and malformed-JSON coverage for video description

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-30 12:12:46 -07:00
Vincent Koc
66e676d29b chore(release): close out 2026.6.11 on main 2026-06-30 11:31:08 -07:00
Vincent Koc
c16bb8725a fix(channels): keep text previews UTF-16 safe 2026-06-30 11:04:32 -07:00
lsr911
7d98ad2a92 fix(signal): guard containerRestRequest JSON.parse against malformed responses (#98073)
* fix(signal): guard containerRestRequest JSON.parse against malformed responses

Wrap JSON.parse(text) in containerRestRequest with try/catch to prevent a malformed Signal REST container response from throwing an unhandled SyntaxError.

On parse failure, throw a descriptive Error. The success body is already bounded by readProviderTextResponse (16 MiB cap, D1 protection).

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: lsr911 <liao.shirong@xydigit.com>

* fix(signal): add real HTTP server proof for malformed JSON guard

Starts a local node:http server returning malformed JSON, then calls
containerRestRequest against it.  This exercises the actual changed
try/catch code path through the real fetch stack (no mock override).

Proof output:
  PASS  malformed JSON: throws Error :: type=Error
  PASS  malformed JSON: message describes malformed JSON
  PASS  malformed JSON: NOT raw SyntaxError

Signed-off-by: lsr911 <liao.shirong@xydigit.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: lsr911 <liao.shirong@xydigit.com>

* test(signal): remove committed proof script

---------

Signed-off-by: lsr911 <liao.shirong@xydigit.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-06-30 10:50:59 -07:00
Ayaan Zaidi
86bdfec6b7 refactor(telegram): simplify album prompt selection 2026-06-30 10:45:44 -07:00
NianJiuZst
44f3c3e43a test(telegram): satisfy album context lint 2026-06-30 10:45:44 -07:00
NianJiuZst
bba63d3fe0 fix(telegram): omit skipped album context 2026-06-30 10:45:44 -07:00
NianJiuZst
9aec0f089b fix(telegram): hydrate album sibling media context 2026-06-30 10:45:44 -07:00