Files
projectAIpopular/gateway/static/assets/SettingsView-DDuLU_To.js

1 line
26 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import{A as e,B as t,D as n,E as r,F as ee,H as te,I as i,J as a,K as o,L as s,M as c,O as ne,P as l,Q as u,R as d,S as re,U as f,V as ie,W as p,X as m,Z as ae,a as oe,b as se,c as ce,h as le,i as ue,j as h,l as de,m as fe,o as pe,p as me,q as g,s as he,t as _,v as ge,w as _e,x as ve,y as ye,z as v}from"./index-C3pjQqOl.js";var be={class:`settings-view`},xe={class:`settings-section`},Se={class:`section-body`},Ce={class:`role-bar`},we=[`onUpdate:modelValue`],Te=[`value`],Ee={key:0,class:`pool-table`},De={class:`mono`},Oe=[`onUpdate:modelValue`,`onChange`],ke={class:`row-actions`},Ae=[`disabled`,`onClick`],je=[`onClick`],Me=[`onClick`],Ne={key:1,class:`no-models`},Pe={key:3,class:`pool-edit`},Fe={class:`pool-edit-title`},Ie={class:`form-grid`},Le={class:`field`},Re={class:`field`},ze={class:`field`},Be={class:`field`},Ve=[`disabled`],He={id:`pool-model-options`},Ue=[`value`],We={key:0,class:`field full-width`},Ge={key:1,class:`field`},Ke={class:`field`},qe={class:`field`},Je={class:`field`},Ye={class:`field`},Xe={class:`pool-edit-actions`},Ze={class:`checkbox-label`},Qe=[`disabled`],$e={class:`settings-section`},et={class:`section-title`},tt={class:`title-right`},nt={class:`section-body`},rt={class:`server-control-bar`},it={class:`server-info`},at={class:`model-chip`},ot={class:`model-chip port-chip`},st={class:`model-chip pid-chip`},ct={key:1,class:`server-idle`},lt={class:`server-actions`},ut=[`disabled`],dt=[`disabled`],ft={key:0,class:`error-msg llama-error`},pt={class:`local-models`},mt={class:`local-models-header`},ht=[`disabled`],gt={key:0,class:`no-models`},_t={key:1,class:`model-list`},vt=[`onClick`],yt={class:`model-item-name`},bt={class:`model-item-size`},xt={class:`download-section`},St={class:`download-form`},Ct=[`disabled`],wt=[`disabled`],Tt={key:0,class:`progress-wrap`},Et={class:`progress-bar`},Dt={class:`progress-info`},Ot={key:1,class:`error-msg download-error`},kt={key:2,class:`done-msg`},At={class:`form-grid`,style:{"margin-top":`16px`}},jt={class:`field full-width`},Mt={key:0,class:`field full-width`},Nt=[`disabled`],Pt={class:`input-row`},Ft=[`placeholder`],It={key:1,class:`field full-width`},Lt=[`disabled`],Rt=[`value`],zt=[`value`],Bt={key:3,class:`field-hint warn`},Vt={key:2,class:`field`},Ht={class:`field`},Ut={class:`field`},Wt={class:`field`},Gt={class:`settings-section`},Kt={class:`section-title`},qt={class:`title-right`},Jt={class:`section-body`},Yt={class:`form-grid`},Xt={class:`field full-width`},Zt=[`disabled`],Qt={class:`field full-width`},$t=[`placeholder`],en={class:`field full-width`},tn=[`disabled`],nn=[`value`],rn={key:0,class:`field-hint warn`},an={class:`settings-section`},on={class:`section-body`},sn={class:`form-grid`},cn={class:`field full-width`},ln={class:`checkbox-label`},un={class:`field`},dn={class:`field`},fn={class:`field full-width`},pn={class:`settings-section`},mn={class:`section-title`},hn={class:`title-right`},gn={class:`section-body`},_n={class:`role-hint`},vn={class:`form-grid`},yn={class:`field`},bn={class:`checkbox-label`},xn={class:`field`},Sn=[`disabled`],Cn={class:`field`},wn=[`value`],Tn={class:`actions`},En=[`disabled`],Dn=[`disabled`],On=_(t({__name:`SettingsView`,setup(t){let _=a(!1),On=a(``),y=a(null),kn=[{key:`architect`,label:`🧠 Architect(决策/终审)`},{key:`worker`,label:`🔧 Worker(实现/自验证)`},{key:`agent`,label:`🤖 Agent(智能体工具)`}],An={local:`本地/零成本`,budget:`低价 API`,premium:`旗舰 API`},b=a({roles:{architect:``,worker:``,agent:``},entries:[]}),x=g({architect:``,worker:``,agent:``}),S=a(null),C=a(!1),w=a(``),T=a(``),E=a(!1),D=a(!1),O=a(!1),jn=a([]),Mn=ee(()=>b.value.entries.filter(e=>e.enabled));function Nn(e){return An[e]??e}async function Pn(){try{b.value=await de(),x.architect=b.value.roles.architect||``,x.worker=b.value.roles.worker||``,x.agent=b.value.roles.agent||``}catch{}}async function Fn(){try{b.value=await se({...x}),y.value={ok:!0,msg:`✅ 角色已更新,管线已重建`}}catch(e){y.value={ok:!1,msg:`❌ 角色指派失败:`+(e?.response?.data?.detail||e?.message||e)},await Pn()}setTimeout(()=>y.value=null,3e3)}function In(){C.value=!0,S.value={name:``,tier:`budget`,backend:`openai`,base_url:``,model:``,api_key:``,price_in:.1,price_out:.1,temperature:.3,max_tokens:4096,enabled:!0}}function Ln(e){C.value=!1,S.value={...e,api_key:``}}async function Rn(){if(S.value){D.value=!0;try{b.value=await n(S.value),S.value=null,y.value={ok:!0,msg:`✅ 模型条目已保存`}}catch(e){y.value={ok:!1,msg:`❌ 保存失败:`+(e?.response?.data?.detail||e?.message||e)}}finally{D.value=!1,setTimeout(()=>y.value=null,3e3)}}}async function zn(e){confirm(`删除模型条目「${e.name}」?相关角色指派会一并清空。`)&&(b.value=await ue(e.id))}async function Bn(e){b.value=await n({...e,api_key:``})}async function Vn(e){w.value=e.id,T.value=``;try{let t=await _e(e.id);E.value=t.ok,T.value=t.ok?`✅ ${e.name} 连接正常`:`❌ ${e.name}: ${t.detail||`连接失败`}`}catch(e){E.value=!1,T.value=`❌ `+(e?.message||String(e))}finally{w.value=``}}async function Hn(){if(S.value){O.value=!0;try{let e;e=!C.value&&S.value.id?await le(S.value.id):S.value.backend===`mock`?{models:[{id:`mock`,name:`mock(内置模拟)`}]}:await fe(S.value.backend||`openai`,S.value.base_url||``,S.value.api_key||``),e.error?(E.value=!1,T.value=e.error,jn.value=[]):jn.value=e.models||[]}finally{O.value=!1}}}let k=a({running:!1}),A=a(!1),j=a(!1),M=a([]),N=a(!1),P=a(``),F=a(!1),I=a(``),L=a(0),Un=a(``),Wn=a(``),Gn=a(``),Kn=a(null),qn=a(``),R=a(``),Jn=a(!1),z=null,B=a([]),V=a([]),H=g({worker:!1,architect:!1}),U=g({worker:``,architect:``}),W=g({worker:!1,architect:!1}),G=g({worker:null,architect:null}),K=g({worker:``,architect:``}),q=[{id:`deepseek-v4-flash`,name:`deepseek-v4-flash(推荐)`},{id:`deepseek-v4-pro`,name:`deepseek-v4-pro(推理模式)`},{id:`deepseek-coder`,name:`deepseek-coder`},{id:`gpt-4o-mini`,name:`gpt-4o-mini`},{id:`gpt-4o`,name:`gpt-4o`},{id:`claude-3-5-sonnet-20241022`,name:`claude-3.5-sonnet`},{id:`qwen-plus`,name:`qwen-plus`},{id:`qwen-max`,name:`qwen-max`}],J=a(null),Y=g({worker:{backend:`mock`,model:``,base_url:``,port:8901,temperature:.3,max_fix_attempts:2,code_timeout_s:10},architect:{model:`deepseek-v4-flash`,base_url:`https://api.deepseek.com`,api_key:``},pipeline:{fast_path:!0,rounds_cap:6,api_token_cap:8e3,breach_policy:`architect_do`}}),Yn=ee(()=>Y.worker.backend===`llama_server`?`http://127.0.0.1:${Y.worker.port}/v1`:`http://127.0.0.1:11434/v1`),Xn=ee(()=>J.value?JSON.stringify(Y)!==JSON.stringify(J.value):!1);function Zn(e){return e>=1e9?(e/1e9).toFixed(1)+` GB`:e>=1e6?(e/1e6).toFixed(1)+` MB`:e>=1e3?(e/1e3).toFixed(0)+` KB`:e+` B`}async function Qn(){try{let e=await he();return k.value=e,e}catch{return k.value={running:!1},{running:!1}}}async function X(){N.value=!0;try{M.value=await me()}catch{M.value=[]}finally{N.value=!1}}async function $n(){if(!Y.worker.model){alert(`请先从上方「本地模型」列表中选择一个模型,再启动服务`);return}A.value=!0;try{let e=await ve(Y.worker.model,Y.worker.port,99,4096);k.value=e,e.running&&(Y.worker.backend=`llama_server`,Y.worker.base_url=`http://127.0.0.1:${e.port}/v1`,await X(),await Z())}catch(e){k.value={running:!1,error:String(e?.message||e)}}finally{A.value=!1}}async function er(){j.value=!0;try{await re(),k.value={running:!1}}catch{k.value={running:!1}}finally{j.value=!1}}function tr(e){P.value=e.id,Y.worker.model=e.id}function nr(){I.value.trim()&&(R.value=``,Jn.value=!1,L.value=0,Un.value=``,Wn.value=``,Gn.value=`0 B`,Kn.value=null,F.value=!0,oe(I.value.trim()).then(e=>{if(e.error){R.value=e.error,F.value=!1;return}if(e.done){rr(e);return}z=ne(I.value.trim()),z.subscribe({onProgress:rr,onDone:e=>{rr(e),z?.close(),z=null}})}))}function rr(e){L.value=Math.round(e.progress_pct),Un.value=e.speed,Wn.value=e.eta,Gn.value=Zn(e.downloaded_bytes),Kn.value=e.total_bytes?Zn(e.total_bytes):null,qn.value=e.dest,e.done&&(F.value=!1,e.error?R.value=e.error:(Jn.value=!0,X()))}async function ir(){U.worker=``,B.value=[],Y.worker.backend!==`mock`&&await Z()}async function ar(){U.architect=``,V.value=[],await or()}async function Z(){if(Y.worker.backend!==`mock`){H.worker=!0,U.worker=``;try{let e=await fe(Y.worker.backend,Y.worker.base_url,``);e.error?Y.worker.backend===`llama_server`?U.worker=`💡 llama-server 未启动,请先点击上方「启动服务」`:U.worker=e.error||`连接失败`:B.value=e.models||[]}catch{U.worker=`获取模型列表失败`}finally{H.worker=!1}}}async function or(){if(H.architect=!0,U.architect=``,!Y.architect.base_url){V.value=[...q],H.architect=!1;return}try{let e=await fe(`openai`,Y.architect.base_url,Y.architect.api_key||``);e.error?(U.architect=e.error,V.value=[...q]):(e.models||[]).length>0?V.value=e.models||[]:V.value=[...q]}catch{U.architect=`获取模型列表失败`,V.value=[...q]}finally{H.architect=!1}}async function sr(){if(Y.worker.backend!==`mock`){W.worker=!0,G.worker=null,K.worker=``;try{let e=await ge(Y.worker.backend,Y.worker.base_url,``);G.worker=e.ok,e.ok||(K.worker=e.detail||`连接失败`)}catch(e){G.worker=!1,K.worker=e?.message||String(e)}finally{W.worker=!1}}}async function cr(){if(!Y.architect.base_url){G.architect=!1,K.architect=`请先填写 API 端点`;return}W.architect=!0,G.architect=null,K.architect=``;try{let e=await ge(`openai`,Y.architect.base_url,Y.architect.api_key||``);G.architect=e.ok,e.ok||(K.architect=e.detail||`连接失败`)}catch(e){G.architect=!1,K.architect=e?.message||String(e)}finally{W.architect=!1}}function Q(e,t){if(t)for(let n of Object.keys(e))t[n]!==void 0&&(typeof e[n]==`object`&&typeof t[n]==`object`&&e[n]!==null?Q(e[n],t[n]):e[n]=t[n])}function lr(e){if(!e)return;let{api_key:t,api_key_set:n,...r}=e;Q(Y.architect,r),Y.architect.api_key_set=!!n,Y.architect.api_key=``}async function ur(){On.value=``;try{let[e,t]=await Promise.all([pe(),Qn()]);k.value=t,Pn(),e.worker&&Q(Y.worker,e.worker),e.architect&&lr(e.architect),e.pipeline&&Q(Y.pipeline,e.pipeline),J.value=JSON.parse(JSON.stringify(Y)),await X(),V.value=[...q],Y.worker.backend!==`mock`&&Z(),Y.worker.model&&(P.value=Y.worker.model)}catch(e){On.value=`加载配置失败:`+(e?.message||String(e))}}async function dr(){_.value=!0,y.value=null;try{let e=JSON.parse(JSON.stringify(Y));e.architect.api_key||delete e.architect.api_key;let t=await r(e);Q(Y.worker,t.worker||{}),lr(t.architect||{}),Q(Y.pipeline,t.pipeline||{}),J.value=JSON.parse(JSON.stringify(Y)),y.value={ok:!0,msg:`✅ 设置已保存,管线已重建`},setTimeout(()=>y.value=null,3e3)}catch(e){y.value={ok:!1,msg:`❌ 保存失败:`+(e?.message||String(e))}}finally{_.value=!1}}async function fr(){if(confirm(`确定恢复默认设置?`)){_.value=!0,y.value=null;try{let e=await ye();Q(Y.worker,e.worker||{}),lr(e.architect||{}),Q(Y.pipeline,e.pipeline||{}),J.value=JSON.parse(JSON.stringify(Y)),B.value=[],V.value=[...q],G.worker=null,G.architect=null,y.value={ok:!0,msg:`✅ 已恢复默认设置`},setTimeout(()=>y.value=null,3e3)}catch(e){y.value={ok:!1,msg:`❌ 重置失败:`+(e?.message||String(e))}}finally{_.value=!1}}}let $=g({enabled:!1,mode:`collect`,obs:0,labeled:0,min_labels:500});async function pr(){try{let[e,t]=await Promise.all([pe(),ce()]),n=e.sense||{};$.enabled=!!n.enabled,$.mode=n.mode||`collect`,$.min_labels=n.policy?.min_labels??500;let r=t.sense||{};$.obs=r.observations??0,$.labeled=r.labeled??0}catch{}}async function mr(){try{await r({sense:{enabled:$.enabled,mode:$.mode}}),y.value={ok:!0,msg:`✅ 语义分级已${$.enabled?`启用(`+$.mode+``:`关闭`}`}}catch(e){y.value={ok:!1,msg:`❌ 保存失败:`+(e?.response?.data?.detail||e?.message||e)},await pr()}setTimeout(()=>y.value=null,3e3)}return ie(()=>{ur(),pr()}),te(()=>{z?.close()}),(t,n)=>(f(),d(`div`,be,[n[73]||=i(`header`,{class:`settings-header`},[i(`h2`,null,`⚙️ 模型设置`),i(`p`,{class:`subtitle`},`配置小模型(Worker)与大模型(Architect)参数,保存后实时生效`)],-1),i(`section`,xe,[i(`div`,{class:`section-title`},[n[31]||=i(`span`,null,`🗄️ 模型池(多价位异构模型)`,-1),i(`div`,{class:`title-right`},[i(`button`,{class:`btn-refresh`,onClick:In},` 添加模型`)])]),i(`div`,Se,[i(`div`,Ce,[(f(),d(l,null,p(kn,e=>i(`div`,{class:`role-item`,key:e.key},[i(`label`,null,u(e.label),1),o(i(`select`,{"onUpdate:modelValue":t=>x[e.key]=t,onChange:Fn},[n[32]||=i(`option`,{value:``},`经典设置(下方表单)`,-1),(f(!0),d(l,null,p(Mn.value,e=>(f(),d(`option`,{key:e.id,value:e.id},u(e.name),9,Te))),128))],40,we),[[h,x[e.key]]])])),64))]),n[46]||=i(`p`,{class:`role-hint`},` 按价位组织模型:本地 llama.cpp 为零成本档,低价 API 干批量活,旗舰 API 做决策—— 随时切换,保存后管线自动重建。 `,-1),b.value.entries.length?(f(),d(`table`,Ee,[n[33]||=i(`thead`,null,[i(`tr`,null,[i(`th`,null,`名称`),i(`th`,null,`档位`),i(`th`,null,`后端`),i(`th`,null,`模型`),i(`th`,null,`单价 $/1M(入/出)`),i(`th`,null,`启用`),i(`th`,null,`操作`)])],-1),i(`tbody`,null,[(f(!0),d(l,null,p(b.value.entries,t=>(f(),d(`tr`,{key:t.id},[i(`td`,null,u(t.name),1),i(`td`,null,[i(`span`,{class:m([`tier-badge`,`tier-`+t.tier])},u(Nn(t.tier)),3)]),i(`td`,null,u(t.backend),1),i(`td`,De,u(t.model||`—`),1),i(`td`,null,u(t.price_in)+` / `+u(t.price_out),1),i(`td`,null,[o(i(`input`,{type:`checkbox`,"onUpdate:modelValue":e=>t.enabled=e,onChange:e=>Bn(t)},null,40,Oe),[[e,t.enabled]])]),i(`td`,ke,[i(`button`,{class:`btn-refresh`,disabled:w.value===t.id,onClick:e=>Vn(t)},u(w.value===t.id?`…`:`测试`),9,Ae),i(`button`,{class:`btn-refresh`,onClick:e=>Ln(t)},`编辑`,8,je),i(`button`,{class:`btn-refresh danger`,onClick:e=>zn(t)},`删除`,8,Me)])]))),128))])])):(f(),d(`div`,Ne,` 池为空——可添加本地 llama.cpp 模型(零成本档)、低价 API、旗舰 API 等,随时指派给 Architect / Worker / Agent。 `)),T.value?(f(),d(`div`,{key:2,class:m([`field-hint`,E.value?`ok`:`warn`])},u(T.value),3)):s(``,!0),S.value?(f(),d(`div`,Pe,[i(`div`,Fe,u(C.value?`添加模型`:`编辑模型`),1),i(`div`,Ie,[i(`div`,Le,[n[34]||=i(`label`,null,`名称`,-1),o(i(`input`,{"onUpdate:modelValue":n[0]||=e=>S.value.name=e,placeholder:`如:DeepSeek 旗舰 / 本地 Qwen4B`},null,512),[[c,S.value.name]])]),i(`div`,Re,[n[36]||=i(`label`,null,`档位`,-1),o(i(`select`,{"onUpdate:modelValue":n[1]||=e=>S.value.tier=e},[...n[35]||=[i(`option`,{value:`local`},`local(本地 / 零边际成本)`,-1),i(`option`,{value:`budget`},`budget(低价 API`,-1),i(`option`,{value:`premium`},`premium(旗舰 API`,-1)]],512),[[h,S.value.tier]])]),i(`div`,ze,[n[38]||=i(`label`,null,`后端`,-1),o(i(`select`,{"onUpdate:modelValue":n[2]||=e=>S.value.backend=e},[...n[37]||=[i(`option`,{value:`openai`},`openai / 兼容 API`,-1),i(`option`,{value:`llama_server`},`llama_server(内置本地)`,-1),i(`option`,{value:`mock`},`mock(模拟)`,-1)]],512),[[h,S.value.backend]])]),i(`div`,Be,[i(`label`,null,[n[39]||=v(` 模型 `,-1),i(`button`,{class:`btn-refresh btn-inline`,disabled:O.value,onClick:Hn},u(O.value?`…`:`🔄 刷新列表`),9,Ve)]),o(i(`input`,{"onUpdate:modelValue":n[3]||=e=>S.value.model=e,list:`pool-model-options`,placeholder:`模型名`},null,512),[[c,S.value.model]]),i(`datalist`,He,[(f(!0),d(l,null,p(jn.value,e=>(f(),d(`option`,{key:e.id,value:e.id},null,8,Ue))),128))])]),S.value.backend===`mock`?s(``,!0):(f(),d(`div`,We,[n[40]||=i(`label`,null,`API 地址`,-1),o(i(`input`,{"onUpdate:modelValue":n[4]||=e=>S.value.base_url=e,placeholder:`https://api.deepseek.com 或 http://127.0.0.1:8901/v1`},null,512),[[c,S.value.base_url]])])),S.value.backend===`openai`?(f(),d(`div`,Ge,[i(`label`,null,`API Key`+u(S.value.api_key_set?`(已设置,留空保留)`:``),1),o(i(`input`,{"onUpdate:modelValue":n[5]||=e=>S.value.api_key=e,type:`password`,autocomplete:`off`,placeholder:`sk-…`},null,512),[[c,S.value.api_key]])])):s(``,!0),i(`div`,Ke,[n[41]||=i(`label`,null,`输入单价 $/1M`,-1),o(i(`input`,{"onUpdate:modelValue":n[6]||=e=>S.value.price_in=e,type:`number`,min:`0`,step:`0.01`},null,512),[[c,S.value.price_in,void 0,{number:!0}]])]),i(`div`,qe,[n[42]||=i(`label`,null,`输出单价 $/1M`,-1),o(i(`input`,{"onUpdate:modelValue":n[7]||=e=>S.value.price_out=e,type:`number`,min:`0`,step:`0.01`},null,512),[[c,S.value.price_out,void 0,{number:!0}]])]),i(`div`,Je,[n[43]||=i(`label`,null,`Temperature`,-1),o(i(`input`,{"onUpdate:modelValue":n[8]||=e=>S.value.temperature=e,type:`number`,min:`0`,max:`2`,step:`0.05`},null,512),[[c,S.value.temperature,void 0,{number:!0}]])]),i(`div`,Ye,[n[44]||=i(`label`,null,`Max Tokens`,-1),o(i(`input`,{"onUpdate:modelValue":n[9]||=e=>S.value.max_tokens=e,type:`number`,min:`256`,max:`32768`},null,512),[[c,S.value.max_tokens,void 0,{number:!0}]])])]),i(`div`,Xe,[i(`label`,Ze,[o(i(`input`,{type:`checkbox`,"onUpdate:modelValue":n[10]||=e=>S.value.enabled=e},null,512),[[e,S.value.enabled]]),n[45]||=v(` 启用 `,-1)]),i(`button`,{class:`btn-primary`,disabled:D.value,onClick:Rn},u(D.value?`保存中…`:`保存条目`),9,Qe),i(`button`,{class:`btn-secondary`,onClick:n[11]||=e=>S.value=null},`取消`)])])):s(``,!0)])]),i(`section`,$e,[i(`div`,et,[n[47]||=i(`span`,null,`🔧 小模型 (Worker · 本地 llama.cpp)`,-1),i(`div`,tt,[i(`span`,{class:m([`server-badge`,k.value.running?`badge-running`:`badge-stopped`])},u(k.value.running?`● 运行中`:`○ 已停止`),3)])]),i(`div`,nt,[i(`div`,rt,[i(`div`,it,[k.value.running?(f(),d(l,{key:0},[i(`span`,at,u(k.value.model?.split(/[/\\]/).pop()),1),i(`span`,ot,`:`+u(k.value.port),1),i(`span`,st,`PID `+u(k.value.pid),1)],64)):(f(),d(`span`,ct,`llama-server 未运行 — 点击「启动服务」即可启用`))]),i(`div`,lt,[k.value.running?(f(),d(`button`,{key:1,class:`btn-stop`,disabled:A.value||j.value,onClick:er},u(j.value?`停止中…`:`■ 停止服务`),9,dt)):(f(),d(`button`,{key:0,class:`btn-start`,disabled:A.value||j.value,onClick:$n},u(A.value?`启动中…`:`▶ 启动服务`),9,ut))])]),k.value.error?(f(),d(`div`,ft,u(k.value.error),1)):s(``,!0),i(`div`,pt,[i(`div`,mt,[i(`span`,null,`📁 本地模型 (`+u(M.value.length)+`)`,1),i(`button`,{class:`btn-refresh`,disabled:N.value,onClick:X},u(N.value?`…`:`🔄`),9,ht)]),M.value.length===0&&!N.value?(f(),d(`div`,gt,` 暂无本地模型,请下载或放置 .gguf 文件到 models/ 目录 `)):(f(),d(`div`,_t,[(f(!0),d(l,null,p(M.value,e=>(f(),d(`div`,{key:e.id,class:m([`model-item`,P.value===e.id?`selected`:``]),onClick:t=>tr(e)},[i(`span`,yt,u(e.name),1),i(`span`,bt,u(e.size_mb)+` MB`,1)],10,vt))),128))]))]),i(`div`,xt,[n[48]||=i(`div`,{class:`download-header`},`⬇️ 下载模型`,-1),i(`div`,St,[o(i(`input`,{"onUpdate:modelValue":n[12]||=e=>I.value=e,class:`download-input`,placeholder:`HuggingFace 路径或直链,如:Qwen/Qwen3-4B-GGUF/Qwen3-4B-Q4_K_M.gguf`,disabled:F.value},null,8,Ct),[[c,I.value]]),i(`button`,{class:`btn-download`,disabled:F.value||!I.value.trim(),onClick:nr},u(F.value?L.value+`%`:`下载`),9,wt)]),F.value?(f(),d(`div`,Tt,[i(`div`,Et,[i(`div`,{class:`progress-fill`,style:ae({width:L.value+`%`})},null,4)]),i(`div`,Dt,[i(`span`,null,u(Un.value),1),i(`span`,null,u(Wn.value),1),i(`span`,null,u(Gn.value)+`/`+u(Kn.value||`?`),1)])])):s(``,!0),R.value?(f(),d(`div`,Ot,u(R.value),1)):s(``,!0),Jn.value&&!R.value?(f(),d(`div`,kt,` ✅ 下载完成:`+u(qn.value),1)):s(``,!0)]),i(`div`,At,[i(`div`,jt,[n[50]||=i(`label`,null,`后端类型`,-1),o(i(`select`,{"onUpdate:modelValue":n[13]||=e=>Y.worker.backend=e,onChange:ir},[...n[49]||=[i(`option`,{value:`mock`},`mock(模拟,不真实调用)`,-1),i(`option`,{value:`llama_server`},`llama_server(内置本地服务,推荐)`,-1),i(`option`,{value:`openai`},`openai / 兼容 APIOllama 等)`,-1)]],544),[[h,Y.worker.backend]])]),Y.worker.backend===`mock`?s(``,!0):(f(),d(`div`,Mt,[i(`label`,null,[n[51]||=v(` API 地址 `,-1),i(`button`,{class:`btn-refresh btn-inline`,disabled:W.worker,onClick:sr},u(W.worker?`…`:`🔗 连接测试`),9,Nt)]),i(`div`,Pt,[o(i(`input`,{"onUpdate:modelValue":n[14]||=e=>Y.worker.base_url=e,placeholder:Yn.value,onBlur:ir},null,40,Ft),[[c,Y.worker.base_url]]),G.worker===null?s(``,!0):(f(),d(`span`,{key:0,class:m([`ping-badge`,G.worker?`ping-ok`:`ping-err`])},u(G.worker?`✅ 正常`:`❌ `+K.worker),3))])])),Y.worker.backend===`mock`?s(``,!0):(f(),d(`div`,It,[i(`label`,null,[n[52]||=v(` 模型 `,-1),i(`button`,{class:`btn-refresh btn-inline`,disabled:H.worker,onClick:Z},u(H.worker?`…`:`🔄 刷新列表`),9,Lt)]),Y.worker.backend===`llama_server`?o((f(),d(`select`,{key:0,"onUpdate:modelValue":n[15]||=e=>Y.worker.model=e},[n[53]||=i(`option`,{value:``,disabled:``},`—— 从本地模型中选择 ——`,-1),(f(!0),d(l,null,p(M.value,e=>(f(),d(`option`,{key:e.id,value:e.id},u(e.name),9,Rt))),128))],512)),[[h,Y.worker.model]]):Y.worker.backend===`openai`?o((f(),d(`select`,{key:1,"onUpdate:modelValue":n[16]||=e=>Y.worker.model=e},[n[54]||=i(`option`,{value:``,disabled:``},`—— 从 API 获取 ——`,-1),(f(!0),d(l,null,p(B.value,e=>(f(),d(`option`,{key:e.id,value:e.id},u(e.name||e.id),9,zt))),128))],512)),[[h,Y.worker.model]]):o((f(),d(`input`,{key:2,"onUpdate:modelValue":n[17]||=e=>Y.worker.model=e,placeholder:`输入模型名称…`},null,512)),[[c,Y.worker.model]]),U.worker?(f(),d(`span`,Bt,u(U.worker),1)):s(``,!0)])),Y.worker.backend===`llama_server`?(f(),d(`div`,Vt,[n[55]||=i(`label`,null,`端口`,-1),o(i(`input`,{"onUpdate:modelValue":n[18]||=e=>Y.worker.port=e,type:`number`,min:`1`,max:`65535`},null,512),[[c,Y.worker.port,void 0,{number:!0}]])])):s(``,!0),i(`div`,Ht,[n[56]||=i(`label`,null,`Temperature`,-1),o(i(`input`,{"onUpdate:modelValue":n[19]||=e=>Y.worker.temperature=e,type:`number`,min:`0`,max:`2`,step:`0.05`},null,512),[[c,Y.worker.temperature,void 0,{number:!0}]])]),i(`div`,Ut,[n[57]||=i(`label`,null,`最大修复轮次`,-1),o(i(`input`,{"onUpdate:modelValue":n[20]||=e=>Y.worker.max_fix_attempts=e,type:`number`,min:`0`,max:`10`},null,512),[[c,Y.worker.max_fix_attempts,void 0,{number:!0}]])]),i(`div`,Wt,[n[58]||=i(`label`,null,`代码执行超时 (秒)`,-1),o(i(`input`,{"onUpdate:modelValue":n[21]||=e=>Y.worker.code_timeout_s=e,type:`number`,min:`1`,max:`300`},null,512),[[c,Y.worker.code_timeout_s,void 0,{number:!0}]])])])])]),i(`section`,Gt,[i(`div`,Kt,[n[59]||=i(`span`,null,`🧠 大模型 (Architect · API 云端)`,-1),i(`div`,qt,[G.architect===null?s(``,!0):(f(),d(`span`,{key:0,class:m([`ping-badge`,G.architect?`ping-ok`:`ping-err`])},u(G.architect?`✅ 已连接`:`❌ `+K.architect),3))])]),i(`div`,Jt,[i(`div`,Yt,[i(`div`,Xt,[i(`label`,null,[n[60]||=v(` API 端点 `,-1),i(`button`,{class:`btn-refresh btn-inline`,disabled:W.architect,onClick:cr},u(W.architect?`…`:`🔗 连接测试`),9,Zt)]),o(i(`input`,{"onUpdate:modelValue":n[22]||=e=>Y.architect.base_url=e,placeholder:`https://api.deepseek.com`,onBlur:ar},null,544),[[c,Y.architect.base_url]])]),i(`div`,Qt,[i(`label`,null,`API Key`+u(Y.architect.api_key_set?`(已设置,留空保留)`:`(保存在本地 config/settings.json,不入代码库;优先级高于 .env)`),1),o(i(`input`,{"onUpdate:modelValue":n[23]||=e=>Y.architect.api_key=e,type:`password`,placeholder:Y.architect.api_key_set?`已设置,留空保留原值`:`sk-xxxxxxxxxxxxxxxx`,autocomplete:`off`},null,8,$t),[[c,Y.architect.api_key]])]),i(`div`,en,[i(`label`,null,[n[61]||=v(` 模型 `,-1),i(`button`,{class:`btn-refresh btn-inline`,disabled:H.architect,onClick:or},u(H.architect?`…`:`🔄 刷新列表`),9,tn)]),o(i(`select`,{"onUpdate:modelValue":n[24]||=e=>Y.architect.model=e,class:`model-select`},[n[62]||=i(`option`,{value:``,disabled:``},`—— 从 API 获取模型列表 ——`,-1),(f(!0),d(l,null,p(V.value,e=>(f(),d(`option`,{key:e.id,value:e.id},u(e.name||e.id),9,nn))),128))],512),[[h,Y.architect.model]]),U.architect?(f(),d(`span`,rn,u(U.architect),1)):s(``,!0)])])])]),i(`section`,an,[n[68]||=i(`div`,{class:`section-title`},[i(`span`,null,`⚙️ 协作管线 (Pipeline)`)],-1),i(`div`,on,[i(`div`,sn,[i(`div`,cn,[i(`label`,ln,[o(i(`input`,{type:`checkbox`,"onUpdate:modelValue":n[25]||=e=>Y.pipeline.fast_path=e},null,512),[[e,Y.pipeline.fast_path]]),n[63]||=v(` 启用快路径(简单查询跳过本地模型,直接由大模型回答,省 API 费用) `,-1)])]),i(`div`,un,[n[64]||=i(`label`,null,`最大协作轮次`,-1),o(i(`input`,{"onUpdate:modelValue":n[26]||=e=>Y.pipeline.rounds_cap=e,type:`number`,min:`1`,max:`20`},null,512),[[c,Y.pipeline.rounds_cap,void 0,{number:!0}]])]),i(`div`,dn,[n[65]||=i(`label`,null,`API Token 熔断上限`,-1),o(i(`input`,{"onUpdate:modelValue":n[27]||=e=>Y.pipeline.api_token_cap=e,type:`number`,min:`100`,max:`100000`},null,512),[[c,Y.pipeline.api_token_cap,void 0,{number:!0}]])]),i(`div`,fn,[n[67]||=i(`label`,null,`超限策略`,-1),o(i(`select`,{"onUpdate:modelValue":n[28]||=e=>Y.pipeline.breach_policy=e},[...n[66]||=[i(`option`,{value:`architect_do`},`architect_do(超限交给大模型处理,推荐)`,-1),i(`option`,{value:`local_only`},`local_only(强制留在本地小模型)`,-1)]],512),[[h,Y.pipeline.breach_policy]])])])])]),i(`section`,pn,[i(`div`,mn,[n[69]||=i(`span`,null,`🧠 语义分级(Sense · 三级任务分级)`,-1),i(`div`,hn,[i(`span`,{class:m([`server-badge`,$.enabled?`badge-running`:`badge-stopped`])},u($.enabled?`● ${$.mode}`:`○ 未启用`),3)])]),i(`div`,gn,[i(`p`,_n,` 灰度纪律:collect(只记不决策)攒满 `+u($.min_labels)+` 条标签并过晋升门 (一致率 ≥85% + conformal 覆盖 ≤α+2% + 审计无误判)后才可开 live。 `,1),i(`div`,vn,[i(`div`,yn,[i(`label`,bn,[o(i(`input`,{type:`checkbox`,"onUpdate:modelValue":n[29]||=e=>$.enabled=e,onChange:mr},null,544),[[e,$.enabled]]),n[70]||=v(` 启用语义分析器(总开关,改后保存生效) `,-1)])]),i(`div`,xn,[n[72]||=i(`label`,null,`灰度模式`,-1),o(i(`select`,{"onUpdate:modelValue":n[30]||=e=>$.mode=e,onChange:mr,disabled:!$.enabled},[...n[71]||=[i(`option`,{value:`collect`},`collect — 只采集观察`,-1),i(`option`,{value:`shadow`},`shadow — 决策只比对不执行`,-1),i(`option`,{value:`live`},`live — 真分流(需晋升门通过)`,-1)]],40,Sn),[[h,$.mode]])]),i(`div`,Cn,[i(`label`,null,`观察/标签数(min_labels=`+u($.min_labels)+``,1),i(`input`,{value:`${$.obs} / ${$.labeled}`,disabled:``},null,8,wn)])])])]),i(`div`,Tn,[i(`button`,{class:`btn-primary`,disabled:_.value||!Xn.value,onClick:dr},u(_.value?`保存中…`:`💾 保存设置`),9,En),i(`button`,{class:`btn-secondary`,disabled:_.value,onClick:fr},` 🔁 恢复默认 `,8,Dn)]),y.value?(f(),d(`div`,{key:0,class:m([`toast`,y.value.ok?`toast-ok`:`toast-err`])},u(y.value.msg),3)):s(``,!0)]))}}),[[`__scopeId`,`data-v-bedfedd6`]]);export{On as default};