Commit Graph

2260 Commits

Author SHA1 Message Date
chelsealong 9a8755f6e3 fix(discord): resolve default account for presence actions (#127748)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-08-25 11:24:44 -07:00
Peter Steinberger 4fd42aa037 refactor(discord): unify reaction client resolution (#129441) 2026-08-25 09:37:20 -07:00
Peter Steinberger 712a97d2ab fix(discord): prevent accidental mentions inside unfinished code (#129338)
* fix(discord): protect mentions inside unfinished inline code

* fix(discord): respect escaped inline-code delimiters
2026-08-25 07:11:28 -07:00
Peter Steinberger 05a3b2ac82 fix(discord): honor explicit names for new forum posts (#129294) 2026-08-25 05:01:26 -07:00
Peter Steinberger 4dc7bb7411 chore(deps): refresh dependencies after seven-day cooldown (#129187)
* chore(deps): refresh dependencies after cooldown

* fix(gateway): emit append-only Responses content events

* chore(deps): retain unverified Sherpa runtime
2026-08-25 05:00:46 -07:00
Peter Steinberger 0dc639f59e refactor(discord): unify approval lifecycle rendering (#129246)
* refactor(discord): unify approval lifecycle rendering

* test(discord): narrow serialized approval container payload
2026-08-25 04:18:52 -07:00
Peter Steinberger c5d1cb38e2 fix(channels): attachment filenames disappear from model context (#129140)
* fix(channels): preserve inbound attachment filenames

Fixes #128956

* test(discord): verify names on successfully downloaded media

* test(discord): verify referenced attachment filenames

* fix(telegram): preserve accepted resolved-media shapes
2026-08-25 02:15:34 -07:00
Peter Steinberger d99ed2ac5b fix(discord): preserve per-button reusable settings (#129068) 2026-08-25 01:23:20 -07:00
Peter Steinberger 38f3e13466 fix(discord): retain video caption delivery receipts (#129134) 2026-08-25 01:21:55 -07:00
Peter Steinberger 0a79ae5fd0 refactor(discord): reuse canonical interactive component renderer (#129031) 2026-08-24 23:30:25 -07:00
Peter Steinberger 9a15d4cbf9 fix(discord): keep forum attachments and receipts in their first thread (#128765)
* fix(discord): keep structured forum attachments in one thread

* test(discord): type forum delivery fixture sender
2026-08-24 13:17:06 -07:00
ClawSweeper 29f39affc2 fix(agents): resolve terminal from admitted gateway (#128348)
Co-authored-by: RoboClaw <309084314+roboclaw-bot@users.noreply.github.com>
Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
2026-08-24 12:46:14 -04:00
Peter Steinberger a9fdb68496 fix(discord): preserve distinct super reaction events (#128649) 2026-08-24 03:17:10 -07:00
Peter Steinberger 234df15a6d chore: refresh dependencies after seven-day cooldown (#128414)
* build(deps): refresh dependencies after cooldown

Apply dependency, toolchain, action, image, and exact tool updates released by the inclusive 2026-08-16 seven-day cutoff. Adapt owner boundaries for the resulting CUA, logging, Teams, Markdown, native, and test-harness contract changes while retaining versions blocked by upstream compatibility constraints.

* fix(ui): align markdown renderer env typing

* fix(deps): align postcss and mistral peer contracts

* fix(deps): repair refreshed dependency contracts

* fix(deps): retain tslog startup budget

* fix(ci): verify Android tools with SHA-256

* fix(ci): fence Android SDK cache version
2026-08-24 03:01:54 -07:00
Peter Steinberger 23df5799fd fix(discord): classify announcement threads consistently (#128568)
* refactor(discord): deduplicate thread channel classification

* fix(discord): classify announcement threads during channel resolution
2026-08-24 01:02:16 -07:00
Peter Steinberger 65bcdf2f26 fix(discord): report actual delivered message kinds (#128575) 2026-08-24 00:05:07 -07:00
Peter Steinberger b136df2307 feat(channels): matrix custom emote discovery, discord guild-emoji cache (#128518)
Matrix gains emoji-list backed by MSC2545 image packs: room state
im.ponies.room_emotes (any state key) plus the personal
im.ponies.user_emotes account-data pack, sticker-only entries excluded,
identifiers are literal shortcodes (Matrix reactions send the annotation
key as-is; the mxc URL is exposed alongside). Discord emoji-list results
now ride the lifecycle-owned bounded entity cache, invalidated by
GuildEmojisUpdate; the non-privileged GuildExpressions intent is added so
that dispatch actually arrives. Google Chat custom-emoji listing is
documented as unavailable: customEmojis.list requires user auth while the
plugin is a chat.bot service-account channel.
2026-08-23 23:00:22 -07:00
Peter Steinberger 2aa5eee34e feat(channels): custom emoji discovery via emoji-list across Discord, Slack, Telegram (#128435)
* feat(channels): custom emoji discovery via emoji-list across Discord, Slack, Telegram

Make custom emojis discoverable by the agent. The message tool's emoji
param now documents custom-emoji syntax per channel (gate-aware, only
naming emoji-list when the action is actually advertised). Discord
emoji-list defaults guildId from the current conversation and returns
reaction-ready { name, identifier, animated? } entries; Slack returns
normalized shortcodes with aliasOf. Telegram gains emoji-list backed by
one canonical allowed-reactions owner (getChat available_reactions,
custom_emoji entries preserved), numeric custom-emoji reactions, and
replaces the dead 'reaction disallow list' error advice with a bounded
sample of the chat's allowed reactions.

* test(channels): expect telegram emoji-list provider-owned read gate in plugin shape contract

* test(telegram): prove emoji-list authority chain via mock-gateway e2e

Ephemeral gateway + mock Bot API + mock OpenAI provider: current-chat
emoji-list returns normalized standard and custom_emoji identifiers with
exactly one getChat call; a delegated cross-chat request is rejected with
the conversation-binding error and zero Bot API requests reference the
foreign chat.
2026-08-23 20:39:06 -07:00
Peter Steinberger cd10b65257 fix(discord): revalidate delivery authority per send (#128357)
* fix(discord): fence media caption follow-ups

* fix(discord): revalidate delivery custody per post

* test(discord): prove delivery fence over HTTP

Amp-Thread-ID: https://ampcode.com/threads/T-01a021f4-b547-7788-a916-d4a94cbd3e3b

* fix(discord): fence each retry attempt

Amp-Thread-ID: https://ampcode.com/threads/T-01a021f4-b547-7788-a916-d4a94cbd3e3b

* fix(discord): fence remaining retry paths

Amp-Thread-ID: https://ampcode.com/threads/T-01a021f4-b547-7788-a916-d4a94cbd3e3b

---------

Co-authored-by: Amp <amp@ampcode.com>
2026-08-23 20:05:29 -07:00
Peter Steinberger 267f1ad917 perf(discord): reuse prepared outbound account (#128462)
Co-authored-by: Amp <amp@ampcode.com>
2026-08-23 19:52:19 -07:00
Peter Steinberger 3aab15c077 fix(discord): honor explicit component attachment filenames (#128401) 2026-08-23 17:56:50 -07:00
Peter Steinberger 7864980d9e fix(discord): expire stale thread starter cache entries (#128404) 2026-08-23 16:42:25 -07:00
Peter Steinberger 4d00dc4fca fix(outbound): retain attachments when plural media URLs are blank (#128372) 2026-08-23 14:35:39 -07:00
Peter Steinberger 663a9d2f15 fix(discord): recover question feedback after failed acknowledgements (#128293) 2026-08-23 10:51:12 -07:00
Peter Steinberger 3d75c27103 perf(discord): avoid duplicate inbound binding lookup (#128264)
Amp-Thread-ID: https://ampcode.com/threads/T-01a021f5-984a-7628-a30c-491c166ff247

Co-authored-by: Amp <amp@ampcode.com>
2026-08-23 09:13:04 -07:00
xingzhou 056d6a1da6 fix(discord): surface failed voice notes after text fallback (#127876)
* fix(discord): surface failed voice notes after text fallback

* fix(discord): preserve voice failure after attachment errors
2026-08-23 05:10:43 -07:00
Peter Steinberger 1475b67111 fix(discord): deliver embed-only and component-only messages (#128152) 2026-08-23 05:01:17 -07:00
sunlit-deng 1e9d493be9 fix(discord): preserve MIME extension for component uploads (#119671) 2026-08-23 04:55:20 -07:00
Masato Hoshino 6c37eb01d9 fix(discord): malformed gateway HELLO frame kills the bot's socket listener (#121468)
* fix(discord): survive malformed gateway HELLO frames

The HELLO branch dereferenced payload.d through a bare cast and replaced
only null/undefined with the 45s default, so a { op: 10, d: null } frame
threw a TypeError out of the socket message listener (no try/catch), and
a zero, negative, sub-second, or out-of-range interval reached setTimeout
unchanged, scheduling the first heartbeat immediately.

Normalize the HELLO body with the canonical record guard and accept the
interval only inside the timer-safe range, matching the QQ gateway. The
cast is removed rather than guarded.

* fix(discord): honor any heartbeat interval the gateway can schedule

Review of the first revision pointed out that the 1000 ms lower bound was
an interoperability break: a compatible gateway negotiating, say, 500 ms
would have had its interval replaced by the 45s default and then been
disconnected as unresponsive. Discord documents no lower bound.

Drop the bound to a positive timer-safe integer, so shape validation and
the timer ceiling stay while every interval this client can actually
schedule is honored. Regression rows pin 500 ms and 1 ms.
2026-08-23 04:14:15 -07:00
Sebastian B Otaegui b9b6ca46c3 fix(discord): upload-file with a base64 buffer fails without pointing at send (#123748)
* fix(discord): reject upload-file buffer attachments with send guidance

The flat message tool schema advertises buffer for every action, so
callers reasonably infer upload-file + buffer is valid on Discord. The
Discord handler only reads filePath/path/media for upload-file and
failed with an error that never mentioned the supported path.

Scope the buffer schema description to action="send" and make Discord
upload-file reject a buffer-only call with guidance to use send instead
of duplicating the send buffer pipeline under a second action.

* review: keep the shared buffer description channel-neutral

iMessage's upload-file deliberately consumes a buffer, so scoping the
shared schema text to send would teach models away from a supported
path. Keep the guidance owner-local: Discord's rejection carries it.
2026-08-23 02:32:11 -07:00
Yiğit ERDOĞAN 60136ec1a2 fix(discord): upload-file silently drops a caption (#124255)
* fix(discord,msteams): upload-file silently drops a caption

Both channels accept `media` as an alias for the uploaded file, so a
send-shaped call reaches `upload-file` carrying its text in `caption`.
Discord read only `message`/`content` and MS Teams read only
`text`/`content`/`message`, so that text was dropped and the file landed
with no message at all.

Accept `caption` as the lowest-precedence alias on both channels, matching
the WhatsApp and Slack upload paths. An explicitly empty higher-precedence
value still wins, so existing callers keep their behavior. The MS Teams
reader is scoped to `upload-file` because the other actions carry their own
text field.

* refactor: narrow this PR to the Discord channel

Microsoft Teams keeps the same defect and the same fix shape, but a Teams
after-fix delivery or activity trace is not reachable without a live tenant,
so that half is deferred to its own change rather than blocking the Discord
repair that already has a production-boundary trace.
2026-08-23 00:01:04 -07:00
Vito Cappello 5ddf381eed fix(channels): preserve gateway context for inbound turns (#127962)
* fix(channels): preserve gateway context for inbound turns

* fix(plugin-sdk): type bound channel reply dispatcher

* fix(channels): carry bound reply dispatchers

* fix(channels): keep reply carrier internal

* fix(auto-reply): consolidate dispatcher type imports

* fix(channels): keep reply dispatch typing internal

* fix(channels): derive inbound reply dispatcher types from turn plan

Keep ChannelRuntimeSurface identical to main: adapters read the bound
dispatchReplyFromConfig through the existing PluginRuntime["channel"]
wiring type and derive its type from the public ChannelInboundTurnPlan
contract, so the compatibility surface no longer grows a Gateway-bound
reply member.

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

* fix(channels): hoist bound channel runtime casts for assertion ratchet

The assertion-safety ratchet collects SAFETY comments with a plain
ts.Scanner pass, which desyncs at the first template literal with a
substitution — comments after that point in a file are invisible, so
deep casts in monitor files cannot be SAFETY-covered. Hoist one shared
cast per call-site scope (absorbing the pre-existing buildContext
casts) and retype Discord's internal channelRuntime chain as
PluginRuntime["channel"] so dispatch reads need no assertion.

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

* test(channels): verify gateway dispatcher ownership

Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>

* test(codex): assert sequenced node process notifications

Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>

* docs(changelog): preserve release-owned root changelog

Channel Gateway tools preserve the owning dispatcher for Telegram, Discord, iMessage, Signal, and WhatsApp so terminal tools remain available. Thanks @VACInc.

Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>

* test(codex): avoid shadowing process notification bindings

Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>

---------

Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-08-22 13:44:47 -07:00
Peter Lee 97fe326660 fix(discord): treat audio transcripts as untrusted input (#123098)
Centralize untrusted audio transcript framing across channel plugins and keep Discord voice transcripts out of typed command provenance.

Co-authored-by: xialonglee <li.xialong@xydigit.com>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-22 14:28:18 +05:30
Peter Steinberger 3376c29800 perf(discord): avoid redundant payload cleaning (#127422)
Co-authored-by: Amp <amp@ampcode.com>
2026-08-21 12:42:14 -07:00
Josh Avant 0b85966072 fix gateway conversation route ownership (#126424) 2026-08-21 12:20:21 -07:00
Peter Steinberger 782a7d7aed refactor(discord): remove obsolete action runtime wrapper (#127123) 2026-08-21 02:07:48 -07:00
Peter Steinberger fd3a919063 fix(media): clean failed temporary staging (#127092) 2026-08-21 01:02:27 -07:00
Peter Steinberger 07c8b42a71 fix(channels): preserve delivery after preview cleanup (#126922) 2026-08-20 18:18:25 -07:00
Peter Steinberger 319df0e7a1 test: trim plugin test duplicates (#126917) 2026-08-20 18:07:27 -07:00
Peter Steinberger a4178c7eb1 fix(discord): demote expected command truncation logs (#126824) 2026-08-20 13:26:44 -07:00
Peter Steinberger 231405930a fix(discord): record activity after successful poll and sticker sends (#126791)
* fix(discord): record activity for structured outbound messages

* chore(discord): shrink structured-send assertion baseline
2026-08-20 11:56:07 -07:00
Peter Steinberger aafa61be65 fix(discord): preserve message text from every embed (#126752)
* fix(discord): preserve text from every message embed

* chore(discord): shrink assertion baseline after embed cleanup
2026-08-20 10:28:20 -07:00
Peter Steinberger 0961247d94 fix(discord): route polls through canonical delivery (#126250)
* fix(discord): route polls through canonical delivery

* test(discord): align canonical poll action coverage

* test(gateway): isolate canonical poll fallback coverage

* fix(gateway): align canonical poll capability
2026-08-19 18:07:21 -07:00
Peter Steinberger c6ecfd26e5 fix(outbound): preserve first-reply behavior through durable delivery (#126205)
* fix(outbound): preserve reply facts through durable delivery

* fix(protocol): regenerate message action models

* fix(outbound): complete reply fact custody
2026-08-19 17:52:12 -07:00
Peter Steinberger 2fe6c0206d fix(discord): retain attachment-only reply context (#126204) 2026-08-19 15:55:55 -07:00
Steven ff37627804 fix(discord): resolve realtime voice API key references (#125443)
* fix(discord): resolve realtime voice SecretRefs

* fix(discord): isolate realtime voice secret owners

* fix(discord): contain realtime secret owner gate

* fix(build): align plugin SDK boundary paths

* fix(discord): normalize realtime secret owner accounts

* fix(discord): gate canonical realtime secret owners

* style(discord): format realtime voice tests

* test(codex): assign run-attempt tools shard

* fix(discord): skip unavailable realtime providers

* fix(discord): preserve realtime provider availability errors

---------

Co-authored-by: Patrick Erichsen <patrick.a.erichsen@gmail.com>
2026-08-19 15:23:14 -07:00
Peter Steinberger 97557ec3f5 fix(widgets): route show_widget through Discord Activities (#126294)
* refactor(widgets): unify Discord presentation

* fix(discord): keep incomplete Activity routes private

* fix(discord): require usable Activity accounts

* docs(discord): clarify hidden Activity routes
2026-08-19 05:41:37 -07:00
Michael Appel 55f6700fe1 fix(discord): preserve realtime speaker context (#123243) 2026-08-19 04:25:24 -07:00
Peter Steinberger 554dfbe0a2 feat(discord): auto-join occupied voice rooms (#125974)
* feat(discord): auto-join occupied voice rooms

Add opt-in voice.autoJoin[].whenOccupied residency so Discord voice bots join for the first human and leave when the room becomes empty while preserving existing always-on, manual, transcript, and follow-user behavior.\n\nCloses #125973

* test(discord): isolate process runtime mocks

Use stable hoisted runtime-env mocks so isolate=false Discord test ordering cannot turn sleepWithAbort back into an unmocked function.

* fix(discord): defer unknown voice occupancy

Treat memberless voice states as unresolved instead of human so bot-only rooms cannot trigger occupancy-managed auto-join. Add cache-to-listener and manager regressions.\n\nCloses #125973

* test: isolate shared module mocks

Replace ineffective non-isolated module spies with stable hoisted mocks and a child-process SQLite connection-reuse probe so gateway and Discord shards are order-independent.

* test(gateway): inline connection reuse probe

Keep the child-process SQLite ownership probe in its owning Vitest file so Knip sees the full test surface without weakening process isolation or the original order regression.
2026-08-19 00:08:54 -07:00
Peter Steinberger baefd067bb fix(deps): keep package runtime dependencies single-owned (#126119)
* fix(deps): consolidate shared runtime helpers

* test(concurrency): support current test lib target

* fix(time): preserve year-scale plugin durations

* fix(agents): preserve empty subagent completions
2026-08-18 22:12:45 -07:00