mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-10 12:37:55 +01:00
fix(native): let a run blocked for a rejected model be retried
The status arbiter already blocks the task for a model choice. The release path then opened a native reconciliation incident because the task was blocked, which put the run in recovery_needed and hid its Retry. A rejected model or incomplete configuration has no execution to reconcile; release without the incident. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d22e4962f9
commit
3178ef875a
2 files changed
+19
No files matched your search
@@ -780,6 +780,18 @@ describeEmbeddedPostgres("wake-queue postgres adapter", () => {
|
||||
expect((await db.select().from(issues).where(eq(issues.id, issueId)))[0].statusVersion).toBe(blockedIssue.statusVersion);
|
||||
});
|
||||
|
||||
it("does not open a reconciliation incident for a native run whose model the provider rejected", async () => {
|
||||
const companyId = await seedCompany();
|
||||
const agentId = await seedAgent({ companyId });
|
||||
const issueId = await seedIssue({ companyId, assigneeAgentId: agentId, status: "blocked" });
|
||||
const runId = await seedRun({ companyId, agentId, status: "failed", contextSnapshot: { issueId } });
|
||||
await db.update(heartbeatRuns).set({ runtimeMode: "native", errorCode: "native_provider_model_rejected" }).where(eq(heartbeatRuns.id, runId));
|
||||
const adapter = createPostgresWakeQueueAdapter(db, stubDeps);
|
||||
await adapter.withIssueExecutionLock({ companyId, runId, now: new Date() }, async () => { throw new Error("must not restart a rejected model"); });
|
||||
expect((await db.select().from(issues).where(eq(issues.id, issueId)))[0].status).toBe("blocked");
|
||||
expect(await db.select().from(issueRecoveryActions).where(eq(issueRecoveryActions.sourceIssueId, issueId))).toHaveLength(0);
|
||||
});
|
||||
|
||||
it.each(["active", "escalated"])("repairs a failed native task with an existing %s recovery action", async (status) => {
|
||||
const companyId = await seedCompany();
|
||||
const agentId = await seedAgent({ companyId });
|
||||
|
||||
@@ -1369,6 +1369,13 @@ export function createPostgresWakeQueueAdapter(db: Db, deps: WakeQueuePostgresAd
|
||||
};
|
||||
}
|
||||
|
||||
// A native run blocked for a rejected model or incomplete configuration waits for that
|
||||
// change and a retry. The provider refused the request, so there is no execution to
|
||||
// reconcile; a reconciliation incident would also hide the run's Retry.
|
||||
if (!handoffAssigneeAgentId && run.runtimeMode === "native" && isConfigurationIncompleteFailedRun(run)
|
||||
&& issueRow.status === "blocked" && issueRow.assigneeAgentId === run.agentId) {
|
||||
return { outcome: { kind: "released" }, postCommitEffects: [], run: runSnapshot };
|
||||
}
|
||||
if (!handoffAssigneeAgentId && await recordNativeTerminalRecoveryIfNeeded(tx, run, issueRow, input.now)) {
|
||||
return { outcome: { kind: "released" }, postCommitEffects: [], run: runSnapshot };
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user