llm-simple-router 0.11.30 → 0.12.0-dev.7cf31a2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/config/recommended-providers.json +24 -12
  2. package/config/recommended-retry-rules.json +128 -11
  3. package/dist/admin/providers.js +1 -1
  4. package/dist/admin/quick-setup.js +61 -6
  5. package/dist/admin/usage.js +19 -12
  6. package/dist/config/recommended-providers.json +24 -12
  7. package/dist/config/recommended-retry-rules.json +128 -11
  8. package/dist/config/recommended.d.ts +1 -0
  9. package/dist/core/concurrency/adaptive-controller.d.ts +2 -0
  10. package/dist/core/concurrency/adaptive-controller.js +32 -27
  11. package/dist/core/concurrency/types.d.ts +0 -1
  12. package/dist/core/monitor/types.d.ts +2 -0
  13. package/dist/db/index.js +42 -0
  14. package/dist/proxy/orchestration/orchestrator.js +2 -0
  15. package/frontend-dist/assets/AuthLayout-AvTL8TD9.js +1 -0
  16. package/frontend-dist/assets/Card-_-Rsez1Z.js +1 -0
  17. package/frontend-dist/assets/CardContent-CXB0aTQX.js +1 -0
  18. package/frontend-dist/assets/{CardTitle-Cs6WQYrl.js → CardTitle-DEgSNH9O.js} +1 -1
  19. package/frontend-dist/assets/CascadingModelSelect-vGUnj1X-.js +1 -0
  20. package/frontend-dist/assets/{Checkbox-ljNZhtRQ.js → Checkbox-Bwhfqxux.js} +1 -1
  21. package/frontend-dist/assets/{CollapsibleContent-Yk-lxVPc.js → CollapsibleContent-DDzm_Bxn.js} +1 -1
  22. package/frontend-dist/assets/CollapsibleTrigger-CWUxEdhm.js +1 -0
  23. package/frontend-dist/assets/ConcurrencyControl-DXIrmfyy.js +1 -0
  24. package/frontend-dist/assets/Dashboard-Gzd7h17f.js +3 -0
  25. package/frontend-dist/assets/{Input-BGoap26P.js → Input-Qz28j7do.js} +1 -1
  26. package/frontend-dist/assets/{Label-CR9CcQmY.js → Label-CgLYbqNp.js} +1 -1
  27. package/frontend-dist/assets/Login-Dds3B1xs.js +1 -0
  28. package/frontend-dist/assets/Logs-OknLq4IX.js +1 -0
  29. package/frontend-dist/assets/ModelMappings-BBOSIVlU.js +1 -0
  30. package/frontend-dist/assets/Monitor-BN6VeuSD.js +1 -0
  31. package/frontend-dist/assets/Providers-C6v2RKW1.js +1 -0
  32. package/frontend-dist/assets/ProxyEnhancement-Bs_ocCbv.js +1 -0
  33. package/frontend-dist/assets/QuickSetup-CG1X-HWo.js +1 -0
  34. package/frontend-dist/assets/RetryRules-DCXYuPl-.js +1 -0
  35. package/frontend-dist/assets/RouterKeys-4hYMVOwN.js +1 -0
  36. package/frontend-dist/assets/RouterKeys-DEMKBc7g.css +1 -0
  37. package/frontend-dist/assets/{RovingFocusItem-C31XRuKO.js → RovingFocusItem-CCbZ7_un.js} +1 -1
  38. package/frontend-dist/assets/Schedules-C0Kf-gvS.js +1 -0
  39. package/frontend-dist/assets/Settings-u7_Vhsqi.js +6 -0
  40. package/frontend-dist/assets/Setup-BXxAhB7r.js +1 -0
  41. package/frontend-dist/assets/Skeleton-QesVeTCW.js +1 -0
  42. package/frontend-dist/assets/{Switch-Dxml8U-u.js → Switch-D2xEGYqH.js} +1 -1
  43. package/frontend-dist/assets/TableHeader-CHaThXAU.js +1 -0
  44. package/frontend-dist/assets/TabsTrigger-Cl1kx8BK.js +1 -0
  45. package/frontend-dist/assets/TooltipTrigger-8hiSB2Rk.js +1 -0
  46. package/frontend-dist/assets/UnifiedRequestDialog-Cm6Ao45M.js +3 -0
  47. package/frontend-dist/assets/UnifiedRequestDialog-DaZodSzm.css +1 -0
  48. package/frontend-dist/assets/{VisuallyHiddenInput-D7dv0owV.js → VisuallyHiddenInput-Lv6BsAIS.js} +1 -1
  49. package/frontend-dist/assets/_plugin-vue_export-helper-BH2M0_bF.js +1 -0
  50. package/frontend-dist/assets/arrow-down-C7Be80wb.js +1 -0
  51. package/frontend-dist/assets/badge-C82CIl1p.js +1 -0
  52. package/frontend-dist/assets/{button-CiJBAzrS.js → button-DXlWUlLe.js} +2 -2
  53. package/frontend-dist/assets/chevron-right-DJE8HF-i.js +1 -0
  54. package/frontend-dist/assets/common-ZLJwmI0c.js +1 -0
  55. package/frontend-dist/assets/common-qa3O5YJX.js +1 -0
  56. package/frontend-dist/assets/dashboard-BlCt9ud6.js +1 -0
  57. package/frontend-dist/assets/dashboard-CqwGLWoK.js +1 -0
  58. package/frontend-dist/assets/dialog-DN2mvc9h.js +1 -0
  59. package/frontend-dist/assets/image-8GxBtf66.js +1 -0
  60. package/frontend-dist/assets/index-BcYqgllr.css +1 -0
  61. package/frontend-dist/assets/index-FYAc4GSw.js +3 -0
  62. package/frontend-dist/assets/logs-BI_TLeBe.js +1 -0
  63. package/frontend-dist/assets/logs-DZyb4-Ew.js +1 -0
  64. package/frontend-dist/assets/mappings-Bw39-I5f.js +1 -0
  65. package/frontend-dist/assets/mappings-DBDiQL8p.js +1 -0
  66. package/frontend-dist/assets/model-patches-Dr6eEIuK.js +1 -0
  67. package/frontend-dist/assets/monitor-Crmj9XSn.js +1 -0
  68. package/frontend-dist/assets/monitor-D5lXaCoi.js +1 -0
  69. package/frontend-dist/assets/pencil-BzLz9HuE.js +1 -0
  70. package/frontend-dist/assets/plus-DghQKiGV.js +1 -0
  71. package/frontend-dist/assets/providers-Cy6EVDp5.js +1 -0
  72. package/frontend-dist/assets/providers-DTIaw_44.js +1 -0
  73. package/frontend-dist/assets/proxyEnhancement-BEbUoM8Y.js +3 -0
  74. package/frontend-dist/assets/proxyEnhancement-rdWlqMlw.js +3 -0
  75. package/frontend-dist/assets/quickSetup-CjxI1qgV.js +1 -0
  76. package/frontend-dist/assets/quickSetup-zSIVom2e.js +1 -0
  77. package/frontend-dist/assets/requestDetail-BgwV24CW.js +1 -0
  78. package/frontend-dist/assets/requestDetail-zegFIYZs.js +1 -0
  79. package/frontend-dist/assets/routerKeys-B2_9kz1O.js +1 -0
  80. package/frontend-dist/assets/routerKeys-C579ZS8v.js +1 -0
  81. package/frontend-dist/assets/{schedules-ByzpVhl2.js → schedules-DeR-EOsE.js} +1 -1
  82. package/frontend-dist/assets/schedules-u1et4hyF.js +1 -0
  83. package/frontend-dist/assets/search-BvelBk-g.js +1 -0
  84. package/frontend-dist/assets/{sparkles-DcNGAfEa.js → sparkles-B2aVxqID.js} +1 -1
  85. package/frontend-dist/assets/transform-domain-BGh_oMvU.js +1 -0
  86. package/frontend-dist/assets/{trash-2-C_XOOsld.js → trash-2-BFS2nrZH.js} +1 -1
  87. package/frontend-dist/assets/useClipboard-D_fR9Erj.js +1 -0
  88. package/frontend-dist/assets/useLogRetention-CLvwmbya.js +1 -0
  89. package/frontend-dist/assets/useProviderGroups-DYlN-TXY.js +1 -0
  90. package/frontend-dist/index.html +4 -4
  91. package/package.json +1 -1
  92. package/frontend-dist/assets/CardContent-BU3fjxiM.js +0 -1
  93. package/frontend-dist/assets/CascadingModelSelect-B_n7DYfi.js +0 -1
  94. package/frontend-dist/assets/CollapsibleTrigger-8_A4LNtD.js +0 -1
  95. package/frontend-dist/assets/Dashboard-C5oqC_3e.js +0 -3
  96. package/frontend-dist/assets/Login-CM-J-SVi.js +0 -1
  97. package/frontend-dist/assets/Logs-CSZi8Fkp.js +0 -1
  98. package/frontend-dist/assets/MappingEntryEditor-Dng2wCdx.js +0 -1
  99. package/frontend-dist/assets/ModelMappings-_ONUTtBQ.js +0 -1
  100. package/frontend-dist/assets/Monitor-o28u2RV9.js +0 -1
  101. package/frontend-dist/assets/Providers-awOg4hbb.js +0 -1
  102. package/frontend-dist/assets/ProxyEnhancement-DV-dfZLk.js +0 -1
  103. package/frontend-dist/assets/QuickSetup-XvyghGod.js +0 -1
  104. package/frontend-dist/assets/RetryRules-EnfS-FTJ.js +0 -1
  105. package/frontend-dist/assets/RouterKeys-BzcUK5x_.js +0 -1
  106. package/frontend-dist/assets/Schedules-BuP-3qX8.js +0 -1
  107. package/frontend-dist/assets/Settings-hBsvQQWG.js +0 -6
  108. package/frontend-dist/assets/Setup-CukhOjX3.js +0 -1
  109. package/frontend-dist/assets/TooltipTrigger-BITX1gT4.js +0 -1
  110. package/frontend-dist/assets/TransformRulesForm-DFW-oDll.js +0 -1
  111. package/frontend-dist/assets/UnifiedRequestDialog-C3sWdkTe.css +0 -1
  112. package/frontend-dist/assets/UnifiedRequestDialog-DChZe4do.js +0 -3
  113. package/frontend-dist/assets/common-BCe8fK5N.js +0 -1
  114. package/frontend-dist/assets/common-CdzdKRsV.js +0 -1
  115. package/frontend-dist/assets/copy-C035pTD9.js +0 -1
  116. package/frontend-dist/assets/dashboard-C0XEgNnb.js +0 -1
  117. package/frontend-dist/assets/dashboard-uBv6TkGn.js +0 -1
  118. package/frontend-dist/assets/dialog-QrJZom9g.js +0 -1
  119. package/frontend-dist/assets/index-B_tA9Si9.css +0 -1
  120. package/frontend-dist/assets/index-bv08h-oy.js +0 -3
  121. package/frontend-dist/assets/logs-C3X3MZjQ.js +0 -1
  122. package/frontend-dist/assets/logs-HY8sUOwb.js +0 -1
  123. package/frontend-dist/assets/mappings-B6NCfNio.js +0 -1
  124. package/frontend-dist/assets/mappings-yo-RxHK6.js +0 -1
  125. package/frontend-dist/assets/model-patches-1yALrtK3.js +0 -1
  126. package/frontend-dist/assets/monitor-CcfwHbJF.js +0 -1
  127. package/frontend-dist/assets/monitor-XNX6LZGC.js +0 -1
  128. package/frontend-dist/assets/plus-7SwZDVUb.js +0 -1
  129. package/frontend-dist/assets/providers-BaiCysMg.js +0 -1
  130. package/frontend-dist/assets/providers-DsC5Qd6m.js +0 -1
  131. package/frontend-dist/assets/proxyEnhancement-BC3eVKDp.js +0 -3
  132. package/frontend-dist/assets/proxyEnhancement-Dq47MAAI.js +0 -3
  133. package/frontend-dist/assets/quickSetup-C8jt6VzA.js +0 -1
  134. package/frontend-dist/assets/quickSetup-tMWsXvo3.js +0 -1
  135. package/frontend-dist/assets/requestDetail-C5px2Mru.js +0 -1
  136. package/frontend-dist/assets/requestDetail-Tozq3jwE.js +0 -1
  137. package/frontend-dist/assets/routerKeys-C4oCPJrT.js +0 -1
  138. package/frontend-dist/assets/routerKeys-CyZ4L-1h.js +0 -1
  139. package/frontend-dist/assets/schedules-tSjne6S-.js +0 -1
  140. package/frontend-dist/assets/useClipboard-DaHSM2Ce.js +0 -1
  141. package/frontend-dist/assets/useLogRetention-D7MYPV9z.js +0 -1
  142. /package/frontend-dist/assets/{login-DXMVxesL.js → login-BjRWJuuH.js} +0 -0
  143. /package/frontend-dist/assets/{login-BozjQrft.js → login-Drdlb6If.js} +0 -0
  144. /package/frontend-dist/assets/{retryRules-DGg26acb.js → retryRules-KY-2u2K-.js} +0 -0
  145. /package/frontend-dist/assets/{retryRules-CR3EIOTr.js → retryRules-v9HTZUGQ.js} +0 -0
  146. /package/frontend-dist/assets/{settings-DQqli04G.js → settings-av7tA8wt.js} +0 -0
  147. /package/frontend-dist/assets/{settings-CveTb9z9.js → settings-dzu7sg6b.js} +0 -0
  148. /package/frontend-dist/assets/{setup-BKw9vkV3.js → setup-B0bSyAH4.js} +0 -0
  149. /package/frontend-dist/assets/{setup-D9yk-VSM.js → setup-Bw-U-YJa.js} +0 -0
  150. /package/frontend-dist/assets/{sidebar-T-fjy0Pb.js → sidebar-BxTRaJDZ.js} +0 -0
  151. /package/frontend-dist/assets/{sidebar-HuUg5Wsk.js → sidebar-Dl1-HY8Q.js} +0 -0
@@ -0,0 +1 @@
1
+ var e=`请求日志`,t=`清理日志`,n=`清除`,r=`全部供应商`,i=`全部模型`,a=`全部密钥`,o=`全部状态`,s=`非 200`,c={clientModel:`客户端模型`,allClientModels:`全部客户端模型`,backendModel:`目标模型`,allBackendModels:`全部目标模型`},l=`暂无日志`,u=`当前筛选条件下没有匹配的日志`,d=`清除所有筛选`,f=`共 {total} 条,第 {page} / {totalPages} 页`,p=`首页`,m=`上一页`,h=`下一页`,g=`末页`,_={title:`清理日志`,description:`删除指定天数之前的日志`,keepRecentDays:`保留最近天数`,autoCleanup:`自动清理:保留`,retentionDays:`保留天数`,noAutoCleanup:`0 = 不自动清理`,saveSettings:`保存设置`,confirmCleanup:`确认清理`,days:`天`},v={title:`清理完成`,description:`已删除 {count} 条日志。`,ok:`确定`},y={id:`ID`,time:`时间`,type:`类型`,model:`模型`,clientModel:`客户端模型`,targetModel:`目标模型`,actualForward:`实际转发`,tags:`标签`,statusCode:`状态码`,latency:`耗时`,streaming:`流式`,retry:`重试`,failover:`故障转移`,error:`错误`,actions:`操作`},b={copyFullId:`复制完整 ID`,replaced:`已替换`,proxyEnhancement:`代理增强:{label}`,unknown:`未知`,detail:`详情`},x={loadFailed:`加载日志失败`,cleanupFailed:`清理日志失败`,loadSubRequestsFailed:`加载子请求失败`,loadDetailFailed:`加载日志详情失败`,loadProvidersFailed:`加载供应商列表失败`,loadKeysFailed:`加载密钥列表失败`},S={endTimeAfterStart:`结束时间须晚于开始时间`},C={saved:`日志保留天数已更新`,updateFailed:`更新保留天数失败`,loadFailed:`加载保留天数失败,使用默认值`},w=`生成重试规则`,T=`分析中...`,E=`AI 分析失败`,D=`需要配置 AI 模型`,O=`使用 AI 生成重试规则前,需要先在代理增强设置中配置 AI 模型。`,k=`配置路径:代理增强 → AI 重试规则生成 → 选择 Provider / Model`,A=`前往配置`,j=`AI 生成的重试规则`,M=`AI 生成`,N=`匹配条件`,P=`重试参数`,F=`AI 分析完成`,I=`保存规则`,L={structured:`结构化`,rawData:`原始数据`,rawJson:`原始 JSON`,rawSse:`原始 SSE`,copied:`已复制`,copyJson:`复制 JSON`,copy:`复制`,parseError:`解析失败,请切换到原始 JSON 查看`,claudeCodeRequest:`Claude Code 请求`,headers:`Headers ({count} 个)`,key:`Key`,expand:`展开`,expandAll:`展开全部`,collapse:`收起`,moreTools:`+{count}`,otherFields:`其他字段`,deltaEvents:`{count} 个 delta 事件`,completeResponse:`完整响应`,rawEvents:`原始事件流`,streamEnd:`流结束`,content:`内容`,deltaGroupSummary:`{deltaType} · keep {kept} 个`,deltaFoldedInfo:` +{folded} 个已折叠 ({chars} 字符)`,collapsedEvents:`已折叠事件`,rawSseText:`原始 SSE 文本`,thinkingTokens:`思考 Token`,toolsCount:`工具 ({count})`,value:`值`},R={title:e,cleanupLogs:t,clear:n,allProviders:r,allModels:i,allKeys:a,allStatus:o,non200:s,filters:c,noLogs:l,noLogsFilterHint:u,clearAllFilters:d,pagination:f,firstPage:p,prevPage:m,nextPage:h,lastPage:g,cleanup:_,cleanupResult:v,table:y,row:b,messages:x,validation:S,retention:C,generateRetryRule:w,analyzing:T,generateFailed:E,needAiConfig:D,needAiConfigDesc:O,configPath:k,goToConfig:A,aiGeneratedRule:j,aiGenerated:M,matchConditions:N,retryParams:P,aiAnalysisComplete:F,saveRule:I,viewer:L};export{F as aiAnalysisComplete,M as aiGenerated,j as aiGeneratedRule,a as allKeys,i as allModels,r as allProviders,o as allStatus,T as analyzing,_ as cleanup,t as cleanupLogs,v as cleanupResult,n as clear,d as clearAllFilters,k as configPath,R as default,c as filters,p as firstPage,E as generateFailed,w as generateRetryRule,A as goToConfig,g as lastPage,N as matchConditions,x as messages,D as needAiConfig,O as needAiConfigDesc,h as nextPage,l as noLogs,u as noLogsFilterHint,s as non200,f as pagination,m as prevPage,C as retention,P as retryParams,b as row,I as saveRule,y as table,e as title,S as validation,L as viewer};
@@ -0,0 +1 @@
1
+ var e=`Request Logs`,t=`Cleanup Logs`,n=`Clear`,r=`All Providers`,i=`All Models`,a=`All Keys`,o=`All Status`,s=`Non-200`,c={clientModel:`Client Model`,allClientModels:`All Client Models`,backendModel:`Target Model`,allBackendModels:`All Target Models`},l=`No logs`,u=`No logs match the current filters`,d=`Clear all filters`,f=`Total {total}, Page {page} / {totalPages}`,p=`First`,m=`Previous`,h=`Next`,g=`Last`,_={title:`Cleanup Logs`,description:`Delete logs older than specified days`,keepRecentDays:`Keep recent days`,autoCleanup:`Auto cleanup: keep`,retentionDays:`Retention days`,noAutoCleanup:`0 = No auto cleanup`,saveSettings:`Save Settings`,confirmCleanup:`Confirm Cleanup`,days:`days`},v={title:`Cleanup Complete`,description:`Deleted {count} log entries.`,ok:`OK`},y={id:`ID`,time:`Time`,type:`Type`,model:`Model`,clientModel:`Client Model`,targetModel:`Target Model`,actualForward:`Actual Forward`,tags:`Tags`,statusCode:`Status Code`,latency:`Latency`,streaming:`Streaming`,retry:`Retry`,failover:`Failover`,error:`Error`,actions:`Actions`},b={copyFullId:`Copy full ID`,replaced:`Replaced`,proxyEnhancement:`Enhancement: {label}`,unknown:`Unknown`,detail:`Detail`},x={loadFailed:`Failed to load logs`,cleanupFailed:`Failed to cleanup logs`,loadSubRequestsFailed:`Failed to load sub-requests`,loadDetailFailed:`Failed to load log details`,loadProvidersFailed:`Failed to load providers`,loadKeysFailed:`Failed to load router keys`},S={endTimeAfterStart:`End time must be after start time`},C={saved:`Log retention days updated`,updateFailed:`Failed to update retention days`,loadFailed:`Failed to load retention days, using default`},w=`Generate Retry Rule`,T=`Analyzing...`,E=`AI analysis failed`,D=`AI Configuration Required`,O=`To use AI retry rule generation, configure an AI model in the Proxy Enhancement settings.`,k=`Proxy Enhancement → AI Retry Rule Generation → Select Provider / Model`,A=`Go to Settings`,j=`AI-Generated Retry Rule`,M=`AI`,N=`Match Conditions`,P=`Retry Parameters`,F=`AI analysis complete`,I=`Save Rule`,L={structured:`Structured`,rawData:`Raw Data`,rawJson:`Raw JSON`,rawSse:`Raw SSE`,copied:`Copied`,copyJson:`Copy JSON`,copy:`Copy`,parseError:`Parse failed, switch to Raw JSON to view`,claudeCodeRequest:`Claude Code Request`,headers:`Headers ({count})`,key:`Key`,expand:`Expand`,expandAll:`Expand All`,collapse:`Collapse`,moreTools:`+{count}`,otherFields:`Other Fields`,deltaEvents:`{count} delta events`,completeResponse:`Complete Response`,rawEvents:`Raw Events`,streamEnd:`Stream End`,content:`Content`,deltaGroupSummary:`{deltaType} · keep {kept}`,deltaFoldedInfo:` +{folded} collapsed ({chars} chars)`,collapsedEvents:`Collapsed Events`,rawSseText:`Raw SSE Text`,thinkingTokens:`Thinking Tokens`,toolsCount:`Tools ({count})`,value:`Value`},R={title:e,cleanupLogs:t,clear:n,allProviders:r,allModels:i,allKeys:a,allStatus:o,non200:s,filters:c,noLogs:l,noLogsFilterHint:u,clearAllFilters:d,pagination:f,firstPage:p,prevPage:m,nextPage:h,lastPage:g,cleanup:_,cleanupResult:v,table:y,row:b,messages:x,validation:S,retention:C,generateRetryRule:w,analyzing:T,generateFailed:E,needAiConfig:D,needAiConfigDesc:O,configPath:k,goToConfig:A,aiGeneratedRule:j,aiGenerated:`AI`,matchConditions:N,retryParams:P,aiAnalysisComplete:F,saveRule:I,viewer:L};export{F as aiAnalysisComplete,M as aiGenerated,j as aiGeneratedRule,a as allKeys,i as allModels,r as allProviders,o as allStatus,T as analyzing,_ as cleanup,t as cleanupLogs,v as cleanupResult,n as clear,d as clearAllFilters,k as configPath,R as default,c as filters,p as firstPage,E as generateFailed,w as generateRetryRule,A as goToConfig,g as lastPage,N as matchConditions,x as messages,D as needAiConfig,O as needAiConfigDesc,h as nextPage,l as noLogs,u as noLogsFilterHint,s as non200,f as pagination,m as prevPage,C as retention,P as retryParams,b as row,I as saveRule,y as table,e as title,S as validation,L as viewer};
@@ -0,0 +1 @@
1
+ var e=`模型映射`,t=`添加分组`,n=`编辑分组`,r=`故障转移`,i=`故障转移 · {count} 级`,a=`首选`,o=`备{n}`,s=`无目标`,c=`暂无映射分组`,l=`失败时切换`,u=`失败时自动切换`,d=`故障转移链`,f=`已启用`,p=`添加多个目标启用故障转移`,m=`添加备选`,h=`请求按顺序依次尝试,当前一个目标失败时自动切换到下一个`,g=`备选 {idx}`,_=`模型`,v=`溢出模型(可选)`,y=`上下文超过目标模型限制时自动切换到此模型`,b=`当前模型上下文 >= 1M,无需配置溢出模型`,x=`上下文超过 {model} 限制 ({context}) 时自动切换到 {overflowModel}`,S=`选择模型...`,C=`点击选择模型...`,w=`选择供应商 / 模型`,T=`配置客户端模型到后端供应商模型的映射规则`,E=`客户端模型`,D=`确认{action}`,O=`确定要{action}映射「{model}」吗?`,k=`禁用`,A=`启用`,j=`确认删除`,M=`确定要删除映射「{model}」吗?`,N=`请输入客户端模型名称`,P=`至少添加一个目标`,F=`请选择模型`,I=`加载供应商失败`,L=`保存分组失败`,R=`删除分组失败`,z=`切换状态失败`,B=`{count} 条映射`,V=`{count} 启用`,H=`有未保存的修改`,U={deleteFailed:`删除 {model} 失败`,createFailed:`创建 {model} 失败`,updateFailed:`更新 {model} 失败`,toggleFailed:`切换 {model} 状态失败`,partialFail:`{count} 个操作失败`,saveFailed:`保存失败`,parseRuleFailed:`路由规则格式异常,已使用默认配置`},W={clientLabel:`客户端`,edit:`编辑`,clientInputPlaceholder:`客户端模型名称`,clickToEdit:`点击编辑`,failoverChain:`故障转移链`,failoverOnError:`失败时切换`,contextOverflow:`上下文溢出`,contextOverflowHint:`上下文超限时切换`,multimodalFallback:`多模态回退`,new:`新增`},G=`选择供应商 / 模型`,K={title:`多模态 Fallback`,add:`添加多模态 Fallback`,configured:`已配置`,selectProvider:`选择供应商`,modelPlaceholder:`模型名称(如 gpt-4o)`,selectProviderModel:`选择供应商和模型`,sessionLockWarning:`注意:一旦请求中包含图片、音频或视频,整个会话将持续路由到 fallback 模型。`,sessionLockReason:`原因:客户端每轮发送完整对话历史,历史中的多媒体内容会持续触发重定向。客户端执行 compact 或开启新会话后自动恢复。`,costSuggestion:`建议:选择与原始模型价位相近的 fallback 模型,避免成本差异过大。`},q={title:e,addGroup:t,editGroup:n,failover:r,failoverLevel:i,primary:a,backup:o,noTarget:s,noGroups:c,switchOnFail:l,switchOnFailAuto:u,failoverChain:d,enabled:f,addMoreToEnableFailover:p,addBackup:m,failoverChainHint:h,backupLabel:g,model:_,overflowModel:v,overflowTooltip:y,overflowHintNoNeed:b,overflowHint:x,selectModel:S,clickToSelectModel:C,selectProviderOrModel:w,configureMappingRule:T,clientModel:E,confirmToggleTitle:D,confirmToggleDesc:O,disableAction:k,enableAction:A,confirmDeleteTitle:j,confirmDeleteDesc:M,errorClientModelRequired:N,errorAtLeastOneTarget:P,errorSelectModel:F,errorLoadProviders:I,errorSaveGroup:L,errorDeleteGroup:R,errorToggleStatus:z,totalMappings:B,enabledCount:V,unsavedChanges:H,messages:U,editor:W,selectProviderModel:G,multimodalFallback:K};export{m as addBackup,t as addGroup,p as addMoreToEnableFailover,o as backup,g as backupLabel,C as clickToSelectModel,E as clientModel,T as configureMappingRule,M as confirmDeleteDesc,j as confirmDeleteTitle,O as confirmToggleDesc,D as confirmToggleTitle,q as default,k as disableAction,n as editGroup,W as editor,A as enableAction,f as enabled,V as enabledCount,P as errorAtLeastOneTarget,N as errorClientModelRequired,R as errorDeleteGroup,I as errorLoadProviders,L as errorSaveGroup,F as errorSelectModel,z as errorToggleStatus,r as failover,d as failoverChain,h as failoverChainHint,i as failoverLevel,U as messages,_ as model,K as multimodalFallback,c as noGroups,s as noTarget,x as overflowHint,b as overflowHintNoNeed,v as overflowModel,y as overflowTooltip,a as primary,S as selectModel,G as selectProviderModel,w as selectProviderOrModel,l as switchOnFail,u as switchOnFailAuto,e as title,B as totalMappings,H as unsavedChanges};
@@ -0,0 +1 @@
1
+ var e=`Model Mappings`,t=`Add Group`,n=`Edit Group`,r=`Failover`,i=`Failover · {count} levels`,a=`Primary`,o=`Backup {n}`,s=`No targets`,c=`No mapping groups yet`,l=`Switch on failure`,u=`Auto-switch on failure`,d=`Failover Chain`,f=`Enabled`,p=`Add multiple targets to enable failover`,m=`Add Backup`,h=`Requests are tried in order; automatically switches to the next target when the current one fails`,g=`Backup {idx}`,_=`Model`,v=`Overflow Model (optional)`,y=`Automatically switch to this model when context exceeds the target model limit`,b=`Current model context >= 1M, no overflow model needed`,x=`Auto-switch to {overflowModel} when context exceeds {model} limit ({context})`,S=`Select model...`,C=`Click to select model...`,w=`Select provider / model`,T=`Configure mapping rules from client models to backend provider models`,E=`Client Model`,D=`Confirm {action}`,O=`Are you sure you want to {action} mapping "{model}"?`,k=`disable`,A=`enable`,j=`Confirm Delete`,M=`Are you sure you want to delete mapping "{model}"?`,N=`Please enter a client model name`,P=`Add at least one target`,F=`Please select a model`,I=`Failed to load providers`,L=`Failed to save group`,R=`Failed to delete group`,z=`Failed to toggle status`,B=`{count} mappings`,V=`{count} enabled`,H=`Unsaved changes`,U={deleteFailed:`Failed to delete {model}`,createFailed:`Failed to create {model}`,updateFailed:`Failed to update {model}`,toggleFailed:`Failed to toggle {model} status`,partialFail:`{count} operations failed`,saveFailed:`Failed to save`,parseRuleFailed:`Invalid rule format, using defaults`},W={clientLabel:`Client`,edit:`edit`,clientInputPlaceholder:`client model name`,clickToEdit:`click to edit`,failoverChain:`Failover chain`,failoverOnError:`failover on error`,contextOverflow:`Context overflow`,contextOverflowHint:`when context exceeds model limit`,multimodalFallback:`Multimodal Fallback`,new:`New`},G=`Select Provider / Model`,K={title:`Multimodal Fallback`,add:`Add Multimodal Fallback`,configured:`Configured`,selectProvider:`Select Provider`,modelPlaceholder:`Model name (e.g. gpt-4o)`,selectProviderModel:`Select provider & model`,sessionLockWarning:`Note: Once a request contains images, audio, or video, the entire session will be persistently routed to the fallback model.`,sessionLockReason:`Reason: The client sends the full conversation history each turn, and multimedia content in history keeps triggering redirects. Session auto-recovers after client compact or new session.`,costSuggestion:`Tip: Choose a fallback model with similar pricing to the original model.`},q={title:e,addGroup:t,editGroup:n,failover:r,failoverLevel:i,primary:a,backup:o,noTarget:s,noGroups:c,switchOnFail:l,switchOnFailAuto:u,failoverChain:d,enabled:f,addMoreToEnableFailover:p,addBackup:m,failoverChainHint:h,backupLabel:g,model:_,overflowModel:v,overflowTooltip:y,overflowHintNoNeed:b,overflowHint:x,selectModel:S,clickToSelectModel:C,selectProviderOrModel:w,configureMappingRule:T,clientModel:E,confirmToggleTitle:D,confirmToggleDesc:O,disableAction:k,enableAction:A,confirmDeleteTitle:j,confirmDeleteDesc:M,errorClientModelRequired:N,errorAtLeastOneTarget:P,errorSelectModel:F,errorLoadProviders:I,errorSaveGroup:L,errorDeleteGroup:R,errorToggleStatus:z,totalMappings:B,enabledCount:V,unsavedChanges:H,messages:U,editor:W,selectProviderModel:G,multimodalFallback:K};export{m as addBackup,t as addGroup,p as addMoreToEnableFailover,o as backup,g as backupLabel,C as clickToSelectModel,E as clientModel,T as configureMappingRule,M as confirmDeleteDesc,j as confirmDeleteTitle,O as confirmToggleDesc,D as confirmToggleTitle,q as default,k as disableAction,n as editGroup,W as editor,A as enableAction,f as enabled,V as enabledCount,P as errorAtLeastOneTarget,N as errorClientModelRequired,R as errorDeleteGroup,I as errorLoadProviders,L as errorSaveGroup,F as errorSelectModel,z as errorToggleStatus,r as failover,d as failoverChain,h as failoverChainHint,i as failoverLevel,U as messages,_ as model,K as multimodalFallback,c as noGroups,s as noTarget,x as overflowHint,b as overflowHintNoNeed,v as overflowModel,y as overflowTooltip,a as primary,S as selectModel,G as selectProviderModel,w as selectProviderOrModel,l as switchOnFail,u as switchOnFailAuto,e as title,B as totalMappings,H as unsavedChanges};
@@ -0,0 +1 @@
1
+ import{$ as e,Gt as t,H as n,J as r,L as i,Lt as a,N as o,Q as s,X as c,Xt as l,Z as u,bt as d,et as f,gt as p,it as m,kt as h,n as g,nt as _,qt as v,r as y,rt as b,vt as x,xt as S}from"./button-DXlWUlLe.js";import{t as C}from"./image-8GxBtf66.js";import{t as w}from"./plus-DghQKiGV.js";import{t as T}from"./trash-2-BFS2nrZH.js";import{n as E,t as D}from"./CollapsibleContent-DDzm_Bxn.js";import{t as O}from"./Label-CgLYbqNp.js";import{_ as k,g as A,gt as j,h as M,m as N,v as P}from"./index-FYAc4GSw.js";import{t as F}from"./badge-C82CIl1p.js";import{t as I}from"./Input-Qz28j7do.js";var L=i(`type`,[[`path`,{d:`M12 4v16`,key:`1654pz`}],[`path`,{d:`M4 7V5a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v2`,key:`e0r10z`}],[`path`,{d:`M9 20h6`,key:`s66wpe`}]]),ee=i(`video`,[[`path`,{d:`m16 13 5.223 3.482a.5.5 0 0 0 .777-.416V7.87a.5.5 0 0 0-.752-.432L16 10.5`,key:`ftymec`}],[`rect`,{x:`2`,y:`6`,width:`14`,height:`12`,rx:`2`,key:`158x01`}]]),te=i(`volume-2`,[[`path`,{d:`M11 4.702a.705.705 0 0 0-1.203-.498L6.413 7.587A1.4 1.4 0 0 1 5.416 8H3a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h2.416a1.4 1.4 0 0 1 .997.413l3.383 3.384A.705.705 0 0 0 11 19.298z`,key:`uqj9uw`}],[`path`,{d:`M16 9a5 5 0 0 1 0 6`,key:`1q6k2b`}],[`path`,{d:`M19.364 18.364a9 9 0 0 0 0-12.728`,key:`ijwkga`}]]),R=[{id:`claude-code`,name:`Claude Code`,icon:`C`,iconClass:`cc`,iconSvg:`claude`,brandBg:`bg-[#D97757]`,format:`anthropic`,defaultProvider:`DeepSeek`,defaultPlan:`Anthropic`,descriptionKey:`quickSetup.client.claudeCodeDesc`,popular:!0},{id:`codex`,name:`Codex CLI`,icon:`CX`,iconClass:`cx`,iconSvg:`codex`,brandBg:`bg-[#74AA9C]`,format:`openai-responses`,defaultProvider:`DeepSeek`,defaultPlan:`OpenAI`,descriptionKey:`quickSetup.client.codexDesc`,popular:!0},{id:`pi`,name:`Pi`,icon:`P`,iconClass:`pi`,iconSvg:`pi`,brandBg:`bg-emerald-600`,format:`anthropic`,defaultProvider:`DeepSeek`,defaultPlan:`Anthropic`,descriptionKey:`quickSetup.client.piDesc`},{id:`openai-sdk`,name:`OpenAI SDK`,icon:`OA`,iconClass:`oa`,iconSvg:`openai`,brandBg:`bg-[#10a37f]`,format:`openai`,defaultProvider:`DeepSeek`,defaultPlan:`OpenAI`,descriptionKey:`quickSetup.client.openaiSdkDesc`},{id:`anthropic-sdk`,name:`Anthropic SDK`,icon:`AN`,iconClass:`an`,iconSvg:`anthropic`,brandBg:`bg-[#D4976A]`,format:`anthropic`,defaultProvider:`DeepSeek`,defaultPlan:`Anthropic`,descriptionKey:`quickSetup.client.anthropicSdkDesc`}],z=[{key:`deepseek_anthropic`,labelKey:`quickSetup.patch.deepseekAnthropic`,items:[{id:`thinking_consistency`,nameKey:`quickSetup.patch.thinkingConsistency`,descKey:`quickSetup.patch.thinkingConsistencyDesc`},{id:`orphan_tool_results`,nameKey:`quickSetup.patch.orphanToolResult`,descKey:`quickSetup.patch.orphanToolResultDesc`}]},{key:`deepseek_openai`,labelKey:`quickSetup.patch.deepseekOpenai`,items:[{id:`thinking_consistency`,nameKey:`quickSetup.patch.thinkingConsistency`,descKey:`quickSetup.patch.thinkingConsistencyDesc`},{id:`orphan_tool_results_oa`,nameKey:`quickSetup.patch.orphanToolResultOa`,descKey:`quickSetup.patch.orphanToolResultOaDesc`}]},{key:`general`,labelKey:`quickSetup.patch.general`,items:[{id:`developer_role`,nameKey:`quickSetup.patch.developerRole`,descKey:`quickSetup.patch.developerRoleDesc`}]}],B=[{label:`8K`,value:8e3},{label:`16K`,value:16e3},{label:`32K`,value:32e3},{label:`64K`,value:64e3},{label:`128K`,value:128e3},{label:`160K`,value:16e4},{label:`200K`,value:2e5},{label:`256K`,value:256e3},{label:`1M`,value:1e6}],V=1e6,H=256e3,U=2e5,W=128e3,G=32e3,K=16e3,q=8e3;function J(e){let t=e.toLowerCase();return t.includes(`v4`)||t.includes(`v3.2`)||t.includes(`r1`)||t.includes(`reasoner`)||t.includes(`qwen3.6`)?V:t.includes(`kimi`)||t.includes(`moonshotai`)||t.includes(`hunyuan-2.0`)||t.includes(`hunyuan-a13b`)||t.includes(`hunyuan-t1`)||t.includes(`step-3.5`)||t.includes(`step-3`)||t.includes(`qwen3.5-plus`)||t.includes(`qwen3-max`)||t.includes(`doubao`)||t.includes(`ark-code`)||t.includes(`tc-code`)?H:t.includes(`glm-5`)||t.includes(`glm-4.7`)||t.includes(`minimax`)?U:t.includes(`128k`)?W:t.includes(`32k`)?G:t.includes(`16k`)?K:t.includes(`8k`)?q:W}var ne={"claude-code":[`sonnet`,`opus`,`haiku`],codex:[`gpt-5.5`,`gpt-5.4`,`gpt-5.4-mini`,`gpt-5.3-codex`,`gpt-5.2`],"openai-sdk":[`gpt-5.1`,`gpt-4.1`,`o3`,`o4-mini`],"anthropic-sdk":[`claude-sonnet-4-20250514`,`claude-opus-4-20250116`,`claude-haiku-4-20250414`]},Y={class:`space-y-3`},X={class:`mb-1.5 text-xs font-medium text-muted-foreground`},Z={class:`flex flex-wrap gap-1.5`},re=m({__name:`PatchChips`,props:{apiType:{},isDeepSeek:{type:Boolean},isNonOpenaiEndpoint:{type:Boolean},modelValue:{}},emits:[`update:modelValue`],setup(e,{emit:i}){let{t:a}=n();function o(e){return e.replace(/-/g,`_`)}let d=e,m=i,b=c(()=>z.filter(e=>e.key===`deepseek_anthropic`?d.isDeepSeek&&d.apiType===`anthropic`:e.key===`deepseek_openai`?d.isDeepSeek&&d.apiType===`openai`:e.key===`general`?d.apiType===`openai`&&d.isNonOpenaiEndpoint:!0));function S(e){let t=o(e);m(`update:modelValue`,d.modelValue.includes(t)?d.modelValue.filter(e=>e!==t):[...d.modelValue,t])}function C(e){return d.modelValue.includes(o(e))}return(e,n)=>(p(),f(`div`,Y,[(p(!0),f(r,null,x(b.value,e=>(p(),f(`div`,{key:e.key},[u(`p`,X,l(t(a)(e.labelKey)),1),u(`div`,Z,[(p(!0),f(r,null,x(e.items,e=>(p(),s(t(g),{key:e.id,type:`button`,variant:`outline`,size:`sm`,"aria-pressed":C(e.id),title:t(a)(e.descKey),class:v(t(y)(`inline-flex items-center gap-1.5 rounded-md border px-2 py-1 text-xs font-medium transition-all cursor-pointer select-none`,C(e.id)?`border-ring bg-primary/10 text-primary`:`border-border bg-transparent text-muted-foreground hover:border-muted-foreground hover:text-foreground`)),onClick:t=>S(e.id)},{default:h(()=>[u(`span`,{class:v(t(y)(`size-1.5 rounded-full transition-colors`,C(e.id)?`bg-primary`:`bg-border`))},null,2),_(` `+l(t(a)(e.nameKey)),1)]),_:2},1032,[`aria-pressed`,`title`,`class`,`onClick`]))),128))])]))),128))]))}}),ie={class:`flex items-center gap-2.5 px-3 min-h-8 py-1.5`},ae={key:0,width:`10`,height:`10`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,"stroke-width":`3`,class:`text-primary-foreground`},Q=[`title`],oe={key:2,class:`flex items-center gap-0.5 shrink-0`},se=[`title`,`onClick`],ce={class:`text-[11px]`},le={class:`pl-9 pr-3 py-2 border-t border-border space-y-2`},ue={class:`text-[10px] font-medium uppercase tracking-wider text-muted-foreground mb-1`},de={key:0},fe={class:`text-[10px] font-medium uppercase tracking-wider text-muted-foreground mb-1`},pe={class:`flex items-center gap-1.5`},me={class:`text-[11px] text-muted-foreground`},$=1e3,he=m({__name:`ModelCard`,props:{model:{},apiType:{},isDeepSeek:{type:Boolean},isNonOpenaiEndpoint:{type:Boolean},streamTimeoutMs:{},capabilities:{}},emits:[`update:model`,`remove`,`update:stream-timeout-ms`,`toggle-capability`],setup(i,{emit:m}){let g=o/$,{t:w}=n(),O=i,j=m,R=a(!1),z=c(()=>B.find(e=>e.value===O.model.contextWindow)),V=c(()=>!!z.value);function H(e){let t=e;if(t===`__custom__`)return;let n=parseInt(t,10);isNaN(n)||j(`update:model`,{...O.model,contextWindow:n})}function U(e){let t=parseInt(e,10);!isNaN(t)&&t>0&&j(`update:model`,{...O.model,contextWindow:t})}function W(e){j(`update:model`,{...O.model,patches:e})}let G=c(()=>O.streamTimeoutMs!==void 0&&O.streamTimeoutMs!==null?Math.round(O.streamTimeoutMs/$):g),K=c(()=>O.streamTimeoutMs===void 0),q=[{key:`text`,icon:L,label:`text`},{key:`image`,icon:C,label:`image`},{key:`audio`,icon:te,label:`audio`},{key:`video`,icon:ee,label:`video`}];function J(e){return e===`text`?!0:O.capabilities?.includes(e)??!1}return(n,a)=>{let o=d(`Button`);return p(),f(`div`,{class:v([`transition-colors group bg-card`,!i.model.enabled&&`opacity-40`])},[u(`div`,ie,[u(`div`,{class:v([`shrink-0 w-3.5 h-3.5 rounded-sm border-[1px] border-border flex items-center justify-center cursor-pointer transition-all`,i.model.enabled?`bg-primary border-primary`:`border-border hover:border-muted-foreground/50`]),onClick:a[0]||=e=>j(`update:model`,{...i.model,enabled:!i.model.enabled})},[i.model.enabled?(p(),f(`svg`,ae,[...a[6]||=[u(`path`,{d:`M18 6L9 17l-5-6`},null,-1)]])):e(``,!0)],2),u(`span`,{class:`truncate text-xs font-medium text-foreground min-w-[160px] max-w-[280px] font-mono`,title:i.model.name},l(i.model.name),9,Q),V.value?(p(),s(t(P),{key:0,"model-value":String(i.model.contextWindow),"onUpdate:modelValue":H},{default:h(()=>[b(t(M),{class:`h-6 w-16 text-[11px] font-mono px-1 gap-0 data-[size=default]:h-6`},{default:h(()=>[b(t(N),null,{default:h(()=>[_(l(z.value.label),1)]),_:1})]),_:1}),b(t(k),null,{default:h(()=>[(p(!0),f(r,null,x(t(B),e=>(p(),s(t(A),{key:e.value,value:String(e.value)},{default:h(()=>[_(l(e.label),1)]),_:2},1032,[`value`]))),128)),b(t(A),{value:`__custom__`},{default:h(()=>[_(l(t(w)(`quickSetup.model.contextCustom`)),1)]),_:1})]),_:1})]),_:1},8,[`model-value`])):(p(),s(t(I),{key:1,"model-value":String(i.model.contextWindow),type:`number`,min:`1`,class:`h-6 w-16 !text-[11px] text-center font-mono px-1.5 py-0 rounded [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none`,"onUpdate:modelValue":a[1]||=e=>U(e)},null,8,[`model-value`])),i.capabilities===void 0?e(``,!0):(p(),f(`div`,oe,[(p(),f(r,null,x(q,e=>u(`div`,{key:e.key,class:v([`w-5 h-5 rounded flex items-center justify-center border-[1px] transition-colors cursor-pointer`,t(y)(J(e.key)?`bg-primary/10 border-primary/30 text-primary`:`border-border text-muted-foreground/40 hover:text-muted-foreground`)]),title:e.label,onClick:t=>e.key!==`text`&&j(`toggle-capability`,e.key)},[(p(),s(S(e.icon),{class:`size-[11px]`}))],10,se)),64))])),u(`div`,{class:v([`inline-flex items-center gap-1 h-[22px] px-2 border-[1px] border-border rounded cursor-pointer transition-colors shrink-0 select-none`,t(y)(i.model.patches.length>0?`bg-primary/10 border-primary/25 text-primary`:`border-border text-muted-foreground hover:border-foreground/20 hover:text-foreground`)]),onClick:a[2]||=e=>R.value=!R.value},[u(`span`,ce,l(i.model.patches.length)+` `+l(t(w)(`quickSetup.patch.label`)),1),u(`span`,{class:v([`text-[8px] inline-block transition-transform`,R.value?`rotate-90`:``])},`▶`,2)],2),b(o,{type:`button`,variant:`ghost`,size:`icon-xs`,class:`shrink-0 text-muted-foreground hover:text-destructive`,onClick:a[3]||=e=>n.$emit(`remove`)},{default:h(()=>[b(t(T),{class:`size-3`})]),_:1})]),b(t(E),{open:R.value,"onUpdate:open":a[5]||=e=>R.value=e},{default:h(()=>[b(t(D),null,{default:h(()=>[u(`div`,le,[u(`div`,null,[u(`div`,ue,l(t(w)(`quickSetup.patch.sectionTitle`)),1),b(re,{"api-type":i.apiType,"is-deep-seek":i.isDeepSeek,"is-non-openai-endpoint":i.isNonOpenaiEndpoint,"model-value":i.model.patches,"onUpdate:modelValue":W},null,8,[`api-type`,`is-deep-seek`,`is-non-openai-endpoint`,`model-value`])]),i.streamTimeoutMs===void 0?e(``,!0):(p(),f(`div`,de,[u(`div`,fe,l(t(w)(`quickSetup.patch.timeoutTitle`)),1),u(`div`,pe,[b(t(I),{type:`number`,"model-value":G.value,"onUpdate:modelValue":a[4]||=e=>j(`update:stream-timeout-ms`,e?Number(e)*$:void 0),class:`h-6 w-[72px] !text-[11px] font-mono text-right px-1.5 py-0 rounded [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none`,min:`1`},null,8,[`model-value`]),u(`span`,me,l(t(w)(`quickSetup.patch.timeoutSeconds`)),1),K.value?(p(),s(t(F),{key:0,variant:`outline`,class:`text-[9px] px-1 py-0 h-4 font-normal text-muted-foreground`},{default:h(()=>[_(l(t(w)(`providers.fields.timeoutPlaceholder`)),1)]),_:1})):e(``,!0)])]))])]),_:1})]),_:1},8,[`open`])],2)}}}),ge={class:`space-y-2`},_e={class:`flex items-center justify-between`},ve={key:0,class:`flex items-center gap-1.5`},ye={key:0,class:`flex items-center gap-2 text-[11px] text-muted-foreground`},be={key:0,class:`opacity-70`},xe={class:`flex items-center gap-2`},Se={key:0,class:`flex-1 min-w-0`},Ce={key:1,class:`flex-1 text-[10px] text-muted-foreground`},we={class:`flex items-end gap-2`},Te={class:`min-w-0 space-y-0.5`,style:{flex:`6`}},Ee={class:`space-y-0.5`,style:{flex:`4`}},De={class:`text-xs text-muted-foreground`},Oe=m({__name:`EndpointEditor`,props:{modelValue:{},sharedKey:{},readonly:{type:Boolean}},emits:[`update:modelValue`],setup(i,{emit:o}){let{t:d}=n(),m=[`openai`,`openai-responses`,`anthropic`],y={openai:`bg-emerald-100 text-emerald-700 border-emerald-300 hover:bg-emerald-200 dark:bg-emerald-900/40 dark:text-emerald-400 dark:border-emerald-700 dark:hover:bg-emerald-800/50`,"openai-responses":`bg-blue-100 text-blue-700 border-blue-300 hover:bg-blue-200 dark:bg-blue-900/40 dark:text-blue-400 dark:border-blue-700 dark:hover:bg-blue-800/50`,anthropic:`bg-amber-100 text-amber-700 border-amber-300 hover:bg-amber-200 dark:bg-amber-900/40 dark:text-amber-400 dark:border-amber-700 dark:hover:bg-amber-800/50`},S={openai:`bg-emerald-200 text-emerald-800 border-emerald-400 dark:bg-emerald-800/60 dark:text-emerald-300 dark:border-emerald-500`,"openai-responses":`bg-blue-200 text-blue-800 border-blue-400 dark:bg-blue-800/60 dark:text-blue-300 dark:border-blue-500`,anthropic:`bg-amber-200 text-amber-800 border-amber-400 dark:bg-amber-800/60 dark:text-amber-300 dark:border-amber-500`},C=i,E=o,D=c(()=>C.modelValue.some(e=>e.api_key!==null&&e.api_key!==void 0&&e.api_key!==``)),k=a(!1),A=c(()=>k.value||D.value),M=c(()=>new Set(C.modelValue.map(e=>e.api_type)));function N(e){M.value.has(e)||E(`update:modelValue`,[...C.modelValue,{api_type:e,base_url:``,upstream_path:null,api_key:null}])}function P(e){let t=[...C.modelValue];t.splice(e,1),E(`update:modelValue`,t)}function L(e,t,n){let r=[...C.modelValue];r[e]={...r[e],[t]:n},E(`update:modelValue`,r)}return(n,a)=>(p(),f(`div`,ge,[u(`div`,_e,[b(t(O),{class:`text-xs text-muted-foreground`},{default:h(()=>[_(l(t(d)(`providers.endpoints.title`)),1)]),_:1}),i.readonly?e(``,!0):(p(),f(`div`,ve,[(p(),f(r,null,x(m,e=>b(t(g),{key:e,type:`button`,variant:`outline`,size:`sm`,class:v([`h-6 text-[10px] gap-0.5 px-2.5 border font-medium transition-colors`,M.value.has(e)?S[e]:y[e]]),disabled:M.value.has(e),onClick:t=>N(e)},{default:h(()=>[M.value.has(e)?(p(),s(t(j),{key:0,class:`w-3 h-3`})):(p(),s(t(w),{key:1,class:`w-3 h-3`})),_(` `+l(t(d)(`providers.endpoints.apiTypes.${e}`)),1)]),_:2},1032,[`class`,`disabled`,`onClick`])),64))]))]),i.readonly?e(``,!0):(p(),f(`div`,ye,[b(t(g),{type:`button`,variant:`link`,size:`sm`,class:`h-auto p-0 text-[11px] text-muted-foreground underline decoration-dotted underline-offset-2 hover:text-foreground`,onClick:a[0]||=e=>k.value=!k.value},{default:h(()=>[_(l(A.value?t(d)(`providers.endpoints.hidePerEndpointKeys`):t(d)(`providers.endpoints.showPerEndpointKeys`)),1)]),_:1}),i.sharedKey&&!A.value?(p(),f(`span`,be,l(t(d)(`providers.endpoints.allUseSharedKey`)),1)):e(``,!0)])),(p(!0),f(r,null,x(i.modelValue,(n,r)=>(p(),f(`div`,{key:r,class:`rounded-md border bg-muted/30 p-2.5 space-y-2`},[u(`div`,xe,[b(t(F),{variant:`secondary`,class:`text-[11px] px-1.5 py-0 shrink-0`},{default:h(()=>[_(l(t(d)(`providers.endpoints.apiTypes.${n.api_type}`)),1)]),_:2},1024),A.value?(p(),f(`div`,Se,[b(t(I),{"model-value":n.api_key??``,type:`password`,disabled:i.readonly,placeholder:i.sharedKey?t(d)(`providers.endpoints.useSharedKey`):t(d)(`providers.endpoints.apiKeyPlaceholder`),class:`h-6 text-xs font-mono`,"onUpdate:modelValue":e=>L(r,`api_key`,String(e)||null)},null,8,[`model-value`,`disabled`,`placeholder`,`onUpdate:modelValue`])])):n.api_key?(p(),f(`div`,Ce,l(t(d)(`providers.endpoints.customKeySet`)),1)):e(``,!0),i.readonly?e(``,!0):(p(),s(t(g),{key:2,type:`button`,variant:`ghost`,size:`sm`,class:`h-6 w-6 p-0 shrink-0 text-muted-foreground hover:text-destructive`,disabled:i.modelValue.length<=1,onClick:e=>P(r)},{default:h(()=>[b(t(T),{class:`w-3.5 h-3.5`})]),_:1},8,[`disabled`,`onClick`]))]),u(`div`,we,[u(`div`,Te,[b(t(O),{class:`text-[10px] text-muted-foreground`},{default:h(()=>[...a[1]||=[_(`Base URL`,-1)]]),_:1}),b(t(I),{"model-value":n.base_url,type:`url`,required:``,disabled:i.readonly,placeholder:`https://api.example.com/v1`,class:`h-6 text-xs font-mono`,"onUpdate:modelValue":e=>L(r,`base_url`,String(e))},null,8,[`model-value`,`disabled`,`onUpdate:modelValue`])]),u(`div`,Ee,[b(t(O),{class:`text-[10px] text-muted-foreground`},{default:h(()=>[_(l(t(d)(`providers.fields.upstreamPath`)),1)]),_:1}),b(t(I),{"model-value":n.upstream_path??``,disabled:i.readonly,placeholder:t(d)(`providers.fields.upstreamPathPlaceholder`),class:`h-6 text-xs font-mono`,"onUpdate:modelValue":e=>L(r,`upstream_path`,String(e)||null)},null,8,[`model-value`,`disabled`,`placeholder`,`onUpdate:modelValue`])])])]))),128)),u(`p`,De,l(t(d)(`providers.endpoints.hint`)),1)]))}});function ke(e,t,n){let r=[];return e.toLowerCase().includes(`deepseek`)&&(r.push(`thinking_consistency`),t===`anthropic`?r.push(`orphan_tool_results`):r.push(`orphan_tool_results_oa`)),t===`openai`&&n&&r.push(`developer_role`),r}export{ne as a,R as i,Oe as n,J as o,he as r,ke as t};
@@ -0,0 +1 @@
1
+ var e=`Realtime Monitor`,t=`Connected`,n=`Disconnected`,r=`Active Requests`,i=`Queued Requests`,a=`Completed`,o=`No active requests`,s=`No queued requests`,c=`No completed requests`,l=`Queued`,u=`Copy ID`,d=`Provider Stats`,f=`Hide Stats`,p=`Show Stats`,m=`Concurrency`,h=`Status Code Distribution`,g=`Runtime`,_={activeRequests:`Active Requests`,streamNonStream:`{stream} streaming / {nonStream} non-streaming`,errorRate:`Error Rate`,p50Latency:`P50 Latency`,avgLatency:`Avg {value}ms`,retryRate:`Retry Rate`},v={noData:`No concurrency data`,adaptive:`Adaptive`,unlimited:`Unlimited`,queued:`Queued: {count}`,queueLimit:`Queue limit: {limit}`},y={noData:`No data`,noProviders:`No provider stats`,requests:`Requests`,successRate:`Success Rate`,avgLatency:`Avg Latency`,retryRate:`Retry Rate`,topErrors:`Top Errors`},b={noData:`No runtime data`,uptime:`Uptime`,memoryRss:`Memory RSS`,heapUsage:`Heap Usage`,activeHandles:`Active Handles`,activeRequests:`Active Requests`,eventLoopDelay:`Event Loop Delay`},x=`Kill`,S=`Cancel`,C=`Confirm Kill Request`,w=`Are you sure you want to kill the request for {model} ({provider})? This action cannot be undone.`,T=`Request killed`,E=`Failed to kill request`,D={noData:`No status code data`,success:`2xx Success`,clientError:`4xx Client Error`,rateLimited:`429 Rate Limited`,serverError:`5xx Server Error`},O={title:e,connected:t,disconnected:n,activeRequests:r,queuedRequests:i,completed:a,noActiveRequests:o,noQueuedRequests:s,noCompletedRequests:c,queued:l,copyId:u,providerStats:d,providerStatsHide:f,providerStatsShow:p,concurrency:m,statusCodeDistribution:h,runtime:g,header:_,concurrencyPanel:v,providerTable:y,runtimePanel:b,kill:x,killCancel:S,killConfirmTitle:C,killConfirm:w,killSuccess:T,killFailed:E,statusCodes:D};export{r as activeRequests,a as completed,m as concurrency,v as concurrencyPanel,t as connected,u as copyId,O as default,n as disconnected,_ as header,x as kill,S as killCancel,w as killConfirm,C as killConfirmTitle,E as killFailed,T as killSuccess,o as noActiveRequests,c as noCompletedRequests,s as noQueuedRequests,d as providerStats,f as providerStatsHide,p as providerStatsShow,y as providerTable,l as queued,i as queuedRequests,g as runtime,b as runtimePanel,h as statusCodeDistribution,D as statusCodes,e as title};
@@ -0,0 +1 @@
1
+ var e=`实时监控`,t=`已连接`,n=`未连接`,r=`活跃请求`,i=`队列请求`,a=`已完成`,o=`暂无活跃请求`,s=`暂无排队请求`,c=`暂无已完成请求`,l=`排队`,u=`复制 ID`,d=`Provider 统计`,f=`Hide`,p=`Show`,m=`并发度`,h=`状态码分布`,g=`运行时`,_={activeRequests:`活跃请求`,streamNonStream:`{stream} 流式 / {nonStream} 非流式`,errorRate:`错误率`,p50Latency:`P50 延迟`,avgLatency:`平均 {value}ms`,retryRate:`重试率`},v={noData:`暂无并发数据`,adaptive:`自适应`,unlimited:`未限制`,queued:`排队: {count}`,queueLimit:`队列上限: {limit}`},y={noData:`暂无数据`,noProviders:`暂无 Provider 统计`,requests:`请求数`,successRate:`成功率`,avgLatency:`平均延迟`,retryRate:`重试率`,provider:`Provider`,topErrors:`Top Errors`},b={noData:`暂无运行时数据`,uptime:`运行时间`,memoryRss:`内存 RSS`,heapUsage:`Heap 使用`,activeHandles:`Active Handles`,activeRequests:`Active Requests`,eventLoopDelay:`Event Loop 延迟`},x=`终止`,S=`取消`,C=`确认终止请求`,w=`确定要终止 {model}({provider})的请求吗?此操作不可撤销。`,T=`请求已终止`,E=`终止请求失败`,D={noData:`暂无状态码数据`,success:`2xx 成功`,clientError:`4xx 客户端错误`,rateLimited:`429 限流`,serverError:`5xx 服务端错误`},O={title:e,connected:t,disconnected:n,activeRequests:r,queuedRequests:i,completed:a,noActiveRequests:o,noQueuedRequests:s,noCompletedRequests:c,queued:l,copyId:u,providerStats:d,providerStatsHide:f,providerStatsShow:p,concurrency:m,statusCodeDistribution:h,runtime:g,header:_,concurrencyPanel:v,providerTable:y,runtimePanel:b,kill:x,killCancel:S,killConfirmTitle:C,killConfirm:w,killSuccess:T,killFailed:E,statusCodes:D};export{r as activeRequests,a as completed,m as concurrency,v as concurrencyPanel,t as connected,u as copyId,O as default,n as disconnected,_ as header,x as kill,S as killCancel,w as killConfirm,C as killConfirmTitle,E as killFailed,T as killSuccess,o as noActiveRequests,c as noCompletedRequests,s as noQueuedRequests,d as providerStats,f as providerStatsHide,p as providerStatsShow,y as providerTable,l as queued,i as queuedRequests,g as runtime,b as runtimePanel,h as statusCodeDistribution,D as statusCodes,e as title};
@@ -0,0 +1 @@
1
+ import{L as e}from"./button-DXlWUlLe.js";var t=e(`pencil`,[[`path`,{d:`M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z`,key:`1a8usu`}],[`path`,{d:`m15 5 4 4`,key:`1mk7zo`}]]);export{t};
@@ -0,0 +1 @@
1
+ import{L as e}from"./button-DXlWUlLe.js";var t=e(`plus`,[[`path`,{d:`M5 12h14`,key:`1ays0h`}],[`path`,{d:`M12 5v14`,key:`s699le`}]]);export{t};
@@ -0,0 +1 @@
1
+ var e=`供应商`,t=`添加供应商`,n=`编辑供应商`,r=`重载插件`,i=`暂无供应商`,a={total:`Provider 总数`,enabled:`启用`,disabled:`禁用`,models:`模型总数`},o={searchPlaceholder:`搜索名称或 URL...`,status:`状态`,all:`全部`,enabled:`启用`,disabled:`禁用`,count:`个供应商`,noResults:`无匹配结果`},s={title:`尚未配置任何 Provider`,description:`添加第一个上游 API 供应商以开始路由 LLM 请求。支持 OpenAI、Anthropic 及所有兼容接口。`,addFirst:`添加第一个 Provider`},c={name:`名称`,type:`类型`,baseUrl:`Base URL`,apiKey:`API Key`,models:`模型`,concurrency:`并发`,status:`状态`,actions:`操作`,apiType:`API 类型`},l={title:`快速配置`,selectProvider:`选择供应商`,selectPlan:`选择套餐`,selectApiType:`选择 API 类型`},u={title:`模板选择`,selectProvider:`选择供应商模板`,selectPlan:`选择套餐`,custom:`自定义`,selectFirst:`请先选择模板,或使用自定义模式`},d={name:`名称`,apiType:`API 类型`,baseUrl:`Base URL`,apiKey:`API Key`,apiKeyPlaceholder:`留空则保持原密钥不变`,availableModels:`可用模型`,modelInputPlaceholder:`输入模型名称,多个用逗号分隔`,context:`上下文`,addModel:`添加`,proxyTitle:`代理配置`,proxyType:`代理类型`,proxyNoProxy:`无代理`,proxyHttp:`HTTP/HTTPS`,proxySocks5:`SOCKS5`,proxyUrl:`代理地址`,proxyUrlPlaceholderHttp:`http://127.0.0.1:7890`,proxyUrlPlaceholderSocks5:`socks5://127.0.0.1:1080`,proxyUsername:`用户名`,proxyPassword:`密码`,proxyAuthOptional:`可选`,connectionSection:`连接配置`,modelsSection:`模型管理`,advancedSection:`高级配置`,upstreamPath:`上游路径`,upstreamPathPlaceholder:`默认: /v1/chat/completions 或 /v1/messages`,upstreamPathHint:`留空使用 API 类型默认路径`,timeoutLabel:`超时(秒)`,timeoutPlaceholder:`默认`,sharedKeyHint:`作为 Endpoint 的默认 API Key,留空则保持原密钥不变`},f={title:`并发控制`,mode:`模式`,selectMode:`选择模式`,autoAdaptive:`自动(自适应)`,manual:`手动`,none:`无限制`,maxConcurrency:`最大并发度`,queueTimeout:`队列超时 (ms)`,queueTimeoutPlaceholder:`0 = 无限等待`,maxQueueSize:`最大队列长度`},p={title:`转换规则`,injectHeaders:`注入 Headers (JSON)`,dropFields:`丢弃字段(逗号分隔)`,requestDefaults:`请求默认值 (JSON)`,saveRules:`保存规则`,deleteRules:`删除规则`,loadFailed:`加载转换规则失败`,requestDefaultsJsonError:`请求默认值 JSON 格式错误`,injectHeadersJsonError:`注入 Headers JSON 格式错误`,saved:`转换规则已保存`,deleteFailed:`删除规则失败`,deleted:`转换规则已删除`},m={nameRequired:`请输入名称`,namePattern:`仅允许英文、数字、横线和下划线`,baseUrlRequired:`请输入 Base URL`,baseUrlInvalid:`请输入合法的 URL`,apiKeyRequired:`请输入 API Key`,concurrencyRange:`范围 {min}-{max}`,negativeNotAllowed:`不能为负数`,queueSizeRange:`范围 {min}-{max}`,duplicateApiType:`同一供应商内 API 类型不能重复`},h={title:`确认删除`,message:`确定要删除供应商「{name}」吗?此操作不可撤销。`},g={titleDisable:`确认禁用`,titleEnable:`确认启用`,messageDisable:`确定要禁用供应商「{name}」吗?`,messageEnable:`确定要启用供应商「{name}」吗?`,dependencyWarning:`以下映射分组正在使用此供应商:`},_={clientModel:`客户端模型`,targetModel:`目标模型`,targetChain:`目标链`,actions:`操作`,enabled:`启用`,disabled:`已禁用`,level:`{count}级`,overflow:`溢出`,primary:`首选`,backup:`备{n}`,switchOnFail:`失败时切换`,overflowPlaceholder:`可选,上下文超限时切换...`,addFailover:`添加故障转移`,addMappingModel:`添加映射模型`,addOverflow:`添加溢出模型`,noMappings:`暂无映射`,add:`添加`,autoHint:`自适应模式会根据错误率自动调整并发度`,queueTimeoutPlaceholder:`0=无限`,tagDefault:`默认`,tagAuto:`自动`,tagCustom:`自定义`,tagExisting:`已有`,selectModel:`选择模型...`,unlimited:`无限制`},v={loadFailed:`加载供应商失败`,saveFailed:`保存供应商失败,请检查必填项(名称、Base URL、API Key)`,toggleFailed:`切换供应商状态失败,该供应商可能正在被映射分组引用。`,deleteFailed:`删除供应商失败`,reloadFailed:`重载失败`,reloadSuccess:`插件重载完成:{pluginCount} 个插件,{rulesCount} 条规则`,cascadeClean:`清理 {count} 个分组的引用`,cascadeDisable:`禁用 {count} 个分组`,cascadeAuto:`已自动{actions}`},y={button:`从上游获取模型`,buttonPreset:`使用预设模型`,loading:`获取中...`,noApiKey:`请先输入 API Key`,success:`{source}获取到 {total} 个模型,新增 {added} 个`,allExist:`{source}共 {total} 个模型,已全部存在`,empty:`上游返回空模型列表,已使用预设模型`,failed:`获取上游模型列表失败`,sourceUpstream:`上游`,sourcePreset:`预设`},b={label:`能力`,text:`文本`,image:`图片`,audio:`音频`,video:`视频`},x={title:`端点`,add:`添加端点`,useSharedKey:`使用共享 API Key`,apiKeyPlaceholder:`输入 API Key`,hint:`每个 API 类型只能配置一个端点。API Key 留空则使用共享 Key。`,apiTypes:{openai:`OpenAI`,"openai-responses":`Responses`,anthropic:`Anthropic`},showPerEndpointKeys:`为每个端点单独设置 API Key`,hidePerEndpointKeys:`收起单独 API Key 设置`,allUseSharedKey:`所有端点将使用共享 Key`,customKeySet:`已设置独立 Key`},S={title:e,addProvider:t,editProvider:n,reloadPlugin:r,noProviders:i,anchor:a,filter:o,empty:s,tableHeaders:c,quickConfig:l,template:u,fields:d,concurrency:f,transform:p,validation:m,confirmDelete:h,confirmToggle:g,shared:_,toast:v,fetchModels:y,capabilities:b,endpoints:x};export{t as addProvider,a as anchor,b as capabilities,f as concurrency,h as confirmDelete,g as confirmToggle,S as default,n as editProvider,s as empty,x as endpoints,y as fetchModels,d as fields,o as filter,i as noProviders,l as quickConfig,r as reloadPlugin,_ as shared,c as tableHeaders,u as template,e as title,v as toast,p as transform,m as validation};
@@ -0,0 +1 @@
1
+ var e=`Providers`,t=`Add Provider`,n=`Edit Provider`,r=`Reload Plugins`,i=`No providers yet`,a={total:`Total Providers`,enabled:`Enabled`,disabled:`Disabled`,models:`Total Models`},o={searchPlaceholder:`Search name or URL...`,status:`Status`,all:`All`,enabled:`Enabled`,disabled:`Disabled`,count:`providers`,noResults:`No matching results`},s={title:`No Providers Configured`,description:`Add your first upstream API provider to start routing LLM requests. Supports OpenAI, Anthropic, and all compatible APIs.`,addFirst:`Add First Provider`},c={name:`Name`,type:`Type`,baseUrl:`Base URL`,apiKey:`API Key`,models:`Models`,concurrency:`Concurrency`,status:`Status`,actions:`Actions`,apiType:`API Type`},l={title:`Template Selection`,selectProvider:`Select provider template`,selectPlan:`Select plan`,custom:`Custom`,selectFirst:`Select a template first, or use custom mode`},u={title:`Quick Config`,selectProvider:`Select Provider`,selectPlan:`Select Plan`,selectApiType:`Select API Type`},d={name:`Name`,apiType:`API Type`,baseUrl:`Base URL`,apiKey:`API Key`,apiKeyPlaceholder:`Leave empty to keep the original key`,availableModels:`Available Models`,modelInputPlaceholder:`Enter model names, separated by commas`,context:`Context`,addModel:`Add`,proxyTitle:`Proxy Configuration`,proxyType:`Proxy Type`,proxyNoProxy:`No Proxy`,proxyHttp:`HTTP/HTTPS`,proxySocks5:`SOCKS5`,proxyUrl:`Proxy URL`,proxyUrlPlaceholderHttp:`http://127.0.0.1:7890`,proxyUrlPlaceholderSocks5:`socks5://127.0.0.1:1080`,proxyUsername:`Username`,proxyPassword:`Password`,proxyAuthOptional:`Optional`,connectionSection:`Connection`,modelsSection:`Models`,advancedSection:`Advanced`,upstreamPath:`Upstream Path`,upstreamPathPlaceholder:`Default: /v1/chat/completions or /v1/messages`,upstreamPathHint:`Leave empty for API type default path`,timeoutLabel:`Timeout(s)`,timeoutPlaceholder:`Default`,sharedKeyHint:`Default fallback key for endpoints. Leave empty to keep original.`},f={title:`Concurrency Control`,mode:`Mode`,selectMode:`Select Mode`,autoAdaptive:`Auto (Adaptive)`,manual:`Manual`,none:`Unlimited`,maxConcurrency:`Max Concurrency`,queueTimeout:`Queue Timeout (ms)`,queueTimeoutPlaceholder:`0 = unlimited wait`,maxQueueSize:`Max Queue Size`},p={title:`Transform Rules`,injectHeaders:`Inject Headers (JSON)`,dropFields:`Drop Fields (comma-separated)`,requestDefaults:`Request Defaults (JSON)`,saveRules:`Save Rules`,deleteRules:`Delete Rules`,loadFailed:`Failed to load transform rules`,requestDefaultsJsonError:`Invalid JSON format for request defaults`,injectHeadersJsonError:`Invalid JSON format for inject headers`,saved:`Transform rules saved`,deleteFailed:`Failed to delete rules`,deleted:`Transform rules deleted`},m={nameRequired:`Please enter a name`,namePattern:`Only letters, numbers, hyphens and underscores allowed`,baseUrlRequired:`Please enter Base URL`,baseUrlInvalid:`Please enter a valid URL`,apiKeyRequired:`Please enter API Key`,concurrencyRange:`Range {min}-{max}`,negativeNotAllowed:`Cannot be negative`,queueSizeRange:`Range {min}-{max}`,duplicateApiType:`API types must be unique within a provider`},h={title:`Confirm Delete`,message:`Are you sure you want to delete provider "{name}"? This action cannot be undone.`},g={titleDisable:`Confirm Disable`,titleEnable:`Confirm Enable`,messageDisable:`Are you sure you want to disable provider "{name}"?`,messageEnable:`Are you sure you want to enable provider "{name}"?`,dependencyWarning:`The following mapping groups are using this provider:`},_={clientModel:`Client Model`,targetModel:`Target Model`,targetChain:`Target Chain`,actions:`Actions`,enabled:`Enabled`,disabled:`Disabled`,level:`{count} levels`,overflow:`Overflow`,primary:`Primary`,backup:`Backup {n}`,switchOnFail:`Switch on failure`,overflowPlaceholder:`Optional, switch when context exceeds limit...`,addFailover:`Add Failover`,addMappingModel:`Add Mapping Model`,addOverflow:`Add Overflow Model`,noMappings:`No mappings yet`,add:`Add`,autoHint:`Adaptive mode auto-adjusts concurrency based on error rate`,queueTimeoutPlaceholder:`0=unlimited`,tagDefault:`Default`,tagAuto:`Auto`,tagCustom:`Custom`,tagExisting:`Existing`,selectModel:`Select model...`,unlimited:`Unlimited`},v={loadFailed:`Failed to load providers`,saveFailed:`Failed to save provider. Check required fields (name, base URL, API key) and try again.`,toggleFailed:`Failed to toggle provider status. The provider may be in use by active mapping groups.`,deleteFailed:`Failed to delete provider`,reloadFailed:`Reload failed`,reloadSuccess:`Plugin reload complete: {pluginCount} plugins, {rulesCount} rules`,cascadeClean:`cleaned {count} group references`,cascadeDisable:`disabled {count} groups`,cascadeAuto:`Auto-{actions}`},y={button:`Fetch Models from Upstream`,buttonPreset:`Use Preset Models`,loading:`Fetching...`,noApiKey:`Please enter API Key first`,success:`{source}: fetched {total} models, {added} new`,allExist:`{source}: {total} models already exist`,empty:`Upstream returned empty model list, using preset models`,failed:`Failed to fetch upstream models`,sourceUpstream:`Upstream`,sourcePreset:`Preset`},b={title:`Endpoints`,add:`Add Endpoint`,useSharedKey:`Use shared API Key`,apiKeyPlaceholder:`Enter API Key`,hint:`Each API type can only have one endpoint. Leave API Key empty to use the shared key.`,apiTypes:{openai:`OpenAI`,"openai-responses":`Responses`,anthropic:`Anthropic`},showPerEndpointKeys:`Set API Key per endpoint`,hidePerEndpointKeys:`Hide per-endpoint API Keys`,allUseSharedKey:`All endpoints use the shared key`,customKeySet:`Custom key set`},x={label:`Capabilities`,text:`Text`,image:`Image`,audio:`Audio`,video:`Video`},S={title:e,addProvider:t,editProvider:n,reloadPlugin:r,noProviders:i,anchor:a,filter:o,empty:s,tableHeaders:c,template:l,quickConfig:u,fields:d,concurrency:f,transform:p,validation:m,confirmDelete:h,confirmToggle:g,shared:_,toast:v,fetchModels:y,endpoints:b,capabilities:x};export{t as addProvider,a as anchor,x as capabilities,f as concurrency,h as confirmDelete,g as confirmToggle,S as default,n as editProvider,s as empty,b as endpoints,y as fetchModels,d as fields,o as filter,i as noProviders,u as quickConfig,r as reloadPlugin,_ as shared,c as tableHeaders,l as template,e as title,v as toast,p as transform,m as validation};
@@ -0,0 +1,3 @@
1
+ var e=`Proxy Enhancement`,t={enabled:`Enabled`,disabled:`Disabled`},n=`Click "Save" to apply changes`,r={toolRoundLimit:{title:`Tool Call Round Limit`,description:`Detect consecutive AI tool call rounds (assistant → tool_use → user → tool_result counts as one round). Automatically injects a prompt after 5 rounds to prevent infinite loops.`},toolCallLoop:{title:`Tool Call Loop Detection`,description:`Detect repeated calls to the same tool by the model. Automatically interrupts the request or injects a prompt when the threshold is exceeded.`},streamLoop:{title:`SSE Output Loop Detection`,description:`Detect content repetition loops in streaming output (N-gram pattern). Automatically interrupts the stream when the threshold is exceeded.`}},i={title:`Client Identification`,description:`Configure client session header mapping to identify request sources. Requests with matching headers will be identified as the corresponding client type.`,addEntry:`Add Entry`,placeholder:{type:`Client type`,header:`Header name`}},a={title:`Tool Error Logging`,description:`Record detailed information about Claude Code / pi tool call failures (including tool_use input, error content, provider, model). Used for analyzing patterns of model-generated incorrect tool_use parameters.`},o={title:`Token Estimation`,shortDescription:`When upstream API doesn't return token statistics, use gpt-tokenizer to estimate input token count and cache hits. Only applies to requests with session_id.`,setupTitle:`Client Setup`,claudeCode:`Claude Code: sends x-claude-code-session-id automatically, no extra config needed`,piExtension:`Pi: install extension at ~/.pi/agent/extensions/llm-router-session/
2
+ (generates a UUID on session_start and injects x-pi-session-id header)`,piModelsJson:`Pi: add headers to your provider config in models.json:
3
+ "headers": {'{'} "x-client-type": "pi-coding-agent" {'}'}`,desc:`Only applies to requests with a session_id. Requests without a session_id will not participate in cache hit rate calculation.`},s=`Failed to load configuration`,c=`Failed to save`,l=`Failed to load provider list`,u=`AI Retry Rule Generation`,d=`Configure the AI model for automatically analyzing request responses and generating retry rules. The model is invoked directly through configured Providers.`,f=`Configure proxy enhancement strategies, loop detection, token management, and AI-assisted features`,p=`You have unsaved changes`,m=`Always on`,h={loopDetection:`Loop Detection`,errorHandling:`Error Handling`,clientIdentification:`Client Identification`,tokenManagement:`Token Management`,aiFeatures:`AI Features`},g={title:`Context Overflow Redirect`,description:`Automatically redirects to a model with a larger context window when request tokens exceed the current model's limit. Uses gpt-tokenizer for accurate token counting.`},_={title:`Session Model State Tracking`,description:`Tracks model usage state per session, ensuring subsequent requests from the same session route to the same Provider. Prevents model behavior inconsistencies caused by context switching.`},v={title:e,status:t,saveHint:n,loopDetection:r,clientIdentification:i,toolErrorLogging:a,tokenEstimation:o,loadFailed:s,saveFailed:c,loadProvidersFailed:l,aiRetryRuleGen:u,aiRetryRuleGenDesc:d,subtitle:f,unsavedChanges:p,alwaysOn:m,sections:h,contextOverflow:g,sessionState:_};export{u as aiRetryRuleGen,d as aiRetryRuleGenDesc,m as alwaysOn,i as clientIdentification,g as contextOverflow,v as default,s as loadFailed,l as loadProvidersFailed,r as loopDetection,c as saveFailed,n as saveHint,h as sections,_ as sessionState,t as status,f as subtitle,e as title,o as tokenEstimation,a as toolErrorLogging,p as unsavedChanges};
@@ -0,0 +1,3 @@
1
+ var e=`代理增强`,t={enabled:`已启用`,disabled:`已禁用`},n=`修改后点击「保存」按钮生效`,r={toolRoundLimit:{title:`工具调用轮数限制`,description:`检测 AI 连续进行工具调用的轮数(assistant → tool_use → user → tool_result 算一轮),超过 5 轮时自动注入提示词提醒 AI 不要陷入无限循环。`},toolCallLoop:{title:`工具调用循环检测`,description:`检测模型重复调用同一工具的行为,超过阈值时自动中断请求或注入提示词。`},streamLoop:{title:`SSE 输出内容循环检测`,description:`检测流式输出中内容重复循环(N-gram 模式),超过阈值时自动中断流。`}},i={title:`客户端识别`,description:`配置客户端 session header 映射,用于识别请求来源。携带对应 header 的请求将被识别为该客户端类型。`,addEntry:`新增条目`,placeholder:{type:`客户端类型`,header:`Header 名称`}},a={title:`工具调用错误日志`,description:`记录 Claude Code / pi 工具调用失败的详细信息(包含 tool_use 输入参数、错误内容、provider、模型),用于分析各模型产生错误 tool_use 参数的模式。`},o={title:`Token 预估`,shortDescription:`上游 API 不返回 token 统计数据时,通过 gpt-tokenizer 估算输入 token 数和缓存命中量。仅对携带 session_id 的请求生效。`,setupTitle:`客户端配置要求`,claudeCode:`Claude Code:自动发送 x-claude-code-session-id,无需额外配置`,piExtension:`Pi:安装扩展 ~/.pi/agent/extensions/llm-router-session/
2
+ (session_start 时自动生成 UUID 并注入 x-pi-session-id header)`,piModelsJson:`Pi:在 models.json 的 provider 配置中添加 headers:
3
+ "headers": {'{'} "x-client-type": "pi-coding-agent" {'}'}`,desc:`开启后仅对携带 session_id 的请求生效。无 session_id 的请求不参与缓存命中率计算。`},s=`加载配置失败`,c=`保存失败`,l=`加载 Provider 列表失败`,u=`AI 重试规则生成`,d=`配置用于自动分析请求响应并生成重试规则的 AI 模型。模型通过已配置的 Provider 直接调用。`,f=`配置请求转发增强策略、循环检测、Token 管理和 AI 辅助功能`,p=`有未保存的更改`,m=`始终开启`,h={loopDetection:`循环检测`,errorHandling:`错误处理`,clientIdentification:`客户端识别`,tokenManagement:`Token 管理`,aiFeatures:`AI 功能`},g={title:`上下文溢出重定向`,description:`请求 token 数超过当前模型上下文窗口时,自动重定向到支持更大上下文的模型。基于 gpt-tokenizer 精确计算 token 数。`},_={title:`会话模型状态跟踪`,description:`跟踪每个会话的模型使用状态,确保同一会话的后续请求路由到相同的 Provider,避免上下文切换导致模型行为不一致。`},v={title:e,status:t,saveHint:n,loopDetection:r,clientIdentification:i,toolErrorLogging:a,tokenEstimation:o,loadFailed:s,saveFailed:c,loadProvidersFailed:l,aiRetryRuleGen:u,aiRetryRuleGenDesc:d,subtitle:f,unsavedChanges:p,alwaysOn:m,sections:h,contextOverflow:g,sessionState:_};export{u as aiRetryRuleGen,d as aiRetryRuleGenDesc,m as alwaysOn,i as clientIdentification,g as contextOverflow,v as default,s as loadFailed,l as loadProvidersFailed,r as loopDetection,c as saveFailed,n as saveHint,h as sections,_ as sessionState,t as status,f as subtitle,e as title,o as tokenEstimation,a as toolErrorLogging,p as unsavedChanges};
@@ -0,0 +1 @@
1
+ var e=`Quick Setup`,t={selectClient:`Select Client`,claudeCode:`Claude Code`,claudeCodeDesc:`Official Anthropic CLI coding assistant`,codex:`Codex CLI`,codexDesc:`OpenAI`,pi:`Pi`,piDesc:`Universal coding Agent framework`,openaiSdk:`OpenAI SDK`,openaiSdkDesc:`Direct OpenAI API calls`,anthropicSdk:`Anthropic SDK`,anthropicSdkDesc:`Direct Anthropic API calls`,popular:`Popular`,infoBar:`{client} uses the {format}. We'll auto-map {models} to your provider models.`},n={connection:`Provider Connection`,config:`Provider Configuration`,label:`Provider`,groupLabel:`Provider`,endpoint:`Endpoint`,baseUrl:`Base URL`,upstreamPath:`Upstream Path`,select:`Select`,custom:`Custom`,customProvider:`Custom Provider`,format:`Format`,plan:`Plan`,apiKey:`API Key`,apiKeyPlaceholder:`Enter API Key`,connect:`Connect`,testing:`Testing`,connected:`Connected`,test:`Test`,autoConfigured:`Auto-configured based on your client`},r={config:`Model Configuration`,selectProviderFirst:`Please select a provider and plan first`,namePlaceholder:`Enter model name`,contextCustom:`Custom`,contextWindow:`Context Window`},i={deepseekAnthropic:`DeepSeek Compatible (Anthropic)`,thinkingConsistency:`Thinking Consistency`,thinkingConsistencyDesc:`Unified thinking param injection and missing block fill`,orphanToolResult:`Orphan Tool Result`,orphanToolResultDesc:`Clean up orphan tool_result`,deepseekOpenai:`DeepSeek Compatible (OpenAI)`,orphanToolResultOa:`Orphan Tool Result`,orphanToolResultOaDesc:`OpenAI format orphan handling`,general:`General Compatibility`,developerRole:`Developer Role`,developerRoleDesc:`Convert developer role to system`,label:`patches`,sectionTitle:`Patches`,timeoutTitle:`Timeout`,timeoutSeconds:`seconds`},a={control:`Concurrency Control`,optional:`Optional`},o={title:`Model Mappings`,count:`{count} items`},s={title:`Retry Rules`,selectedCount:`{count} selected`,allCreated:`All recommended rules have been created`,selectProviderFirst:`Select a provider to see recommended rules`,configured:`Configured`,general:`General`,fixed:`Fixed`,exponential:`Exponential`,times:`times`},c={title:`Transform Rules`,optional:`Optional`},l={models:`{count} models`,mappings:`{count} mappings`,rules:`{count} rules`,validate:`Validate`,validated:`Validated`,invalid:`Invalid`,saving:`Saving`,saveConfig:`Save Config`},u={selectProvider:`Please select a provider`,fillApiKey:`Please enter API Key`,enableOneModel:`Please enable at least one model`,validationPassed:`Configuration validated`,existingMappingDelete:`Existing mappings can only be deleted from the Model Mappings page`,fillApiKeyFirst:`Please enter API Key first`,injectHeadersJsonError:`Invalid inject headers JSON format`,requestDefaultsJsonError:`Invalid request defaults JSON format`,selectProviderAndPlan:`Please select a provider and plan`,setupCompleteWithErrors:`Quick setup complete! {count} mapping toggle(s) failed`,setupComplete:`Quick setup complete!`,setupFailed:`Quick setup failed`,loadFailed:`Failed to load recommended configuration`},d={selectClient:`Select Client`,configureProvider:`Configure Provider`,modelMappings:`Model Mappings`,retryRules:`Retry Rules`,optional:`Optional`},f={title:e,client:t,provider:n,model:r,patch:i,concurrency:a,mapping:o,retry:s,transform:c,footer:l,messages:u,steps:d};export{t as client,a as concurrency,f as default,l as footer,o as mapping,u as messages,r as model,i as patch,n as provider,s as retry,d as steps,e as title,c as transform};
@@ -0,0 +1 @@
1
+ var e=`快速配置`,t={selectClient:`选择客户端`,claudeCode:`Claude Code`,claudeCodeDesc:`Anthropic 官方 CLI 编程助手`,codex:`Codex CLI`,codexDesc:`OpenAI`,pi:`Pi`,piDesc:`通用编程 Agent 框架`,openaiSdk:`OpenAI SDK`,openaiSdkDesc:`OpenAI API 直接调用`,anthropicSdk:`Anthropic SDK`,anthropicSdkDesc:`Anthropic API 直接调用`,popular:`Popular`,infoBar:`{client} 使用 {format}。我们会自动映射 {models} 到你的供应商模型。`},n={connection:`供应商配置`,config:`供应商配置`,label:`供应商`,groupLabel:`供应商`,endpoint:`端点`,baseUrl:`Base URL`,upstreamPath:`Upstream Path`,select:`选择`,custom:`自定义`,customProvider:`自定义供应商`,format:`格式`,plan:`套餐`,apiKey:`API Key`,apiKeyPlaceholder:`输入 API Key`,connect:`连接`,testing:`测试中`,connected:`已连接`,test:`测试`,autoConfigured:`根据客户端自动配置`},r={config:`模型配置`,selectProviderFirst:`请先选择供应商与套餐`,namePlaceholder:`输入模型名称`,contextCustom:`自定义`,contextWindow:`上下文窗口`},i={deepseekAnthropic:`DeepSeek 兼容 (Anthropic)`,thinkingConsistency:`Thinking 一致性`,thinkingConsistencyDesc:`统一处理 thinking 参数注入和缺失补全`,orphanToolResult:`孤儿 Tool Result`,orphanToolResultDesc:`清理孤儿 tool_result`,deepseekOpenai:`DeepSeek 兼容 (OpenAI)`,orphanToolResultOa:`孤儿 Tool Result`,orphanToolResultOaDesc:`OpenAI 格式孤儿处理`,general:`通用兼容`,developerRole:`Developer Role`,developerRoleDesc:`developer role 转 system`,label:`补丁`,sectionTitle:`补丁`,timeoutTitle:`超时`,timeoutSeconds:`秒`},a={control:`并发控制`,optional:`可选`},o={title:`模型映射`,count:`{count} 条`},s={title:`重试规则`,selectedCount:`{count} 条已选`,allCreated:`所有推荐规则已创建,无需重复添加`,selectProviderFirst:`选择供应商后显示推荐规则`,configured:`已配置`,general:`通用`,fixed:`固定`,exponential:`指数退避`,times:`次`},c={title:`转换规则`,optional:`可选`},l={models:`{count} 模型`,mappings:`{count} 映射`,rules:`{count} 规则`,validate:`验证`,validated:`已验证`,invalid:`无效`,saving:`保存中`,saveConfig:`保存配置`},u={selectProvider:`请选择供应商`,fillApiKey:`请填写 API Key`,enableOneModel:`至少启用一个模型`,validationPassed:`配置验证通过`,existingMappingDelete:`已有映射请到"模型映射"页面删除`,fillApiKeyFirst:`请先填写 API Key`,injectHeadersJsonError:`注入 Headers JSON 格式错误`,requestDefaultsJsonError:`请求默认值 JSON 格式错误`,selectProviderAndPlan:`请选择供应商和套餐`,setupCompleteWithErrors:`快速配置完成!{count} 个映射状态切换失败`,setupComplete:`快速配置完成!`,setupFailed:`快速配置失败`,loadFailed:`加载推荐配置失败`},d={selectClient:`选择客户端`,configureProvider:`配置供应商`,modelMappings:`模型映射`,retryRules:`重试规则`,optional:`可选`},f={title:e,client:t,provider:n,model:r,patch:i,concurrency:a,mapping:o,retry:s,transform:c,footer:l,messages:u,steps:d};export{t as client,a as concurrency,f as default,l as footer,o as mapping,u as messages,r as model,i as patch,n as provider,s as retry,d as steps,e as title,c as transform};
@@ -0,0 +1 @@
1
+ var e=`Client Request`,t=`Upstream Request`,n=`No request data available`,r=`Request in progress, upstream content will be shown after mapping completes`,i=`Model Mapping`,a=`System`,o=`Messages ({count})`,s=`Modified`,c=`{count} tool result(s)`,l=`tools: {count}`,u=`Stream Options`,d=`Injected`,f=`Auth Replacement`,p=`Request Overview`,m=`In Progress`,h=`Failed`,g=`Completed`,_=`Non-streaming`,v=`Latency`,y=`TTFT`,b=`Est Input Tokens`,x=`Input Tokens`,S=`Output Tokens`,C=`Speed (tok/s)`,w=`Cache Read`,T=`Attempt History`,E=`No retries`,D=`Status Code`,O=`Client Type`,k=`Upstream API Type`,A=`Upstream Base URL`,j=`Cache Source`,M=`API Reported`,N=`Estimated (Prefix Match)`,P=`Client IP`,F=`Reply`,I=`Thinking`,L=`Tool Use`,R=`Tool Result`,z=`{count} characters`,B=`(Waiting for data...)`,V=`(No return data)`,H=`Request Details`,U=`View response content and request content`,W=`Response`,G=`Request`,K=`Loading...`,q=`No request selected`,J=`Response Content`,Y=`Waiting for response...`,X=`Stream response content not persisted`,Z=`No response content`,Q=`unknown`,$=`Raw SSE Text`,ee=`Value`,te=`+{count} delta events collapsed`,ne=`thinking: {count} tokens`,re=`Raw Data`,ie=`Raw JSON`,ae=`Raw SSE`,oe=`Structured`,se={direct_format:`Direct Format`,group_base_rule:`Base Rule`,group_schedule:`Scheduled Rule`,fallback_provider:`Provider Match`,overflow_redirect:`Overflow Redirect`,failover_retry:`Failover Retry`},ce=`Execution Chain`,le=`retry`,ue=`final`,de=`first`,fe={clientRequest:e,upstreamRequest:t,noRequestData:n,requestInProgress:r,modelMapping:i,system:a,messagesCount:o,modified:s,toolResultCount:c,toolsCount:l,streamOptions:u,injected:d,authReplacement:f,overviewTitle:p,pending:m,failed:h,completed:g,nonStream:_,latency:v,ttft:y,estInputTokens:b,inputTokens:x,outputTokens:S,speed:C,cacheRead:w,attemptHistory:T,noRetry:E,statusCodeLabel:D,clientType:O,upstreamApiType:k,upstreamBaseUrl:A,cacheSource:j,cacheSourceApi:M,cacheSourceEstimated:N,clientIp:P,reply:F,thinking:I,toolUse:L,toolResultLabel:R,charCount:z,waitingData:B,noReturnData:V,dialogTitle:H,dialogDescription:U,responseTab:W,requestTab:G,loading:K,noSelectedRequest:q,responseTitle:J,waitingResponse:Y,streamNotPersisted:X,noResponseContent:Z,unknownProvider:Q,rawSseText:$,value:ee,collapsedEvents:te,thinkingTokens:ne,rawData:re,rawJson:ie,rawSse:ae,structured:oe,mappingReason:se,executionChain:ce,executionRetry:le,executionFinal:ue,firstExecution:de};export{T as attemptHistory,f as authReplacement,w as cacheRead,j as cacheSource,M as cacheSourceApi,N as cacheSourceEstimated,z as charCount,P as clientIp,e as clientRequest,O as clientType,te as collapsedEvents,g as completed,fe as default,U as dialogDescription,H as dialogTitle,b as estInputTokens,ce as executionChain,ue as executionFinal,le as executionRetry,h as failed,de as firstExecution,d as injected,x as inputTokens,v as latency,K as loading,se as mappingReason,o as messagesCount,i as modelMapping,s as modified,n as noRequestData,Z as noResponseContent,E as noRetry,V as noReturnData,q as noSelectedRequest,_ as nonStream,S as outputTokens,p as overviewTitle,m as pending,re as rawData,ie as rawJson,ae as rawSse,$ as rawSseText,F as reply,r as requestInProgress,G as requestTab,W as responseTab,J as responseTitle,C as speed,D as statusCodeLabel,X as streamNotPersisted,u as streamOptions,oe as structured,a as system,I as thinking,ne as thinkingTokens,c as toolResultCount,R as toolResultLabel,L as toolUse,l as toolsCount,y as ttft,Q as unknownProvider,k as upstreamApiType,A as upstreamBaseUrl,t as upstreamRequest,ee as value,B as waitingData,Y as waitingResponse};
@@ -0,0 +1 @@
1
+ var e=`客户端请求`,t=`上游请求`,n=`无请求数据`,r=`请求进行中,上游请求内容将在映射完成后显示`,i=`模型映射`,a=`系统`,o=`消息 ({count})`,s=`已修改`,c=`{count} 个工具结果`,l=`tools: {count} 个`,u=`流选项`,d=`已注入`,f=`认证替换`,p=`请求概览`,m=`进行中`,h=`失败`,g=`已完成`,_=`非流式`,v=`耗时`,y=`TTFT`,b=`估算输入 Token`,x=`输入 Token`,S=`输出 Token`,C=`速度 (tok/s)`,w=`缓存读取`,T=`尝试历史`,E=`无重试`,D=`状态码`,O=`客户端类型`,k=`缓存命中来源`,A=`API 上报`,j=`预估(前缀匹配)`,M=`Client IP`,N=`上游 API 类型`,P=`上游 Base URL`,F=`回复`,I=`思考`,L=`工具调用`,R=`工具结果`,z=`{count} 字符`,B=`(等待数据...)`,V=`(无返回数据)`,H=`请求详情`,U=`查看请求的响应内容和请求内容`,W=`响应内容`,G=`请求内容`,K=`加载中...`,q=`无选中请求`,J=`响应内容`,Y=`等待响应数据...`,X=`流式响应内容未持久化存储`,Z=`无响应内容`,Q=`unknown`,$=`原始 SSE 文本`,ee=`Value`,te=`+{count} 个 delta 事件已折叠`,ne=`thinking: {count} tokens`,re=`原始数据`,ie=`原始 JSON`,ae=`原始 SSE`,oe=`结构化`,se={direct_format:`直接指定`,group_base_rule:`基础规则`,group_schedule:`分时段规则`,fallback_provider:`Provider 匹配`,overflow_redirect:`溢出重定向`,failover_retry:`Failover 重试`},ce=`执行链`,le=`重试`,ue=`最终`,de=`首次执行`,fe={clientRequest:e,upstreamRequest:t,noRequestData:n,requestInProgress:r,modelMapping:i,system:a,messagesCount:o,modified:s,toolResultCount:c,toolsCount:l,streamOptions:u,injected:d,authReplacement:f,overviewTitle:p,pending:m,failed:h,completed:g,nonStream:_,latency:v,ttft:y,estInputTokens:b,inputTokens:x,outputTokens:S,speed:C,cacheRead:w,attemptHistory:T,noRetry:E,statusCodeLabel:D,clientType:O,cacheSource:k,cacheSourceApi:A,cacheSourceEstimated:j,clientIp:M,upstreamApiType:N,upstreamBaseUrl:P,reply:F,thinking:I,toolUse:L,toolResultLabel:R,charCount:z,waitingData:B,noReturnData:V,dialogTitle:H,dialogDescription:U,responseTab:W,requestTab:G,loading:K,noSelectedRequest:q,responseTitle:J,waitingResponse:Y,streamNotPersisted:X,noResponseContent:Z,unknownProvider:Q,rawSseText:$,value:ee,collapsedEvents:te,thinkingTokens:ne,rawData:re,rawJson:ie,rawSse:ae,structured:oe,mappingReason:se,executionChain:ce,executionRetry:le,executionFinal:ue,firstExecution:de};export{T as attemptHistory,f as authReplacement,w as cacheRead,k as cacheSource,A as cacheSourceApi,j as cacheSourceEstimated,z as charCount,M as clientIp,e as clientRequest,O as clientType,te as collapsedEvents,g as completed,fe as default,U as dialogDescription,H as dialogTitle,b as estInputTokens,ce as executionChain,ue as executionFinal,le as executionRetry,h as failed,de as firstExecution,d as injected,x as inputTokens,v as latency,K as loading,se as mappingReason,o as messagesCount,i as modelMapping,s as modified,n as noRequestData,Z as noResponseContent,E as noRetry,V as noReturnData,q as noSelectedRequest,_ as nonStream,S as outputTokens,p as overviewTitle,m as pending,re as rawData,ie as rawJson,ae as rawSse,$ as rawSseText,F as reply,r as requestInProgress,G as requestTab,W as responseTab,J as responseTitle,C as speed,D as statusCodeLabel,X as streamNotPersisted,u as streamOptions,oe as structured,a as system,I as thinking,ne as thinkingTokens,c as toolResultCount,R as toolResultLabel,L as toolUse,l as toolsCount,y as ttft,Q as unknownProvider,N as upstreamApiType,P as upstreamBaseUrl,t as upstreamRequest,ee as value,B as waitingData,Y as waitingResponse};
@@ -0,0 +1 @@
1
+ var e=`API Keys`,t=`创建密钥`,n=`编辑密钥`,r=`密钥已创建`,i=`此密钥仅显示一次,请立即复制保存。`,a=`显示`,o=`隐藏`,s=`搜索名称或密钥...`,c=`密钥总数`,l=`活跃`,u=`有白名单`,d=`过滤模型...`,f={name:`名称`,key:`密钥`,whitelist:`白名单`,status:`状态`,createdAt:`创建时间`,actions:`操作`},p=`暂无密钥`,m=`点击上方按钮创建第一个 API 密钥`,h=`没有匹配的密钥`,g=`确认删除`,_=`确定要删除密钥「{name}」吗?使用此密钥的所有请求将被拒绝,此操作不可撤销。`,v=`白名单模型`,y=`不勾选 = 允许所有模型`,b=`暂无可用模型,请先配置模型映射`,x={name:`例如:Production`},S=`加载 API 密钥失败,请检查连接后重试`,C=`保存密钥失败,名称需唯一且至少 1 个字符`,w=`删除密钥失败,请稍后重试`,T=`请输入名称`,E=`切换状态失败`,D=`+{count}`,O={title:e,createKey:t,editKey:n,keyCreated:r,keyShownOnce:i,showKey:a,hideKey:o,searchPlaceholder:s,statTotal:c,statActive:l,statWhitelist:u,modelFilterPlaceholder:d,tableHeaders:f,noKeys:p,noKeysHint:m,noMatch:h,confirmDeleteTitle:g,confirmDeleteDesc:_,whitelistLabel:v,whitelistHint:y,noModels:b,placeholder:x,loadFailed:S,saveFailed:C,deleteFailed:w,nameRequired:T,toggleActiveFailed:E,moreModels:D};export{_ as confirmDeleteDesc,g as confirmDeleteTitle,t as createKey,O as default,w as deleteFailed,n as editKey,o as hideKey,r as keyCreated,i as keyShownOnce,S as loadFailed,d as modelFilterPlaceholder,D as moreModels,T as nameRequired,p as noKeys,m as noKeysHint,h as noMatch,b as noModels,x as placeholder,C as saveFailed,s as searchPlaceholder,a as showKey,l as statActive,c as statTotal,u as statWhitelist,f as tableHeaders,e as title,E as toggleActiveFailed,y as whitelistHint,v as whitelistLabel};
@@ -0,0 +1 @@
1
+ var e=`API Keys`,t=`Create Key`,n=`Edit Key`,r=`Key Created`,i=`This key is shown only once. Copy it now.`,a=`Show`,o=`Hide`,s=`Search by name or key...`,c=`Total Keys`,l=`Active`,u=`With Whitelist`,d=`Filter models...`,f={name:`Name`,key:`Key`,whitelist:`Whitelist`,status:`Status`,createdAt:`Created`,actions:`Actions`},p=`No API keys yet`,m=`Click the button above to create your first API key`,h=`No matching keys`,g=`Confirm Delete`,_=`Are you sure you want to delete key "{name}"? All requests using this key will be rejected. This action cannot be undone.`,v=`Model Whitelist`,y=`Leave empty to allow all models`,b=`No models available. Configure model mappings first`,x={name:`e.g. Production`},S=`Failed to load API keys. Check your connection and try again.`,C=`Failed to save API key. The name must be unique and at least 1 character.`,w=`Failed to delete API key. Try again or check if the key is in use.`,T=`Please enter a name`,E=`Failed to toggle key status`,D=`+{count}`,O={title:e,createKey:t,editKey:n,keyCreated:r,keyShownOnce:i,showKey:a,hideKey:o,searchPlaceholder:s,statTotal:c,statActive:l,statWhitelist:u,modelFilterPlaceholder:d,tableHeaders:f,noKeys:p,noKeysHint:m,noMatch:h,confirmDeleteTitle:g,confirmDeleteDesc:_,whitelistLabel:v,whitelistHint:y,noModels:b,placeholder:x,loadFailed:S,saveFailed:C,deleteFailed:w,nameRequired:T,toggleActiveFailed:E,moreModels:D};export{_ as confirmDeleteDesc,g as confirmDeleteTitle,t as createKey,O as default,w as deleteFailed,n as editKey,o as hideKey,r as keyCreated,i as keyShownOnce,S as loadFailed,d as modelFilterPlaceholder,D as moreModels,T as nameRequired,p as noKeys,m as noKeysHint,h as noMatch,b as noModels,x as placeholder,C as saveFailed,s as searchPlaceholder,a as showKey,l as statActive,c as statTotal,u as statWhitelist,f as tableHeaders,e as title,E as toggleActiveFailed,y as whitelistHint,v as whitelistLabel};
@@ -1 +1 @@
1
- var e=`Time-based Mapping`,t=`Configure time-based mapping rules for mapping groups to use different models and concurrency settings in different time periods`,n=`Select Mapping Group`,r=`Please select a mapping group`,i=`Time Rules`,a=`New Rule`,o=`Edit Rule`,s={name:`Name`,status:`Status`,week:`Day of Week`,timeRange:`Time Range`,actions:`Actions`},c=`Enabled`,l=`Disabled`,u=`No time rules yet. Click "New Rule" to add one`,d=`Not configured`,f=`No mapping groups yet. Create one on the Model Mappings page first`,p=`{count} rules`,m=`Please select a mapping group first`,h={label:`Quick Select`,morning:`Morning`,afternoon:`Afternoon`,evening:`Evening`},g={name:`Name`,namePlaceholder:`e.g., Weekday Daytime`,nameRequired:`Please enter a name`,week:`Applicable Days`,weekRequired:`Please select at least one day`,startTime:`Start Time`,endTime:`End Time`,selectHour:`Select hour`,timeInvalid:`Start time must be earlier than end time`,targets:`Mapping Targets`,selectModel:`Select model...`,targetRequired:`Each target must have a model selected`,addTarget:`Add Target`,concurrencyTitle:`Concurrency Settings (Optional)`},_={sun:`Sun`,mon:`Mon`,tue:`Tue`,wed:`Wed`,thu:`Thu`,fri:`Fri`,sat:`Sat`},v=`Confirm Delete`,y=`Are you sure you want to delete rule "{name}"? This action cannot be undone.`,b=`Failed to load mapping groups`,x=`Failed to load providers`,S=`Failed to load rules`,C=`Failed to save rule`,w=`Failed to toggle status`,T=`Failed to delete rule`,E=`Invalid rule format, using defaults`,D=`Invalid week format, using defaults`,O=`Invalid concurrency format, using defaults`,k=`Invalid transform format, using defaults`,A={title:e,description:t,selectGroup:n,selectGroupPlaceholder:r,scheduleRules:i,createSchedule:a,editSchedule:o,tableHeaders:s,enabled:c,disabled:l,emptyRules:u,noRules:d,noGroups:f,ruleCount:p,pleaseSelectGroup:m,timePresets:h,form:g,weekDays:_,confirmDeleteTitle:v,confirmDeleteMessage:y,loadGroupsFailed:b,loadProvidersFailed:x,loadSchedulesFailed:S,saveFailed:C,toggleFailed:w,deleteFailed:T,parseRuleFailed:E,parseWeekFailed:D,parseConcurrencyFailed:O,parseTransformFailed:k};export{y as confirmDeleteMessage,v as confirmDeleteTitle,a as createSchedule,A as default,T as deleteFailed,t as description,l as disabled,o as editSchedule,u as emptyRules,c as enabled,g as form,b as loadGroupsFailed,x as loadProvidersFailed,S as loadSchedulesFailed,f as noGroups,d as noRules,O as parseConcurrencyFailed,E as parseRuleFailed,k as parseTransformFailed,D as parseWeekFailed,m as pleaseSelectGroup,p as ruleCount,C as saveFailed,i as scheduleRules,n as selectGroup,r as selectGroupPlaceholder,s as tableHeaders,h as timePresets,e as title,w as toggleFailed,_ as weekDays};
1
+ var e=`Time-based Mapping`,t=`Configure time-based mapping rules for mapping groups to use different models and concurrency settings in different time periods`,n=`Select Mapping Group`,r=`Please select a mapping group`,i=`Time Rules`,a=`New Rule`,o=`Edit Rule`,s={name:`Name`,status:`Status`,week:`Day of Week`,timeRange:`Time Range`,actions:`Actions`},c=`Enabled`,l=`Disabled`,u=`No time rules yet. Click "New Rule" to add one`,d=`Not configured`,f=`No mapping groups yet. Create one on the Model Mappings page first`,p=`{count} rules`,m=`Please select a mapping group first`,h={label:`Quick Select`,morning:`Morning`,afternoon:`Afternoon`,evening:`Evening`},g={name:`Name`,namePlaceholder:`e.g., Weekday Daytime`,nameRequired:`Please enter a name`,week:`Applicable Days`,weekRequired:`Please select at least one day`,startTime:`Start Time`,endTime:`End Time`,selectHour:`Select hour`,timeInvalid:`Start time must be earlier than end time`,targets:`Mapping Targets`,selectModel:`Select model...`,targetRequired:`Each target must have a model selected`,addTarget:`Add Target`,concurrencyTitle:`Concurrency Settings (Optional)`},_={sun:`Sun`,mon:`Mon`,tue:`Tue`,wed:`Wed`,thu:`Thu`,fri:`Fri`,sat:`Sat`},v=`Confirm Delete`,y=`Are you sure you want to delete rule "{name}"? This action cannot be undone.`,b=`Failed to load mapping groups`,x=`Failed to load providers`,S=`Failed to load rules`,C=`Failed to save rule`,w=`Failed to toggle status`,T=`Failed to delete rule`,E=`Invalid rule format, using defaults`,D=`Invalid week format, using defaults`,O=`Invalid concurrency format, using defaults`,k=`Invalid transform format, using defaults`,A=`Weekly Timeline`,j={groups:`Groups`,active:`Active Rules`,inactive:`Inactive Rules`,coveredDays:`Days Covered`},M={title:e,description:t,selectGroup:n,selectGroupPlaceholder:r,scheduleRules:i,createSchedule:a,editSchedule:o,tableHeaders:s,enabled:c,disabled:l,emptyRules:u,noRules:d,noGroups:f,ruleCount:p,pleaseSelectGroup:m,timePresets:h,form:g,weekDays:_,confirmDeleteTitle:v,confirmDeleteMessage:y,loadGroupsFailed:b,loadProvidersFailed:x,loadSchedulesFailed:S,saveFailed:C,toggleFailed:w,deleteFailed:T,parseRuleFailed:E,parseWeekFailed:D,parseConcurrencyFailed:O,parseTransformFailed:k,weekTimeline:A,stats:j};export{y as confirmDeleteMessage,v as confirmDeleteTitle,a as createSchedule,M as default,T as deleteFailed,t as description,l as disabled,o as editSchedule,u as emptyRules,c as enabled,g as form,b as loadGroupsFailed,x as loadProvidersFailed,S as loadSchedulesFailed,f as noGroups,d as noRules,O as parseConcurrencyFailed,E as parseRuleFailed,k as parseTransformFailed,D as parseWeekFailed,m as pleaseSelectGroup,p as ruleCount,C as saveFailed,i as scheduleRules,n as selectGroup,r as selectGroupPlaceholder,j as stats,s as tableHeaders,h as timePresets,e as title,w as toggleFailed,_ as weekDays,A as weekTimeline};
@@ -0,0 +1 @@
1
+ var e=`分时段映射`,t=`为映射组配置分时段映射规则,在不同时间段使用不同的模型和并发配置`,n=`选择映射组`,r=`请选择映射组`,i=`时段规则`,a=`新建时段`,o=`编辑时段`,s={name:`名称`,status:`状态`,week:`星期`,timeRange:`时间段`,targets:`目标`,actions:`操作`},c=`启用`,l=`禁用`,u=`暂无时段规则,点击「新建时段」添加`,d=`未配置`,f=`暂无映射组,请先在模型映射页面创建`,p=`{count} 条规则`,m=`每天`,h=`周一~周五`,g=`周六~周日`,_=`请先选择一个映射组`,v={label:`快捷选择`,morning:`上午`,afternoon:`下午`,evening:`晚上`},y={name:`名称`,namePlaceholder:`例如:工作日白天`,nameRequired:`请输入名称`,week:`适用星期`,weekRequired:`至少选择一天`,startTime:`开始时间`,endTime:`结束时间`,selectHour:`选择小时`,timeInvalid:`开始时间必须小于结束时间`,targets:`映射目标`,selectModel:`选择模型...`,targetRequired:`每个目标必须选择模型`,addTarget:`添加目标`,concurrencyTitle:`并发配置(可选)`},b={sun:`周日`,mon:`周一`,tue:`周二`,wed:`周三`,thu:`周四`,fri:`周五`,sat:`周六`},x=`确认删除`,S=`确定要删除时段「{name}」吗?此操作不可撤销。`,C=`加载映射组失败`,w=`加载供应商失败`,T=`加载时段失败`,E=`保存时段失败`,D=`切换状态失败`,O=`删除时段失败`,k=`路由规则格式异常,已使用默认值`,A=`工作日格式异常,已使用默认工作日`,j=`并发规则格式异常,已使用默认配置`,M=`转换规则格式异常,已使用默认配置`,N={groupCount:`映射组`,activeRules:`活跃规则`,disabledRules:`停用规则`,coveredDays:`覆盖天数`},P={title:e,description:t,selectGroup:n,selectGroupPlaceholder:r,scheduleRules:i,createSchedule:a,editSchedule:o,tableHeaders:s,enabled:c,disabled:l,emptyRules:u,noRules:d,noGroups:f,ruleCount:p,everyDay:m,weekdays:h,weekend:g,pleaseSelectGroup:_,timePresets:v,form:y,weekDays:b,confirmDeleteTitle:x,confirmDeleteMessage:S,loadGroupsFailed:C,loadProvidersFailed:w,loadSchedulesFailed:T,saveFailed:E,toggleFailed:D,deleteFailed:O,parseRuleFailed:k,parseWeekFailed:A,parseConcurrencyFailed:j,parseTransformFailed:M,"timeline.weekView":`一周时间线`,stats:N};export{S as confirmDeleteMessage,x as confirmDeleteTitle,a as createSchedule,P as default,O as deleteFailed,t as description,l as disabled,o as editSchedule,u as emptyRules,c as enabled,m as everyDay,y as form,C as loadGroupsFailed,w as loadProvidersFailed,T as loadSchedulesFailed,f as noGroups,d as noRules,j as parseConcurrencyFailed,k as parseRuleFailed,M as parseTransformFailed,A as parseWeekFailed,_ as pleaseSelectGroup,p as ruleCount,E as saveFailed,i as scheduleRules,n as selectGroup,r as selectGroupPlaceholder,N as stats,s as tableHeaders,v as timePresets,e as title,D as toggleFailed,b as weekDays,h as weekdays,g as weekend};
@@ -0,0 +1 @@
1
+ import{L as e}from"./button-DXlWUlLe.js";var t=e(`search`,[[`path`,{d:`m21 21-4.34-4.34`,key:`14j7rj`}],[`circle`,{cx:`11`,cy:`11`,r:`8`,key:`4ej97u`}]]);export{t};
@@ -1 +1 @@
1
- import{L as e}from"./button-CiJBAzrS.js";var t=e(`sparkles`,[[`path`,{d:`M11.017 2.814a1 1 0 0 1 1.966 0l1.051 5.558a2 2 0 0 0 1.594 1.594l5.558 1.051a1 1 0 0 1 0 1.966l-5.558 1.051a2 2 0 0 0-1.594 1.594l-1.051 5.558a1 1 0 0 1-1.966 0l-1.051-5.558a2 2 0 0 0-1.594-1.594l-5.558-1.051a1 1 0 0 1 0-1.966l5.558-1.051a2 2 0 0 0 1.594-1.594z`,key:`1s2grr`}],[`path`,{d:`M20 2v4`,key:`1rf3ol`}],[`path`,{d:`M22 4h-4`,key:`gwowj6`}],[`circle`,{cx:`4`,cy:`20`,r:`2`,key:`6kqj1y`}]]);export{t};
1
+ import{L as e}from"./button-DXlWUlLe.js";var t=e(`sparkles`,[[`path`,{d:`M11.017 2.814a1 1 0 0 1 1.966 0l1.051 5.558a2 2 0 0 0 1.594 1.594l5.558 1.051a1 1 0 0 1 0 1.966l-5.558 1.051a2 2 0 0 0-1.594 1.594l-1.051 5.558a1 1 0 0 1-1.966 0l-1.051-5.558a2 2 0 0 0-1.594-1.594l-5.558-1.051a1 1 0 0 1 0-1.966l5.558-1.051a2 2 0 0 0 1.594-1.594z`,key:`1s2grr`}],[`path`,{d:`M20 2v4`,key:`1rf3ol`}],[`path`,{d:`M22 4h-4`,key:`gwowj6`}],[`circle`,{cx:`4`,cy:`20`,r:`2`,key:`6kqj1y`}]]);export{t};
@@ -0,0 +1 @@
1
+ import{Gt as e,H as t,X as n,Xt as r,Z as i,et as a,gt as o,it as s,kt as c,nt as l,qt as u,rt as d}from"./button-DXlWUlLe.js";import{t as f}from"./Label-CgLYbqNp.js";import{t as p}from"./Input-Qz28j7do.js";var m={mode:`auto`,max_concurrency:10,queue_timeout_ms:12e4,max_queue_size:100},h={mode:`manual`,max_concurrency:3,queue_timeout_ms:12e4,max_queue_size:10},g={injectHeaders:``,dropFields:``,requestDefaults:``},_={proxyType:``,proxyUrl:``,proxyUsername:``,proxyPassword:``},v=s({__name:`TransformRulesForm`,props:{modelValue:{},compact:{type:Boolean}},emits:[`update:modelValue`],setup(s,{emit:m}){let h=s,_=m,{t:v}=t();function y(e){_(`update:modelValue`,{...h.modelValue,...e})}let b=n(()=>h.modelValue.injectHeaders??g.injectHeaders),x=n(()=>h.modelValue.dropFields??g.dropFields),S=n(()=>h.modelValue.requestDefaults??g.requestDefaults);return(t,n)=>(o(),a(`div`,{class:u(s.compact?`space-y-2`:`space-y-3`)},[i(`div`,null,[d(e(f),{class:`text-[11px] text-muted-foreground`},{default:c(()=>[l(r(e(v)(`providers.transform.injectHeaders`)),1)]),_:1}),d(e(p),{"model-value":b.value,placeholder:`{"x-custom": "value"}`,class:`mt-0.5 md:text-xs font-mono`,"onUpdate:modelValue":n[0]||=e=>y({injectHeaders:e})},null,8,[`model-value`])]),i(`div`,null,[d(e(f),{class:`text-[11px] text-muted-foreground`},{default:c(()=>[l(r(e(v)(`providers.transform.dropFields`)),1)]),_:1}),d(e(p),{"model-value":x.value,placeholder:`logprobs, frequency_penalty`,class:`mt-0.5 md:text-xs font-mono`,"onUpdate:modelValue":n[1]||=e=>y({dropFields:e})},null,8,[`model-value`])]),i(`div`,null,[d(e(f),{class:`text-[11px] text-muted-foreground`},{default:c(()=>[l(r(e(v)(`providers.transform.requestDefaults`)),1)]),_:1}),d(e(p),{"model-value":S.value,placeholder:`{"max_tokens": 4096}`,class:`mt-0.5 md:text-xs font-mono`,"onUpdate:modelValue":n[2]||=e=>y({requestDefaults:e})},null,8,[`model-value`])])],2))}});function y(e){let{injectHeaders:t,dropFields:n,requestDefaults:r}=e;if(!t.trim()&&!n.trim()&&!r.trim())return{rule:null,errorKey:null};let i=n?n.split(`,`).map(e=>e.trim()).filter(Boolean):null,a=null;if(r.trim())try{a=JSON.parse(r)}catch{return{rule:null,errorKey:`requestDefaultsJsonError`}}let o=null;if(t.trim())try{o=JSON.parse(t)}catch{return{rule:null,errorKey:`injectHeadersJsonError`}}return{rule:JSON.stringify({drop_fields:i,request_defaults:a,inject_headers:o}),errorKey:null}}export{_ as a,h as i,v as n,g as o,m as r,y as t};
@@ -1 +1 @@
1
- import{L as e}from"./button-CiJBAzrS.js";var t=e(`trash-2`,[[`path`,{d:`M10 11v6`,key:`nco0om`}],[`path`,{d:`M14 11v6`,key:`outv1u`}],[`path`,{d:`M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6`,key:`miytrc`}],[`path`,{d:`M3 6h18`,key:`d0wm0j`}],[`path`,{d:`M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2`,key:`e791ji`}]]);export{t};
1
+ import{L as e}from"./button-DXlWUlLe.js";var t=e(`trash-2`,[[`path`,{d:`M10 11v6`,key:`nco0om`}],[`path`,{d:`M14 11v6`,key:`outv1u`}],[`path`,{d:`M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6`,key:`miytrc`}],[`path`,{d:`M3 6h18`,key:`d0wm0j`}],[`path`,{d:`M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2`,key:`e791ji`}]]);export{t};
@@ -0,0 +1 @@
1
+ import{L as e,Lt as t}from"./button-DXlWUlLe.js";var n=e(`copy`,[[`rect`,{width:`14`,height:`14`,x:`8`,y:`8`,rx:`2`,ry:`2`,key:`17jyea`}],[`path`,{d:`M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2`,key:`zix9uf`}]]),r=2e3;function i(){let e=t(!1);async function n(t){try{return navigator.clipboard?.writeText?await navigator.clipboard.writeText(t):a(t),e.value=!0,setTimeout(()=>{e.value=!1},r),!0}catch{try{return a(t),e.value=!0,setTimeout(()=>{e.value=!1},r),!0}catch{return!1}}}return{copied:e,copy:n}}function a(e){let t=document.createElement(`textarea`);if(t.value=e,t.style.cssText=`position:fixed;left:-9999px;opacity:0`,document.body.appendChild(t),t.select(),!document.execCommand(`copy`))throw Error(`execCommand copy failed`);document.body.removeChild(t)}export{n,i as t};
@@ -0,0 +1 @@
1
+ import{A as e,H as t,Lt as n,k as r}from"./button-DXlWUlLe.js";import{a as i}from"./index-FYAc4GSw.js";var a=3;function o(){let{t:o}=t(),s=n(a),c=n(!1);async function l(){c.value=!0;try{s.value=(await r.setLogRetention(s.value)).days,i.success(o(`logs.retention.saved`))}catch(t){console.error(`logRetention.save:`,t),i.error(e(t,o(`logs.retention.updateFailed`)))}finally{c.value=!1}}async function u(){try{let{days:e}=await r.getLogRetention();s.value=e}catch(t){console.error(`logRetention.load:`,t),i.error(e(t,o(`logs.retention.loadFailed`)))}}return{retentionDays:s,retentionSaving:c,saveRetention:l,loadRetention:u}}export{o as t};
@@ -0,0 +1 @@
1
+ import{M as e}from"./button-DXlWUlLe.js";function t(t,n){let{activeOnly:r=!1,includeStreamTimeout:i=!0,defaultContextWindow:a=e}=n??{};return(r?t.filter(e=>e.is_active):t).map(e=>({provider:{id:e.id,name:e.name},models:(e.models??[]).map(e=>{let t={name:e.name,contextWindow:e.context_window??a};return i&&(t.streamTimeoutMs=e.stream_timeout_ms??null),t})}))}export{t};
@@ -6,11 +6,11 @@
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
7
  <link rel="preconnect" href="https://fonts.googleapis.com" />
8
8
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
9
- <link href="https://fonts.googleapis.com/css2?family=Geist:wght@400;500;600;700&display=swap" rel="stylesheet" />
9
+ <link href="https://fonts.googleapis.com/css2?family=Geist:wght@400;500;600;700&display=optional" rel="stylesheet" />
10
10
  <title>LLM Simple Router</title>
11
- <script type="module" crossorigin src="/admin/assets/index-bv08h-oy.js"></script>
12
- <link rel="modulepreload" crossorigin href="/admin/assets/button-CiJBAzrS.js">
13
- <link rel="stylesheet" crossorigin href="/admin/assets/index-B_tA9Si9.css">
11
+ <script type="module" crossorigin src="/admin/assets/index-FYAc4GSw.js"></script>
12
+ <link rel="modulepreload" crossorigin href="/admin/assets/button-DXlWUlLe.js">
13
+ <link rel="stylesheet" crossorigin href="/admin/assets/index-BcYqgllr.css">
14
14
  </head>
15
15
  <body>
16
16
  <div id="app"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "llm-simple-router",
3
- "version": "0.11.30",
3
+ "version": "0.12.0-dev.7cf31a2",
4
4
  "description": "LLM API proxy router with OpenAI/Anthropic support, model mapping, retry strategies, and admin dashboard",
5
5
  "license": "MIT",
6
6
  "author": "ZZzzswszzZZ",
@@ -1 +0,0 @@
1
- import{Gt as e,et as t,gt as n,it as r,qt as i,r as a,yt as o}from"./button-CiJBAzrS.js";var s=[`data-size`],c=r({__name:`Card`,props:{class:{type:[Boolean,null,String,Object,Array]},size:{default:`default`}},setup(r){let c=r;return(l,u)=>(n(),t(`div`,{"data-slot":`card`,"data-size":r.size,class:i(e(a)(`ring-foreground/10 bg-card text-card-foreground gap-4 overflow-hidden rounded-lg py-4 text-sm ring-1 has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:gap-3 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-lg *:[img:last-child]:rounded-b-lg group/card flex flex-col`,c.class))},[o(l.$slots,`default`)],10,s))}}),l=r({__name:`CardContent`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(r){let s=r;return(r,c)=>(n(),t(`div`,{"data-slot":`card-content`,class:i(e(a)(`px-4 group-data-[size=sm]/card:px-3`,s.class))},[o(r.$slots,`default`)],2))}});export{c as n,l as t};
@@ -1 +0,0 @@
1
- import{$ as e,Gt as t,H as n,J as r,L as i,Lt as a,Q as o,X as s,Xt as c,Z as l,et as u,gt as d,it as f,kt as p,qt as m,rt as h,vt as g}from"./button-CiJBAzrS.js";import{b as _,ft as v,ht as y,v as b,y as x}from"./index-bv08h-oy.js";var S=i(`chevron-right`,[[`path`,{d:`m9 18 6-6-6-6`,key:`mthhwq`}]]),C=[`onMouseenter`],w={class:`truncate max-w-40`},T={key:0,class:`ml-1 text-[10px] px-1 py-px rounded bg-emerald-500/15 text-emerald-400 shrink-0`},E=[`onMouseenter`],D=[`onClick`],O={class:`truncate`},k={key:0,class:`shrink-0 text-xs text-muted-foreground`},A={key:0,class:`px-2 py-1.5 text-sm text-muted-foreground`},j=f({__name:`CascadingSelect`,props:{groups:{},modelValue:{},placeholder:{default:``},compact:{type:Boolean,default:!1}},emits:[`update:modelValue`],setup(i,{emit:f}){let{t:y}=n(),j=i,M=s(()=>j.placeholder||y(`common.selectPlaceholder`)),N=f,P=a(!1),F=a(null),I=s(()=>{if(!j.modelValue)return``;let e=j.groups.find(e=>e.key===j.modelValue.groupKey);if(!e)return``;let t=e.options.find(e=>e.value===j.modelValue.value);return t?`${e.label} / ${t.label}`:``});function L(e,t){N(`update:modelValue`,{groupKey:e,value:t}),P.value=!1}function R(e){P.value=e,e||(F.value=null)}return(n,a)=>(d(),o(t(_),{open:P.value,"onUpdate:open":R},{default:p(()=>[h(t(b),{"as-child":``},{default:p(()=>[l(`div`,{class:m([`flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background cursor-pointer hover:bg-accent hover:text-accent-foreground`,[i.compact?`h-8 text-xs px-2.5 py-1`:`h-10 text-sm px-3 py-2`,{"ring-2 ring-ring ring-offset-2":P.value}]])},[l(`span`,{class:m([`truncate`,i.modelValue?`text-foreground`:`text-muted-foreground`])},c(I.value||M.value),3),h(t(v),{class:`h-4 w-4 shrink-0 opacity-50`})],2)]),_:1}),h(t(x),{align:`start`,"side-offset":4,class:`z-[200] w-auto min-w-56 overflow-visible p-1`},{default:p(()=>[(d(!0),u(r,null,g(i.groups,n=>(d(),u(`div`,{key:n.key,class:m([`relative flex cursor-pointer items-center justify-between rounded-sm px-2 py-1.5 text-sm hover:bg-accent hover:text-accent-foreground`,{"bg-accent text-accent-foreground z-10":F.value===n.key}]),onMouseenter:e=>F.value=n.key},[l(`span`,w,c(n.label),1),n.badge?(d(),u(`span`,T,c(n.badge),1)):e(``,!0),h(t(S),{class:`ml-1 h-4 w-4 shrink-0 opacity-50`}),F.value===n.key&&n.options.length>0?(d(),u(`div`,{key:1,class:`absolute left-full top-0 ml-0.5 min-w-48 rounded-md border bg-popover p-1 text-popover-foreground shadow-md`,onMouseenter:e=>F.value=n.key},[(d(!0),u(r,null,g(n.options,t=>(d(),u(`div`,{key:t.value,class:m([`flex cursor-pointer items-center justify-between gap-2 rounded-sm px-2 py-1.5 text-sm hover:bg-accent hover:text-accent-foreground`,{"bg-accent text-accent-foreground":i.modelValue?.groupKey===n.key&&i.modelValue?.value===t.value}]),onClick:e=>L(n.key,t.value)},[l(`span`,O,c(t.label),1),t.tag?(d(),u(`span`,k,c(t.tag),1)):e(``,!0)],10,D))),128))],40,E)):e(``,!0)],42,C))),128)),i.groups.length===0?(d(),u(`div`,A,c(t(y)(`common.noOptions`)),1)):e(``,!0)]),_:1})]),_:1},8,[`open`]))}}),M=f({__name:`CascadingModelSelect`,props:{providers:{},modelValue:{},placeholder:{default:``},compact:{type:Boolean}},emits:[`update:modelValue`],setup(e,{emit:t}){let{t:r}=n(),i=e,a=s(()=>i.placeholder||r(`mappings.selectProviderModel`)),c=t,l=s(()=>i.providers.map(e=>({key:e.provider.id,label:e.provider.name,badge:e.isNew?r(`common.new`):void 0,options:e.models.map(e=>({value:e.name,label:e.name,tag:y(e.contextWindow)}))}))),u=s(()=>i.modelValue?{groupKey:i.modelValue.provider_id,value:i.modelValue.model}:void 0);function f(e){c(`update:modelValue`,{provider_id:e.groupKey,model:e.value})}return(t,n)=>(d(),o(j,{groups:l.value,"model-value":u.value,placeholder:a.value,compact:e.compact,"onUpdate:modelValue":f},null,8,[`groups`,`model-value`,`placeholder`,`compact`]))}});export{M as t};
@@ -1 +0,0 @@
1
- import{Gt as e,Ht as t,Jt as n,K as r,Lt as i,Q as a,X as o,dt as s,gt as c,i as l,it as u,kt as d,m as f,o as p,ot as m,q as h,r as g,rt as _,x as v,yt as y,zt as b}from"./button-CiJBAzrS.js";import{r as x}from"./CollapsibleContent-Yk-lxVPc.js";import{n as S,t as C}from"./RovingFocusItem-C31XRuKO.js";import{B as w,H as T,J as E,V as D,W as O}from"./index-bv08h-oy.js";var k=u({__name:`CollapsibleTrigger`,props:{asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`button`}},setup(t){let n=t;p();let r=x();return(t,i)=>(c(),a(e(l),{type:t.as===`button`?`button`:void 0,as:t.as,"as-child":n.asChild,"aria-controls":e(r).contentId,"aria-expanded":e(r).open.value,"data-state":e(r).open.value?`open`:`closed`,"data-disabled":e(r).disabled?.value?``:void 0,disabled:e(r).disabled?.value,onClick:e(r).onOpenToggle},{default:d(()=>[y(t.$slots,`default`)]),_:3},8,[`type`,`as`,`as-child`,`aria-controls`,`aria-expanded`,`data-state`,`data-disabled`,`disabled`,`onClick`]))}}),[A,j]=E(`TabsRoot`),M=u({__name:`TabsRoot`,props:{defaultValue:{type:null,required:!1},orientation:{type:String,required:!1,default:`horizontal`},dir:{type:String,required:!1},activationMode:{type:String,required:!1,default:`automatic`},modelValue:{type:null,required:!1},unmountOnHide:{type:Boolean,required:!1,default:!0},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},emits:[`update:modelValue`],setup(n,{emit:r}){let o=n,s=r,{orientation:u,unmountOnHide:m,dir:h}=t(o),g=O(h);p();let _=f(o,`modelValue`,s,{defaultValue:o.defaultValue,passive:o.modelValue===void 0}),v=i(),x=b(new Set);return j({modelValue:_,changeModelValue:e=>{_.value=e},orientation:u,dir:g,unmountOnHide:m,activationMode:o.activationMode,baseId:w(void 0,`reka-tabs`),tabsList:v,contentIds:x,registerContent:e=>{x.value=new Set([...x.value,e])},unregisterContent:e=>{let t=new Set(x.value);t.delete(e),x.value=t}}),(t,n)=>(c(),a(e(l),{dir:e(g),"data-orientation":e(u),"as-child":t.asChild,as:t.as},{default:d(()=>[y(t.$slots,`default`,{modelValue:e(_)})]),_:3},8,[`dir`,`data-orientation`,`as-child`,`as`]))}});function N(e,t){return`${e}-trigger-${t}`}function P(e,t){return`${e}-content-${t}`}var F=u({__name:`TabsList`,props:{loop:{type:Boolean,required:!1,default:!0},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},setup(n){let{loop:r}=t(n),{forwardRef:i,currentElement:o}=p(),s=A();return s.tabsList=o,(t,n)=>(c(),a(e(S),{"as-child":``,orientation:e(s).orientation.value,dir:e(s).dir.value,loop:e(r)},{default:d(()=>[_(e(l),{ref:e(i),role:`tablist`,"as-child":t.asChild,as:t.as,"aria-orientation":e(s).orientation.value},{default:d(()=>[y(t.$slots,`default`)]),_:3},8,[`as-child`,`as`,`aria-orientation`])]),_:3},8,[`orientation`,`dir`,`loop`]))}}),I=u({__name:`TabsTrigger`,props:{value:{type:[String,Number],required:!0},disabled:{type:Boolean,required:!1,default:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`button`}},setup(t){let n=t,{forwardRef:i}=p(),s=A(),u=o(()=>N(s.baseId,n.value)),f=o(()=>s.contentIds.value.has(n.value)?P(s.baseId,n.value):void 0),m=o(()=>n.value===s.modelValue.value);return(t,n)=>(c(),a(e(C),{"as-child":``,focusable:!t.disabled,active:m.value},{default:d(()=>[_(e(l),{id:u.value,ref:e(i),role:`tab`,type:t.as===`button`?`button`:void 0,as:t.as,"as-child":t.asChild,"aria-selected":m.value?`true`:`false`,"aria-controls":f.value,"data-state":m.value?`active`:`inactive`,disabled:t.disabled,"data-disabled":t.disabled?``:void 0,"data-orientation":e(s).orientation.value,onMousedown:n[0]||=h(n=>{!t.disabled&&n.ctrlKey===!1?e(s).changeModelValue(t.value):n.preventDefault()},[`left`]),onKeydown:n[1]||=r(n=>e(s).changeModelValue(t.value),[`enter`,`space`]),onFocus:n[2]||=()=>{let n=e(s).activationMode!==`manual`;!m.value&&!t.disabled&&n&&e(s).changeModelValue(t.value)}},{default:d(()=>[y(t.$slots,`default`)]),_:3},8,[`id`,`type`,`as`,`as-child`,`aria-selected`,`aria-controls`,`data-state`,`disabled`,`data-disabled`,`data-orientation`])]),_:3},8,[`focusable`,`active`]))}}),L=u({__name:`Tabs`,props:{defaultValue:{},orientation:{},dir:{},activationMode:{},modelValue:{},unmountOnHide:{type:Boolean},asChild:{type:Boolean},as:{},class:{type:[Boolean,null,String,Object,Array]}},emits:[`update:modelValue`],setup(t,{emit:r}){let i=t,o=r,l=D(v(i,`class`),o);return(t,r)=>(c(),a(e(M),s({"data-slot":`tabs`,"data-orientation":e(l).orientation||`horizontal`},e(l),{class:e(g)(`gap-2 group/tabs flex data-[orientation=horizontal]:flex-col`,i.class)}),{default:d(e=>[y(t.$slots,`default`,n(m(e)))]),_:3},16,[`data-orientation`,`class`]))}}),R=u({__name:`TabsList`,props:{loop:{type:Boolean},asChild:{type:Boolean},as:{},class:{type:[Boolean,null,String,Object,Array]},variant:{default:`default`}},setup(t){let n=t,r=v(n,`class`,`variant`);return(i,o)=>(c(),a(e(F),s({"data-slot":`tabs-list`,"data-variant":t.variant},e(r),{class:e(g)(`rounded-lg p-[3px] group-data-[orientation=horizontal]/tabs:h-8 data-[variant=line]:rounded-none group/tabs-list inline-flex w-fit items-center justify-center text-muted-foreground group-data-[orientation=vertical]/tabs:h-fit group-data-[orientation=vertical]/tabs:flex-col`,t.variant===`default`&&`bg-muted`,t.variant===`line`&&`gap-1 bg-transparent`,n.class)}),{default:d(()=>[y(i.$slots,`default`)]),_:3},16,[`data-variant`,`class`]))}}),z=u({__name:`TabsTrigger`,props:{value:{},disabled:{type:Boolean},asChild:{type:Boolean},as:{},class:{type:[Boolean,null,String,Object,Array]}},setup(t){let n=t,r=T(v(n,`class`));return(t,i)=>(c(),a(e(I),s({"data-slot":`tabs-trigger`,class:e(g)(`gap-1.5 rounded-md border border-transparent px-1.5 py-0.5 text-sm font-medium group-data-[variant=default]/tabs-list:data-[state=active]:shadow-sm group-data-[variant=line]/tabs-list:data-[state=active]:shadow-none [&_svg:not([class*=size-])]:size-4 has-data-[icon=inline-end]:pr-1 has-data-[icon=inline-start]:pl-1 relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center whitespace-nowrap text-foreground/60 transition-all group-data-[orientation=vertical]/tabs:w-full group-data-[orientation=vertical]/tabs:justify-start hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 dark:text-muted-foreground dark:hover:text-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0`,`group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent dark:group-data-[variant=line]/tabs-list:data-[state=active]:border-transparent dark:group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent`,`data-[state=active]:bg-background data-[state=active]:text-foreground dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 dark:data-[state=active]:text-foreground`,`after:absolute after:bg-foreground after:opacity-0 after:transition-opacity group-data-[orientation=horizontal]/tabs:after:inset-x-0 group-data-[orientation=horizontal]/tabs:after:bottom-[-5px] group-data-[orientation=horizontal]/tabs:after:h-0.5 group-data-[orientation=vertical]/tabs:after:inset-y-0 group-data-[orientation=vertical]/tabs:after:-right-1 group-data-[orientation=vertical]/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-[state=active]:after:opacity-100`,n.class)},e(r)),{default:d(()=>[y(t.$slots,`default`)]),_:3},16,[`class`]))}}),B=u({__name:`CollapsibleTrigger`,props:{asChild:{type:Boolean},as:{}},setup(t){let n=t;return(t,r)=>(c(),a(e(k),s({"data-slot":`collapsible-trigger`},n),{default:d(()=>[y(t.$slots,`default`)]),_:3},16))}});export{P as a,L as i,z as n,N as o,R as r,A as s,B as t};