Expose Ranker source traces in result cards

This commit is contained in:
OpenClaw Bot
2026-05-27 15:30:34 +02:00
parent 470965b8b7
commit 5cd5dd2fcf
3 changed files with 35 additions and 7 deletions
+31 -3
View File
@@ -61,8 +61,13 @@ function parsePastedJsonPayload(value) {
try {
const parsed = JSON.parse(jsonText);
const looksLikeBridgePayload = parsed && typeof parsed === 'object' && !Array.isArray(parsed) && (
parsed.schema || parsed.featureSet || parsed.snapshot || parsed.conceptMap || parsed.buildOrder || parsed.lenses || parsed.reference_code || parsed.referenceCode || parsed.artifactId || parsed.ideaText
|| Array.isArray(parsed.nextActions) || Array.isArray(parsed.nextMoves) || Array.isArray(parsed.validateNext) || Array.isArray(parsed.deferred) || Array.isArray(parsed.parkingLot)
parsed.schema || parsed.featureSet || parsed.feature_set || parsed.snapshot || parsed.conceptMap || parsed.concept_map || parsed.buildOrder || parsed.build_order || parsed.lenses
|| parsed.payload || parsed.rankPayload || parsed.scattermindPayload || parsed.conceptMapJson
|| parsed.reference_code || parsed.referenceCode || parsed.artifactId || parsed.sourceArtifactId || parsed.source_artifact_id
|| parsed.ideaText || parsed.idea_text || parsed.originalPrompt || parsed.original_prompt || parsed.sourceSummary || parsed.source_summary || parsed.opening_reflection || parsed.restated_idea
|| Array.isArray(parsed.features) || Array.isArray(parsed.actions) || Array.isArray(parsed.candidates)
|| Array.isArray(parsed.nextActions) || Array.isArray(parsed.next_actions) || Array.isArray(parsed.nextMoves) || Array.isArray(parsed.next_moves)
|| Array.isArray(parsed.validateNext) || Array.isArray(parsed.validate_next) || Array.isArray(parsed.deferred) || Array.isArray(parsed.parkingLot) || Array.isArray(parsed.parking_lot)
);
return looksLikeBridgePayload ? parsed : null;
} catch {
@@ -105,7 +110,8 @@ function payloadFromForm(formPayload) {
const optionsJson = parsePastedJsonPayload(formPayload.optionsText);
const embedded = ideaJson || optionsJson;
if (!embedded) return formPayload;
const merged = { ...embedded };
const unwrapped = embedded.payload || embedded.rankPayload || embedded.scattermindPayload || embedded.conceptMapJson || embedded;
const merged = { ...unwrapped };
if (!merged.mode && formPayload.mode) merged.mode = formPayload.mode;
if (String(formPayload.context || '').trim() && !merged.context) merged.context = formPayload.context;
return merged;
@@ -142,6 +148,26 @@ function renderSourceTrace(sourceTrace = {}) {
`;
}
function renderItemSourceTrace(item = {}) {
const provenance = item.provenance || {};
const trace = {
sourceSection: provenance.sourceSection || '',
sourceId: provenance.sourceId || '',
sourceTitle: provenance.sourceTitle || '',
sourceQuote: provenance.sourceQuote || '',
};
const hasTrace = trace.sourceSection || trace.sourceId || trace.sourceQuote;
if (!hasTrace) return '';
const label = [trace.sourceTitle, trace.sourceId || trace.sourceSection].filter(Boolean).join(' · ');
return `
<details class="item-source-trace">
<summary>Source trace${label ? ` · ${escapeHtml(label)}` : ''}</summary>
${trace.sourceQuote ? `<p>${escapeHtml(trace.sourceQuote)}</p>` : ''}
${trace.sourceSection ? `<small>Section: ${escapeHtml(trace.sourceSection)}</small>` : ''}
</details>
`;
}
function renderHandoffStatus(handoff = {}) {
const readiness = handoff.readiness || {};
if (!readiness.status) return '';
@@ -174,6 +200,7 @@ function renderRankCard(item) {
<div><span>Evidence question</span><p>${escapeHtml(item.evidenceQuestion || 'What proof would change this ranking?')}</p></div>
<div><span>Success / kill signal</span><p>${escapeHtml(item.successSignal || '')} ${escapeHtml(item.killSignal ? `Kill if: ${item.killSignal}` : '')}</p></div>
</div>
${renderItemSourceTrace(item)}
${renderMetrics(item.metrics)}
${renderPills(item.scoringNotes || [])}
</article>
@@ -210,6 +237,7 @@ function sourceCitation(data) {
trace.sourceTitle ? `Source title: ${trace.sourceTitle}` : '',
trace.sourceQuote ? `Source quote: ${trace.sourceQuote}` : '',
source.originalPromptExcerpt ? `Original prompt: ${source.originalPromptExcerpt}` : '',
source.sourceSummaryExcerpt ? `Source summary: ${source.sourceSummaryExcerpt}` : '',
].filter(Boolean);
return parts.length ? parts.join('\n') : 'No source citation was carried into this result.';
}