193 lines
25 KiB
Plaintext
193 lines
25 KiB
Plaintext
<%- include("../../../src/web/views/partials/layout-top", { title }) %>
|
|
<link rel="stylesheet" href="/plugins/lumi_ai/assets/settings.css?v=0.8.5" />
|
|
<link rel="stylesheet" href="/plugins/lumi_ai/assets/improvement-center.css?v=0.8.5" />
|
|
|
|
<% const statusLabel = (status) => ({ pending: "New", flagged: "Needs attention", verified: "Reviewed by moderator", approved: "Ready to apply", implemented: "Applied", rejected: "Dismissed", reviewed: "No change needed", archived: "Archived" }[status] || status); %>
|
|
<section class="ai-titlebar improvement-titlebar">
|
|
<div>
|
|
<h1>Improve Lumi AI</h1>
|
|
<p>Review feedback and either apply an improvement or close it. Finished items move to searchable history automatically.</p>
|
|
</div>
|
|
<span class="ai-tag"><%= access.role %><%= access.trusted ? " · trusted reviewer" : "" %></span>
|
|
<% if (access.can_approve) { %><a class="button subtle" href="/plugins/lumi_ai">AI settings</a><% } %>
|
|
</section>
|
|
|
|
<div class="improvement-live-status" data-improvement-status role="status" aria-live="polite"></div>
|
|
|
|
<div data-improvement-workspace>
|
|
<section class="ai-band improvement-guide" aria-labelledby="improvement-guide-title">
|
|
<div class="ai-section-heading">
|
|
<div><h2 id="improvement-guide-title">A simpler review process</h2><p>The usual path takes one decision and no manual activation step.</p></div>
|
|
<button class="button subtle" type="button" data-open-history>Search finished feedback (<%= reviewCounts.history %>)</button>
|
|
</div>
|
|
<ol class="improvement-steps">
|
|
<li><span>1</span><div><strong>Read the report</strong><small>Compare the question, Lumi's answer, and the user's suggestion.</small></div></li>
|
|
<li><span>2</span><div><strong>Choose an outcome</strong><small>Apply the improvement, dismiss it, or mark that no change is needed.</small></div></li>
|
|
<li><span>3</span><div><strong>Done automatically</strong><small>Applied corrections become active immediately. Finished reports move to history.</small></div></li>
|
|
</ol>
|
|
<div class="improvement-counts" aria-label="Feedback queue summary">
|
|
<div><span>Active queue</span><strong><%= reviewCounts.active %></strong></div>
|
|
<div><span>New</span><strong><%= reviewCounts.pending %></strong></div>
|
|
<div><span>Needs attention</span><strong><%= reviewCounts.needs_attention %></strong></div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="ai-band" id="reviews">
|
|
<div class="ai-section-heading">
|
|
<div><h2>Feedback waiting for review</h2><p>Finished feedback is hidden from this queue and remains available in history.</p></div>
|
|
<button class="button subtle" type="button" data-open-history>Open history</button>
|
|
</div>
|
|
<div class="improvement-list">
|
|
<% reviews.entries.forEach((review) => { const snapshot = review.context_snapshot || {}; const retrieval = snapshot.retrieval || {}; const snapshotRows = [...(snapshot.okf || []), ...(snapshot.corrections || []), ...(snapshot.repository || [])]; %>
|
|
<article class="improvement-card" id="review-<%= review.id %>" data-review-id="<%= review.id %>">
|
|
<header>
|
|
<div class="improvement-card-labels"><strong><%= review.rating === "up" ? "Helpful response" : "Response needs work" %></strong><span class="ai-tag status-<%= review.status %>"><%= statusLabel(review.status) %></span><span class="ai-tag"><%= review.feedback_tag.replaceAll("_", " ") %></span></div>
|
|
<span><%= formatDate(review.timestamp) %> · <%= review.role %> · <%= review.platform %></span>
|
|
</header>
|
|
<div class="improvement-pair">
|
|
<div><span>User asked</span><pre><%= review.user_message %></pre></div>
|
|
<div><span>Lumi answered</span><pre><%= review.assistant_answer %></pre></div>
|
|
</div>
|
|
<% if (review.optional_correction) { %><div class="improvement-correction"><strong>User's suggested improvement</strong><pre><%= review.optional_correction %></pre></div><% } %>
|
|
<% if (review.review_notes) { %><div class="improvement-review-note"><strong>Reviewer note</strong><p><%= review.review_notes %></p></div><% } %>
|
|
<% if (snapshotRows.length || retrieval.query || (snapshot.tools || []).length) { %>
|
|
<details class="lumi-expandable-settings">
|
|
<summary><strong>What Lumi used to answer</strong><span class="hint"><%= retrieval.selected_count || snapshotRows.length %> source(s) selected</span></summary>
|
|
<div class="lumi-expandable-body">
|
|
<% if (retrieval.query) { %><p class="hint"><strong>Knowledge lookup:</strong> <%= retrieval.query %></p><% } %>
|
|
<% snapshotRows.forEach((source) => { %><pre><%= source %></pre><% }) %>
|
|
<% if ((snapshot.tools || []).length) { %><p class="hint"><strong>Tools available:</strong> <%= snapshot.tools.join(", ") %></p><% } %>
|
|
</div>
|
|
</details>
|
|
<% } %>
|
|
<div class="improvement-decision-row">
|
|
<% if (access.can_implement) { %>
|
|
<button class="button" type="button" data-open-dialog="implement-<%= review.id %>">Apply improvement</button>
|
|
<form method="post" action="/plugins/lumi_ai/improvement_center/reviews/<%= review.id %>" data-improvement-action>
|
|
<input type="hidden" name="action" value="reviewed" />
|
|
<button class="button subtle" type="submit">No change needed</button>
|
|
</form>
|
|
<form method="post" action="/plugins/lumi_ai/improvement_center/reviews/<%= review.id %>" data-improvement-action>
|
|
<input type="hidden" name="action" value="reject" />
|
|
<button class="button subtle" type="submit">Dismiss feedback</button>
|
|
</form>
|
|
<button class="button subtle" type="button" data-open-dialog="edit-<%= review.id %>">Edit details</button>
|
|
<% } else { %>
|
|
<% if (access.can_verify) { %><form method="post" action="/plugins/lumi_ai/improvement_center/reviews/<%= review.id %>" data-improvement-action><input type="hidden" name="action" value="verify" /><button class="button" type="submit">Reviewed — send to admin</button></form><% } %>
|
|
<% if (access.can_flag) { %><form method="post" action="/plugins/lumi_ai/improvement_center/reviews/<%= review.id %>" data-improvement-action><input type="hidden" name="action" value="flag" /><button class="button subtle" type="submit">Needs closer review</button></form><% } %>
|
|
<% } %>
|
|
</div>
|
|
</article>
|
|
|
|
<% if (access.can_edit) { %>
|
|
<dialog class="improvement-dialog" id="edit-<%= review.id %>">
|
|
<div class="improvement-dialog-heading"><div><h3>Edit feedback details</h3><p>Clarify the report without changing its outcome.</p></div><button class="icon-button" type="button" data-close-dialog aria-label="Close">×</button></div>
|
|
<form method="post" action="/plugins/lumi_ai/improvement_center/reviews/<%= review.id %>" class="form-grid ai-form" data-improvement-action>
|
|
<input type="hidden" name="action" value="edit" />
|
|
<div class="field"><label>Problem type</label><select name="feedback_tag"><% feedbackTags.forEach((tag) => { %><option value="<%= tag %>" <%= tag === review.feedback_tag ? "selected" : "" %>><%= tag.replaceAll("_", " ") %></option><% }) %></select></div>
|
|
<div class="field"><label>Improvement style</label><select name="feedback_kind"><% feedbackKinds.forEach((kind) => { %><option value="<%= kind %>" <%= kind === (review.feedback_kind || "instruction_based") ? "selected" : "" %>><%= kind === "instruction_based" ? "Behavior guidance" : "Exact correction" %></option><% }) %></select></div>
|
|
<div class="field full"><label>Suggested improvement</label><textarea name="optional_correction" rows="6"><%= review.optional_correction %></textarea></div>
|
|
<div class="field full"><label>Private reviewer note</label><textarea name="review_notes" rows="3"><%= review.review_notes %></textarea></div>
|
|
<div class="field full improvement-actions"><button class="button" type="submit">Save details</button><button class="button subtle" type="button" data-close-dialog>Cancel</button></div>
|
|
</form>
|
|
</dialog>
|
|
<% } %>
|
|
|
|
<% if (access.can_implement) { %>
|
|
<dialog class="improvement-dialog" id="implement-<%= review.id %>">
|
|
<div class="improvement-dialog-heading"><div><h3>Apply this improvement</h3><p>Tell Lumi what it should do instead. Saving here activates the change and finishes the feedback.</p></div><button class="icon-button" type="button" data-close-dialog aria-label="Close">×</button></div>
|
|
<form method="post" action="/plugins/lumi_ai/improvement_center/reviews/<%= review.id %>/implement" class="form-grid ai-form" data-improvement-action>
|
|
<div class="field full"><label>What should Lumi do instead?</label><textarea name="corrected_answer" rows="8" required placeholder="Write the answer or behavior Lumi should use for similar requests."><%= review.optional_correction %></textarea><span class="hint">Use clear, user-facing wording. This becomes the reviewed guidance for similar requests.</span></div>
|
|
<div class="field"><label>Who may receive this improvement?</label><select name="min_role"><% [["user", "Everyone"], ["mod", "Moderators and admins"], ["admin", "Admins only"]].forEach(([role, label]) => { %><option value="<%= role %>" <%= role === review.role ? "selected" : "" %>><%= label %></option><% }) %></select></div>
|
|
<div class="field"><label class="checkbox-inline"><input type="checkbox" name="enabled" checked /><span>Start using it immediately</span></label></div>
|
|
<details class="field full ai-settings-group">
|
|
<summary>Advanced options</summary>
|
|
<div class="form-grid ai-form improvement-advanced-fields">
|
|
<div class="field"><label>Apply as</label><select name="target"><option value="correction">Answer or behavior guidance</option><option value="predefined_answer">Exact predefined answer</option><option value="route_alias">Route/link answer</option><option value="eval_case">Test case only</option><option value="training_export">Training export only</option></select></div>
|
|
<div class="field"><label>Searchable knowledge title</label><input name="okf_title" placeholder="Short title for this improvement" /></div>
|
|
<div class="field"><label>Origin</label><input name="permission_origin" value="<%= review.origin || "any" %>" /></div>
|
|
<div class="field"><label>Platform</label><input name="permission_platform" value="<%= review.platform || "any" %>" /></div>
|
|
<div class="field"><label>Route alias</label><input name="route_alias" /></div>
|
|
<div class="field"><label>Verified Lumi link</label><input name="expected_link" placeholder="/verified/path" /></div>
|
|
<div class="field full"><label>Behavior Lumi must avoid</label><textarea name="forbidden_behavior" rows="2"></textarea></div>
|
|
<div class="field full"><label>Implementation note</label><textarea name="notes" rows="2"></textarea></div>
|
|
<div class="field"><label class="checkbox-inline"><input type="checkbox" name="explicitly_safe" /><span>Safe as an exact predefined answer</span></label></div>
|
|
</div>
|
|
</details>
|
|
<div class="field full improvement-actions"><button class="button" type="submit">Apply and finish</button><button class="button subtle" type="button" data-close-dialog>Cancel</button></div>
|
|
</form>
|
|
</dialog>
|
|
<% } %>
|
|
<% }) %>
|
|
<% if (!reviews.entries.length) { %><div class="improvement-empty"><strong>The queue is clear.</strong><p>New AI feedback will appear here automatically.</p><button class="button subtle" type="button" data-open-history>Search finished feedback</button></div><% } %>
|
|
</div>
|
|
<% if (reviews.pages > 1) { %><div class="table-pagination"><a class="button subtle <%= reviews.page <= 1 ? "disabled" : "" %>" href="?review_page=<%= Math.max(1, reviews.page - 1) %>#reviews" data-improvement-page>Previous</a><span class="table-page-label">Page <%= reviews.page %> of <%= reviews.pages %></span><a class="button subtle <%= reviews.page >= reviews.pages ? "disabled" : "" %>" href="?review_page=<%= Math.min(reviews.pages, reviews.page + 1) %>#reviews" data-improvement-page>Next</a></div><% } %>
|
|
</section>
|
|
|
|
<dialog class="improvement-dialog improvement-history-dialog" id="improvement-history">
|
|
<div class="improvement-dialog-heading"><div><h2>Finished feedback history</h2><p>Search, inspect, restore, edit, or permanently delete earlier decisions.</p></div><button class="icon-button" type="button" data-close-dialog aria-label="Close history">×</button></div>
|
|
<form class="improvement-history-search" method="get" action="/plugins/lumi_ai/improvement_center" data-improvement-history-search>
|
|
<label class="field"><span>Search feedback</span><input type="search" name="history_q" value="<%= historyQuery %>" placeholder="Question, answer, tag, note, or status" /></label>
|
|
<label class="field"><span>Outcome</span><select name="history_status"><option value="">All finished feedback</option><% [["implemented", "Applied"], ["rejected", "Dismissed"], ["reviewed", "No change needed"], ["archived", "Archived"]].forEach(([value, label]) => { %><option value="<%= value %>" <%= historyStatus === value ? "selected" : "" %>><%= label %></option><% }) %></select></label>
|
|
<button class="button" type="submit">Search</button>
|
|
<button class="button subtle" type="button" data-history-clear>Clear</button>
|
|
</form>
|
|
<div class="improvement-history-list">
|
|
<% historyReviews.entries.forEach((review) => { %>
|
|
<article class="improvement-card history-card">
|
|
<header><div class="improvement-card-labels"><strong><%= statusLabel(review.status) %></strong><span class="ai-tag status-<%= review.status %>"><%= statusLabel(review.status) %></span><span class="ai-tag"><%= review.feedback_tag.replaceAll("_", " ") %></span></div><span><%= formatDate(review.reviewed_at || review.timestamp) %></span></header>
|
|
<details>
|
|
<summary><%= review.user_message.slice(0, 180) %><%= review.user_message.length > 180 ? "…" : "" %></summary>
|
|
<div class="improvement-pair"><div><span>User asked</span><pre><%= review.user_message %></pre></div><div><span>Lumi answered</span><pre><%= review.assistant_answer %></pre></div></div>
|
|
<% if (review.optional_correction) { %><div class="improvement-correction"><strong>Suggested improvement</strong><pre><%= review.optional_correction %></pre></div><% } %>
|
|
<% if (review.implementation_summary) { %><div class="callout success"><strong>What was applied</strong><p><%= review.implementation_summary %></p></div><% } %>
|
|
<% if (review.review_notes) { %><p><strong>Reviewer note:</strong> <%= review.review_notes %></p><% } %>
|
|
<% if (review.linked_okf_correction) { %><p><a href="/plugins/okf?q=<%= encodeURIComponent(review.user_message.slice(0, 80)) %>">Open searchable knowledge entry</a></p><% } %>
|
|
</details>
|
|
<% if (access.can_edit) { %><div class="improvement-actions"><form method="post" action="/plugins/lumi_ai/improvement_center/reviews/<%= review.id %>" data-improvement-action><input type="hidden" name="action" value="restore" /><button class="button subtle" type="submit">Restore to queue</button></form><button class="button subtle" type="button" data-open-dialog="history-edit-<%= review.id %>">Edit details</button><form method="post" action="/plugins/lumi_ai/improvement_center/reviews/<%= review.id %>/delete" data-improvement-action data-confirm-mode="modal" data-confirm-title="Delete feedback record" data-confirm-text="Permanently delete this finished feedback record?" data-confirm-label="Delete feedback"><button class="button danger" type="submit">Delete permanently</button></form></div><% } %>
|
|
</article>
|
|
<% if (access.can_edit) { %><dialog class="improvement-dialog" id="history-edit-<%= review.id %>"><div class="improvement-dialog-heading"><h3>Edit finished feedback</h3><button class="icon-button" type="button" data-close-dialog aria-label="Close">×</button></div><form method="post" action="/plugins/lumi_ai/improvement_center/reviews/<%= review.id %>" class="form-grid ai-form" data-improvement-action><input type="hidden" name="action" value="edit" /><div class="field"><label>Problem type</label><select name="feedback_tag"><% feedbackTags.forEach((tag) => { %><option value="<%= tag %>" <%= tag === review.feedback_tag ? "selected" : "" %>><%= tag.replaceAll("_", " ") %></option><% }) %></select></div><input type="hidden" name="feedback_kind" value="<%= review.feedback_kind || "instruction_based" %>" /><div class="field full"><label>Suggested improvement</label><textarea name="optional_correction" rows="6"><%= review.optional_correction %></textarea></div><div class="field full"><label>Reviewer note</label><textarea name="review_notes" rows="3"><%= review.review_notes %></textarea></div><div class="field full improvement-actions"><button class="button" type="submit">Save details</button><button class="button subtle" type="button" data-close-dialog>Cancel</button></div></form></dialog><% } %>
|
|
<% }) %>
|
|
<% if (!historyReviews.entries.length) { %><div class="improvement-empty"><strong>No finished feedback found.</strong><p>Try a different search or status.</p></div><% } %>
|
|
</div>
|
|
<% if (historyReviews.pages > 1) { %><div class="table-pagination"><a class="button subtle <%= historyReviews.page <= 1 ? "disabled" : "" %>" href="?history_q=<%= encodeURIComponent(historyQuery) %>&history_status=<%= historyStatus %>&history_page=<%= Math.max(1, historyReviews.page - 1) %>" data-improvement-history-page>Previous</a><span class="table-page-label">Page <%= historyReviews.page %> of <%= historyReviews.pages %> (<%= historyReviews.total %> records)</span><a class="button subtle <%= historyReviews.page >= historyReviews.pages ? "disabled" : "" %>" href="?history_q=<%= encodeURIComponent(historyQuery) %>&history_status=<%= historyStatus %>&history_page=<%= Math.min(historyReviews.pages, historyReviews.page + 1) %>" data-improvement-history-page>Next</a></div><% } %>
|
|
</dialog>
|
|
|
|
<% if (access.can_approve) { %>
|
|
<details class="ai-band improvement-advanced" id="advanced-tools">
|
|
<summary><span><strong>Advanced tools and access</strong><small>Correction bank, moderator access, evaluation cases, and training exports</small></span></summary>
|
|
<div class="improvement-advanced-body">
|
|
<section>
|
|
<div class="ai-section-heading"><div><h2>Review access</h2><p>Choose whether selected moderators may help triage feedback.</p></div></div>
|
|
<form method="post" action="/plugins/lumi_ai/improvement_center/settings" class="form-grid ai-form" data-improvement-action>
|
|
<div class="field"><label class="checkbox-inline"><input type="checkbox" name="allow_moderators_to_review_responses" <%= config.improvement.allow_moderators_to_review_responses ? "checked" : "" %> /><span>Allow moderators to review responses</span></label></div>
|
|
<div class="field"><label class="checkbox-inline"><input type="checkbox" name="corrections_enabled" <%= config.improvement.corrections_enabled ? "checked" : "" %> /><span>Use active reviewed corrections</span></label></div>
|
|
<div class="field full"><label>Trusted moderator reviewer IDs</label><textarea name="trusted_moderator_reviewers" rows="2"><%= config.improvement.trusted_moderator_reviewers.join("\n") %></textarea></div>
|
|
<div class="field full"><button class="button" type="submit">Save access</button></div>
|
|
</form>
|
|
</section>
|
|
|
|
<section id="corrections">
|
|
<div class="ai-section-heading"><div><h2>Correction bank</h2><p>Normal “Apply improvement” actions are saved immediately. Use this table for manual maintenance.</p></div><form method="post" action="/plugins/lumi_ai/improvement_center/corrections/save" data-improvement-action><button class="button subtle" type="submit">Activate staged changes</button></form></div>
|
|
<div class="table-wrap"><table class="table"><thead><tr><th>Type</th><th>Prompt / answer</th><th>Audience</th><th>State</th><th>Actions</th></tr></thead><tbody>
|
|
<% corrections.entries.forEach((entry) => { %><tr><td><%= entry.target.replaceAll("_", " ") %></td><td><details><summary><%= entry.prompt.slice(0, 100) %></summary><pre><%= entry.corrected_answer %></pre></details></td><td><%= entry.min_role %> · <%= entry.permission_scope.origin %>/<%= entry.permission_scope.platform %></td><td><span class="ai-tag"><%= entry.active ? "active" : entry.enabled ? "staged" : "disabled" %></span></td><td class="improvement-actions"><% if (entry.linked_okf_path) { %><a class="button subtle" href="/plugins/okf?q=<%= encodeURIComponent(entry.prompt.slice(0, 80)) %>">Open knowledge</a><% } %><form method="post" action="/plugins/lumi_ai/improvement_center/corrections/<%= entry.id %>" data-improvement-action><input type="hidden" name="action" value="toggle" /><input type="hidden" name="enabled" value="<%= entry.enabled ? "off" : "on" %>" /><button class="button subtle" type="submit"><%= entry.enabled ? "Disable" : "Enable" %></button></form><form method="post" action="/plugins/lumi_ai/improvement_center/corrections/<%= entry.id %>/delete" data-improvement-action data-confirm-mode="modal" data-confirm-title="Delete correction" data-confirm-text="Delete this correction permanently?" data-confirm-label="Delete correction"><button class="button danger" type="submit">Delete</button></form></td></tr><% }) %>
|
|
<% if (!corrections.entries.length) { %><tr><td colspan="5">No corrections have been created.</td></tr><% } %>
|
|
</tbody></table></div>
|
|
</section>
|
|
|
|
<section id="evals">
|
|
<div class="ai-section-heading"><div><h2>Evaluation cases</h2><p>Optional technical tests for checking the current AI configuration.</p></div><form method="post" action="/plugins/lumi_ai/improvement_center/evals/run" data-improvement-action><button class="button subtle" type="submit">Run all tests</button></form></div>
|
|
<details class="ai-settings-group"><summary>Add a test case</summary><form method="post" action="/plugins/lumi_ai/improvement_center/evals" class="form-grid ai-form" data-improvement-action><div class="field full"><label>Prompt</label><textarea name="prompt" rows="3" required></textarea></div><div class="field"><label>Role</label><select name="role"><option>user</option><option>mod</option><option>admin</option></select></div><div class="field"><label>Origin</label><input name="origin" value="webui" /></div><div class="field full"><label>Expected behavior</label><textarea name="expected_behavior" rows="3"></textarea></div><div class="field full"><label>Forbidden behavior</label><textarea name="forbidden_behavior" rows="3"></textarea></div><div class="field"><label>Expected verified link</label><input name="expected_link" /></div><div class="field"><label>Notes</label><input name="notes" /></div><div class="field full"><button class="button" type="submit">Add test</button></div></form></details>
|
|
<div class="table-wrap"><table class="table"><thead><tr><th>Prompt</th><th>Role / origin</th><th>Expected</th><th>Must avoid</th><th>Actions</th></tr></thead><tbody><% evalCases.entries.forEach((entry) => { %><tr><td><%= entry.prompt %></td><td><%= entry.role %> / <%= entry.origin %></td><td><%= entry.expected_behavior || "-" %></td><td><%= entry.forbidden_behavior || "-" %></td><td><form method="post" action="/plugins/lumi_ai/improvement_center/evals/<%= entry.id %>/delete" data-improvement-action data-confirm-mode="modal" data-confirm-title="Delete eval case" data-confirm-text="Delete this evaluation case?" data-confirm-label="Delete test"><button class="button danger" type="submit">Delete</button></form></td></tr><% }) %><% if (!evalCases.entries.length) { %><tr><td colspan="5">No evaluation cases.</td></tr><% } %></tbody></table></div>
|
|
<details class="ai-settings-group"><summary>Recent test results</summary><div class="table-wrap"><table class="table"><thead><tr><th>Time</th><th>Case</th><th>Result</th><th>Notes</th></tr></thead><tbody><% evalResults.forEach((result) => { %><tr><td><%= formatDate(result.run_at) %></td><td><%= result.case_id %></td><td><span class="ai-tag"><%= result.status %></span></td><td><%= result.notes || "-" %></td></tr><% }) %><% if (!evalResults.length) { %><tr><td colspan="4">No test results.</td></tr><% } %></tbody></table></div></details>
|
|
</section>
|
|
|
|
<% if (access.can_export) { %><section id="exports"><div class="ai-section-heading"><div><h2>Training exports</h2><p>Manual exports include only approved examples. Lumi does not start training.</p></div></div><div class="improvement-actions"><form method="post" action="/plugins/lumi_ai/improvement_center/exports/instruction"><button class="button subtle" type="submit">Export instruction data</button></form><form method="post" action="/plugins/lumi_ai/improvement_center/exports/dpo"><button class="button subtle" type="submit">Export preference data</button></form></div></section><% } %>
|
|
</div>
|
|
</details>
|
|
<% } %>
|
|
</div>
|
|
|
|
<script src="/plugins/lumi_ai/assets/improvement-center.js?v=0.8.5" defer></script>
|
|
<%- include("../../../src/web/views/partials/layout-bottom") %>
|