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