test(discord): exercise runtime approval consumption

This commit is contained in:
Jarvis
2026-07-13 03:39:59 -05:00
parent 318a7bdda8
commit 80fc236cb5
2 changed files with 18 additions and 28 deletions

View File

@@ -667,7 +667,8 @@ export class ChatGateway implements OnGatewayInit, OnGatewayConnection, OnGatewa
'approve', 'approve',
); );
const actorId = binding && resolveDiscordInteractionActorId(binding, ingress.userId); const actorId = binding && resolveDiscordInteractionActorId(binding, ingress.userId);
if (!actorId) return; const agentName = process.env['MOSAIC_AGENT_NAME']?.trim();
if (!actorId || !agentName || binding.instanceId !== agentName) return;
const providerId = actionParts[1]!; const providerId = actionParts[1]!;
const sessionId = actionParts[2]!; const sessionId = actionParts[2]!;
const approval = await this.commandAuthorization.createRuntimeTerminationApproval({ const approval = await this.commandAuthorization.createRuntimeTerminationApproval({
@@ -682,7 +683,7 @@ export class ChatGateway implements OnGatewayInit, OnGatewayConnection, OnGatewa
providerId, providerId,
sessionId, sessionId,
), ),
agentName: binding.instanceId, agentName,
}); });
client.emit('discord:approval', { client.emit('discord:approval', {
correlationId: ingress.correlationId, correlationId: ingress.correlationId,

View File

@@ -8,6 +8,7 @@ import {
resolveDiscordInteractionActorId, resolveDiscordInteractionActorId,
resolveDiscordInteractionBinding, resolveDiscordInteractionBinding,
} from '@mosaicstack/discord-plugin'; } from '@mosaicstack/discord-plugin';
import { RuntimeProviderService } from '../agent/runtime-provider-registry.service.js';
import { ChatGateway } from '../chat/chat.gateway.js'; import { ChatGateway } from '../chat/chat.gateway.js';
import { CommandAuthorizationService } from '../commands/command-authorization.service.js'; import { CommandAuthorizationService } from '../commands/command-authorization.service.js';
import { validateDiscordServiceToken } from '../chat/chat.gateway-auth.js'; import { validateDiscordServiceToken } from '../chat/chat.gateway-auth.js';
@@ -79,33 +80,21 @@ function discordGateway(role: 'admin' | 'member'): {
} { } {
const authorization = commandAuthorization(role); const authorization = commandAuthorization(role);
const consumedActions: Array<{ actorId: string; correlationId: string }> = []; const consumedActions: Array<{ actorId: string; correlationId: string }> = [];
const runtimeRegistry = { const runtimeRegistry = new RuntimeProviderService(
terminate: async ( {
providerId: string, require: () => ({
sessionId: string, capabilities: async () => ({ supported: ['session.terminate'] }),
approvalId: string, terminate: async () => undefined,
context: { }),
actorScope: { userId: string; tenantId: string }; } as never,
channelId: string; { record: async () => undefined } as never,
correlationId: string; {
consume: async (approvalId, action) => {
consumedActions.push({ actorId: action.actorId, correlationId: action.correlationId });
return authorization.consumeRuntimeTerminationApproval(approvalId, action);
}, },
): Promise<void> => {
consumedActions.push({
actorId: context.actorScope.userId,
correlationId: context.correlationId,
});
const approved = await authorization.consumeRuntimeTerminationApproval(approvalId, {
providerId,
sessionId,
actorId: context.actorScope.userId,
tenantId: context.actorScope.tenantId,
channelId: context.channelId,
correlationId: context.correlationId,
agentName: 'Nova',
});
if (!approved) throw new Error('approval denied');
}, },
}; );
return { return {
gateway: new ChatGateway( gateway: new ChatGateway(
{} as never, {} as never,
@@ -115,7 +104,7 @@ function discordGateway(role: 'admin' | 'member'): {
{} as never, {} as never,
{} as never, {} as never,
authorization, authorization,
runtimeRegistry as never, runtimeRegistry,
), ),
client: { data: { discordService: true }, emit: vi.fn() }, client: { data: { discordService: true }, emit: vi.fn() },
consumedActions, consumedActions,