@mastra/discord 1.2.1 → 1.3.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/dist/index.cjs +14616 -5830
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +89 -18
- package/dist/index.d.ts +89 -18
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +451 -52
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.cts
CHANGED
|
@@ -138,9 +138,9 @@ interface DiscordProviderConfig {
|
|
|
138
138
|
*/
|
|
139
139
|
waitUntil?: WaitUntilFn;
|
|
140
140
|
/**
|
|
141
|
-
* Start the Gateway WebSocket (
|
|
142
|
-
* and reactions in addition to slash
|
|
143
|
-
*
|
|
141
|
+
* Start the Gateway WebSocket (provider-owned reconnect loop with backoff)
|
|
142
|
+
* so the bot receives DMs, @mentions, and reactions in addition to slash
|
|
143
|
+
* commands. Set `false` for interactions-only serverless deployments.
|
|
144
144
|
*
|
|
145
145
|
* @default true
|
|
146
146
|
*/
|
|
@@ -265,6 +265,42 @@ interface DiscordInstallation {
|
|
|
265
265
|
commandVersions?: Record<string, string>;
|
|
266
266
|
/** When the installation was created. */
|
|
267
267
|
installedAt: Date;
|
|
268
|
+
/**
|
|
269
|
+
* The bot's guild ids at the moment a pending invite was issued. Lets
|
|
270
|
+
* {@link DiscordProvider.reconcileInstallation} confirm the install after the
|
|
271
|
+
* operator completes the invite in another tab: exactly one guild appearing
|
|
272
|
+
* since the snapshot is the authorized guild, so the install activates
|
|
273
|
+
* without waiting for a first interaction. `undefined` when the snapshot
|
|
274
|
+
* couldn't be taken (or the bot is in too many guilds to page) — the install
|
|
275
|
+
* then activates only via the first interaction, as before. Cleared on
|
|
276
|
+
* activation.
|
|
277
|
+
*/
|
|
278
|
+
guildSnapshot?: string[];
|
|
279
|
+
/**
|
|
280
|
+
* When the invite flow that owns {@link guildSnapshot} was last (re)started.
|
|
281
|
+
* The snapshot is only trusted for a bounded claim window after this moment
|
|
282
|
+
* (see `SNAPSHOT_TTL_MS` in `reconcile.ts`) — an abandoned Connect click must
|
|
283
|
+
* not claim a guild the bot joins days later. Set on every invite-flow
|
|
284
|
+
* `connect()`, including when the fetch that should have produced
|
|
285
|
+
* {@link guildSnapshot} failed. Cleared on activation.
|
|
286
|
+
*/
|
|
287
|
+
snapshotAt?: Date;
|
|
288
|
+
/**
|
|
289
|
+
* The Discord application {@link guildSnapshot} was taken against. A baseline
|
|
290
|
+
* from app A says nothing about app B's membership — after `configure()`
|
|
291
|
+
* swaps the bot token, every guild B was already in would look newly
|
|
292
|
+
* authorized. Reconciliation and snapshot reuse require it to match the
|
|
293
|
+
* current app. Cleared on activation.
|
|
294
|
+
*/
|
|
295
|
+
snapshotApplicationId?: string;
|
|
296
|
+
/**
|
|
297
|
+
* The guild `connect()` explicitly targeted (`options.guildId`) when the
|
|
298
|
+
* pending invite was issued, if any. Reconciliation only auto-activates this
|
|
299
|
+
* install on that guild — a different guild appearing in the bot's
|
|
300
|
+
* membership contradicts the caller's intent and waits for an authoritative
|
|
301
|
+
* first interaction instead. Cleared on activation.
|
|
302
|
+
*/
|
|
303
|
+
targetGuildId?: string;
|
|
268
304
|
}
|
|
269
305
|
//#endregion
|
|
270
306
|
//#region src/discord-provider.d.ts
|
|
@@ -272,8 +308,10 @@ interface DiscordInstallation {
|
|
|
272
308
|
* Resolve the per-adapter config the provider applies to the Discord entry in
|
|
273
309
|
* `AgentChannels.adapters`. Discord has native embeds + action-row buttons, so
|
|
274
310
|
* `toolDisplay` defaults to `'cards'` (unlike Telegram's `'text'`); `streaming`
|
|
275
|
-
* post-and-edits the interaction followup; `gateway` (default `true`) makes
|
|
276
|
-
*
|
|
311
|
+
* post-and-edits the interaction followup; `gateway` (default `true`) makes the
|
|
312
|
+
* **provider** run the DM/mention Gateway reconnection loop. (The adapter entry
|
|
313
|
+
* handed to `AgentChannels` always carries `gateway: false` — core's loop must
|
|
314
|
+
* never start; see `#createAgentChannels`.)
|
|
277
315
|
*/
|
|
278
316
|
declare function resolveDiscordAdapterConfig(config: Pick<DiscordProviderConfig, 'streaming' | 'typingStatus' | 'toolDisplay' | 'gateway'>): {
|
|
279
317
|
streaming: StreamingConfig;
|
|
@@ -295,11 +333,15 @@ declare function resolveDiscordAdapterConfig(config: Pick<DiscordProviderConfig,
|
|
|
295
333
|
* member) or lazily off the first inbound interaction's authoritative `guild_id`
|
|
296
334
|
* (see {@link activateGuild}).
|
|
297
335
|
*
|
|
298
|
-
* **Gateway is
|
|
299
|
-
* HTTP Interactions (PING, slash commands, buttons). DMs / @mentions /
|
|
300
|
-
* arrive over the Gateway WebSocket, whose reconnection loop
|
|
301
|
-
*
|
|
302
|
-
*
|
|
336
|
+
* **Gateway is the provider's job.** The mounted interactions route only ever
|
|
337
|
+
* receives HTTP Interactions (PING, slash commands, buttons). DMs / @mentions /
|
|
338
|
+
* reactions arrive over the Gateway WebSocket, whose reconnection loop the
|
|
339
|
+
* provider owns ({@link #startGatewayLoop} → `./gateway-loop`): one abortable
|
|
340
|
+
* loop per installation, exponential backoff on failed connects, parked on a
|
|
341
|
+
* revoked token. Core's `AgentChannels` loop is explicitly disabled
|
|
342
|
+
* (`gateway: false` on the adapter entry) — it reconnects with no backoff and
|
|
343
|
+
* cannot be stopped, which is how a failing IDENTIFY once tripped Discord's
|
|
344
|
+
* 1000-connect abuse limit and got the bot token force-reset.
|
|
303
345
|
*
|
|
304
346
|
* Implemented (issues `mastra-discord-13x.2` + `.3`): the app-config +
|
|
305
347
|
* guild-keyed install store, `connect()`/`disconnect()`, OAuth2 invite-URL
|
|
@@ -363,17 +405,46 @@ declare class DiscordProvider implements ChannelProvider {
|
|
|
363
405
|
*/
|
|
364
406
|
activateGuild(webhookId: string, guildId: string): Promise<DiscordInstallation | null>;
|
|
365
407
|
/**
|
|
366
|
-
* Disconnect an agent from Discord:
|
|
367
|
-
* adapter entry.
|
|
368
|
-
*
|
|
369
|
-
* **Limitation:** the Gateway loop is owned by core (it calls
|
|
370
|
-
* `startGatewayListener` itself; there is no `stopGatewayListener`), so
|
|
371
|
-
* disconnect cannot kill an in-flight gateway window — it lapses at the next
|
|
372
|
-
* duration boundary. Contrast Telegram's clean `stopPolling()`.
|
|
408
|
+
* Disconnect an agent from Discord: abort its Gateway loop, remove its
|
|
409
|
+
* installation row, and drop the adapter entry.
|
|
373
410
|
*/
|
|
374
411
|
disconnect(agentId: string): Promise<void>;
|
|
375
|
-
/**
|
|
412
|
+
/**
|
|
413
|
+
* List installations (public info only — no secrets). A pure read: pending
|
|
414
|
+
* installs are confirmed through the write-authorized
|
|
415
|
+
* {@link reconcileInstallation} path, never as a listing side effect.
|
|
416
|
+
*/
|
|
376
417
|
listInstallations(): Promise<ChannelInstallationInfo[]>;
|
|
418
|
+
/**
|
|
419
|
+
* Activate an agent's pending install if its invite has since been completed.
|
|
420
|
+
*
|
|
421
|
+
* The invite URL carries no `redirect_uri` (the app would have to allowlist
|
|
422
|
+
* every operator origin), so nothing calls back when the operator authorizes
|
|
423
|
+
* the bot — and a pending install has no adapter, so no interaction or
|
|
424
|
+
* gateway event can reach it either. Instead, each pending install carries a
|
|
425
|
+
* {@link DiscordInstallation.guildSnapshot} taken when the invite was issued;
|
|
426
|
+
* this diffs it against the bot's current membership and activates the
|
|
427
|
+
* install when exactly one new, uncontested guild has appeared (the full
|
|
428
|
+
* claim rules live in {@link planReconcile}). The claim analysis spans every
|
|
429
|
+
* install — other pending invites contest the diff — but only **this**
|
|
430
|
+
* agent's install can activate: the caller holds write access for this agent
|
|
431
|
+
* alone. Anything ambiguous stays pending and retries on the next call, with
|
|
432
|
+
* the first interaction as the authoritative fallback. Best-effort: failures
|
|
433
|
+
* log and resolve rather than throw.
|
|
434
|
+
*
|
|
435
|
+
* Called by the server's reconcile route (write-authorized); Studio invokes
|
|
436
|
+
* it on window focus while a connect is in flight. Returns the (possibly
|
|
437
|
+
* just-activated) installation's public info, or `null` when the agent has
|
|
438
|
+
* no installation.
|
|
439
|
+
*
|
|
440
|
+
* Limitation: the bot-invite URL is per-app, not per-install, so when the
|
|
441
|
+
* operator invites the bot to a new server *for an already-active install*
|
|
442
|
+
* (as `connect()`'s already-connected error suggests) while an invite for
|
|
443
|
+
* another agent is outstanding, nothing distinguishes the two intents — the
|
|
444
|
+
* new guild can be attributed to the pending install. Reconciliation is only
|
|
445
|
+
* reliable while a single invite flow is in progress.
|
|
446
|
+
*/
|
|
447
|
+
reconcileInstallation(agentId: string): Promise<ChannelInstallationInfo | null>;
|
|
377
448
|
/** The full installation for an agent (no secrets live on it), or `null`. */
|
|
378
449
|
getInstallation(agentId: string): Promise<DiscordInstallation | null>;
|
|
379
450
|
/** Whether the Discord app is configured (credentials resolvable). */
|
package/dist/index.d.ts
CHANGED
|
@@ -138,9 +138,9 @@ interface DiscordProviderConfig {
|
|
|
138
138
|
*/
|
|
139
139
|
waitUntil?: WaitUntilFn;
|
|
140
140
|
/**
|
|
141
|
-
* Start the Gateway WebSocket (
|
|
142
|
-
* and reactions in addition to slash
|
|
143
|
-
*
|
|
141
|
+
* Start the Gateway WebSocket (provider-owned reconnect loop with backoff)
|
|
142
|
+
* so the bot receives DMs, @mentions, and reactions in addition to slash
|
|
143
|
+
* commands. Set `false` for interactions-only serverless deployments.
|
|
144
144
|
*
|
|
145
145
|
* @default true
|
|
146
146
|
*/
|
|
@@ -265,6 +265,42 @@ interface DiscordInstallation {
|
|
|
265
265
|
commandVersions?: Record<string, string>;
|
|
266
266
|
/** When the installation was created. */
|
|
267
267
|
installedAt: Date;
|
|
268
|
+
/**
|
|
269
|
+
* The bot's guild ids at the moment a pending invite was issued. Lets
|
|
270
|
+
* {@link DiscordProvider.reconcileInstallation} confirm the install after the
|
|
271
|
+
* operator completes the invite in another tab: exactly one guild appearing
|
|
272
|
+
* since the snapshot is the authorized guild, so the install activates
|
|
273
|
+
* without waiting for a first interaction. `undefined` when the snapshot
|
|
274
|
+
* couldn't be taken (or the bot is in too many guilds to page) — the install
|
|
275
|
+
* then activates only via the first interaction, as before. Cleared on
|
|
276
|
+
* activation.
|
|
277
|
+
*/
|
|
278
|
+
guildSnapshot?: string[];
|
|
279
|
+
/**
|
|
280
|
+
* When the invite flow that owns {@link guildSnapshot} was last (re)started.
|
|
281
|
+
* The snapshot is only trusted for a bounded claim window after this moment
|
|
282
|
+
* (see `SNAPSHOT_TTL_MS` in `reconcile.ts`) — an abandoned Connect click must
|
|
283
|
+
* not claim a guild the bot joins days later. Set on every invite-flow
|
|
284
|
+
* `connect()`, including when the fetch that should have produced
|
|
285
|
+
* {@link guildSnapshot} failed. Cleared on activation.
|
|
286
|
+
*/
|
|
287
|
+
snapshotAt?: Date;
|
|
288
|
+
/**
|
|
289
|
+
* The Discord application {@link guildSnapshot} was taken against. A baseline
|
|
290
|
+
* from app A says nothing about app B's membership — after `configure()`
|
|
291
|
+
* swaps the bot token, every guild B was already in would look newly
|
|
292
|
+
* authorized. Reconciliation and snapshot reuse require it to match the
|
|
293
|
+
* current app. Cleared on activation.
|
|
294
|
+
*/
|
|
295
|
+
snapshotApplicationId?: string;
|
|
296
|
+
/**
|
|
297
|
+
* The guild `connect()` explicitly targeted (`options.guildId`) when the
|
|
298
|
+
* pending invite was issued, if any. Reconciliation only auto-activates this
|
|
299
|
+
* install on that guild — a different guild appearing in the bot's
|
|
300
|
+
* membership contradicts the caller's intent and waits for an authoritative
|
|
301
|
+
* first interaction instead. Cleared on activation.
|
|
302
|
+
*/
|
|
303
|
+
targetGuildId?: string;
|
|
268
304
|
}
|
|
269
305
|
//#endregion
|
|
270
306
|
//#region src/discord-provider.d.ts
|
|
@@ -272,8 +308,10 @@ interface DiscordInstallation {
|
|
|
272
308
|
* Resolve the per-adapter config the provider applies to the Discord entry in
|
|
273
309
|
* `AgentChannels.adapters`. Discord has native embeds + action-row buttons, so
|
|
274
310
|
* `toolDisplay` defaults to `'cards'` (unlike Telegram's `'text'`); `streaming`
|
|
275
|
-
* post-and-edits the interaction followup; `gateway` (default `true`) makes
|
|
276
|
-
*
|
|
311
|
+
* post-and-edits the interaction followup; `gateway` (default `true`) makes the
|
|
312
|
+
* **provider** run the DM/mention Gateway reconnection loop. (The adapter entry
|
|
313
|
+
* handed to `AgentChannels` always carries `gateway: false` — core's loop must
|
|
314
|
+
* never start; see `#createAgentChannels`.)
|
|
277
315
|
*/
|
|
278
316
|
declare function resolveDiscordAdapterConfig(config: Pick<DiscordProviderConfig, 'streaming' | 'typingStatus' | 'toolDisplay' | 'gateway'>): {
|
|
279
317
|
streaming: StreamingConfig;
|
|
@@ -295,11 +333,15 @@ declare function resolveDiscordAdapterConfig(config: Pick<DiscordProviderConfig,
|
|
|
295
333
|
* member) or lazily off the first inbound interaction's authoritative `guild_id`
|
|
296
334
|
* (see {@link activateGuild}).
|
|
297
335
|
*
|
|
298
|
-
* **Gateway is
|
|
299
|
-
* HTTP Interactions (PING, slash commands, buttons). DMs / @mentions /
|
|
300
|
-
* arrive over the Gateway WebSocket, whose reconnection loop
|
|
301
|
-
*
|
|
302
|
-
*
|
|
336
|
+
* **Gateway is the provider's job.** The mounted interactions route only ever
|
|
337
|
+
* receives HTTP Interactions (PING, slash commands, buttons). DMs / @mentions /
|
|
338
|
+
* reactions arrive over the Gateway WebSocket, whose reconnection loop the
|
|
339
|
+
* provider owns ({@link #startGatewayLoop} → `./gateway-loop`): one abortable
|
|
340
|
+
* loop per installation, exponential backoff on failed connects, parked on a
|
|
341
|
+
* revoked token. Core's `AgentChannels` loop is explicitly disabled
|
|
342
|
+
* (`gateway: false` on the adapter entry) — it reconnects with no backoff and
|
|
343
|
+
* cannot be stopped, which is how a failing IDENTIFY once tripped Discord's
|
|
344
|
+
* 1000-connect abuse limit and got the bot token force-reset.
|
|
303
345
|
*
|
|
304
346
|
* Implemented (issues `mastra-discord-13x.2` + `.3`): the app-config +
|
|
305
347
|
* guild-keyed install store, `connect()`/`disconnect()`, OAuth2 invite-URL
|
|
@@ -363,17 +405,46 @@ declare class DiscordProvider implements ChannelProvider {
|
|
|
363
405
|
*/
|
|
364
406
|
activateGuild(webhookId: string, guildId: string): Promise<DiscordInstallation | null>;
|
|
365
407
|
/**
|
|
366
|
-
* Disconnect an agent from Discord:
|
|
367
|
-
* adapter entry.
|
|
368
|
-
*
|
|
369
|
-
* **Limitation:** the Gateway loop is owned by core (it calls
|
|
370
|
-
* `startGatewayListener` itself; there is no `stopGatewayListener`), so
|
|
371
|
-
* disconnect cannot kill an in-flight gateway window — it lapses at the next
|
|
372
|
-
* duration boundary. Contrast Telegram's clean `stopPolling()`.
|
|
408
|
+
* Disconnect an agent from Discord: abort its Gateway loop, remove its
|
|
409
|
+
* installation row, and drop the adapter entry.
|
|
373
410
|
*/
|
|
374
411
|
disconnect(agentId: string): Promise<void>;
|
|
375
|
-
/**
|
|
412
|
+
/**
|
|
413
|
+
* List installations (public info only — no secrets). A pure read: pending
|
|
414
|
+
* installs are confirmed through the write-authorized
|
|
415
|
+
* {@link reconcileInstallation} path, never as a listing side effect.
|
|
416
|
+
*/
|
|
376
417
|
listInstallations(): Promise<ChannelInstallationInfo[]>;
|
|
418
|
+
/**
|
|
419
|
+
* Activate an agent's pending install if its invite has since been completed.
|
|
420
|
+
*
|
|
421
|
+
* The invite URL carries no `redirect_uri` (the app would have to allowlist
|
|
422
|
+
* every operator origin), so nothing calls back when the operator authorizes
|
|
423
|
+
* the bot — and a pending install has no adapter, so no interaction or
|
|
424
|
+
* gateway event can reach it either. Instead, each pending install carries a
|
|
425
|
+
* {@link DiscordInstallation.guildSnapshot} taken when the invite was issued;
|
|
426
|
+
* this diffs it against the bot's current membership and activates the
|
|
427
|
+
* install when exactly one new, uncontested guild has appeared (the full
|
|
428
|
+
* claim rules live in {@link planReconcile}). The claim analysis spans every
|
|
429
|
+
* install — other pending invites contest the diff — but only **this**
|
|
430
|
+
* agent's install can activate: the caller holds write access for this agent
|
|
431
|
+
* alone. Anything ambiguous stays pending and retries on the next call, with
|
|
432
|
+
* the first interaction as the authoritative fallback. Best-effort: failures
|
|
433
|
+
* log and resolve rather than throw.
|
|
434
|
+
*
|
|
435
|
+
* Called by the server's reconcile route (write-authorized); Studio invokes
|
|
436
|
+
* it on window focus while a connect is in flight. Returns the (possibly
|
|
437
|
+
* just-activated) installation's public info, or `null` when the agent has
|
|
438
|
+
* no installation.
|
|
439
|
+
*
|
|
440
|
+
* Limitation: the bot-invite URL is per-app, not per-install, so when the
|
|
441
|
+
* operator invites the bot to a new server *for an already-active install*
|
|
442
|
+
* (as `connect()`'s already-connected error suggests) while an invite for
|
|
443
|
+
* another agent is outstanding, nothing distinguishes the two intents — the
|
|
444
|
+
* new guild can be attributed to the pending install. Reconciliation is only
|
|
445
|
+
* reliable while a single invite flow is in progress.
|
|
446
|
+
*/
|
|
447
|
+
reconcileInstallation(agentId: string): Promise<ChannelInstallationInfo | null>;
|
|
377
448
|
/** The full installation for an agent (no secrets live on it), or `null`. */
|
|
378
449
|
getInstallation(agentId: string): Promise<DiscordInstallation | null>;
|
|
379
450
|
/** Whether the Discord app is configured (credentials resolvable). */
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/discord-provider.ts","../src/install-store.ts","../src/discord-client.ts","../src/commands.ts","../src/crypto.ts"],"mappings":";;;;;;;;;;;;cAgBa;;cAGA;;;;;;;;cASA;WACX;WACA;WACA;WACA;WACA;WACA;WACA;WACA;;;;;;;;;cAUW;;cAWA;;;;;;UAOI;;EAEf;;EAEA;;;KAIU;EAAiC;EAAc;;;;;;;;UAQ1C;;EAEf;;EAEA;;EAEA;;;;;;;;;;UAWe;;;;;;;;;EASf,MAAM,QAAQ;;;;;EAKd;;;;;;EAMA,UAAU;;;;;EAKV;;;;;;;EAOA;;;;;EAKA;;;;;;EAMA,WAAW;;;;;;;;;;EAUX;;;;;EAKA,YAAY;;;;;;;;EAQZ;;;;;EAKA;;;;;;EAMA,mBAAmB;;EAEnB,SAAS;;;;;;;;EAQT,YAAY;;;;;;EAMZ;;EASA,WAAW;;EAEX,cAAc;;EAEd,cAAc;;EAEd,QAAQ;;EAER,gBAAgB;;EAEhB,cAAc;;EAEd,oBAAoB;;EAEpB,mBAAmB;;EAEnB,OAAO;;EAEP,cAAc;;;;;;;;EAQd,cAAc;;;;;;;EAOd,QAAQ;;EAER,aAAa,cAAc,+BAA+B;;;UAI3C;;;;;;;EAOf;;EAEA;;;;;EAKA,WAAW;;EAEX;;;;;;;;;UAUe;;EAEf;;EAEA;;;;;EAKA;;;;;EAKA;;EAEA;;EAEA;;EAEA,WAAW;;;;;;EAMX,kBAAkB;;EAElB,aAAa;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/discord-provider.ts","../src/install-store.ts","../src/discord-client.ts","../src/commands.ts","../src/crypto.ts"],"mappings":"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"}
|