Skip to content

Commit 04033f3

Browse files
committed
fix(workflows): count repeated review completion once
1 parent 03520e2 commit 04033f3

2 files changed

Lines changed: 27 additions & 7 deletions

File tree

apps/sim/lib/workflows/executor/human-in-the-loop-manager.test.ts

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2060,19 +2060,28 @@ describe('repeated human review pauses', () => {
20602060
).toBe(true)
20612061
})
20622062

2063-
it('settles the answered context when the same run pauses at its next question', async () => {
2063+
it('settles the answered context exactly once when the same run pauses again', async () => {
20642064
const runSpy = vi
20652065
.spyOn(PauseResumeManager as unknown as PauseResumeManagerInternals, 'runResumeExecution')
20662066
.mockResolvedValueOnce({
20672067
status: 'paused',
20682068
success: true,
20692069
metadata: { executionId: 'durable-run' },
20702070
snapshotSeed: createSnapshotSeed(),
2071-
pausePoints: [{ contextId: 'hitl_loop1', blockId: 'hitl' }],
2071+
pausePoints: [{ contextId: 'hitl_loop1', blockId: 'hitl', resumeStatus: 'paused' }],
20722072
})
2073-
const persistSpy = vi
2074-
.spyOn(PauseResumeManager, 'persistPauseResult')
2075-
.mockResolvedValueOnce(undefined)
2073+
const persistSpy = vi.spyOn(PauseResumeManager, 'persistPauseResult')
2074+
dbChainMockFns.limit.mockResolvedValueOnce([{ status: 'running' }]).mockResolvedValueOnce([
2075+
{
2076+
id: 'pause-1',
2077+
executionId: 'durable-run',
2078+
status: 'paused',
2079+
metadata: {},
2080+
pausePoints: {
2081+
hitl_loop0: { contextId: 'hitl_loop0', blockId: 'hitl', resumeStatus: 'resuming' },
2082+
},
2083+
},
2084+
])
20762085
const completeSpy = vi
20772086
.spyOn(
20782087
PauseResumeManager as unknown as {
@@ -2105,7 +2114,18 @@ describe('repeated human review pauses', () => {
21052114
expect(completeSpy).toHaveBeenCalledWith(
21062115
expect.objectContaining({
21072116
parentExecutionId: 'durable-run',
2108-
contextId: 'hitl_loop0',
2117+
})
2118+
)
2119+
expect(completeSpy.mock.calls[0][0]).not.toHaveProperty('contextId')
2120+
expect(dbChainMockFns.set).toHaveBeenCalledWith(
2121+
expect.objectContaining({
2122+
resumedCount: 1,
2123+
totalPauseCount: 2,
2124+
status: 'partially_resumed',
2125+
pausePoints: expect.objectContaining({
2126+
hitl_loop0: expect.objectContaining({ resumeStatus: 'resumed' }),
2127+
hitl_loop1: expect.objectContaining({ resumeStatus: 'paused' }),
2128+
}),
21092129
})
21102130
)
21112131
} finally {

apps/sim/lib/workflows/executor/human-in-the-loop-manager.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -969,11 +969,11 @@ export class PauseResumeManager {
969969
}
970970

971971
if (result.status === 'paused') {
972+
/** persistPauseResult already settles the answered context and recounts the merged pauses. */
972973
await PauseResumeManager.markResumeCompleted({
973974
resumeEntryId,
974975
pausedExecutionId: pausedExecution.id,
975976
parentExecutionId: pausedExecution.executionId,
976-
contextId,
977977
})
978978
}
979979

0 commit comments

Comments
 (0)