fix(frontend): agent activity cap (#10675)

## Changes 🏗️

Add the following caps to the **Agent Activity Dropdown**:
- display activity only from the last 72h
- display up to 1000 items

## Checklist 📋

### For code changes

- [x] I have clearly listed my changes in the PR description
- [x] I have made a test plan
- [x] I have tested my changes according to the test plan:
  - [x] Open the agent activity with a big amount of times locally
  - [x] It displays up to a 1000 and with 72h cap  

### For configuration changes

None

Co-authored-by: Abhimanyu Yadav <122007096+Abhi1992002@users.noreply.github.com>
This commit is contained in:
Ubbe
2025-08-19 08:56:26 +01:00
committed by GitHub
parent 650be0d1f7
commit e2c33e3d2a

View File

@@ -7,13 +7,11 @@ import type { GraphExecution } from "@/lib/autogpt-server-api/types";
const MILLISECONDS_PER_SECOND = 1000;
const SECONDS_PER_MINUTE = 60;
const MINUTES_PER_HOUR = 60;
const HOURS_PER_DAY = 24;
const DAYS_PER_WEEK = 7;
const MILLISECONDS_PER_MINUTE = SECONDS_PER_MINUTE * MILLISECONDS_PER_SECOND;
const MILLISECONDS_PER_HOUR = MINUTES_PER_HOUR * MILLISECONDS_PER_MINUTE;
const MILLISECONDS_PER_DAY = HOURS_PER_DAY * MILLISECONDS_PER_HOUR;
const MILLISECONDS_PER_WEEK = DAYS_PER_WEEK * MILLISECONDS_PER_DAY;
const MILLISECONDS_PER_72_HOURS = 72 * MILLISECONDS_PER_HOUR;
const SHORT_DURATION_THRESHOLD_SECONDS = 5;
const MAX_EXECUTIONS_CAP = 1000;
export function formatTimeAgo(dateStr: string): string {
const date = new Date(dateStr);
@@ -24,8 +22,8 @@ export function formatTimeAgo(dateStr: string): string {
if (diffMins < 1) return "just now";
if (diffMins < SECONDS_PER_MINUTE) return `${diffMins}m ago`;
const diffHours = Math.floor(diffMins / MINUTES_PER_HOUR);
if (diffHours < HOURS_PER_DAY) return `${diffHours}h ago`;
const diffDays = Math.floor(diffHours / HOURS_PER_DAY);
if (diffHours < 24) return `${diffHours}h ago`;
const diffDays = Math.floor(diffHours / 24);
return `${diffDays}d ago`;
}
@@ -159,34 +157,34 @@ export function isActiveExecution(
export function isRecentCompletion(
execution: GeneratedGraphExecutionMeta,
oneWeekAgo: Date,
cutoffDate: Date,
): boolean {
const status = execution.status;
return (
status === AgentExecutionStatus.COMPLETED &&
!!execution.ended_at &&
new Date(execution.ended_at) > oneWeekAgo
new Date(execution.ended_at) > cutoffDate
);
}
export function isRecentFailure(
execution: GeneratedGraphExecutionMeta,
oneWeekAgo: Date,
cutoffDate: Date,
): boolean {
const status = execution.status;
return (
(status === AgentExecutionStatus.FAILED ||
status === AgentExecutionStatus.TERMINATED) &&
!!execution.ended_at &&
new Date(execution.ended_at) > oneWeekAgo
new Date(execution.ended_at) > cutoffDate
);
}
export function isRecentNotification(
execution: AgentExecutionWithInfo,
oneWeekAgo: Date,
cutoffDate: Date,
): boolean {
return execution.ended_at ? new Date(execution.ended_at) > oneWeekAgo : false;
return execution.ended_at ? new Date(execution.ended_at) > cutoffDate : false;
}
export function categorizeExecutions(
@@ -196,21 +194,34 @@ export function categorizeExecutions(
{ name: string; description: string; library_agent_id?: string }
>,
): NotificationState {
const oneWeekAgo = new Date(Date.now() - MILLISECONDS_PER_WEEK);
const seventyTwoHoursAgo = new Date(Date.now() - MILLISECONDS_PER_72_HOURS);
const enrichedExecutions = executions.map((execution) =>
// First filter by 72-hour window, then apply cap
const recentExecutions = executions
.filter((execution) => {
// Always include active executions regardless of time
if (isActiveExecution(execution)) return true;
// For completed/failed executions, check if they're within 72 hours
return (
execution.ended_at && new Date(execution.ended_at) > seventyTwoHoursAgo
);
})
.slice(0, MAX_EXECUTIONS_CAP); // Apply 800 execution cap
const enrichedExecutions = recentExecutions.map((execution) =>
enrichExecutionWithAgentInfo(execution, agentInfoMap),
);
// Filter and limit each category to prevent unbounded state growth
// Categorize the capped executions
const activeExecutions = enrichedExecutions.filter(isActiveExecution);
const recentCompletions = enrichedExecutions.filter((execution) =>
isRecentCompletion(execution, oneWeekAgo),
isRecentCompletion(execution, seventyTwoHoursAgo),
);
const recentFailures = enrichedExecutions.filter((execution) =>
isRecentFailure(execution, oneWeekAgo),
isRecentFailure(execution, seventyTwoHoursAgo),
);
return {
@@ -250,14 +261,14 @@ export function addExecutionToCategory(
state: NotificationState,
execution: AgentExecutionWithInfo,
): NotificationState {
const oneWeekAgo = new Date(Date.now() - MILLISECONDS_PER_WEEK);
const seventyTwoHoursAgo = new Date(Date.now() - MILLISECONDS_PER_72_HOURS);
const newState = { ...state };
if (isActiveExecution(execution)) {
newState.activeExecutions = [execution, ...newState.activeExecutions];
} else if (isRecentCompletion(execution, oneWeekAgo)) {
} else if (isRecentCompletion(execution, seventyTwoHoursAgo)) {
newState.recentCompletions = [execution, ...newState.recentCompletions];
} else if (isRecentFailure(execution, oneWeekAgo)) {
} else if (isRecentFailure(execution, seventyTwoHoursAgo)) {
newState.recentFailures = [execution, ...newState.recentFailures];
}
@@ -267,13 +278,13 @@ export function addExecutionToCategory(
export function cleanupOldNotifications(
state: NotificationState,
): NotificationState {
const oneWeekAgo = new Date(Date.now() - MILLISECONDS_PER_WEEK);
const seventyTwoHoursAgo = new Date(Date.now() - MILLISECONDS_PER_72_HOURS);
const filteredRecentCompletions = state.recentCompletions.filter((e) =>
isRecentNotification(e, oneWeekAgo),
isRecentNotification(e, seventyTwoHoursAgo),
);
const filteredRecentFailures = state.recentFailures.filter((e) =>
isRecentNotification(e, oneWeekAgo),
isRecentNotification(e, seventyTwoHoursAgo),
);
return {