ohwow 0.6.4 → 0.6.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.
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -411,7 +411,7 @@ If you want to call a tool, output exactly one tool_call block. If you want to r
|
|
|
411
411
|
`);o=i.pop()||"";for(let l of i){if(!l.startsWith("data: "))continue;let c=l.slice(6).trim();if(c!=="[DONE]")try{let u=JSON.parse(c),d=u.choices?.[0]?.delta,m={};d?.content&&(m.content=d.content),d?.tool_calls&&(m.toolCalls=d.tool_calls.map(g=>({index:g.index,id:g.id,name:g.function?.name,arguments:g.function?.arguments}))),u.usage&&(m.usage=u.usage),(m.content||m.toolCalls||m.usage)&&(yield m)}catch{}}}}finally{n.releaseLock()}}setDefaultModel(t){this.defaultModel=t}getDefaultModel(){return this.defaultModel}resetAvailability(){this._available=null,this._availableCheckedAt=0}}});var Mq,K4e=G(()=>{"use strict";Mq=class{constructor(t,n,r){this.name="openai-compatible";this._available=null;this._availableCheckedAt=0;this._responseCallback=null;this.baseUrl=t.replace(/\/$/,""),this.defaultModel=n,this.apiKey=r}getHeaders(){let t={"Content-Type":"application/json"};return this.apiKey&&(t.Authorization=`Bearer ${this.apiKey}`),t}setResponseCallback(t){this._responseCallback=t}async createMessage(t){let n=t.model||this.defaultModel,r=[];t.system&&r.push({role:"system",content:t.system});for(let u of t.messages)r.push({role:u.role,content:u.content});let o=Date.now(),s;try{s=await fetch(`${this.baseUrl}/v1/chat/completions`,{method:"POST",headers:this.getHeaders(),signal:AbortSignal.timeout(12e4),body:JSON.stringify({model:n,messages:r,max_tokens:t.maxTokens||4096,temperature:t.temperature??.5,stream:!1})})}catch(u){throw this._available=null,this._availableCheckedAt=0,u}s.ok||await this.throwServerError(s);let a=await s.json(),i=a.choices?.[0]?.message?.content||"",l=a.usage||{prompt_tokens:0,completion_tokens:0},c=Date.now()-o;if(this._responseCallback)try{this._responseCallback(n,l.prompt_tokens,l.completion_tokens,c)}catch{}return{content:i,inputTokens:l.prompt_tokens,outputTokens:l.completion_tokens,model:n,provider:"openai-compatible"}}async createMessageWithTools(t){let n=t.model||this.defaultModel,r=[];t.system&&r.push({role:"system",content:t.system});for(let m of t.messages){let g={role:m.role,content:m.content};m.tool_call_id&&(g.tool_call_id=m.tool_call_id),m.tool_calls&&(g.tool_calls=m.tool_calls),r.push(g)}let o=Date.now(),s;try{s=await fetch(`${this.baseUrl}/v1/chat/completions`,{method:"POST",headers:this.getHeaders(),signal:AbortSignal.timeout(12e4),body:JSON.stringify({model:n,messages:r,max_tokens:t.maxTokens||4096,temperature:t.temperature??.5,stream:!1,tools:t.tools,tool_choice:"auto"})})}catch(m){throw this._available=null,this._availableCheckedAt=0,m}s.ok||await this.throwServerError(s);let a=await s.json(),i=a.choices?.[0],l=i?.message?.content||"",c=a.usage||{prompt_tokens:0,completion_tokens:0},u=Date.now()-o;if(this._responseCallback)try{this._responseCallback(n,c.prompt_tokens,c.completion_tokens,u)}catch{}let d=(i?.message?.tool_calls||[]).filter(m=>m.function&&typeof m.function.name=="string").map((m,g)=>({id:m.id||`call_${g}_${Date.now()}_${Math.random().toString(36).slice(2,6)}`,type:"function",function:{name:m.function.name,arguments:m.function.arguments??"{}"}}));return{content:l,inputTokens:c.prompt_tokens,outputTokens:c.completion_tokens,model:n,provider:"openai-compatible",toolCalls:d}}async*createMessageStreaming(t){let n=t.model||this.defaultModel,r=[];t.system&&r.push({role:"system",content:t.system});for(let c of t.messages)r.push({role:c.role,content:c.content});let o=Date.now(),s;try{s=await fetch(`${this.baseUrl}/v1/chat/completions`,{method:"POST",headers:this.getHeaders(),signal:AbortSignal.timeout(12e4),body:JSON.stringify({model:n,messages:r,max_tokens:t.maxTokens||4096,temperature:t.temperature??.5,stream:!0})})}catch(c){throw this._available=null,this._availableCheckedAt=0,c}s.ok||await this.throwServerError(s);let a="",i={prompt_tokens:0,completion_tokens:0};for await(let c of this.parseStream(s))c.content&&(a+=c.content,yield{type:"token",content:c.content}),c.usage&&(i=c.usage);let l=Date.now()-o;if(this._responseCallback)try{this._responseCallback(n,i.prompt_tokens,i.completion_tokens,l)}catch{}return{content:a,inputTokens:i.prompt_tokens,outputTokens:i.completion_tokens,model:n,provider:"openai-compatible"}}async*createMessageWithToolsStreaming(t){let n=t.model||this.defaultModel,r=[];t.system&&r.push({role:"system",content:t.system});for(let m of t.messages){let g={role:m.role,content:m.content};m.tool_call_id&&(g.tool_call_id=m.tool_call_id),m.tool_calls&&(g.tool_calls=m.tool_calls),r.push(g)}let o=Date.now(),s;try{s=await fetch(`${this.baseUrl}/v1/chat/completions`,{method:"POST",headers:this.getHeaders(),signal:AbortSignal.timeout(12e4),body:JSON.stringify({model:n,messages:r,max_tokens:t.maxTokens||4096,temperature:t.temperature??.5,stream:!0,tools:t.tools,tool_choice:"auto"})})}catch(m){throw this._available=null,this._availableCheckedAt=0,m}s.ok||await this.throwServerError(s);let a="",i={prompt_tokens:0,completion_tokens:0},l=new Map,c=!1;for await(let m of this.parseStream(s)){if(m.content&&!c?(a+=m.content,yield{type:"token",content:m.content}):m.content&&(a+=m.content),m.toolCalls){c=!0;for(let g of m.toolCalls){let h=l.get(g.index);h?(g.name&&(h.name+=g.name),g.arguments&&(h.arguments+=g.arguments)):l.set(g.index,{id:g.id||`call_${g.index}_${Date.now()}_${Math.random().toString(36).slice(2,6)}`,name:g.name||"",arguments:g.arguments||""})}}m.usage&&(i=m.usage)}let u=Date.now()-o;if(this._responseCallback)try{this._responseCallback(n,i.prompt_tokens,i.completion_tokens,u)}catch{}let d=Array.from(l.values()).filter(m=>m.name).map(m=>({id:m.id,type:"function",function:{name:m.name,arguments:m.arguments||"{}"}}));return{content:a,inputTokens:i.prompt_tokens,outputTokens:i.completion_tokens,model:n,provider:"openai-compatible",toolCalls:d}}async isAvailable(){if(this._available!==null){let t=this._available?3e4:5e3;if(Date.now()-this._availableCheckedAt<t)return this._available}try{let t={};this.apiKey&&(t.Authorization=`Bearer ${this.apiKey}`);let n=await fetch(`${this.baseUrl}/v1/models`,{headers:t,signal:AbortSignal.timeout(3e3)});return this._available=n.ok,this._availableCheckedAt=Date.now(),this._available}catch{return this._available=!1,this._availableCheckedAt=Date.now(),!1}}async throwServerError(t){let n=await t.text(),r=n.toLowerCase();throw r.includes("out of memory")||r.includes("oom")||r.includes("not enough memory")?new Error(`Model too large for available memory. Try a smaller model. Server: ${n.slice(0,200)}`):t.status===404||r.includes("not found")?new Error(`Model not found. Check your model configuration. Server: ${n.slice(0,200)}`):t.status===401||t.status===403?new Error(`Authentication failed. Check your API key. Server: ${n.slice(0,200)}`):new Error(`OpenAI-compatible server request failed (${t.status}): ${n}`)}async*parseStream(t){if(!t.body)return;let n=t.body.getReader(),r=new TextDecoder,o="";try{for(;;){let{done:s,value:a}=await n.read();if(s)break;o+=r.decode(a,{stream:!0});let i=o.split(`
|
|
412
412
|
`);o=i.pop()||"";for(let l of i){if(!l.startsWith("data: "))continue;let c=l.slice(6).trim();if(c!=="[DONE]")try{let u=JSON.parse(c),d=u.choices?.[0]?.delta,m={};d?.content&&(m.content=d.content),d?.tool_calls&&(m.toolCalls=d.tool_calls.map(g=>({index:g.index,id:g.id,name:g.function?.name,arguments:g.function?.arguments}))),u.usage&&(m.usage=u.usage),(m.content||m.toolCalls||m.usage)&&(yield m)}catch{}}}}finally{n.releaseLock()}}setDefaultModel(t){this.defaultModel=t}getDefaultModel(){return this.defaultModel}resetAvailability(){this._available=null,this._availableCheckedAt=0}}});var Z4e={};$n(Z4e,{AnthropicProvider:()=>Oq,CURATED_OPENROUTER_MODELS:()=>pv,ModelRouter:()=>c9,OllamaProvider:()=>k2,OpenRouterProvider:()=>kR});import fRt from"@anthropic-ai/sdk";var Oq,Y4e,X4e,k2,Pq,pv,kR,c9,u9=G(()=>{"use strict";vc();x2();G4e();V4e();W4e();J4e();K4e();Oq=class{constructor(t){this.name="anthropic";this.client=new fRt({apiKey:t})}async createMessage(t){let n=t.messages.filter(s=>s.role!=="system").map(s=>({role:s.role,content:typeof s.content=="string"?s.content:this.convertToAnthropicContent(s.content)})),r=await this.client.messages.create({model:t.model||"claude-haiku-4-5-20251001",max_tokens:t.maxTokens||4096,temperature:t.temperature??.5,system:t.system,messages:n});return{content:r.content.filter(s=>s.type==="text").map(s=>s.text).join(""),inputTokens:r.usage.input_tokens,outputTokens:r.usage.output_tokens,model:t.model||"claude-haiku-4-5-20251001",provider:"anthropic"}}async createMessageWithTools(t){let n=t.tools.map(i=>({name:i.function.name,description:i.function.description,input_schema:i.function.parameters})),r=[];for(let i of t.messages)if(i.role!=="system")if(i.role==="tool"&&i.tool_call_id){let l=typeof i.content=="string"?i.content:JSON.stringify(i.content);r.push({role:"user",content:[{type:"tool_result",tool_use_id:i.tool_call_id,content:l}]})}else if(i.role==="assistant"&&i.tool_calls&&i.tool_calls.length>0){let l=[],c=typeof i.content=="string"?i.content:"";c&&l.push({type:"text",text:c});for(let u of i.tool_calls){let d;try{d=JSON.parse(u.function.arguments)}catch{d={}}l.push({type:"tool_use",id:u.id,name:u.function.name,input:d})}r.push({role:"assistant",content:l})}else r.push({role:i.role,content:typeof i.content=="string"?i.content:this.convertToAnthropicContent(i.content)});let o=await this.client.messages.create({model:t.model||"claude-haiku-4-5-20251001",max_tokens:t.maxTokens||4096,temperature:t.temperature??.5,system:t.system,messages:r,tools:n,tool_choice:{type:"auto"}}),s="",a=[];for(let i of o.content)if(i.type==="text")s+=i.text;else if(i.type==="tool_use"){let l=i;a.push({id:l.id,type:"function",function:{name:l.name,arguments:JSON.stringify(l.input)}})}return{content:s,inputTokens:o.usage.input_tokens,outputTokens:o.usage.output_tokens,model:t.model||"claude-haiku-4-5-20251001",provider:"anthropic",toolCalls:a}}convertToAnthropicContent(t){if(!t.some(o=>o.type==="image_url"))return t.filter(o=>o.type==="text").map(o=>o.text).join(`
|
|
413
413
|
`);let r=[];for(let o of t)if(o.type==="text")r.push({type:"text",text:o.text});else if(o.type==="image_url"){let a=o.image_url.url.match(/^data:(image\/[^;]+);base64,(.+)$/);if(a){let i=a[1];r.push({type:"image",source:{type:"base64",media_type:i,data:a[2]}})}}return r}async isAvailable(){return!0}},Y4e=3e4,X4e=5e3,k2=class{constructor(t,n){this.name="ollama";this._available=null;this._availableCheckedAt=0;this._responseCallback=null;this.baseUrl=t.replace(/\/$/,""),this.defaultModel=n}setResponseCallback(t){this._responseCallback=t}async createMessage(t){let n=t.model||this.defaultModel,r=[];t.system&&r.push({role:"system",content:t.system});for(let u of t.messages)r.push({role:u.role,content:u.content});let o=Date.now(),s;try{s=await fetch(`${this.baseUrl}/v1/chat/completions`,{method:"POST",headers:{"Content-Type":"application/json"},signal:AbortSignal.timeout(12e4),body:JSON.stringify({model:n,messages:r,max_tokens:t.maxTokens||4096,temperature:t.temperature??.5,stream:!1,options:{num_ctx:t.numCtx||Mg(n)}})})}catch(u){throw this._available=null,this._availableCheckedAt=0,u}s.ok||await this.throwOllamaError(s);let a=await s.json(),i=a.choices?.[0]?.message?.content||"",l=a.usage||{prompt_tokens:0,completion_tokens:0},c=Date.now()-o;if(this._responseCallback)try{this._responseCallback(n,l.prompt_tokens,l.completion_tokens,c)}catch{}return{content:i,inputTokens:l.prompt_tokens,outputTokens:l.completion_tokens,model:n,provider:"ollama"}}async createMessageWithTools(t){let n=t.model||this.defaultModel,r=[];t.system&&r.push({role:"system",content:t.system});for(let m of t.messages){let g={role:m.role,content:m.content};m.tool_call_id&&(g.tool_call_id=m.tool_call_id),m.tool_calls&&(g.tool_calls=m.tool_calls),r.push(g)}let o=Date.now(),s;try{s=await fetch(`${this.baseUrl}/v1/chat/completions`,{method:"POST",headers:{"Content-Type":"application/json"},signal:AbortSignal.timeout(12e4),body:JSON.stringify({model:n,messages:r,max_tokens:t.maxTokens||4096,temperature:t.temperature??.5,stream:!1,tools:t.tools,tool_choice:"auto",options:{num_ctx:t.numCtx||Mg(n)}})})}catch(m){throw this._available=null,this._availableCheckedAt=0,m}s.ok||await this.throwOllamaError(s);let a=await s.json(),i=a.choices?.[0],l=i?.message?.content||"",c=a.usage||{prompt_tokens:0,completion_tokens:0},u=Date.now()-o;if(this._responseCallback)try{this._responseCallback(n,c.prompt_tokens,c.completion_tokens,u)}catch{}let d=(i?.message?.tool_calls||[]).filter(m=>m.function&&typeof m.function.name=="string").map((m,g)=>({id:m.id||`call_${g}_${Date.now()}_${Math.random().toString(36).slice(2,6)}`,type:"function",function:{name:m.function.name,arguments:m.function.arguments??"{}"}}));return{content:l,inputTokens:c.prompt_tokens,outputTokens:c.completion_tokens,model:n,provider:"ollama",toolCalls:d}}async isAvailable(){if(this._available!==null){let t=this._available?Y4e:X4e;if(Date.now()-this._availableCheckedAt<t)return this._available}try{let t=await fetch(`${this.baseUrl}/api/tags`,{signal:AbortSignal.timeout(3e3)});return this._available=t.ok,this._availableCheckedAt=Date.now(),this._available}catch{return this._available=!1,this._availableCheckedAt=Date.now(),!1}}async throwOllamaError(t){let n=await t.text(),r=n.toLowerCase();throw r.includes("out of memory")||r.includes("cuda")||r.includes("mmap")||r.includes("oom")||r.includes("not enough memory")?new Error(`Model too large for available memory. Try a smaller model. Ollama: ${n.slice(0,200)}`):t.status===404||r.includes("not found")||r.includes("no such model")?new Error(`Model not found in Ollama. Make sure it's downloaded first. Ollama: ${n.slice(0,200)}`):new Error(`Ollama request failed (${t.status}): ${n}`)}async*createMessageStreaming(t){let n=t.model||this.defaultModel,r=[];t.system&&r.push({role:"system",content:t.system});for(let c of t.messages)r.push({role:c.role,content:c.content});let o=Date.now(),s;try{s=await fetch(`${this.baseUrl}/v1/chat/completions`,{method:"POST",headers:{"Content-Type":"application/json"},signal:AbortSignal.timeout(12e4),body:JSON.stringify({model:n,messages:r,max_tokens:t.maxTokens||4096,temperature:t.temperature??.5,stream:!0,options:{num_ctx:t.numCtx||Mg(n)}})})}catch(c){throw this._available=null,this._availableCheckedAt=0,c}s.ok||await this.throwOllamaError(s);let a="",i={prompt_tokens:0,completion_tokens:0};for await(let c of this.parseOllamaStream(s))c.content&&(a+=c.content,yield{type:"token",content:c.content}),c.usage&&(i=c.usage);let l=Date.now()-o;if(this._responseCallback)try{this._responseCallback(n,i.prompt_tokens,i.completion_tokens,l)}catch{}return{content:a,inputTokens:i.prompt_tokens,outputTokens:i.completion_tokens,model:n,provider:"ollama"}}async*createMessageWithToolsStreaming(t){let n=t.model||this.defaultModel,r=[];t.system&&r.push({role:"system",content:t.system});for(let m of t.messages){let g={role:m.role,content:m.content};m.tool_call_id&&(g.tool_call_id=m.tool_call_id),m.tool_calls&&(g.tool_calls=m.tool_calls),r.push(g)}let o=Date.now(),s;try{s=await fetch(`${this.baseUrl}/v1/chat/completions`,{method:"POST",headers:{"Content-Type":"application/json"},signal:AbortSignal.timeout(12e4),body:JSON.stringify({model:n,messages:r,max_tokens:t.maxTokens||4096,temperature:t.temperature??.5,stream:!0,tools:t.tools,tool_choice:"auto",options:{num_ctx:t.numCtx||Mg(n)}})})}catch(m){throw this._available=null,this._availableCheckedAt=0,m}s.ok||await this.throwOllamaError(s);let a="",i={prompt_tokens:0,completion_tokens:0},l=new Map,c=!1;for await(let m of this.parseOllamaStream(s)){if(m.content&&!c?(a+=m.content,yield{type:"token",content:m.content}):m.content&&(a+=m.content),m.toolCalls){c=!0;for(let g of m.toolCalls){let h=l.get(g.index);h?(g.name&&(h.name+=g.name),g.arguments&&(h.arguments+=g.arguments)):l.set(g.index,{id:g.id||`call_${g.index}_${Date.now()}_${Math.random().toString(36).slice(2,6)}`,name:g.name||"",arguments:g.arguments||""})}}m.usage&&(i=m.usage)}let u=Date.now()-o;if(this._responseCallback)try{this._responseCallback(n,i.prompt_tokens,i.completion_tokens,u)}catch{}let d=Array.from(l.values()).filter(m=>m.name).map(m=>({id:m.id,type:"function",function:{name:m.name,arguments:m.arguments||"{}"}}));return{content:a,inputTokens:i.prompt_tokens,outputTokens:i.completion_tokens,model:n,provider:"ollama",toolCalls:d}}async*parseOllamaStream(t){if(!t.body)return;let n=t.body.getReader(),r=new TextDecoder,o="";try{for(;;){let{done:s,value:a}=await n.read();if(s)break;o+=r.decode(a,{stream:!0});let i=o.split(`
|
|
414
|
-
`);o=i.pop()||"";for(let l of i){if(!l.startsWith("data: "))continue;let c=l.slice(6).trim();if(c!=="[DONE]")try{let u=JSON.parse(c),d=u.choices?.[0]?.delta,m={};d?.content&&(m.content=d.content),d?.tool_calls&&(m.toolCalls=d.tool_calls.map(g=>({index:g.index,id:g.id,name:g.function?.name,arguments:g.function?.arguments}))),u.usage&&(m.usage=u.usage),(m.content||m.toolCalls||m.usage)&&(yield m)}catch{}}}}finally{n.releaseLock()}}setDefaultModel(t){this.defaultModel=t}getDefaultModel(){return this.defaultModel}resetAvailability(){this._available=null,this._availableCheckedAt=0}async listModels(){try{let t=await fetch(`${this.baseUrl}/api/tags`,{signal:AbortSignal.timeout(3e3)});return t.ok?((await t.json()).models||[]).map(r=>r.name):[]}catch{return[]}}},Pq="https://openrouter.ai/api/v1",pv=[{id:"google/gemini-3.1-flash-lite-preview",name:"Gemini 3.1 Flash Lite",contextLength:1048576,pricing:{prompt:25e-8,completion:15e-7},supportsTools:!0,supportsVision:!0,isFree:!1},{id:"deepseek/deepseek-v3.2",name:"DeepSeek V3.2",contextLength:163840,pricing:{prompt:26e-8,completion:38e-8},supportsTools:!0,supportsVision:!1,isFree:!1},{id:"xiaomi/mimo-v2-flash",name:"MiMo-V2-Flash",contextLength:262144,pricing:{prompt:0,completion:0},supportsTools:!0,supportsVision:!1,isFree:!0},{id:"google/gemini-3.1-flash-image-preview",name:"Nano Banana 2 (image gen)",contextLength:65536,pricing:{prompt:5e-7,completion:3e-6},supportsTools:!1,supportsVision:!0,isFree:!1},{id:"qwen/qwen3.5-9b",name:"Qwen 3.5 9B",contextLength:262144,pricing:{prompt:5e-8,completion:15e-8},supportsTools:!0,supportsVision:!0,isFree:!1},{id:"qwen/qwen3.5-35b-a3b",name:"Qwen 3.5 35B",contextLength:262144,pricing:{prompt:16e-8,completion:13e-7},supportsTools:!0,supportsVision:!0,isFree:!1},{id:"google/gemini-3-flash-preview",name:"Gemini 3 Flash",contextLength:1048576,pricing:{prompt:5e-7,completion:3e-6},supportsTools:!0,supportsVision:!0,isFree:!1},{id:"anthropic/claude-sonnet-4.6",name:"Claude Sonnet 4.6",contextLength:1e6,pricing:{prompt:3e-6,completion:15e-6},supportsTools:!0,supportsVision:!0,isFree:!1},{id:"deepseek/deepseek-r1",name:"DeepSeek R1",contextLength:64e3,pricing:{prompt:7e-7,completion:25e-7},supportsTools:!1,supportsVision:!1,isFree:!1},{id:"google/gemini-3.1-pro-preview",name:"Gemini 3.1 Pro",contextLength:1048576,pricing:{prompt:2e-6,completion:12e-6},supportsTools:!0,supportsVision:!0,isFree:!1},{id:"z-ai/glm-5.1",name:"GLM 5.1",contextLength:2e5,pricing:{prompt:1e-6,completion:32e-7},supportsTools:!0,supportsVision:!1,isFree:!1},{id:"xiaomi/mimo-v2-pro",name:"MiMo-V2-Pro",contextLength:1048576,pricing:{prompt:1e-6,completion:3e-6},supportsTools:!0,supportsVision:!1,isFree:!1},{id:"anthropic/claude-haiku-4.5",name:"Claude Haiku 4.5",contextLength:2e5,pricing:{prompt:1e-6,completion:5e-6},supportsTools:!0,supportsVision:!0,isFree:!1},{id:"anthropic/claude-opus-4.6",name:"Claude Opus 4.6",contextLength:1e6,pricing:{prompt:5e-6,completion:25e-6},supportsTools:!0,supportsVision:!0,isFree:!1},{id:"xiaomi/mimo-v2-omni",name:"MiMo-V2-Omni",contextLength:262144,pricing:{prompt:4e-7,completion:2e-6},supportsTools:!0,supportsVision:!0,isFree:!1},{id:"mistralai/devstral-2512",name:"Devstral 2",contextLength:262144,pricing:{prompt:5e-8,completion:22e-8},supportsTools:!0,supportsVision:!1,isFree:!1},{id:"qwen/qwen3.5-flash-02-23",name:"Qwen 3.5 Flash",contextLength:1e6,pricing:{prompt:7e-8,completion:26e-8},supportsTools:!0,supportsVision:!1,isFree:!1}],kR=class e{constructor(t,n="deepseek/deepseek-v3.2"){this.name="openrouter";this._available=null;this._availableCheckedAt=0;this._modelsCache=null;this._modelsCachedAt=0;this.apiKey=t,this.defaultModel=n}static{this.MODELS_CACHE_TTL_MS=300*1e3}getHeaders(){return{Authorization:`Bearer ${this.apiKey}`,"Content-Type":"application/json","HTTP-Referer":"https://ohwow.fun","X-Title":"OHWOW"}}async createMessage(t){let n=t.model||this.defaultModel,r=[];t.system&&r.push({role:"system",content:t.system});for(let m of t.messages)r.push({role:m.role,content:m.content});let o=Date.now(),s;try{s=await fetch(`${Pq}/chat/completions`,{method:"POST",headers:this.getHeaders(),signal:AbortSignal.timeout(12e4),body:JSON.stringify({model:n,messages:r,max_tokens:t.maxTokens||4096,temperature:t.temperature??.5,stream:!1})})}catch(m){throw this._available=null,this._availableCheckedAt=0,m}if(!s.ok){let m=await s.text().catch(()=>"");throw new Error(`OpenRouter request failed (${s.status}): ${m.slice(0,200)}`)}let a=await s.json(),i=a.choices?.[0]?.message?.content||"",l=a.usage||{prompt_tokens:0,completion_tokens:0},c=Date.now()-o,u=s.headers.get("x-openrouter-cost"),d=u?Math.ceil(parseFloat(u)*100):void 0;return{content:i,inputTokens:l.prompt_tokens,outputTokens:l.completion_tokens,model:n,provider:"openrouter",costCents:d}}async createMessageWithTools(t){let n=t.model||this.defaultModel,r=[];t.system&&r.push({role:"system",content:t.system});for(let m of t.messages){let g={role:m.role,content:m.content};m.tool_call_id&&(g.tool_call_id=m.tool_call_id),m.tool_calls&&(g.tool_calls=m.tool_calls),r.push(g)}let o;try{o=await fetch(`${Pq}/chat/completions`,{method:"POST",headers:this.getHeaders(),signal:AbortSignal.timeout(12e4),body:JSON.stringify({model:n,messages:r,max_tokens:t.maxTokens||4096,temperature:t.temperature??.5,stream:!1,tools:t.tools,tool_choice:"auto"})})}catch(m){throw this._available=null,this._availableCheckedAt=0,m}if(!o.ok){let m=await o.text().catch(()=>"");throw new Error(`OpenRouter request failed (${o.status}): ${m.slice(0,200)}`)}let s=await o.json(),a=s.choices?.[0],i=a?.message?.content||"",l=s.usage||{prompt_tokens:0,completion_tokens:0},c=(a?.message?.tool_calls||[]).filter(m=>m.function&&typeof m.function.name=="string").map((m,g)=>({id:m.id||`call_${g}_${Date.now()}_${Math.random().toString(36).slice(2,6)}`,type:"function",function:{name:m.function.name,arguments:m.function.arguments??"{}"}})),u=o.headers.get("x-openrouter-cost"),d=u?Math.ceil(parseFloat(u)*100):void 0;return{content:i,inputTokens:l.prompt_tokens,outputTokens:l.completion_tokens,model:n,provider:"openrouter",costCents:d,toolCalls:c}}async isAvailable(){if(this._available!==null){let t=this._available?Y4e:X4e;if(Date.now()-this._availableCheckedAt<t)return this._available}try{let t=await fetch(`${Pq}/models`,{headers:{Authorization:`Bearer ${this.apiKey}`},signal:AbortSignal.timeout(5e3)});return this._available=t.ok,this._availableCheckedAt=Date.now(),this._available}catch{return this._available=!1,this._availableCheckedAt=Date.now(),!1}}async listModels(t=!1){if(!t&&this._modelsCache&&Date.now()-this._modelsCachedAt<e.MODELS_CACHE_TTL_MS)return this._modelsCache;try{let n=await fetch(`${Pq}/models`,{headers:{Authorization:`Bearer ${this.apiKey}`},signal:AbortSignal.timeout(1e4)});if(!n.ok)return this._modelsCache||pv;let o=((await n.json()).data||[]).map(c=>{let u=parseFloat(c.pricing?.prompt||"0"),d=parseFloat(c.pricing?.completion||"0"),m=c.architecture?.modality||"";return{id:c.id,name:c.name||c.id,contextLength:c.context_length||4096,pricing:{prompt:u,completion:d},supportsTools:(c.supported_parameters||[]).includes("tools"),supportsVision:m.includes("image")||m.includes("vision"),isFree:u===0&&d===0}}),s=new Set(pv.map(c=>c.id)),a=new Map(o.map(c=>[c.id,c])),i=pv.map(c=>a.get(c.id)||c),l=o.filter(c=>!s.has(c.id));return this._modelsCache=[...i,...l],this._modelsCachedAt=Date.now(),this._modelsCache}catch{return this._modelsCache||pv}}getDefaultModel(){return this.defaultModel}setDefaultModel(t){this.defaultModel=t}setApiKey(t){this.apiKey=t,this._available=null,this._availableCheckedAt=0,this._modelsCache=null,this._modelsCachedAt=0}resetAvailability(){this._available=null,this._availableCheckedAt=0}},c9=class{constructor(t){this._onOllamaResponse=null;this._creditBalancePercent=100;if(this.anthropic=t.anthropicApiKey?new Oq(t.anthropicApiKey):null,this.modelSource=t.modelSource??"auto",this.cloudProvider=t.cloudProvider??"anthropic",this.ollama=t.ollamaUrl?new k2(t.ollamaUrl,t.ollamaModel||"qwen3:4b"):null,this.ocrOllama=t.ollamaUrl&&t.ocrModel?new k2(t.ollamaUrl,t.ocrModel):null,this.quickOllama=t.ollamaUrl&&t.quickModel?new k2(t.ollamaUrl,t.quickModel):null,this.openrouter=t.openRouterApiKey?new kR(t.openRouterApiKey,t.openRouterModel||"deepseek/deepseek-v3.2"):null,this.claudeCode=this.modelSource==="claude-code"?new l9(t.claudeCodeCliPath,t.claudeCodeCliModel):null,this.llamaCpp=t.llamaCppUrl&&t.turboQuantBits&&t.turboQuantBits>0?new Dq(t.llamaCppUrl,t.ollamaModel||"qwen3:4b"):null,this.mlx=t.mlxServerUrl&&t.mlxEnabled?new Bq(t.mlxServerUrl,t.mlxModel||""):null,this.openaiCompatible=t.openaiCompatibleUrl?new Mq(t.openaiCompatibleUrl,t.ollamaModel||"qwen3:4b",t.openaiCompatibleApiKey||void 0):null,this.preferLocal=t.preferLocalModel??!1,this.mainModelHasVision=t.mainModelHasVision??!1,this.mainModelHasAudio=t.mainModelHasAudio??!1,this._openRouterApiKey=t.openRouterApiKey??"",this._onOllamaResponse=t.onOllamaResponse??null,this._onOllamaResponse){let n=this._onOllamaResponse;this.ollama?.setResponseCallback(n),this.ocrOllama?.setResponseCallback(n),this.quickOllama?.setResponseCallback(n),this.llamaCpp?.setResponseCallback(n),this.mlx?.setResponseCallback(n),this.openaiCompatible?.setResponseCallback(n)}}setOnOllamaResponse(t){this._onOllamaResponse=t,this.ollama?.setResponseCallback(t),this.ocrOllama?.setResponseCallback(t)}notifyOllamaResponse(t,n,r,o){if(this._onOllamaResponse)try{this._onOllamaResponse(t,n,r,o)}catch{}}async tryCloudProvider(){if(this.cloudProvider==="openrouter"){if(this.openrouter&&await this.openrouter.isAvailable())return this.openrouter;if(this.anthropic)return this.anthropic}else{if(this.anthropic)return this.anthropic;if(this.openrouter&&await this.openrouter.isAvailable())return this.openrouter}return null}async getProvider(t,n,r,o){if(o&&this.modelSource==="auto"){let{avgTruthScore:i,attempts:l}=o;if(l>=5&&i<60&&this.anthropic)return this.anthropic;if(l>=10&&i>85&&this.ollama&&await this.ollama.isAvailable())return this.ollama}if(t==="ocr"||t==="vision"){if(this.mlx&&await this.mlx.isAvailable())return this.mlx;if(this.ocrOllama&&await this.ocrOllama.isAvailable())return this.ocrOllama;if(this.mainModelHasVision&&this.ollama&&await this.ollama.isAvailable())return this.ollama;if(this.anthropic)return this.anthropic;throw new Error("No vision-capable model available. Configure an OCR model, use a vision-capable local model, or add an Anthropic API key.")}if(t==="audio"){if(this.mlx&&await this.mlx.isAvailable())return this.mlx;if(this.mainModelHasAudio&&this.ollama&&await this.ollama.isAvailable())return this.ollama;if(this.anthropic)return this.anthropic;throw new Error("No audio-capable model available. Install Gemma 4 E2B or E4B, or add an Anthropic API key.")}if(r&&this.modelSource==="auto"){let i=$4e(r);if(H4e(i,this._creditBalancePercent)){if(this.ollama&&await this.ollama.isAvailable())return this.ollama;if(i.fallback==="cloud"){let l=await this.tryCloudProvider();if(l)return l}}else if(i.modelSource==="cloud"){let l=await this.tryCloudProvider();if(l)return l;if(i.fallback==="local"&&this.ollama&&await this.ollama.isAvailable())return this.ollama}}if(this.modelSource==="claude-code"){if(this.claudeCode&&await this.claudeCode.isAvailable())return this.claudeCode;if(this.ollama&&await this.ollama.isAvailable())return this.ollama;if(this.anthropic)return this.anthropic;throw new Error("Claude Code mode selected but the CLI is not available. Make sure Claude Code is installed and authenticated.")}if(this.modelSource==="cloud"){if(this.cloudProvider==="openrouter"){if(this.openrouter&&await this.openrouter.isAvailable())return this.openrouter;if(this.anthropic)return this.anthropic;if(this.ollama&&await this.ollama.isAvailable())return this.ollama;throw new Error("Cloud mode with OpenRouter selected but OpenRouter is not available. Check your API key or switch provider.")}if(this.anthropic)return this.anthropic;if(this.openrouter&&await this.openrouter.isAvailable())return this.openrouter;if(this.ollama&&await this.ollama.isAvailable())return this.ollama;throw new Error("Cloud mode selected but no API key configured. Add an Anthropic or OpenRouter API key, or switch to local mode.")}if(this.modelSource==="local"){if(this.mlx&&await this.mlx.isAvailable())return this.mlx;if(this.llamaCpp&&await this.llamaCpp.isAvailable())return this.llamaCpp;if(this.openaiCompatible&&await this.openaiCompatible.isAvailable())return this.openaiCompatible;if(this.ollama&&await this.ollama.isAvailable())return this.ollama;if(this.anthropic)return this.anthropic;throw new Error("Local mode selected but neither llama-server nor Ollama is running. Start a local server or switch to cloud mode.")}if(n==="simple"&&this.quickOllama&&await this.quickOllama.isAvailable())return this.quickOllama;if(n==="complex"&&this.anthropic)return this.anthropic;if(this.preferLocal&&(this.mlx||this.llamaCpp||this.openaiCompatible||this.ollama)&&(t==="orchestrator"||t==="memory_extraction")){if(this.mlx&&await this.mlx.isAvailable())return this.mlx;if(this.llamaCpp&&await this.llamaCpp.isAvailable())return this.llamaCpp;if(this.openaiCompatible&&await this.openaiCompatible.isAvailable())return this.openaiCompatible;if(this.ollama&&await this.ollama.isAvailable())return this.ollama}let a=await this.tryCloudProvider();if(a)return a;if(this.openaiCompatible&&await this.openaiCompatible.isAvailable())return this.openaiCompatible;if(this.ollama&&await this.ollama.isAvailable())return this.ollama;throw new Error("No model provider available. Make sure Ollama is running, or configure an Anthropic API key.")}async selectModelWithContext(t,n){let r=n.difficulty;if(n.endocrineEffects){let o=n.endocrineEffects.find(a=>a.parameter==="ambition");o&&o.modifier<.85&&(!r||r==="simple"?r="moderate":r==="moderate"&&(r="complex"));let s=n.endocrineEffects.find(a=>a.parameter==="prediction_confidence");s&&s.modifier>1.1&&r==="complex"&&(r="moderate")}return n.selfModelConfidence!==void 0&&n.selfModelConfidence<.3&&(r="complex"),n.recentPredictionAccuracy!==void 0&&n.recentPredictionAccuracy<.3&&(r="complex"),this.getProvider(t,r,void 0,n.routingHistory)}getAnthropicProvider(){return this.anthropic}getOllamaProvider(){return this.ollama}getOcrProvider(){return this.ocrOllama}async isOllamaAvailable(){return this.ollama?this.ollama.isAvailable():!1}resetOllamaStatus(){this.ollama?.resetAvailability()}setOllamaModel(t){this.ollama?.setDefaultModel(t),this.ollama?.resetAvailability()}setModelSource(t){this.modelSource=t,t==="claude-code"&&!this.claudeCode&&(this.claudeCode=new l9)}setCloudProvider(t){this.cloudProvider=t,t==="openrouter"&&!this.openrouter&&this._openRouterApiKey&&(this.openrouter=new kR(this._openRouterApiKey))}getCloudProvider(){return this.cloudProvider}getOpenRouterProvider(){return this.openrouter}getOpenRouterApiKey(){return this._openRouterApiKey}setOpenRouterApiKey(t){this._openRouterApiKey=t,t?this.openrouter?this.openrouter.setApiKey(t):this.openrouter=new kR(t):this.openrouter=null}setOpenRouterModel(t){this.openrouter?.setDefaultModel(t)}setCreditBalance(t){this._creditBalancePercent=Math.max(0,Math.min(100,t))}getCreditBalance(){return this._creditBalancePercent}async getContextLimit(t,n){let r;try{r=await this.getProvider(t)}catch{return E2["claude-sonnet-4-5"]}return r.name==="anthropic"?E2["claude-sonnet-4-5"]:r.name==="ollama"&&this.ollama?Mg(this.ollama.getDefaultModel(),n):E2["claude-sonnet-4-5"]}}});function T2(e,t){let n=e/1e6*gRt,r=t/1e6*hRt;return Math.round((n+r)*100)/100}async function I2(e,t){try{let n=await e.getProvider("memory_extraction"),r=[{role:"user",content:t.userMessage}],o={system:t.system,messages:r,maxTokens:t.maxTokens??300,temperature:t.temperature??.3},s=await n.createMessage(o);return{success:!0,content:s.content,inputTokens:s.inputTokens,outputTokens:s.outputTokens,tokensUsed:s.inputTokens+s.outputTokens}}catch(n){let r=n instanceof Error?n.message:String(n);return U.error({err:r},"[LLMHelper] LLM call failed"),{success:!1,content:"",inputTokens:0,outputTokens:0,tokensUsed:0,error:r}}}function R2(e){try{let t=e.trim(),n=t.match(/^```(?:json)?\s*\n?([\s\S]*?)```$/);return n&&(t=n[1].trim()),JSON.parse(t)}catch{return null}}function TR(e){return e.toLowerCase().replace(/[^\w\s]/g," ").split(/\s+/).filter(t=>t.length>2&&!yRt.has(t))}function Nq(e,t){let n=new Set(e),r=new Set(t),o=0;for(let a of n)r.has(a)&&o++;let s=n.size+r.size-o;return s===0?0:o/s}var gRt,hRt,yRt,d9=G(()=>{"use strict";wt();gRt=.8,hRt=4;yRt=new Set(["the","a","an","is","was","are","were","be","been","being","have","has","had","do","does","did","will","would","could","should","may","might","shall","can","to","of","in","for","on","with","at","by","from","as","into","about","and","or","but","not","no","it","its","this","that","these","those","when","where","what","which","who","whom","how","if","then","than","so","up","out","just","also","very"])});function bRt(e){let t=[],n=new Set,r=e.map(o=>({memory:o,keywords:TR(o.content)}));for(let{memory:o,keywords:s}of r){if(n.has(o.id))continue;let a=[o];n.add(o.id);for(let{memory:i,keywords:l}of r)n.has(i.id)||Nq(s,l)>=.3&&(a.push(i),n.add(i.id));if(a.length>=vRt){let i=a.flatMap(u=>TR(u.content)),l=new Map;for(let u of i)l.set(u,(l.get(u)||0)+1);let c=[...l.entries()].sort((u,d)=>d[1]-u[1]).slice(0,3).map(([u])=>u);t.push({theme:c.join(", "),memories:a})}}return t}function CRt(e){let t=e.memories.map(n=>`- [${n.memory_type}] ${n.content}`).join(`
|
|
414
|
+
`);o=i.pop()||"";for(let l of i){if(!l.startsWith("data: "))continue;let c=l.slice(6).trim();if(c!=="[DONE]")try{let u=JSON.parse(c),d=u.choices?.[0]?.delta,m={};d?.content&&(m.content=d.content),d?.tool_calls&&(m.toolCalls=d.tool_calls.map(g=>({index:g.index,id:g.id,name:g.function?.name,arguments:g.function?.arguments}))),u.usage&&(m.usage=u.usage),(m.content||m.toolCalls||m.usage)&&(yield m)}catch{}}}}finally{n.releaseLock()}}setDefaultModel(t){this.defaultModel=t}getDefaultModel(){return this.defaultModel}resetAvailability(){this._available=null,this._availableCheckedAt=0}async listModels(){try{let t=await fetch(`${this.baseUrl}/api/tags`,{signal:AbortSignal.timeout(3e3)});return t.ok?((await t.json()).models||[]).map(r=>r.name):[]}catch{return[]}}},Pq="https://openrouter.ai/api/v1",pv=[{id:"google/gemini-3.1-flash-lite-preview",name:"Gemini 3.1 Flash Lite",contextLength:1048576,pricing:{prompt:25e-8,completion:15e-7},supportsTools:!0,supportsVision:!0,isFree:!1},{id:"deepseek/deepseek-v3.2",name:"DeepSeek V3.2",contextLength:163840,pricing:{prompt:26e-8,completion:38e-8},supportsTools:!0,supportsVision:!1,isFree:!1},{id:"xiaomi/mimo-v2-flash",name:"MiMo-V2-Flash",contextLength:262144,pricing:{prompt:0,completion:0},supportsTools:!0,supportsVision:!1,isFree:!0},{id:"google/gemini-3.1-flash-image-preview",name:"Nano Banana 2 (image gen)",contextLength:65536,pricing:{prompt:5e-7,completion:3e-6},supportsTools:!1,supportsVision:!0,isFree:!1},{id:"qwen/qwen3.5-9b",name:"Qwen 3.5 9B",contextLength:262144,pricing:{prompt:5e-8,completion:15e-8},supportsTools:!0,supportsVision:!0,isFree:!1},{id:"qwen/qwen3.5-35b-a3b",name:"Qwen 3.5 35B",contextLength:262144,pricing:{prompt:16e-8,completion:13e-7},supportsTools:!0,supportsVision:!0,isFree:!1},{id:"google/gemini-3-flash-preview",name:"Gemini 3 Flash",contextLength:1048576,pricing:{prompt:5e-7,completion:3e-6},supportsTools:!0,supportsVision:!0,isFree:!1},{id:"anthropic/claude-sonnet-4.6",name:"Claude Sonnet 4.6",contextLength:1e6,pricing:{prompt:3e-6,completion:15e-6},supportsTools:!0,supportsVision:!0,isFree:!1},{id:"deepseek/deepseek-r1",name:"DeepSeek R1",contextLength:64e3,pricing:{prompt:7e-7,completion:25e-7},supportsTools:!1,supportsVision:!1,isFree:!1},{id:"google/gemini-3.1-pro-preview",name:"Gemini 3.1 Pro",contextLength:1048576,pricing:{prompt:2e-6,completion:12e-6},supportsTools:!0,supportsVision:!0,isFree:!1},{id:"z-ai/glm-5.1",name:"GLM 5.1",contextLength:2e5,pricing:{prompt:1e-6,completion:32e-7},supportsTools:!0,supportsVision:!1,isFree:!1},{id:"xiaomi/mimo-v2-pro",name:"MiMo-V2-Pro",contextLength:1048576,pricing:{prompt:1e-6,completion:3e-6},supportsTools:!0,supportsVision:!1,isFree:!1},{id:"anthropic/claude-haiku-4.5",name:"Claude Haiku 4.5",contextLength:2e5,pricing:{prompt:1e-6,completion:5e-6},supportsTools:!0,supportsVision:!0,isFree:!1},{id:"anthropic/claude-opus-4.6",name:"Claude Opus 4.6",contextLength:1e6,pricing:{prompt:5e-6,completion:25e-6},supportsTools:!0,supportsVision:!0,isFree:!1},{id:"xiaomi/mimo-v2-omni",name:"MiMo-V2-Omni",contextLength:262144,pricing:{prompt:4e-7,completion:2e-6},supportsTools:!0,supportsVision:!0,isFree:!1},{id:"mistralai/devstral-2512",name:"Devstral 2",contextLength:262144,pricing:{prompt:5e-8,completion:22e-8},supportsTools:!0,supportsVision:!1,isFree:!1},{id:"qwen/qwen3.5-flash-02-23",name:"Qwen 3.5 Flash",contextLength:1e6,pricing:{prompt:7e-8,completion:26e-8},supportsTools:!0,supportsVision:!1,isFree:!1}],kR=class e{constructor(t,n="deepseek/deepseek-v3.2"){this.name="openrouter";this._available=null;this._availableCheckedAt=0;this._modelsCache=null;this._modelsCachedAt=0;this.apiKey=t,this.defaultModel=n}static{this.MODELS_CACHE_TTL_MS=300*1e3}getHeaders(){return{Authorization:`Bearer ${this.apiKey}`,"Content-Type":"application/json","HTTP-Referer":"https://ohwow.fun","X-Title":"OHWOW"}}async createMessage(t){let n=t.model||this.defaultModel,r=[];t.system&&r.push({role:"system",content:t.system});for(let m of t.messages)r.push({role:m.role,content:m.content});let o=Date.now(),s;try{s=await fetch(`${Pq}/chat/completions`,{method:"POST",headers:this.getHeaders(),signal:AbortSignal.timeout(12e4),body:JSON.stringify({model:n,messages:r,max_tokens:t.maxTokens||4096,temperature:t.temperature??.5,stream:!1})})}catch(m){throw this._available=null,this._availableCheckedAt=0,m}if(!s.ok){let m=await s.text().catch(()=>"");throw new Error(`OpenRouter request failed (${s.status}): ${m.slice(0,200)}`)}let a=await s.json(),i=a.choices?.[0]?.message?.content||"",l=a.usage||{prompt_tokens:0,completion_tokens:0},c=Date.now()-o,u=s.headers.get("x-openrouter-cost"),d=u?Math.ceil(parseFloat(u)*100):void 0;return{content:i,inputTokens:l.prompt_tokens,outputTokens:l.completion_tokens,model:n,provider:"openrouter",costCents:d}}async createMessageWithTools(t){let n=t.model||this.defaultModel,r=[];t.system&&r.push({role:"system",content:t.system});for(let m of t.messages){let g={role:m.role,content:m.content};m.tool_call_id&&(g.tool_call_id=m.tool_call_id),m.tool_calls&&(g.tool_calls=m.tool_calls),r.push(g)}let o;try{o=await fetch(`${Pq}/chat/completions`,{method:"POST",headers:this.getHeaders(),signal:AbortSignal.timeout(12e4),body:JSON.stringify({model:n,messages:r,max_tokens:t.maxTokens||4096,temperature:t.temperature??.5,stream:!1,tools:t.tools,tool_choice:"auto"})})}catch(m){throw this._available=null,this._availableCheckedAt=0,m}if(!o.ok){let m=await o.text().catch(()=>"");throw new Error(`OpenRouter request failed (${o.status}): ${m.slice(0,200)}`)}let s=await o.json(),a=s.choices?.[0],i=a?.message?.content||"",l=s.usage||{prompt_tokens:0,completion_tokens:0},c=(a?.message?.tool_calls||[]).filter(m=>m.function&&typeof m.function.name=="string").map((m,g)=>({id:m.id||`call_${g}_${Date.now()}_${Math.random().toString(36).slice(2,6)}`,type:"function",function:{name:m.function.name,arguments:m.function.arguments??"{}"}})),u=o.headers.get("x-openrouter-cost"),d=u?Math.ceil(parseFloat(u)*100):void 0;return{content:i,inputTokens:l.prompt_tokens,outputTokens:l.completion_tokens,model:n,provider:"openrouter",costCents:d,toolCalls:c}}async isAvailable(){if(this._available!==null){let t=this._available?Y4e:X4e;if(Date.now()-this._availableCheckedAt<t)return this._available}try{let t=await fetch(`${Pq}/models`,{headers:{Authorization:`Bearer ${this.apiKey}`},signal:AbortSignal.timeout(5e3)});return this._available=t.ok,this._availableCheckedAt=Date.now(),this._available}catch{return this._available=!1,this._availableCheckedAt=Date.now(),!1}}async listModels(t=!1){if(!t&&this._modelsCache&&Date.now()-this._modelsCachedAt<e.MODELS_CACHE_TTL_MS)return this._modelsCache;try{let n=await fetch(`${Pq}/models`,{headers:{Authorization:`Bearer ${this.apiKey}`},signal:AbortSignal.timeout(1e4)});if(!n.ok)return this._modelsCache||pv;let o=((await n.json()).data||[]).map(c=>{let u=parseFloat(c.pricing?.prompt||"0"),d=parseFloat(c.pricing?.completion||"0"),m=c.architecture?.modality||"";return{id:c.id,name:c.name||c.id,contextLength:c.context_length||4096,pricing:{prompt:u,completion:d},supportsTools:(c.supported_parameters||[]).includes("tools"),supportsVision:m.includes("image")||m.includes("vision"),isFree:u===0&&d===0}}),s=new Set(pv.map(c=>c.id)),a=new Map(o.map(c=>[c.id,c])),i=pv.map(c=>a.get(c.id)||c),l=o.filter(c=>!s.has(c.id));return this._modelsCache=[...i,...l],this._modelsCachedAt=Date.now(),this._modelsCache}catch{return this._modelsCache||pv}}getDefaultModel(){return this.defaultModel}setDefaultModel(t){this.defaultModel=t}setApiKey(t){this.apiKey=t,this._available=null,this._availableCheckedAt=0,this._modelsCache=null,this._modelsCachedAt=0}resetAvailability(){this._available=null,this._availableCheckedAt=0}},c9=class{constructor(t){this._onOllamaResponse=null;this._creditBalancePercent=100;if(this.anthropic=t.anthropicApiKey?new Oq(t.anthropicApiKey):null,this.modelSource=t.modelSource??"auto",this.cloudProvider=t.cloudProvider??"anthropic",this.ollama=t.ollamaUrl?new k2(t.ollamaUrl,t.ollamaModel||"qwen3:4b"):null,this.ocrOllama=t.ollamaUrl&&t.ocrModel?new k2(t.ollamaUrl,t.ocrModel):null,this.quickOllama=t.ollamaUrl&&t.quickModel?new k2(t.ollamaUrl,t.quickModel):null,this.openrouter=t.openRouterApiKey?new kR(t.openRouterApiKey,t.openRouterModel||"deepseek/deepseek-v3.2"):null,this.claudeCode=this.modelSource==="claude-code"?new l9(t.claudeCodeCliPath,t.claudeCodeCliModel):null,this.llamaCpp=t.llamaCppUrl&&t.turboQuantBits&&t.turboQuantBits>0?new Dq(t.llamaCppUrl,t.ollamaModel||"qwen3:4b"):null,this.mlx=t.mlxServerUrl&&t.mlxEnabled?new Bq(t.mlxServerUrl,t.mlxModel||""):null,this.openaiCompatible=t.openaiCompatibleUrl?new Mq(t.openaiCompatibleUrl,t.ollamaModel||"qwen3:4b",t.openaiCompatibleApiKey||void 0):null,this.preferLocal=t.preferLocalModel??!1,this.mainModelHasVision=t.mainModelHasVision??!1,this.mainModelHasAudio=t.mainModelHasAudio??!1,this._openRouterApiKey=t.openRouterApiKey??"",this._onOllamaResponse=t.onOllamaResponse??null,this._onOllamaResponse){let n=this._onOllamaResponse;this.ollama?.setResponseCallback(n),this.ocrOllama?.setResponseCallback(n),this.quickOllama?.setResponseCallback(n),this.llamaCpp?.setResponseCallback(n),this.mlx?.setResponseCallback(n),this.openaiCompatible?.setResponseCallback(n)}}setOnOllamaResponse(t){this._onOllamaResponse=t,this.ollama?.setResponseCallback(t),this.ocrOllama?.setResponseCallback(t)}notifyOllamaResponse(t,n,r,o){if(this._onOllamaResponse)try{this._onOllamaResponse(t,n,r,o)}catch{}}async tryCloudProvider(){if(this.cloudProvider==="openrouter"){if(this.openrouter&&await this.openrouter.isAvailable())return this.openrouter;if(this.anthropic)return this.anthropic}else{if(this.anthropic)return this.anthropic;if(this.openrouter&&await this.openrouter.isAvailable())return this.openrouter}return null}async getProvider(t,n,r,o){if(o&&this.modelSource==="auto"){let{avgTruthScore:i,attempts:l}=o;if(l>=5&&i<60&&this.anthropic)return this.anthropic;if(l>=10&&i>85&&this.ollama&&await this.ollama.isAvailable())return this.ollama}if(t==="ocr"||t==="vision"){if(this.mlx&&await this.mlx.isAvailable())return this.mlx;if(this.ocrOllama&&await this.ocrOllama.isAvailable())return this.ocrOllama;if(this.mainModelHasVision&&this.ollama&&await this.ollama.isAvailable())return this.ollama;if(this.anthropic)return this.anthropic;throw new Error("No vision-capable model available. Configure an OCR model, use a vision-capable local model, or add an Anthropic API key.")}if(t==="audio"){if(this.mlx&&await this.mlx.isAvailable())return this.mlx;if(this.mainModelHasAudio&&this.ollama&&await this.ollama.isAvailable())return this.ollama;if(this.anthropic)return this.anthropic;throw new Error("No audio-capable model available. Install Gemma 4 E2B or E4B, or add an Anthropic API key.")}if(r&&this.modelSource==="auto"){let i=$4e(r);if(H4e(i,this._creditBalancePercent)){if(this.ollama&&await this.ollama.isAvailable())return this.ollama;if(i.fallback==="cloud"){let l=await this.tryCloudProvider();if(l)return l}}else if(i.modelSource==="cloud"){let l=await this.tryCloudProvider();if(l)return l;if(i.fallback==="local"&&this.ollama&&await this.ollama.isAvailable())return this.ollama}}if(this.modelSource==="claude-code"){if(this.claudeCode&&await this.claudeCode.isAvailable())return this.claudeCode;if(this.ollama&&await this.ollama.isAvailable())return this.ollama;if(this.anthropic)return this.anthropic;throw new Error("Claude Code mode selected but the CLI is not available. Make sure Claude Code is installed and authenticated.")}if(this.modelSource==="cloud"){if(this.cloudProvider==="openrouter"){if(this.openrouter)return this.openrouter;throw new Error("Cloud mode with OpenRouter selected but no API key configured. Add openRouterApiKey to your config.")}if(this.anthropic)return this.anthropic;if(this.openrouter&&await this.openrouter.isAvailable())return this.openrouter;if(this.ollama&&await this.ollama.isAvailable())return this.ollama;throw new Error("Cloud mode selected but no API key configured. Add an Anthropic or OpenRouter API key, or switch to local mode.")}if(this.modelSource==="local"){if(this.mlx&&await this.mlx.isAvailable())return this.mlx;if(this.llamaCpp&&await this.llamaCpp.isAvailable())return this.llamaCpp;if(this.openaiCompatible&&await this.openaiCompatible.isAvailable())return this.openaiCompatible;if(this.ollama&&await this.ollama.isAvailable())return this.ollama;if(this.anthropic)return this.anthropic;throw new Error("Local mode selected but neither llama-server nor Ollama is running. Start a local server or switch to cloud mode.")}if(n==="simple"&&this.quickOllama&&await this.quickOllama.isAvailable())return this.quickOllama;if(n==="complex"&&this.anthropic)return this.anthropic;if(this.preferLocal&&(this.mlx||this.llamaCpp||this.openaiCompatible||this.ollama)&&(t==="orchestrator"||t==="memory_extraction")){if(this.mlx&&await this.mlx.isAvailable())return this.mlx;if(this.llamaCpp&&await this.llamaCpp.isAvailable())return this.llamaCpp;if(this.openaiCompatible&&await this.openaiCompatible.isAvailable())return this.openaiCompatible;if(this.ollama&&await this.ollama.isAvailable())return this.ollama}let a=await this.tryCloudProvider();if(a)return a;if(this.openaiCompatible&&await this.openaiCompatible.isAvailable())return this.openaiCompatible;if(this.ollama&&await this.ollama.isAvailable())return this.ollama;throw new Error("No model provider available. Make sure Ollama is running, or configure an Anthropic API key.")}async selectModelWithContext(t,n){let r=n.difficulty;if(n.endocrineEffects){let o=n.endocrineEffects.find(a=>a.parameter==="ambition");o&&o.modifier<.85&&(!r||r==="simple"?r="moderate":r==="moderate"&&(r="complex"));let s=n.endocrineEffects.find(a=>a.parameter==="prediction_confidence");s&&s.modifier>1.1&&r==="complex"&&(r="moderate")}return n.selfModelConfidence!==void 0&&n.selfModelConfidence<.3&&(r="complex"),n.recentPredictionAccuracy!==void 0&&n.recentPredictionAccuracy<.3&&(r="complex"),this.getProvider(t,r,void 0,n.routingHistory)}getAnthropicProvider(){return this.anthropic}getOllamaProvider(){return this.ollama}getOcrProvider(){return this.ocrOllama}async isOllamaAvailable(){return this.ollama?this.ollama.isAvailable():!1}resetOllamaStatus(){this.ollama?.resetAvailability()}setOllamaModel(t){this.ollama?.setDefaultModel(t),this.ollama?.resetAvailability()}setModelSource(t){this.modelSource=t,t==="claude-code"&&!this.claudeCode&&(this.claudeCode=new l9)}setCloudProvider(t){this.cloudProvider=t,t==="openrouter"&&!this.openrouter&&this._openRouterApiKey&&(this.openrouter=new kR(this._openRouterApiKey))}getCloudProvider(){return this.cloudProvider}getOpenRouterProvider(){return this.openrouter}getOpenRouterApiKey(){return this._openRouterApiKey}setOpenRouterApiKey(t){this._openRouterApiKey=t,t?this.openrouter?this.openrouter.setApiKey(t):this.openrouter=new kR(t):this.openrouter=null}setOpenRouterModel(t){this.openrouter?.setDefaultModel(t)}setCreditBalance(t){this._creditBalancePercent=Math.max(0,Math.min(100,t))}getCreditBalance(){return this._creditBalancePercent}async getContextLimit(t,n){let r;try{r=await this.getProvider(t)}catch{return E2["claude-sonnet-4-5"]}return r.name==="anthropic"?E2["claude-sonnet-4-5"]:r.name==="ollama"&&this.ollama?Mg(this.ollama.getDefaultModel(),n):E2["claude-sonnet-4-5"]}}});function T2(e,t){let n=e/1e6*gRt,r=t/1e6*hRt;return Math.round((n+r)*100)/100}async function I2(e,t){try{let n=await e.getProvider("memory_extraction"),r=[{role:"user",content:t.userMessage}],o={system:t.system,messages:r,maxTokens:t.maxTokens??300,temperature:t.temperature??.3},s=await n.createMessage(o);return{success:!0,content:s.content,inputTokens:s.inputTokens,outputTokens:s.outputTokens,tokensUsed:s.inputTokens+s.outputTokens}}catch(n){let r=n instanceof Error?n.message:String(n);return U.error({err:r},"[LLMHelper] LLM call failed"),{success:!1,content:"",inputTokens:0,outputTokens:0,tokensUsed:0,error:r}}}function R2(e){try{let t=e.trim(),n=t.match(/^```(?:json)?\s*\n?([\s\S]*?)```$/);return n&&(t=n[1].trim()),JSON.parse(t)}catch{return null}}function TR(e){return e.toLowerCase().replace(/[^\w\s]/g," ").split(/\s+/).filter(t=>t.length>2&&!yRt.has(t))}function Nq(e,t){let n=new Set(e),r=new Set(t),o=0;for(let a of n)r.has(a)&&o++;let s=n.size+r.size-o;return s===0?0:o/s}var gRt,hRt,yRt,d9=G(()=>{"use strict";wt();gRt=.8,hRt=4;yRt=new Set(["the","a","an","is","was","are","were","be","been","being","have","has","had","do","does","did","will","would","could","should","may","might","shall","can","to","of","in","for","on","with","at","by","from","as","into","about","and","or","but","not","no","it","its","this","that","these","those","when","where","what","which","who","whom","how","if","then","than","so","up","out","just","also","very"])});function bRt(e){let t=[],n=new Set,r=e.map(o=>({memory:o,keywords:TR(o.content)}));for(let{memory:o,keywords:s}of r){if(n.has(o.id))continue;let a=[o];n.add(o.id);for(let{memory:i,keywords:l}of r)n.has(i.id)||Nq(s,l)>=.3&&(a.push(i),n.add(i.id));if(a.length>=vRt){let i=a.flatMap(u=>TR(u.content)),l=new Map;for(let u of i)l.set(u,(l.get(u)||0)+1);let c=[...l.entries()].sort((u,d)=>d[1]-u[1]).slice(0,3).map(([u])=>u);t.push({theme:c.join(", "),memories:a})}}return t}function CRt(e){let t=e.memories.map(n=>`- [${n.memory_type}] ${n.content}`).join(`
|
|
415
415
|
`);return`Theme: ${e.theme}
|
|
416
416
|
|
|
417
417
|
Episodic memories (${e.memories.length}):
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ohwow",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.5",
|
|
4
4
|
"description": "Local-first AI business operating system. Put your business ops on autopilot with AI agents that learn, remember, and coordinate.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Jesus David Oñoro Delgado <ogsus@ohwow.fun>",
|