(
args,
label,
predicate,
failureMessage,
options = {},
)
| 836 | } |
| 837 | |
| 838 | async function retrySimdeckTextUntil( |
| 839 | args, |
| 840 | label, |
| 841 | predicate, |
| 842 | failureMessage, |
| 843 | options = {}, |
| 844 | ) { |
| 845 | const attempts = options.attempts ?? 4; |
| 846 | const delayMs = options.delayMs ?? 2_000; |
| 847 | let lastDetail = ""; |
| 848 | for (let attempt = 1; attempt <= attempts; attempt += 1) { |
| 849 | try { |
| 850 | const output = await retrySimdeckText(args, label, { |
| 851 | ...options, |
| 852 | attempts: 1, |
| 853 | }); |
| 854 | if (predicate(output)) { |
| 855 | return output; |
| 856 | } |
| 857 | lastDetail = summarizeText(output); |
| 858 | } catch (error) { |
| 859 | lastDetail = error?.message ?? String(error); |
| 860 | } |
| 861 | if (attempt < attempts) { |
| 862 | logStep(`${label} attempt ${attempt}/${attempts} did not pass; retrying`); |
| 863 | await sleep(delayMs); |
| 864 | } |
| 865 | } |
| 866 | throw new Error( |
| 867 | `${failureMessage} after ${attempts} attempts:\n${lastDetail}`, |
| 868 | ); |
| 869 | } |
| 870 | |
| 871 | function looksLikeAgentHierarchy(output) { |
| 872 | return output.includes("source:") && output.includes("- "); |
no test coverage detected