mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-17 20:09:05 +02:00
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:
1 parent
4bdbee9100
commit
646795e8f9
3 files changed
+24
-7
No files matched your search
@@ -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");
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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("");
|
||||
|
||||
Reference in new issue
Block a user