Wait for the selected native response in live qualification

Hydrate the final run receipt while polling persisted comments so an earlier deliverable-preparation comment cannot end the response consistency wait.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-10-06 10:03:49 -05:00
1 parent 4bdbee9100
commit 646795e8f9
3 files changed
+24 -7

No files matched your search

+4 -1
View File
@@ -172,7 +172,7 @@ export async function evaluateMatchers(
export function persistedFinalRunMessage(
comments: Array<{ id: string; createdByRunId?: string | null; body?: string | null }>,
run: { id: string; resultJson?: Record<string, unknown> | null },
run: { id: string; runtimeMode?: string; resultJson?: Record<string, unknown> | null },
): string {
const runComments = comments.filter(comment => comment.createdByRunId === run.id);
const decision = run.resultJson?.presentationDecision;
@@ -183,5 +183,8 @@ export function persistedFinalRunMessage(
if (typeof selectedId === "string") {
return runComments.find(comment => comment.id === selectedId)?.body ?? "";
}
// Native finalization can publish a deliverable-preparation comment before
// its response decision. That earlier comment is not the selected reply.
if (run.runtimeMode === "native") return "";
return runComments.map(comment => comment.body ?? "").join("\n");
}
+13 -6
View File
@@ -1858,17 +1858,24 @@ for (const execution of executions) {
terminal = await pollUntil({
label: `final agent comment for issue ${issue.id}`,
deadlineAt: Math.min(deadlineAt, Date.now() + 30_000),
load: loadTaskState,
load: async () => {
const state = await loadTaskState();
const finalRun = sortRunsChronologically(state.taskRuns).at(-1);
if (!finalRun) return state;
// The compact run list omits the native presentation receipt.
// Poll its public detail together with comments so an earlier
// deliverable-preparation comment cannot settle this wait.
const detailed = await api.get<RunRecord>(`/api/heartbeat-runs/${finalRun.id}`);
return { ...state, taskRuns: state.taskRuns.map(run => run.id === detailed.id ? detailed : run) };
},
accept: ({ taskRuns, comments }) => {
if (!matchesRunCount(execution.task, taskRuns.length)) {
return false;
}
const finalRun = sortRunsChronologically(taskRuns).at(-1);
return comments.some(
(comment) =>
comment.createdByRunId === finalRun?.id &&
comment.authorAgentId === fixtures!.agent.id,
);
return Boolean(finalRun && persistedFinalRunMessage(
comments.filter(comment => comment.authorAgentId === fixtures!.agent.id), finalRun,
).trim());
},
reject: ({ taskRuns }) => definitiveRunFailure(taskRuns),
}).catch(() => terminal);
+7
View File
@@ -1431,6 +1431,13 @@ describe("persisted final response selection", () => {
expect(persistedFinalRunMessage(comments.slice(0, 1), run)).toBe("");
expect(persistedFinalRunMessage(comments, { ...run, resultJson: { presentationDecision: { commentId: "other-run" } } })).toBe("");
});
it("waits for the native response receipt and its selected comment, not an earlier attachment comment", () => {
const native = { ...run, runtimeMode: "native" };
expect(persistedFinalRunMessage(comments.slice(0, 1), { id: native.id, runtimeMode: "native" })).toBe("");
expect(persistedFinalRunMessage(comments, { id: native.id, runtimeMode: "native", resultJson: { summary: "FINAL" } })).toBe("");
expect(persistedFinalRunMessage(comments.slice(0, 1), native)).toBe("");
expect(persistedFinalRunMessage(comments, native)).toBe("FINAL");
});
it("keeps legacy fallback and does not replace absent visible text with a summary", () => {
expect(persistedFinalRunMessage(comments, { id: "run-1" })).toBe("Prepared file for this response.\nFINAL");
expect(persistedFinalRunMessage([], { id: "run-1", resultJson: { summary: "FINAL" } })).toBe("");