diff --git a/src/genesis/server/static/chat.js b/src/genesis/server/static/chat.js
index 3548408..678a90f 100644
--- a/src/genesis/server/static/chat.js
+++ b/src/genesis/server/static/chat.js
@@ -42,9 +42,6 @@ function autoBindProject(draftProject2, projects2, explicitNone) {
}
return draftProject2;
}
-function resolveUploadType(_activeProject, _draftProject, selectValue) {
- return selectValue;
-}
function computeDrawerSnapshot(fields) {
return fields.map((f) => (f == null ? "" : String(f)).trim()).join(String.fromCharCode(1));
}
@@ -131,15 +128,8 @@ var sidebarEl = must("sidebar");
var sidebarToggleBtn = must("sidebar-toggle");
var projSwitcherEl = maybe("proj-switcher");
var sessMenuEl = must("sess-menu");
-var fileTypeSel = must("file-type");
var fileInputEl = must("file-input");
var uploadStatusEl = must("upload-status");
-var projHintEl = must("proj-hint");
-var uploadPanelEl = maybe("upload-panel");
-var ragEnabledEl = must("rag-enabled");
-var ragStatsEl = must("rag-stats");
-var ragBarEl = must("rag-bar");
-var impactBtnEl = must("impact-btn");
var pfName = must("pf-name");
var pfDisplay = must("pf-display");
var pfTemplate = must("pf-template");
@@ -281,7 +271,6 @@ function onProjectRowClick(name) {
setExplicitNone(false);
applyProjectContext();
renderProjectSwitcher();
- updateUploadBar();
}
const collapsed = loadCollapsedProjects();
if (collapsed.has(name)) collapsed.delete(name);
@@ -336,7 +325,6 @@ function renderProjectSwitcher() {
setExplicitNone(draftProject === null);
applyProjectContext();
renderProjectSwitcher();
- updateUploadBar();
toggleProjectSwitcher(false);
};
});
@@ -487,15 +475,6 @@ function toggleSidebar(force) {
} catch (e) {
}
}
-function updateUploadBar() {
- fileTypeSel.style.display = "";
- if (fileTypeSel.value !== "requirements") fileTypeSel.value = "requirements";
- if (draftProject) {
- projHintEl.textContent = "\u9ED8\u8BA4\u4E0A\u4F20\u8981\u4EF6\u5B9A\u4E49 xlsx\uFF1B\u5982\u9700\u8865\u4F20\u6A21\u677F/\u89C4\u5219/\u65E2\u6709\u7CFB\u7EDF zip\uFF0C\u8BF7\u5728\u4E0B\u62C9\u4E2D\u9009\u62E9\u5BF9\u5E94\u7C7B\u578B\u3002";
- } else {
- projHintEl.textContent = "\u8BF7\u9009\u62E9 file_type \u540E\u4E0A\u4F20\uFF08\u672A\u9009\u9879\u76EE\u65F6\uFF0C\u6A21\u677F/\u89C4\u5219\u4ECD\u53EF\u624B\u52A8\u4E0A\u4F20\uFF09\u3002";
- }
-}
function insertPrompt(text) {
inputEl.value = text;
inputEl.focus();
@@ -504,6 +483,7 @@ function insertPrompt(text) {
} catch (e) {
}
autoGrowInput();
+ updateSendState();
}
function renderEmptyOrWelcome() {
chatEl.innerHTML = "";
@@ -584,8 +564,6 @@ async function newSession() {
}
chatEl.innerHTML = "";
setText(sessionTitle, "\u672A\u521B\u5EFA\u4F1A\u8BDD");
- updateUploadBar();
- await refreshRagStats();
await refreshSessions();
renderEmptyOrWelcome();
}
@@ -614,8 +592,6 @@ async function loadSession(id) {
const role = roleMap[m.role] || "assistant";
addMsg(role, esc(m.content));
}
- updateUploadBar();
- await refreshRagStats();
await refreshSessions();
try {
localStorage.setItem("genesis_session", sid);
@@ -650,7 +626,6 @@ function renderProjectMismatchHint() {
draftProject = activeProject;
applyProjectContext();
renderProjectSwitcher();
- updateUploadBar();
void refreshSessions();
wrap.remove();
};
@@ -666,11 +641,15 @@ function renderProjectMismatchHint() {
};
}
var sendInFlight = false;
+function updateSendState() {
+ sendBtn.disabled = sendInFlight || inputEl.value.trim() === "";
+}
async function send() {
if (sendInFlight) return;
const text = inputEl.value.trim();
if (!text) return;
sendInFlight = true;
+ updateSendState();
if (!sid) {
try {
const d = await api("POST", "/api/sessions", { user_id: "default", project: draftProject || null });
@@ -685,6 +664,7 @@ async function send() {
} catch (e) {
addMsg("error", "\u521B\u5EFA\u4F1A\u8BDD\u5931\u8D25\uFF1A" + esc(String(e)));
sendInFlight = false;
+ updateSendState();
return;
}
}
@@ -706,7 +686,6 @@ async function send() {
if (es) es.remove();
addMsg("user", esc(text));
const typing = showTyping();
- sendBtn.disabled = true;
try {
const res = await api("POST", "/api/chat/" + encodeURIComponent(sessionId) + "/messages", { content: text });
typing.remove();
@@ -725,7 +704,7 @@ async function send() {
addMsg("error", "\u8BF7\u6C42\u5931\u8D25\uFF1A" + esc(String(e)));
} finally {
sendInFlight = false;
- sendBtn.disabled = false;
+ updateSendState();
inputEl.focus();
}
}
@@ -738,7 +717,11 @@ inputEl.addEventListener("keydown", (e) => {
void send();
}
});
-inputEl.addEventListener("input", autoGrowInput);
+inputEl.addEventListener("input", () => {
+ autoGrowInput();
+ updateSendState();
+});
+updateSendState();
document.getElementById("new-chat").addEventListener("click", () => {
void newSession().catch((e) => addMsg("error", esc(String(e))));
});
@@ -761,7 +744,10 @@ document.getElementById("side-add-project").addEventListener("click", () => {
openProjectDrawer(null);
});
document.getElementById("tb-upload").addEventListener("click", () => {
- if (uploadPanelEl) uploadPanelEl.hidden = !uploadPanelEl.hidden;
+ fileInputEl.click();
+});
+fileInputEl.addEventListener("change", () => {
+ void uploadRequirements();
});
document.getElementById("sm-rename").addEventListener("click", (ev) => {
ev.stopPropagation();
@@ -769,88 +755,6 @@ document.getElementById("sm-rename").addEventListener("click", (ev) => {
closeSessMenu();
if (t) startRenameSession(t.el, { session_id: t.sid, name: t.name });
});
-var RAG_LS_KEY = "genesis_rag_enabled";
-function readRagFlag() {
- try {
- return localStorage.getItem(RAG_LS_KEY) === "1";
- } catch (e) {
- return false;
- }
-}
-function writeRagFlag(v) {
- try {
- localStorage.setItem(RAG_LS_KEY, v ? "1" : "0");
- } catch (e) {
- }
-}
-ragEnabledEl.addEventListener("change", () => {
- writeRagFlag(ragEnabledEl.checked);
- updateImpactButton();
-});
-async function refreshRagStats() {
- if (!sid) {
- ragBarEl.hidden = true;
- return;
- }
- ragBarEl.hidden = false;
- let stats = { chunks: 0, rag_enabled: false };
- try {
- stats = await api("GET", "/api/sessions/" + encodeURIComponent(sid) + "/rag-stats");
- } catch (e) {
- stats = { chunks: 0, rag_enabled: false };
- }
- const n = Number(stats.chunks) || 0;
- setText(ragStatsEl, n > 0 ? "RAG \u5DF2\u7D22\u5F15 " + n + " \u7247\u6BB5" : "RAG 0 \u7247\u6BB5\uFF08\u8BF7\u5728\u9879\u76EE\u914D\u7F6E\u4E2D\u8BBE\u7F6E\u4EE3\u7801\u5E93\u76EE\u5F55\uFF09");
- ragStatsEl.classList.toggle("ready", n > 0);
- ragStatsEl.classList.toggle("zero", n === 0);
- ragEnabledEl.disabled = n === 0;
- if (n === 0) {
- ragEnabledEl.checked = false;
- writeRagFlag(false);
- if (ragEnabledEl.parentElement) ragEnabledEl.parentElement.title = "\u8BF7\u5728\u9879\u76EE\u914D\u7F6E\u4E2D\u8BBE\u7F6E\u65E2\u6709\u7CFB\u7EDF\u4EE3\u7801\u5E93\u76EE\u5F55";
- } else {
- ragEnabledEl.checked = readRagFlag();
- if (ragEnabledEl.parentElement) {
- ragEnabledEl.parentElement.title = ragEnabledEl.checked ? "RAG \u68C0\u7D22\u7ED3\u679C\u4F1A\u6CE8\u5165\u5230 LLM prompt" : "\u52FE\u9009\u540E\u542F\u7528 RAG \u68C0\u7D22";
- }
- }
- updateImpactButton();
-}
-function updateImpactButton() {
- if (!sid) {
- impactBtnEl.disabled = true;
- return;
- }
- const hasRag = Number(ragStatsEl.dataset.chunks || 0) > 0 || !ragEnabledEl.disabled;
- impactBtnEl.disabled = !hasRag;
- setText(impactBtnEl, ragEnabledEl.checked ? "\u5F00\u59CB\u5F71\u54CD\u8C03\u67E5\uFF08\u542F\u7528 RAG\uFF09" : "\u5F00\u59CB\u5F71\u54CD\u8C03\u67E5");
-}
-impactBtnEl.addEventListener("click", () => {
- void (async () => {
- if (!sid) {
- addMsg("error", "\u8BF7\u5148\u53D1\u9001\u4E00\u6761\u6D88\u606F\u4EE5\u521B\u5EFA\u4F1A\u8BDD");
- inputEl.focus();
- return;
- }
- const useRag = !!ragEnabledEl.checked;
- impactBtnEl.disabled = true;
- const typing = showTyping();
- try {
- const url = "/api/sessions/" + encodeURIComponent(sid) + "/start-impact?use_rag=" + (useRag ? "true" : "false");
- const r = await fetch(url, { method: "POST" });
- const d = await r.json().catch(() => ({}));
- if (!r.ok) throw new Error(d && d.detail && d.detail.message || String(r.status));
- typing.remove();
- addMsg("progress", '