Commit Graph

37799 Commits

Author SHA1 Message Date
Chris Zhang
6ade320421 fix(bluebubbles): apply cross-chat guard to full message GUIDs as well
The cross-chat guard added in the prior commit (resolveBlueBubblesMessageId
with chatContext) only ran on numeric short ids — `if (/^\d+$/.test(trimmed))`.
Full GUID input fell through to `return trimmed` with no chat check.

Once the short-id guard started rejecting cross-chat reuses, agents would
retry the same call with the full GUID copied from history or a previous
tool result. That second attempt bypassed the guard entirely and the
group reaction landed in the DM anyway — exactly the symptom the prior
commit was meant to close.

Apply the same `isCrossChatMismatch` check to full GUID input. Cache miss
still falls through (callers may legitimately supply a fresh-from-the-wire
GUID the cache hasn't observed yet), but cache hits with a chat mismatch
throw with a remediation hint pointed at the chat target rather than at
the id format — telling an agent to "retry with the full GUID" makes no
sense when it already supplied one.

Tests (extensions/bluebubbles/src/monitor-reply-cache.test.ts):
- UUID + same chat → resolves
- UUID + different chat → throws (this is the regression)
- UUID + cache miss → passes through (preserves behavior for fresh GUIDs)
- UUID + empty chatContext → passes through (preserves prior behavior)
- UUID error message hints at the chat target, not the id format
- chatIdentifier fallback applies to UUID input too

Local patch for upstream consideration — completes the cross-chat guard
started in the prior commit so both id forms are protected symmetrically.
2026-04-28 21:06:49 +01:00
Chris Zhang
4bd3d258cd fix(bluebubbles): refuse sender-DM fallback when resolving group inbound chatGuid
When a BlueBubbles inbound webhook arrives without `chatGuid`, processMessage
falls back to `resolveChatGuidForTarget` to look it up. The previous fallback
target was:

    isGroup && (chatId || chatIdentifier)
      ? <chat_id or chat_identifier>
      : { kind: "handle", address: message.senderId }

That `else` branch quietly covered two very different cases:

1. DM with no chatGuid — resolving via sender handle is correct, the chat
   IS the conversation with that handle.
2. **Group with no chatGuid AND no chatId AND no chatIdentifier** — resolving
   via sender handle yields *that sender's DM chatGuid*, then the rest of
   processMessage uses it for ack reactions, mark-read, outbound reply cache,
   typing indicators, and outboundTarget.

Case 2 is reachable: `monitor.webhook.test-helpers.ts` ships a default
`createMessageReactionPayloadForTest` payload with no chatGuid/chatId/
chatIdentifier and `isGroup` defaulted to `false`, mirroring real BlueBubbles
reaction/tapback webhooks. When a group reaction or tapback arrives in that
shape and isGroup is later corrected to true (or the message takes the same
poisoned path), `chatGuidForActions` becomes the sender's DM chatGuid. The
poisoned chatGuid then writes the outbound reply cache (line ~1395) with the
wrong chat, defeating the cross-chat short-id guard added in
9912472289 — a later short id resolved against that cache cannot detect the
mismatch and the agent's reaction/reply silently lands in the DM.

Symptom Chris observed (recurring after 9912472289 baked): group messages
getting reacted to from the agent's side show up in a DM transcript with
that sender, attached to a message GUID the user can no longer locate in
the DM.

Extract the fallback target construction into
`buildBlueBubblesInboundChatResolveTarget` so the rule is testable in
isolation and the wrong fallback can never be reached again:

- Group inbound + chatId present → `chat_id`
- Group inbound + chatIdentifier present → `chat_identifier`
- **Group inbound + neither → return null (caller skips chatGuid-dependent actions)**
- DM inbound → `handle` (unchanged: the conversation IS that sender)

processMessage now logs at verbose when the group case returns null instead
of silently degrading to the sender's DM.

Tests: extensions/bluebubbles/src/monitor-processing-chat-resolve.test.ts
covers the eight branches (group with id, group with identifier, group
preferring id, group with neither, blank/non-finite/null variants, DM, DM
with chat_id present, DM with empty sender).

Local patch for upstream consideration — pairs with the short-id chat guard
landed in the previous commit.
2026-04-28 21:06:49 +01:00
Chris Zhang
9f97e8c521 fix(bluebubbles): scope short message id resolution to the caller's chat
BlueBubbles short message ids (numeric aliases like "1", "5" that agents
use instead of full GUIDs to save tokens) are allocated from a single
global counter across every account and every chat. Nothing in
resolveBlueBubblesMessageId verified that the resolved GUID was actually
in the chat the caller was acting on, so any time an agent reused or
mis-remembered a short id — especially common after a long group
conversation — the id could silently point at a different chat entirely.

Symptom Chris observed: reactions/tapbacks and quoted replies authored
inside a group would intermittently land in a DM, targeting an old
message the user could no longer see. Tool call looks successful, chat
archive shows a group reaction appearing in the DM transcript.

Add an optional chatContext parameter to resolveBlueBubblesMessageId
(chatGuid / chatIdentifier / chatId). When provided, look up the
cached reply entry for the resolved GUID and compare. A clear mismatch
(same identifier present on both sides, different values) throws with a
message that lists both chats and points at "use the full GUID", so the
agent fails fast and retries with a disambiguated id. Ambiguous cases
(either side missing all identifiers) pass through to preserve existing
behavior for callers that cannot supply chat hints. The comparison
mirrors resolveReplyContextFromCache so outbound and inbound paths agree
on scope.

Update every call site that resolves a short id for outbound BB traffic
to pass chatContext:
- extensions/bluebubbles/src/actions.ts: react, edit, unsend, reply
  (build context from chat* params, then to/target, then the tool's
  currentChannelId)
- extensions/bluebubbles/src/channel.ts sendText: derive context from
  the `to` target
- extensions/bluebubbles/src/media-send.ts: same
- extensions/bluebubbles/src/monitor-processing.ts deliver path: pass
  the chat already resolved for routing

Add buildBlueBubblesChatContextFromTarget to targets.ts so callers can
project a raw target string (`chat_guid:...`, `chat_id:42`,
`imessage:+1...`, bare handle) into the context shape.

Tests:
- extensions/bluebubbles/src/monitor-reply-cache.test.ts (new, 8 cases):
  same-chat resolves, cross-chatGuid throws, ambiguous passes,
  chatIdentifier fallback, chatId fallback, full GUID input bypasses,
  error message identifies both chats, unknown short id still errors.
- extensions/bluebubbles/src/actions.test.ts: update the react short-id
  assertion to verify chatContext now flows through.

Local patch for upstream consideration — same root cause affects every
BB user; plan is to open a separate upstream PR once this bakes locally.
2026-04-28 21:06:49 +01:00
Peter Steinberger
96a21e2553 fix(qa): restore release channel reply checks 2026-04-28 21:05:35 +01:00
Peter Steinberger
3aac8e650c fix(googlechat): keep config schema on runtime api 2026-04-28 21:04:44 +01:00
Peter Steinberger
5dfc14d49b fix(tasks): close stale terminal acp sessions 2026-04-28 21:03:55 +01:00
Peter Steinberger
3cad579c4e fix(plugin-sdk): restore discord compatibility facade 2026-04-28 20:59:26 +01:00
Peter Steinberger
d1a7612bd6 docs(changelog): narrow gateway status fix reference 2026-04-28 20:58:09 +01:00
Peter Steinberger
c399fb750b fix(ui): handle Google Live binary talk frames 2026-04-28 20:57:46 +01:00
Peter Steinberger
0a2d635e68 fix(gateway): harden local reachability checks
Co-authored-by: arthurianresolve <arthurianresolve@users.noreply.github.com>
Co-authored-by: codexGW <9350182+codexGW@users.noreply.github.com>
2026-04-28 20:57:14 +01:00
Peter Steinberger
3d736f67cf test: fix onboard Docker test state setup 2026-04-28 20:56:19 +01:00
Peter Steinberger
c1c217035d test: align bare reset bootstrap expectation 2026-04-28 20:56:04 +01:00
Peter Steinberger
3b593bc561 fix(cli): authorize gateway model probe overrides 2026-04-28 20:55:44 +01:00
Vincent Koc
87172dc9fe fix(ci): harden package acceptance refs 2026-04-28 12:53:05 -07:00
Peter Steinberger
f0c8640d81 test: speed up read-only channel fixtures 2026-04-28 20:49:55 +01:00
Peter Steinberger
0dcab4e347 fix(agents): harden bootstrap and ACP session routing 2026-04-28 20:47:34 +01:00
Vincent Koc
3ae69498e2 ci: shard channel codeql security
Add a narrow channel-runtime CodeQL critical-security shard and document it.
2026-04-28 12:46:44 -07:00
Peter Steinberger
230f8886c6 ci: keep full release validation children pinned 2026-04-28 20:43:39 +01:00
HeYan
170a961744 fix(config): guard non-string values in env.vars to prevent TypeError (#42402)
* fix(config): guard non-string values in env.vars to prevent TypeError (#42363)

* docs(changelog): note malformed env vars crash fix

---------

Co-authored-by: Altay <altay@uinaf.dev>
2026-04-28 22:43:22 +03:00
Peter Steinberger
0f3a9d812b docs(changelog): note model auth fixes 2026-04-28 20:40:11 +01:00
Peter Steinberger
771846c5fa fix(bedrock): omit Opus temperature for profiles 2026-04-28 20:39:58 +01:00
Peter Steinberger
1f26e32f5f fix(agents): strip empty assistant transcript text 2026-04-28 20:39:58 +01:00
Peter Steinberger
1824ceba54 fix(agents): reuse cached Claude keychain credentials 2026-04-28 20:39:58 +01:00
Peter Steinberger
aec5efed8d fix(agents): resolve model aliases before fallback 2026-04-28 20:39:58 +01:00
Peter Steinberger
06a0cd88fb fix(discord): align gateway metadata timeout tests 2026-04-28 20:39:28 +01:00
Peter Steinberger
0608c1015b perf(plugins): cache manifest metadata loads 2026-04-28 20:39:28 +01:00
Vincent Koc
98f5fd12df docs(gateway/security): list system-reminder and previous_response in outbound stripping
For c2d31a5e59: docs/gateway/security/index.md "External content
special-token sanitization" section already mentions the outbound
sanitizer with `<tool_call>` and `<function_calls>` examples, but it
predates the new internal-runtime-scaffolding stripping that targets
`<system-reminder>` and `<previous_response>` tags. Adds those two tags
as explicit examples and notes the final channel delivery boundary so
operators reading the security page see the same coverage exposed by
the c2d31a5e59 sanitizer.
2026-04-28 12:39:15 -07:00
Peter Steinberger
c500e8704f fix(gateway): recover stale session lanes 2026-04-28 20:37:29 +01:00
Peter Steinberger
933c7968dc fix(ci): stabilize full release validation lanes 2026-04-28 20:36:42 +01:00
Peter Steinberger
1e9faa2a59 docs: document inter-session prompt guards 2026-04-28 20:34:55 +01:00
Peter Steinberger
c2d31a5e59 fix(outbound): strip internal runtime scaffolding 2026-04-28 20:34:55 +01:00
Peter Steinberger
c5c08c074a fix(agents): mark inter-session prompts 2026-04-28 20:34:54 +01:00
Peter Steinberger
5de06ac00e test: keep bundled root fixtures scoped 2026-04-28 20:28:45 +01:00
Peter Steinberger
cb8c513ce3 fix(telegram): honor final-only streaming mode 2026-04-28 20:28:06 +01:00
Vincent Koc
df8611c420 test(loader): re-enable bundled fixtures 2026-04-28 12:24:28 -07:00
Vincent Koc
b014462690 fix(test): trust bundled plugin fixtures explicitly 2026-04-28 12:24:28 -07:00
Peter Steinberger
0311e172e0 test: preserve bundled dir fixture helpers 2026-04-28 20:19:51 +01:00
Peter Steinberger
c89b67e6c8 test(config): isolate bundled channel metadata fixture 2026-04-28 20:17:51 +01:00
Peter Steinberger
9f37ff0c6c test: allow bundled root fixtures under vitest 2026-04-28 20:14:56 +01:00
Peter Steinberger
e61756f9e8 test(plugin-sdk): avoid heavy facade fallback fixture 2026-04-28 20:14:14 +01:00
Peter Steinberger
df4e2ecb87 fix(plugin-sdk): expose concrete memory host types 2026-04-28 20:14:14 +01:00
Peter Steinberger
4a24b23e3e fix(ci): stabilize full release validation 2026-04-28 20:14:14 +01:00
Peter Steinberger
f641691910 fix(discord): harden account and binding routing 2026-04-28 20:08:27 +01:00
Vincent Koc
87fd216d9a chore(plugin-sdk): refresh api baseline 2026-04-28 12:06:27 -07:00
Peter Steinberger
702e5fc4a9 test: isolate facade bundled fixture roots 2026-04-28 20:04:06 +01:00
Peter Steinberger
6d4599a796 fix: satisfy discord gateway lint 2026-04-28 19:54:52 +01:00
Peter Steinberger
f2f34e5f35 fix: restore ci gates on main 2026-04-28 19:54:52 +01:00
Vincent Koc
bb0461b682 ci: shard channel codeql quality
Add a narrow channel-runtime CodeQL critical-quality shard and document it.
2026-04-28 11:52:54 -07:00
Peter Steinberger
6d542ebcee test: clean up Docker test-state leftovers 2026-04-28 19:50:51 +01:00
Peter Steinberger
d22a851253 test: reuse Docker test-state in core E2E lanes 2026-04-28 19:47:11 +01:00