agentxchain 2.155.69 → 2.155.70

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.69",
3
+ "version": "2.155.70",
4
4
  "description": "CLI for AgentXchain — governed multi-agent software delivery",
5
5
  "type": "module",
6
6
  "bin": {
@@ -54,6 +54,7 @@ import {
54
54
  } from './intent-startup-migration.js';
55
55
  import { checkpointAcceptedTurn } from './turn-checkpoint.js';
56
56
  import {
57
+ hasClaudeEnvAuth,
57
58
  hasClaudeAuthenticationFailureText,
58
59
  hasClaudeNodeIncompatibilityText,
59
60
  isClaudeLocalCliRuntime,
@@ -497,6 +498,78 @@ function reclassifyRetainedClaudeNodeIncompatGhost(context, session, state, cand
497
498
  return nextState;
498
499
  }
499
500
 
501
+ function findRetainedClaudeAuthDispatchBlocker(root, state, config) {
502
+ if (!state || state.status !== 'blocked') return null;
503
+ if (state.blocked_on !== 'dispatch:claude_auth_failed') return null;
504
+ if (state.blocked_reason?.category !== 'dispatch_error') return null;
505
+ const activeTurns = state.active_turns || {};
506
+ const turnId = state.blocked_reason?.turn_id || null;
507
+ const candidateIds = turnId && activeTurns[turnId] ? [turnId] : Object.keys(activeTurns);
508
+ for (const candidateId of candidateIds) {
509
+ const turn = activeTurns[candidateId];
510
+ if (!turn) continue;
511
+ const runtime = config?.runtimes?.[turn.runtime_id];
512
+ if (!isClaudeLocalCliRuntime(runtime)) continue;
513
+ const logPath = join(root, getDispatchLogPath(candidateId));
514
+ if (!existsSync(logPath)) continue;
515
+ let logText = '';
516
+ try {
517
+ logText = readFileSync(logPath, 'utf8');
518
+ } catch {
519
+ continue;
520
+ }
521
+ if (!hasClaudeAuthenticationFailureText(logText)) continue;
522
+ return { turn_id: candidateId, turn, previous_blocked_on: state.blocked_on || null };
523
+ }
524
+ return null;
525
+ }
526
+
527
+ function maybeAutoRetryRetainedClaudeAuthDispatch(context, session, state, log = console.log) {
528
+ const { root, config } = context;
529
+ if (!hasClaudeEnvAuth(process.env)) return null;
530
+ const candidate = findRetainedClaudeAuthDispatchBlocker(root, state, config);
531
+ if (!candidate) return null;
532
+
533
+ const reissued = reissueTurn(root, config, {
534
+ turnId: candidate.turn_id,
535
+ reason: 'auto_retry_claude_auth_refreshed',
536
+ });
537
+ if (!reissued.ok) {
538
+ log(`Claude auth auto-retry skipped: ${reissued.error}`);
539
+ return null;
540
+ }
541
+
542
+ const runId = session.current_run_id || state.run_id || reissued.state?.run_id || null;
543
+ const nextState = clearGhostBlockerAfterReissue(root, reissued.state);
544
+ Object.assign(session, {
545
+ status: 'running',
546
+ current_run_id: runId,
547
+ });
548
+ writeContinuousSession(root, session);
549
+ emitRunEvent(root, 'auto_retried_ghost', {
550
+ run_id: runId,
551
+ phase: nextState.phase || state.phase || null,
552
+ status: 'active',
553
+ turn: { turn_id: reissued.newTurn.turn_id, role_id: reissued.newTurn.assigned_role || null },
554
+ payload: {
555
+ old_turn_id: candidate.turn_id,
556
+ new_turn_id: reissued.newTurn.turn_id,
557
+ failure_type: 'claude_auth_failed',
558
+ recovery_class: 'claude_auth_refreshed',
559
+ runtime_id: candidate.turn.runtime_id || null,
560
+ },
561
+ });
562
+ log(`Claude auth refreshed; auto-retried ${candidate.turn_id} -> ${reissued.newTurn.turn_id}.`);
563
+ return {
564
+ ok: true,
565
+ status: 'running',
566
+ action: 'auto_retried_claude_auth_refreshed',
567
+ run_id: runId,
568
+ old_turn_id: candidate.turn_id,
569
+ new_turn_id: reissued.newTurn.turn_id,
570
+ };
571
+ }
572
+
500
573
  const RECOVERABLE_ACTIVE_TURN_STATUSES = new Set(['assigned', 'dispatched', 'starting', 'running']);
501
574
 
502
575
  function hasOnlyRecoverableActiveTurns(activeTurns = {}) {
@@ -1913,6 +1986,8 @@ export async function advanceContinuousRunOnce(context, session, contOpts, execu
1913
1986
  if (startupGovernedState?.status === 'blocked') {
1914
1987
  const reclassifiedState = maybeReclassifyRetainedClaudeAuthEscalation(context, session, startupGovernedState, log);
1915
1988
  let effectiveBlockedState = reclassifiedState || startupGovernedState;
1989
+ const authRetry = maybeAutoRetryRetainedClaudeAuthDispatch(context, session, effectiveBlockedState, log);
1990
+ if (authRetry?.status === 'running') return authRetry;
1916
1991
  const nodeCandidate = findRetainedClaudeNodeIncompatGhost(root, effectiveBlockedState, context.config);
1917
1992
  if (nodeCandidate) {
1918
1993
  const nodeRecovery = reclassifyRetainedClaudeNodeIncompatGhost(