mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-01 06:42:06 +01:00
Preserve accepted messages for paused recipients (#16679)
Keep accepted deferred requests pending while their recipient is paused and deliver through normal gates after resume. Preserve company, task hold, and cleanup checks. Verification: 247 focused checks, recursive typecheck, the full CI test and build matrix, and Apex 5/5. The local Git fixture initial-branch limitation is documented in the PR. Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
391dd15ff2
commit
d30648dee8
11 files changed
+133
-8
No files matched your search
@@ -152,12 +152,12 @@ async function runReleaseDrain(
|
||||
// The `processedWakeIds` guard below makes a break of the invariant
|
||||
// fail loudly, instead of holding this transaction open forever.
|
||||
const processedWakeIds = new Set<string>();
|
||||
const handoffWakeIds: string[] = [];
|
||||
const preservedWakeIds: string[] = [];
|
||||
|
||||
while (true) {
|
||||
const candidate = await ports.transaction.findNextDeferredWake({
|
||||
companyId: run.companyId, issueId: issue.id,
|
||||
...(handoffWakeIds.length ? { excludedWakeIds: handoffWakeIds } : {}),
|
||||
...(preservedWakeIds.length ? { excludedWakeIds: preservedWakeIds } : {}),
|
||||
});
|
||||
if (!candidate) break;
|
||||
if (processedWakeIds.has(candidate.id)) {
|
||||
@@ -205,7 +205,7 @@ async function runReleaseDrain(
|
||||
// The old owner can release before assignment admission adopts these
|
||||
// exact IDs. Leave its receipt intact, skip it for this drain, and let
|
||||
// a current-assignee wake behind it proceed.
|
||||
handoffWakeIds.push(candidate.id);
|
||||
preservedWakeIds.push(candidate.id);
|
||||
} else {
|
||||
// The current owner has finished. An obsolete assignment cannot
|
||||
// launch another former-owner run or reopen its completed task.
|
||||
@@ -283,7 +283,7 @@ async function runReleaseDrain(
|
||||
|
||||
// A comment-id rewrite cannot change the agent or pause-hold facts already fetched above, so one decision covers both the rewritten and un-rewritten cases.
|
||||
const wakeOutcome = decideWakeOutcome({
|
||||
agent: { agentFound: deferredAgent !== null, invokable: deferredAgent?.invokable ?? false },
|
||||
agent: { agentFound: deferredAgent !== null, invokable: deferredAgent?.invokable ?? false, paused: deferredAgent?.paused === true },
|
||||
pauseHold: { activePauseHold: pauseHold.activePauseHold, treeHoldInteractionWake: pauseHold.treeHoldInteractionWake },
|
||||
});
|
||||
|
||||
@@ -292,6 +292,11 @@ async function runReleaseDrain(
|
||||
continue;
|
||||
}
|
||||
|
||||
if (wakeOutcome.kind === "defer_agent_pause") {
|
||||
preservedWakeIds.push(workingCandidate.id);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (wakeOutcome.kind === "cancel_pause_hold") {
|
||||
await ports.transaction.cancelDeferredWake({
|
||||
companyId: run.companyId,
|
||||
|
||||
Reference in new issue
Block a user