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
|
errorMessage String? @db.Text
|
||||||
createdAt DateTime @default(now())
|
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 { BackupModule } from './modules/backup/backup.module';
|
||||||
import { ReportingModule } from './modules/reporting/reporting.module';
|
import { ReportingModule } from './modules/reporting/reporting.module';
|
||||||
import { ProjectCenterModule } from './modules/project-center/project-center.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 { JwtAuthGuard } from './common/guards/jwt-auth.guard';
|
||||||
import { RolesGuard } from './common/guards/roles.guard';
|
import { RolesGuard } from './common/guards/roles.guard';
|
||||||
@ -155,6 +156,7 @@ import appleConfig from './config/apple.config';
|
|||||||
BackupModule,
|
BackupModule,
|
||||||
ReportingModule,
|
ReportingModule,
|
||||||
ProjectCenterModule,
|
ProjectCenterModule,
|
||||||
|
HermesAgentModule,
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: APP_GUARD, useClass: RateLimitGuard },
|
{ 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