PageSourceSearch

https://treerouter.ai/static/js/async/4895.d035136ba9.js

js treerouter.ai collected 2026-10-05 13:09:12 UTC 10,808 bytes, 1 lines download raw bytes

1"use strict";(self.rspackChunkreact_template=self.rspackChunkreact_template||[]).push([[4895],{41714(e,t,a){a.r(t);var l=a(5423),r=a(55456),s=a(74848),d=a(96540),n=a(90909),i=a(84747),o=a(82761);let{Title:c}=n.o5,_=e=>e&&e>0?new Date(1e3*e).toLocaleString():"-",u={"model_redirect_guard_setting.enabled":!1,"model_redirect_guard_setting.webhook_url":"","model_redirect_guard_setting.webhook_secret":"","model_redirect_guard_setting.mode":"block","model_redirect_guard_setting.allowed_aliases":"","model_redirect_guard_setting.report_interval_hours":6,"model_redirect_guard_setting.events_retention_days":30,"model_redirect_guard_setting.active_probe_enabled":!1,"model_redirect_guard_setting.auto_disable_enabled":!1,"model_redirect_guard_setting.auto_disable_threshold":10,"model_redirect_guard_setting.auto_disable_window_minutes":60};t.default=()=>{let{t:e}=(0,o.Bd)(),[t,a]=(0,d.useState)(!1),[g,h]=(0,d.useState)(u),m=(0,d.useRef)(),[x,p]=(0,d.useState)(u),[b,f]=(0,d.useState)(null),[j,v]=(0,d.useState)(!1),[y,k]=(0,d.useState)([]),[w,S]=(0,d.useState)(0),[C,I]=(0,d.useState)(!1),[V,T]=(0,d.useState)(1),[z,M]=(0,d.useState)(20),[L,B]=(0,d.useState)(""),[N,Q]=(0,d.useState)(""),[P,R]=(0,d.useState)("0"),$=(0,d.useCallback)(async()=>{a(!0);try{let e=await i.nC.get("/api/option/");if(!e.data.success)return void(0,i.Qg)(e.data.message);let t=(0,l._)({},u);for(let a of e.data.data){if(!(a.key in u))continue;let e=u[a.key];"boolean"==typeof e?t[a.key]=!0===a.value||"true"===a.value:"number"==typeof e?t[a.key]=Number(a.value)||e:t[a.key]=a.value}h(t),p(structuredClone(t)),m.current&&m.current.setValues(t)}catch(e){(0,i.Qg)(e.message)}finally{a(!1)}},[]),A=(0,d.useCallback)(async()=>{try{let e=await i.nC.get("/api/model-redirect-guard/status");e.data.success&&f(e.data.data)}catch(e){}},[]),W=(0,d.useCallback)(async()=>{I(!0);try{let e=new URLSearchParams({page:String(V),page_size:String(z),blocked:P});L&&e.set("channel_id",L),N&&e.set("expected_model",N);let t=await i.nC.get("/api/model-redirect-guard/events?".concat(e.toString()));t.data.success&&(k(t.data.data.items||[]),S(t.data.data.total||0))}catch(e){}finally{I(!1)}},[V,z,L,N,P]);async function Z(){v(!0);try{let t=await i.nC.post("/api/model-redirect-guard/test-webhook");t.data.success?(0,i.Te)(t.data.message||e("测试 webhook 已发送")):(0,i.Qg)(t.data.message||e("测试 webhook 失败"))}catch(e){(0,i.Qg)(String(e))}finally{v(!1)}}(0,d.useEffect)(()=>{$(),A()},[$,A]),(0,d.useEffect)(()=>{W()},[W]);let H=[{title:e("时间"),dataIndex:"created_at",width:170,render:e=>_(e)},{title:e("期望模型"),dataIndex:"expected_model",width:200},{title:e("实际模型"),dataIndex:"actual_model",width:200},{title:e("渠道"),dataIndex:"channel_name",render:(e,t)=>"".concat(e," (#").concat(t.channel_id,")")},{title:e("用户"),dataIndex:"username",render:(e,t)=>"".concat(e," (#").concat(t.user_id,")")},{title:e("流式"),dataIndex:"is_stream",width:70,render:t=>t?e("是"):e("否")},{title:e("结果"),dataIndex:"blocked",width:100,render:t=>t?(0,s.jsx)(n.vw,{color:"red",children:e("已阻断")}):(0,s.jsx)(n.vw,{color:"yellow",children:e("仅告警")})}];return(0,s.jsxs)("div",{style:{padding:16},children:[(0,s.jsx)(c,{heading:3,style:{marginBottom:12},children:e("模型重定向监测")}),(0,s.jsx)(n.lZ,{type:"info",description:e("检测上游渠道是否静默把高价模型换成低价模型(如 claude-opus → claude-sonnet)。仅能识别上游响应里诚实写了实际模型名的场景。"),style:{marginBottom:12},closeIcon:null}),(0,s.jsx)(n.Zp,{style:{marginBottom:12},children:(0,s.jsx)(n.tK,{spinning:t,children:(0,s.jsxs)(n.lV,{values:g,getFormApi:e=>m.current=e,style:{marginBottom:0},children:[(0,s.jsxs)(n.lV.Section,{text:e("基础配置"),children:[(0,s.jsxs)(n.fI,{gutter:16,children:[(0,s.jsx)(n.fv,{xs:24,sm:12,md:8,children:(0,s.jsx)(n.lV.Switch,{field:"model_redirect_guard_setting.enabled",label:e("启用监测"),checkedText:"|",uncheckedText:"〇",onChange:e=>h((0,r._)((0,l._)({},g),{"model_redirect_guard_setting.enabled":e}))})}),(0,s.jsx)(n.fv,{xs:24,sm:12,md:8,children:(0,s.jsx)(n.lV.Switch,{field:"model_redirect_guard_setting.active_probe_enabled",label:e("主动探测(含渠道测试)"),checkedText:"|",uncheckedText:"〇",onChange:e=>h((0,r._)((0,l._)({},g),{"model_redirect_guard_setting.active_probe_enabled":e}))})})]}),(0,s.jsxs)(n.fI,{gutter:16,children:[(0,s.jsx)(n.fv,{xs:24,sm:12,children:(0,s.jsx)(n.lV.Input,{field:"model_redirect_guard_setting.webhook_url",label:e("Webhook URL"),placeholder:"https://...",onChange:e=>h((0,r._)((0,l._)({},g),{"model_redirect_guard_setting.webhook_url":e}))})}),(0,s.jsx)(n.fv,{xs:24,sm:12,children:(0,s.jsx)(n.lV.Input,{field:"model_redirect_guard_setting.webhook_secret",label:e("Webhook Secret(可选)"),mode:"password",extraText:e("设置
1后请求头会带 X-Webhook-Signature HMAC-SHA256"),onChange:e=>h((0,r._)((0,l._)({},g),{"model_redirect_guard_setting.webhook_secret":e}))})})]}),(0,s.jsxs)(n.fI,{gutter:16,children:[(0,s.jsx)(n.fv,{xs:24,sm:12,md:8,children:(0,s.jsx)(n.lV.Select,{field:"model_redirect_guard_setting.mode",label:e("处理模式"),style:{width:"100%"},onChange:e=>h((0,r._)((0,l._)({},g),{"model_redirect_guard_setting.mode":e})),optionList:[{value:"block",label:e("告警并阻断(仅非流式)")},{value:"alert_only",label:e("仅告警")}]})}),(0,s.jsx)(n.fv,{xs:24,sm:12,md:8,children:(0,s.jsx)(n.lV.InputNumber,{field:"model_redirect_guard_setting.report_interval_hours",label:e("汇总报告间隔(小时)"),min:1,max:24,step:1,onChange:e=>h((0,r._)((0,l._)({},g),{"model_redirect_guard_setting.report_interval_hours":parseInt(e)||6}))})}),(0,s.jsx)(n.fv,{xs:24,sm:12,md:8,children:(0,s.jsx)(n.lV.InputNumber,{field:"model_redirect_guard_setting.events_retention_days",label:e("事件保留天数"),min:1,max:365,step:1,onChange:e=>h((0,r._)((0,l._)({},g),{"model_redirect_guard_setting.events_retention_days":parseInt(e)||30}))})})]})]}),(0,s.jsx)(n.lV.Section,{text:e("自动关停"),children:(0,s.jsxs)(n.fI,{gutter:16,children:[(0,s.jsx)(n.fv,{xs:24,sm:12,md:8,children:(0,s.jsx)(n.lV.Switch,{field:"model_redirect_guard_setting.auto_disable_enabled",label:e("自动关停问题渠道"),checkedText:"|",uncheckedText:"〇",onChange:e=>h((0,r._)((0,l._)({},g),{"model_redirect_guard_setting.auto_disable_enabled":e}))})}),(0,s.jsx)(n.fv,{xs:24,sm:12,md:8,children:(0,s.jsx)(n.lV.InputNumber,{field:"model_redirect_guard_setting.auto_disable_threshold",label:e("关停阈值(次数)"),min:1,step:1,onChange:e=>h((0,r._)((0,l._)({},g),{"model_redirect_guard_setting.auto_disable_threshold":parseInt(e)||10}))})}),(0,s.jsx)(n.fv,{xs:24,sm:12,md:8,children:(0,s.jsx)(n.lV.InputNumber,{field:"model_redirect_guard_setting.auto_disable_window_minutes",label:e("关停窗口(分钟)"),min:1,max:1440,step:1,onChange:e=>h((0,r._)((0,l._)({},g),{"model_redirect_guard_setting.auto_disable_window_minutes":parseInt(e)||60}))})})]})}),(0,s.jsx)(n.lV.Section,{text:e("白名单 alias"),children:(0,s.jsx)(n.fI,{children:(0,s.jsx)(n.fv,{xs:24,md:20,children:(0,s.jsx)(n.lV.TextArea,{field:"model_redirect_guard_setting.allowed_aliases",placeholder:'{\n  "grok-4": ["grok-4.3"],\n  "claude-sonnet-4-5": ["claude-sonnet-4-5-20250929"]\n}',autosize:{minRows:6,maxRows:14},extraText:e('格式:{"请求模型": ["允许的响应模型1", "允许的响应模型2"]}'),onChange:e=>h((0,r._)((0,l._)({},g),{"model_redirect_guard_setting.allowed_aliases":e}))})})})}),(0,s.jsxs)(n.fI,{style:{marginTop:8},children:[(0,s.jsx)(n.$n,{onClick:function(){let t=(0,i.Gq)(g,x);if(!t.length)return(0,i.pM)(e("你似乎并没有修改什么"));let l=String(g["model_redirect_guard_setting.allowed_aliases"]||"").trim();if(l)try{JSON.parse(l)}catch(t){return(0,i.Qg)(e("白名单 alias JSON 格式不正确"))}a(!0),Promise.all(t.map(e=>{let t,a=g[e.key];return t="boolean"==typeof a?String(a):a,i.nC.put("/api/option/",{key:e.key,value:t})})).then(t=>{if(t.some(e=>{var t;return!e||!(null==(t=e.data)?void 0:t.success)}))return(0,i.Qg)(e("部分保存失败,请重试"));(0,i.Te)(e("保存成功")),p(structuredClone(g)),A()}).catch(()=>{(0,i.Qg)(e("保存失败,请重试"))}).finally(()=>{a(!1)})},type:"primary",children:e("保存")}),(0,s.jsx)(n.$n,{style:{marginLeft:8},loading:j,onClick:Z,children:e("发送测试 webhook")})]})]})})}),b&&(0,s.jsx)(n.Zp,{title:e("运行状态"),style:{marginBottom:12},children:(0,s.jsxs)("div",{style:{fontSize:13,lineHeight:"24px"},children:[(0,s.jsxs)("div",{children:[e("启用"),": ",b.enabled?e("是"):e("否")," ·"," ",e("Webhook"),":"," ",b.webhook_configured?e("已配置"):e("未配置")," ·"," ",e("模式"),": ",b.mode]}),(0,s.jsxs)("div",{children:[e("待汇总事件 / 组合"),": ",b.pending_report_events," /"," ",b.pending_report_groups]}),(0,s.jsxs)("div",{children:[e("上次触发"),": ",_(b.last_trigger_at)," ·"," ",e("上次汇总"),": ",_(b.last_report_at)]}),b.last_error_msg&&(0,s.jsxs)("div",{style:{color:"#e53935"},children:[e("上次错误"),": ",b.last_error_msg]})]})}
1),(0,s.jsxs)(n.Zp,{title:e("检测事件"),children:[(0,s.jsxs)(n.fI,{gutter:8,style:{marginBottom:12},children:[(0,s.jsx)(n.fv,{xs:24,sm:5,children:(0,s.jsx)(n.lV.Input,{noLabel:!0,placeholder:e("渠道 ID"),value:L,onChange:e=>{B(e),T(1)}})}),(0,s.jsx)(n.fv,{xs:24,sm:6,children:(0,s.jsx)(n.lV.Input,{noLabel:!0,placeholder:e("期望模型名(精确匹配)"),value:N,onChange:e=>{Q(e),T(1)}})}),(0,s.jsx)(n.fv,{xs:24,sm:5,children:(0,s.jsx)(n.l6,{style:{width:"100%"},value:P,onChange:e=>{R(e),T(1)},optionList:[{value:"0",label:e("全部结果")},{value:"1",label:e("仅看阻断")},{value:"-1",label:e("仅看告警")}]})}),(0,s.jsx)(n.fv,{xs:24,sm:4,children:(0,s.jsx)(n.l6,{style:{width:"100%"},value:z,onChange:e=>{M(e),T(1)},optionList:[10,20,50,100].map(t=>({value:t,label:"".concat(t," ").concat(e("条/页"))}))})}),(0,s.jsx)(n.fv,{xs:24,sm:4,children:(0,s.jsx)(n.$n,{onClick:W,loading:C,block:!0,children:e("刷新")})})]}),(0,s.jsxs)("div",{style:{marginBottom:8,fontSize:12,color:"var(--semi-color-text-2)"},children:[e("共")," ",w," ",e("条")," · ",e("第")," ",V," /"," ",Math.max(1,Math.ceil(w/z))," ",e("页")]}),(0,s.jsx)(n.XI,{columns:H,dataSource:y,rowKey:"id",loading:C,pagination:{currentPage:V,pageSize:z,total:w,pageSizeOpts:[10,20,50,100],showSizeChanger:!0,onPageChange:T,onPageSizeChange:e=>{M(e),T(1)}},empty:e("暂无事件"),size:"small"}),0===w&&(0,s.jsxs)("div",{style:{marginTop:8,display:"flex",justifyContent:"center",gap:8},children:[(0,s.jsx)(n.$n,{size:"small",disabled:V<=1,onClick:()=>T(e=>Math.max(1,e-1)),children:e("上一页")}),(0,s.jsx)(n.$n,{size:"small",disabled:V>=Math.max(1,Math.ceil(w/z)),onClick:()=>T(e=>Math.min(Math.max(1,Math.ceil(w/z)),e+1)),children:e("下一页")})]})]})]})}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.