8 lines
22 KiB
JavaScript
8 lines
22 KiB
JavaScript
import{_ as oe,u as le,i as ne,j as g,c as s,b as t,k as x,f as r,F as V,l as J,w as se,t as u,e as a,v as p,m as T,d as m,y as I,q as C,r as y,p as ie,n as B,o as i}from"./index-BZEF5hZc.js";const re={class:"toolbar"},ae={class:"panel"},de={class:"data-table"},ue={class:"url-cell"},pe=["onClick"],me=["onClick","disabled"],fe=["onClick"],_e={class:"modal"},ye={class:"modal-header"},ve={class:"modal-body"},be={class:"form-group"},ke={class:"form-group"},ge={key:0,class:"field-hint"},ce={key:1,class:"field-hint"},we={key:0,class:"form-group"},xe={key:1,class:"form-group"},Ie=["value"],Ce=["value"],Ue={class:"form-group"},Se={class:"workflow-actions"},Pe={class:"btn btn-secondary btn-sm file-btn"},Ae={class:"form-group"},he={key:0,class:"form-group"},Ve={class:"form-row-2"},$e={class:"form-group"},Me={class:"form-group"},Oe={class:"form-row-2"},Ne={class:"form-group"},Fe={class:"form-group"},De={class:"form-group"},qe=["placeholder"],Je={key:3,class:"form-group"},Te={key:0,class:"saved-key-hint"},Be={key:1,class:"field-hint field-hint-warn"},Ke=["placeholder"],Xe={key:4,class:"form-group"},Ee=["placeholder"],We={key:5,class:"form-group"},ze={key:6,class:"form-group"},Le={class:"form-group"},Re={class:"form-group"},je={key:7,class:"form-group"},Ge={key:0,class:"field-hint"},Ze={key:1,class:"field-hint"},He={key:8,class:"form-group"},Ye={class:"form-group"},Qe={class:"form-group"},et={key:0},tt={key:0},ot={key:1,class:"reply-preview"},lt={key:2},nt={class:"modal-footer"},st=["disabled"],it=`留空则使用内置通用扩写规则。
|
||
可自定义,例如:
|
||
You are a prompt engineer...
|
||
Always prefer Chinese mythic illustration style when relevant.
|
||
Never put readable text in the image.`,rt={__name:"ModelsView",setup(at){const c=le(),F=y([]),v=y(!1),f=y(null),U=y(!1),S=y(null),d=y(null),w=y(!1),$=y(""),b=y(""),P=["1:1 (Square)","2:3 (Portrait Photo)","3:2 (Photo)","3:4 (Portrait Standard)","4:3 (Standard)","9:16 (Portrait Widescreen)","16:9 (Widescreen)","21:9 (Ultrawide)"],M=B(()=>{const l=(b.value||"").trim();if(/^\d+\s*[xX×]\s*\d+$/.test(l))return l.replace(/\s*[xX×]\s*/,"x");const e=(o.model_id||"").trim();return/^\d+\s*[xX×]\s*\d+$/.test(e)&&!P.includes(e)?e.replace(/\s*[xX×]\s*/,"x"):""}),o=ie({name:"",provider:"openai",model_id:"",api_base_url:"https://api.openai.com/v1",api_key:"",max_tokens:4096,temperature:.7,is_default:!1,enabled:!0,support_context:!0,support_image:!0,frequency_penalty:0,presence_penalty:0,workflow_json:"",prompt_node:"",seed_node:"",img2img_denoise:.45,inpaint_denoise:.72,refine_prompt:!0,system_prompt:""});function K(){const l=(b.value||"").trim();/^\d+\s*[xX×]\s*\d+$/.test(l)&&(o.model_id=l.replace(/\s*[xX×]\s*/,"x"))}function O(l){const e=(l||"").trim();if(!e)return"";if(P.includes(e))return e;if(/^\d+\s*[xX×]\s*\d+$/.test(e))return e.replace(/\s*[xX×]\s*/,"x");const n=e.match(/^(\d+)\s*:\s*(\d+)$/);if(n){const _=`${n[1]}:${n[2]}`,h=P.find(k=>k.startsWith(_+" "));if(h)return h}return""}const X=B(()=>o.provider==="dify"?"https://api.dify.ai/v1(或自部署地址)":o.provider==="comfy"?"http://127.0.0.1:8188":"https://api.openai.com/v1");function E(l){return l==="dify"?"Dify":l==="comfy"?"ComfyUI":"OpenAI 兼容"}function W(l){return l==="dify"?"badge-info":l==="comfy"?"badge-warn":"badge-success"}function z(l){return l==="dify"||l==="comfy"?l:"openai"}function L(){o.provider==="comfy"?((!o.api_base_url||o.api_base_url.includes("openai")||o.api_base_url.includes("dify"))&&(o.api_base_url="http://127.0.0.1:8188"),o.support_context=!1,o.support_image=!1,o.model_id=O(o.model_id)||"1:1 (Square)",b.value=/^\d+x\d+$/.test(o.model_id)?o.model_id:""):o.provider==="dify"?(!o.api_base_url||o.api_base_url.includes("8188")||o.api_base_url.includes("openai"))&&(o.api_base_url="https://api.dify.ai/v1"):(!o.api_base_url||o.api_base_url.includes("8188")||o.api_base_url.includes("dify"))&&(o.api_base_url="https://api.openai.com/v1")}function R(l){if(!l)return{workflow_json:"",prompt_node:"",seed_node:"",img2img_denoise:.45,inpaint_denoise:.72,refine_prompt:!0,system_prompt:""};if(typeof l=="string")try{l=JSON.parse(l)}catch{return{workflow_json:"",prompt_node:"",seed_node:"",img2img_denoise:.45,inpaint_denoise:.72,refine_prompt:!0,system_prompt:""}}return{workflow_json:l.workflow?JSON.stringify(l.workflow,null,2):"",prompt_node:l.prompt_node||"",seed_node:l.seed_node||"",img2img_denoise:Number(l.img2img_denoise??.45),inpaint_denoise:Number(l.inpaint_denoise??.72),refine_prompt:l.refine_prompt===void 0?!0:!!l.refine_prompt,system_prompt:l.system_prompt||""}}function D(l){return!!(l&&typeof l=="object"&&Array.isArray(l.nodes)&&(l.links||l.version||l.last_node_id))}function A(l){return!l||typeof l!="object"||Array.isArray(l)?!1:Object.values(l).some(e=>e&&typeof e=="object"&&e.class_type&&e.inputs&&typeof e.inputs=="object")}function q(l){return l!=null&&l.prompt&&A(l.prompt)?l.prompt:l!=null&&l.workflow&&A(l.workflow)?l.workflow:l}function j(){if(o.provider!=="comfy")return null;const l={},e=(o.workflow_json||"").trim();if(e){let n;try{n=JSON.parse(e)}catch{throw new Error("工作流 JSON 格式无效,请检查是否为合法 JSON")}if(n=q(n),D(n))throw new Error("请导入 API Format 工作流(ComfyUI 开发者模式 → Save (API Format)),不要导入带 nodes/links 的 UI Format");if(!A(n))throw new Error("工作流不是有效的 API Format(节点需包含 class_type / inputs)");l.workflow=n}return(o.prompt_node||"").trim()&&(l.prompt_node=o.prompt_node.trim()),(o.seed_node||"").trim()&&(l.seed_node=o.seed_node.trim()),l.img2img_denoise=Math.max(.01,Math.min(1,Number(o.img2img_denoise)||.45)),l.inpaint_denoise=Math.max(.01,Math.min(1,Number(o.inpaint_denoise)||.72)),(o.system_prompt||"").trim()&&(l.system_prompt=o.system_prompt.trim()),l.refine_prompt=!!o.refine_prompt,l}function G(l){var _;const e=(_=l.target.files)==null?void 0:_[0];if(l.target.value="",!e)return;const n=new FileReader;n.onload=()=>{try{const h=String(n.result||"");let k=JSON.parse(h);if(k=q(k),D(k)){alert("这是 UI Format 工作流,不能用于后端生图。请在 ComfyUI 开启开发者模式后使用 Save (API Format) 重新导出。");return}if(!A(k)){alert("无法识别为 API Format 工作流");return}o.workflow_json=JSON.stringify(k,null,2)}catch{alert("无法解析该 JSON 文件")}},n.readAsText(e)}ne(N);async function N(){const l=await g.get("/admin/models");F.value=l.data.data}function Z(){f.value=null,d.value=null,w.value=!1,$.value="",b.value="",Object.assign(o,{name:"",provider:"openai",model_id:"",api_base_url:"https://api.openai.com/v1",api_key:"",max_tokens:4096,temperature:.7,is_default:!1,enabled:!0,support_context:!0,support_image:!0,frequency_penalty:0,presence_penalty:0,workflow_json:"",prompt_node:"",seed_node:"",img2img_denoise:.45,inpaint_denoise:.72,refine_prompt:!0,system_prompt:""}),v.value=!0}function H(l){f.value=l.id,d.value=null,w.value=!!l.has_api_key,$.value=l.api_key_hint||"";const e=R(l.extra_config),n=z(l.provider),_=n==="comfy"?O(l.model_id):l.model_id||"";b.value=/^\d+x\d+$/.test(_)?_:"",Object.assign(o,{name:l.name,provider:n,model_id:_,api_base_url:l.api_base_url,api_key:"",max_tokens:l.max_tokens,temperature:parseFloat(l.temperature),is_default:!!l.is_default,enabled:!!l.enabled,support_context:l.support_context===void 0?!0:!!l.support_context,support_image:l.support_image===void 0?!0:!!l.support_image,frequency_penalty:l.frequency_penalty!==void 0&&l.frequency_penalty!==null?parseFloat(l.frequency_penalty):0,presence_penalty:l.presence_penalty!==void 0&&l.presence_penalty!==null?parseFloat(l.presence_penalty):0,workflow_json:e.workflow_json,prompt_node:e.prompt_node,seed_node:e.seed_node,img2img_denoise:e.img2img_denoise,inpaint_denoise:e.inpaint_denoise,refine_prompt:e.refine_prompt,system_prompt:e.system_prompt}),v.value=!0}async function Y(){let l=null;try{l=j()}catch(n){alert(n.message||"配置无效");return}o.provider==="comfy"&&(o.model_id=O(o.model_id));const e={...o,is_default:o.is_default?1:0,enabled:o.enabled?1:0,support_context:o.support_context?1:0,support_image:o.support_image?1:0,extra_config:l};delete e.workflow_json,delete e.prompt_node,delete e.seed_node,delete e.img2img_denoise,delete e.inpaint_denoise,delete e.refine_prompt,delete e.system_prompt,f.value?(e.api_key||delete e.api_key,await g.put(`/admin/models/${f.value}`,e)):await g.post("/admin/models",e),v.value=!1,await N()}async function Q(l){confirm("确定删除此模型?")&&(await g.delete(`/admin/models/${l}`),await N())}async function ee(){if(o.provider==="comfy"){if(!o.api_base_url){d.value={ok:!1,message:"请填写 ComfyUI 地址"};return}}else if(o.provider==="dify"){if(!o.api_base_url){d.value={ok:!1,message:"请填写 API 地址"};return}if(!o.api_key&&!f.value){d.value={ok:!1,message:"请填写 API Key"};return}if(!o.api_key&&f.value&&!w.value){d.value={ok:!1,message:"当前模型未配置 Key,请填写"};return}}else if(!o.model_id||!o.api_base_url){d.value={ok:!1,message:"请填写 Model ID 和 API 地址"};return}U.value=!0,d.value=null;try{const l={provider:o.provider,model_id:o.model_id,api_base_url:o.api_base_url,temperature:o.temperature};o.api_key&&(l.api_key=o.api_key);const e=f.value?`/admin/models/${f.value}/test`:"/admin/models/test",n=await g.post(e,l);d.value={ok:!0,...n.data.data}}catch(l){d.value={ok:!1,message:l.message}}finally{U.value=!1}}async function te(l){S.value=l;try{const e=await g.post(`/admin/models/${l}/test`,{});alert(`测试成功!
|
||
延迟: ${e.data.data.latency_ms}ms
|
||
回复: ${e.data.data.reply}`)}catch(e){alert("测试失败: "+e.message)}finally{S.value=null}}return(l,e)=>(i(),s("div",null,[e[66]||(e[66]=t("div",{class:"page-header"},[t("h2",null,"AI 模型配置"),t("p",null,"对接 OpenAI / Dify / ComfyUI 接口")],-1)),t("div",re,[x(c).hasButton("btn:model:create")?(i(),s("button",{key:0,class:"btn btn-primary",onClick:Z},"添加模型")):r("",!0)]),t("div",ae,[t("table",de,[e[28]||(e[28]=t("thead",null,[t("tr",null,[t("th",null,"名称"),t("th",null,"接口类型"),t("th",null,"Model ID"),t("th",null,"API 地址"),t("th",null,"Max Tokens"),t("th",null,"默认"),t("th",null,"上下文"),t("th",null,"图片"),t("th",null,"状态"),t("th",null,"操作")])],-1)),t("tbody",null,[(i(!0),s(V,null,J(F.value,n=>(i(),s("tr",{key:n.id},[t("td",null,u(n.name),1),t("td",null,[t("span",{class:C(["badge",W(n.provider)])},u(E(n.provider)),3)]),t("td",null,[t("code",null,u(n.model_id||"-"),1)]),t("td",ue,u(n.api_base_url),1),t("td",null,u(n.provider==="dify"||n.provider==="comfy"?"-":n.max_tokens),1),t("td",null,u(n.is_default?"✓":"-"),1),t("td",null,[t("span",{class:C(["badge",n.support_context?"badge-success":"badge-info"])},u(n.support_context?"支持":"不支持"),3)]),t("td",null,[t("span",{class:C(["badge",n.support_image?"badge-success":"badge-info"])},u(n.support_image?"支持":"不支持"),3)]),t("td",null,[t("span",{class:C(["badge",n.enabled?"badge-success":"badge-danger"])},u(n.enabled?"启用":"禁用"),3)]),t("td",null,[x(c).hasButton("btn:model:edit")?(i(),s("button",{key:0,class:"btn btn-ghost",onClick:_=>H(n)},"编辑",8,pe)):r("",!0),x(c).hasButton("btn:model:test")?(i(),s("button",{key:1,class:"btn btn-ghost",onClick:_=>te(n.id),disabled:S.value===n.id},u(S.value===n.id?"测试中...":"测试"),9,me)):r("",!0),x(c).hasButton("btn:model:delete")?(i(),s("button",{key:2,class:"btn btn-danger",onClick:_=>Q(n.id)},"删除",8,fe)):r("",!0)])]))),128))])])]),v.value?(i(),s("div",{key:0,class:"modal-overlay",onClick:e[27]||(e[27]=se(n=>v.value=!1,["self"]))},[t("div",_e,[t("div",ye,[t("h3",null,u(f.value?"编辑模型":"添加模型"),1),t("button",{onClick:e[0]||(e[0]=n=>v.value=!1)},"×")]),t("div",ve,[t("div",be,[e[29]||(e[29]=t("label",null,"显示名称",-1)),a(t("input",{"onUpdate:modelValue":e[1]||(e[1]=n=>o.name=n),class:"form-input"},null,512),[[p,o.name]])]),t("div",ke,[e[32]||(e[32]=t("label",null,"接口类型",-1)),a(t("select",{"onUpdate:modelValue":e[2]||(e[2]=n=>o.provider=n),class:"form-input",onChange:L},[...e[30]||(e[30]=[t("option",{value:"openai"},"OpenAI 兼容(GPT / DeepSeek / vLLM / SGLang 等)",-1),t("option",{value:"dify"},"Dify 应用(chat-messages 接口)",-1),t("option",{value:"comfy"},"ComfyUI 文生图",-1)])],544),[[T,o.provider]]),o.provider==="dify"?(i(),s("p",ge," Dify 使用自己的一套接口协议(/chat-messages),跟 OpenAI 的 /chat/completions 不同,不要混用,否则会报 404 ")):r("",!0),o.provider==="comfy"?(i(),s("p",ce,[...e[31]||(e[31]=[m(" 用户发送的文字会写入工作流的提示词节点并调用本地 ComfyUI 生图。可在下方粘贴自定义工作流 JSON;留空则使用服务器默认文件 ",-1),t("code",null,"backend/config/comfyui_workflow.json",-1),m("(当前为 ZImageTurbo)。 ",-1)])])):r("",!0)]),o.provider==="openai"?(i(),s("div",we,[e[33]||(e[33]=t("label",null,"Model ID",-1)),a(t("input",{"onUpdate:modelValue":e[3]||(e[3]=n=>o.model_id=n),class:"form-input",placeholder:"gpt-4o-mini"},null,512),[[p,o.model_id]])])):r("",!0),o.provider==="comfy"?(i(),s("div",xe,[e[35]||(e[35]=t("label",null,"宽高比(可选)",-1)),a(t("select",{"onUpdate:modelValue":e[4]||(e[4]=n=>o.model_id=n),class:"form-input"},[e[34]||(e[34]=t("option",{value:""},"使用工作流默认",-1)),(i(),s(V,null,J(P,n=>t("option",{key:n,value:n},u(n),9,Ie)),64)),M.value?(i(),s("option",{key:0,value:M.value},u(M.value)+"(自定义分辨率)",9,Ce)):r("",!0)],512),[[T,o.model_id]]),e[36]||(e[36]=t("p",{class:"field-hint"},[m(" 对应 ResolutionSelector 的 aspect_ratio。不要填无关文字;需要像素尺寸时可在下方自定义,例如 "),t("code",null,"1024x1024")],-1)),a(t("input",{"onUpdate:modelValue":e[5]||(e[5]=n=>b.value=n),class:"form-input",style:{"margin-top":"8px"},placeholder:"可选:自定义分辨率 1024x1024",onChange:K},null,544),[[p,b.value]])])):r("",!0),o.provider==="comfy"?(i(),s(V,{key:2},[t("div",Ue,[e[38]||(e[38]=t("label",null,"自定义工作流 JSON(可选)",-1)),a(t("textarea",{"onUpdate:modelValue":e[6]||(e[6]=n=>o.workflow_json=n),class:"form-input workflow-json",rows:"10",placeholder:"从 ComfyUI 导出 API Format 的 workflow JSON,粘贴到这里;留空使用默认工作流"},null,512),[[p,o.workflow_json]]),t("div",Se,[t("label",Pe,[e[37]||(e[37]=m(" 从文件导入 ",-1)),t("input",{type:"file",accept:".json,application/json",onChange:G,hidden:""},null,32)]),t("button",{type:"button",class:"btn btn-secondary btn-sm",onClick:e[7]||(e[7]=n=>o.workflow_json="")},"清空(用默认)")])]),t("div",Ae,[t("label",null,[a(t("input",{type:"checkbox","onUpdate:modelValue":e[8]||(e[8]=n=>o.refine_prompt=n)},null,512),[[I,o.refine_prompt]]),e[39]||(e[39]=m(" AI 提示词扩写(推荐)",-1))]),e[40]||(e[40]=t("p",{class:"field-hint"}," 开启后走工作流 TextGenerate:把用户描述扩成英文视觉提示词再画图。画风以用户描述为准,也可在下方自定义扩写规则。 ",-1))]),o.refine_prompt?(i(),s("div",he,[e[41]||(e[41]=t("label",null,"扩写 System Prompt(可选,自定义风格规则)",-1)),a(t("textarea",{"onUpdate:modelValue":e[9]||(e[9]=n=>o.system_prompt=n),class:"form-input workflow-json",rows:"8",placeholder:it},null,512),[[p,o.system_prompt]]),e[42]||(e[42]=t("p",{class:"field-hint"}," 留空用内置通用规则(不写死清明上河图等具体画风)。若要固定品牌/画风偏好,在此自行编写,例如「默认国潮插画、禁止照片风」等。 ",-1)),t("button",{type:"button",class:"btn btn-secondary btn-sm",style:{"margin-top":"6px"},onClick:e[10]||(e[10]=n=>o.system_prompt="")},"恢复默认")])):r("",!0),t("div",Ve,[t("div",$e,[e[43]||(e[43]=t("label",null,"提示词节点 ID(可选)",-1)),a(t("input",{"onUpdate:modelValue":e[11]||(e[11]=n=>o.prompt_node=n),class:"form-input",placeholder:"自动识别,如 30:19"},null,512),[[p,o.prompt_node]])]),t("div",Me,[e[44]||(e[44]=t("label",null,"种子节点 ID(可选)",-1)),a(t("input",{"onUpdate:modelValue":e[12]||(e[12]=n=>o.seed_node=n),class:"form-input",placeholder:"自动识别,如 30:3"},null,512),[[p,o.seed_node]])])]),t("div",Oe,[t("div",Ne,[e[45]||(e[45]=t("label",null,"img2img 重绘强度",-1)),a(t("input",{"onUpdate:modelValue":e[13]||(e[13]=n=>o.img2img_denoise=n),type:"number",min:"0.01",max:"1",step:"0.01",class:"form-input"},null,512),[[p,o.img2img_denoise,void 0,{number:!0}]]),e[46]||(e[46]=t("p",{class:"field-hint"},"默认 0.45;越低越保留原图,越高变化越明显。",-1))]),t("div",Fe,[e[47]||(e[47]=t("label",null,"inpaint 重绘强度",-1)),a(t("input",{"onUpdate:modelValue":e[14]||(e[14]=n=>o.inpaint_denoise=n),type:"number",min:"0.01",max:"1",step:"0.01",class:"form-input"},null,512),[[p,o.inpaint_denoise,void 0,{number:!0}]]),e[48]||(e[48]=t("p",{class:"field-hint"},"默认 0.72;仅作用于白色遮罩区域。",-1))])]),e[49]||(e[49]=t("p",{class:"field-hint"},[m(" 必须使用 "),t("code",null,"Save (API Format)"),m(" 导出的 JSON(节点含 class_type)。 UI Format(含 nodes/links)导入后会秒结束且不出图。 ZImageTurbo 默认提示词节点 "),t("code",null,"30:19"),m(",采样种子 "),t("code",null,"30:3"),m("。 ")],-1))],64)):r("",!0),t("div",De,[e[50]||(e[50]=t("label",null,"API Base URL",-1)),a(t("input",{"onUpdate:modelValue":e[15]||(e[15]=n=>o.api_base_url=n),class:"form-input",placeholder:X.value},null,8,qe),[[p,o.api_base_url]])]),o.provider!=="comfy"?(i(),s("div",Je,[e[53]||(e[53]=t("label",null,"API Key",-1)),f.value&&w.value?(i(),s("p",Te,[e[51]||(e[51]=m(" 已保存 Key:",-1)),t("code",null,u($.value),1),e[52]||(e[52]=m("(输入新值可覆盖,留空则不修改) ",-1))])):f.value&&!w.value?(i(),s("p",Be," 当前未配置 Key,请填写 ")):r("",!0),a(t("input",{"onUpdate:modelValue":e[16]||(e[16]=n=>o.api_key=n),type:"password",class:"form-input",placeholder:f.value?"留空则使用已保存的 Key":o.provider==="dify"?"Dify 应用“访问 API”页面获取的密钥":"可选,部分本地模型可不填"},null,8,Ke),[[p,o.api_key]])])):(i(),s("div",Xe,[e[54]||(e[54]=t("label",null,"API Key(可选)",-1)),a(t("input",{"onUpdate:modelValue":e[17]||(e[17]=n=>o.api_key=n),type:"password",class:"form-input",placeholder:f.value?"留空则使用已保存的 Key":"本地 ComfyUI 一般无需填写"},null,8,Ee),[[p,o.api_key]])])),o.provider==="openai"?(i(),s("div",We,[e[55]||(e[55]=t("label",null,"Max Tokens",-1)),a(t("input",{"onUpdate:modelValue":e[18]||(e[18]=n=>o.max_tokens=n),type:"number",class:"form-input"},null,512),[[p,o.max_tokens,void 0,{number:!0}]])])):r("",!0),o.provider==="openai"?(i(),s("div",ze,[e[56]||(e[56]=t("label",null,"Temperature",-1)),a(t("input",{"onUpdate:modelValue":e[19]||(e[19]=n=>o.temperature=n),type:"number",step:"0.1",class:"form-input"},null,512),[[p,o.temperature,void 0,{number:!0}]])])):r("",!0),t("div",Le,[t("label",null,[a(t("input",{type:"checkbox","onUpdate:modelValue":e[20]||(e[20]=n=>o.is_default=n)},null,512),[[I,o.is_default]]),e[57]||(e[57]=m(" 设为默认模型",-1))])]),t("div",Re,[t("label",null,[a(t("input",{type:"checkbox","onUpdate:modelValue":e[21]||(e[21]=n=>o.enabled=n)},null,512),[[I,o.enabled]]),e[58]||(e[58]=m(" 启用",-1))])]),o.provider!=="comfy"?(i(),s("div",je,[t("label",null,[a(t("input",{type:"checkbox","onUpdate:modelValue":e[22]||(e[22]=n=>o.support_context=n)},null,512),[[I,o.support_context]]),e[59]||(e[59]=m(" 支持上下文(多轮对话)",-1))]),o.provider==="dify"?(i(),s("p",Ge,"关闭后每次提问都会让 Dify 开启一个新会话,不延续之前的上下文")):(i(),s("p",Ze,"关闭后每次提问只发送当前这一条消息,不携带历史聊天记录"))])):r("",!0),o.provider!=="comfy"?(i(),s("div",He,[t("label",null,[a(t("input",{type:"checkbox","onUpdate:modelValue":e[23]||(e[23]=n=>o.support_image=n)},null,512),[[I,o.support_image]]),e[60]||(e[60]=m(" 支持图片/多模态输入",-1))]),e[61]||(e[61]=t("p",{class:"field-hint"},'关闭后用户仍可上传图片给自己看,但不会把图片发给该模型识别(避免"not a multimodal model"报错),关闭后聊天界面也会自动隐藏图片上传按钮',-1))])):r("",!0),o.provider==="openai"?(i(),s(V,{key:9},[t("div",Ye,[e[62]||(e[62]=t("label",null,"Frequency Penalty(频率惩罚)",-1)),a(t("input",{"onUpdate:modelValue":e[24]||(e[24]=n=>o.frequency_penalty=n),type:"number",step:"0.1",min:"0",max:"2",class:"form-input"},null,512),[[p,o.frequency_penalty,void 0,{number:!0}]]),e[63]||(e[63]=t("p",{class:"field-hint"},"部分自部署/OCR 类模型容易陷入重复输出循环(同一句话刷屏),调高此值(如 1.0~1.5)可以有效抑制,默认 0 表示不干预",-1))]),t("div",Qe,[e[64]||(e[64]=t("label",null,"Presence Penalty(存在惩罚)",-1)),a(t("input",{"onUpdate:modelValue":e[25]||(e[25]=n=>o.presence_penalty=n),type:"number",step:"0.1",min:"0",max:"2",class:"form-input"},null,512),[[p,o.presence_penalty,void 0,{number:!0}]]),e[65]||(e[65]=t("p",{class:"field-hint"},"抑制模型反复围绕同一话题/短语,与频率惩罚搭配使用效果更好,默认 0 表示不干预",-1))])],64)):r("",!0),d.value?(i(),s("div",{key:10,class:C(["test-result",d.value.ok?"success":"error"])},[t("strong",null,u(d.value.ok?"✓ 测试成功":"✗ 测试失败"),1),d.value.ok?(i(),s("p",et,[m(" 延迟 "+u(d.value.latency_ms)+"ms ",1),d.value.tokens?(i(),s("span",tt," · Token "+u(d.value.tokens),1)):r("",!0)])):r("",!0),d.value.reply?(i(),s("p",ot,"模型回复:"+u(d.value.reply),1)):r("",!0),d.value.ok?r("",!0):(i(),s("p",lt,u(d.value.message),1))],2)):r("",!0)]),t("div",nt,[t("button",{class:"btn btn-ghost",onClick:e[26]||(e[26]=n=>v.value=!1)},"取消"),x(c).hasButton("btn:model:test")?(i(),s("button",{key:0,class:"btn btn-ghost",onClick:ee,disabled:U.value},u(U.value?"测试中...":"测试连接"),9,st)):r("",!0),t("button",{class:"btn btn-primary",onClick:Y},"保存")])])])):r("",!0)]))}},ut=oe(rt,[["__scopeId","data-v-16cf4364"]]);export{ut as default};
|