feat(v2): 模型设置(用户可调小模型/大模型/管线,/config + UI)
This commit is contained in:
@@ -58,6 +58,9 @@ input,select{background:var(--panel2);border:1px solid var(--line);color:var(--t
|
||||
.muted{color:var(--muted)}
|
||||
.history{max-height:220px;overflow:auto;margin-top:8px}
|
||||
table{width:100%;border-collapse:collapse;font-size:13px}
|
||||
.form-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px}
|
||||
.form-grid label{display:flex;flex-direction:column;gap:5px;font-size:12px;color:var(--muted)}
|
||||
.form-grid input,.form-grid select{width:100%}
|
||||
th,td{text-align:left;padding:8px;border-bottom:1px solid var(--line)}
|
||||
th{color:var(--muted);font-weight:600}
|
||||
footer{padding:8px 20px;color:var(--muted);font-size:11px;border-top:1px solid var(--line);background:var(--panel)}
|
||||
@@ -74,6 +77,7 @@ footer{padding:8px 20px;color:var(--muted);font-size:11px;border-top:1px solid v
|
||||
<button data-tab="work">🔗 协作过程</button>
|
||||
<button data-tab="review">🧑💻 人工检验</button>
|
||||
<button data-tab="metrics">📊 指标</button>
|
||||
<button data-tab="settings">⚙️ 模型设置</button>
|
||||
</nav>
|
||||
<main>
|
||||
<!-- 对话 -->
|
||||
@@ -115,6 +119,53 @@ footer{padding:8px 20px;color:var(--muted);font-size:11px;border-top:1px solid v
|
||||
<div class="row-btns" style="margin-bottom:10px"><button class="small" id="refreshMetrics">刷新</button></div>
|
||||
<div id="metricsResult"></div>
|
||||
</section>
|
||||
<!-- 模型设置 -->
|
||||
<section class="panel" id="panel-settings">
|
||||
<div class="card">
|
||||
<h3>⚙️ 内置小模型(Worker)</h3>
|
||||
<div class="form-grid">
|
||||
<label>后端 backend
|
||||
<select id="set-worker-backend">
|
||||
<option value="llama_server">llama_server(内置本地模型)</option>
|
||||
<option value="openai">openai/api(Ollama / vLLM 等兼容端点)</option>
|
||||
<option value="mock">mock(演示,零运行时)</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>模型路径/名称 <input id="set-worker-model" type="text" placeholder="models/xxx.gguf 或模型名"></label>
|
||||
<label>端点 base_url(openai 用) <input id="set-worker-baseurl" type="text" placeholder="http://127.0.0.1:11434/v1"></label>
|
||||
<label>端口(llama_server) <input id="set-worker-port" type="number"></label>
|
||||
<label>temperature <input id="set-worker-temperature" type="number" step="0.1"></label>
|
||||
<label>max_fix_attempts <input id="set-worker-fix" type="number"></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h3>🧠 大模型(Architect / API)</h3>
|
||||
<div class="form-grid">
|
||||
<label>model <input id="set-arch-model" type="text"></label>
|
||||
<label>base_url <input id="set-arch-baseurl" type="text"></label>
|
||||
<label>api_key_env <input id="set-arch-keyenv" type="text"></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h3>🔀 管线 pipeline</h3>
|
||||
<div class="form-grid">
|
||||
<label>fast_path(快路径直答) <input id="set-pipe-fast" type="checkbox"></label>
|
||||
<label>rounds_cap <input id="set-pipe-rounds" type="number"></label>
|
||||
<label>api_token_cap <input id="set-pipe-tokens" type="number"></label>
|
||||
<label>breach_policy
|
||||
<select id="set-pipe-breach">
|
||||
<option value="architect_do">architect_do(兜底代做)</option>
|
||||
<option value="local_only">local_only(本地降级)</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row-btns">
|
||||
<button class="primary" id="saveSettingsBtn">保存并生效</button>
|
||||
<button class="small" id="resetSettingsBtn">恢复默认</button>
|
||||
<span class="muted" id="settingsMsg"></span>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
<footer>端云协同 LLM 协作系统 · v2 · 交流文本协议 · 北极星:token 下降 ≥80%</footer>
|
||||
<script>
|
||||
@@ -123,7 +174,7 @@ let lastRequestId=null;
|
||||
const esc=s=>{const d=document.createElement("div");d.textContent=s==null?"":String(s);return d.innerHTML;};
|
||||
function el(tag,cls,txt){const n=document.createElement(tag);if(cls)n.className=cls;if(txt!=null)n.textContent=txt;return n;}
|
||||
function setTab(t){document.querySelectorAll("nav button").forEach(b=>b.classList.toggle("active",b.dataset.tab===t));document.querySelectorAll(".panel").forEach(p=>p.classList.toggle("active",p.id==="panel-"+t));}
|
||||
document.querySelectorAll("nav button").forEach(b=>b.onclick=()=>{setTab(b.dataset.tab);if(b.dataset.tab==="review")loadReview();if(b.dataset.tab==="metrics")loadMetrics();});
|
||||
document.querySelectorAll("nav button").forEach(b=>b.onclick=()=>{setTab(b.dataset.tab);if(b.dataset.tab==="review")loadReview();if(b.dataset.tab==="metrics")loadMetrics();if(b.dataset.tab==="settings")loadSettings();});
|
||||
|
||||
// ---- 健康状态 ----
|
||||
async function health(){try{const r=await fetch("/health");const d=await r.json();$("healthPill").textContent="健康 · "+d.domains.length+" 领域";}catch(e){$("healthPill").textContent="离线";}}
|
||||
@@ -154,6 +205,12 @@ async function sendLegacy(){const q=$("query").value.trim();if(!q)return;const h
|
||||
const SAMPLES=["用 Python 实现快速排序,并分析时间与空间复杂度","求解方程 x^2 - 5x + 6 = 0","高血压患者日常饮食需要注意什么","解释一下深度学习中的注意力机制"];
|
||||
function sample(){$("query").value=SAMPLES[Math.floor(Math.random()*SAMPLES.length)];}
|
||||
|
||||
// ---- 模型设置 ----
|
||||
async function loadSettings(){try{const r=await fetch("/config");const s=await r.json();const w=s.worker||{};$("set-worker-backend").value=w.backend||"llama_server";$("set-worker-model").value=w.model||"";$("set-worker-baseurl").value=w.base_url||"";$("set-worker-port").value=w.port||8901;$("set-worker-temperature").value=w.temperature||0.3;$("set-worker-fix").value=w.max_fix_attempts||2;const a=s.architect||{};$("set-arch-model").value=a.model||"";$("set-arch-baseurl").value=a.base_url||"";$("set-arch-keyenv").value=a.api_key_env||"";const p=s.pipeline||{};$("set-pipe-fast").checked=!!p.fast_path;$("set-pipe-rounds").value=p.rounds_cap||6;$("set-pipe-tokens").value=p.api_token_cap||8000;$("set-pipe-breach").value=p.breach_policy||"architect_do";$("settingsMsg").textContent="";}catch(e){$("settingsMsg").textContent="读取失败:"+e.message;}}
|
||||
async function saveSettings(){const patch={worker:{backend:$("set-worker-backend").value,model:$("set-worker-model").value,base_url:$("set-worker-baseurl").value,port:parseInt($("set-worker-port").value||8901),temperature:parseFloat($("set-worker-temperature").value||0.3),max_fix_attempts:parseInt($("set-worker-fix").value||2)},architect:{model:$("set-arch-model").value,base_url:$("set-arch-baseurl").value,api_key_env:$("set-arch-keyenv").value},pipeline:{fast_path:$("set-pipe-fast").checked,rounds_cap:parseInt($("set-pipe-rounds").value||6),api_token_cap:parseInt($("set-pipe-tokens").value||8000),breach_policy:$("set-pipe-breach").value}};try{const r=await fetch("/config",{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(patch)});const d=await r.json();$("settingsMsg").textContent=r.ok?"✅ 已保存并重建管线":"❌ "+(d.detail||"保存失败");}catch(e){$("settingsMsg").textContent="保存失败:"+e.message;}}
|
||||
async function resetSettings(){try{await fetch("/config/reset",{method:"POST"});$("settingsMsg").textContent="已恢复默认设置";loadSettings();}catch(e){$("settingsMsg").textContent="重置失败:"+e.message;}}
|
||||
$("saveSettingsBtn").onclick=saveSettings;
|
||||
$("resetSettingsBtn").onclick=resetSettings;
|
||||
$("sendBtn").onclick=sendChat;
|
||||
$("legacyBtn").onclick=sendLegacy;
|
||||
$("sampleBtn").onclick=sample;
|
||||
|
||||
Reference in New Issue
Block a user