@musistudio/claude-code-router 3.0.4 → 3.0.5

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.
@@ -1,10 +1,10 @@
1
- "use strict";var V=require("node:fs/promises"),U=require("node:path"),j="2024-11-05",v="https://api.openai.com/v1",Y="gpt-4o-mini",M=3e4,B=20*1024*1024,R=fe(s("FUSION_BUILTIN_TOOL_KIND")),_=s("FUSION_TOOL_NAME")||s("FUSION_VISION_TOOL_NAME")||(R==="web_search"?"web_search":"vision_understand"),$=s("FUSION_TOOL_TITLE")||s("FUSION_VISION_TOOL_TITLE")||(R==="web_search"?"Fusion Web Search":"Fusion Vision Understand"),H={description:"Analyze one or more images with this Fusion profile's configured OpenAI-compatible vision model.",inputSchema:N({detail:{enum:["auto","low","high"],type:"string"},imageBase64:{description:"Single raw base64 image payload or data URL.",type:"string"},imagePath:{description:"Single local image path.",type:"string"},imageUrl:{description:"Single HTTP(S) image URL or data URL.",type:"string"},images:{items:N({base64:{type:"string"},label:{type:"string"},mimeType:{type:"string"},path:{type:"string"},url:{type:"string"}}),type:"array"},prompt:{description:"Task instruction for image analysis.",type:"string"},systemPrompt:{type:"string"},timeoutMs:{minimum:100,type:"number"}},["prompt"]),name:_,title:$},G={description:"Search the web with this Fusion profile's configured search provider.",inputSchema:N({allowedDomains:{items:{type:"string"},type:"array"},allowed_domains:{items:{type:"string"},type:"array"},blockedDomains:{items:{type:"string"},type:"array"},blocked_domains:{items:{type:"string"},type:"array"},count:{maximum:20,minimum:1,type:"number"},country:{type:"string"},excludeDomains:{items:{type:"string"},type:"array"},freshness:{enum:["day","week","month"],type:"string"},includeDomains:{items:{type:"string"},type:"array"},includeRaw:{type:"boolean"},language:{type:"string"},prompt:{description:"Natural-language search query.",type:"string"},safeSearch:{enum:["off","moderate","strict"],type:"string"},timeoutMs:{minimum:100,type:"number"}},["prompt"]),name:_,title:$},F=R==="web_search"?G:H,g=Buffer.alloc(0);process.stdin.on("data",e=>{g=Buffer.concat([g,Buffer.isBuffer(e)?e:Buffer.from(e)]),W().catch(t=>{A(p(null,-32603,I(t)))})});process.stdin.resume();async function W(){for(;;){let e=g.indexOf(`\r
1
+ "use strict";var G=require("node:crypto"),H=require("node:fs/promises"),F=require("node:path"),te="2024-11-05",ne="https://api.openai.com/v1",re="gpt-4o-mini",W=3e4,L=20*1024*1024,se="ccr.fusion-usage.v1",oe=100,ie=15e3,J=3,ae=5e3,A=new Set,B=!1,$=!1,x=ve(i("FUSION_BUILTIN_TOOL_KIND")),E=i("FUSION_TOOL_NAME")||i("FUSION_VISION_TOOL_NAME")||(x==="web_search"?"web_search":"vision_understand"),z=i("FUSION_TOOL_TITLE")||i("FUSION_VISION_TOOL_TITLE")||(x==="web_search"?"Fusion Web Search":"Fusion Vision Understand"),ce={description:"Analyze one or more images with this Fusion profile's configured OpenAI-compatible vision model.",inputSchema:M({detail:{enum:["auto","low","high"],type:"string"},imageBase64:{description:"Single raw base64 image payload or data URL.",type:"string"},imagePath:{description:"Single local image path.",type:"string"},imageUrl:{description:"Single HTTP(S) image URL or data URL.",type:"string"},images:{items:M({base64:{type:"string"},label:{type:"string"},mimeType:{type:"string"},path:{type:"string"},url:{type:"string"}}),type:"array"},prompt:{description:"Task instruction for image analysis.",type:"string"},systemPrompt:{type:"string"},timeoutMs:{minimum:100,type:"number"}},["prompt"]),name:E,title:z},ue={description:"Search the web with this Fusion profile's configured search provider.",inputSchema:M({allowedDomains:{items:{type:"string"},type:"array"},allowed_domains:{items:{type:"string"},type:"array"},blockedDomains:{items:{type:"string"},type:"array"},blocked_domains:{items:{type:"string"},type:"array"},count:{maximum:20,minimum:1,type:"number"},country:{type:"string"},excludeDomains:{items:{type:"string"},type:"array"},freshness:{enum:["day","week","month"],type:"string"},includeDomains:{items:{type:"string"},type:"array"},includeRaw:{type:"boolean"},language:{type:"string"},prompt:{description:"Natural-language search query.",type:"string"},safeSearch:{enum:["off","moderate","strict"],type:"string"},timeoutMs:{minimum:100,type:"number"}},["prompt"]),name:E,title:z},le=x==="web_search"?ue:ce,d=Buffer.alloc(0);process.stdin.on("data",e=>{d=Buffer.concat([d,Buffer.isBuffer(e)?e:Buffer.from(e)]),me().catch(n=>{O(p(null,-32603,I(n)))})});process.stdin.resume();process.once("SIGINT",()=>{X(130)});process.once("SIGTERM",()=>{X(143)});async function me(){for(;;){let e=d.indexOf(`\r
2
2
  \r
3
- `);if(e<0)return;let r=g.subarray(0,e).toString("utf8").match(/content-length:\s*(\d+)/i);if(!r){g=g.subarray(e+4),A(p(null,-32600,"Missing Content-Length header."));continue}let n=Number(r[1]),i=e+4,c=i+n;if(g.length<c)return;let l=g.subarray(i,c).toString("utf8");g=g.subarray(c);let m;try{m=JSON.parse(l)}catch(w){A(p(null,-32700,`Invalid JSON-RPC request: ${I(w)}`));continue}let u=await z(m);u&&A(u)}}async function z(e){if(!a(e))return p(null,-32600,"JSON-RPC request must be an object.");let t=e,r=t.id??null;if(!(t.id===void 0&&t.method?.startsWith("notifications/"))){if(t.jsonrpc!=="2.0"||!t.method)return p(r,-32600,"Invalid JSON-RPC 2.0 request.");try{switch(t.method){case"initialize":return E(r,{capabilities:{tools:{}},protocolVersion:j,serverInfo:{name:"ccr-fusion-builtins",title:"CCR Fusion Builtins",version:"1.0.0"}});case"ping":return E(r,{});case"tools/list":return E(r,{tools:[F]});case"tools/call":return E(r,await X(t.params));default:return p(r,-32601,`Unsupported MCP method: ${t.method}`)}}catch(n){return p(r,-32603,I(n))}}}async function X(e){if(!a(e)||typeof e.name!="string")throw new Error("tools/call params must include a tool name.");if(e.name!==_)throw new Error(`Unknown fusion tool: ${e.name}`);let t=a(e.arguments)?e.arguments:{};try{let r=R==="web_search"?await Z(t):await Q(t);return J(r)}catch(r){return{...J(I(r)),isError:!0}}}async function Q(e){let t=o(e.prompt);if(!t)throw new Error(`${_} requires prompt.`);let r=s("VISION_GATEWAY_BASE_URL"),n=r||s("VISION_BASE_URL")||s("OPENAI_BASE_URL")||v,i=r?s("VISION_GATEWAY_API_KEY"):s("VISION_API_KEY")||s("OPENAI_API_KEY");if(!r&&!i)throw new Error("Missing vision API key. Set VISION_API_KEY.");let c=s("VISION_MODEL")||s("OPENAI_MODEL")||Y,l=o(e.detail),m=await ce(e,l==="low"||l==="high"?l:"auto");if(m.length===0)throw new Error(`${_} requires imageUrl, imagePath, imageBase64, or images.`);let u=o(e.systemPrompt),w=[...u?[{role:"system",content:u}]:[],{role:"user",content:[{type:"text",text:t},...m]}],q=k(b(e.timeoutMs)??b(s("VISION_TIMEOUT_MS"))??M,100,6e5),O=await fetch(me(n),{body:JSON.stringify({model:c,messages:w}),headers:{...i?{authorization:`Bearer ${i}`}:{},"content-type":"application/json"},method:"POST",signal:AbortSignal.timeout(q)}),T=await O.text(),x=D(T);if(!O.ok)throw new Error(`Vision request failed (${O.status}): ${K(T,x)}`);return ge(x)||T}async function Z(e){let t=o(e.prompt);if(!t)throw new Error(`${_} requires prompt.`);let r=pe(),n=k(b(e.count)??b(s("SEARCH_RESULT_COUNT"))??5,1,20),i=k(b(e.timeoutMs)??b(s("SEARCH_TIMEOUT_MS"))??M,100,6e5),c={count:n,country:o(e.country),excludeDomains:L([...P(e.excludeDomains),...P(e.blockedDomains),...P(e.blocked_domains)]),freshness:o(e.freshness),includeDomains:L([...P(e.includeDomains),...P(e.allowedDomains),...P(e.allowed_domains)]),includeRaw:e.includeRaw===!0,language:o(e.language),prompt:t,safeSearch:o(e.safeSearch),timeoutMs:i},l=await ee(r,c);return l.length===0?`Search provider: ${r}
4
- No results.`:[`Search provider: ${r}`,...l.slice(0,n).map((m,u)=>[`${u+1}. ${m.title||m.url||"Untitled"}`,m.url?`URL: ${m.url}`:"",m.snippet?`Snippet: ${m.snippet}`:""].filter(Boolean).join(`
3
+ `);if(e<0)return;let t=d.subarray(0,e).toString("utf8").match(/content-length:\s*(\d+)/i);if(!t){d=d.subarray(e+4),O(p(null,-32600,"Missing Content-Length header."));continue}let r=Number(t[1]),s=e+4,o=s+r;if(d.length<o)return;let a=d.subarray(s,o).toString("utf8");d=d.subarray(o);let u;try{u=JSON.parse(a)}catch(_){O(p(null,-32700,`Invalid JSON-RPC request: ${I(_)}`));continue}let m=await ge(u);m&&O(m)}}async function ge(e){if(!c(e))return p(null,-32600,"JSON-RPC request must be an object.");let n=e,t=n.id??null;if(!(n.id===void 0&&n.method?.startsWith("notifications/"))){if(n.jsonrpc!=="2.0"||!n.method)return p(t,-32600,"Invalid JSON-RPC 2.0 request.");try{switch(n.method){case"initialize":return k(t,{capabilities:{tools:{}},protocolVersion:te,serverInfo:{name:"ccr-fusion-builtins",title:"CCR Fusion Builtins",version:"1.0.0"}});case"ping":return k(t,{});case"tools/list":return k(t,{tools:[le]});case"tools/call":return k(t,await de(n.params));default:return p(t,-32601,`Unsupported MCP method: ${n.method}`)}}catch(r){return p(t,-32603,I(r))}}}async function de(e){if(!c(e)||typeof e.name!="string")throw new Error("tools/call params must include a tool name.");if(e.name!==E)throw new Error(`Unknown fusion tool: ${e.name}`);let n=c(e.arguments)?e.arguments:{};try{let t=x==="web_search"?await be(n):await fe(n);return Y(t)}catch(t){return{...Y(I(t)),isError:!0}}}async function fe(e){let n=l(e.prompt);if(!n)throw new Error(`${E} requires prompt.`);let t=i("VISION_GATEWAY_BASE_URL"),r=t||i("VISION_BASE_URL")||i("OPENAI_BASE_URL")||ne,s=t?i("VISION_GATEWAY_API_KEY"):i("VISION_API_KEY")||i("OPENAI_API_KEY");if(!t&&!s)throw new Error("Missing vision API key. Set VISION_API_KEY.");let o=i("VISION_MODEL")||i("OPENAI_MODEL")||re,a=l(e.detail),u=await Ne(e,a==="low"||a==="high"?a:"auto");if(u.length===0)throw new Error(`${E} requires imageUrl, imagePath, imageBase64, or images.`);let m=l(e.systemPrompt),_=[...m?[{role:"system",content:m}]:[],{role:"user",content:[{type:"text",text:n},...u]}],ee=v(g(e.timeoutMs)??g(i("VISION_TIMEOUT_MS"))??W,100,6e5),D=Date.now(),b,V=!1;try{b=await fetch(Be(r),{body:JSON.stringify({model:o,messages:_}),headers:{...s?{authorization:`Bearer ${s}`}:{},"content-type":"application/json"},method:"POST",signal:AbortSignal.timeout(ee)});let R=await b.text(),U=C(R);if(K({durationMs:Date.now()-D,gatewayRuntime:!!t,model:o,payload:U,response:b}),V=!0,!b.ok)throw new Error(`Vision request failed (${b.status}): ${Z(R,U)}`);return Me(U)||R}catch(R){throw V||K({durationMs:Date.now()-D,gatewayRuntime:!!t,model:o,response:b,statusCode:502}),R}}function K(e){let n=i("CCR_FUSION_USAGE_SYNC_ENDPOINT"),t=i("CCR_FUSION_USAGE_SYNC_HEADER"),r=i("CCR_FUSION_USAGE_SYNC_TOKEN");if(!n||!t||!r)return;let s=e.gatewayRuntime?we(e.model):{model:e.model},o=e.response?.status??e.statusCode??502,a={billing:{cost:{total:Se(e.response,e.payload)},usage:ye(e.response,e.payload)},emittedAt:new Date().toISOString(),eventId:(0,G.randomUUID)(),outcome:{status:_e(o),statusCode:o},performance:{latency_ms:e.durationMs},route:{method:"POST",url:"/v1/chat/completions"},schema:se,source:{adapterKey:"openai_chat",provider:"fusion_vision"},target:s},u=pe(n,t,r,a);A.add(u),u.then(()=>A.delete(u),()=>A.delete(u))}async function pe(e,n,t,r){let s;for(let o=1;o<=J;o+=1)try{let a=await fetch(e,{body:JSON.stringify(r),headers:{[n]:t,"content-type":"application/json"},method:"POST",signal:AbortSignal.timeout(ae)}),u=await a.text();if(!a.ok)throw new T(a.status);let m=u?C(u):void 0;if(c(m)&&m.applied===!1)throw new N;B=!1;return}catch(a){if(s=a,o>=J||!he(a))break;await Q(oe*2**(o-1))}B||(B=!0,console.warn(`[fusion-vision] Failed to publish lightweight usage event: ${I(s)}`))}var T=class extends Error{constructor(t){super(`HTTP ${t}`);this.statusCode=t;this.name="FusionUsageSyncHttpError",this.retryable=t===408||t===409||t===425||t===429||t>=500}statusCode;retryable},N=class extends Error{retryable=!1;constructor(){super("Usage sync endpoint rejected the event."),this.name="FusionUsageSyncRejectedError"}};function he(e){return!(e instanceof N)&&(!(e instanceof T)||e.retryable)}async function X(e){if($)return;$=!0;let n=Date.now()+ie;for(;A.size>0&&Date.now()<n;){let t=Math.max(1,n-Date.now());await Promise.race([Promise.allSettled([...A]),Q(t)])}process.exit(e)}function Q(e){return new Promise(n=>setTimeout(n,e))}function ye(e,n){let t=c(n)?n:{},r=c(t.usage)?t.usage:{},s=c(r.input_tokens_details)?r.input_tokens_details:c(r.prompt_tokens_details)?r.prompt_tokens_details:{},o=a=>g(e?.headers.get(a));return{cache_read_tokens:o("x-gateway-billing-cache-read-tokens")??g(r.cache_read_tokens)??g(r.cache_read_input_tokens)??g(s.cached_tokens),cache_write_tokens:o("x-gateway-billing-cache-write-tokens")??g(r.cache_write_tokens)??g(r.cache_creation_input_tokens)??g(s.cache_creation_tokens),input_tokens:o("x-gateway-billing-input-tokens")??g(r.input_tokens)??g(r.prompt_tokens),output_tokens:o("x-gateway-billing-output-tokens")??g(r.output_tokens)??g(r.completion_tokens),total_tokens:o("x-gateway-billing-total-tokens")??g(r.total_tokens)}}function Se(e,n){let t=g(e?.headers.get("x-gateway-billing-total-cost"));if(t!==void 0)return t;let r=c(n)?n:{},s=c(r.billing)?r.billing:{},o=c(s.cost)?s.cost:{};return g(o.total)}function we(e){let n=e.indexOf("/"),t=n>0?e.slice(0,n).trim():void 0,r=n>0&&n<e.length-1?e.slice(n+1).trim():e,s=t?.split("::").find(o=>o.startsWith("cred:"))?.slice(5).trim();return{...s?{credentialId:s}:{},model:r,...t?{providerName:t}:{}}}function _e(e){return e>=200&&e<400?"success":e===429?"rate-limited":e===408||e===504?"timeout":"error"}async function be(e){let n=l(e.prompt);if(!n)throw new Error(`${E} requires prompt.`);let t=Ce(),r=v(g(e.count)??g(i("SEARCH_RESULT_COUNT"))??5,1,20),s=v(g(e.timeoutMs)??g(i("SEARCH_TIMEOUT_MS"))??W,100,6e5),o={count:r,country:l(e.country),excludeDomains:j([...P(e.excludeDomains),...P(e.blockedDomains),...P(e.blocked_domains)]),freshness:l(e.freshness),includeDomains:j([...P(e.includeDomains),...P(e.allowedDomains),...P(e.allowed_domains)]),includeRaw:e.includeRaw===!0,language:l(e.language),prompt:n,safeSearch:l(e.safeSearch),timeoutMs:s},a=await Pe(t,o);return a.length===0?`Search provider: ${t}
4
+ No results.`:[`Search provider: ${t}`,...a.slice(0,r).map((u,m)=>[`${m+1}. ${u.title||u.url||"Untitled"}`,u.url?`URL: ${u.url}`:"",u.snippet?`Snippet: ${u.snippet}`:""].filter(Boolean).join(`
5
5
  `))].join(`
6
6
 
7
- `)}async function ee(e,t){return e==="brave"?te(t):e==="bing"?re(t):e==="google_cse"?ne(t):e==="serper"?se(t):e==="serpapi"?ie(t):e==="tavily"?oe(t):ae(t)}async function te(e){let t=f("BRAVE_SEARCH_API_KEY","Brave Search API key"),r=new URL(s("BRAVE_SEARCH_ENDPOINT")||"https://api.search.brave.com/res/v1/web/search");r.searchParams.set("q",d(e)),r.searchParams.set("count",String(e.count)),e.country&&r.searchParams.set("country",e.country),e.language&&r.searchParams.set("search_lang",e.language),e.safeSearch&&r.searchParams.set("safesearch",e.safeSearch);let n=await h(r.toString(),{headers:{"x-subscription-token":t},signal:AbortSignal.timeout(e.timeoutMs)});return(a(n)&&a(n.web)&&Array.isArray(n.web.results)?n.web.results:[]).map(c=>y(c,"title","url","description")).filter(S)}async function re(e){let t=f("BING_SEARCH_API_KEY","Bing Web Search API key"),r=new URL(s("BING_SEARCH_ENDPOINT")||"https://api.bing.microsoft.com/v7.0/search");r.searchParams.set("q",d(e)),r.searchParams.set("count",String(e.count)),(e.country||e.language)&&r.searchParams.set("mkt",[e.language,e.country].filter(Boolean).join("-")),e.safeSearch&&r.searchParams.set("safeSearch",e.safeSearch);let n=await h(r.toString(),{headers:{"ocp-apim-subscription-key":t},signal:AbortSignal.timeout(e.timeoutMs)});return(a(n)&&a(n.webPages)&&Array.isArray(n.webPages.value)?n.webPages.value:[]).map(c=>y(c,"name","url","snippet")).filter(S)}async function ne(e){let t=f("GOOGLE_SEARCH_API_KEY","Google Programmable Search API key"),r=f("GOOGLE_SEARCH_CX","Google Programmable Search Engine ID"),n=new URL(s("GOOGLE_SEARCH_ENDPOINT")||"https://www.googleapis.com/customsearch/v1");n.searchParams.set("key",t),n.searchParams.set("cx",r),n.searchParams.set("q",d(e)),n.searchParams.set("num",String(Math.min(e.count,10))),e.country&&n.searchParams.set("gl",e.country),e.language&&n.searchParams.set("hl",e.language);let i=await h(n.toString(),{signal:AbortSignal.timeout(e.timeoutMs)});return(a(i)&&Array.isArray(i.items)?i.items:[]).map(l=>y(l,"title","link","snippet")).filter(S)}async function se(e){let t=f("SERPER_API_KEY","Serper API key"),r=await h(s("SERPER_SEARCH_ENDPOINT")||"https://google.serper.dev/search",{body:JSON.stringify({gl:e.country,hl:e.language,num:e.count,q:d(e),tbs:ye(e.freshness)}),headers:{"content-type":"application/json","x-api-key":t},method:"POST",signal:AbortSignal.timeout(e.timeoutMs)});return(a(r)&&Array.isArray(r.organic)?r.organic:[]).map(i=>y(i,"title","link","snippet")).filter(S)}async function ie(e){let t=f("SERPAPI_API_KEY","SerpAPI key"),r=new URL(s("SERPAPI_SEARCH_ENDPOINT")||"https://serpapi.com/search.json");r.searchParams.set("api_key",t),r.searchParams.set("engine","google"),r.searchParams.set("q",d(e)),r.searchParams.set("num",String(e.count)),e.country&&r.searchParams.set("gl",e.country),e.language&&r.searchParams.set("hl",e.language),e.safeSearch&&r.searchParams.set("safe",e.safeSearch==="off"?"off":"active");let n=await h(r.toString(),{signal:AbortSignal.timeout(e.timeoutMs)});return(a(n)&&Array.isArray(n.organic_results)?n.organic_results:[]).map(c=>y(c,"title","link","snippet")).filter(S)}async function oe(e){let t=f("TAVILY_API_KEY","Tavily API key"),r=await h(s("TAVILY_SEARCH_ENDPOINT")||"https://api.tavily.com/search",{body:JSON.stringify({api_key:t,include_raw_content:e.includeRaw,max_results:e.count,query:d(e),search_depth:"basic"}),headers:{"content-type":"application/json"},method:"POST",signal:AbortSignal.timeout(e.timeoutMs)});return(a(r)&&Array.isArray(r.results)?r.results:[]).map(i=>y(i,"title","url","content")).filter(S)}async function ae(e){let t=f("EXA_API_KEY","Exa API key"),r=await h(s("EXA_SEARCH_ENDPOINT")||"https://api.exa.ai/search",{body:JSON.stringify({numResults:e.count,query:d(e)}),headers:{authorization:`Bearer ${t}`,"content-type":"application/json"},method:"POST",signal:AbortSignal.timeout(e.timeoutMs)});return(a(r)&&Array.isArray(r.results)?r.results:[]).map(i=>y(i,"title","url","text")).filter(S)}async function ce(e,t){let r=[],n=o(e.imageUrl),i=o(e.imagePath),c=o(e.imageBase64);n&&r.push({url:n}),i&&r.push({path:i}),c&&r.push({base64:c,mimeType:o(e.mimeType)});let l=Array.isArray(e.images)?e.images:[];for(let u of l)a(u)&&r.push({base64:o(u.base64),label:o(u.label),mimeType:o(u.mimeType),path:o(u.path),url:o(u.url)});let m=[];for(let u of r){let w=await ue(u);w&&(u.label&&m.push({text:`Image: ${u.label}`,type:"text"}),m.push({image_url:{detail:t,url:w},type:"image_url"}))}return m}async function ue(e){if(e.url)return e.url;if(e.base64)return C(e.base64,e.mimeType||"image/png");if(!e.path)return;let t=await(0,V.readFile)(e.path);if(t.byteLength>B)throw new Error(`Local image exceeds ${B} bytes: ${e.path}`);return C(t.toString("base64"),e.mimeType||le(e.path))}function C(e,t){return e.startsWith("data:")?e:`data:${t};base64,${e}`}function le(e){let t=(0,U.extname)(e).toLowerCase();return t===".jpg"||t===".jpeg"?"image/jpeg":t===".webp"?"image/webp":t===".gif"?"image/gif":"image/png"}function me(e){let t=e.trim().replace(/\/+$/,"");return t.endsWith("/chat/completions")?t:`${t}/chat/completions`}function ge(e){if(!a(e))return;let t=Array.isArray(e.choices)?e.choices:[],r=a(t[0])?t[0]:void 0,i=(a(r?.message)?r.message:void 0)?.content;return typeof i=="string"?i:Array.isArray(i)?i.map(l=>a(l)?o(l.text):void 0).filter(l=>!!l).join(`
8
- `)||void 0:o(e.output_text)}function K(e,t){if(a(t)){let r=t.error;if(typeof r=="string")return r;if(a(r)&&typeof r.message=="string")return r.message;if(typeof t.message=="string")return t.message}return e.slice(0,500)}function D(e){try{return JSON.parse(e)}catch{throw new Error(`Invalid JSON from provider: ${e.slice(0,500)}`)}}function fe(e){return e==="web_search"?"web_search":"vision"}function pe(){let e=he(s("SEARCH_PROVIDER"))??"auto";if(e!=="auto")return e;let r=["brave","bing","google_cse","serper","serpapi","tavily","exa"].find(de);if(!r)throw new Error("No search provider configured. Set SEARCH_PROVIDER and its API key.");return r}function he(e){if(e==="auto"||e==="brave"||e==="bing"||e==="google_cse"||e==="serper"||e==="serpapi"||e==="tavily"||e==="exa")return e}function de(e){return e==="brave"?!!s("BRAVE_SEARCH_API_KEY"):e==="bing"?!!s("BING_SEARCH_API_KEY"):e==="google_cse"?!!(s("GOOGLE_SEARCH_API_KEY")&&s("GOOGLE_SEARCH_CX")):e==="serper"?!!s("SERPER_API_KEY"):e==="serpapi"?!!s("SERPAPI_API_KEY"):e==="tavily"?!!s("TAVILY_API_KEY"):!!s("EXA_API_KEY")}function f(e,t){let r=s(e);if(!r)throw new Error(`Missing ${t}. Set ${e}.`);return r}async function h(e,t){let r=await fetch(e,t),n=await r.text(),i=n?D(n):{};if(!r.ok)throw new Error(`Search request failed (${r.status}): ${K(n,i)}`);return i}function d(e){let t=e.includeDomains.map(n=>`site:${n}`).join(" "),r=e.excludeDomains.map(n=>`-site:${n}`).join(" ");return[e.prompt,t,r].filter(Boolean).join(" ")}function ye(e){if(e==="day")return"qdr:d";if(e==="week")return"qdr:w";if(e==="month")return"qdr:m"}function y(e,t,r,n){return a(e)?{snippet:o(e[n]),title:o(e[t]),url:o(e[r])}:{}}function S(e){return!!(e.title||e.url||e.snippet)}function P(e){return typeof e=="string"?e.split(",").map(t=>t.trim()).filter(Boolean):Array.isArray(e)?e.map(o).filter(t=>!!t):[]}function L(e){return[...new Set(e.filter(Boolean))]}function J(e){return{content:[{text:e,type:"text"}]}}function N(e,t=[]){return{additionalProperties:!1,properties:e,required:t,type:"object"}}function E(e,t){return{id:e,jsonrpc:"2.0",result:t}}function p(e,t,r,n){return{error:{code:t,...n===void 0?{}:{data:n},message:r},id:e,jsonrpc:"2.0"}}function A(e){let t=JSON.stringify(e);process.stdout.write(`Content-Length: ${Buffer.byteLength(t,"utf8")}\r
7
+ `)}async function Pe(e,n){return e==="brave"?Ee(n):e==="bing"?Re(n):e==="google_cse"?Ae(n):e==="serper"?Ie(n):e==="serpapi"?ke(n):e==="tavily"?Oe(n):Te(n)}async function Ee(e){let n=f("BRAVE_SEARCH_API_KEY","Brave Search API key"),t=new URL(i("BRAVE_SEARCH_ENDPOINT")||"https://api.search.brave.com/res/v1/web/search");t.searchParams.set("q",y(e)),t.searchParams.set("count",String(e.count)),e.country&&t.searchParams.set("country",e.country),e.language&&t.searchParams.set("search_lang",e.language),e.safeSearch&&t.searchParams.set("safesearch",e.safeSearch);let r=await h(t.toString(),{headers:{"x-subscription-token":n},signal:AbortSignal.timeout(e.timeoutMs)});return(c(r)&&c(r.web)&&Array.isArray(r.web.results)?r.web.results:[]).map(o=>S(o,"title","url","description")).filter(w)}async function Re(e){let n=f("BING_SEARCH_API_KEY","Bing Web Search API key"),t=new URL(i("BING_SEARCH_ENDPOINT")||"https://api.bing.microsoft.com/v7.0/search");t.searchParams.set("q",y(e)),t.searchParams.set("count",String(e.count)),(e.country||e.language)&&t.searchParams.set("mkt",[e.language,e.country].filter(Boolean).join("-")),e.safeSearch&&t.searchParams.set("safeSearch",e.safeSearch);let r=await h(t.toString(),{headers:{"ocp-apim-subscription-key":n},signal:AbortSignal.timeout(e.timeoutMs)});return(c(r)&&c(r.webPages)&&Array.isArray(r.webPages.value)?r.webPages.value:[]).map(o=>S(o,"name","url","snippet")).filter(w)}async function Ae(e){let n=f("GOOGLE_SEARCH_API_KEY","Google Programmable Search API key"),t=f("GOOGLE_SEARCH_CX","Google Programmable Search Engine ID"),r=new URL(i("GOOGLE_SEARCH_ENDPOINT")||"https://www.googleapis.com/customsearch/v1");r.searchParams.set("key",n),r.searchParams.set("cx",t),r.searchParams.set("q",y(e)),r.searchParams.set("num",String(Math.min(e.count,10))),e.country&&r.searchParams.set("gl",e.country),e.language&&r.searchParams.set("hl",e.language);let s=await h(r.toString(),{signal:AbortSignal.timeout(e.timeoutMs)});return(c(s)&&Array.isArray(s.items)?s.items:[]).map(a=>S(a,"title","link","snippet")).filter(w)}async function Ie(e){let n=f("SERPER_API_KEY","Serper API key"),t=await h(i("SERPER_SEARCH_ENDPOINT")||"https://google.serper.dev/search",{body:JSON.stringify({gl:e.country,hl:e.language,num:e.count,q:y(e),tbs:Le(e.freshness)}),headers:{"content-type":"application/json","x-api-key":n},method:"POST",signal:AbortSignal.timeout(e.timeoutMs)});return(c(t)&&Array.isArray(t.organic)?t.organic:[]).map(s=>S(s,"title","link","snippet")).filter(w)}async function ke(e){let n=f("SERPAPI_API_KEY","SerpAPI key"),t=new URL(i("SERPAPI_SEARCH_ENDPOINT")||"https://serpapi.com/search.json");t.searchParams.set("api_key",n),t.searchParams.set("engine","google"),t.searchParams.set("q",y(e)),t.searchParams.set("num",String(e.count)),e.country&&t.searchParams.set("gl",e.country),e.language&&t.searchParams.set("hl",e.language),e.safeSearch&&t.searchParams.set("safe",e.safeSearch==="off"?"off":"active");let r=await h(t.toString(),{signal:AbortSignal.timeout(e.timeoutMs)});return(c(r)&&Array.isArray(r.organic_results)?r.organic_results:[]).map(o=>S(o,"title","link","snippet")).filter(w)}async function Oe(e){let n=f("TAVILY_API_KEY","Tavily API key"),t=await h(i("TAVILY_SEARCH_ENDPOINT")||"https://api.tavily.com/search",{body:JSON.stringify({api_key:n,include_raw_content:e.includeRaw,max_results:e.count,query:y(e),search_depth:"basic"}),headers:{"content-type":"application/json"},method:"POST",signal:AbortSignal.timeout(e.timeoutMs)});return(c(t)&&Array.isArray(t.results)?t.results:[]).map(s=>S(s,"title","url","content")).filter(w)}async function Te(e){let n=f("EXA_API_KEY","Exa API key"),t=await h(i("EXA_SEARCH_ENDPOINT")||"https://api.exa.ai/search",{body:JSON.stringify({numResults:e.count,query:y(e)}),headers:{authorization:`Bearer ${n}`,"content-type":"application/json"},method:"POST",signal:AbortSignal.timeout(e.timeoutMs)});return(c(t)&&Array.isArray(t.results)?t.results:[]).map(s=>S(s,"title","url","text")).filter(w)}async function Ne(e,n){let t=[],r=l(e.imageUrl),s=l(e.imagePath),o=l(e.imageBase64);r&&t.push({url:r}),s&&t.push({path:s}),o&&t.push({base64:o,mimeType:l(e.mimeType)});let a=Array.isArray(e.images)?e.images:[];for(let m of a)c(m)&&t.push({base64:l(m.base64),label:l(m.label),mimeType:l(m.mimeType),path:l(m.path),url:l(m.url)});let u=[];for(let m of t){let _=await xe(m);_&&(m.label&&u.push({text:`Image: ${m.label}`,type:"text"}),u.push({image_url:{detail:n,url:_},type:"image_url"}))}return u}async function xe(e){if(e.url)return e.url;if(e.base64)return q(e.base64,e.mimeType||"image/png");if(!e.path)return;let n=await(0,H.readFile)(e.path);if(n.byteLength>L)throw new Error(`Local image exceeds ${L} bytes: ${e.path}`);return q(n.toString("base64"),e.mimeType||Ue(e.path))}function q(e,n){return e.startsWith("data:")?e:`data:${n};base64,${e}`}function Ue(e){let n=(0,F.extname)(e).toLowerCase();return n===".jpg"||n===".jpeg"?"image/jpeg":n===".webp"?"image/webp":n===".gif"?"image/gif":"image/png"}function Be(e){let n=e.trim().replace(/\/+$/,"");return n.endsWith("/chat/completions")?n:`${n}/chat/completions`}function Me(e){if(!c(e))return;let n=Array.isArray(e.choices)?e.choices:[],t=c(n[0])?n[0]:void 0,s=(c(t?.message)?t.message:void 0)?.content;return typeof s=="string"?s:Array.isArray(s)?s.map(a=>c(a)?l(a.text):void 0).filter(a=>!!a).join(`
8
+ `)||void 0:l(e.output_text)}function Z(e,n){if(c(n)){let t=n.error;if(typeof t=="string")return t;if(c(t)&&typeof t.message=="string")return t.message;if(typeof n.message=="string")return n.message}return e.slice(0,500)}function C(e){try{return JSON.parse(e)}catch{throw new Error(`Invalid JSON from provider: ${e.slice(0,500)}`)}}function ve(e){return e==="web_search"?"web_search":"vision"}function Ce(){let e=De(i("SEARCH_PROVIDER"))??"auto";if(e!=="auto")return e;let t=["brave","bing","google_cse","serper","serpapi","tavily","exa"].find(Ve);if(!t)throw new Error("No search provider configured. Set SEARCH_PROVIDER and its API key.");return t}function De(e){if(e==="auto"||e==="brave"||e==="bing"||e==="google_cse"||e==="serper"||e==="serpapi"||e==="tavily"||e==="exa")return e}function Ve(e){return e==="brave"?!!i("BRAVE_SEARCH_API_KEY"):e==="bing"?!!i("BING_SEARCH_API_KEY"):e==="google_cse"?!!(i("GOOGLE_SEARCH_API_KEY")&&i("GOOGLE_SEARCH_CX")):e==="serper"?!!i("SERPER_API_KEY"):e==="serpapi"?!!i("SERPAPI_API_KEY"):e==="tavily"?!!i("TAVILY_API_KEY"):!!i("EXA_API_KEY")}function f(e,n){let t=i(e);if(!t)throw new Error(`Missing ${n}. Set ${e}.`);return t}async function h(e,n){let t=await fetch(e,n),r=await t.text(),s=r?C(r):{};if(!t.ok)throw new Error(`Search request failed (${t.status}): ${Z(r,s)}`);return s}function y(e){let n=e.includeDomains.map(r=>`site:${r}`).join(" "),t=e.excludeDomains.map(r=>`-site:${r}`).join(" ");return[e.prompt,n,t].filter(Boolean).join(" ")}function Le(e){if(e==="day")return"qdr:d";if(e==="week")return"qdr:w";if(e==="month")return"qdr:m"}function S(e,n,t,r){return c(e)?{snippet:l(e[r]),title:l(e[n]),url:l(e[t])}:{}}function w(e){return!!(e.title||e.url||e.snippet)}function P(e){return typeof e=="string"?e.split(",").map(n=>n.trim()).filter(Boolean):Array.isArray(e)?e.map(l).filter(n=>!!n):[]}function j(e){return[...new Set(e.filter(Boolean))]}function Y(e){return{content:[{text:e,type:"text"}]}}function M(e,n=[]){return{additionalProperties:!1,properties:e,required:n,type:"object"}}function k(e,n){return{id:e,jsonrpc:"2.0",result:n}}function p(e,n,t,r){return{error:{code:n,...r===void 0?{}:{data:r},message:t},id:e,jsonrpc:"2.0"}}function O(e){let n=JSON.stringify(e);process.stdout.write(`Content-Length: ${Buffer.byteLength(n,"utf8")}\r
9
9
  \r
10
- ${t}`)}function a(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function o(e){return typeof e=="string"&&e.trim()?e.trim():void 0}function b(e){if(typeof e=="number"&&Number.isFinite(e))return e;if(typeof e=="string"&&e.trim()){let t=Number(e);return Number.isFinite(t)?t:void 0}}function k(e,t,r){return Math.min(r,Math.max(t,Math.trunc(e)))}function s(e){return o(process.env[e])}function I(e){return e instanceof Error?e.message:String(e)}
10
+ ${n}`)}function c(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function l(e){return typeof e=="string"&&e.trim()?e.trim():void 0}function g(e){if(typeof e=="number"&&Number.isFinite(e))return e;if(typeof e=="string"&&e.trim()){let n=Number(e);return Number.isFinite(n)?n:void 0}}function v(e,n,t){return Math.min(t,Math.max(n,Math.trunc(e)))}function i(e){return l(process.env[e])}function I(e){return e instanceof Error?e.message:String(e)}