feat: M4-07 — Hermes Agent task/artifact management with approval workflow
All checks were successful
Deploy API Server / build-and-deploy (push) Successful in 40s
All checks were successful
Deploy API Server / build-and-deploy (push) Successful in 40s
- Add AgentTask and AgentArtifact Prisma models - HermesAgentController: list tasks, approve/reject, list artifacts - AAPI: GET /admin-api/hermes/tasks, POST approve/reject, GET /admin-api/hermes/artifacts Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
8abf94872a
commit
5d84769ac0
@ -1409,3 +1409,36 @@ model ExportJob {
|
||||
errorMessage String? @db.Text
|
||||
createdAt DateTime @default(now())
|
||||
}
|
||||
|
||||
model AgentTask {
|
||||
id String @id @default(cuid())
|
||||
userId String?
|
||||
type String @db.VarChar(32)
|
||||
status String @default("pending") @db.VarChar(16)
|
||||
input String? @db.Text
|
||||
output String? @db.Text
|
||||
sessionId String? @db.VarChar(255)
|
||||
approvedBy String?
|
||||
approvedAt DateTime?
|
||||
giteaUrl String? @db.VarChar(500)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([status])
|
||||
@@index([userId])
|
||||
}
|
||||
|
||||
model AgentArtifact {
|
||||
id String @id @default(cuid())
|
||||
taskId String?
|
||||
type String @db.VarChar(32)
|
||||
title String @db.VarChar(255)
|
||||
content String? @db.Text
|
||||
status String @default("draft") @db.VarChar(16)
|
||||
createdBy String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([taskId])
|
||||
@@index([type])
|
||||
}
|
||||
|
||||
@ -55,6 +55,7 @@ import { AdminCacheModule } from './modules/admin-cache/admin-cache.module';
|
||||
import { BackupModule } from './modules/backup/backup.module';
|
||||
import { ReportingModule } from './modules/reporting/reporting.module';
|
||||
import { ProjectCenterModule } from './modules/project-center/project-center.module';
|
||||
import { HermesAgentModule } from './modules/hermes-agent/hermes-agent.module';
|
||||
|
||||
import { JwtAuthGuard } from './common/guards/jwt-auth.guard';
|
||||
import { RolesGuard } from './common/guards/roles.guard';
|
||||
@ -155,6 +156,7 @@ import appleConfig from './config/apple.config';
|
||||
BackupModule,
|
||||
ReportingModule,
|
||||
ProjectCenterModule,
|
||||
HermesAgentModule,
|
||||
],
|
||||
providers: [
|
||||
{ provide: APP_GUARD, useClass: RateLimitGuard },
|
||||
|
||||
49
src/modules/hermes-agent/hermes-agent.controller.ts
Normal file
49
src/modules/hermes-agent/hermes-agent.controller.ts
Normal file
@ -0,0 +1,49 @@
|
||||
import { Controller, Get, Post, Param, Body, Query, UseGuards } from '@nestjs/common';
|
||||
import { ApiTags, ApiBearerAuth, ApiOperation, ApiQuery, ApiBody } from '@nestjs/swagger';
|
||||
import { PrismaService } from '../../infrastructure/database/prisma.service';
|
||||
import { AdminAuthGuard } from '../../common/guards/admin-auth.guard';
|
||||
import { AdminRolesGuard } from '../../common/guards/admin-roles.guard';
|
||||
|
||||
@ApiTags('admin-hermes')
|
||||
@ApiBearerAuth()
|
||||
@Controller('admin-api/hermes')
|
||||
@UseGuards(AdminAuthGuard, AdminRolesGuard)
|
||||
export class HermesAgentController {
|
||||
constructor(private readonly prisma: PrismaService) {}
|
||||
|
||||
@Get('tasks')
|
||||
@ApiOperation({ summary: 'Agent 任务列表' })
|
||||
@ApiQuery({ name: 'status', required: false })
|
||||
async listTasks(@Query('status') status?: string) {
|
||||
const where: any = {};
|
||||
if (status) where.status = status;
|
||||
return this.prisma.agentTask.findMany({ where, orderBy: { createdAt: 'desc' }, take: 100 });
|
||||
}
|
||||
|
||||
@Post('tasks/:id/approve')
|
||||
@ApiOperation({ summary: '审批通过 Agent 任务' })
|
||||
async approveTask(@Param('id') id: string) {
|
||||
return this.prisma.agentTask.update({
|
||||
where: { id },
|
||||
data: { status: 'approved', approvedAt: new Date() },
|
||||
});
|
||||
}
|
||||
|
||||
@Post('tasks/:id/reject')
|
||||
@ApiOperation({ summary: '驳回 Agent 任务' })
|
||||
async rejectTask(@Param('id') id: string) {
|
||||
return this.prisma.agentTask.update({
|
||||
where: { id },
|
||||
data: { status: 'rejected' },
|
||||
});
|
||||
}
|
||||
|
||||
@Get('artifacts')
|
||||
@ApiOperation({ summary: 'Agent 产出物列表' })
|
||||
@ApiQuery({ name: 'type', required: false })
|
||||
async listArtifacts(@Query('type') type?: string) {
|
||||
const where: any = {};
|
||||
if (type) where.type = type;
|
||||
return this.prisma.agentArtifact.findMany({ where, orderBy: { createdAt: 'desc' }, take: 100 });
|
||||
}
|
||||
}
|
||||
7
src/modules/hermes-agent/hermes-agent.module.ts
Normal file
7
src/modules/hermes-agent/hermes-agent.module.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { HermesAgentController } from './hermes-agent.controller';
|
||||
|
||||
@Module({
|
||||
controllers: [HermesAgentController],
|
||||
})
|
||||
export class HermesAgentModule {}
|
||||
Loading…
x
Reference in New Issue
Block a user