fix(#709): use durable Discord termination approvals
All checks were successful
ci/woodpecker/pr/ci Pipeline was successful
All checks were successful
ci/woodpecker/pr/ci Pipeline was successful
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { Inject, Logger } from '@nestjs/common';
|
import { Inject, Logger, Optional } from '@nestjs/common';
|
||||||
import {
|
import {
|
||||||
WebSocketGateway,
|
WebSocketGateway,
|
||||||
WebSocketServer,
|
WebSocketServer,
|
||||||
@@ -39,6 +39,7 @@ import {
|
|||||||
import { BRAIN } from '../brain/brain.tokens.js';
|
import { BRAIN } from '../brain/brain.tokens.js';
|
||||||
import { CommandRegistryService } from '../commands/command-registry.service.js';
|
import { CommandRegistryService } from '../commands/command-registry.service.js';
|
||||||
import { CommandExecutorService } from '../commands/command-executor.service.js';
|
import { CommandExecutorService } from '../commands/command-executor.service.js';
|
||||||
|
import { CommandAuthorizationService } from '../commands/command-authorization.service.js';
|
||||||
import { RoutingEngineService } from '../agent/routing/routing-engine.service.js';
|
import { RoutingEngineService } from '../agent/routing/routing-engine.service.js';
|
||||||
import { v4 as uuid } from 'uuid';
|
import { v4 as uuid } from 'uuid';
|
||||||
import { ChatSocketMessageDto } from './chat.dto.js';
|
import { ChatSocketMessageDto } from './chat.dto.js';
|
||||||
@@ -124,6 +125,9 @@ export class ChatGateway implements OnGatewayInit, OnGatewayConnection, OnGatewa
|
|||||||
@Inject(CommandRegistryService) private readonly commandRegistry: CommandRegistryService,
|
@Inject(CommandRegistryService) private readonly commandRegistry: CommandRegistryService,
|
||||||
@Inject(CommandExecutorService) private readonly commandExecutor: CommandExecutorService,
|
@Inject(CommandExecutorService) private readonly commandExecutor: CommandExecutorService,
|
||||||
@Inject(RoutingEngineService) private readonly routingEngine: RoutingEngineService,
|
@Inject(RoutingEngineService) private readonly routingEngine: RoutingEngineService,
|
||||||
|
@Optional()
|
||||||
|
@Inject(CommandAuthorizationService)
|
||||||
|
private readonly commandAuthorization: CommandAuthorizationService | null = null,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
afterInit(): void {
|
afterInit(): void {
|
||||||
@@ -646,19 +650,28 @@ export class ChatGateway implements OnGatewayInit, OnGatewayConnection, OnGatewa
|
|||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
if (!client.data.discordService) return;
|
if (!client.data.discordService) return;
|
||||||
const ingress = this.resolveDiscordIngress(client, envelope, 'approve');
|
const ingress = this.resolveDiscordIngress(client, envelope, 'approve');
|
||||||
const command = ingress?.content.match(/^\/approve\s+([a-z][\w-]*)$/i)?.[1];
|
const actionParts = ingress?.content.match(/^\/approve\s+([^\s]+)\s+([^\s]+)$/i);
|
||||||
const serviceUserId = process.env['DISCORD_SERVICE_USER_ID'];
|
const serviceUserId = process.env['DISCORD_SERVICE_USER_ID'];
|
||||||
if (!ingress || !command || !serviceUserId) return;
|
if (!ingress || !actionParts || !serviceUserId || !this.commandAuthorization) return;
|
||||||
const approval = await this.commandExecutor.createApproval(
|
const binding = resolveDiscordInteractionBinding(
|
||||||
{ command, conversationId: ingress.conversationId },
|
parseDiscordInteractionBindings(process.env['DISCORD_INTERACTION_BINDINGS']),
|
||||||
{
|
ingress.guildId,
|
||||||
userId: serviceUserId,
|
ingress.channelId,
|
||||||
tenantId: process.env['DISCORD_SERVICE_TENANT_ID'] ?? serviceUserId,
|
ingress.userId,
|
||||||
},
|
'approve',
|
||||||
);
|
);
|
||||||
|
if (!binding) return;
|
||||||
|
const approval = await this.commandAuthorization.createRuntimeTerminationApproval({
|
||||||
|
providerId: actionParts[1]!,
|
||||||
|
sessionId: actionParts[2]!,
|
||||||
|
actorId: serviceUserId,
|
||||||
|
tenantId: process.env['DISCORD_SERVICE_TENANT_ID'] ?? serviceUserId,
|
||||||
|
channelId: ingress.channelId,
|
||||||
|
correlationId: ingress.correlationId,
|
||||||
|
agentName: binding.instanceId,
|
||||||
|
});
|
||||||
client.emit('discord:approval', {
|
client.emit('discord:approval', {
|
||||||
correlationId: ingress.correlationId,
|
correlationId: ingress.correlationId,
|
||||||
command,
|
|
||||||
success: approval !== null,
|
success: approval !== null,
|
||||||
approvalId: approval?.approvalId,
|
approvalId: approval?.approvalId,
|
||||||
expiresAt: approval?.expiresAt,
|
expiresAt: approval?.expiresAt,
|
||||||
|
|||||||
Reference in New Issue
Block a user