@promptbook/cli 0.112.0-128 → 0.112.0-129
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apps/agents-server/src/middleware/resolveAccessControlResponse.ts +3 -2
- package/apps/agents-server/src/middleware/resolveMiddlewareResponse.ts +8 -3
- package/apps/agents-server/src/middleware.ts +14 -0
- package/esm/index.es.js +285 -95
- package/esm/index.es.js.map +1 -1
- package/esm/scripts/run-codex-prompts/common/sleepWithCountdown.d.ts +27 -0
- package/esm/src/cli/cli-commands/coder/waitOptions.d.ts +14 -0
- package/esm/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/cli/cli-commands/coder/run.ts +38 -10
- package/src/cli/cli-commands/coder/server.ts +31 -8
- package/src/cli/cli-commands/coder/waitOptions.ts +24 -0
- package/src/other/templates/getTemplatesPipelineCollection.ts +993 -687
- package/src/version.ts +2 -2
- package/src/versions.txt +1 -0
- package/umd/index.umd.js +285 -95
- package/umd/index.umd.js.map +1 -1
- package/umd/scripts/run-codex-prompts/common/sleepWithCountdown.d.ts +27 -0
- package/umd/src/cli/cli-commands/coder/waitOptions.d.ts +14 -0
- package/umd/src/version.d.ts +1 -1
package/esm/index.es.js
CHANGED
|
@@ -58,7 +58,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
|
|
|
58
58
|
* @generated
|
|
59
59
|
* @see https://github.com/webgptorg/promptbook
|
|
60
60
|
*/
|
|
61
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-
|
|
61
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-129';
|
|
62
62
|
/**
|
|
63
63
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
64
64
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -5192,7 +5192,9 @@ function createCoderRunOptionsForAgent(options) {
|
|
|
5192
5192
|
noUi: options.noUi,
|
|
5193
5193
|
thinkingLevel: options.thinkingLevel,
|
|
5194
5194
|
waitForUser: false,
|
|
5195
|
+
waitAfterPrompt: 0,
|
|
5195
5196
|
waitBetweenPrompts: 0,
|
|
5197
|
+
waitAfterError: 0,
|
|
5196
5198
|
noCommit: options.noCommit,
|
|
5197
5199
|
ignoreGitChanges: options.ignoreGitChanges,
|
|
5198
5200
|
normalizeLineEndings: options.normalizeLineEndings,
|
|
@@ -39922,6 +39924,27 @@ function formatDurationMs(ms) {
|
|
|
39922
39924
|
return parts.join(' ');
|
|
39923
39925
|
}
|
|
39924
39926
|
|
|
39927
|
+
/**
|
|
39928
|
+
* Default wait duration applied before retrying a prompt round after an error (10 minutes).
|
|
39929
|
+
*
|
|
39930
|
+
* @private internal constant of `ptbk coder` wait handling
|
|
39931
|
+
*/
|
|
39932
|
+
const DEFAULT_WAIT_AFTER_ERROR_MS$1 = 10 * 60 * 1000;
|
|
39933
|
+
/**
|
|
39934
|
+
* Parses an optional Commander duration string and returns the resolved milliseconds.
|
|
39935
|
+
*
|
|
39936
|
+
* Returns `defaultMs` when the flag was not provided or was provided without a non-empty value.
|
|
39937
|
+
*
|
|
39938
|
+
* @private internal utility of `ptbk coder` wait handling
|
|
39939
|
+
*/
|
|
39940
|
+
function parseOptionalWaitDuration(value, defaultMs) {
|
|
39941
|
+
if (typeof value !== 'string' || value === '') {
|
|
39942
|
+
return defaultMs;
|
|
39943
|
+
}
|
|
39944
|
+
return parseDuration(value);
|
|
39945
|
+
}
|
|
39946
|
+
// Note: [💞] Ignore a discrepancy between file name and entity name
|
|
39947
|
+
|
|
39925
39948
|
/**
|
|
39926
39949
|
* Initializes `coder run` command for Promptbook CLI utilities
|
|
39927
39950
|
*
|
|
@@ -39955,31 +39978,46 @@ function $initializeCoderRunCommand(program) {
|
|
|
39955
39978
|
command.option('--preserve-logs', 'Keep generated temp prompt/log artifacts after successful rounds for debugging and analytics', false);
|
|
39956
39979
|
addPromptRunnerExecutionOptions(command);
|
|
39957
39980
|
command.option('--priority <minimum-priority>', 'Filter prompts by minimum priority level', parseIntOption$1, 0);
|
|
39958
|
-
command.option('--wait <duration>', spaceTrim$1(`
|
|
39959
|
-
Wait this long
|
|
39960
|
-
Accepts durations like 1h, 30m, 5s.
|
|
39981
|
+
command.option('--wait-after-prompt <duration>', spaceTrim$1(`
|
|
39982
|
+
Wait this long after each prompt has been implemented, verified and committed before starting the next prompt.
|
|
39983
|
+
Accepts durations like 1h, 30m, 5s. Defaults to 0 (no wait).
|
|
39984
|
+
`));
|
|
39985
|
+
command.option('--wait-between-prompts <duration>', spaceTrim$1(`
|
|
39986
|
+
Pace prompts so that each next prompt starts at least this long after the previous one began.
|
|
39987
|
+
If the previous prompt already took longer than this, the next prompt starts immediately.
|
|
39988
|
+
Accepts durations like 1h, 30m, 5s. Defaults to 0 (no pacing).
|
|
39989
|
+
`));
|
|
39990
|
+
command.option('--wait-after-error <duration>', spaceTrim$1(`
|
|
39991
|
+
Wait this long before retrying a prompt after an error occurs (up to 3 retries before giving up).
|
|
39992
|
+
Accepts durations like 1h, 30m, 5s. Defaults to 10m.
|
|
39961
39993
|
`));
|
|
39962
39994
|
// Note: --no-auto disables the default auto behaviour and waits for user confirmation before each prompt
|
|
39963
39995
|
command.option('--no-auto', 'Wait for user confirmation before each prompt instead of running automatically through the queue');
|
|
39964
39996
|
command.option('--auto-migrate', 'Run testing-server database migrations automatically after each successfully processed prompt');
|
|
39965
39997
|
command.option('--allow-destructive-auto-migrate', 'Allow auto-migrate even when heuristic SQL safety check flags destructive pending migrations');
|
|
39966
39998
|
command.action(handleActionErrors(async (cliOptions) => {
|
|
39967
|
-
const { dryRun, agent, context, test, preserveLogs, priority,
|
|
39999
|
+
const { dryRun, agent, context, test, preserveLogs, priority, waitAfterPrompt: waitAfterPromptValue, waitBetweenPrompts: waitBetweenPromptsValue, waitAfterError: waitAfterErrorValue, auto, autoMigrate, allowDestructiveAutoMigrate, } = cliOptions;
|
|
39968
40000
|
const testCommand = normalizeCommandOptionValue$1(test);
|
|
39969
40001
|
const runnerOptions = normalizePromptRunnerCliOptions(cliOptions, {
|
|
39970
40002
|
isAgentRequired: !dryRun,
|
|
39971
40003
|
});
|
|
39972
|
-
// [1] Parse the
|
|
39973
|
-
// default: run automatically through the queue (no waiting)
|
|
40004
|
+
// [1] Parse the wait options and --no-auto:
|
|
40005
|
+
// default: run automatically through the queue (no waiting between prompts)
|
|
39974
40006
|
// --no-auto: wait for user confirmation before each prompt (interactive mode)
|
|
39975
|
-
// --wait
|
|
40007
|
+
// --wait-after-prompt: pause after a successful round before starting the next prompt
|
|
40008
|
+
// --wait-between-prompts: pace from start of one prompt to start of next
|
|
40009
|
+
// --wait-after-error: wait before retrying after an error (default 10m)
|
|
39976
40010
|
const waitForUser = !auto;
|
|
39977
|
-
const
|
|
40011
|
+
const waitAfterPrompt = parseOptionalWaitDuration(waitAfterPromptValue, 0);
|
|
40012
|
+
const waitBetweenPrompts = parseOptionalWaitDuration(waitBetweenPromptsValue, 0);
|
|
40013
|
+
const waitAfterError = parseOptionalWaitDuration(waitAfterErrorValue, DEFAULT_WAIT_AFTER_ERROR_MS$1);
|
|
39978
40014
|
// Convert commander options to RunOptions format
|
|
39979
40015
|
const runOptions = {
|
|
39980
40016
|
dryRun,
|
|
39981
40017
|
waitForUser,
|
|
40018
|
+
waitAfterPrompt,
|
|
39982
40019
|
waitBetweenPrompts,
|
|
40020
|
+
waitAfterError,
|
|
39983
40021
|
noCommit: runnerOptions.noCommit,
|
|
39984
40022
|
ignoreGitChanges: runnerOptions.ignoreGitChanges,
|
|
39985
40023
|
agentName: runnerOptions.agentName,
|
|
@@ -40087,28 +40125,41 @@ function $initializeCoderServerCommand(program) {
|
|
|
40087
40125
|
command.option('--preserve-logs', 'Keep generated temp prompt/log artifacts after successful rounds for debugging and analytics', false);
|
|
40088
40126
|
addPromptRunnerExecutionOptions(command);
|
|
40089
40127
|
command.option('--priority <minimum-priority>', 'Filter prompts by minimum priority level', parseIntOption, 0);
|
|
40090
|
-
command.option('--wait <duration>', spaceTrim$1(`
|
|
40091
|
-
Wait this long
|
|
40092
|
-
Accepts durations like 1h, 30m, 5s.
|
|
40128
|
+
command.option('--wait-after-prompt <duration>', spaceTrim$1(`
|
|
40129
|
+
Wait this long after each prompt has been implemented, verified and committed before starting the next prompt.
|
|
40130
|
+
Accepts durations like 1h, 30m, 5s. Defaults to 0 (no wait).
|
|
40131
|
+
`));
|
|
40132
|
+
command.option('--wait-between-prompts <duration>', spaceTrim$1(`
|
|
40133
|
+
Pace prompts so that each next prompt starts at least this long after the previous one began.
|
|
40134
|
+
If the previous prompt already took longer than this, the next prompt starts immediately.
|
|
40135
|
+
Accepts durations like 1h, 30m, 5s. Defaults to 0 (no pacing).
|
|
40136
|
+
`));
|
|
40137
|
+
command.option('--wait-after-error <duration>', spaceTrim$1(`
|
|
40138
|
+
Wait this long before retrying a prompt after an error occurs (up to 3 retries before giving up).
|
|
40139
|
+
Accepts durations like 1h, 30m, 5s. Defaults to 10m.
|
|
40093
40140
|
`));
|
|
40094
40141
|
command.option('--no-auto', 'Wait for user confirmation before each prompt instead of running automatically through the queue');
|
|
40095
40142
|
command.option('--auto-migrate', 'Run testing-server database migrations automatically after each successfully processed prompt');
|
|
40096
40143
|
command.option('--allow-destructive-auto-migrate', 'Allow auto-migrate even when heuristic SQL safety check flags destructive pending migrations');
|
|
40097
40144
|
command.action(handleActionErrors(async (cliOptions) => {
|
|
40098
|
-
const { port: rawPort, dryRun, agent, context, test, preserveLogs, priority,
|
|
40145
|
+
const { port: rawPort, dryRun, agent, context, test, preserveLogs, priority, waitAfterPrompt: waitAfterPromptValue, waitBetweenPrompts: waitBetweenPromptsValue, waitAfterError: waitAfterErrorValue, auto, autoMigrate, allowDestructiveAutoMigrate, } = cliOptions;
|
|
40099
40146
|
const port = parseCoderServerPort(rawPort);
|
|
40100
40147
|
const testCommand = normalizeCommandOptionValue(test);
|
|
40101
40148
|
const runnerOptions = normalizePromptRunnerCliOptions(cliOptions, {
|
|
40102
40149
|
isAgentRequired: !dryRun,
|
|
40103
40150
|
});
|
|
40104
|
-
// [1] Parse the
|
|
40151
|
+
// [1] Parse the wait options and --no-auto (same logic as `coder run`)
|
|
40105
40152
|
const waitForUser = !auto;
|
|
40106
|
-
const
|
|
40153
|
+
const waitAfterPrompt = parseOptionalWaitDuration(waitAfterPromptValue, 0);
|
|
40154
|
+
const waitBetweenPrompts = parseOptionalWaitDuration(waitBetweenPromptsValue, 0);
|
|
40155
|
+
const waitAfterError = parseOptionalWaitDuration(waitAfterErrorValue, DEFAULT_WAIT_AFTER_ERROR_MS$1);
|
|
40107
40156
|
const runOptions = {
|
|
40108
40157
|
port,
|
|
40109
40158
|
dryRun,
|
|
40110
40159
|
waitForUser,
|
|
40160
|
+
waitAfterPrompt,
|
|
40111
40161
|
waitBetweenPrompts,
|
|
40162
|
+
waitAfterError,
|
|
40112
40163
|
noCommit: runnerOptions.noCommit,
|
|
40113
40164
|
ignoreGitChanges: runnerOptions.ignoreGitChanges,
|
|
40114
40165
|
agentName: runnerOptions.agentName,
|
|
@@ -63583,7 +63634,9 @@ function createPromptRunnerOptions(options) {
|
|
|
63583
63634
|
noUi: options.noUi,
|
|
63584
63635
|
thinkingLevel: options.thinkingLevel,
|
|
63585
63636
|
waitForUser: false,
|
|
63637
|
+
waitAfterPrompt: 0,
|
|
63586
63638
|
waitBetweenPrompts: 0,
|
|
63639
|
+
waitAfterError: 0,
|
|
63587
63640
|
noCommit: true,
|
|
63588
63641
|
ignoreGitChanges: true,
|
|
63589
63642
|
normalizeLineEndings: false,
|
|
@@ -69418,10 +69471,14 @@ var findUnwrittenPrompts$1 = /*#__PURE__*/Object.freeze({
|
|
|
69418
69471
|
findUnwrittenPrompts: findUnwrittenPrompts
|
|
69419
69472
|
});
|
|
69420
69473
|
|
|
69474
|
+
/**
|
|
69475
|
+
* Default wait duration applied before retrying a failed prompt round.
|
|
69476
|
+
*/
|
|
69477
|
+
const DEFAULT_WAIT_AFTER_ERROR_MS = 10 * 60 * 1000;
|
|
69421
69478
|
/**
|
|
69422
69479
|
* CLI usage text for this script.
|
|
69423
69480
|
*/
|
|
69424
|
-
const USAGE = 'Usage: run-codex-prompts [--dry-run] [--harness <harness-name>] [--model <model>] [--context <context-or-file>] [--test <test-command...>] [--preserve-logs] [--no-ui] [--thinking-level <thinking-level>] [--priority <minimum-priority>] [--allow-credits] [--auto-migrate] [--allow-destructive-auto-migrate] [--wait <duration>] [--no-auto] [--no-commit] [--ignore-git-changes] [--no-normalize-line-endings] [--auto-push] [--auto-pull]';
|
|
69481
|
+
const USAGE = 'Usage: run-codex-prompts [--dry-run] [--harness <harness-name>] [--model <model>] [--context <context-or-file>] [--test <test-command...>] [--preserve-logs] [--no-ui] [--thinking-level <thinking-level>] [--priority <minimum-priority>] [--allow-credits] [--auto-migrate] [--allow-destructive-auto-migrate] [--wait-after-prompt <duration>] [--wait-between-prompts <duration>] [--wait-after-error <duration>] [--no-auto] [--no-commit] [--ignore-git-changes] [--no-normalize-line-endings] [--auto-push] [--auto-pull]';
|
|
69425
69482
|
/**
|
|
69426
69483
|
* Top-level flags supported by this command.
|
|
69427
69484
|
*/
|
|
@@ -69438,7 +69495,9 @@ const KNOWN_OPTION_FLAGS = new Set([
|
|
|
69438
69495
|
'--allow-credits',
|
|
69439
69496
|
'--auto-migrate',
|
|
69440
69497
|
'--allow-destructive-auto-migrate',
|
|
69441
|
-
'--wait',
|
|
69498
|
+
'--wait-after-prompt',
|
|
69499
|
+
'--wait-between-prompts',
|
|
69500
|
+
'--wait-after-error',
|
|
69442
69501
|
'--no-auto',
|
|
69443
69502
|
'--no-commit',
|
|
69444
69503
|
'--ignore-git-changes',
|
|
@@ -69482,15 +69541,9 @@ function parseRunOptions(args) {
|
|
|
69482
69541
|
// --no-auto: wait for user confirmation before each prompt (interactive mode)
|
|
69483
69542
|
// --wait 1h: wait 1h between prompt rounds to avoid rate limits
|
|
69484
69543
|
const waitForUser = args.includes('--no-auto');
|
|
69485
|
-
|
|
69486
|
-
const
|
|
69487
|
-
const
|
|
69488
|
-
if (hasWaitFlag) {
|
|
69489
|
-
if (waitValue === undefined || waitValue.startsWith('-')) {
|
|
69490
|
-
exitWithUsageError('Missing value for --wait. Use a duration like 1h, 30m, 5s.');
|
|
69491
|
-
}
|
|
69492
|
-
waitBetweenPrompts = parseDuration(waitValue);
|
|
69493
|
-
}
|
|
69544
|
+
const waitAfterPrompt = parseWaitOption(args, '--wait-after-prompt', 0);
|
|
69545
|
+
const waitBetweenPrompts = parseWaitOption(args, '--wait-between-prompts', 0);
|
|
69546
|
+
const waitAfterError = parseWaitOption(args, '--wait-after-error', DEFAULT_WAIT_AFTER_ERROR_MS);
|
|
69494
69547
|
let thinkingLevel;
|
|
69495
69548
|
if (hasTestCommandFlag && testCommand === undefined) {
|
|
69496
69549
|
exitWithUsageError('Missing value for --test. Use a shell command such as `npm run test` and quote it when it contains top-level CLI flags.');
|
|
@@ -69510,7 +69563,9 @@ function parseRunOptions(args) {
|
|
|
69510
69563
|
return {
|
|
69511
69564
|
dryRun,
|
|
69512
69565
|
waitForUser,
|
|
69566
|
+
waitAfterPrompt,
|
|
69513
69567
|
waitBetweenPrompts,
|
|
69568
|
+
waitAfterError,
|
|
69514
69569
|
noCommit,
|
|
69515
69570
|
ignoreGitChanges,
|
|
69516
69571
|
normalizeLineEndings,
|
|
@@ -69529,6 +69584,19 @@ function parseRunOptions(args) {
|
|
|
69529
69584
|
priority,
|
|
69530
69585
|
};
|
|
69531
69586
|
}
|
|
69587
|
+
/**
|
|
69588
|
+
* Reads a duration-typed CLI flag, applying the provided default when the flag is absent.
|
|
69589
|
+
*/
|
|
69590
|
+
function parseWaitOption(args, flag, defaultMs) {
|
|
69591
|
+
if (!args.includes(flag)) {
|
|
69592
|
+
return defaultMs;
|
|
69593
|
+
}
|
|
69594
|
+
const value = readOptionValue(args, flag);
|
|
69595
|
+
if (value === undefined || value.startsWith('-')) {
|
|
69596
|
+
exitWithUsageError(`Missing value for ${flag}. Use a duration like 1h, 30m, 5s.`);
|
|
69597
|
+
}
|
|
69598
|
+
return parseDuration(value);
|
|
69599
|
+
}
|
|
69532
69600
|
/**
|
|
69533
69601
|
* Reads a value of a CLI option that follows a given flag.
|
|
69534
69602
|
*/
|
|
@@ -69765,6 +69833,58 @@ async function resolveAgentSystemMessage(agentPath, currentWorkingDirectory) {
|
|
|
69765
69833
|
return createAgentRunnerSystemMessage(agentSource);
|
|
69766
69834
|
}
|
|
69767
69835
|
|
|
69836
|
+
/**
|
|
69837
|
+
* Refresh interval used by the countdown display while waiting.
|
|
69838
|
+
*
|
|
69839
|
+
* @private internal constant of `sleepWithCountdown`
|
|
69840
|
+
*/
|
|
69841
|
+
const WAIT_COUNTDOWN_UPDATE_INTERVAL_MS = 30000;
|
|
69842
|
+
/**
|
|
69843
|
+
* Returns the human-readable status message used for one wait kind.
|
|
69844
|
+
*
|
|
69845
|
+
* @private internal utility of `sleepWithCountdown`
|
|
69846
|
+
*/
|
|
69847
|
+
function describeCoderRunWait(waitKind, remainingMs, totalMs) {
|
|
69848
|
+
const formattedRemaining = formatDurationMs(remainingMs);
|
|
69849
|
+
const formattedTotal = totalMs !== undefined ? formatDurationMs(totalMs) : undefined;
|
|
69850
|
+
const totalSuffix = formattedTotal !== undefined ? ` of ${formattedTotal}` : '';
|
|
69851
|
+
switch (waitKind) {
|
|
69852
|
+
case 'between-prompts':
|
|
69853
|
+
return `Waiting ${formattedRemaining}${totalSuffix} between prompts (paced from previous start)`;
|
|
69854
|
+
case 'after-prompt':
|
|
69855
|
+
return `Waiting ${formattedRemaining}${totalSuffix} after previous prompt`;
|
|
69856
|
+
case 'after-error':
|
|
69857
|
+
return `Waiting ${formattedRemaining}${totalSuffix} before retrying after error`;
|
|
69858
|
+
}
|
|
69859
|
+
}
|
|
69860
|
+
/**
|
|
69861
|
+
* Sleeps the requested duration while refreshing the status message on a UI handle and the plain console.
|
|
69862
|
+
*
|
|
69863
|
+
* The wait kind is shown in the UI status so the user can distinguish `--wait-after-prompt`,
|
|
69864
|
+
* `--wait-between-prompts`, and `--wait-after-error` waits at a glance.
|
|
69865
|
+
*
|
|
69866
|
+
* @public exported from `@promptbook/cli`
|
|
69867
|
+
*/
|
|
69868
|
+
async function sleepWithCountdown(options) {
|
|
69869
|
+
const { durationMs, waitKind, isRichUiEnabled, uiHandle } = options;
|
|
69870
|
+
if (durationMs <= 0) {
|
|
69871
|
+
return;
|
|
69872
|
+
}
|
|
69873
|
+
let remaining = durationMs;
|
|
69874
|
+
while (remaining > 0) {
|
|
69875
|
+
const statusMessage = describeCoderRunWait(waitKind, remaining, durationMs);
|
|
69876
|
+
if (!isRichUiEnabled) {
|
|
69877
|
+
console.info(colors.gray(`${statusMessage}...`));
|
|
69878
|
+
}
|
|
69879
|
+
else {
|
|
69880
|
+
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.setStatusMessage(`${statusMessage}...`);
|
|
69881
|
+
}
|
|
69882
|
+
const sleepMs = Math.min(WAIT_COUNTDOWN_UPDATE_INTERVAL_MS, remaining);
|
|
69883
|
+
await new Promise((resolve) => setTimeout(resolve, sleepMs));
|
|
69884
|
+
remaining -= sleepMs;
|
|
69885
|
+
}
|
|
69886
|
+
}
|
|
69887
|
+
|
|
69768
69888
|
/**
|
|
69769
69889
|
* Resolves optional coding context provided inline or via a file path.
|
|
69770
69890
|
*/
|
|
@@ -71495,6 +71615,13 @@ async function writePromptFile(file) {
|
|
|
71495
71615
|
await writeFile(file.path, content, 'utf-8');
|
|
71496
71616
|
}
|
|
71497
71617
|
|
|
71618
|
+
/**
|
|
71619
|
+
* Maximum number of retry attempts performed after a prompt round throws an error.
|
|
71620
|
+
* After this many retries the round is finalized as failed.
|
|
71621
|
+
*
|
|
71622
|
+
* @private internal constant of `runPromptRound`
|
|
71623
|
+
*/
|
|
71624
|
+
const MAX_RETRY_ATTEMPTS_AFTER_ERROR = 3;
|
|
71498
71625
|
/**
|
|
71499
71626
|
* Runs one prompt round from prompt construction through commit or failure logging.
|
|
71500
71627
|
*
|
|
@@ -71527,54 +71654,101 @@ async function runPromptRound({ options, runner, runnerMetadata, nextPrompt, pro
|
|
|
71527
71654
|
? await captureChangedFilesSnapshot(process.cwd())
|
|
71528
71655
|
: undefined;
|
|
71529
71656
|
await withPromptRuntimeLog(scriptPath, async (logPath) => {
|
|
71530
|
-
|
|
71531
|
-
|
|
71532
|
-
|
|
71533
|
-
|
|
71534
|
-
|
|
71535
|
-
|
|
71536
|
-
|
|
71537
|
-
|
|
71538
|
-
|
|
71539
|
-
|
|
71540
|
-
|
|
71541
|
-
|
|
71542
|
-
|
|
71543
|
-
|
|
71544
|
-
|
|
71545
|
-
|
|
71546
|
-
|
|
71547
|
-
|
|
71548
|
-
|
|
71549
|
-
|
|
71550
|
-
|
|
71551
|
-
|
|
71552
|
-
|
|
71553
|
-
|
|
71554
|
-
|
|
71555
|
-
|
|
71556
|
-
|
|
71557
|
-
|
|
71558
|
-
|
|
71559
|
-
|
|
71560
|
-
|
|
71561
|
-
|
|
71562
|
-
|
|
71563
|
-
|
|
71564
|
-
|
|
71565
|
-
|
|
71566
|
-
|
|
71567
|
-
|
|
71568
|
-
|
|
71569
|
-
|
|
71570
|
-
|
|
71571
|
-
|
|
71572
|
-
|
|
71573
|
-
|
|
71574
|
-
|
|
71657
|
+
let lastError;
|
|
71658
|
+
for (let errorRetryAttempt = 0; errorRetryAttempt <= MAX_RETRY_ATTEMPTS_AFTER_ERROR; errorRetryAttempt++) {
|
|
71659
|
+
try {
|
|
71660
|
+
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.startCapturingAgentOutput();
|
|
71661
|
+
const result = await runPromptWithTestFeedback({
|
|
71662
|
+
runner,
|
|
71663
|
+
prompt: codexPrompt,
|
|
71664
|
+
scriptPath,
|
|
71665
|
+
projectPath: process.cwd(),
|
|
71666
|
+
promptLabel,
|
|
71667
|
+
testCommand: options.testCommand,
|
|
71668
|
+
preserveArtifactsOnSuccess: options.preserveLogs,
|
|
71669
|
+
logPath,
|
|
71670
|
+
onAttemptStarted: (nextAttemptCount) => {
|
|
71671
|
+
attemptCount = nextAttemptCount;
|
|
71672
|
+
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.setAttempt(nextAttemptCount);
|
|
71673
|
+
},
|
|
71674
|
+
waitForPauseCheckpoint: waitForRequestedPause,
|
|
71675
|
+
});
|
|
71676
|
+
await finalizeSuccessfulPromptRound({
|
|
71677
|
+
options,
|
|
71678
|
+
nextPrompt,
|
|
71679
|
+
runnerMetadata,
|
|
71680
|
+
promptExecutionStartedDate,
|
|
71681
|
+
result,
|
|
71682
|
+
commitMessage,
|
|
71683
|
+
logPath,
|
|
71684
|
+
roundChangedFilesSnapshot,
|
|
71685
|
+
isRichUiEnabled,
|
|
71686
|
+
progressDisplay,
|
|
71687
|
+
uiHandle,
|
|
71688
|
+
waitForRequestedPause,
|
|
71689
|
+
});
|
|
71690
|
+
return;
|
|
71691
|
+
}
|
|
71692
|
+
catch (error) {
|
|
71693
|
+
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.stopCapturingAgentOutput();
|
|
71694
|
+
lastError = error;
|
|
71695
|
+
if (errorRetryAttempt >= MAX_RETRY_ATTEMPTS_AFTER_ERROR) {
|
|
71696
|
+
break;
|
|
71697
|
+
}
|
|
71698
|
+
await waitAfterErrorBeforeRetry({
|
|
71699
|
+
options,
|
|
71700
|
+
error,
|
|
71701
|
+
attemptedRetries: errorRetryAttempt + 1,
|
|
71702
|
+
isRichUiEnabled,
|
|
71703
|
+
progressDisplay,
|
|
71704
|
+
uiHandle,
|
|
71705
|
+
waitForRequestedPause,
|
|
71706
|
+
});
|
|
71707
|
+
}
|
|
71575
71708
|
}
|
|
71709
|
+
await finalizeFailedPromptRound({
|
|
71710
|
+
nextPrompt,
|
|
71711
|
+
runnerMetadata,
|
|
71712
|
+
promptExecutionStartedDate,
|
|
71713
|
+
attemptCount,
|
|
71714
|
+
error: lastError,
|
|
71715
|
+
options,
|
|
71716
|
+
roundChangedFilesSnapshot,
|
|
71717
|
+
uiHandle,
|
|
71718
|
+
waitForRequestedPause,
|
|
71719
|
+
});
|
|
71720
|
+
throw lastError;
|
|
71576
71721
|
}, { preserveArtifactsOnSuccess: options.preserveLogs });
|
|
71577
71722
|
}
|
|
71723
|
+
/**
|
|
71724
|
+
* Sleeps `options.waitAfterError` while keeping the rich UI and plain console in sync, then resets state for the retry.
|
|
71725
|
+
*/
|
|
71726
|
+
async function waitAfterErrorBeforeRetry(options) {
|
|
71727
|
+
const { options: runOptions, error, attemptedRetries, isRichUiEnabled, progressDisplay, uiHandle, waitForRequestedPause, } = options;
|
|
71728
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
71729
|
+
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.addError(errorMessage);
|
|
71730
|
+
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.setPhase('waiting');
|
|
71731
|
+
if (!isRichUiEnabled) {
|
|
71732
|
+
console.warn(colors.yellow(`Prompt round failed (retry ${attemptedRetries}/${MAX_RETRY_ATTEMPTS_AFTER_ERROR}): ${errorMessage}`));
|
|
71733
|
+
}
|
|
71734
|
+
await waitForRequestedPause({
|
|
71735
|
+
checkpointLabel: 'waiting after error before retrying the prompt',
|
|
71736
|
+
phase: 'waiting',
|
|
71737
|
+
statusMessage: `Waiting before retry ${attemptedRetries}/${MAX_RETRY_ATTEMPTS_AFTER_ERROR} after error`,
|
|
71738
|
+
});
|
|
71739
|
+
progressDisplay === null || progressDisplay === void 0 ? void 0 : progressDisplay.pauseTimer();
|
|
71740
|
+
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.pauseTimer();
|
|
71741
|
+
await sleepWithCountdown({
|
|
71742
|
+
durationMs: runOptions.waitAfterError,
|
|
71743
|
+
waitKind: 'after-error',
|
|
71744
|
+
isRichUiEnabled,
|
|
71745
|
+
uiHandle,
|
|
71746
|
+
});
|
|
71747
|
+
progressDisplay === null || progressDisplay === void 0 ? void 0 : progressDisplay.resumeTimer();
|
|
71748
|
+
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.resumeTimer();
|
|
71749
|
+
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.setPhase('running');
|
|
71750
|
+
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.setStatusMessage(`Retrying prompt (retry ${attemptedRetries}/${MAX_RETRY_ATTEMPTS_AFTER_ERROR})`);
|
|
71751
|
+
}
|
|
71578
71752
|
/**
|
|
71579
71753
|
* Updates UI or console output to reflect that the selected prompt is being processed.
|
|
71580
71754
|
*/
|
|
@@ -71755,7 +71929,8 @@ async function runCodexPrompts(providedOptions) {
|
|
|
71755
71929
|
initializeRunUi(uiHandle, runner.name, actualRunnerModel, options);
|
|
71756
71930
|
let hasShownUpcomingTasks = false;
|
|
71757
71931
|
let hasWaitedForStart = false;
|
|
71758
|
-
let
|
|
71932
|
+
let previousRoundStartTime;
|
|
71933
|
+
let previousRoundEndTime;
|
|
71759
71934
|
while (just(true)) {
|
|
71760
71935
|
if (options.autoPull && !options.dryRun) {
|
|
71761
71936
|
await waitForRequestedPause({
|
|
@@ -71798,15 +71973,16 @@ async function runCodexPrompts(providedOptions) {
|
|
|
71798
71973
|
const nextPrompt = promptQueueSnapshot.nextPrompt;
|
|
71799
71974
|
const promptLabel = buildPromptLabelForDisplay(nextPrompt.file, nextPrompt.section);
|
|
71800
71975
|
// Wait between prompt rounds (skipped for the first round)
|
|
71801
|
-
if (
|
|
71976
|
+
if (previousRoundStartTime !== undefined && previousRoundEndTime !== undefined) {
|
|
71802
71977
|
await waitBetweenPromptRoundsIfNeeded({
|
|
71803
71978
|
options,
|
|
71979
|
+
previousRoundStartTime,
|
|
71980
|
+
previousRoundEndTime,
|
|
71804
71981
|
isRichUiEnabled,
|
|
71805
71982
|
progressDisplay,
|
|
71806
71983
|
uiHandle,
|
|
71807
71984
|
});
|
|
71808
71985
|
}
|
|
71809
|
-
hasRunAtLeastOneRound = true;
|
|
71810
71986
|
hasWaitedForStart = await waitForPromptConfirmationIfNeeded({
|
|
71811
71987
|
options,
|
|
71812
71988
|
nextPrompt,
|
|
@@ -71824,6 +72000,7 @@ async function runCodexPrompts(providedOptions) {
|
|
|
71824
72000
|
});
|
|
71825
72001
|
await ensureWorkingTreeClean();
|
|
71826
72002
|
}
|
|
72003
|
+
const currentRoundStartTime = Date.now();
|
|
71827
72004
|
await runPromptRound({
|
|
71828
72005
|
options,
|
|
71829
72006
|
runner,
|
|
@@ -71837,6 +72014,8 @@ async function runCodexPrompts(providedOptions) {
|
|
|
71837
72014
|
uiHandle,
|
|
71838
72015
|
waitForRequestedPause,
|
|
71839
72016
|
});
|
|
72017
|
+
previousRoundStartTime = currentRoundStartTime;
|
|
72018
|
+
previousRoundEndTime = Date.now();
|
|
71840
72019
|
}
|
|
71841
72020
|
}
|
|
71842
72021
|
finally {
|
|
@@ -72061,39 +72240,50 @@ async function waitForPromptConfirmationIfNeeded(options) {
|
|
|
72061
72240
|
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.resumeTimer();
|
|
72062
72241
|
return true;
|
|
72063
72242
|
}
|
|
72064
|
-
/**
|
|
72065
|
-
* Countdown update interval for the between-rounds wait display.
|
|
72066
|
-
*/
|
|
72067
|
-
const WAIT_COUNTDOWN_UPDATE_INTERVAL_MS = 30000;
|
|
72068
72243
|
/**
|
|
72069
72244
|
* Polling interval when in keepAlive server mode and no runnable prompts are available.
|
|
72070
72245
|
*/
|
|
72071
72246
|
const KEEP_ALIVE_POLL_INTERVAL_MS = 5000;
|
|
72072
72247
|
/**
|
|
72073
|
-
* Waits
|
|
72074
|
-
*
|
|
72248
|
+
* Waits between prompt rounds according to `--wait-between-prompts` (paced from the previous round's start)
|
|
72249
|
+
* and `--wait-after-prompt` (measured from the previous round's end).
|
|
72250
|
+
* Both phases are shown separately in the UI so the user can see which type of wait is active.
|
|
72075
72251
|
*/
|
|
72076
72252
|
async function waitBetweenPromptRoundsIfNeeded(options) {
|
|
72077
|
-
const { options: runOptions, isRichUiEnabled, progressDisplay, uiHandle } = options;
|
|
72078
|
-
const { waitBetweenPrompts } = runOptions;
|
|
72079
|
-
if (waitBetweenPrompts <= 0) {
|
|
72253
|
+
const { options: runOptions, previousRoundStartTime, previousRoundEndTime, isRichUiEnabled, progressDisplay, uiHandle, } = options;
|
|
72254
|
+
const { waitAfterPrompt, waitBetweenPrompts } = runOptions;
|
|
72255
|
+
if (waitAfterPrompt <= 0 && waitBetweenPrompts <= 0) {
|
|
72256
|
+
return;
|
|
72257
|
+
}
|
|
72258
|
+
const now = Date.now();
|
|
72259
|
+
const waitBetweenPromptsEndTime = previousRoundStartTime + waitBetweenPrompts;
|
|
72260
|
+
const waitAfterPromptEndTime = previousRoundEndTime + waitAfterPrompt;
|
|
72261
|
+
// Phase 1: pace from start of previous prompt (`--wait-between-prompts`)
|
|
72262
|
+
const phase1Duration = Math.max(0, waitBetweenPromptsEndTime - now);
|
|
72263
|
+
// Phase 2: rest from end of previous prompt (`--wait-after-prompt`)
|
|
72264
|
+
const phase2StartTime = Math.max(now, waitBetweenPromptsEndTime);
|
|
72265
|
+
const phase2Duration = Math.max(0, waitAfterPromptEndTime - phase2StartTime);
|
|
72266
|
+
if (phase1Duration <= 0 && phase2Duration <= 0) {
|
|
72080
72267
|
return;
|
|
72081
72268
|
}
|
|
72082
72269
|
progressDisplay === null || progressDisplay === void 0 ? void 0 : progressDisplay.pauseTimer();
|
|
72083
72270
|
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.pauseTimer();
|
|
72084
72271
|
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.setPhase('waiting');
|
|
72085
|
-
|
|
72086
|
-
|
|
72087
|
-
|
|
72088
|
-
|
|
72089
|
-
|
|
72090
|
-
|
|
72091
|
-
|
|
72092
|
-
|
|
72093
|
-
|
|
72094
|
-
|
|
72095
|
-
|
|
72096
|
-
|
|
72272
|
+
if (phase1Duration > 0) {
|
|
72273
|
+
await sleepWithCountdown({
|
|
72274
|
+
durationMs: phase1Duration,
|
|
72275
|
+
waitKind: 'between-prompts',
|
|
72276
|
+
isRichUiEnabled,
|
|
72277
|
+
uiHandle,
|
|
72278
|
+
});
|
|
72279
|
+
}
|
|
72280
|
+
if (phase2Duration > 0) {
|
|
72281
|
+
await sleepWithCountdown({
|
|
72282
|
+
durationMs: phase2Duration,
|
|
72283
|
+
waitKind: 'after-prompt',
|
|
72284
|
+
isRichUiEnabled,
|
|
72285
|
+
uiHandle,
|
|
72286
|
+
});
|
|
72097
72287
|
}
|
|
72098
72288
|
progressDisplay === null || progressDisplay === void 0 ? void 0 : progressDisplay.resumeTimer();
|
|
72099
72289
|
uiHandle === null || uiHandle === void 0 ? void 0 : uiHandle.state.resumeTimer();
|