import { Injectable } from "@nestjs/common"; import type { Prisma } from "@prisma/client"; import { KillswitchService } from "../../killswitch/killswitch.service"; import { PrismaService } from "../../prisma/prisma.service"; @Injectable() export class AgentControlService { constructor( private readonly prisma: PrismaService, private readonly killswitchService: KillswitchService ) {} private toJsonValue(value: Record): Prisma.InputJsonValue { return value as Prisma.InputJsonValue; } private async createOperatorAuditLog( agentId: string, operatorId: string, action: "inject" | "pause" | "resume" | "kill", payload: Record ): Promise { await this.prisma.operatorAuditLog.create({ data: { sessionId: agentId, userId: operatorId, provider: "internal", action, metadata: this.toJsonValue({ payload }), }, }); } async injectMessage(agentId: string, operatorId: string, message: string): Promise { const treeEntry = await this.prisma.agentSessionTree.findUnique({ where: { sessionId: agentId }, select: { id: true }, }); if (treeEntry) { await this.prisma.agentConversationMessage.create({ data: { sessionId: agentId, role: "operator", content: message, provider: "internal", metadata: this.toJsonValue({}), }, }); } await this.createOperatorAuditLog(agentId, operatorId, "inject", { message }); } async pauseAgent(agentId: string, operatorId: string): Promise { await this.prisma.agentSessionTree.updateMany({ where: { sessionId: agentId }, data: { status: "paused" }, }); await this.createOperatorAuditLog(agentId, operatorId, "pause", {}); } async resumeAgent(agentId: string, operatorId: string): Promise { await this.prisma.agentSessionTree.updateMany({ where: { sessionId: agentId }, data: { status: "running" }, }); await this.createOperatorAuditLog(agentId, operatorId, "resume", {}); } async killAgent(agentId: string, operatorId: string, force = true): Promise { await this.killswitchService.killAgent(agentId); await this.createOperatorAuditLog(agentId, operatorId, "kill", { force }); } }