Files
chat/backend/public/admin/assets/ModelsView-BBsHmI-q.js
T
2026-07-22 10:18:59 +08:00

8 lines
22 KiB
JavaScript
Raw 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{_ as oe,u as le,g as ne,h as k,c as s,a as t,i as x,d as r,F as V,j as J,w as se,t as u,b as a,v as p,k as T,s as m,x as I,n as C,r as y,m as ie,l as B,o as i}from"./index-z4tF8s-R.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"},ge={class:"form-group"},ke={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"},he={class:"form-group"},Ae={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]}`,A=P.find(g=>g.startsWith(_+" "));if(A)return A}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 h(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&&h(l.prompt)?l.prompt:l!=null&&l.workflow&&h(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(!h(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 A=String(n.result||"");let g=JSON.parse(A);if(g=q(g),D(g)){alert("这是 UI Format 工作流,不能用于后端生图。请在 ComfyUI 开启开发者模式后使用 Save (API Format) 重新导出。");return}if(!h(g)){alert("无法识别为 API Format 工作流");return}o.workflow_json=JSON.stringify(g,null,2)}catch{alert("无法解析该 JSON 文件")}},n.readAsText(e)}ne(N);async function N(){const l=await k.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 k.put(`/admin/models/${f.value}`,e)):await k.post("/admin/models",e),v.value=!1,await N()}async function Q(l){confirm("确定删除此模型?")&&(await k.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 k.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 k.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",ge,[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",ke," 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",he,[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",Ae,[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};