fix: interrupt running agents before archive
This commit is contained in:
@@ -196,6 +196,64 @@ describe("daemon client E2E", () => {
|
||||
await expect(ctx.client.archiveAgent(randomUUID())).rejects.toThrow();
|
||||
}, 10000);
|
||||
|
||||
test("interrupts a running agent before archiving", async () => {
|
||||
const cwd = tmpCwd();
|
||||
try {
|
||||
const created = await ctx.client.createAgent({
|
||||
config: {
|
||||
...getFullAccessConfig("codex"),
|
||||
cwd,
|
||||
},
|
||||
});
|
||||
|
||||
await ctx.client.sendMessage(
|
||||
created.id,
|
||||
"Use your shell tool to run `sleep 30` and then confirm when done."
|
||||
);
|
||||
await ctx.client.waitForAgentUpsert(
|
||||
created.id,
|
||||
(snapshot) => snapshot.status === "running",
|
||||
15000
|
||||
);
|
||||
|
||||
const result = await ctx.client.archiveAgent(created.id);
|
||||
expect(result.archivedAt).toBeTruthy();
|
||||
|
||||
const archived = await ctx.client.fetchAgent(created.id);
|
||||
expect(archived).not.toBeNull();
|
||||
expect(archived?.archivedAt).toBeTruthy();
|
||||
expect(archived?.status).not.toBe("running");
|
||||
|
||||
const runningAgents = await ctx.client.fetchAgents({
|
||||
filter: { includeArchived: true, statuses: ["running"] },
|
||||
});
|
||||
expect(
|
||||
runningAgents.entries.some((entry) => entry.agent.id === created.id)
|
||||
).toBe(false);
|
||||
} finally {
|
||||
rmSync(cwd, { recursive: true, force: true });
|
||||
}
|
||||
}, 60000);
|
||||
|
||||
test("rejects send_agent_message for archived agents", async () => {
|
||||
const cwd = tmpCwd();
|
||||
try {
|
||||
const created = await ctx.client.createAgent({
|
||||
config: {
|
||||
...getFullAccessConfig("codex"),
|
||||
cwd,
|
||||
},
|
||||
});
|
||||
|
||||
await ctx.client.archiveAgent(created.id);
|
||||
await expect(
|
||||
ctx.client.sendMessage(created.id, "Say hello and nothing else")
|
||||
).rejects.toThrow("archived");
|
||||
} finally {
|
||||
rmSync(cwd, { recursive: true, force: true });
|
||||
}
|
||||
}, 30000);
|
||||
|
||||
test("returns home-scoped directory suggestions", async () => {
|
||||
const insideHomeDir = mkdtempSync(path.join(homedir(), "paseo-dir-suggestion-"));
|
||||
const outsideHomeDir = mkdtempSync(path.join(tmpdir(), "paseo-dir-suggestion-outside-"));
|
||||
|
||||
@@ -1674,6 +1674,10 @@ export class Session {
|
||||
private async handleArchiveAgentRequest(agentId: string, requestId: string): Promise<void> {
|
||||
this.sessionLogger.info({ agentId }, `Archiving agent ${agentId}`)
|
||||
|
||||
if (this.agentManager.getAgent(agentId)) {
|
||||
await this.interruptAgentIfRunning(agentId)
|
||||
}
|
||||
|
||||
const archivedAt = new Date().toISOString()
|
||||
|
||||
const existing = await this.agentStorage.get(agentId)
|
||||
@@ -1717,6 +1721,11 @@ export class Session {
|
||||
})
|
||||
}
|
||||
|
||||
private async getArchivedAt(agentId: string): Promise<string | null> {
|
||||
const record = await this.agentStorage.get(agentId)
|
||||
return record?.archivedAt ?? null
|
||||
}
|
||||
|
||||
private async handleUpdateAgentRequest(
|
||||
agentId: string,
|
||||
name: string | undefined,
|
||||
@@ -2308,6 +2317,16 @@ export class Session {
|
||||
return
|
||||
}
|
||||
|
||||
const archivedAt = await this.getArchivedAt(agentId)
|
||||
if (archivedAt) {
|
||||
this.handleAgentRunError(
|
||||
agentId,
|
||||
new Error(`Agent ${agentId} is archived`),
|
||||
'Refusing to send prompt to archived agent'
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
await this.interruptAgentIfRunning(agentId)
|
||||
} catch (error) {
|
||||
@@ -5250,6 +5269,20 @@ export class Session {
|
||||
try {
|
||||
const agentId = resolved.agentId
|
||||
|
||||
const archivedAt = await this.getArchivedAt(agentId)
|
||||
if (archivedAt) {
|
||||
this.emit({
|
||||
type: 'send_agent_message_response',
|
||||
payload: {
|
||||
requestId: msg.requestId,
|
||||
agentId,
|
||||
accepted: false,
|
||||
error: `Agent ${agentId} is archived`,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
await this.ensureAgentLoaded(agentId)
|
||||
await this.interruptAgentIfRunning(agentId)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user