Pretty print fenced JSON in admin AI replies
Build and publish frontend / publish (push) Successful in 1m14s
Build and publish frontend / publish (push) Successful in 1m14s
This commit is contained in:
+44
-1
@@ -59,6 +59,9 @@
|
||||
.json-long-text { margin: .2rem .5rem .5rem; padding: .5rem; max-height: 24rem; overflow: auto; background: #e2e8f0; white-space: pre-wrap; overflow-wrap: anywhere; }
|
||||
.json-raw-value { margin-inline-start: .5rem; color: #475569; font-size: .9em; }
|
||||
.json-raw-value > .json-long-text { border-inline-start: 2px solid #94a3b8; }
|
||||
.admin-ai-response { margin: .35rem 0 .75rem; }
|
||||
.admin-ai-response-text { white-space: pre-wrap; overflow-wrap: anywhere; }
|
||||
.admin-ai-response-code { max-width: 100%; overflow: auto; padding: .65rem; border-inline-start: 2px solid #94a3b8; white-space: pre-wrap; overflow-wrap: anywhere; }
|
||||
@media (max-width: 42rem) { .json-entry { grid-template-columns: 1fr; gap: .05rem; } }
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.json-view { border-color: #475569; background: #111827; color: #e5e7eb; }
|
||||
@@ -842,6 +845,43 @@
|
||||
renderJsonTree(adminElement('div', undefined, details), value);
|
||||
return details;
|
||||
}
|
||||
function parseAiResponseSegments(response) {
|
||||
const text = String(response ?? '');
|
||||
const fencedJson = /```json\s*([\s\S]*?)```/gi;
|
||||
const segments = [];
|
||||
let cursor = 0;
|
||||
for (const match of text.matchAll(fencedJson)) {
|
||||
const index = match.index ?? cursor;
|
||||
if (index > cursor) segments.push({type: 'text', value: text.slice(cursor, index)});
|
||||
const source = match[1].trim();
|
||||
try {
|
||||
segments.push({type: 'json', value: JSON.parse(source)});
|
||||
} catch (_) {
|
||||
segments.push({type: 'code', value: source});
|
||||
}
|
||||
cursor = index + match[0].length;
|
||||
}
|
||||
if (cursor < text.length || segments.length === 0) segments.push({type: 'text', value: text.slice(cursor)});
|
||||
return segments;
|
||||
}
|
||||
function renderAdminAiResponse(parent, response) {
|
||||
const segments = parseAiResponseSegments(response);
|
||||
if (!segments.some(segment => segment.type === 'json' || segment.type === 'code')) return false;
|
||||
const output = adminElement('section', undefined, parent);
|
||||
output.className = 'admin-ai-response';
|
||||
for (const segment of segments) {
|
||||
if (segment.type === 'json') {
|
||||
adminJson('JSON-svar · formaterat', segment.value, output);
|
||||
} else if (segment.type === 'code') {
|
||||
const code = adminElement('pre', segment.value, output);
|
||||
code.className = 'admin-ai-response-code';
|
||||
} else if (segment.value.trim()) {
|
||||
const text = adminElement('p', decodeEscapedSequences(segment.value.trim()), output);
|
||||
text.className = 'admin-ai-response-text';
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
async function loadAdminPlayers(query = '', offset = 0) {
|
||||
adminOffset = offset;
|
||||
adminContent.replaceChildren();
|
||||
@@ -969,8 +1009,11 @@
|
||||
}
|
||||
for (const interaction of group.interactions) {
|
||||
if (!interaction.response) continue;
|
||||
const button = adminElement('button', `AI-svar · ${interaction.prompt_id} · ${interaction.outcome}: ${interaction.response}`, card);
|
||||
const responseHasJson = parseAiResponseSegments(interaction.response).some(segment => segment.type === 'json' || segment.type === 'code');
|
||||
const responseButtonLabel = `AI-svar · ${interaction.prompt_id} · ${interaction.outcome}${responseHasJson ? ' · JSON' : `: ${interaction.response}`}`;
|
||||
const button = adminElement('button', responseButtonLabel, card);
|
||||
button.type = 'button'; button.setAttribute('aria-expanded', 'false');
|
||||
if (responseHasJson) renderAdminAiResponse(card, interaction.response);
|
||||
const detail = adminElement('section', undefined, card); detail.hidden = true;
|
||||
button.addEventListener('click', () => {
|
||||
detail.hidden = !detail.hidden; button.setAttribute('aria-expanded', String(!detail.hidden));
|
||||
|
||||
Reference in New Issue
Block a user