agentxchain 2.65.0 → 2.66.1
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
|
@@ -167,7 +167,10 @@ export async function acceptTurnCommand(opts = {}) {
|
|
|
167
167
|
console.log(` ${chalk.dim('Cost:')} $${formatUsd(accepted.cost.usd)}`);
|
|
168
168
|
}
|
|
169
169
|
if (accepted?.verification_replay) {
|
|
170
|
-
|
|
170
|
+
const verifiedAt = accepted.verification_replay.verified_at
|
|
171
|
+
? ` at ${accepted.verification_replay.verified_at}`
|
|
172
|
+
: '';
|
|
173
|
+
console.log(` ${chalk.dim('Replay:')} ${accepted.verification_replay.overall} (${accepted.verification_replay.matched_commands}/${accepted.verification_replay.replayed_commands})${verifiedAt}`);
|
|
171
174
|
}
|
|
172
175
|
if (result.budget_warning) {
|
|
173
176
|
console.log(` ${chalk.yellow('Budget warning:')} ${result.budget_warning}`);
|
package/src/commands/step.js
CHANGED
|
@@ -1024,7 +1024,10 @@ function printAcceptSummary(result) {
|
|
|
1024
1024
|
console.log(` ${chalk.dim('Cost:')} $${(accepted.cost.usd || 0).toFixed(2)}`);
|
|
1025
1025
|
}
|
|
1026
1026
|
if (accepted?.verification_replay) {
|
|
1027
|
-
|
|
1027
|
+
const verifiedAt = accepted.verification_replay.verified_at
|
|
1028
|
+
? ` at ${accepted.verification_replay.verified_at}`
|
|
1029
|
+
: '';
|
|
1030
|
+
console.log(` ${chalk.dim('Replay:')} ${accepted.verification_replay.overall} (${accepted.verification_replay.matched_commands}/${accepted.verification_replay.replayed_commands})${verifiedAt}`);
|
|
1028
1031
|
}
|
|
1029
1032
|
console.log('');
|
|
1030
1033
|
|
|
@@ -15,6 +15,9 @@ import { renderContextSections } from './context-section-parser.js';
|
|
|
15
15
|
const COMPRESSION_STEPS = [
|
|
16
16
|
{ id: 'budget', action: 'drop' },
|
|
17
17
|
{ id: 'phase_gate_status', action: 'drop' },
|
|
18
|
+
{ id: 'decision_history', action: 'drop' },
|
|
19
|
+
{ id: 'workflow_artifacts', action: 'drop' },
|
|
20
|
+
{ id: 'last_turn_verification', action: 'drop' },
|
|
18
21
|
{ id: 'gate_required_files', action: 'drop' },
|
|
19
22
|
{ id: 'last_turn_objections', action: 'drop' },
|
|
20
23
|
{ id: 'last_turn_decisions', action: 'drop' },
|
|
@@ -3,11 +3,14 @@ const CONTEXT_TITLE = '# Execution Context';
|
|
|
3
3
|
const SECTION_DEFINITIONS = [
|
|
4
4
|
{ id: 'current_state', header: 'Current State', required: true },
|
|
5
5
|
{ id: 'budget', header: null, required: false },
|
|
6
|
+
{ id: 'project_goal', header: 'Project Goal', required: true },
|
|
7
|
+
{ id: 'inherited_run_context', header: 'Inherited Run Context', required: true },
|
|
6
8
|
{ id: 'last_turn_header', header: 'Last Accepted Turn', required: true },
|
|
7
9
|
{ id: 'last_turn_summary', header: null, required: false },
|
|
8
10
|
{ id: 'last_turn_decisions', header: null, required: false },
|
|
9
11
|
{ id: 'last_turn_objections', header: null, required: false },
|
|
10
12
|
{ id: 'last_turn_verification', header: null, required: false },
|
|
13
|
+
{ id: 'decision_history', header: 'Decision History', required: false },
|
|
11
14
|
{ id: 'blockers', header: 'Blockers', required: true },
|
|
12
15
|
{ id: 'escalation', header: 'Escalation', required: true },
|
|
13
16
|
{ id: 'workflow_artifacts', header: 'Workflow Artifacts', required: false },
|
|
@@ -79,6 +82,8 @@ export function renderContextSections(sections) {
|
|
|
79
82
|
sectionMap.get('budget')?.content,
|
|
80
83
|
]);
|
|
81
84
|
|
|
85
|
+
appendTopLevelSection(lines, 'Project Goal', [sectionMap.get('project_goal')?.content]);
|
|
86
|
+
appendTopLevelSection(lines, 'Inherited Run Context', [sectionMap.get('inherited_run_context')?.content]);
|
|
82
87
|
appendTopLevelSection(lines, 'Last Accepted Turn', [
|
|
83
88
|
sectionMap.get('last_turn_header')?.content,
|
|
84
89
|
sectionMap.get('last_turn_summary')?.content,
|
|
@@ -87,6 +92,7 @@ export function renderContextSections(sections) {
|
|
|
87
92
|
sectionMap.get('last_turn_verification')?.content,
|
|
88
93
|
]);
|
|
89
94
|
|
|
95
|
+
appendTopLevelSection(lines, 'Decision History', [sectionMap.get('decision_history')?.content]);
|
|
90
96
|
appendTopLevelSection(lines, 'Blockers', [sectionMap.get('blockers')?.content]);
|
|
91
97
|
appendTopLevelSection(lines, 'Escalation', [sectionMap.get('escalation')?.content]);
|
|
92
98
|
appendTopLevelSection(lines, 'Workflow Artifacts', [sectionMap.get('workflow_artifacts')?.content]);
|
|
@@ -30,6 +30,8 @@ import {
|
|
|
30
30
|
} from './turn-paths.js';
|
|
31
31
|
|
|
32
32
|
const HISTORY_PATH = '.agentxchain/history.jsonl';
|
|
33
|
+
const LEDGER_PATH = '.agentxchain/decision-ledger.jsonl';
|
|
34
|
+
const DECISION_HISTORY_MAX_ENTRIES = 50;
|
|
33
35
|
const FILE_PREVIEW_MAX_FILES = 5;
|
|
34
36
|
const FILE_PREVIEW_MAX_LINES = 120;
|
|
35
37
|
const PROPOSAL_SUMMARY_MAX_LINES = 80;
|
|
@@ -691,6 +693,12 @@ function renderContext(state, config, root, turn, role) {
|
|
|
691
693
|
}
|
|
692
694
|
}
|
|
693
695
|
|
|
696
|
+
// Cumulative decision history from the decision ledger
|
|
697
|
+
const decisionHistoryLines = renderDecisionHistory(root, warnings);
|
|
698
|
+
if (decisionHistoryLines.length > 0) {
|
|
699
|
+
lines.push(...decisionHistoryLines);
|
|
700
|
+
}
|
|
701
|
+
|
|
694
702
|
// Blockers / escalation
|
|
695
703
|
if (state.blocked_on) {
|
|
696
704
|
lines.push('## Blockers');
|
|
@@ -1102,6 +1110,68 @@ function writeDispatchIndex(root, state, warningsByTurn = {}) {
|
|
|
1102
1110
|
);
|
|
1103
1111
|
}
|
|
1104
1112
|
|
|
1113
|
+
/**
|
|
1114
|
+
* Read agent-authored decisions from the decision ledger and render as a
|
|
1115
|
+
* markdown section for CONTEXT.md.
|
|
1116
|
+
*
|
|
1117
|
+
* Returns an array of markdown lines (including the ## header) or an empty
|
|
1118
|
+
* array when there are no agent-authored decisions.
|
|
1119
|
+
*/
|
|
1120
|
+
function renderDecisionHistory(root, warnings = []) {
|
|
1121
|
+
const ledgerPath = join(root, LEDGER_PATH);
|
|
1122
|
+
if (!existsSync(ledgerPath)) return [];
|
|
1123
|
+
|
|
1124
|
+
let content;
|
|
1125
|
+
try {
|
|
1126
|
+
content = readFileSync(ledgerPath, 'utf8').trim();
|
|
1127
|
+
} catch (err) {
|
|
1128
|
+
warnings.push(`Failed to read ${LEDGER_PATH}: ${err.message}`);
|
|
1129
|
+
return [];
|
|
1130
|
+
}
|
|
1131
|
+
if (!content) return [];
|
|
1132
|
+
|
|
1133
|
+
// Parse all lines, skip malformed ones
|
|
1134
|
+
const rawLines = content.split('\n');
|
|
1135
|
+
const agentDecisions = [];
|
|
1136
|
+
for (const line of rawLines) {
|
|
1137
|
+
if (!line.trim()) continue;
|
|
1138
|
+
try {
|
|
1139
|
+
const entry = JSON.parse(line);
|
|
1140
|
+
// Agent-authored decisions have an `id` field; system entries do not
|
|
1141
|
+
if (entry.id) {
|
|
1142
|
+
agentDecisions.push(entry);
|
|
1143
|
+
}
|
|
1144
|
+
} catch {
|
|
1145
|
+
warnings.push(`Skipped malformed decision-ledger line`);
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
if (agentDecisions.length === 0) return [];
|
|
1150
|
+
|
|
1151
|
+
const totalCount = agentDecisions.length;
|
|
1152
|
+
const displayed = totalCount > DECISION_HISTORY_MAX_ENTRIES
|
|
1153
|
+
? agentDecisions.slice(totalCount - DECISION_HISTORY_MAX_ENTRIES)
|
|
1154
|
+
: agentDecisions;
|
|
1155
|
+
|
|
1156
|
+
const lines = [];
|
|
1157
|
+
lines.push('## Decision History');
|
|
1158
|
+
lines.push('');
|
|
1159
|
+
lines.push('| ID | Phase | Role | Statement |');
|
|
1160
|
+
lines.push('|----|-------|------|-----------|');
|
|
1161
|
+
for (const d of displayed) {
|
|
1162
|
+
// Escape pipes in statement to avoid breaking the table
|
|
1163
|
+
const stmt = (d.statement || '').replace(/\|/g, '\\|').replace(/\n/g, ' ');
|
|
1164
|
+
lines.push(`| ${d.id} | ${d.phase || ''} | ${d.role || ''} | ${stmt} |`);
|
|
1165
|
+
}
|
|
1166
|
+
if (totalCount > DECISION_HISTORY_MAX_ENTRIES) {
|
|
1167
|
+
lines.push('');
|
|
1168
|
+
lines.push(`_Showing ${DECISION_HISTORY_MAX_ENTRIES} of ${totalCount} decisions. Full ledger at ${LEDGER_PATH}._`);
|
|
1169
|
+
}
|
|
1170
|
+
lines.push('');
|
|
1171
|
+
|
|
1172
|
+
return lines;
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1105
1175
|
function readLastHistoryEntry(root, warnings = []) {
|
|
1106
1176
|
const historyPath = join(root, HISTORY_PATH);
|
|
1107
1177
|
if (!existsSync(historyPath)) return null;
|
|
@@ -3,11 +3,13 @@ import { spawnSync } from 'node:child_process';
|
|
|
3
3
|
export const DEFAULT_VERIFICATION_REPLAY_TIMEOUT_MS = 30_000;
|
|
4
4
|
|
|
5
5
|
export function replayVerificationMachineEvidence({ root, verification, timeoutMs = DEFAULT_VERIFICATION_REPLAY_TIMEOUT_MS }) {
|
|
6
|
+
const verifiedAt = new Date().toISOString();
|
|
6
7
|
const machineEvidence = Array.isArray(verification?.machine_evidence)
|
|
7
8
|
? verification.machine_evidence
|
|
8
9
|
: [];
|
|
9
10
|
|
|
10
11
|
const payload = {
|
|
12
|
+
verified_at: verifiedAt,
|
|
11
13
|
timeout_ms: timeoutMs,
|
|
12
14
|
overall: 'not_reproducible',
|
|
13
15
|
replayed_commands: 0,
|
|
@@ -59,6 +61,7 @@ export function summarizeVerificationReplay(payload) {
|
|
|
59
61
|
}
|
|
60
62
|
|
|
61
63
|
return {
|
|
64
|
+
verified_at: payload.verified_at || null,
|
|
62
65
|
overall: payload.overall,
|
|
63
66
|
replayed_commands: payload.replayed_commands || 0,
|
|
64
67
|
matched_commands: payload.matched_commands || 0,
|