@madh-io/alfred-ai 0.19.0-jarvis.1163 → 0.19.0-jarvis.1164

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/bundle/index.js +2 -2
  2. package/package.json +1 -1
package/bundle/index.js CHANGED
@@ -4189,7 +4189,7 @@ ${e}`,n.id]);return s.length}async appendSkillCall(e,t){let s=(await this.db.que
4189
4189
  `);i.trim()&&t.push({role:"assistant",content:i});for(let r of s.content)r.type==="tool_use"&&t.push({type:"function_call",call_id:r.id,name:r.name,arguments:JSON.stringify(r.input??{})});continue}let n=[];for(let i of s.content)i.type==="text"?n.push({type:"input_text",text:i.text}):i.type==="image"?n.push({type:"input_image",image_url:`data:${i.source.media_type};base64,${i.source.data}`}):i.type==="tool_result"&&t.push({type:"function_call_output",call_id:i.tool_use_id,output:i.is_error?`FEHLER: ${i.content}`:i.content});n.length>0&&t.push({role:"user",content:n})}return t}mapResponsesTools(e){return e.map(t=>({type:"function",name:t.name,description:t.description,parameters:t.inputSchema,strict:!1}))}buildResponsesParams(e){let t;if(e.previousResponseId){let n=e.messages[e.messages.length-1];t=n?this.mapResponsesInput([n]).filter(i=>i.type==="function_call_output"):[],t.length===0&&(t=this.mapResponsesInput(e.messages))}else t=this.mapResponsesInput(e.messages);let s=e.reasoningEffort;return{model:this.config.model,input:t,...e.system?{instructions:e.system}:{},max_output_tokens:e.maxTokens??this.config.maxTokens??4096,...e.tools&&e.tools.length>0?{tools:this.mapResponsesTools(e.tools)}:{},...s?{reasoning:{effort:s}}:{},...e.previousResponseId&&t.some(n=>n.type==="function_call_output")?{previous_response_id:e.previousResponseId}:{}}}mapResponsesResponse(e){let t="",s=[];for(let n of e.output??[])if(n.type==="message")for(let i of n.content??[])i.type==="output_text"&&i.text&&(t+=i.text);else if(n.type==="function_call"&&n.call_id&&n.name){let i={};try{i=JSON.parse(n.arguments||"{}")}catch{}s.push({id:n.call_id,name:n.name,input:i})}return{content:t,model:this.config.model,toolCalls:s.length>0?s:void 0,usage:{inputTokens:e.usage?.input_tokens??0,outputTokens:e.usage?.output_tokens??0,cacheReadTokens:e.usage?.input_tokens_details?.cached_tokens??0},stopReason:s.length>0?"tool_use":e.status==="incomplete"&&e.incomplete_details?.reason==="max_output_tokens"?"max_tokens":"end_turn",...e.id?{responseId:e.id}:{}}}async completeViaResponses(e){let t=this.buildResponsesParams(e),s=await this.client.responses.create(t);return this.mapResponsesResponse(s)}async*streamViaResponses(e){let t={...this.buildResponsesParams(e),stream:!0},s=await this.client.responses.create(t);for await(let n of s){let i=n.type;if(i==="response.output_text.delta"&&typeof n.delta=="string")yield{type:"text_delta",text:n.delta};else if(i==="response.output_item.added"){let r=n.item;r?.type==="function_call"&&r.call_id&&r.name&&(yield{type:"tool_use_start",toolCall:{id:r.call_id,name:r.name}})}else if(i==="response.function_call_arguments.delta"&&typeof n.delta=="string")yield{type:"tool_use_delta",toolCall:{input:n.delta}};else if(i==="response.completed")yield{type:"message_complete",response:this.mapResponsesResponse(n.response)};else if(i==="response.failed"||i==="error"){let r=n.response?.error?.message??n.message??"Responses-Stream fehlgeschlagen";throw new Error(r)}}}isReasoningModel(){return/^(o[1-9]|gpt-6|gpt-5($|[.-][0156]))/.test(this.config.model)}reasoningEffortParam(e){if(e&&this.isReasoningModel())return e==="none"&&/^gpt-6/.test(this.config.model)?"low":e==="max"?"xhigh":e}tokenLimitParam(e){let t=e??this.config.maxTokens??4096;return/^(gpt-5|gpt-6|o[1-9])/.test(this.config.model)?{max_completion_tokens:t}:{max_tokens:t}}safeTemperature(e){if(!this.isReasoningModel())return e??this.config.temperature}mapMessages(e,t){let s=[];t&&s.push({role:"system",content:t});for(let n of e){if(typeof n.content=="string"){s.push({role:n.role,content:n.content});continue}let i=[],r=[],a=[];for(let o of n.content)switch(o.type){case"text":i.push({type:"text",text:o.text});break;case"image":i.push({type:"image_url",image_url:{url:`data:${o.source.media_type};base64,${o.source.data}`}});break;case"tool_use":r.push({id:o.id,type:"function",function:{name:o.name,arguments:JSON.stringify(o.input)}});break;case"tool_result":a.push({tool_call_id:o.tool_use_id,content:o.content});break}if(n.role==="assistant"&&r.length>0){let o=i.map(c=>c.text).join("");s.push({role:"assistant",content:o||null,tool_calls:r})}else if(a.length>0)for(let o of a)s.push({role:"tool",tool_call_id:o.tool_call_id,content:o.content});else i.length>0&&(n.role==="user"?s.push({role:"user",content:i}):s.push({role:n.role,content:i.map(o=>o.text).join("")}))}return s}mapTools(e){return e.map(t=>({type:"function",function:{name:t.name,description:t.description,parameters:t.inputSchema}}))}mapResponse(e){let t=e.choices[0],s=t?.message,n=s?.content??"",i=s?.tool_calls?.map(r=>{if(r.type==="function")return{id:r.id,name:r.function.name,input:(()=>{try{return JSON.parse(r.function.arguments)}catch{return{}}})()}}).filter(r=>r!==void 0);return{content:n,model:e.model??this.config.model,toolCalls:i&&i.length>0?i:void 0,usage:{inputTokens:e.usage?.prompt_tokens??0,outputTokens:e.usage?.completion_tokens??0,cacheReadTokens:e.usage?.prompt_tokens_details?.cached_tokens??0},stopReason:this.mapStopReason(t?.finish_reason??null)}}mapStopReason(e){switch(e){case"stop":return"end_turn";case"tool_calls":return"tool_use";case"length":return"max_tokens";default:return"end_turn"}}}});var pa,ag=A(()=>{"use strict";ha();pa=class extends Gs{static{m(this,"OpenRouterProvider")}constructor(e){super({...e,baseUrl:e.baseUrl??"https://openrouter.ai/api/v1"})}isAvailable(){return!!this.config.apiKey}supportsEmbeddings(){return!1}}});var fa,og=A(()=>{"use strict";Yi();fa=class extends Is{static{m(this,"OllamaProvider")}baseUrl="";constructor(e){super(e)}apiKey="";async initialize(){let e=this.config.baseUrl??"http://localhost:11434";this.baseUrl=e.replace(/\/v1\/?$/,"").replace(/\/+$/,""),this.apiKey=this.config.apiKey??"";let t=_n(this.config.model);t?this.contextWindow=t:await this.fetchModelContextWindow()}async fetchModelContextWindow(){try{let e=await fetch(`${this.baseUrl}/api/show`,{method:"POST",headers:this.getHeaders(),body:JSON.stringify({name:this.config.model})});if(!e.ok)return;let s=(await e.json()).model_info??{},n=Object.keys(s).find(r=>r.includes("context_length")||r==="num_ctx"),i=n?Number(s[n]):0;i>0&&(this.contextWindow={maxInputTokens:i,maxOutputTokens:Math.min(i,4096)})}catch{}}getHeaders(){let e={"Content-Type":"application/json"};return this.apiKey&&(e.Authorization=`Bearer ${this.apiKey}`),e}async complete(e){let t=this.buildMessages(e.messages,e.system),s=e.tools?this.mapTools(e.tools):void 0,n={model:this.config.model,messages:t,stream:!1,options:this.buildOptions(e)};s&&s.length>0&&(n.tools=s);let i=await fetch(`${this.baseUrl}/api/chat`,{method:"POST",headers:this.getHeaders(),body:JSON.stringify(n)});if(!i.ok){let a=await i.text();throw new Error(`Ollama API error (${i.status}): ${a}`)}let r=await i.json();return this.mapResponse(r)}async*stream(e){let t=this.buildMessages(e.messages,e.system),s=e.tools?this.mapTools(e.tools):void 0,n={model:this.config.model,messages:t,stream:!0,options:this.buildOptions(e)};s&&s.length>0&&(n.tools=s);let i=await fetch(`${this.baseUrl}/api/chat`,{method:"POST",headers:this.getHeaders(),body:JSON.stringify(n)});if(!i.ok){let p=await i.text();throw new Error(`Ollama API error (${i.status}): ${p}`)}if(!i.body)throw new Error("Ollama streaming response has no body");let r=i.body.getReader(),a=new TextDecoder,o="",c="",d=0,u=0,h=[];try{for(;;){let{done:p,value:f}=await r.read();if(p)break;o+=a.decode(f,{stream:!0});let g=o.split(`
4190
4190
  `);o=g.pop()??"";for(let y of g){let w=y.trim();if(!w)continue;let _;try{_=JSON.parse(w)}catch{continue}if(_.message?.content&&(c+=_.message.content,yield{type:"text_delta",text:_.message.content}),_.message?.tool_calls)for(let E of _.message.tool_calls){let T={id:`ollama_tool_${h.length}`,name:E.function.name,input:E.function.arguments};h.push(T),yield{type:"tool_use_start",toolCall:{id:T.id,name:T.name}},yield{type:"tool_use_delta",toolCall:{input:T.input}}}_.done&&(d=_.prompt_eval_count??0,u=_.eval_count??0,yield{type:"message_complete",response:{content:c,model:this.config.model,toolCalls:h.length>0?h:void 0,usage:{inputTokens:d,outputTokens:u},stopReason:h.length>0?"tool_use":"end_turn"}})}}if(o.trim()){let p;try{p=JSON.parse(o.trim())}catch{return}if(p.message?.content&&(c+=p.message.content,yield{type:"text_delta",text:p.message.content}),p.message?.tool_calls)for(let f of p.message.tool_calls){let g={id:`ollama_tool_${h.length}`,name:f.function.name,input:f.function.arguments};h.push(g),yield{type:"tool_use_start",toolCall:{id:g.id,name:g.name}},yield{type:"tool_use_delta",toolCall:{input:g.input}}}p.done&&(d=p.prompt_eval_count??0,u=p.eval_count??0,yield{type:"message_complete",response:{content:c,toolCalls:h.length>0?h:void 0,usage:{inputTokens:d,outputTokens:u},stopReason:h.length>0?"tool_use":"end_turn"}})}}finally{r.releaseLock()}}isAvailable(){try{return this.baseUrl.length>0}catch{return!1}}async embed(e){try{let t=await fetch(`${this.baseUrl}/api/embed`,{method:"POST",headers:this.getHeaders(),body:JSON.stringify({model:"nomic-embed-text",input:e})});if(!t.ok)return;let s=await t.json();if(!s.embeddings||s.embeddings.length===0)return;let n=s.embeddings[0];return{embedding:n,model:"nomic-embed-text",dimensions:n.length}}catch{return}}supportsEmbeddings(){return!0}buildOptions(e){let t={},s=e.temperature??this.config.temperature;s!==void 0&&(t.temperature=s);let n=e.maxTokens??this.config.maxTokens;return n!==void 0&&(t.num_predict=n),t}buildMessages(e,t){let s=[];t&&s.push({role:"system",content:t});for(let n of e)typeof n.content=="string"?s.push({role:n.role,content:n.content}):s.push(this.mapContentBlocks(n.role,n.content));return s}mapContentBlocks(e,t){let s=[],n=[];for(let r of t)switch(r.type){case"text":s.push(r.text);break;case"image":n.push(r.source.data);break;case"tool_use":s.push(`[Tool call: ${r.name}(${JSON.stringify(r.input)})]`);break;case"tool_result":s.push(`[Tool result for ${r.tool_use_id}]: ${r.content}`);break}let i={role:e,content:s.join(`
4191
4191
  `)};return n.length>0&&(i.images=n),i}mapTools(e){return e.map(t=>({type:"function",function:{name:t.name,description:t.description,parameters:t.inputSchema}}))}mapResponse(e){let t=[];if(e.message.tool_calls)for(let s of e.message.tool_calls)t.push({id:`ollama_tool_${t.length}`,name:s.function.name,input:s.function.arguments});return{content:e.message.content,model:this.config.model,toolCalls:t.length>0?t:void 0,usage:{inputTokens:e.prompt_eval_count??0,outputTokens:e.eval_count??0},stopReason:t.length>0?"tool_use":"end_turn"}}}});var ma,cg=A(()=>{"use strict";ha();ma=class extends Gs{static{m(this,"OpenWebUIProvider")}constructor(e){super({...e,apiKey:e.apiKey||"openwebui",baseUrl:e.baseUrl??"http://localhost:3000/api/v1"})}isAvailable(){return!0}supportsEmbeddings(){return!1}}});import{GoogleGenAI as gP}from"@google/genai";var ga,lg=A(()=>{"use strict";Yi();ga=class extends Is{static{m(this,"GoogleProvider")}client;rawContentCache=new Map;constructor(e){super(e)}async initialize(){this.client=new gP({apiKey:this.config.apiKey});let e=_n(this.config.model);e&&(this.contextWindow=e)}async complete(e){let t=this.mapContents(e.messages),s=e.tools?this.mapTools(e.tools):void 0,n=await this.client.models.generateContent({model:this.config.model,contents:t,config:{systemInstruction:e.system,...s?{tools:[{functionDeclarations:s}]}:{},temperature:e.temperature??this.config.temperature,maxOutputTokens:e.maxTokens??this.config.maxTokens??4096}});return this.cacheRawContent(n),this.mapResponse(n)}async*stream(e){let t=this.mapContents(e.messages),s=e.tools?this.mapTools(e.tools):void 0,n=await this.client.models.generateContentStream({model:this.config.model,contents:t,config:{systemInstruction:e.system,...s?{tools:[{functionDeclarations:s}]}:{},temperature:e.temperature??this.config.temperature,maxOutputTokens:e.maxTokens??this.config.maxTokens??4096}}),i="",r=[],a=0,o=0,c=0,d;for await(let u of n){d=u;let h=u.text;if(h&&(i+=h,yield{type:"text_delta",text:h}),u.functionCalls)for(let p of u.functionCalls){let f={id:p.id??`google_tool_${r.length}`,name:p.name,input:p.args??{}};r.push(f),yield{type:"tool_use_start",toolCall:{id:f.id,name:f.name}}}u.usageMetadata&&(a=u.usageMetadata.promptTokenCount??0,o=u.usageMetadata.candidatesTokenCount??0,c=u.usageMetadata.cachedContentTokenCount??0)}d&&this.cacheRawContent(d),yield{type:"message_complete",response:{content:i,model:this.config.model,toolCalls:r.length>0?r:void 0,usage:{inputTokens:a,outputTokens:o,cacheReadTokens:c},stopReason:r.length>0?"tool_use":"end_turn"}}}isAvailable(){return!!this.config.apiKey}supportsEmbeddings(){return!1}cacheRawContent(e){let t=e.candidates?.[0]?.content;if(!t?.parts)return;let s=t.parts.filter(i=>i.functionCall);if(s.length===0)return;let n=this.buildCacheKey(s);if(this.rawContentCache.set(n,t),this.rawContentCache.size>20){let i=this.rawContentCache.keys().next().value;i&&this.rawContentCache.delete(i)}}buildCacheKey(e){return e.map(t=>`${t.functionCall.id??""}:${t.functionCall.name}`).sort().join("|")}buildCacheKeyFromBlocks(e){return e.map(t=>`${t.id}:${t.name}`).sort().join("|")}mapContents(e){let t=new Map;for(let n of e)if(!(n.role!=="assistant"||typeof n.content=="string"))for(let i of n.content)i.type==="tool_use"&&t.set(i.id,i.name);let s=[];for(let n of e){let i=n.role==="assistant"?"model":"user";if(typeof n.content=="string"){s.push({role:i,parts:[{text:n.content}]});continue}let r=[],a=[],o=[];for(let c of n.content)switch(c.type){case"text":a.push({text:c.text});break;case"image":a.push({inlineData:{mimeType:c.source.media_type,data:c.source.data}});break;case"tool_use":r.push({id:c.id,name:c.name,input:c.input});break;case"tool_result":{let d=t.get(c.tool_use_id)??c.tool_use_id,u;try{let h=JSON.parse(c.content);u=typeof h=="object"&&h!==null?h:{result:h}}catch{u={result:c.content}}o.push({functionResponse:{id:c.tool_use_id,name:d,response:u}});break}}if(n.role==="assistant"&&r.length>0){let c=this.buildCacheKeyFromBlocks(r),d=this.rawContentCache.get(c);if(d)this.rawContentCache.delete(c),this.rawContentCache.set(c,d),s.push(d);else{let u=[...a];for(let h=0;h<r.length;h++){let p=r[h];u.push({functionCall:{id:p.id,name:p.name,args:p.input},...h===0?{thoughtSignature:"skip_thought_signature_validator"}:{}})}s.push({role:"model",parts:u})}}else a.length>0&&s.push({role:i,parts:a});o.length>0&&s.push({role:"user",parts:o})}return this.sanitizeContents(s)}sanitizeContents(e){let t=new Set,s=[];for(let a of e)if(a.role==="model"){for(let o of a.parts??[])if(o.functionCall){let c=o.functionCall.id??o.functionCall.name??"";c&&t.add(c)}s.push(a)}else{let o=(a.parts??[]).filter(c=>{if(c.functionResponse){let d=c.functionResponse.id??c.functionResponse.name??"";return d?t.has(d):!1}return!0});o.length>0&&s.push({role:a.role,parts:o})}let n=new Set;for(let a of s)if(a.role!=="model"){for(let o of a.parts??[])if(o.functionResponse){let c=o.functionResponse.id??o.functionResponse.name??"";c&&n.add(c)}}let i=[];for(let a of s)if(a.role==="model"){let o=(a.parts??[]).filter(c=>{if(c.functionCall){let d=c.functionCall.id??c.functionCall.name??"";return d?n.has(d):!1}return!0});o.length>0&&i.push({role:a.role,parts:o})}else i.push(a);if(i.length<=1)return i;let r=[i[0]];for(let a=1;a<i.length;a++){let o=r[r.length-1],c=i[a];o.role===c.role?o.parts=[...o.parts??[],...c.parts??[]]:r.push(c)}return r}mapTools(e){return e.map(t=>({name:t.name,description:t.description,parameters:t.inputSchema}))}mapResponse(e){let t=e.text??"",n=e.functionCalls?.map((i,r)=>({id:i.id??`google_tool_${r}`,name:i.name,input:i.args??{}}));return{content:t,model:this.config.model,toolCalls:n&&n.length>0?n:void 0,usage:{inputTokens:e.usageMetadata?.promptTokenCount??0,outputTokens:e.usageMetadata?.candidatesTokenCount??0,cacheReadTokens:e.usageMetadata?.cachedContentTokenCount??0},stopReason:n&&n.length>0?"tool_use":"end_turn"}}}});import{createHash as yP}from"node:crypto";var ya,dg=A(()=>{"use strict";ha();ya=class extends Gs{static{m(this,"MistralProvider")}constructor(e){super({...e,baseUrl:e.baseUrl??"https://api.mistral.ai/v1/"})}isAvailable(){return!!this.config.apiKey}supportsEmbeddings(){return!0}supportsPromptCaching(){return/^mistral-medium-(3-5|3\.5|2604|latest)/i.test(this.config.model)}computeCacheKey(e){let t=typeof e.system=="string"&&e.system.length>0,s=Array.isArray(e.tools)&&e.tools.length>0;if(!t&&!s)return;let n=`${e.system??""}
4192
- ${JSON.stringify(e.tools??[])}`;return yP("sha256").update(n).digest("hex").slice(0,32)}extraRequestParams(e){if(!this.supportsPromptCaching())return{};let t=this.computeCacheKey(e);return t?{prompt_cache_key:t}:{}}}});function Mu(l){switch(l.provider){case"anthropic":return new ua(l);case"openai":return new Gs(l);case"openrouter":return new pa(l);case"ollama":return new fa(l);case"openwebui":return new ma(l);case"google":return new ga(l);case"mistral":return new ya(l);default:throw new Error(`Unknown LLM provider: ${l.provider}`)}}var ug=A(()=>{"use strict";rg();ha();ag();og();cg();lg();dg();m(Mu,"createLLMProvider")});function hg(l){let e=l.toLowerCase();for(let[t,s]of wP)if(e.startsWith(t.toLowerCase()))return s}function _P(l,e){let t=l.toLowerCase();return e<=272e3?{input:1,output:1}:/^(gpt-6|gpt-5\.6|gpt-5\.5($|-\d)|gpt-5\.4($|-\d|-pro))/.test(t)?{input:2,output:1.5}:{input:1,output:1}}function fc(l,e){let t=hg(l);if(!t)return 0;let s=1e6,n=_P(l,e.inputTokens),i=0,r=e.cacheReadTokens??0,a=e.cacheCreationTokens??0,o=Math.max(0,e.inputTokens-r);return i+=o/s*t.input*n.input,i+=e.outputTokens/s*t.output*n.output,r>0&&t.cacheRead&&(i+=r/s*t.cacheRead*n.input),a>0&&t.cacheWrite&&(i+=a/s*t.cacheWrite*n.input),i}var wP,wa,pg=A(()=>{"use strict";wP=[["gpt-6-astra",{input:10,output:50,cacheRead:1}],["gpt-6",{input:10,output:50,cacheRead:1}],["gpt-5.6-sol",{input:4,output:20,cacheRead:.4}],["gpt-5.6-terra",{input:2,output:12,cacheRead:.2}],["gpt-5.6-luna",{input:.2,output:1.2,cacheRead:.02}],["gpt-5.5-pro",{input:30,output:180}],["gpt-5.5",{input:5,output:30,cacheRead:.5}],["gpt-5.4-pro",{input:30,output:180}],["gpt-5.4-nano",{input:.2,output:1.25,cacheRead:.02}],["gpt-5.4-mini",{input:.75,output:4.5,cacheRead:.075}],["gpt-5.4",{input:2.5,output:15,cacheRead:.25}],["gpt-5.3-codex",{input:1.75,output:14,cacheRead:.175}],["gpt-5.2-pro",{input:21,output:168}],["gpt-5-pro",{input:15,output:120}],["gpt-5",{input:.625,output:5,cacheRead:.125}],["gpt-image-2.5",{input:5,output:30,cacheRead:1.25}],["gpt-image-2",{input:5,output:30,cacheRead:1.25}],["gpt-image-1.5",{input:5,output:10,cacheRead:1.25}],["gpt-image-1-mini",{input:2,output:8,cacheRead:.2}],["gpt-image-1",{input:5,output:40,cacheRead:1.25}],["gpt-4.1-nano",{input:.05,output:.2,cacheRead:.025}],["gpt-4.1-mini",{input:.2,output:.8,cacheRead:.1}],["gpt-4.1",{input:2,output:8,cacheRead:.5}],["gpt-4o-mini",{input:.15,output:.6,cacheRead:.075}],["gpt-4o",{input:2.5,output:10,cacheRead:1.25}],["o4-mini",{input:1.1,output:4.4,cacheRead:.275}],["o3-mini",{input:1.1,output:4.4,cacheRead:.55}],["o3",{input:2,output:8,cacheRead:.5}],["claude-fable-5-1",{input:10,output:50,cacheRead:.25,cacheWrite:12.5}],["claude-mythos-5-1",{input:10,output:50,cacheRead:.25,cacheWrite:12.5}],["claude-fable-5",{input:10,output:50,cacheRead:1,cacheWrite:12.5}],["claude-mythos-5",{input:10,output:50,cacheRead:1,cacheWrite:12.5}],["claude-opus-5",{input:5,output:25,cacheRead:.5,cacheWrite:6.25}],["claude-opus-4-8",{input:5,output:25,cacheRead:.5,cacheWrite:6.25}],["claude-opus-4-7",{input:5,output:25,cacheRead:.5,cacheWrite:6.25}],["claude-opus-4-6",{input:5,output:25,cacheRead:.5,cacheWrite:6.25}],["claude-opus-4-5",{input:5,output:25,cacheRead:.5,cacheWrite:6.25}],["claude-opus-4-1",{input:15,output:75,cacheRead:1.5,cacheWrite:18.75}],["claude-opus-4",{input:15,output:75,cacheRead:1.5,cacheWrite:18.75}],["claude-sonnet-5",{input:2,output:10,cacheRead:.2,cacheWrite:2.5}],["claude-sonnet-4",{input:3,output:15,cacheRead:.3,cacheWrite:3.75}],["claude-haiku-4",{input:1,output:5,cacheRead:.1,cacheWrite:1.25}],["claude-haiku-3-5",{input:.8,output:4,cacheRead:.08,cacheWrite:1}],["claude-3.5-sonnet",{input:3,output:15,cacheRead:.3,cacheWrite:3.75}],["claude-3-haiku",{input:.25,output:1.25,cacheRead:.03,cacheWrite:.3}],["gemini-3.8-flash",{input:.75,output:3.75,cacheRead:.075}],["gemini-3.7-flash",{input:.75,output:3.75,cacheRead:.075}],["gemini-3.6-flash",{input:.75,output:3.75,cacheRead:.075}],["gemini-3.5-flash-lite",{input:.3,output:2.5,cacheRead:.03}],["gemini-3.5-flash",{input:1.5,output:9,cacheRead:.15}],["gemini-3.1-pro",{input:2,output:12,cacheRead:.2}],["gemini-3.1-flash-lite",{input:.25,output:1.5,cacheRead:.025}],["gemini-3.1-flash",{input:.5,output:3,cacheRead:.05}],["gemini-3-pro",{input:2,output:12,cacheRead:.2}],["gemini-3-flash",{input:.5,output:3,cacheRead:.05}],["gemini-2.5-pro",{input:1.25,output:10,cacheRead:.125}],["gemini-2.5-flash",{input:.3,output:2.5,cacheRead:.03}],["gemini-2.0-flash",{input:.1,output:.4,cacheRead:.025}],["text-embedding-3-small",{input:.02,output:0}],["text-embedding-3-large",{input:.13,output:0}],["text-embedding-ada-002",{input:.1,output:0}],["codestral-embed",{input:.15,output:0}],["codestral",{input:.3,output:.9,cacheRead:.03}],["devstral-medium",{input:.4,output:2}],["devstral-small",{input:.1,output:.3}],["magistral-medium",{input:2,output:5}],["magistral-small",{input:.5,output:1.5}],["ministral-3b",{input:.1,output:.1}],["ministral-8b",{input:.15,output:.15}],["ministral-14b",{input:.2,output:.2}],["mistral-large",{input:.5,output:1.5,cacheRead:.05}],["mistral-medium-3-5",{input:1.5,output:7.5,cacheRead:.15}],["mistral-medium-3.5",{input:1.5,output:7.5,cacheRead:.15}],["mistral-medium-2604",{input:1.5,output:7.5,cacheRead:.15}],["mistral-medium-latest",{input:1.5,output:7.5,cacheRead:.15}],["mistral-medium",{input:.4,output:2,cacheRead:.04}],["zai-glm",{input:1.4,output:4.4}],["glm-5",{input:1.4,output:4.4}],["labs-leanstral",{input:0,output:0}],["mistral-small",{input:.15,output:.6,cacheRead:.015}],["mistral-moderation",{input:.1,output:0}],["mistral-embed",{input:.1,output:0}],["pixtral-large",{input:2,output:6}],["pixtral-12b",{input:.15,output:.15}],["open-mixtral-8x22b",{input:2,output:6}],["open-mixtral-8x7b",{input:.7,output:.7}],["open-mistral-nemo",{input:.15,output:.15}],["open-mistral-7b",{input:.25,output:.25}]];m(hg,"getModelPricing");m(_P,"longPromptMultiplier");m(fc,"calculateCost");wa=class{static{m(this,"TokenCostTracker")}data={totalInputTokens:0,totalOutputTokens:0,totalCacheReadTokens:0,totalCacheWriteTokens:0,totalCostUsd:0,byModel:{}};persistFn;setPersist(e){this.persistFn=e}record(e,t){let s=fc(e,t),n=t.cacheReadTokens??0,i=t.cacheCreationTokens??0;this.data.totalInputTokens+=t.inputTokens,this.data.totalOutputTokens+=t.outputTokens,this.data.totalCacheReadTokens+=n,this.data.totalCacheWriteTokens+=i,this.data.totalCostUsd+=s;let r=this.data.byModel[e];r||(r={calls:0,inputTokens:0,outputTokens:0,cacheReadTokens:0,cacheWriteTokens:0,costUsd:0},this.data.byModel[e]=r),r.calls++,r.inputTokens+=t.inputTokens,r.outputTokens+=t.outputTokens,r.cacheReadTokens+=n,r.cacheWriteTokens+=i,r.costUsd+=s;try{this.persistFn?.(e,t.inputTokens,t.outputTokens,n,i,s)}catch{}return s}getSummary(){return{...this.data,totalCostUsd:Math.round(this.data.totalCostUsd*1e6)/1e6,byModel:Object.fromEntries(Object.entries(this.data.byModel).map(([e,t])=>[e,{...t,costUsd:Math.round(t.costUsd*1e6)/1e6}]))}}}});function Pu(l,e){return new mc(l,e)}var E0,TP,k0,EP,mc,b0=A(()=>{"use strict";Yi();ug();pg();E0=["default","strong","medium","fast","embeddings","local","fallback"],TP=5*6e4,k0=["default","strong","medium","fast","fallback"],EP={fast:"low",medium:"medium",default:"medium",strong:"high"},mc=class extends Is{static{m(this,"ModelRouter")}providers=new Map;multiConfig;logger;costTracker=new wa;constructor(e,t){super(e.default),this.multiConfig=e,this.logger=t}async initialize(){for(let e of E0){let t=this.multiConfig[e];if(t){let s=Mu(t);await s.initialize(),this.providers.set(e,s),this.logger?.info({tier:e,provider:t.provider,model:t.model},"LLM tier initialized")}}if(!this.providers.has("default"))throw new Error(`ModelRouter: no "default" tier configured. Available tiers: [${[...this.providers.keys()].join(", ")}]`)}resolve(e){if(e&&e!=="fallback"&&this.providers.has(e))return{provider:this.providers.get(e),resolvedTier:e};let t=this.providers.get("default");if(!t)throw new Error('ModelRouter: no "default" tier available. Was initialize() called?');return{provider:t,resolvedTier:"default"}}sanitizeRequest(e){let t=m(s=>s&&s.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g,"\uFFFD"),"clean");return{...e,system:t(e.system),messages:e.messages.map(s=>({...s,content:typeof s.content=="string"?t(s.content)??"":s.content}))}}withTierEffort(e,t){if(e.reasoningEffort)return e;let s=EP[t];return s?{...e,reasoningEffort:s}:e}async complete(e){let t=this.sanitizeRequest(e),{provider:s,resolvedTier:n}=this.resolve(t.tier),i=this.multiConfig[n],r=this.withTierEffort(t,n);if(this.logger?.debug({requestedTier:t.tier??"default",resolvedTier:n,model:i?.model},"LLM routing request"),this.isInBillingCooldown(n))return this.logger?.info({tier:n},"v868.3 billing-cooldown aktiv \u2014 Primary \xFCbersprungen, Fallback-Kette"),this.completeWithFallback(r,n,new Error(`Tier "${n}" im Billing-Cooldown (Guthaben/Quota-Fehler vor < 5 min)`));try{let a=await this.executeComplete(s,n,r);return this.maybeNotifyRecovery(n),this.meldePuls("erfolg",n),a}catch(a){this.meldePuls("fehler",n,a);let o=this.isBillingError(a);if(o&&this.registerBillingFailure(n,a),!o&&!this.isRetryableError(a))throw a;return this.logger?.warn({err:a,tier:n,billing:o},o?"Provider billing failure (credit/quota), attempting fallback":"Provider failed, attempting fallback"),this.completeWithFallback(r,n,a)}}isBillingError(e){if(!(e instanceof Error))return!1;let t=e.message.toLowerCase();return t.includes("credit balance is too low")||t.includes("insufficient_quota")||t.includes("insufficient credits")||t.includes("exceeded your current quota")||t.includes("billing")&&t.includes("error")}pulsCallback;setPulsCallback(e){this.pulsCallback=e}meldePuls(e,t,s){if(!this.pulsCallback)return;let n=this.multiConfig[t];try{this.pulsCallback({art:e,tier:t,provider:n?.provider??"unknown",model:n?.model??"unknown",...e==="fehler"?{klasse:this.klassifiziereFehler(s),fehler:(s?.message??String(s)).slice(0,300)}:{}})}catch{}}klassifiziereFehler(e){if(this.isBillingError(e))return"billing";let t=e instanceof Error?e.message.toLowerCase():String(e).toLowerCase(),s=e?.status??e?.statusCode;return s===401||s===403||t.includes("401")||t.includes("403")||t.includes("invalid api key")||t.includes("invalid x-api-key")||t.includes("authentication")||t.includes("permission")?"auth":s===429||t.includes("429")||t.includes("rate limit")||t.includes("too many requests")||t.includes("overloaded")||t.includes("529")?"rate":t.includes("econnrefused")||t.includes("enotfound")||t.includes("etimedout")||t.includes("econnreset")||t.includes("socket hang up")||t.includes("fetch failed")||t.includes("eai_again")||t.includes("getaddrinfo")||t.includes("connection error")||t.includes("502")||t.includes("503")||t.includes("504")?"netz":s===404||t.includes("404")||t.includes("model")&&(t.includes("not found")||t.includes("does not exist")||t.includes("not supported"))?"modell":"unbekannt"}async probeTier(e){let t=this.multiConfig[e],s=this.providers.get(e),n={tier:e,provider:t?.provider??"unknown",model:t?.model??"unknown"};if(!s)return{...n,ok:!1,klasse:"modell",fehler:"Tier nicht konfiguriert",dauerMs:0};let i=Date.now();try{return await s.complete({messages:[{role:"user",content:"Antworte nur mit OK."}],maxTokens:5,tier:e}),this.meldePuls("erfolg",e),this.maybeNotifyRecovery(e),{...n,ok:!0,dauerMs:Date.now()-i}}catch(r){return this.isBillingError(r)&&this.registerBillingFailure(e,r),this.meldePuls("fehler",e,r),{...n,ok:!1,klasse:this.klassifiziereFehler(r),fehler:(r?.message??String(r)).slice(0,300),dauerMs:Date.now()-i}}}konfigurierteTiers(){return[...this.providers.keys()]}billingAlertCallback;lastBillingAlertAt=new Map;billingCooldownUntil=new Map;pendingRecovery=new Set;setBillingAlertCallback(e){this.billingAlertCallback=e}registerBillingFailure(e,t){this.billingCooldownUntil.set(e,Date.now()+TP),this.pendingRecovery.add(e),this.notifyBillingError(e,t)}isInBillingCooldown(e){return(this.billingCooldownUntil.get(e)??0)>Date.now()}maybeNotifyRecovery(e){if(!this.pendingRecovery.has(e))return;this.pendingRecovery.delete(e),this.lastBillingAlertAt.delete(e),this.billingCooldownUntil.delete(e);let t=this.multiConfig[e];try{this.billingAlertCallback?.({kind:"recovered",tier:e,provider:t?.provider??"unknown",model:t?.model??"unknown",message:"Provider antwortet wieder regul\xE4r \u2014 Fallback nicht mehr aktiv."})}catch{}}notifyBillingError(e,t){if(!this.billingAlertCallback)return;let s=this.lastBillingAlertAt.get(e)??0;if(Date.now()-s<6*36e5)return;this.lastBillingAlertAt.set(e,Date.now());let n=this.multiConfig[e];try{this.billingAlertCallback({kind:"failure",tier:e,provider:n?.provider??"unknown",model:n?.model??"unknown",message:t.message.slice(0,300)})}catch{}}async executeComplete(e,t,s){let n=this.multiConfig[t],i=await e.complete(s),r=i.model??n?.model??"unknown";i.model||(i.model=r);let a=this.costTracker.record(r,i.usage);return this.logger?.info({tier:t,model:r,costUsd:Math.round(a*1e6)/1e6,inputTokens:i.usage?.inputTokens,outputTokens:i.usage?.outputTokens,cacheReadTokens:i.usage?.cacheReadTokens,cacheWriteTokens:i.usage?.cacheCreationTokens},"LLM call completed"),i}isRetryableError(e){if(e instanceof Error){let s=e.message.toLowerCase();if(s.includes("econnrefused")||s.includes("enotfound")||s.includes("etimedout")||s.includes("econnreset")||s.includes("socket hang up")||s.includes("fetch failed")||s.includes("eai_again")||s.includes("getaddrinfo")||s.includes("connection error")||s.includes("500")||s.includes("502")||s.includes("503")||s.includes("504")||s.includes("529")||s.includes("rate limit")||s.includes("overloaded")||s.includes("too many requests"))return!0}let t=e?.status??e?.statusCode;return typeof t=="number"&&(t>=500||t===429)}async completeWithFallback(e,t,s){let n=k0.filter(i=>i!==t);for(let i of n){if(this.isInBillingCooldown(i))continue;let r=this.providers.get(i);if(r)try{this.logger?.info({tier:i},"Fallback to tier");let a=await this.executeComplete(r,i,e);return this.maybeNotifyRecovery(i),this.meldePuls("erfolg",i),a}catch(a){this.isBillingError(a)&&this.registerBillingFailure(i,a),this.meldePuls("fehler",i,a);continue}}throw s}async*stream(e){let{provider:t,resolvedTier:s}=this.resolve(e.tier),n=this.withTierEffort(e,s);if(this.isInBillingCooldown(s)){this.logger?.info({tier:s},"v868.3 billing-cooldown aktiv \u2014 Stream direkt \xFCber Fallback-Kette"),yield*this.streamFallback(e,s,new Error(`Tier "${s}" im Billing-Cooldown`));return}let i=!1;try{for await(let r of t.stream(n))i=!0,yield r;this.maybeNotifyRecovery(s),this.meldePuls("erfolg",s);return}catch(r){let a=this.isBillingError(r);if(a&&this.registerBillingFailure(s,r),this.meldePuls("fehler",s,r),i||!a&&!this.isRetryableError(r))throw r;this.logger?.warn({err:r,tier:s,billing:a},"Stream provider failed before first chunk, attempting fallback"),yield*this.streamFallback(e,s,r)}}async*streamFallback(e,t,s){let n=k0.filter(i=>i!==t);for(let i of n){if(this.isInBillingCooldown(i))continue;let r=this.providers.get(i);if(r)try{this.logger?.info({tier:i},"Stream fallback to tier"),yield*r.stream(this.withTierEffort(e,i)),this.maybeNotifyRecovery(i),this.meldePuls("erfolg",i);return}catch(a){this.isBillingError(a)&&this.registerBillingFailure(i,a),this.meldePuls("fehler",i,a);continue}}throw s}async embed(e){let t=await(this.providers.get("embeddings")??this.resolve().provider).embed(e);return t?.totalTokens&&this.costTracker.record(t.model,{inputTokens:t.totalTokens,outputTokens:0}),t}supportsEmbeddings(){return(this.providers.get("embeddings")??this.resolve().provider).supportsEmbeddings()}isAvailable(){return this.resolve().provider.isAvailable()}getContextWindow(){return this.resolve().provider.getContextWindow()}getProviderStatuses(){let e={};for(let t of E0){let s=this.providers.get(t);if(s){let n=this.multiConfig[t];e[t]={model:n?.model??"unknown",available:s.isAvailable()}}}return e}getCostSummary(){return this.costTracker.getSummary()}setPersist(e){this.costTracker.setPersist(e)}};m(Pu,"createModelRouter")});function kP(l){let e=Date.now()-new Date(l).getTime();if(e<0)return l.slice(0,16).replace("T"," ");let t=Math.floor(e/1e3);if(t<120)return`${t}s ago`;let s=Math.floor(t/60);if(s<120)return`${s}m ago`;let n=Math.floor(s/60);return n<48?`${n}h ago`:`${Math.floor(n/24)}d ago`}function Vs(l){return Math.ceil(l.length/3.5)}function hi(l){if(typeof l.content=="string")return Vs(l.content)+4;let e=4;for(let t of l.content)switch(t.type){case"text":e+=Vs(t.text);break;case"image":e+=1e3;break;case"tool_use":e+=Vs(t.name)+Vs(JSON.stringify(t.input));break;case"tool_result":e+=Vs(t.content);break}return e}function Uu(l,e){let t=e?.keepRecentPairs??3,s=e?.maxTrimmedLength??120,n=e?.minContentLength??300,i=new Map;for(let o of l)if(o.role==="assistant"&&Array.isArray(o.content))for(let c of o.content)c.type==="tool_use"&&i.set(c.id,c.name);let r=[];for(let o=0;o<l.length;o++){let c=l[o];c.role==="user"&&Array.isArray(c.content)&&c.content.some(d=>d.type==="tool_result")&&r.push(o)}let a=new Set(r.slice(-t));return l.map((o,c)=>{if(a.has(c)||o.role!=="user"||!Array.isArray(o.content))return o;let d=!1,u=o.content.map(h=>{if(h.type!=="tool_result")return h;let p=h.content;if(typeof p!="string"||p.length<n)return h;d=!0;let f=i.get(h.tool_use_id)||"unknown",g=p.split(`
4192
+ ${JSON.stringify(e.tools??[])}`;return yP("sha256").update(n).digest("hex").slice(0,32)}extraRequestParams(e){if(!this.supportsPromptCaching())return{};let t=this.computeCacheKey(e);return t?{prompt_cache_key:t}:{}}}});function Mu(l){switch(l.provider){case"anthropic":return new ua(l);case"openai":return new Gs(l);case"openrouter":return new pa(l);case"ollama":return new fa(l);case"openwebui":return new ma(l);case"google":return new ga(l);case"mistral":return new ya(l);default:throw new Error(`Unknown LLM provider: ${l.provider}`)}}var ug=A(()=>{"use strict";rg();ha();ag();og();cg();lg();dg();m(Mu,"createLLMProvider")});function hg(l){let e=l.toLowerCase();for(let[t,s]of wP)if(e.startsWith(t.toLowerCase()))return s}function _P(l,e){let t=l.toLowerCase();return e<=272e3?{input:1,output:1}:/^(gpt-6|gpt-5\.6|gpt-5\.5($|-\d)|gpt-5\.4($|-\d|-pro))/.test(t)?{input:2,output:1.5}:{input:1,output:1}}function fc(l,e){let t=hg(l);if(!t)return 0;let s=1e6,n=_P(l,e.inputTokens),i=0,r=e.cacheReadTokens??0,a=e.cacheCreationTokens??0,o=Math.max(0,e.inputTokens-r);return i+=o/s*t.input*n.input,i+=e.outputTokens/s*t.output*n.output,r>0&&t.cacheRead&&(i+=r/s*t.cacheRead*n.input),a>0&&t.cacheWrite&&(i+=a/s*t.cacheWrite*n.input),i}var wP,wa,pg=A(()=>{"use strict";wP=[["gpt-6-astra",{input:10,output:50,cacheRead:1}],["gpt-6",{input:10,output:50,cacheRead:1}],["gpt-5.6-sol",{input:4,output:20,cacheRead:.4}],["gpt-5.6-terra",{input:2,output:12,cacheRead:.2}],["gpt-5.6-luna",{input:.2,output:1.2,cacheRead:.02}],["gpt-5.5-pro",{input:30,output:180}],["gpt-5.5",{input:5,output:30,cacheRead:.5}],["gpt-5.4-pro",{input:30,output:180}],["gpt-5.4-nano",{input:.2,output:1.25,cacheRead:.02}],["gpt-5.4-mini",{input:.75,output:4.5,cacheRead:.075}],["gpt-5.4",{input:2.5,output:15,cacheRead:.25}],["gpt-5.3-codex",{input:1.75,output:14,cacheRead:.175}],["gpt-5.2-pro",{input:21,output:168}],["gpt-5-pro",{input:15,output:120}],["gpt-5",{input:.625,output:5,cacheRead:.125}],["gpt-image-2.5",{input:5,output:30,cacheRead:1.25}],["gpt-image-2",{input:5,output:30,cacheRead:1.25}],["gpt-image-1.5",{input:5,output:10,cacheRead:1.25}],["gpt-image-1-mini",{input:2,output:8,cacheRead:.2}],["gpt-image-1",{input:5,output:40,cacheRead:1.25}],["gpt-4.1-nano",{input:.05,output:.2,cacheRead:.025}],["gpt-4.1-mini",{input:.2,output:.8,cacheRead:.1}],["gpt-4.1",{input:2,output:8,cacheRead:.5}],["gpt-4o-mini",{input:.15,output:.6,cacheRead:.075}],["gpt-4o",{input:2.5,output:10,cacheRead:1.25}],["o4-mini",{input:1.1,output:4.4,cacheRead:.275}],["o3-mini",{input:1.1,output:4.4,cacheRead:.55}],["o3",{input:2,output:8,cacheRead:.5}],["claude-fable-5-1",{input:10,output:50,cacheRead:.25,cacheWrite:12.5}],["claude-mythos-5-1",{input:10,output:50,cacheRead:.25,cacheWrite:12.5}],["claude-fable-5",{input:10,output:50,cacheRead:1,cacheWrite:12.5}],["claude-mythos-5",{input:10,output:50,cacheRead:1,cacheWrite:12.5}],["claude-opus-5",{input:5,output:25,cacheRead:.5,cacheWrite:6.25}],["claude-opus-4-8",{input:5,output:25,cacheRead:.5,cacheWrite:6.25}],["claude-opus-4-7",{input:5,output:25,cacheRead:.5,cacheWrite:6.25}],["claude-opus-4-6",{input:5,output:25,cacheRead:.5,cacheWrite:6.25}],["claude-opus-4-5",{input:5,output:25,cacheRead:.5,cacheWrite:6.25}],["claude-opus-4-1",{input:15,output:75,cacheRead:1.5,cacheWrite:18.75}],["claude-opus-4",{input:15,output:75,cacheRead:1.5,cacheWrite:18.75}],["claude-sonnet-5",{input:2,output:10,cacheRead:.2,cacheWrite:2.5}],["claude-sonnet-4",{input:3,output:15,cacheRead:.3,cacheWrite:3.75}],["claude-haiku-4",{input:1,output:5,cacheRead:.1,cacheWrite:1.25}],["claude-haiku-3-5",{input:.8,output:4,cacheRead:.08,cacheWrite:1}],["claude-3.5-sonnet",{input:3,output:15,cacheRead:.3,cacheWrite:3.75}],["claude-3-haiku",{input:.25,output:1.25,cacheRead:.03,cacheWrite:.3}],["gemini-3.8-flash",{input:.75,output:3.75,cacheRead:.075}],["gemini-3.7-flash",{input:.75,output:3.75,cacheRead:.075}],["gemini-3.6-flash",{input:.75,output:3.75,cacheRead:.075}],["gemini-3.5-flash-lite",{input:.3,output:2.5,cacheRead:.03}],["gemini-3.5-flash",{input:1.5,output:9,cacheRead:.15}],["gemini-3.1-pro",{input:2,output:12,cacheRead:.2}],["gemini-3.1-flash-lite",{input:.25,output:1.5,cacheRead:.025}],["gemini-3.1-flash",{input:.5,output:3,cacheRead:.05}],["gemini-3-pro",{input:2,output:12,cacheRead:.2}],["gemini-3-flash",{input:.5,output:3,cacheRead:.05}],["gemini-2.5-pro",{input:1.25,output:10,cacheRead:.125}],["gemini-2.5-flash",{input:.3,output:2.5,cacheRead:.03}],["gemini-2.0-flash",{input:.1,output:.4,cacheRead:.025}],["text-embedding-3-small",{input:.02,output:0}],["text-embedding-3-large",{input:.13,output:0}],["text-embedding-ada-002",{input:.1,output:0}],["codestral-embed",{input:.15,output:0}],["codestral",{input:.3,output:.9,cacheRead:.03}],["devstral-medium",{input:.4,output:2}],["devstral-small",{input:.1,output:.3}],["magistral-medium",{input:2,output:5}],["magistral-small",{input:.5,output:1.5}],["ministral-3b",{input:.1,output:.1}],["ministral-8b",{input:.15,output:.15}],["ministral-14b",{input:.2,output:.2}],["mistral-large",{input:.5,output:1.5,cacheRead:.05}],["mistral-medium-3-5",{input:1.5,output:7.5,cacheRead:.15}],["mistral-medium-3.5",{input:1.5,output:7.5,cacheRead:.15}],["mistral-medium-2604",{input:1.5,output:7.5,cacheRead:.15}],["mistral-medium-latest",{input:1.5,output:7.5,cacheRead:.15}],["mistral-medium",{input:.4,output:2,cacheRead:.04}],["zai-glm",{input:1.4,output:4.4}],["glm-5",{input:1.4,output:4.4}],["labs-leanstral",{input:0,output:0}],["mistral-small",{input:.15,output:.6,cacheRead:.015}],["mistral-moderation",{input:.1,output:0}],["mistral-embed",{input:.1,output:0}],["pixtral-large",{input:2,output:6}],["pixtral-12b",{input:.15,output:.15}],["open-mixtral-8x22b",{input:2,output:6}],["open-mixtral-8x7b",{input:.7,output:.7}],["open-mistral-nemo",{input:.15,output:.15}],["open-mistral-7b",{input:.25,output:.25}]];m(hg,"getModelPricing");m(_P,"longPromptMultiplier");m(fc,"calculateCost");wa=class{static{m(this,"TokenCostTracker")}data={totalInputTokens:0,totalOutputTokens:0,totalCacheReadTokens:0,totalCacheWriteTokens:0,totalCostUsd:0,byModel:{}};persistFn;setPersist(e){this.persistFn=e}record(e,t){let s=fc(e,t),n=t.cacheReadTokens??0,i=t.cacheCreationTokens??0;this.data.totalInputTokens+=t.inputTokens,this.data.totalOutputTokens+=t.outputTokens,this.data.totalCacheReadTokens+=n,this.data.totalCacheWriteTokens+=i,this.data.totalCostUsd+=s;let r=this.data.byModel[e];r||(r={calls:0,inputTokens:0,outputTokens:0,cacheReadTokens:0,cacheWriteTokens:0,costUsd:0},this.data.byModel[e]=r),r.calls++,r.inputTokens+=t.inputTokens,r.outputTokens+=t.outputTokens,r.cacheReadTokens+=n,r.cacheWriteTokens+=i,r.costUsd+=s;try{this.persistFn?.(e,t.inputTokens,t.outputTokens,n,i,s)}catch{}return s}getSummary(){return{...this.data,totalCostUsd:Math.round(this.data.totalCostUsd*1e6)/1e6,byModel:Object.fromEntries(Object.entries(this.data.byModel).map(([e,t])=>[e,{...t,costUsd:Math.round(t.costUsd*1e6)/1e6}]))}}}});function Pu(l,e){return new mc(l,e)}var E0,TP,k0,EP,mc,b0=A(()=>{"use strict";Yi();ug();pg();E0=["default","strong","medium","fast","embeddings","local","fallback"],TP=5*6e4,k0=["default","strong","medium","fast","fallback"],EP={fast:"low",medium:"medium",default:"medium",strong:"high"},mc=class extends Is{static{m(this,"ModelRouter")}providers=new Map;multiConfig;logger;costTracker=new wa;constructor(e,t){super(e.default),this.multiConfig=e,this.logger=t}async initialize(){for(let e of E0){let t=this.multiConfig[e];if(t){let s=Mu(t);await s.initialize(),this.providers.set(e,s),this.logger?.info({tier:e,provider:t.provider,model:t.model},"LLM tier initialized")}}if(!this.providers.has("default"))throw new Error(`ModelRouter: no "default" tier configured. Available tiers: [${[...this.providers.keys()].join(", ")}]`)}resolve(e){if(e&&e!=="fallback"&&this.providers.has(e))return{provider:this.providers.get(e),resolvedTier:e};let t=this.providers.get("default");if(!t)throw new Error('ModelRouter: no "default" tier available. Was initialize() called?');return{provider:t,resolvedTier:"default"}}sanitizeRequest(e){let t=m(s=>s&&s.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g,"\uFFFD"),"clean");return{...e,system:t(e.system),messages:e.messages.map(s=>({...s,content:typeof s.content=="string"?t(s.content)??"":s.content}))}}withTierEffort(e,t){if(e.reasoningEffort)return e;let s=EP[t];return s?{...e,reasoningEffort:s}:e}async complete(e){let t=this.sanitizeRequest(e),{provider:s,resolvedTier:n}=this.resolve(t.tier),i=this.multiConfig[n],r=this.withTierEffort(t,n);if(this.logger?.debug({requestedTier:t.tier??"default",resolvedTier:n,model:i?.model},"LLM routing request"),this.isInBillingCooldown(n))return this.logger?.info({tier:n},"v868.3 billing-cooldown aktiv \u2014 Primary \xFCbersprungen, Fallback-Kette"),this.completeWithFallback(r,n,new Error(`Tier "${n}" im Billing-Cooldown (Guthaben/Quota-Fehler vor < 5 min)`));try{let a=await this.executeComplete(s,n,r);return this.maybeNotifyRecovery(n),this.meldePuls("erfolg",n),a}catch(a){this.meldePuls("fehler",n,a);let o=this.isBillingError(a);if(o&&this.registerBillingFailure(n,a),!o&&!this.isRetryableError(a))throw a;return this.logger?.warn({err:a,tier:n,billing:o},o?"Provider billing failure (credit/quota), attempting fallback":"Provider failed, attempting fallback"),this.completeWithFallback(r,n,a)}}isBillingError(e){if(!(e instanceof Error))return!1;let t=e.message.toLowerCase();return t.includes("credit balance is too low")||t.includes("insufficient_quota")||t.includes("insufficient credits")||t.includes("exceeded your current quota")||t.includes("no credits remaining")||t.includes("add credits to continue")||t.includes("billing")&&t.includes("error")}pulsCallback;setPulsCallback(e){this.pulsCallback=e}meldePuls(e,t,s){if(!this.pulsCallback)return;let n=this.multiConfig[t];try{this.pulsCallback({art:e,tier:t,provider:n?.provider??"unknown",model:n?.model??"unknown",...e==="fehler"?{klasse:this.klassifiziereFehler(s),fehler:(s?.message??String(s)).slice(0,300)}:{}})}catch{}}klassifiziereFehler(e){if(this.isBillingError(e))return"billing";let t=e instanceof Error?e.message.toLowerCase():String(e).toLowerCase(),s=e?.status??e?.statusCode;return s===401||s===403||t.includes("401")||t.includes("403")||t.includes("invalid api key")||t.includes("invalid x-api-key")||t.includes("authentication")||t.includes("permission")?"auth":s===429||t.includes("429")||t.includes("rate limit")||t.includes("too many requests")||t.includes("overloaded")||t.includes("529")?"rate":t.includes("econnrefused")||t.includes("enotfound")||t.includes("etimedout")||t.includes("econnreset")||t.includes("socket hang up")||t.includes("fetch failed")||t.includes("eai_again")||t.includes("getaddrinfo")||t.includes("connection error")||t.includes("502")||t.includes("503")||t.includes("504")?"netz":s===404||t.includes("404")||t.includes("model")&&(t.includes("not found")||t.includes("does not exist")||t.includes("not supported"))?"modell":"unbekannt"}async probeTier(e){let t=this.multiConfig[e],s=this.providers.get(e),n={tier:e,provider:t?.provider??"unknown",model:t?.model??"unknown"};if(!s)return{...n,ok:!1,klasse:"modell",fehler:"Tier nicht konfiguriert",dauerMs:0};let i=Date.now();try{return await s.complete({messages:[{role:"user",content:"Antworte nur mit OK."}],maxTokens:5,tier:e}),this.meldePuls("erfolg",e),this.maybeNotifyRecovery(e),{...n,ok:!0,dauerMs:Date.now()-i}}catch(r){return this.isBillingError(r)&&this.registerBillingFailure(e,r),this.meldePuls("fehler",e,r),{...n,ok:!1,klasse:this.klassifiziereFehler(r),fehler:(r?.message??String(r)).slice(0,300),dauerMs:Date.now()-i}}}konfigurierteTiers(){return[...this.providers.keys()]}billingAlertCallback;lastBillingAlertAt=new Map;billingCooldownUntil=new Map;pendingRecovery=new Set;setBillingAlertCallback(e){this.billingAlertCallback=e}registerBillingFailure(e,t){this.billingCooldownUntil.set(e,Date.now()+TP),this.pendingRecovery.add(e),this.notifyBillingError(e,t)}isInBillingCooldown(e){return(this.billingCooldownUntil.get(e)??0)>Date.now()}maybeNotifyRecovery(e){if(!this.pendingRecovery.has(e))return;this.pendingRecovery.delete(e),this.lastBillingAlertAt.delete(e),this.billingCooldownUntil.delete(e);let t=this.multiConfig[e];try{this.billingAlertCallback?.({kind:"recovered",tier:e,provider:t?.provider??"unknown",model:t?.model??"unknown",message:"Provider antwortet wieder regul\xE4r \u2014 Fallback nicht mehr aktiv."})}catch{}}notifyBillingError(e,t){if(!this.billingAlertCallback)return;let s=this.lastBillingAlertAt.get(e)??0;if(Date.now()-s<6*36e5)return;this.lastBillingAlertAt.set(e,Date.now());let n=this.multiConfig[e];try{this.billingAlertCallback({kind:"failure",tier:e,provider:n?.provider??"unknown",model:n?.model??"unknown",message:t.message.slice(0,300)})}catch{}}async executeComplete(e,t,s){let n=this.multiConfig[t],i=await e.complete(s),r=i.model??n?.model??"unknown";i.model||(i.model=r);let a=this.costTracker.record(r,i.usage);return this.logger?.info({tier:t,model:r,costUsd:Math.round(a*1e6)/1e6,inputTokens:i.usage?.inputTokens,outputTokens:i.usage?.outputTokens,cacheReadTokens:i.usage?.cacheReadTokens,cacheWriteTokens:i.usage?.cacheCreationTokens},"LLM call completed"),i}isRetryableError(e){if(e instanceof Error){let s=e.message.toLowerCase();if(s.includes("econnrefused")||s.includes("enotfound")||s.includes("etimedout")||s.includes("econnreset")||s.includes("socket hang up")||s.includes("fetch failed")||s.includes("eai_again")||s.includes("getaddrinfo")||s.includes("connection error")||s.includes("500")||s.includes("502")||s.includes("503")||s.includes("504")||s.includes("529")||s.includes("rate limit")||s.includes("overloaded")||s.includes("too many requests"))return!0}let t=e?.status??e?.statusCode;return typeof t=="number"&&(t>=500||t===429)}async completeWithFallback(e,t,s){let n=k0.filter(i=>i!==t);for(let i of n){if(this.isInBillingCooldown(i))continue;let r=this.providers.get(i);if(r)try{this.logger?.info({tier:i},"Fallback to tier");let a=await this.executeComplete(r,i,e);return this.maybeNotifyRecovery(i),this.meldePuls("erfolg",i),a}catch(a){this.isBillingError(a)&&this.registerBillingFailure(i,a),this.meldePuls("fehler",i,a);continue}}throw s}async*stream(e){let{provider:t,resolvedTier:s}=this.resolve(e.tier),n=this.withTierEffort(e,s);if(this.isInBillingCooldown(s)){this.logger?.info({tier:s},"v868.3 billing-cooldown aktiv \u2014 Stream direkt \xFCber Fallback-Kette"),yield*this.streamFallback(e,s,new Error(`Tier "${s}" im Billing-Cooldown`));return}let i=!1;try{for await(let r of t.stream(n))i=!0,yield r;this.maybeNotifyRecovery(s),this.meldePuls("erfolg",s);return}catch(r){let a=this.isBillingError(r);if(a&&this.registerBillingFailure(s,r),this.meldePuls("fehler",s,r),i||!a&&!this.isRetryableError(r))throw r;this.logger?.warn({err:r,tier:s,billing:a},"Stream provider failed before first chunk, attempting fallback"),yield*this.streamFallback(e,s,r)}}async*streamFallback(e,t,s){let n=k0.filter(i=>i!==t);for(let i of n){if(this.isInBillingCooldown(i))continue;let r=this.providers.get(i);if(r)try{this.logger?.info({tier:i},"Stream fallback to tier"),yield*r.stream(this.withTierEffort(e,i)),this.maybeNotifyRecovery(i),this.meldePuls("erfolg",i);return}catch(a){this.isBillingError(a)&&this.registerBillingFailure(i,a),this.meldePuls("fehler",i,a);continue}}throw s}async embed(e){let t=await(this.providers.get("embeddings")??this.resolve().provider).embed(e);return t?.totalTokens&&this.costTracker.record(t.model,{inputTokens:t.totalTokens,outputTokens:0}),t}supportsEmbeddings(){return(this.providers.get("embeddings")??this.resolve().provider).supportsEmbeddings()}isAvailable(){return this.resolve().provider.isAvailable()}getContextWindow(){return this.resolve().provider.getContextWindow()}getProviderStatuses(){let e={};for(let t of E0){let s=this.providers.get(t);if(s){let n=this.multiConfig[t];e[t]={model:n?.model??"unknown",available:s.isAvailable()}}}return e}getCostSummary(){return this.costTracker.getSummary()}setPersist(e){this.costTracker.setPersist(e)}};m(Pu,"createModelRouter")});function kP(l){let e=Date.now()-new Date(l).getTime();if(e<0)return l.slice(0,16).replace("T"," ");let t=Math.floor(e/1e3);if(t<120)return`${t}s ago`;let s=Math.floor(t/60);if(s<120)return`${s}m ago`;let n=Math.floor(s/60);return n<48?`${n}h ago`:`${Math.floor(n/24)}d ago`}function Vs(l){return Math.ceil(l.length/3.5)}function hi(l){if(typeof l.content=="string")return Vs(l.content)+4;let e=4;for(let t of l.content)switch(t.type){case"text":e+=Vs(t.text);break;case"image":e+=1e3;break;case"tool_use":e+=Vs(t.name)+Vs(JSON.stringify(t.input));break;case"tool_result":e+=Vs(t.content);break}return e}function Uu(l,e){let t=e?.keepRecentPairs??3,s=e?.maxTrimmedLength??120,n=e?.minContentLength??300,i=new Map;for(let o of l)if(o.role==="assistant"&&Array.isArray(o.content))for(let c of o.content)c.type==="tool_use"&&i.set(c.id,c.name);let r=[];for(let o=0;o<l.length;o++){let c=l[o];c.role==="user"&&Array.isArray(c.content)&&c.content.some(d=>d.type==="tool_result")&&r.push(o)}let a=new Set(r.slice(-t));return l.map((o,c)=>{if(a.has(c)||o.role!=="user"||!Array.isArray(o.content))return o;let d=!1,u=o.content.map(h=>{if(h.type!=="tool_result")return h;let p=h.content;if(typeof p!="string"||p.length<n)return h;d=!0;let f=i.get(h.tool_use_id)||"unknown",g=p.split(`
4193
4193
  `)[0].slice(0,s),y=h.is_error?"Fehler":"Ergebnis";return{...h,content:`[${y}: ${f} \u2014 ${g}]`}});return d?{...o,content:u}:o})}var _a,S0=A(()=>{"use strict";m(kP,"relativeAgo");m(Vs,"estimateTokens");m(hi,"estimateMessageTokens");m(Uu,"trimOldToolResults");_a=class{static{m(this,"PromptBuilder")}buildSystemPrompt(e={}){let{memories:t,skills:s,userProfile:n,todayEvents:i,conversationSummary:r}=e,a=process.platform==="darwin"?"macOS":process.platform==="win32"?"Windows":"Linux",o=process.env.HOME||process.env.USERPROFILE||"~",c=`You are Alfred, a personal AI assistant. You run on ${a} (home: ${o}).`;if(e.personality){let y=e.personality,w=[];y.tone&&w.push(`Tone: ${y.tone}`),y.humor&&w.push(`Humor: ${y.humor}`),y.directness&&w.push(`Directness: ${y.directness}`),y.language&&w.push(`Default language: ${y.language}`),y.custom&&w.push(y.custom),w.length>0&&(c+=`
4194
4194
 
4195
4195
  ## Personality
@@ -7748,7 +7748,7 @@ Base commit: \`${e.baseCommitSha.slice(0,8)}\``;return{ok:!0,prUrl:(await a.crea
7748
7748
  `)+d.join(`
7749
7749
  `)+`
7750
7750
  `;r(o,u,"utf8")}}catch(i){this.deps.logger.debug({err:i},"v726 .gitignore update skipped")}if(t.kind!=="empty")try{let{copyFileSync:i,statSync:r}=await import("node:fs");if(t.kind==="repo_path"){if(t.path.includes(".."))throw new Error("repo_path darf kein .. enthalten");let a=Wt.resolve(s,t.path);if(!a.startsWith(Wt.resolve(s)))throw new Error("repo_path verl\xE4sst projectCwd");let o=Wt.join(n,Wt.basename(a));i(a,o),this.deps.logger.info({src:a,target:o,size:r(o).size},"v726 db-seed copied from repo_path")}else if(t.kind==="upload"){if(!this.deps.dbSeedRepo||!this.deps.uploadSeedsPath)throw new Error("Upload-Seed angefordert aber dbSeedRepo/uploadSeedsPath nicht konfiguriert");let a=await this.deps.dbSeedRepo.getById(t.seedId);if(!a)throw new Error(`Seed ${t.seedId} nicht gefunden`);if(a.kind!=="upload")throw new Error(`Seed ${t.seedId} ist kind=${a.kind}, nicht upload`);let o=Wt.resolve(this.deps.uploadSeedsPath,a.storageRef);if(!o.startsWith(Wt.resolve(this.deps.uploadSeedsPath)))throw new Error("Upload-Seed verl\xE4sst uploadSeedsPath");let c=Wt.join(n,a.name);i(o,c),this.deps.logger.info({src:o,target:c,size:r(c).size},"v726 db-seed copied from upload")}}catch(i){this.deps.logger.warn({err:i},"v726 db-seed copy failed (sandbox startet mit leerem .alfred-data)")}}};m(Os,"runGit");m(Hz,"runGitBoth");zz=[{name:"AWS Access Key",re:/\bAKIA[0-9A-Z]{16}\b/g},{name:"GitHub Token",re:/\bghp_[A-Za-z0-9]{36}\b/g},{name:"GitHub PAT",re:/\bghs_[A-Za-z0-9]{36}\b/g},{name:"GitLab Token",re:/\bglpat-[A-Za-z0-9_-]{20}\b/g},{name:"OpenAI Key",re:/\bsk-[A-Za-z0-9]{48,}\b/g},{name:"Anthropic Key",re:/\bsk-ant-[A-Za-z0-9-_]{24,}\b/g},{name:"Stripe Secret",re:/\bsk_live_[A-Za-z0-9]{24,}\b/g},{name:"Slack Token",re:/\bxox[abp]-[A-Za-z0-9-]{10,}\b/g},{name:"Private Key",re:/-----BEGIN (?:RSA |EC |DSA )?PRIVATE KEY-----/g},{name:"JWT Token",re:/\beyJ[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}\b/g}];m(Xz,"stripAnsi");m(Wz,"summarizeTestFailure");m(Kz,"scanForSecrets");m(Gz,"parseRepoFromUrl");m(Vz,"resolveDockerfilesDir")});var oC={};Le(oC,{IdentityResolver:()=>ST});var ST,cC=A(()=>{"use strict";Vi();ST=class{static{m(this,"IdentityResolver")}users;projects;logger;constructor(e,t,s){this.users=e,this.projects=t,this.logger=s}async resolveOwnerFromConfig(e,t){if(!e||typeof e!="string")throw new Error("IdentityResolver.resolveOwnerFromConfig: empty/invalid envValue");if(Wr(e)){try{await this.users.findById(e)||this.logger.warn({envValue:e.slice(0,8)},"v804 owner UUID not found in users-table \u2014 accepting anyway (may belong to alfred_users table)")}catch{}return Wm(e)}let s=t??this.guessPlatformFromFormat(e);if(!s)throw new Error(`IdentityResolver.resolveOwnerFromConfig: "${e.slice(0,20)}" ist kein UUID-Format und keine platform-hint angegeben. Setze ALFRED_OWNER_PLATFORM=telegram (oder matrix/discord/etc.) oder ALFRED_OWNER_USER_ID direkt auf den DB-UUID.`);let n=await this.users.findOrCreate(s,e),i=ic(n.id);if(!i)throw new Error(`IdentityResolver: findOrCreate returned non-UUID id "${n.id}"`);return this.logger.info({platform:s,platformUserId:e.slice(0,12)+"\u2026",resolvedUUID:i.slice(0,8)+"\u2026"},"v804 owner platform-id resolved to UUID"),i}async resolveMasterId(e){try{let t=await this.users.getMasterUserId(e);return ic(t)??e}catch(t){return this.logger.debug({err:t,userId:e.slice(0,8)},"v804 getMasterUserId failed, returning original"),e}}async findProjectOwner(e){if(!this.projects)return null;try{let t=await this.projects.getByIdAnyOwner(e);return t?ic(t.userId)??null:null}catch(t){return this.logger.debug({err:t,projectId:e},"v804 findProjectOwner failed"),null}}guessPlatformFromFormat(e){if(/^\d{6,15}$/.test(e))return"telegram";if(/^@[^:]+:[\w.-]+$/.test(e))return"matrix"}}});var lC={};Le(lC,{UserIdAuditScanner:()=>vT});import{randomUUID as qz}from"node:crypto";var Jz,vT,dC=A(()=>{"use strict";Vi();Jz=[{table:"memories",pk:"id",uidColumn:"user_id"},{table:"documents",pk:"id",uidColumn:"user_id"},{table:"document_chunks",pk:"id",uidColumn:"user_id"},{table:"todos",pk:"id",uidColumn:"user_id"},{table:"notes",pk:"id",uidColumn:"user_id"},{table:"reminders",pk:"id",uidColumn:"user_id"},{table:"conversations",pk:"id",uidColumn:"user_id"},{table:"projects",pk:"id",uidColumn:"user_id"},{table:"background_tasks",pk:"id",uidColumn:"user_id"},{table:"agent_sessions",pk:"id",uidColumn:"user_id"},{table:"sandboxes",pk:"id",uidColumn:"user_id"},{table:"project_automations",pk:"id",uidColumn:"user_id"},{table:"goals",pk:"id",uidColumn:"user_id"},{table:"runbooks",pk:"id",uidColumn:"user_id"},{table:"insights",pk:"id",uidColumn:"user_id"}],vT=class{static{m(this,"UserIdAuditScanner")}adapter;logger;targets;constructor(e,t,s=Jz){this.adapter=e,this.logger=t,this.targets=s}async scan(){let e={scanned:0,flaggedNew:0,alreadyFlagged:0,skippedTables:[]},t=new Date().toISOString();for(let s of this.targets)try{let n=await this.adapter.query(`SELECT ${s.pk} AS row_id, ${s.uidColumn} AS uid FROM ${s.table} WHERE ${s.uidColumn} IS NOT NULL`);for(let i of n){e.scanned+=1;let r=Km(i.uid);if(r==="uuid")continue;if(await this.adapter.queryOne("SELECT id FROM user_id_format_audit WHERE table_name = ? AND column_name = ? AND row_id = ?",[s.table,s.uidColumn,String(i.row_id)])){e.alreadyFlagged+=1;continue}await this.adapter.execute(`INSERT INTO user_id_format_audit (id, table_name, column_name, row_id, user_id_value, format_class, detected_at)
7751
- VALUES (?, ?, ?, ?, ?, ?, ?)`,[qz(),s.table,s.uidColumn,String(i.row_id),i.uid,r,t]),e.flaggedNew+=1}}catch(n){let i=n.message??"";if(/no such table|does not exist|relation .* does not exist/i.test(i)){e.skippedTables.push(s.table);continue}this.logger.warn({err:n,table:s.table},"v808 audit-scan failed for table (continuing)")}return e.flaggedNew>0?this.logger.warn({scanned:e.scanned,flaggedNew:e.flaggedNew,alreadyFlagged:e.alreadyFlagged,skipped:e.skippedTables.length},"v808 UserIdAudit: non-UUID user_id rows detected \u2014 see user_id_format_audit table"):this.logger.debug({scanned:e.scanned,alreadyFlagged:e.alreadyFlagged,skipped:e.skippedTables.length},"v808 UserIdAudit: scan complete, all user_id rows have UUID format"),e}}});var Ff={};Le(Ff,{default:()=>Zz});var Zz,jf=A(()=>{Zz={name:"@madh-io/alfred-ai",version:"0.19.0-jarvis.1163",description:"Alfred \u2014 Personal AI Assistant across Telegram, Discord, WhatsApp, Matrix & Signal",type:"module",bin:{alfred:"bundle/index.js"},files:["bundle"],scripts:{build:"tsc",bundle:"node ../../scripts/bundle.mjs",prepublishOnly:"npm run build && npm run bundle",clean:"rm -rf dist bundle *.tsbuildinfo"},keywords:["ai","assistant","chatbot","telegram","discord","whatsapp","matrix","signal","claude","openai","ollama"],license:"MIT",repository:{type:"git",url:"https://github.com/madh99/alfred-ai.git"},homepage:"https://github.com/madh99/alfred-ai#readme",bugs:{url:"https://github.com/madh99/alfred-ai/issues"},dependencies:{"@anthropic-ai/sdk":"^0.105.0","@google/genai":"^1.45.0","@modelcontextprotocol/sdk":"^1.12.1","better-sqlite3":"^11.8.0",botbuilder:"^4.23.0",ccxt:"^4.4.0","discord.js":"^14.18.0",docx:"^9.0.0",dotenv:"^16.4.0",exceljs:"^4.4.0",grammy:"^1.35.0",imapflow:"^1.2.10","js-yaml":"^4.1.0",mammoth:"^1.8.0",mqtt:"^5.0.0",nodemailer:"^8.0.1",openai:"^6.44.0","pdf-parse":"^1.1.1",pdfkit:"^0.16.0",pino:"^9.6.0","pino-pretty":"^13.0.0",puppeteer:"^24.0.0","puppeteer-core":"^24.0.0","rss-parser":"^3.13.0",sharp:"^0.34.0",sonos:"^1.14.0",undici:"^7.10.0","youtube-transcript":"^1.3.0",zod:"^3.24.0"},optionalDependencies:{"@aws-sdk/client-s3":"^3.700.0","@influxdata/influxdb-client":"^1.35.0","@whiskeysockets/baileys":"6.7.21",googleapis:"^144.0.0","hafas-client":"^6.3.0",ioredis:"^5.4.0","matrix-bot-sdk":"^0.8.0",mongodb:"^6.12.0",mssql:"^11.0.0",mysql2:"^3.12.0",pg:"^8.13.0",tsdav:"^2.1.0"},devDependencies:{"@alfred/config":"workspace:*","@alfred/core":"workspace:*","@alfred/logger":"workspace:*","@alfred/mcp-server":"workspace:*","@alfred/security":"workspace:*","@alfred/storage":"workspace:*","@alfred/types":"workspace:*","@types/js-yaml":"^4.0.9"},publishConfig:{access:"public"},engines:{node:">=20"}}});var uC={};Le(uC,{collectNodeMetrics:()=>Bf});import Po from"node:os";import{statfs as Qz}from"node:fs/promises";async function Bf(l){let e=[],t=new Set;for(let s of l)if(s)try{let n=await Qz(s),i=Number(n.blocks)*Number(n.bsize),r=Number(n.bavail)*Number(n.bsize);if(i<=0)continue;let a=`${i}:${Number(n.bfree)}:${Number(n.type)}`;if(t.has(a))continue;t.add(a),e.push({path:s,totalGb:IT(i/1024**3),freeGb:IT(r/1024**3),usedPct:Math.min(100,Math.max(0,Math.round((1-r/i)*100)))})}catch{}return{cpuLoad1m:IT(Po.loadavg()[0]??0),cpuCores:Po.cpus().length,memTotalMb:Math.round(Po.totalmem()/1024**2),memFreeMb:Math.round(Po.freemem()/1024**2),rssMb:Math.round(process.memoryUsage().rss/1024**2),nodeJs:process.version,platform:Po.platform(),osRelease:Po.release(),disks:e}}function IT(l){return Math.round(l*10)/10}var Hf=A(()=>{"use strict";m(Bf,"collectNodeMetrics");m(IT,"round1")});var pC={};Le(pC,{ClusterManager:()=>wd});import hC from"node:os";var wd,AT=A(()=>{"use strict";Hf();wd=class{static{m(this,"ClusterManager")}config;logger;redis;heartbeatTimer;heartbeatMs;failoverMs;constructor(e,t){this.config=e,this.logger=t,this.heartbeatMs=e.heartbeatIntervalMs??1e4,this.failoverMs=e.failoverAfterMs??3e4}async connect(){try{let e;try{e=(await Function('return import("ioredis")')()).default}catch{throw new Error('Cluster mode requires the "ioredis" package. Install it: npm install ioredis')}this.redis=new e(this.config.redisUrl),this.logger.info({nodeId:this.config.nodeId,role:this.config.role},"Cluster manager connected to Redis")}catch(e){this.logger.error({err:e},"Failed to connect to Redis \u2014 cluster features disabled");return}this.heartbeatTimer=setInterval(()=>this.sendHeartbeat(),this.heartbeatMs),await this.sendHeartbeat()}async disconnect(){this.heartbeatTimer&&clearInterval(this.heartbeatTimer),await this.redis?.quit()}nodeInfo;setNodeInfo(e){this.nodeInfo=e}async collectMetricsSafe(){try{return JSON.stringify(await Bf(this.nodeInfo?.diskPaths??["/"]))}catch{return"{}"}}async sendHeartbeat(){try{let e=Math.floor(process.uptime()),t=JSON.stringify({id:this.config.nodeId,role:this.config.role,timestamp:new Date().toISOString(),uptime:e,host:hC.hostname(),version:this.nodeInfo?.version??"",adapters:this.nodeInfo?.adapters?.()??[]});await this.redis.set(`alfred:cluster:heartbeat:${this.config.nodeId}`,t,"EX",Math.ceil(this.failoverMs/1e3))}catch(e){this.logger.warn({err:e},"Heartbeat send failed")}}async getNodes(){if(!this.redis)return[];try{let e=await this.redis.keys("alfred:cluster:heartbeat:*"),t=[];for(let s of e){let n=await this.redis.get(s);if(n)try{let i=JSON.parse(n);t.push({...i,healthy:!0})}catch{}}return t}catch{return[]}}async acquireLock(e,t=3e5){if(!this.redis)return!0;try{return await this.redis.set(`alfred:lock:${e}`,this.config.nodeId,"NX","PX",t)==="OK"}catch{return!0}}async releaseLock(e){if(this.redis)try{await this.redis.get(`alfred:lock:${e}`)===this.config.nodeId&&await this.redis.del(`alfred:lock:${e}`)}catch{}}async publish(e,t){if(this.redis)try{await this.redis.publish(`alfred:${e}`,JSON.stringify({...t,nodeId:this.config.nodeId}))}catch(s){this.logger.warn({err:s,channel:e},"Cluster publish failed")}}async subscribe(e,t){if(this.redis)try{let s=this.redis.duplicate();await s.subscribe(`alfred:${e}`),s.on("message",(n,i)=>{try{let r=JSON.parse(i);r.nodeId!==this.config.nodeId&&t(r)}catch{}})}catch(s){this.logger.warn({err:s,channel:e},"Cluster subscribe failed")}}async routeMessage(e,t,s){await this.publish("messages",{type:"send_message",targetPlatform:e,chatId:t,text:s})}failoverCheckTimer;onFailoverCallback;startFailoverMonitoring(e){this.config.role==="secondary"&&(this.onFailoverCallback=e,this.failoverCheckTimer=setInterval(async()=>{try{let t=await this.getNodes(),s=new Set(t.map(n=>n.id));for(let n of this.config.nodes??[])n.id!==this.config.nodeId&&(s.has(n.id)||(this.logger.warn({deadNodeId:n.id},"Node heartbeat missing \u2014 failover triggered"),this.onFailoverCallback?.(n.id)))}catch(t){this.logger.debug({err:t},"Failover check error")}},this.failoverMs))}stopFailoverMonitoring(){this.failoverCheckTimer&&clearInterval(this.failoverCheckTimer)}async announceTakeover(e,t){await this.publish("events",{type:"failover",deadNodeId:e,takenOverBy:this.config.nodeId,adapters:t}),this.logger.info({deadNodeId:e,adapters:t},"Failover: adapters taken over")}async syncConfig(e,t){await this.publish("config-sync",{type:e,...t})}async onConfigSync(e){await this.subscribe("config-sync",t=>{let{type:s,...n}=t;e(s,n)})}get nodeId(){return this.config.nodeId}get role(){return this.config.role??"node"}get isConnected(){return!!this.redis}pgAdapter;pgHeartbeatTimer;startPgHeartbeat(e){this.pgAdapter=e,this.pgHeartbeatTimer=setInterval(()=>this.sendPgHeartbeat(),this.heartbeatMs),this.sendPgHeartbeat()}async sendPgHeartbeat(){if(this.pgAdapter)try{let e=new Date().toISOString(),t=Math.floor(process.uptime()),s=new Date(Date.now()-t*1e3).toISOString(),n=await this.collectMetricsSafe();await this.pgAdapter.execute(`INSERT INTO node_heartbeats (node_id, host, last_seen_at, started_at, uptime_s, adapters, version, metrics)
7751
+ VALUES (?, ?, ?, ?, ?, ?, ?)`,[qz(),s.table,s.uidColumn,String(i.row_id),i.uid,r,t]),e.flaggedNew+=1}}catch(n){let i=n.message??"";if(/no such table|does not exist|relation .* does not exist/i.test(i)){e.skippedTables.push(s.table);continue}this.logger.warn({err:n,table:s.table},"v808 audit-scan failed for table (continuing)")}return e.flaggedNew>0?this.logger.warn({scanned:e.scanned,flaggedNew:e.flaggedNew,alreadyFlagged:e.alreadyFlagged,skipped:e.skippedTables.length},"v808 UserIdAudit: non-UUID user_id rows detected \u2014 see user_id_format_audit table"):this.logger.debug({scanned:e.scanned,alreadyFlagged:e.alreadyFlagged,skipped:e.skippedTables.length},"v808 UserIdAudit: scan complete, all user_id rows have UUID format"),e}}});var Ff={};Le(Ff,{default:()=>Zz});var Zz,jf=A(()=>{Zz={name:"@madh-io/alfred-ai",version:"0.19.0-jarvis.1164",description:"Alfred \u2014 Personal AI Assistant across Telegram, Discord, WhatsApp, Matrix & Signal",type:"module",bin:{alfred:"bundle/index.js"},files:["bundle"],scripts:{build:"tsc",bundle:"node ../../scripts/bundle.mjs",prepublishOnly:"npm run build && npm run bundle",clean:"rm -rf dist bundle *.tsbuildinfo"},keywords:["ai","assistant","chatbot","telegram","discord","whatsapp","matrix","signal","claude","openai","ollama"],license:"MIT",repository:{type:"git",url:"https://github.com/madh99/alfred-ai.git"},homepage:"https://github.com/madh99/alfred-ai#readme",bugs:{url:"https://github.com/madh99/alfred-ai/issues"},dependencies:{"@anthropic-ai/sdk":"^0.105.0","@google/genai":"^1.45.0","@modelcontextprotocol/sdk":"^1.12.1","better-sqlite3":"^11.8.0",botbuilder:"^4.23.0",ccxt:"^4.4.0","discord.js":"^14.18.0",docx:"^9.0.0",dotenv:"^16.4.0",exceljs:"^4.4.0",grammy:"^1.35.0",imapflow:"^1.2.10","js-yaml":"^4.1.0",mammoth:"^1.8.0",mqtt:"^5.0.0",nodemailer:"^8.0.1",openai:"^6.44.0","pdf-parse":"^1.1.1",pdfkit:"^0.16.0",pino:"^9.6.0","pino-pretty":"^13.0.0",puppeteer:"^24.0.0","puppeteer-core":"^24.0.0","rss-parser":"^3.13.0",sharp:"^0.34.0",sonos:"^1.14.0",undici:"^7.10.0","youtube-transcript":"^1.3.0",zod:"^3.24.0"},optionalDependencies:{"@aws-sdk/client-s3":"^3.700.0","@influxdata/influxdb-client":"^1.35.0","@whiskeysockets/baileys":"6.7.21",googleapis:"^144.0.0","hafas-client":"^6.3.0",ioredis:"^5.4.0","matrix-bot-sdk":"^0.8.0",mongodb:"^6.12.0",mssql:"^11.0.0",mysql2:"^3.12.0",pg:"^8.13.0",tsdav:"^2.1.0"},devDependencies:{"@alfred/config":"workspace:*","@alfred/core":"workspace:*","@alfred/logger":"workspace:*","@alfred/mcp-server":"workspace:*","@alfred/security":"workspace:*","@alfred/storage":"workspace:*","@alfred/types":"workspace:*","@types/js-yaml":"^4.0.9"},publishConfig:{access:"public"},engines:{node:">=20"}}});var uC={};Le(uC,{collectNodeMetrics:()=>Bf});import Po from"node:os";import{statfs as Qz}from"node:fs/promises";async function Bf(l){let e=[],t=new Set;for(let s of l)if(s)try{let n=await Qz(s),i=Number(n.blocks)*Number(n.bsize),r=Number(n.bavail)*Number(n.bsize);if(i<=0)continue;let a=`${i}:${Number(n.bfree)}:${Number(n.type)}`;if(t.has(a))continue;t.add(a),e.push({path:s,totalGb:IT(i/1024**3),freeGb:IT(r/1024**3),usedPct:Math.min(100,Math.max(0,Math.round((1-r/i)*100)))})}catch{}return{cpuLoad1m:IT(Po.loadavg()[0]??0),cpuCores:Po.cpus().length,memTotalMb:Math.round(Po.totalmem()/1024**2),memFreeMb:Math.round(Po.freemem()/1024**2),rssMb:Math.round(process.memoryUsage().rss/1024**2),nodeJs:process.version,platform:Po.platform(),osRelease:Po.release(),disks:e}}function IT(l){return Math.round(l*10)/10}var Hf=A(()=>{"use strict";m(Bf,"collectNodeMetrics");m(IT,"round1")});var pC={};Le(pC,{ClusterManager:()=>wd});import hC from"node:os";var wd,AT=A(()=>{"use strict";Hf();wd=class{static{m(this,"ClusterManager")}config;logger;redis;heartbeatTimer;heartbeatMs;failoverMs;constructor(e,t){this.config=e,this.logger=t,this.heartbeatMs=e.heartbeatIntervalMs??1e4,this.failoverMs=e.failoverAfterMs??3e4}async connect(){try{let e;try{e=(await Function('return import("ioredis")')()).default}catch{throw new Error('Cluster mode requires the "ioredis" package. Install it: npm install ioredis')}this.redis=new e(this.config.redisUrl),this.logger.info({nodeId:this.config.nodeId,role:this.config.role},"Cluster manager connected to Redis")}catch(e){this.logger.error({err:e},"Failed to connect to Redis \u2014 cluster features disabled");return}this.heartbeatTimer=setInterval(()=>this.sendHeartbeat(),this.heartbeatMs),await this.sendHeartbeat()}async disconnect(){this.heartbeatTimer&&clearInterval(this.heartbeatTimer),await this.redis?.quit()}nodeInfo;setNodeInfo(e){this.nodeInfo=e}async collectMetricsSafe(){try{return JSON.stringify(await Bf(this.nodeInfo?.diskPaths??["/"]))}catch{return"{}"}}async sendHeartbeat(){try{let e=Math.floor(process.uptime()),t=JSON.stringify({id:this.config.nodeId,role:this.config.role,timestamp:new Date().toISOString(),uptime:e,host:hC.hostname(),version:this.nodeInfo?.version??"",adapters:this.nodeInfo?.adapters?.()??[]});await this.redis.set(`alfred:cluster:heartbeat:${this.config.nodeId}`,t,"EX",Math.ceil(this.failoverMs/1e3))}catch(e){this.logger.warn({err:e},"Heartbeat send failed")}}async getNodes(){if(!this.redis)return[];try{let e=await this.redis.keys("alfred:cluster:heartbeat:*"),t=[];for(let s of e){let n=await this.redis.get(s);if(n)try{let i=JSON.parse(n);t.push({...i,healthy:!0})}catch{}}return t}catch{return[]}}async acquireLock(e,t=3e5){if(!this.redis)return!0;try{return await this.redis.set(`alfred:lock:${e}`,this.config.nodeId,"NX","PX",t)==="OK"}catch{return!0}}async releaseLock(e){if(this.redis)try{await this.redis.get(`alfred:lock:${e}`)===this.config.nodeId&&await this.redis.del(`alfred:lock:${e}`)}catch{}}async publish(e,t){if(this.redis)try{await this.redis.publish(`alfred:${e}`,JSON.stringify({...t,nodeId:this.config.nodeId}))}catch(s){this.logger.warn({err:s,channel:e},"Cluster publish failed")}}async subscribe(e,t){if(this.redis)try{let s=this.redis.duplicate();await s.subscribe(`alfred:${e}`),s.on("message",(n,i)=>{try{let r=JSON.parse(i);r.nodeId!==this.config.nodeId&&t(r)}catch{}})}catch(s){this.logger.warn({err:s,channel:e},"Cluster subscribe failed")}}async routeMessage(e,t,s){await this.publish("messages",{type:"send_message",targetPlatform:e,chatId:t,text:s})}failoverCheckTimer;onFailoverCallback;startFailoverMonitoring(e){this.config.role==="secondary"&&(this.onFailoverCallback=e,this.failoverCheckTimer=setInterval(async()=>{try{let t=await this.getNodes(),s=new Set(t.map(n=>n.id));for(let n of this.config.nodes??[])n.id!==this.config.nodeId&&(s.has(n.id)||(this.logger.warn({deadNodeId:n.id},"Node heartbeat missing \u2014 failover triggered"),this.onFailoverCallback?.(n.id)))}catch(t){this.logger.debug({err:t},"Failover check error")}},this.failoverMs))}stopFailoverMonitoring(){this.failoverCheckTimer&&clearInterval(this.failoverCheckTimer)}async announceTakeover(e,t){await this.publish("events",{type:"failover",deadNodeId:e,takenOverBy:this.config.nodeId,adapters:t}),this.logger.info({deadNodeId:e,adapters:t},"Failover: adapters taken over")}async syncConfig(e,t){await this.publish("config-sync",{type:e,...t})}async onConfigSync(e){await this.subscribe("config-sync",t=>{let{type:s,...n}=t;e(s,n)})}get nodeId(){return this.config.nodeId}get role(){return this.config.role??"node"}get isConnected(){return!!this.redis}pgAdapter;pgHeartbeatTimer;startPgHeartbeat(e){this.pgAdapter=e,this.pgHeartbeatTimer=setInterval(()=>this.sendPgHeartbeat(),this.heartbeatMs),this.sendPgHeartbeat()}async sendPgHeartbeat(){if(this.pgAdapter)try{let e=new Date().toISOString(),t=Math.floor(process.uptime()),s=new Date(Date.now()-t*1e3).toISOString(),n=await this.collectMetricsSafe();await this.pgAdapter.execute(`INSERT INTO node_heartbeats (node_id, host, last_seen_at, started_at, uptime_s, adapters, version, metrics)
7752
7752
  VALUES (?, ?, ?, ?, ?, ?, ?, ?)
7753
7753
  ON CONFLICT (node_id) DO UPDATE SET
7754
7754
  host = excluded.host,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@madh-io/alfred-ai",
3
- "version": "0.19.0-jarvis.1163",
3
+ "version": "0.19.0-jarvis.1164",
4
4
  "description": "Alfred — Personal AI Assistant across Telegram, Discord, WhatsApp, Matrix & Signal",
5
5
  "type": "module",
6
6
  "bin": {