import{n as e}from"./norm-f7iXVy-b.js";import{t}from"./hostPermissions-Daz5S2M5.js";var n=(e,t)=>`${String(e||``).trim().replace(/\/+$/,``)}/${String(t||``).trim().replace(/^\/+/,``)}`,r=()=>String(e()||``).toLowerCase().startsWith(`en`),i=(e,t)=>r()?t:e,a=e=>{let t=String(e||``);try{let e=new URL(t);return[`key`,`api_key`,`apikey`,`access_token`,`token`].forEach(t=>{e.searchParams.has(t)&&e.searchParams.set(t,`***`)}),e.toString()}catch{return t.replace(/([?&](?:key|api_key|apikey|access_token|token)=)[^&]+/gi,`$1***`)}},o=(e,t)=>{let n=String(e?.name||``),r=String(e?.message||e||``).trim();if(n===`AbortError`||/aborted/i.test(r))return Error(i(`已停止`,`Stopped`));if(/failed to fetch/i.test(r)){let e=!(typeof navigator<`u`)||navigator.onLine?i(`无法连接到自定义模型接口（Failed to fetch）`,`Could not connect to the custom model endpoint (Failed to fetch)`):i(`网络不可用（离线）`,`Network unavailable (offline)`),n=i(`：请检查 Base URL、网络/代理、跨域或防火墙。

地址：`,`: check Base URL, network/proxy, CORS, or firewall.

URL: `);return Error(`${e}${n}${a(t).slice(0,160)}`)}return Error(r||i(`自定义模型请求失败`,`Custom model request failed`))},s=e=>{let t=e?.choices?.[0],n=t?.message;return typeof n?.content==`string`?n.content:Array.isArray(n?.content)?n.content.map(e=>typeof e==`string`?e:String(e?.text||e?.content||``)).join(``):typeof t?.text==`string`?t.text:``},c=e=>(Array.isArray(e?.content)?e.content:[]).map(e=>e?.type===`text`?String(e?.text||``):``).filter(Boolean).join(``),l=e=>{let t=e?.candidates?.[0]?.content?.parts;return Array.isArray(t)?t.map(e=>String(e?.text||``)).filter(Boolean).join(``):``},u=e=>{let t=``,n=[];for(let r of String(e||``).split(`
`)){let e=String(r||``).trimEnd();!e||e.startsWith(`:`)||(e.startsWith(`event:`)?t=e.slice(6).trim():e.startsWith(`data:`)&&n.push(e.slice(5).trim()))}return{eventName:t,rawData:n.join(`
`).trim()}},d=(e,t,n,r=``)=>{if(r){t.thinking+=r;try{e.onThinkingDelta?.(r),e.onThinking?.(t.thinking)}catch{}}if(n){t.text+=n;try{e.onTextDelta?.(n),e.onText?.(t.text)}catch{}}},f=async(e,t,n,r)=>{let a=String(e.headers.get(`content-type`)||``);if(!/text\/event-stream/i.test(a)||!e.body?.getReader){let n=await e.text(),a;try{a=n?JSON.parse(n):null}catch{throw Error(i(`自定义模型返回非 JSON 响应`,`Custom model returned a non-JSON response`))}let o=r(a);return o&&d(t,{text:``,thinking:``},o),{text:o,thinking:``}}let o={text:``,thinking:``},s=e.body.getReader(),c=new TextDecoder,l=``,f=e=>{let r=u(e);if(!r.rawData)return!1;if(r.rawData===`[DONE]`||r.eventName===`message_stop`)return!0;let i=null;try{i=JSON.parse(r.rawData)}catch{return!1}let a=i?.error;if(a)throw Error(String(a?.message||a||`stream_error`));let s=n(i,r.eventName);return d(t,o,String(s?.delta||``),String(s?.thinking||``)),!!s?.done};for(;;){let{done:e,value:t}=await s.read();if(e)break;l+=c.decode(t,{stream:!0}).replace(/\r\n/g,`
`);let n=l.split(`

`);l=n.pop()||``;for(let e of n)if(f(e)){try{s.cancel()}catch{}return o}}return l.trim()&&f(l),o},p=async e=>{if(!e?.baseUrl||!e?.apiKey||!e?.modelId)throw Error(i(`自定义模型配置不完整`,`Custom model configuration is incomplete`));try{new URL(e.baseUrl)}catch{throw Error(i(`Base URL 格式无效`,`Invalid Base URL`))}try{if(!await t(e.baseUrl)){let t=new URL(e.baseUrl).origin;throw Error(i(`未授予访问该地址的权限：${t}`,`Permission was not granted for this endpoint: ${t}`))}}catch(e){let t=String(e?.message||e||``);if(/未授予|permission|granted/i.test(t))throw e}},m=async e=>{let{model:t,messages:r,temperature:a,maxTokens:c,responseFormatJson:l,signal:u}=e,d=n(t.baseUrl,`chat/completions`),f={model:t.modelId,messages:r,temperature:typeof a==`number`?a:.3};typeof c==`number`&&c>0&&(f.max_tokens=c),l&&(f.response_format={type:`json_object`});let p;try{p=await fetch(d,{method:`POST`,headers:{"Content-Type":`application/json`,Authorization:`Bearer ${t.apiKey}`},body:JSON.stringify(f),signal:u})}catch(e){throw o(e,d)}let m=await p.text();if(!p.ok){let e=m.slice(0,400);throw Error(i(`自定义模型返回 ${p.status}：${e||p.statusText}`,`Custom model returned ${p.status}: ${e||p.statusText}`))}let h;try{h=m?JSON.parse(m):null}catch{throw Error(i(`自定义模型返回非 JSON 响应`,`Custom model returned a non-JSON response`))}let g=s(h);if(!g)throw Error(i(`自定义模型返回内容为空`,`Custom model returned empty content`));return g},h=async e=>{let{model:t,messages:r,temperature:a,maxTokens:s,signal:l}=e,u=n(t.baseUrl,`v1/messages`),d=r.filter(e=>e.role===`system`).map(e=>e.content).join(`

`).trim(),f=r.filter(e=>e.role!==`system`).map(e=>({role:e.role===`assistant`?`assistant`:`user`,content:e.content})),p={model:t.modelId,max_tokens:typeof s==`number`&&s>0?s:4096,messages:f.length?f:[{role:`user`,content:``}],temperature:typeof a==`number`?a:.3};d&&(p.system=d);let m;try{m=await fetch(u,{method:`POST`,headers:{"Content-Type":`application/json`,"x-api-key":t.apiKey,"anthropic-version":`2023-06-01`,"anthropic-dangerous-direct-browser-access":`true`},body:JSON.stringify(p),signal:l})}catch(e){throw o(e,u)}let h=await m.text();if(!m.ok){let e=h.slice(0,400);throw Error(i(`Anthropic 返回 ${m.status}：${e||m.statusText}`,`Anthropic returned ${m.status}: ${e||m.statusText}`))}let g;try{g=h?JSON.parse(h):null}catch{throw Error(i(`Anthropic 返回非 JSON 响应`,`Anthropic returned a non-JSON response`))}let _=c(g);if(!_)throw Error(i(`Anthropic 返回内容为空`,`Anthropic returned empty content`));return _},g=async e=>{let{model:t,messages:r,temperature:a,maxTokens:s,responseFormatJson:c,signal:u}=e,d=n(t.baseUrl,`v1beta/models/${encodeURIComponent(t.modelId)}:generateContent`)+`?key=${encodeURIComponent(t.apiKey)}`,f=r.filter(e=>e.role===`system`).map(e=>e.content).join(`

`).trim(),p=r.filter(e=>e.role!==`system`).map(e=>({role:e.role===`assistant`?`model`:`user`,parts:[{text:e.content}]})),m={contents:p.length?p:[{role:`user`,parts:[{text:``}]}],generationConfig:{temperature:typeof a==`number`?a:.3,...typeof s==`number`&&s>0?{maxOutputTokens:s}:{},...c?{responseMimeType:`application/json`}:{}}};f&&(m.systemInstruction={parts:[{text:f}]});let h;try{h=await fetch(d,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(m),signal:u})}catch(e){throw o(e,d)}let g=await h.text();if(!h.ok){let e=g.slice(0,400);throw Error(i(`Gemini 返回 ${h.status}：${e||h.statusText}`,`Gemini returned ${h.status}: ${e||h.statusText}`))}let _;try{_=g?JSON.parse(g):null}catch{throw Error(i(`Gemini 返回非 JSON 响应`,`Gemini returned a non-JSON response`))}let v=l(_);if(!v)throw Error(i(`Gemini 返回内容为空`,`Gemini returned empty content`));return v},_=async e=>{let{model:t,messages:r,temperature:a,maxTokens:c,responseFormatJson:l,signal:u}=e,d=n(t.baseUrl,`chat/completions`),p={model:t.modelId,messages:r,stream:!0,temperature:typeof a==`number`?a:.3};typeof c==`number`&&c>0&&(p.max_tokens=c),l&&(p.response_format={type:`json_object`});let m;try{m=await fetch(d,{method:`POST`,headers:{"Content-Type":`application/json`,Authorization:`Bearer ${t.apiKey}`},body:JSON.stringify(p),signal:u})}catch(e){throw o(e,d)}if(!m.ok){let e=(await m.text()).slice(0,400);throw Error(i(`自定义模型返回 ${m.status}：${e||m.statusText}`,`Custom model returned ${m.status}: ${e||m.statusText}`))}return await f(m,e,e=>{let t=Array.isArray(e?.choices)?e.choices[0]:null,n=t?.delta&&typeof t.delta==`object`?t.delta:{};return{delta:String(n?.content??n?.text??``),thinking:String(n?.reasoning_content??n?.reasoning??n?.thinking??``),done:String(t?.finish_reason||``).length>0}},s)},v=async e=>{let{model:t,messages:r,temperature:a,maxTokens:s,signal:l}=e,u=n(t.baseUrl,`v1/messages`),d=r.filter(e=>e.role===`system`).map(e=>e.content).join(`

`).trim(),p=r.filter(e=>e.role!==`system`).map(e=>({role:e.role===`assistant`?`assistant`:`user`,content:e.content})),m={model:t.modelId,stream:!0,max_tokens:typeof s==`number`&&s>0?s:4096,messages:p.length?p:[{role:`user`,content:``}],temperature:typeof a==`number`?a:.3};d&&(m.system=d);let h;try{h=await fetch(u,{method:`POST`,headers:{"Content-Type":`application/json`,"x-api-key":t.apiKey,"anthropic-version":`2023-06-01`,"anthropic-dangerous-direct-browser-access":`true`},body:JSON.stringify(m),signal:l})}catch(e){throw o(e,u)}if(!h.ok){let e=(await h.text()).slice(0,400);throw Error(i(`Anthropic 返回 ${h.status}：${e||h.statusText}`,`Anthropic returned ${h.status}: ${e||h.statusText}`))}return await f(h,e,(e,t)=>{if(t===`message_stop`)return{done:!0};let n=e?.delta&&typeof e.delta==`object`?e.delta:{},r=e?.content_block&&typeof e.content_block==`object`?e.content_block:{};return{delta:String(n?.text??r?.text??``),thinking:String(n?.thinking??``)}},c)},y=async e=>{let{model:t,messages:r,temperature:a,maxTokens:s,responseFormatJson:c,signal:u}=e,d=n(t.baseUrl,`v1beta/models/${encodeURIComponent(t.modelId)}:streamGenerateContent`)+`?alt=sse&key=${encodeURIComponent(t.apiKey)}`,p=r.filter(e=>e.role===`system`).map(e=>e.content).join(`

`).trim(),m=r.filter(e=>e.role!==`system`).map(e=>({role:e.role===`assistant`?`model`:`user`,parts:[{text:e.content}]})),h={contents:m.length?m:[{role:`user`,parts:[{text:``}]}],generationConfig:{temperature:typeof a==`number`?a:.3,...typeof s==`number`&&s>0?{maxOutputTokens:s}:{},...c?{responseMimeType:`application/json`}:{}}};p&&(h.systemInstruction={parts:[{text:p}]});let g;try{g=await fetch(d,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(h),signal:u})}catch(e){throw o(e,d)}if(!g.ok){let e=(await g.text()).slice(0,400);throw Error(i(`Gemini 返回 ${g.status}：${e||g.statusText}`,`Gemini returned ${g.status}: ${e||g.statusText}`))}return await f(g,e,e=>({delta:l(e)}),e=>Array.isArray(e)?e.map(l).join(``):l(e))},b=async e=>{let{model:t}=e;await p(t);let n=t.provider===`anthropic`?await v(e):t.provider===`gemini`?await y(e):await _(e);try{e.onText?.(n.text)}catch{}try{e.onThinking?.(n.thinking)}catch{}try{e.onResponseMeta?.({provider:`custom:${t.provider}`,model:t.modelId,reasoningContent:n.thinking,rawParts:[]})}catch{}if(!n.text)throw Error(i(`自定义模型返回内容为空`,`Custom model returned empty content`));return n.text},x=async e=>{let{model:t}=e;return await p(t),t.provider===`anthropic`?await h(e):t.provider===`gemini`?await g(e):await m(e)};export{x as callCustomLlm,b as callCustomLlmStream};