fix(hub): fail creates when prompts cannot start

This commit is contained in:
Mohamed Boudra
2026-07-13 13:26:20 +02:00
parent 6ad70c1b1e
commit b23b400212
3 changed files with 32 additions and 2 deletions
@@ -53,3 +53,17 @@ test("a failed Hub create removes its auto-created worktree", async () => {
expect(await hub.listedWorktrees()).toHaveLength(1);
expect(await hub.durableOwnedAgentIds()).toEqual([]);
});
test("a Hub create fails when its initial prompt cannot start", async () => {
const hub = await launchRelationship();
hub.failNextProviderPromptStart();
hub.beginOwnedCreate("failed-prompt-create", "failed-prompt-execution");
const response = await hub.ownedCreateResult("failed-prompt-create");
expect(response).toMatchObject({
type: "hub.agent.create.response",
payload: { success: false, executionId: "failed-prompt-execution" },
});
expect(await hub.durableOwnedAgentIds()).toEqual([]);
});
@@ -137,6 +137,7 @@ export class RelationshipOwnedExecutions implements HubExecutions {
provider: input.model ? `${input.provider}/${input.model}` : input.provider,
title: input.prompt,
initialPrompt: input.prompt,
promptFailure: "throw",
cwd: input.cwd,
workspaceId: input.workspaceId,
mode: input.modeId,
@@ -156,7 +157,11 @@ export class RelationshipOwnedExecutions implements HubExecutions {
},
});
} catch (error) {
await this.cleanupFailedCreate({ createdWorktree, createdAgentId });
if (createdAgentId) {
await this.agentManager.closeAgent(createdAgentId);
await this.agentStorage.remove(createdAgentId);
}
await this.cleanupFailedCreate({ createdWorktree, createdAgentId: null });
throw error;
}
@@ -424,12 +424,19 @@ export class HubRelationshipHarness {
private host = "";
private readonly logs: string[] = [];
private readonly providerPrompts: AgentPromptInput[] = [];
private failNextPromptStart = false;
private observedEnrollments = 0;
private observedSockets = 0;
private reconcileRequests = 0;
private readonly codex = new ControlledAgentClient(
createTestAgentClients({
onStartTurn: (prompt) => this.providerPrompts.push(prompt),
onStartTurn: (prompt) => {
if (this.failNextPromptStart) {
this.failNextPromptStart = false;
throw new Error("Requested provider prompt startup failure");
}
this.providerPrompts.push(prompt);
},
}).codex,
);
@@ -534,6 +541,10 @@ export class HubRelationshipHarness {
this.remote.failRevocations(count);
}
failNextProviderPromptStart(): void {
this.failNextPromptStart = true;
}
async socketDialed(): Promise<void> {
await this.remote.socketAt(this.observedSockets++);
}