Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@

const isSubmitForReview =
currentStage === 'draft' && nextStage === 'review';
if (!isSubmitForReview) {

Check warning on line 292 in workspaces/augment/plugins/augment-backend/src/routes/agentRoutes.ts

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unexpected negated condition.

See more on https://sonarcloud.io/project/issues?id=redhat-developer_rhdh-plugins&issues=AZ5LPFREh3rCDeLGF4M7&open=AZ5LPFREh3rCDeLGF4M7&pullRequest=3215
const isAdmin = await ctx.checkIsAdmin(req);
if (!isAdmin) {
res.status(403).json({
Expand All @@ -299,6 +299,18 @@
});
return;
}
} else {
const isAdmin = await ctx.checkIsAdmin(req);
if (
!isAdmin &&
existing?.createdBy &&
existing.createdBy !== userRef
) {
res.status(403).json({
error: 'You can only submit your own agents for review.',
});
return;
}
}

const now = new Date().toISOString();
Expand Down Expand Up @@ -430,6 +442,55 @@
),
);

// ---------------------------------------------------------------------------
// DELETE /agents/:agentId -- remove a draft agent's config entry
// Non-admin callers can only delete agents they created.
// ---------------------------------------------------------------------------
router.delete(
'/agents/:agentId',
withRoute(
'DELETE /agents/:agentId',
'Failed to delete agent',
async (req, res) => {
const agentId = decodeURIComponent(req.params.agentId);
const userRef = await ctx.getUserRef(req);
const configs = await loadChatAgentConfigs();
const existing = configs.find(c => c.agentId === agentId);

if (!existing) {
throw new InputError(`Agent "${agentId}" not found in config.`);
}

const stage = normalizeLifecycleStage(existing.lifecycleStage);
if (stage !== 'draft') {
throw new InputError(
`Only draft agents can be deleted. Agent "${agentId}" is in stage "${stage}".`,
);
}

const isAdmin = await ctx.checkIsAdmin(req);
if (!isAdmin && existing.createdBy && existing.createdBy !== userRef) {
res.status(403).json({
error: 'You can only delete your own agents.',
});
return;
}

const updated = configs.filter(c => c.agentId !== agentId);
await saveChatAgentConfigs(updated, userRef);
audit.log({
action: 'agent.delete',
actor: userRef,
target: agentId,
outcome: 'success',
sourceIp: AuditLogger.extractIp(req),
});
logger.info(`Draft agent "${agentId}" deleted by ${userRef}`);
res.json({ success: true, agentId });
},
),
);

// ---------------------------------------------------------------------------
// PUT /agents/:agentId/publish -- shortcut: promote to production
// ---------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export type AuditAction =
| 'tool.approval'
| 'tool.lifecycle'
| 'agent.lifecycle'
| 'agent.delete'
| 'document.upload'
| 'document.delete'
| 'admin.login';
Expand Down
2 changes: 2 additions & 0 deletions workspaces/augment/plugins/augment-common/report.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ export interface ChatAgent {
agentRole?: AgentRole;
avatarUrl?: string;
createdAt?: string;
createdBy?: string;
description?: string;
framework?: string;
id: string;
Expand All @@ -281,6 +282,7 @@ export interface ChatAgentConfig {
agentId: string;
avatarUrl?: string;
conversationStarters?: string[];
createdBy?: string;
description?: string;
displayName?: string;
featured: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,8 @@ 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;
}

/**
Expand Down
1 change: 1 addition & 0 deletions workspaces/augment/plugins/augment/report.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ export interface AugmentApi {
createVectorStore(
config?: Record<string, unknown>,
): Promise<VectorStoreCreateResult>;
deleteAgentConfig(agentId: string): Promise<void>;
deleteAdminConfig(key: AdminConfigKey): Promise<{
deleted: boolean;
}>;
Expand Down
11 changes: 11 additions & 0 deletions workspaces/augment/plugins/augment/src/api/AugmentApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,11 @@ export interface AugmentApi {
>,
): Promise<void>;

/**
* Delete a draft agent's configuration entry.
*/
deleteAgentConfig(agentId: string): Promise<void>;

/**
* List tools with lifecycle overlay in a provider-agnostic format.
*/
Expand Down Expand Up @@ -807,6 +812,12 @@ export class AugmentApiClient implements AugmentApi {
});
}

async deleteAgentConfig(agentId: string): Promise<void> {
await this.fetchJson(`/agents/${encodeURIComponent(agentId)}`, {
method: 'DELETE',
});
}

async listToolsWithLifecycle(options?: { published?: boolean }): Promise<
(import('@red-hat-developer-hub/backstage-plugin-augment-common').KagentiToolSummary & {
published?: boolean;
Expand Down
Loading