agentxchain 2.155.63 → 2.155.64

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentxchain",
3
- "version": "2.155.63",
3
+ "version": "2.155.64",
4
4
  "description": "CLI for AgentXchain — governed multi-agent software delivery",
5
5
  "type": "module",
6
6
  "bin": {
@@ -52,6 +52,7 @@ import {
52
52
  formatLegacyIntentMigrationNotice,
53
53
  formatPhantomIntentSupersessionNotice,
54
54
  } from './intent-startup-migration.js';
55
+ import { checkpointAcceptedTurn } from './turn-checkpoint.js';
55
56
 
56
57
  const CONTINUOUS_SESSION_PATH = '.agentxchain/continuous-session.json';
57
58
  const PRODUCTIVE_TIMEOUT_RETRY_MAX_PER_RUN = 1;
@@ -574,6 +575,59 @@ async function maybeAutoRetryContinuousBlocker(context, session, contOpts, block
574
575
  || await maybeAutoRetryGhostBlocker(context, session, contOpts, blockedState, log);
575
576
  }
576
577
 
578
+ function extractCheckpointTurnIdFromExecution(execution) {
579
+ const errors = Array.isArray(execution?.result?.errors) ? execution.result.errors : [];
580
+ for (const error of errors) {
581
+ const text = String(error || '');
582
+ const match = text.match(/\bcheckpoint-turn\s+--turn\s+(turn_[A-Za-z0-9_-]+)/);
583
+ if (match) return match[1];
584
+ }
585
+ return null;
586
+ }
587
+
588
+ function maybeAutoCheckpointBlockedExecution(context, session, contOpts, execution, log = console.log) {
589
+ if (!contOpts.autoCheckpoint) return null;
590
+ const turnId = extractCheckpointTurnIdFromExecution(execution);
591
+ if (!turnId) return null;
592
+
593
+ const checkpoint = checkpointAcceptedTurn(context.root, { turnId });
594
+ if (!checkpoint.ok) {
595
+ log(`Auto-checkpoint skipped for ${turnId}: ${checkpoint.error || 'checkpoint failed'}`);
596
+ return null;
597
+ }
598
+ if (checkpoint.already_checkpointed || checkpoint.skipped) {
599
+ log(`Auto-checkpoint skipped for ${turnId}: ${checkpoint.reason || 'no checkpoint changes were created'}`);
600
+ return null;
601
+ }
602
+
603
+ session.status = 'running';
604
+ session.current_run_id = session.current_run_id || execution?.result?.state?.run_id || null;
605
+ writeContinuousSession(context.root, session);
606
+
607
+ emitRunEvent(context.root, 'continuous_auto_checkpoint_recovered', {
608
+ run_id: session.current_run_id || execution?.result?.state?.run_id || null,
609
+ phase: execution?.result?.state?.phase || null,
610
+ status: 'active',
611
+ turn: { turn_id: turnId, role_id: null },
612
+ payload: {
613
+ session_id: session.session_id,
614
+ checkpoint_sha: checkpoint.checkpoint_sha || null,
615
+ already_checkpointed: Boolean(checkpoint.already_checkpointed),
616
+ recovered_files_changed: checkpoint.recovered_files_changed || checkpoint.files_changed || null,
617
+ },
618
+ });
619
+
620
+ log(`Auto-checkpoint recovered accepted turn ${turnId}; continuing active run.`);
621
+ return {
622
+ ok: true,
623
+ status: 'running',
624
+ action: 'auto_checkpoint_recovered',
625
+ run_id: session.current_run_id,
626
+ turn_id: turnId,
627
+ checkpoint_sha: checkpoint.checkpoint_sha || null,
628
+ };
629
+ }
630
+
577
631
  async function maybeAutoRetryGhostBlocker(context, session, contOpts, blockedState, log = console.log) {
578
632
  const { root, config } = context;
579
633
  const decision = classifyGhostRetryDecision({
@@ -1784,6 +1838,8 @@ export async function advanceContinuousRunOnce(context, session, contOpts, execu
1784
1838
  const resumeStopReason = execution.result?.stop_reason;
1785
1839
 
1786
1840
  if (isBlockedContinuousExecution(execution)) {
1841
+ const checkpointed = maybeAutoCheckpointBlockedExecution(context, session, contOpts, execution, log);
1842
+ if (checkpointed) return checkpointed;
1787
1843
  const blockedState = execution?.result?.state || loadProjectState(root, context.config);
1788
1844
  const retried = await maybeAutoRetryContinuousBlocker(context, session, contOpts, blockedState, log);
1789
1845
  if (retried) return retried;
@@ -1852,6 +1908,8 @@ export async function advanceContinuousRunOnce(context, session, contOpts, execu
1852
1908
  const resumeStopReason = execution.result?.stop_reason;
1853
1909
 
1854
1910
  if (isBlockedContinuousExecution(execution)) {
1911
+ const checkpointed = maybeAutoCheckpointBlockedExecution(context, session, contOpts, execution, log);
1912
+ if (checkpointed) return checkpointed;
1855
1913
  const blockedState = execution?.result?.state || loadProjectState(root, context.config);
1856
1914
  const retried = await maybeAutoRetryContinuousBlocker(context, session, contOpts, blockedState, log);
1857
1915
  if (retried) return retried;
@@ -2044,6 +2102,8 @@ export async function advanceContinuousRunOnce(context, session, contOpts, execu
2044
2102
  }
2045
2103
 
2046
2104
  if (isBlockedContinuousExecution(execution)) {
2105
+ const checkpointed = maybeAutoCheckpointBlockedExecution(context, session, contOpts, execution, log);
2106
+ if (checkpointed) return checkpointed;
2047
2107
  const blockedState = execution?.result?.state || loadProjectState(root, context.config);
2048
2108
  const retried = await maybeAutoRetryContinuousBlocker(context, session, contOpts, blockedState, log);
2049
2109
  if (retried) return retried;