@promptbook/node 0.113.0-10 → 0.113.0-11

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/esm/index.es.js CHANGED
@@ -36,7 +36,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
36
36
  * @generated
37
37
  * @see https://github.com/webgptorg/promptbook
38
38
  */
39
- const PROMPTBOOK_ENGINE_VERSION = '0.113.0-10';
39
+ const PROMPTBOOK_ENGINE_VERSION = '0.113.0-11';
40
40
  /**
41
41
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
42
42
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -3061,6 +3061,47 @@ async function $runGoScriptWithOutput(options) {
3061
3061
  });
3062
3062
  }
3063
3063
 
3064
+ /**
3065
+ * Minimum timer duration used to avoid a zero-millisecond polling loop.
3066
+ */
3067
+ const MINIMUM_WORLD_TIME_WAIT_POLL_INTERVAL_MS = 1;
3068
+ /**
3069
+ * Waits until one wall-clock deadline has passed.
3070
+ *
3071
+ * The remaining time is recalculated from `Date.now()` after every poll and after every tick callback.
3072
+ * This makes waits elapse while the process is paused at a checkpoint or the computer is asleep.
3073
+ *
3074
+ * @private internal utility of `ptbk coder` wait handling
3075
+ */
3076
+ async function waitUntilWorldTimeDeadline(options) {
3077
+ const { deadlineTimeMs, pollIntervalMs, onTick } = options;
3078
+ const normalizedPollIntervalMs = Math.max(MINIMUM_WORLD_TIME_WAIT_POLL_INTERVAL_MS, pollIntervalMs);
3079
+ while (true) {
3080
+ const remainingDurationMs = getRemainingDurationMs(deadlineTimeMs);
3081
+ if (remainingDurationMs <= 0) {
3082
+ return;
3083
+ }
3084
+ await (onTick === null || onTick === void 0 ? void 0 : onTick(remainingDurationMs));
3085
+ const remainingDurationAfterTickMs = getRemainingDurationMs(deadlineTimeMs);
3086
+ if (remainingDurationAfterTickMs <= 0) {
3087
+ return;
3088
+ }
3089
+ await waitForMilliseconds(Math.min(normalizedPollIntervalMs, remainingDurationAfterTickMs));
3090
+ }
3091
+ }
3092
+ /**
3093
+ * Returns the remaining wall-clock duration until a timestamp.
3094
+ */
3095
+ function getRemainingDurationMs(deadlineTimeMs) {
3096
+ return Math.max(0, deadlineTimeMs - Date.now());
3097
+ }
3098
+ /**
3099
+ * Waits for one short polling interval.
3100
+ */
3101
+ async function waitForMilliseconds(durationMs) {
3102
+ await new Promise((resolve) => setTimeout(resolve, durationMs));
3103
+ }
3104
+
3064
3105
  /**
3065
3106
  * Base delimiter used for passing large prompts through stdin.
3066
3107
  */
@@ -3470,36 +3511,32 @@ class ClaudeCodeRunner {
3470
3511
  * Waits until the Claude Code session can be resumed, keeping terminal status clear.
3471
3512
  */
3472
3513
  async function waitForClaudeCodeSessionLimitReset(sessionLimit, resurrectionCount, options) {
3473
- var _a, _b, _c;
3514
+ var _a, _b;
3474
3515
  const delayMs = getClaudeCodeSessionLimitDelayMs(sessionLimit);
3516
+ const resetDeadlineTimeMs = Date.now() + delayMs;
3475
3517
  const sessionLabel = formatClaudeCodeSessionIdForDisplay(sessionLimit.sessionId);
3476
3518
  const resetSummary = formatClaudeCodeSessionLimitForDisplay(sessionLimit);
3477
3519
  if ((_a = options.shouldPrintLiveOutput) !== null && _a !== void 0 ? _a : true) {
3478
3520
  console.warn(colors.yellow(`[claude-code] Session limit detected for ${sessionLimit.sessionId}. Resurrection #${resurrectionCount} will resume with --resume after ${formatDurationMs(delayMs)}. ${resetSummary}`));
3479
3521
  }
3480
- let remainingDelayMs = delayMs;
3481
- while (remainingDelayMs > 0) {
3482
- await ((_b = options.waitForPauseCheckpoint) === null || _b === void 0 ? void 0 : _b.call(options, {
3483
- checkpointLabel: 'the Claude Code session limit reset',
3484
- phase: 'waiting',
3485
- statusMessage: `Claude Code session ${sessionLabel} hit its limit; resurrection #${resurrectionCount} resumes in ${formatDurationMs(remainingDelayMs)}`,
3486
- }));
3487
- const currentDelayMs = Math.min(CLAUDE_CODE_SESSION_RESURRECTION_POLL_MS, remainingDelayMs);
3488
- await waitFor$1(currentDelayMs);
3489
- remainingDelayMs -= currentDelayMs;
3490
- }
3491
- await ((_c = options.waitForPauseCheckpoint) === null || _c === void 0 ? void 0 : _c.call(options, {
3522
+ await waitUntilWorldTimeDeadline({
3523
+ deadlineTimeMs: resetDeadlineTimeMs,
3524
+ pollIntervalMs: CLAUDE_CODE_SESSION_RESURRECTION_POLL_MS,
3525
+ onTick: async (remainingDelayMs) => {
3526
+ var _a;
3527
+ await ((_a = options.waitForPauseCheckpoint) === null || _a === void 0 ? void 0 : _a.call(options, {
3528
+ checkpointLabel: 'the Claude Code session limit reset',
3529
+ phase: 'waiting',
3530
+ statusMessage: `Claude Code session ${sessionLabel} hit its limit; resurrection #${resurrectionCount} resumes in ${formatDurationMs(Math.min(remainingDelayMs, delayMs))}`,
3531
+ }));
3532
+ },
3533
+ });
3534
+ await ((_b = options.waitForPauseCheckpoint) === null || _b === void 0 ? void 0 : _b.call(options, {
3492
3535
  checkpointLabel: 'resurrecting the Claude Code session with --resume',
3493
3536
  phase: 'running',
3494
3537
  statusMessage: `Resurrecting Claude Code session ${sessionLabel} with --resume`,
3495
3538
  }));
3496
3539
  }
3497
- /**
3498
- * Waits for a fixed amount of milliseconds.
3499
- */
3500
- async function waitFor$1(delayMs) {
3501
- await new Promise((resolve) => setTimeout(resolve, delayMs));
3502
- }
3503
3540
  /**
3504
3541
  * Formats a Claude Code session id for compact terminal status lines.
3505
3542
  */
@@ -4460,12 +4497,6 @@ const RATE_LIMIT_BACKOFF_MAX_MS = 30 * 60 * 1000;
4460
4497
  * Randomized delay proportion added/subtracted for retry jitter.
4461
4498
  */
4462
4499
  const RATE_LIMIT_BACKOFF_JITTER_RATIO = 0.15;
4463
- /**
4464
- * Waits for one given amount of milliseconds.
4465
- */
4466
- async function waitFor(delayMs) {
4467
- await new Promise((resolve) => setTimeout(resolve, delayMs));
4468
- }
4469
4500
  /**
4470
4501
  * Formats a delay value into a concise `xh ym zs` style label.
4471
4502
  */
@@ -4555,13 +4586,18 @@ class OpenAiCodexRunner {
4555
4586
  throw error;
4556
4587
  }
4557
4588
  const delayMs = this.rateLimitBackoff.nextDelayMs();
4558
- const retryAt = new Date(Date.now() + delayMs).toISOString();
4589
+ const retryDeadlineTimeMs = Date.now() + delayMs;
4590
+ const retryAt = new Date(retryDeadlineTimeMs).toISOString();
4559
4591
  const retryIndex = this.rateLimitBackoff.retryCount;
4560
4592
  const summary = extractFailureSummary(details);
4561
4593
  if ((_b = options.shouldPrintLiveOutput) !== null && _b !== void 0 ? _b : true) {
4562
4594
  console.warn(colors.yellow(`[codex] Rate limit/quota detected (${summary}). Retry #${retryIndex} in ${formatDelay(delayMs)} at ${retryAt}.`));
4563
4595
  }
4564
- await waitForRetryDelay(delayMs, options);
4596
+ await waitForRetryDelay({
4597
+ delayMs,
4598
+ retryDeadlineTimeMs,
4599
+ promptRunOptions: options,
4600
+ });
4565
4601
  }
4566
4602
  }
4567
4603
  }
@@ -4569,20 +4605,21 @@ class OpenAiCodexRunner {
4569
4605
  /**
4570
4606
  * Waits for the next Codex retry while polling for requested pause checkpoints.
4571
4607
  */
4572
- async function waitForRetryDelay(delayMs, options) {
4573
- var _a;
4574
- let remainingDelayMs = delayMs;
4575
- while (remainingDelayMs > 0) {
4576
- const remainingDelayLabel = formatDelay(remainingDelayMs);
4577
- await ((_a = options.waitForPauseCheckpoint) === null || _a === void 0 ? void 0 : _a.call(options, {
4578
- checkpointLabel: 'the next OpenAI Codex retry after rate limit',
4579
- phase: 'running',
4580
- statusMessage: `Waiting ${remainingDelayLabel} before retrying OpenAI Codex`,
4581
- }));
4582
- const currentDelayMs = Math.min(RATE_LIMIT_BACKOFF_POLL_MS, remainingDelayMs);
4583
- await waitFor(currentDelayMs);
4584
- remainingDelayMs -= currentDelayMs;
4585
- }
4608
+ async function waitForRetryDelay(options) {
4609
+ const { delayMs, retryDeadlineTimeMs, promptRunOptions } = options;
4610
+ await waitUntilWorldTimeDeadline({
4611
+ deadlineTimeMs: retryDeadlineTimeMs,
4612
+ pollIntervalMs: RATE_LIMIT_BACKOFF_POLL_MS,
4613
+ onTick: async (remainingDelayMs) => {
4614
+ var _a;
4615
+ const remainingDelayLabel = formatDelay(Math.min(remainingDelayMs, delayMs));
4616
+ await ((_a = promptRunOptions.waitForPauseCheckpoint) === null || _a === void 0 ? void 0 : _a.call(promptRunOptions, {
4617
+ checkpointLabel: 'the next OpenAI Codex retry after rate limit',
4618
+ phase: 'running',
4619
+ statusMessage: `Waiting ${remainingDelayLabel} before retrying OpenAI Codex`,
4620
+ }));
4621
+ },
4622
+ });
4586
4623
  }
4587
4624
 
4588
4625
  /**