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',
);
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 sessionId = actionParts[2]!;
const approval = await this.commandAuthorization.createRuntimeTerminationApproval({
@@ -682,7 +683,7 @@ export class ChatGateway implements OnGatewayInit, OnGatewayConnection, OnGatewa
providerId,
sessionId,
),
agentName: binding.instanceId,
agentName,
});
client.emit('discord:approval', {
correlationId: ingress.correlationId,

View File

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