diff --git a/workspaces/augment/plugins/augment-backend/src/routes/agentRoutes.ts b/workspaces/augment/plugins/augment-backend/src/routes/agentRoutes.ts index 9a831d9037..65aab3ca78 100644 --- a/workspaces/augment/plugins/augment-backend/src/routes/agentRoutes.ts +++ b/workspaces/augment/plugins/augment-backend/src/routes/agentRoutes.ts @@ -177,6 +177,10 @@ export function registerAgentRoutes( version: cfg?.version ?? 0, promotedAt: cfg?.promotedAt, promotedBy: cfg?.promotedBy, + createdBy: cfg?.createdBy, + rejectionReason: cfg?.rejectionReason, + rejectedBy: cfg?.rejectedBy, + rejectedAt: cfg?.rejectedAt, }; } @@ -311,6 +315,11 @@ export function registerAgentRoutes( existing.version = (existing.version ?? 0) + 1; existing.promotedAt = now; existing.promotedBy = userRef; + if (isSubmitForReview) { + existing.rejectionReason = undefined; + existing.rejectedBy = undefined; + existing.rejectedAt = undefined; + } } else { configs.push({ agentId, @@ -363,7 +372,10 @@ export function registerAgentRoutes( 'Failed to demote agent', async (req, res) => { const agentId = decodeURIComponent(req.params.agentId); - const { targetStage } = req.body as { targetStage?: string }; + const { targetStage, reason } = req.body as { + targetStage?: string; + reason?: string; + }; const resolved = targetStage ? normalizeLifecycleStage(targetStage) : undefined; @@ -393,6 +405,7 @@ export function registerAgentRoutes( const now = new Date().toISOString(); const isProd = isProductionStage(nextStage); + const isRejection = currentStage === 'review' && nextStage === 'draft'; if (existing) { existing.lifecycleStage = nextStage; @@ -403,6 +416,11 @@ export function registerAgentRoutes( } existing.promotedAt = now; existing.promotedBy = userRef; + if (isRejection) { + existing.rejectionReason = reason || undefined; + existing.rejectedBy = userRef; + existing.rejectedAt = now; + } } else { configs.push({ agentId, @@ -422,7 +440,12 @@ export function registerAgentRoutes( target: agentId, outcome: 'success', sourceIp: AuditLogger.extractIp(req), - meta: { from: currentStage, to: nextStage, direction: 'demote' }, + meta: { + from: currentStage, + to: nextStage, + direction: 'demote', + ...(isRejection && reason ? { rejectionReason: reason } : {}), + }, }); logger.info(`Agent "${agentId}" demoted to ${nextStage} by ${userRef}`); res.json({ success: true, agentId, lifecycleStage: nextStage }); diff --git a/workspaces/augment/plugins/augment-common/report.api.md b/workspaces/augment/plugins/augment-common/report.api.md index 217aed3085..e2aa65cf20 100644 --- a/workspaces/augment/plugins/augment-common/report.api.md +++ b/workspaces/augment/plugins/augment-common/report.api.md @@ -257,6 +257,7 @@ export interface ChatAgent { agentRole?: AgentRole; avatarUrl?: string; createdAt?: string; + createdBy?: string; description?: string; framework?: string; id: string; @@ -269,6 +270,9 @@ export interface ChatAgent { protocols?: string[]; providerType: string; published?: boolean; + rejectedAt?: string; + rejectedBy?: string; + rejectionReason?: string; source?: string; starters?: string[]; status: string; @@ -281,6 +285,7 @@ export interface ChatAgentConfig { agentId: string; avatarUrl?: string; conversationStarters?: string[]; + createdBy?: string; description?: string; displayName?: string; featured: boolean; @@ -290,6 +295,9 @@ export interface ChatAgentConfig { promotedAt?: string; promotedBy?: string; published: boolean; + rejectedAt?: string; + rejectedBy?: string; + rejectionReason?: string; version?: number; visible: boolean; } diff --git a/workspaces/augment/plugins/augment-common/src/types/shared.ts b/workspaces/augment/plugins/augment-common/src/types/shared.ts index 44d83f6334..c93759b893 100644 --- a/workspaces/augment/plugins/augment-common/src/types/shared.ts +++ b/workspaces/augment/plugins/augment-common/src/types/shared.ts @@ -404,6 +404,14 @@ export interface ChatAgentConfig { greeting?: string; /** Suggested prompts shown on the agent card and below the input */ conversationStarters?: string[]; + /** User ref of who originally created this agent config entry */ + createdBy?: string; + /** Reason provided by admin when rejecting (demoting review→draft) */ + rejectionReason?: string; + /** User ref of who rejected this agent */ + rejectedBy?: string; + /** ISO timestamp of when the rejection occurred */ + rejectedAt?: string; } /** @@ -614,6 +622,14 @@ export interface ChatAgent { promotedBy?: string; /** Role of this agent in the orchestration topology */ agentRole?: AgentRole; + /** User ref of who originally created this agent */ + createdBy?: string; + /** Reason provided by admin when rejecting (demoting review→draft) */ + rejectionReason?: string; + /** User ref of who rejected this agent */ + rejectedBy?: string; + /** ISO timestamp of when the rejection occurred */ + rejectedAt?: string; } /** diff --git a/workspaces/augment/plugins/augment/report.api.md b/workspaces/augment/plugins/augment/report.api.md index d342dcd378..442ff0f275 100644 --- a/workspaces/augment/plugins/augment/report.api.md +++ b/workspaces/augment/plugins/augment/report.api.md @@ -181,6 +181,7 @@ export interface AugmentApi { demoteAgent( agentId: string, targetStage?: AgentLifecycleStage, + reason?: string, ): Promise<{ lifecycleStage: string; }>; diff --git a/workspaces/augment/plugins/augment/src/api/AugmentApi.ts b/workspaces/augment/plugins/augment/src/api/AugmentApi.ts index e79f9af0c2..2583cd8844 100644 --- a/workspaces/augment/plugins/augment/src/api/AugmentApi.ts +++ b/workspaces/augment/plugins/augment/src/api/AugmentApi.ts @@ -93,10 +93,12 @@ export interface AugmentApi { /** * Demote an agent to a previous lifecycle stage (deployed → registered → draft). + * @param reason - optional rejection reason (used when demoting review→draft) */ demoteAgent( agentId: string, targetStage?: import('@red-hat-developer-hub/backstage-plugin-augment-common').AgentLifecycleStage, + reason?: string, ): Promise<{ lifecycleStage: string }>; /** @@ -775,11 +777,12 @@ export class AugmentApiClient implements AugmentApi { async demoteAgent( agentId: string, targetStage?: import('@red-hat-developer-hub/backstage-plugin-augment-common').AgentLifecycleStage, + reason?: string, ): Promise<{ lifecycleStage: string }> { return this.fetchJson(`/agents/${encodeURIComponent(agentId)}/demote`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ targetStage }), + body: JSON.stringify({ targetStage, reason }), }); }