agentxchain 2.154.10 → 2.154.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/package.json +1 -1
- package/src/lib/governed-state.js +51 -0
package/package.json
CHANGED
|
@@ -89,6 +89,7 @@ const TALK_PATH = 'TALK.md';
|
|
|
89
89
|
const ACCEPTANCE_LOCK_PATH = '.agentxchain/locks/accept-turn.lock';
|
|
90
90
|
const ACCEPTANCE_JOURNAL_DIR = '.agentxchain/transactions/accept';
|
|
91
91
|
const INTAKE_INTENTS_DIR = '.agentxchain/intake/intents';
|
|
92
|
+
const CONTINUOUS_SESSION_PATH = '.agentxchain/continuous-session.json';
|
|
92
93
|
const STALE_LOCK_TIMEOUT_MS = 30_000;
|
|
93
94
|
const GOVERNED_SCHEMA_VERSION = '1.1';
|
|
94
95
|
|
|
@@ -1653,6 +1654,35 @@ function buildStandingRunCompletionSource(state, config, opts = {}) {
|
|
|
1653
1654
|
};
|
|
1654
1655
|
}
|
|
1655
1656
|
|
|
1657
|
+
function syncPausedContinuousSessionAfterOutOfBandCompletion(root, completedState, opts = {}) {
|
|
1658
|
+
const sessionPath = join(root, CONTINUOUS_SESSION_PATH);
|
|
1659
|
+
if (!existsSync(sessionPath) || !completedState?.run_id) {
|
|
1660
|
+
return null;
|
|
1661
|
+
}
|
|
1662
|
+
|
|
1663
|
+
let session = null;
|
|
1664
|
+
try {
|
|
1665
|
+
session = JSON.parse(readFileSync(sessionPath, 'utf8'));
|
|
1666
|
+
} catch {
|
|
1667
|
+
return null;
|
|
1668
|
+
}
|
|
1669
|
+
|
|
1670
|
+
if (!session || session.status !== 'paused' || session.current_run_id !== completedState.run_id) {
|
|
1671
|
+
return session;
|
|
1672
|
+
}
|
|
1673
|
+
|
|
1674
|
+
const nextSession = {
|
|
1675
|
+
...session,
|
|
1676
|
+
status: 'completed',
|
|
1677
|
+
runs_completed: Number.isInteger(session.runs_completed) ? session.runs_completed + 1 : 1,
|
|
1678
|
+
idle_cycles: 0,
|
|
1679
|
+
completed_at: completedState.completed_at || new Date().toISOString(),
|
|
1680
|
+
completed_via: opts.completed_via || 'out_of_band_run_completion',
|
|
1681
|
+
};
|
|
1682
|
+
safeWriteJson(sessionPath, nextSession);
|
|
1683
|
+
return nextSession;
|
|
1684
|
+
}
|
|
1685
|
+
|
|
1656
1686
|
function getPhaseRoles(config, phase) {
|
|
1657
1687
|
const routing = config?.routing?.[phase] || {};
|
|
1658
1688
|
const roles = new Set();
|
|
@@ -3110,6 +3140,9 @@ export function reconcileRunCompletionBeforeDispatch(root, config, state = null,
|
|
|
3110
3140
|
payload: { completed_at: updatedState.completed_at },
|
|
3111
3141
|
});
|
|
3112
3142
|
writeSessionCheckpoint(root, updatedState, 'run_completed');
|
|
3143
|
+
syncPausedContinuousSessionAfterOutOfBandCompletion(root, updatedState, {
|
|
3144
|
+
completed_via: 'approval_policy_reconciled_before_dispatch',
|
|
3145
|
+
});
|
|
3113
3146
|
recordRunHistory(root, updatedState, config, 'completed');
|
|
3114
3147
|
return {
|
|
3115
3148
|
ok: true,
|
|
@@ -3179,6 +3212,18 @@ export function reconcileRunCompletionBeforeDispatch(root, config, state = null,
|
|
|
3179
3212
|
gate: completionResult.gate_id || null,
|
|
3180
3213
|
requested_by_turn: completionSource.turn_id || null,
|
|
3181
3214
|
}, null);
|
|
3215
|
+
emitRunEvent(root, 'gate_approved', {
|
|
3216
|
+
run_id: updatedState.run_id,
|
|
3217
|
+
phase: updatedState.phase,
|
|
3218
|
+
status: 'completed',
|
|
3219
|
+
turn: completionSource.turn_id ? { turn_id: completionSource.turn_id, role_id: completionSource.role || completionSource.assigned_role || null } : undefined,
|
|
3220
|
+
payload: {
|
|
3221
|
+
gate_type: 'run_completion',
|
|
3222
|
+
gate_id: completionResult.gate_id || null,
|
|
3223
|
+
requested_by_turn: completionSource.turn_id || null,
|
|
3224
|
+
trigger: 'reconciled_before_dispatch',
|
|
3225
|
+
},
|
|
3226
|
+
});
|
|
3182
3227
|
emitRunEvent(root, 'run_completed', {
|
|
3183
3228
|
run_id: updatedState.run_id,
|
|
3184
3229
|
phase: updatedState.phase,
|
|
@@ -3186,6 +3231,9 @@ export function reconcileRunCompletionBeforeDispatch(root, config, state = null,
|
|
|
3186
3231
|
payload: { completed_at: updatedState.completed_at },
|
|
3187
3232
|
});
|
|
3188
3233
|
writeSessionCheckpoint(root, updatedState, 'run_completed');
|
|
3234
|
+
syncPausedContinuousSessionAfterOutOfBandCompletion(root, updatedState, {
|
|
3235
|
+
completed_via: 'reconciled_before_dispatch',
|
|
3236
|
+
});
|
|
3189
3237
|
recordRunHistory(root, updatedState, config, 'completed');
|
|
3190
3238
|
return {
|
|
3191
3239
|
ok: true,
|
|
@@ -6574,6 +6622,9 @@ export function approveRunCompletion(root, config, opts = {}) {
|
|
|
6574
6622
|
|
|
6575
6623
|
// Session checkpoint — non-fatal
|
|
6576
6624
|
writeSessionCheckpoint(root, updatedState, 'run_completed');
|
|
6625
|
+
syncPausedContinuousSessionAfterOutOfBandCompletion(root, updatedState, {
|
|
6626
|
+
completed_via: 'approve_run_completion',
|
|
6627
|
+
});
|
|
6577
6628
|
|
|
6578
6629
|
// Run history — non-fatal
|
|
6579
6630
|
recordRunHistory(root, updatedState, config, 'completed');
|