refactor: add dynamic input height, agent sorting, and last activity tracking

This commit is contained in:
Mohamed Boudra
2025-10-25 21:56:44 +02:00
parent 1d6de732b6
commit 8d591da671
10 changed files with 186 additions and 112 deletions
+16 -12
View File
@@ -42,6 +42,7 @@ interface ManagedAgent {
id: string;
cwd: string;
createdAt: Date;
lastActivityAt: Date;
title: string;
options: AgentOptions;
subscribers: Set<AgentUpdateCallback>;
@@ -166,10 +167,15 @@ export class AgentManager {
console.log(
`[AgentManager] Loading agent ${persistedAgent.id} as uninitialized`
);
const createdAt = new Date(persistedAgent.createdAt);
const lastActivityAt = persistedAgent.lastActivityAt
? new Date(persistedAgent.lastActivityAt)
: createdAt;
const agent: ManagedAgent = {
id: persistedAgent.id,
cwd: expandTilde(persistedAgent.cwd),
createdAt: new Date(persistedAgent.createdAt),
createdAt,
lastActivityAt,
title: persistedAgent.title,
options: persistedAgent.options,
subscribers: new Set(),
@@ -225,6 +231,7 @@ export class AgentManager {
id: agentId,
cwd,
createdAt,
lastActivityAt: createdAt,
title: "",
options: agentOptions,
subscribers: new Set(),
@@ -250,6 +257,7 @@ export class AgentManager {
sessionId: null,
options: agent.options,
createdAt: createdAt.toISOString(),
lastActivityAt: agent.lastActivityAt.toISOString(),
cwd: agent.cwd,
});
@@ -553,6 +561,7 @@ export class AgentManager {
id: agent.id,
status,
createdAt: agent.createdAt,
lastActivityAt: agent.lastActivityAt,
type: "claude" as const,
sessionId,
error: error ?? null,
@@ -617,6 +626,7 @@ export class AgentManager {
id: agent.id,
status,
createdAt: agent.createdAt,
lastActivityAt: agent.lastActivityAt,
type: "claude",
sessionId: runtime?.sessionId ?? null,
error: error ?? null,
@@ -1000,6 +1010,7 @@ export class AgentManager {
sessionId: runtime.sessionId,
options: agent.options,
createdAt: agent.createdAt.toISOString(),
lastActivityAt: agent.lastActivityAt.toISOString(),
cwd: agent.cwd,
});
@@ -1056,6 +1067,9 @@ export class AgentManager {
const agent = this.agents.get(agentId);
if (!agent) return;
// Update last activity timestamp
agent.lastActivityAt = new Date();
// Augment update with stable message IDs for deduplication
let enrichedUpdate: EnrichedSessionNotification;
@@ -1286,17 +1300,6 @@ export class AgentManager {
console.log(
`[Agent ${agentId}] Permission request emitted: ${requestId}`
);
// Set a timeout to auto-reject after 5 minutes if no response
setTimeout(() => {
if (agent.pendingPermissions.has(requestId)) {
console.warn(
`[Agent ${agentId}] Permission request ${requestId} timed out`
);
agent.pendingPermissions.delete(requestId);
reject(new Error("Permission request timed out"));
}
}, 5 * 60 * 1000); // 5 minutes
});
}
@@ -1459,6 +1462,7 @@ export class AgentManager {
sessionId: runtime.sessionId,
options: agent.options,
createdAt: agent.createdAt.toISOString(),
lastActivityAt: agent.lastActivityAt.toISOString(),
cwd: agent.cwd,
});
console.log(`[Agent ${agent.id}] State persisted`);
@@ -25,6 +25,7 @@ export const PersistedAgentSchema = z.object({
sessionId: z.string().nullable(), // ACP protocol session ID (null for uninitialized agents)
options: AgentOptionsSchema, // Required field with discriminated union
createdAt: z.string(),
lastActivityAt: z.string().optional(), // Migration: optional for backward compatibility
cwd: z.string(),
});
@@ -52,6 +53,11 @@ export class AgentPersistence {
try {
const validated = PersistedAgentSchema.parse(agent);
// Migration: if lastActivityAt is missing, default to createdAt
if (!validated.lastActivityAt) {
validated.lastActivityAt = validated.createdAt;
}
if (
validated.options.type === "claude" &&
validated.options.sessionId !== null
+1
View File
@@ -116,6 +116,7 @@ export interface AgentInfo {
id: string;
status: AgentStatus;
createdAt: Date;
lastActivityAt: Date;
type: "claude";
sessionId: string | null;
error: string | null;
+1
View File
@@ -10,6 +10,7 @@ const AgentInfoSchema = z.object({
id: z.string(),
status: z.string(),
createdAt: z.date(),
lastActivityAt: z.date(),
type: z.literal("claude"),
sessionId: z.string().nullable(),
error: z.string().nullable(),