@tekmidian/pai 0.58.0 → 0.59.0

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.
@@ -3,7 +3,7 @@ import { i as err } from "../utils-C9HsYDpO.mjs";
3
3
  import "../migrate-BD7D8EEh.mjs";
4
4
  import "../helpers-D9WkIf9R.mjs";
5
5
  import "../factory-DiuntvwG.mjs";
6
- import { n as drainStdio, t as buildProgram } from "../program-D-WkmvuQ.mjs";
6
+ import { n as drainStdio, t as buildProgram } from "../program-B5miXqQa.mjs";
7
7
  import "../wakeup-D0uvqLsE.mjs";
8
8
  import "../context-handover-cache-Dt4HW1Ro.mjs";
9
9
  import "../config-D1omG_UU.mjs";
@@ -2,7 +2,7 @@ import "../utils-C9HsYDpO.mjs";
2
2
  import "../migrate-BD7D8EEh.mjs";
3
3
  import "../helpers-D9WkIf9R.mjs";
4
4
  import "../factory-DiuntvwG.mjs";
5
- import { t as buildProgram } from "../program-D-WkmvuQ.mjs";
5
+ import { t as buildProgram } from "../program-B5miXqQa.mjs";
6
6
  import "../wakeup-D0uvqLsE.mjs";
7
7
  import "../context-handover-cache-Dt4HW1Ro.mjs";
8
8
  import "../config-D1omG_UU.mjs";
@@ -4444,7 +4444,28 @@ async function keepTriggeredSchedule(task, opts, state, now) {
4444
4444
  return `, could NOT keep the schedule: ${e instanceof Error ? e.message : String(e)}`;
4445
4445
  }
4446
4446
  }
4447
- async function handleProbe(task, elapsed, opts, state) {
4447
+ /** Re-dispatch attempts allowed for one claim before NOT-RECEIVED gives up. */
4448
+ const NOT_RECEIVED_MAX_ATTEMPTS = 3;
4449
+ /** Minutes of backoff per attempt: try 1 waits 2m, try 2 waits 4m, try 3 waits 6m. */
4450
+ const NOT_RECEIVED_BACKOFF_BASE_MIN = 2;
4451
+ /**
4452
+ * Does a probe reply say "alive, but the dispatch never reached me"?
4453
+ *
4454
+ * The session answers the liveness probe with NOT-RECEIVED (or the "alive, not
4455
+ * received" spelling) when it is demonstrably live yet has no knowledge of the
4456
+ * work order — the dispatch was reported delivered and was not. That is not
4457
+ * silence (the session is fine) and not death (nothing needs recovering): it is
4458
+ * an UNDELIVERED dispatch, and the honest response is to send it again.
4459
+ *
4460
+ * Anchored to the first line so a reply merely discussing the phrase —
4461
+ * "we discussed not received earlier" — does not trip it.
4462
+ */
4463
+ function isNotReceivedReply(reply) {
4464
+ if (!reply) return false;
4465
+ const first = reply.split("\n", 1)[0].trim().toLowerCase();
4466
+ return first.startsWith("not-received") || /^alive[,:]\s*not[ -]received/.test(first);
4467
+ }
4468
+ async function handleProbe(task, elapsed, opts, state, now) {
4448
4469
  const project = task.owner.project;
4449
4470
  const el = elapsed === null ? "unknown" : `${elapsed}m`;
4450
4471
  if (opts.dryRun) return {
@@ -4458,6 +4479,31 @@ async function handleProbe(task, elapsed, opts, state) {
4458
4479
  const answer = await opts.prober.ask(project, `Are you still working on the task "${task.title}"? Reply in one short line.`);
4459
4480
  if (answer.state === "replied" || answer.state === "busy") {
4460
4481
  state.failedProbes[task.id] = 0;
4482
+ if (isNotReceivedReply(answer.reply)) {
4483
+ const attempts = state.notReceivedAttempts[task.id] ?? 0;
4484
+ const retryAt = state.notReceivedRetryAt[task.id] ?? 0;
4485
+ if (now < retryAt) return {
4486
+ note: `alive but NOT-RECEIVED — re-dispatch backed off ${Math.round((retryAt - now) / 6e4)}m (try ${attempts})`,
4487
+ stuck: false
4488
+ };
4489
+ if (attempts >= NOT_RECEIVED_MAX_ATTEMPTS) return {
4490
+ note: `alive but NOT-RECEIVED x${attempts} — dispatch never landed, claim left for a human`,
4491
+ stuck: true
4492
+ };
4493
+ const next = attempts + 1;
4494
+ state.notReceivedAttempts[task.id] = next;
4495
+ state.notReceivedRetryAt[task.id] = now + next * NOT_RECEIVED_BACKOFF_BASE_MIN * 6e4;
4496
+ const r = await handleDispatch(task, 0, opts, state, now);
4497
+ return {
4498
+ note: `alive but NOT-RECEIVED — re-dispatched (try ${next}): ${r.note}`,
4499
+ stuck: r.alarm === true,
4500
+ dispatched: true
4501
+ };
4502
+ }
4503
+ if (answer.state === "replied") {
4504
+ delete state.notReceivedAttempts[task.id];
4505
+ delete state.notReceivedRetryAt[task.id];
4506
+ }
4461
4507
  const expected = expectedMinutes(state.history[task.id] ?? []);
4462
4508
  if (elapsed !== null && elapsed > expected * GROSS_OVERRUN_FACTOR) return {
4463
4509
  note: `alive but ${el} against an expected ${expected}m — ${GROSS_OVERRUN_FACTOR}x over, worth a look`,
@@ -21517,4 +21563,4 @@ claude() {
21517
21563
 
21518
21564
  //#endregion
21519
21565
  export { drainStdio as n, buildProgram as t };
21520
- //# sourceMappingURL=program-D-WkmvuQ.mjs.map
21566
+ //# sourceMappingURL=program-B5miXqQa.mjs.map