fix(tess): route bare Discord approvals
All checks were successful
ci/woodpecker/pr/ci Pipeline was successful

This commit is contained in:
Jarvis
2026-07-13 05:10:48 -05:00
parent 0b621660c8
commit ed1d985c90
2 changed files with 43 additions and 10 deletions

View File

@@ -2,6 +2,7 @@ import { afterEach, describe, expect, it, vi } from 'vitest';
import { InMemoryDurableSessionStore } from '@mosaicstack/agent'; import { InMemoryDurableSessionStore } from '@mosaicstack/agent';
import { import {
createDiscordIngressEnvelope, createDiscordIngressEnvelope,
DiscordPlugin,
type DiscordIngressPayload, type DiscordIngressPayload,
} from '@mosaicstack/discord-plugin'; } from '@mosaicstack/discord-plugin';
import { InteractionController } from '../../agent/interaction.controller.js'; import { InteractionController } from '../../agent/interaction.controller.js';
@@ -30,7 +31,7 @@ function payload(content: string, messageId: string, correlationId: string): Dis
guildId: 'guild-1', guildId: 'guild-1',
channelId: 'channel-1', channelId: 'channel-1',
userId: 'discord-admin-1', userId: 'discord-admin-1',
conversationId: 'conversation-1', conversationId: 'Nova:discord:channel-1',
}; };
} }
@@ -89,7 +90,7 @@ describe('Tess Discord/CLI durable-session integration', () => {
const controller = new InteractionController(enrollmentRuntime as never, durable); const controller = new InteractionController(enrollmentRuntime as never, durable);
await controller.enroll( await controller.enroll(
'Nova', 'Nova',
'conversation-1', 'Nova:discord:channel-1',
{ providerId: 'fleet', runtimeSessionId: 'runtime-1' }, { providerId: 'fleet', runtimeSessionId: 'runtime-1' },
{ id: 'mosaic-admin-1', tenantId: 'tenant-1' }, { id: 'mosaic-admin-1', tenantId: 'tenant-1' },
'cli-enrollment-correlation', 'cli-enrollment-correlation',
@@ -122,14 +123,46 @@ describe('Tess Discord/CLI durable-session integration', () => {
durable, durable,
); );
const client = { data: { discordService: true }, emit: vi.fn() }; const client = { data: { discordService: true }, emit: vi.fn() };
const plugin = new DiscordPlugin({
token: 'unused',
gatewayUrl: 'http://unused',
serviceToken: SERVICE_TOKEN,
allowedGuildIds: ['guild-1'],
allowedChannelIds: ['channel-1'],
allowedUserIds: ['discord-admin-1'],
interactionBindings: [
{
instanceId: 'Nova',
guildId: 'guild-1',
channelId: 'channel-1',
pairedUsers: {
'discord-admin-1': { role: 'admin', mosaicUserId: 'mosaic-admin-1' },
},
},
],
});
const pluginInternals = plugin as unknown as {
client: { user: { id: string } };
socket: { connected: boolean; emit: ReturnType<typeof vi.fn> };
handleDiscordMessage(message: unknown): void;
};
const pluginSocket = { connected: true, emit: vi.fn() };
pluginInternals.client = { user: { id: 'bot-1' } };
pluginInternals.socket = pluginSocket;
pluginInternals.handleDiscordMessage({
id: 'approve-1',
guildId: 'guild-1',
channelId: 'channel-1',
author: { id: 'discord-admin-1', bot: false },
mentions: { has: () => true },
content: '<@bot-1> /approve',
channel: { parentId: null },
attachments: new Map(),
});
await gateway.handleDiscordApproval( expect(pluginSocket.emit).toHaveBeenCalledWith('discord:approve', expect.any(Object));
client as never, const approvalEnvelope = pluginSocket.emit.mock.calls[0]?.[1];
createDiscordIngressEnvelope( await gateway.handleDiscordApproval(client as never, approvalEnvelope);
payload('/approve', 'approve-1', 'discord-approve-correlation'),
SERVICE_TOKEN,
),
);
const approval = client.emit.mock.calls.find( const approval = client.emit.mock.calls.find(
([event]) => event === 'discord:approval', ([event]) => event === 'discord:approval',
)?.[1] as { )?.[1] as {

View File

@@ -382,7 +382,7 @@ export class DiscordPlugin {
this.config.serviceToken, this.config.serviceToken,
); );
this.socket.emit( this.socket.emit(
content.startsWith('/approve ') /^\/approve$/i.test(content)
? 'discord:approve' ? 'discord:approve'
: content.startsWith('/stop ') : content.startsWith('/stop ')
? 'discord:stop' ? 'discord:stop'