agentxchain 2.74.0 → 2.75.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.
- package/dashboard/app.js +1 -1
- package/dashboard/components/timeline.js +57 -35
- package/package.json +1 -1
package/dashboard/app.js
CHANGED
|
@@ -19,7 +19,7 @@ import { render as renderTimeouts } from './components/timeouts.js';
|
|
|
19
19
|
import { render as renderCoordinatorTimeouts } from './components/coordinator-timeouts.js';
|
|
20
20
|
|
|
21
21
|
const VIEWS = {
|
|
22
|
-
timeline: { fetch: ['state', 'continuity', 'history', 'audit', 'annotations', 'connectors'], render: renderTimeline },
|
|
22
|
+
timeline: { fetch: ['state', 'continuity', 'history', 'audit', 'annotations', 'connectors', 'coordinatorAudit', 'coordinatorAnnotations'], render: renderTimeline },
|
|
23
23
|
ledger: { fetch: ['state', 'ledger', 'coordinatorState', 'coordinatorLedger'], render: renderLedger },
|
|
24
24
|
hooks: { fetch: ['audit', 'annotations', 'coordinatorAudit', 'coordinatorAnnotations'], render: renderHooks },
|
|
25
25
|
blocked: { fetch: ['state', 'audit', 'coordinatorState', 'coordinatorAudit'], render: renderBlocked },
|
|
@@ -114,52 +114,74 @@ function roleBadge(role) {
|
|
|
114
114
|
return `<span class="badge" style="color:${color};border-color:${color}">${esc(role)}</span>`;
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
-
function
|
|
117
|
+
function renderAuditSection(title, auditEntries) {
|
|
118
|
+
if (auditEntries.length === 0) return '';
|
|
119
|
+
let html = `<div class="turn-detail"><span class="detail-label">${esc(title)} (${auditEntries.length}):</span>
|
|
120
|
+
<table class="data-table">
|
|
121
|
+
<thead><tr><th>Phase</th><th>Hook</th><th>Verdict</th></tr></thead>
|
|
122
|
+
<tbody>`;
|
|
123
|
+
for (const entry of auditEntries) {
|
|
124
|
+
const phase = entry.hook_phase || entry.phase || '';
|
|
125
|
+
const hook = entry.hook_name || entry.hook || entry.name || '';
|
|
126
|
+
html += `<tr>
|
|
127
|
+
<td class="mono">${esc(phase)}</td>
|
|
128
|
+
<td>${esc(hook)}</td>
|
|
129
|
+
<td>${esc(entry.verdict || '')}</td>
|
|
130
|
+
</tr>`;
|
|
131
|
+
}
|
|
132
|
+
html += `</tbody></table></div>`;
|
|
133
|
+
return html;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function renderAnnotationSection(title, annotationEntries) {
|
|
137
|
+
if (annotationEntries.length === 0) return '';
|
|
138
|
+
let html = `<div class="turn-detail"><span class="detail-label">${esc(title)} (${annotationEntries.length}):</span><ul>`;
|
|
139
|
+
for (const ann of annotationEntries) {
|
|
140
|
+
const hookName = ann.hook_name || ann.hook || ann.name || '';
|
|
141
|
+
if (Array.isArray(ann.annotations)) {
|
|
142
|
+
for (const a of ann.annotations) {
|
|
143
|
+
html += `<li>${esc(hookName)}: ${esc(a.key || '')} = ${esc(a.value || '')}</li>`;
|
|
144
|
+
}
|
|
145
|
+
} else {
|
|
146
|
+
const text = ann.annotation || ann.message || '';
|
|
147
|
+
html += `<li>${esc(hookName)}: ${esc(text)}</li>`;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
html += `</ul></div>`;
|
|
151
|
+
return html;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function renderTurnDetailPanel(turnId, annotations, audit, coordinatorAnnotations, coordinatorAudit) {
|
|
118
155
|
const turnAnnotations = Array.isArray(annotations)
|
|
119
156
|
? annotations.filter((a) => a.turn_id === turnId)
|
|
120
157
|
: [];
|
|
121
158
|
const turnAudit = Array.isArray(audit)
|
|
122
159
|
? audit.filter((a) => a.turn_id === turnId)
|
|
123
160
|
: [];
|
|
161
|
+
const turnCoordAnnotations = Array.isArray(coordinatorAnnotations)
|
|
162
|
+
? coordinatorAnnotations.filter((a) => a.turn_id === turnId)
|
|
163
|
+
: [];
|
|
164
|
+
const turnCoordAudit = Array.isArray(coordinatorAudit)
|
|
165
|
+
? coordinatorAudit.filter((a) => a.turn_id === turnId)
|
|
166
|
+
: [];
|
|
167
|
+
|
|
168
|
+
const hasRepo = turnAnnotations.length > 0 || turnAudit.length > 0;
|
|
169
|
+
const hasCoord = turnCoordAnnotations.length > 0 || turnCoordAudit.length > 0;
|
|
124
170
|
|
|
125
|
-
if (
|
|
171
|
+
if (!hasRepo && !hasCoord) {
|
|
126
172
|
return `<div class="turn-detail-panel"><p class="turn-detail">No hook evidence for this turn.</p></div>`;
|
|
127
173
|
}
|
|
128
174
|
|
|
175
|
+
const dual = hasRepo && hasCoord;
|
|
129
176
|
let html = `<div class="turn-detail-panel">`;
|
|
130
177
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
<thead><tr><th>Phase</th><th>Hook</th><th>Verdict</th></tr></thead>
|
|
135
|
-
<tbody>`;
|
|
136
|
-
for (const entry of turnAudit) {
|
|
137
|
-
const phase = entry.hook_phase || entry.phase || '';
|
|
138
|
-
const hook = entry.hook_name || entry.hook || entry.name || '';
|
|
139
|
-
html += `<tr>
|
|
140
|
-
<td class="mono">${esc(phase)}</td>
|
|
141
|
-
<td>${esc(hook)}</td>
|
|
142
|
-
<td>${esc(entry.verdict || '')}</td>
|
|
143
|
-
</tr>`;
|
|
144
|
-
}
|
|
145
|
-
html += `</tbody></table></div>`;
|
|
146
|
-
}
|
|
178
|
+
// Repo-local hook evidence
|
|
179
|
+
html += renderAuditSection(dual ? 'Repo Hook Audit Log' : 'Hook Audit Log', turnAudit);
|
|
180
|
+
html += renderAnnotationSection(dual ? 'Repo Hook Annotations' : 'Hook Annotations', turnAnnotations);
|
|
147
181
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
const hookName = ann.hook_name || ann.hook || ann.name || '';
|
|
152
|
-
if (Array.isArray(ann.annotations)) {
|
|
153
|
-
for (const a of ann.annotations) {
|
|
154
|
-
html += `<li>${esc(hookName)}: ${esc(a.key || '')} = ${esc(a.value || '')}</li>`;
|
|
155
|
-
}
|
|
156
|
-
} else {
|
|
157
|
-
const text = ann.annotation || ann.message || '';
|
|
158
|
-
html += `<li>${esc(hookName)}: ${esc(text)}</li>`;
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
html += `</ul></div>`;
|
|
162
|
-
}
|
|
182
|
+
// Coordinator hook evidence
|
|
183
|
+
html += renderAuditSection(dual ? 'Coordinator Hook Audit Log' : 'Hook Audit Log', turnCoordAudit);
|
|
184
|
+
html += renderAnnotationSection(dual ? 'Coordinator Hook Annotations' : 'Hook Annotations', turnCoordAnnotations);
|
|
163
185
|
|
|
164
186
|
html += `</div>`;
|
|
165
187
|
return html;
|
|
@@ -265,7 +287,7 @@ function renderConnectorHealthPanel(connectorsPayload) {
|
|
|
265
287
|
|
|
266
288
|
export { formatDuration, computeElapsed, formatTimestamp };
|
|
267
289
|
|
|
268
|
-
export function render({ state, continuity, history, annotations, audit, connectors }) {
|
|
290
|
+
export function render({ state, continuity, history, annotations, audit, connectors, coordinatorAudit = null, coordinatorAnnotations = null }) {
|
|
269
291
|
if (!state) {
|
|
270
292
|
return `<div class="placeholder"><h2>No Run</h2><p>No governed run found. Start one with <code class="mono">agentxchain init --governed</code></p></div>`;
|
|
271
293
|
}
|
|
@@ -353,7 +375,7 @@ export function render({ state, continuity, history, annotations, audit, connect
|
|
|
353
375
|
html += `<div class="turn-detail"><span class="detail-label">Verification:</span> ${esc(verificationSummary)}</div>`;
|
|
354
376
|
}
|
|
355
377
|
|
|
356
|
-
html += renderTurnDetailPanel(entry.turn_id, annotations, audit);
|
|
378
|
+
html += renderTurnDetailPanel(entry.turn_id, annotations, audit, coordinatorAnnotations, coordinatorAudit);
|
|
357
379
|
|
|
358
380
|
html += `</div>`;
|
|
359
381
|
}
|