|
1 | 1 | import { type CommandFlags } from '../../core/dispatch.ts'; |
2 | | -import type { DaemonRequest, DaemonResponse, SessionAction } from '../../daemon/types.ts'; |
| 2 | +import type { DaemonRequest, DaemonResponse } from '../../daemon/types.ts'; |
3 | 3 | import { getSnapshotReferenceFrame } from '../../daemon/touch-reference-frame.ts'; |
4 | 4 | import { |
5 | | - batchStepToSessionAction, |
| 5 | + batchStepsToSessionActions, |
| 6 | + invokeReplayActionBlock, |
| 7 | + invokeReplayRetryBlock, |
| 8 | +} from '../../replay/control-flow-runtime.ts'; |
| 9 | +import { |
6 | 10 | captureMaestroRawSnapshot, |
7 | 11 | errorResponse, |
8 | 12 | readSnapshotState, |
@@ -53,16 +57,13 @@ export async function invokeMaestroRetry(params: { |
53 | 57 | return errorResponse('INVALID_ARGS', 'retry.maxRetries must be a non-negative integer.'); |
54 | 58 | } |
55 | 59 |
|
56 | | - const steps = (params.batchSteps ?? []).map(batchStepToSessionAction); |
57 | | - let lastResponse: DaemonResponse | undefined; |
58 | | - for (let attempt = 0; attempt <= maxRetries; attempt += 1) { |
59 | | - const response = await invokeMaestroRetryAttempt(params, steps, attempt); |
60 | | - if (response.ok) { |
61 | | - return { ok: true, data: { attempts: attempt + 1, retried: attempt > 0 } }; |
62 | | - } |
63 | | - lastResponse = response; |
64 | | - } |
65 | | - return lastResponse ?? errorResponse('COMMAND_FAILED', 'retry commands failed.'); |
| 60 | + return await invokeReplayRetryBlock({ |
| 61 | + actions: batchStepsToSessionActions(params.batchSteps), |
| 62 | + maxRetries, |
| 63 | + line: params.line, |
| 64 | + step: params.step, |
| 65 | + invokeReplayAction: params.invokeReplayAction, |
| 66 | + }); |
66 | 67 | } |
67 | 68 |
|
68 | 69 | function readMaestroRunFlowWhenCondition(positionals: string[]): MaestroRunFlowWhenCondition { |
@@ -118,40 +119,16 @@ async function invokeMaestroRunFlowWhenSteps( |
118 | 119 | }, |
119 | 120 | condition: Extract<MaestroRunFlowWhenCondition, { ok: true }>, |
120 | 121 | ): Promise<DaemonResponse> { |
121 | | - const steps = (params.batchSteps ?? []).map(batchStepToSessionAction); |
122 | | - for (const [index, action] of steps.entries()) { |
123 | | - // Preserve stable parent-step ordering for nested runtime commands while |
124 | | - // keeping the substep distinguishable in traces. |
125 | | - const response = await params.invokeReplayAction({ |
126 | | - action, |
127 | | - line: params.line, |
128 | | - step: params.step + index / 1000, |
129 | | - }); |
130 | | - if (!response.ok) return response; |
131 | | - } |
| 122 | + const response = await invokeReplayActionBlock({ |
| 123 | + actions: batchStepsToSessionActions(params.batchSteps), |
| 124 | + line: params.line, |
| 125 | + step: params.step, |
| 126 | + invokeReplayAction: params.invokeReplayAction, |
| 127 | + }); |
| 128 | + if (!response.ok) return response; |
132 | 129 |
|
133 | 130 | return { |
134 | 131 | ok: true, |
135 | | - data: { ran: steps.length, condition: condition.mode, selector: condition.selector }, |
| 132 | + data: { ran: response.data?.ran, condition: condition.mode, selector: condition.selector }, |
136 | 133 | }; |
137 | 134 | } |
138 | | - |
139 | | -async function invokeMaestroRetryAttempt( |
140 | | - params: { |
141 | | - line: number; |
142 | | - step: number; |
143 | | - invokeReplayAction: MaestroReplayInvoker; |
144 | | - }, |
145 | | - steps: SessionAction[], |
146 | | - attempt: number, |
147 | | -): Promise<DaemonResponse> { |
148 | | - for (const [index, action] of steps.entries()) { |
149 | | - const response = await params.invokeReplayAction({ |
150 | | - action, |
151 | | - line: params.line, |
152 | | - step: params.step + attempt + index / 1000, |
153 | | - }); |
154 | | - if (!response.ok) return response; |
155 | | - } |
156 | | - return { ok: true, data: { ran: steps.length } }; |
157 | | -} |
0 commit comments