Skip to content
34 changes: 34 additions & 0 deletions packages/server/src/server/agent/agent-manager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1638,6 +1638,40 @@ test("setTitle bumps updatedAt and persists title in the same snapshot write", a
expect(live!.updatedAt.getTime()).toBeGreaterThan(Date.parse(before!.updatedAt));
});

test("updateAgentMetadata bumps updatedAt for stored agents", async () => {
const workdir = mkdtempSync(join(tmpdir(), "agent-manager-stored-metadata-updated-at-"));
const storagePath = join(workdir, "agents");
const storage = new AgentStorage(storagePath, logger);
const manager = new AgentManager({
clients: {
codex: new TestAgentClient(),
},
registry: storage,
logger,
idFactory: () => "00000000-0000-4000-8000-000000000128",
});

const snapshot = await manager.createAgent({
provider: "codex",
cwd: workdir,
});
await manager.closeAgent(snapshot.id);

const before = await storage.get(snapshot.id);
expect(before).not.toBeNull();
expect(manager.getAgent(snapshot.id)).toBeNull();

await manager.updateAgentMetadata(snapshot.id, {
title: "Stored title",
labels: { role: "worker" },
});

const after = await storage.get(snapshot.id);
expect(after?.title).toBe("Stored title");
expect(after?.labels).toEqual({ role: "worker" });
expect(Date.parse(after!.updatedAt)).toBeGreaterThan(Date.parse(before!.updatedAt));
});

test("setGeneratedTitle persists generated title when no title exists", async () => {
const workdir = mkdtempSync(join(tmpdir(), "agent-manager-generated-title-empty-"));
const storagePath = join(workdir, "agents");
Expand Down
8 changes: 8 additions & 0 deletions packages/server/src/server/agent/agent-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,13 @@ export class AgentManager {
return next;
}

private nextStoredUpdatedAt(record: StoredAgentRecord): string {
const previousMs = Date.parse(record.updatedAt);
const nowMs = Date.now();
const nextMs = nowMs > previousMs ? nowMs : previousMs + 1;
return new Date(nextMs).toISOString();
}

hasInFlightRun(agentId: string): boolean {
const agent = this.agents.get(agentId);
if (!agent) {
Expand Down Expand Up @@ -1360,6 +1367,7 @@ export class AgentManager {
...existing,
...(updates.title ? { title: updates.title } : {}),
...(updates.labels ? { labels: { ...existing.labels, ...updates.labels } } : {}),
updatedAt: this.nextStoredUpdatedAt(existing),
});
}

Expand Down
7 changes: 6 additions & 1 deletion packages/server/src/server/agent/agent-prompt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,18 @@ import type { AgentManager, ManagedAgent } from "./agent-manager.js";
import type { AgentStorage } from "./agent-storage.js";
import { ensureAgentLoaded } from "./agent-loading.js";

export type AgentRunController = Pick<
AgentManager,
"getAgent" | "tryRunOutOfBand" | "hasInFlightRun" | "replaceAgentRun" | "streamAgent"
>;

export interface StartAgentRunOptions {
replaceRunning?: boolean;
runOptions?: AgentRunOptions;
}

export function startAgentRun(
agentManager: AgentManager,
agentManager: AgentRunController,
agentId: string,
prompt: AgentPromptInput,
logger: Logger,
Expand Down
Loading
Loading