mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-31 14:16:39 +01:00
fix(server): signal native milestone projection changes
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
56ead750d3
commit
883d45fbc3
6 files changed
+159
-10
No files matched your search
@@ -1,3 +1,4 @@
|
||||
import { notifyChatRunMilestones } from "../chat-run-milestone-notifications.js";
|
||||
import { and, eq, inArray, ne, sql } from "drizzle-orm";
|
||||
import {
|
||||
agents,
|
||||
@@ -573,20 +574,28 @@ export async function restoreNativeChatReviewPresentationInTransaction(
|
||||
assessmentId: input.assessmentId,
|
||||
externalChatReviewPresentation: { ...proof, decisionId: input.decisionId },
|
||||
};
|
||||
const runOwner = and(
|
||||
eq(heartbeatRuns.id, input.runId),
|
||||
eq(heartbeatRuns.companyId, input.companyId),
|
||||
eq(heartbeatRuns.nativeIssueId, input.issueId),
|
||||
eq(heartbeatRuns.runtimeMode, "native"),
|
||||
);
|
||||
const projectedResult = sql`coalesce(${heartbeatRuns.resultJson}, '{}'::jsonb) || ${JSON.stringify(projection)}::jsonb`;
|
||||
const [run] = await db.select({
|
||||
needsUpdate: sql<boolean>`${projectedResult} is distinct from ${heartbeatRuns.resultJson}`,
|
||||
}).from(heartbeatRuns).where(runOwner).for("update");
|
||||
if (!run) return false;
|
||||
// A valid existing projection still permits the caller to materialize its
|
||||
// response. Replaying recovery must not rewrite it or signal another scan.
|
||||
if (!run.needsUpdate) return true;
|
||||
await notifyChatRunMilestones(db, input);
|
||||
const [updated] = await db
|
||||
.update(heartbeatRuns)
|
||||
.set({
|
||||
resultJson: sql`coalesce(${heartbeatRuns.resultJson}, '{}'::jsonb) || ${JSON.stringify(projection)}::jsonb`,
|
||||
resultJson: projectedResult,
|
||||
updatedAt: new Date(),
|
||||
})
|
||||
.where(
|
||||
and(
|
||||
eq(heartbeatRuns.id, input.runId),
|
||||
eq(heartbeatRuns.companyId, input.companyId),
|
||||
eq(heartbeatRuns.nativeIssueId, input.issueId),
|
||||
eq(heartbeatRuns.runtimeMode, "native"),
|
||||
),
|
||||
)
|
||||
.where(runOwner)
|
||||
.returning({ id: heartbeatRuns.id });
|
||||
return Boolean(updated);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { pendingNativeGovernance } from "./native-governance.js";
|
||||
import { notifyChatRunMilestones } from "../chat-run-milestone-notifications.js";
|
||||
import { notifyExecutionRunWork } from "../execution-control-notifications.js";
|
||||
import { reconcileMuseNativeTerminalRun } from "./muse-terminal-reconciliation.js";
|
||||
import { assertNativeCaseHandoffResult } from "./native-case-handoff.js";
|
||||
@@ -376,6 +377,7 @@ async function recordRetryableFailure(input: {
|
||||
: input.failureCode;
|
||||
if (phase === "terminal_failure") await notifyDeliveryWork(tx, DELIVERY_QUEUES.accounting, input.run.companyId);
|
||||
await notifyExecutionRunWork(tx);
|
||||
await notifyChatRunMilestones(tx, { companyId: input.run.companyId, issueId: input.coordinator.issueId });
|
||||
await tx
|
||||
.update(nativeRunFinalizations)
|
||||
.set({
|
||||
@@ -665,6 +667,7 @@ async function projectCommittedRun(input: {
|
||||
const tx = transaction as unknown as Db;
|
||||
await notifyDeliveryWork(tx, DELIVERY_QUEUES.accounting, input.run.companyId);
|
||||
await notifyExecutionRunWork(tx);
|
||||
await notifyChatRunMilestones(tx, { companyId: input.run.companyId, issueId: input.coordinator.issueId });
|
||||
return tx
|
||||
.update(heartbeatRuns)
|
||||
.set({
|
||||
@@ -938,6 +941,7 @@ export async function repairCommittedNativeChatResponse(
|
||||
const authorizationReason = await resolveChatRunPresentationAuthorizationReason(tx, input);
|
||||
const resolved = resolveHeartbeatRunResponse({ resultJson: monitorResult });
|
||||
if (!resolved.text) return false;
|
||||
await notifyChatRunMilestones(tx, input);
|
||||
const comment = await issueService(db).addComment(input.issueId, resolved.text,
|
||||
{ agentId: run.agentId, runId: run.id }, { authorizationReason, completionReply: true }, tx);
|
||||
await tx.update(heartbeatRuns).set({
|
||||
@@ -992,6 +996,7 @@ export async function repairCommittedNativeChatResponse(
|
||||
finalAgentMessage,
|
||||
});
|
||||
if (!resolved.text || resolved.decision.commentAction !== "create") return false;
|
||||
await notifyChatRunMilestones(tx, input);
|
||||
const comment = await issueService(db).addComment(input.issueId, resolved.text,
|
||||
{ agentId: run.agentId, runId: run.id },
|
||||
{ authorizationReason: "internal_agent_write", completionReply: true }, tx);
|
||||
@@ -1035,6 +1040,7 @@ export async function repairCommittedNativeChatResponse(
|
||||
});
|
||||
if (!resolved.text || resolved.decision.commentAction !== "create")
|
||||
return false;
|
||||
await notifyChatRunMilestones(tx, input);
|
||||
const comment = await issueService(db).addComment(
|
||||
input.issueId,
|
||||
resolved.text,
|
||||
@@ -1597,6 +1603,7 @@ export async function finalizeNativeRun(input: {
|
||||
const tx = transaction as unknown as Db;
|
||||
if (input.projectRunStatus) await notifyDeliveryWork(tx, DELIVERY_QUEUES.accounting, run.companyId);
|
||||
await notifyExecutionRunWork(tx);
|
||||
await notifyChatRunMilestones(tx, { companyId: run.companyId, issueId: coordinator.issueId });
|
||||
return projectRun(tx);
|
||||
});
|
||||
if (
|
||||
|
||||
Reference in new issue
Block a user