* fix(thread-ownership): bound 409 response read and preserve cancel semantics
The thread-ownership 409 conflict path still used unbounded resp.json(),
inconsistent with the bounded readers shipped across the other channel/provider
success paths. A compromised or buggy forwarder returning a multi-GB 409 body
would buffer the entire body before JSON.parse, OOMing the agent.
Bound the 409 body via readResponseTextLimited (8 KiB cap; a 409 owner field is
~30 bytes). Wrap the parse in try/catch so a truncated or malformed 409 body
still cancels the send (owner logged as "unknown") — the 409 status itself
means another agent owns this thread, independent of body parseability.
The discord webhook and huggingface /v1/models success reads from the original
PR were superseded upstream by #98098 and #101079 (readProviderJsonResponse),
so this branch now carries only the thread-ownership fix.
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(thread-ownership): bound forwarder conflict handling
---------
Co-authored-by: Claude <noreply@anthropic.com>
* feat(gateway): make chat history max chars configurable
* fix(gateway): address review feedback
* docs(changelog): note configurable chat history limits
* fix(extensions): route fetch calls through fetchWithSsrFGuard
Replace raw fetch() with fetchWithSsrFGuard in BlueBubbles, Mattermost,
Nextcloud Talk, and Thread Ownership extensions so outbound requests go
through the shared DNS-pinning and network-policy layer.
BlueBubbles: thread allowPrivateNetwork from account config through all
fetch call sites (send, chat, reactions, history, probe, attachments,
multipart). Add _setFetchGuardForTesting hook for test overrides.
Mattermost: add guardedFetchImpl wrapper in createMattermostClient that
buffers the response body before releasing the dispatcher. Handle
null-body status codes (204/304).
Nextcloud Talk: wrap both sendMessage and sendReaction with
fetchWithSsrFGuard and try/finally release.
Thread Ownership: add fetchWithSsrFGuard and ssrfPolicyFromAllowPrivateNetwork
to the plugin SDK surface; use allowPrivateNetwork:true for the
Docker-internal forwarder.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(extensions): improve null-body handling and test harness cleanup
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(bluebubbles): default to strict SSRF policy when allowPrivateNetwork is unset
Callers that omit allowPrivateNetwork previously got undefined policy,
which caused blueBubblesFetchWithTimeout to fall through to raw fetch
and bypass the SSRF guard entirely.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(bluebubbles): thread allowPrivateNetwork through action and monitor call sites
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(mattermost,nextcloud-talk): add allowPrivateNetwork config for self-hosted/LAN deployments
* fix: regenerate config docs baseline for new allowPrivateNetwork fields
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>