Issues / #738
#738 Configurable system prompt in the web GUI
open · @RobinMeyer · 1 comentários · No GitHub
Descrição
At first, thanks for the great program!
A system prompt can change the output dramatically, especially for story telling etc.
Please add a system prompt text edit in the preferences of the web GUI. Here is a proposal:
```
--- a/serve/web/app.js
+++ b/serve/web/app.js
@@ -461,7 +461,7 @@
// ------------------------------------------------------------------ Chat
-const DEFAULTS = {thinking: "high", temperature: 0.6, top_p: 0.95, top_k: 20, max: "", seed: "", show: true, esp: true, mcp: true};
+const DEFAULTS = {thinking: "high", temperature: 0.6, top_p: 0.95, top_k: 20, max: "", seed: "", show: true, esp: true, mcp: true, system_prompt: ""};
let settings = {...DEFAULTS, ...store.get("sampling", {})};
let messages = store.get("chat", []);
let attachments = []; // {name, url}
@@ -625,6 +625,8 @@
if (d.open && body.dataset.pending) { body.textContent = messages[+d.closest(".st-msg").dataset.i].reasoning; delete body.dataset.pending; }
}, true);
+// The optional browser-local instruction is prepended to every chat request.
+// It is deliberately not saved in the chat transcript or sent to shared API defaults.
function apiMessages() {
const out = [];
for (const m of messages) {
@@ -637,7 +639,9 @@
out.push(...assistantMessages(m));
}
}
- return out;
+ const systemPrompt = (settings.system_prompt || "").trim();
+ return systemPrompt ? [{role: "system", content: systemPrompt}, ...out] : out;
}
// An answer that used MCP tools goes back as the model wrote it: per round the text before the calls, the calls and
// their results (as the model read them), then the rest - so the next question can build on what the tools found.
@@ -877,6 +881,22 @@
// ------------------------------------------------------------------ the sampling drawer
+function ensureSystemPromptField() {
+ if ($("s-system-prompt")) return;
+
+ const field = document.createElement("div");
+ field.className = "st-field";
+ field.innerHTML =
+ `<label class="st-label" for="s-system-prompt">System prompt</label>` +
+ `<textarea class="st-input" id="s-system-prompt" rows="5" ` +
+ `placeholder="Optional instructions for every message in this chat"></textarea>` +
+ `<span class="muted small">Stored only in this browser; it is sent as the first system message.</span>`;
+
+ $("s-seed").closest(".st-field").insertAdjacentElement("afterend", field);
+}
+
function openDrawer(open) {
$("drawer").dataset.open = String(open);
$("drawer").setAttribute("aria-hidden", String(!open));
@@ -884,10 +904,12 @@
if (open) { loadDrawer(); loadShared(); loadMcp(); }
}
function loadDrawer(s = settings) {
+ ensureSystemPromptField();
for (const b of $("s-thinking").children) b.setAttribute("aria-checked", String(b.dataset.v === s.thinking));
$("s-temp").value = s.temperature; $("s-topp").value = s.top_p; $("s-topk").value = s.top_k;
$("s-max").value = s.max; $("s-seed").value = s.seed;
+ $("s-system-prompt").value = s.system_prompt || "";
$("s-show").setAttribute("aria-checked", String(!!s.show));
$("s-esp").setAttribute("aria-checked", String(s.esp !== false));
$("esp-row").hidden = !projectionLoaded();
@@ -946,10 +968,11 @@
const sel = [...$("s-thinking").children].find((b) => b.getAttribute("aria-checked") === "true");
settings = {thinking: sel ? sel.dataset.v : "high", temperature: +$("s-temp").value, top_p: +$("s-topp").value,
top_k: +$("s-topk").value, max: $("s-max").value.trim(), seed: $("s-seed").value.trim(),
+ system_prompt: $("s-system-prompt").value,
show: $("s-show").getAttribute("aria-checked") === "true",
esp: $("s-esp").getAttribute("aria-checked") === "true",
mcp: $("s-mcp").getAttribute("aria-checked") === "true"};
store.set("sampling", settings);```No site
Links install, modelos, releases.