mirror of
http://100.103.83.12:3003/fegger/odoo-at-payroll.git
synced 2026-09-17 16:56:42 +00:00
feat(agent): add index bootstrap and answer feedback
This commit is contained in:
@@ -137,6 +137,67 @@ function followUpPanel(question) {
|
||||
return box;
|
||||
}
|
||||
|
||||
function ratingPanel(answerRequestId) {
|
||||
const panel = node("div", "rating-panel");
|
||||
panel.append(node("strong", "", "War diese Antwort hilfreich?"));
|
||||
const actions = node("div", "rating-actions");
|
||||
const up = node("button", "secondary rating-choice", "👍 Ja");
|
||||
const down = node("button", "secondary rating-choice", "👎 Nein");
|
||||
up.type = "button";
|
||||
down.type = "button";
|
||||
actions.append(up, down);
|
||||
panel.append(actions);
|
||||
|
||||
const form = node("div", "rating-form");
|
||||
form.hidden = true;
|
||||
const feedback = node("textarea", "rating-feedback");
|
||||
feedback.rows = 2;
|
||||
feedback.maxLength = 1000;
|
||||
feedback.placeholder = "Optional: Was war hilfreich oder was hat gefehlt?";
|
||||
const send = node("button", "primary", "Bewertung senden");
|
||||
send.type = "button";
|
||||
const status = node("span", "rating-status");
|
||||
form.append(feedback, send, status);
|
||||
panel.append(form);
|
||||
|
||||
let selection = null;
|
||||
const select = (value, selected, other) => {
|
||||
selection = value;
|
||||
selected.classList.add("is-selected");
|
||||
other.classList.remove("is-selected");
|
||||
form.hidden = false;
|
||||
feedback.focus();
|
||||
};
|
||||
up.addEventListener("click", () => select("up", up, down));
|
||||
down.addEventListener("click", () => select("down", down, up));
|
||||
send.addEventListener("click", async () => {
|
||||
if (!selection) return;
|
||||
send.disabled = true;
|
||||
status.textContent = "Wird gespeichert …";
|
||||
try {
|
||||
const response = await fetch("/v1/ratings", {
|
||||
method: "POST",
|
||||
headers: apiHeaders(),
|
||||
body: JSON.stringify({
|
||||
request_id: answerRequestId,
|
||||
rating: selection,
|
||||
feedback: feedback.value.trim() || null,
|
||||
}),
|
||||
});
|
||||
if (!response.ok) throw new Error(await errorDetail(response));
|
||||
status.textContent = "Danke, Bewertung gespeichert.";
|
||||
up.disabled = true;
|
||||
down.disabled = true;
|
||||
feedback.disabled = true;
|
||||
send.hidden = true;
|
||||
} catch (error) {
|
||||
status.textContent = error.message || "Bewertung konnte nicht gespeichert werden.";
|
||||
send.disabled = false;
|
||||
}
|
||||
});
|
||||
return panel;
|
||||
}
|
||||
|
||||
function technicalPanel(data) {
|
||||
const details = node("details", "technical-panel");
|
||||
details.append(node("summary", "", "Technische Details"));
|
||||
@@ -182,6 +243,9 @@ function addAgentMessage(data) {
|
||||
if (Array.isArray(data.sources) && data.sources.length) {
|
||||
body.append(sourcePanel(data.sources));
|
||||
}
|
||||
if (data.ratings_enabled && data.request_id) {
|
||||
body.append(ratingPanel(data.request_id));
|
||||
}
|
||||
|
||||
const seconds = typeof data.latency_ms === "number" ? `${(data.latency_ms / 1000).toFixed(1)} s` : "–";
|
||||
body.append(node("div", "answer-meta", `${data.model || "Modell"} · ${seconds} · ${data.citations?.length || 0} Zitate`));
|
||||
|
||||
Reference in New Issue
Block a user