All checks were successful
ci/woodpecker/push/ci Pipeline was successful
Co-authored-by: Jason Woltje <jason@diversecanvas.com> Co-committed-by: Jason Woltje <jason@diversecanvas.com>
154 lines
4.8 KiB
TypeScript
154 lines
4.8 KiB
TypeScript
import {
|
|
Injectable,
|
|
NotFoundException,
|
|
ConflictException,
|
|
ForbiddenException,
|
|
} from "@nestjs/common";
|
|
import { PrismaService } from "../prisma/prisma.service";
|
|
import { CreateUserAgentDto } from "./dto/create-user-agent.dto";
|
|
import { UpdateUserAgentDto } from "./dto/update-user-agent.dto";
|
|
|
|
export interface AgentStatusResponse {
|
|
id: string;
|
|
name: string;
|
|
displayName: string;
|
|
role: string;
|
|
isActive: boolean;
|
|
containerStatus?: "running" | "stopped" | "unknown";
|
|
}
|
|
|
|
@Injectable()
|
|
export class UserAgentService {
|
|
constructor(private readonly prisma: PrismaService) {}
|
|
|
|
async findAll(userId: string) {
|
|
return this.prisma.userAgent.findMany({
|
|
where: { userId },
|
|
orderBy: { createdAt: "asc" },
|
|
});
|
|
}
|
|
|
|
async findOne(userId: string, id: string) {
|
|
const agent = await this.prisma.userAgent.findUnique({ where: { id } });
|
|
if (!agent) throw new NotFoundException(`UserAgent ${id} not found`);
|
|
if (agent.userId !== userId) throw new ForbiddenException("Access denied to this agent");
|
|
return agent;
|
|
}
|
|
|
|
async findByName(userId: string, name: string) {
|
|
const agent = await this.prisma.userAgent.findUnique({
|
|
where: { userId_name: { userId, name } },
|
|
});
|
|
if (!agent) throw new NotFoundException(`UserAgent "${name}" not found for user`);
|
|
return agent;
|
|
}
|
|
|
|
async create(userId: string, dto: CreateUserAgentDto) {
|
|
// Check for unique name within user scope
|
|
const existing = await this.prisma.userAgent.findUnique({
|
|
where: { userId_name: { userId, name: dto.name } },
|
|
});
|
|
if (existing)
|
|
throw new ConflictException(`UserAgent "${dto.name}" already exists for this user`);
|
|
|
|
// If templateId provided, verify it exists
|
|
if (dto.templateId) {
|
|
const template = await this.prisma.agentTemplate.findUnique({
|
|
where: { id: dto.templateId },
|
|
});
|
|
if (!template) throw new NotFoundException(`AgentTemplate ${dto.templateId} not found`);
|
|
}
|
|
|
|
return this.prisma.userAgent.create({
|
|
data: {
|
|
userId,
|
|
templateId: dto.templateId ?? null,
|
|
name: dto.name,
|
|
displayName: dto.displayName,
|
|
role: dto.role,
|
|
personality: dto.personality,
|
|
primaryModel: dto.primaryModel ?? null,
|
|
fallbackModels: dto.fallbackModels ?? ([] as string[]),
|
|
toolPermissions: dto.toolPermissions ?? ([] as string[]),
|
|
discordChannel: dto.discordChannel ?? null,
|
|
isActive: dto.isActive ?? true,
|
|
},
|
|
});
|
|
}
|
|
|
|
async createFromTemplate(userId: string, templateId: string) {
|
|
const template = await this.prisma.agentTemplate.findUnique({
|
|
where: { id: templateId },
|
|
});
|
|
if (!template) throw new NotFoundException(`AgentTemplate ${templateId} not found`);
|
|
|
|
// Check for unique name within user scope
|
|
const existing = await this.prisma.userAgent.findUnique({
|
|
where: { userId_name: { userId, name: template.name } },
|
|
});
|
|
if (existing)
|
|
throw new ConflictException(`UserAgent "${template.name}" already exists for this user`);
|
|
|
|
return this.prisma.userAgent.create({
|
|
data: {
|
|
userId,
|
|
templateId: template.id,
|
|
name: template.name,
|
|
displayName: template.displayName,
|
|
role: template.role,
|
|
personality: template.personality,
|
|
primaryModel: template.primaryModel,
|
|
fallbackModels: template.fallbackModels as string[],
|
|
toolPermissions: template.toolPermissions as string[],
|
|
discordChannel: template.discordChannel,
|
|
isActive: template.isActive,
|
|
},
|
|
});
|
|
}
|
|
|
|
async update(userId: string, id: string, dto: UpdateUserAgentDto) {
|
|
const agent = await this.findOne(userId, id);
|
|
|
|
// If name is being changed, check for uniqueness
|
|
if (dto.name && dto.name !== agent.name) {
|
|
const existing = await this.prisma.userAgent.findUnique({
|
|
where: { userId_name: { userId, name: dto.name } },
|
|
});
|
|
if (existing)
|
|
throw new ConflictException(`UserAgent "${dto.name}" already exists for this user`);
|
|
}
|
|
|
|
return this.prisma.userAgent.update({
|
|
where: { id },
|
|
data: dto,
|
|
});
|
|
}
|
|
|
|
async remove(userId: string, id: string) {
|
|
await this.findOne(userId, id);
|
|
return this.prisma.userAgent.delete({ where: { id } });
|
|
}
|
|
|
|
async getStatus(userId: string, id: string): Promise<AgentStatusResponse> {
|
|
const agent = await this.findOne(userId, id);
|
|
return {
|
|
id: agent.id,
|
|
name: agent.name,
|
|
displayName: agent.displayName,
|
|
role: agent.role,
|
|
isActive: agent.isActive,
|
|
};
|
|
}
|
|
|
|
async getAllStatuses(userId: string): Promise<AgentStatusResponse[]> {
|
|
const agents = await this.findAll(userId);
|
|
return agents.map((agent) => ({
|
|
id: agent.id,
|
|
name: agent.name,
|
|
displayName: agent.displayName,
|
|
role: agent.role,
|
|
isActive: agent.isActive,
|
|
}));
|
|
}
|
|
}
|