@madh-io/alfred-ai 0.19.0-jarvis.1162 → 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 +5 -5
  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
@@ -7183,7 +7183,7 @@ ${i.join(`
7183
7183
 
7184
7184
  `)}
7185
7185
 
7186
- Antworte wenn du einen Vorschlag umsetzen moechtest.`)}e.length>0&&this.logger.info({auto:t.length,proactive:s.length,confirm:n.length},"Reflection: execution complete")}async executeAction(e){switch(e.target.type){case"watch":if(!e.target.id)return;switch(e.action){case"adjust":e.params&&await this.watchRepo.updateSettings(e.target.id,e.params);break;case"delete":await this.watchRepo.delete(e.target.id);break;case"deactivate":case"pause":await this.watchRepo.toggle(e.target.id,!1);break}break;case"workflow":if(!e.target.id||!this.workflowRepo)return;switch(e.action){case"deactivate":await this.workflowRepo.toggle(e.target.id,!1);break;case"delete":await this.workflowRepo.delete(e.target.id);break}break;case"reminder":if(!e.target.id||!this.adapter)return;e.action==="delete"&&await this.adapter.execute("DELETE FROM reminders WHERE id = ?",[e.target.id]);break}}async notifyUser(e){let t=this.adapters.get(this.defaultPlatform);if(t)try{await t.sendMessage(this.defaultChatId,e)}catch(s){this.logger.warn({err:s},"Reflection: failed to notify user")}}}});var ad,T_=A(()=>{"use strict";f_();m_();g_();y_();w_();PR();__();ad=class{static{m(this,"ReflectionEngine")}logger;watchReflector;workflowReflector;reminderReflector;conversationReflector;docReflector;openItemsReflector;actionExecutor;lastOpenItemsHour=-1;config;nodeId;dbAdapter;timer;lastRunDay="";constructor(e,t){this.logger=e.logger.child({component:"reflection-engine"}),this.config=e.config,this.nodeId=e.nodeId,this.dbAdapter=t;let s=e.adapters.get(e.defaultPlatform);this.watchReflector=new Io(e.watchRepo,e.activityRepo,e.logger.child({component:"watch-reflector"}),e.config.watches),this.workflowReflector=new Ao(e.workflowRepo,e.activityRepo,e.logger.child({component:"workflow-reflector"}),e.config.workflows),this.reminderReflector=new Ro(t,e.memoryRepo,e.logger.child({component:"reminder-reflector"}),e.config.reminders),this.conversationReflector=new No(e.llm,e.activityRepo,e.memoryRepo,t,e.logger.child({component:"conversation-reflector"}),e.config.conversation),this.docReflector=new rd(e.cmdbRepo,e.logger.child({component:"doc-reflector"}),e.config.docs),e.projectRepo&&e.ownerUserId&&(this.openItemsReflector=new lf({projectRepo:e.projectRepo,memoryRepo:e.memoryRepo,adapters:e.adapters,defaultPlatform:e.defaultPlatform,defaultChatId:e.defaultChatId,ownerUserId:e.ownerUserId,logger:e.logger.child({component:"open-items-reflector"}),confirmationQueue:e.confirmationQueue,resolveAgent:e.resolveAgent})),this.actionExecutor=new $o(e.watchRepo,e.workflowRepo,t,e.adapters,e.defaultChatId,e.defaultPlatform,e.logger.child({component:"action-executor"}))}start(){if(!this.config.enabled){this.logger.info("Reflection engine disabled");return}this.logger.info({schedule:this.config.schedule},"Reflection engine started"),this.timer=setInterval(()=>{this.tick().catch(e=>this.logger.error({err:e},"Reflection tick error"))},60*6e4)}stop(){this.timer&&(clearInterval(this.timer),this.timer=void 0,this.logger.info("Reflection engine stopped"))}async tick(){let e=new Date,t=e.toISOString().slice(0,10);if(this.openItemsReflector&&this.lastOpenItemsHour!==e.getHours()){this.lastOpenItemsHour=e.getHours();try{await this.openItemsReflector.hourlySweep()}catch(f){this.logger.warn({err:f},"open-items hourly sweep failed")}if(e.getHours()===9)try{await this.openItemsReflector.dailyDigest()}catch(f){this.logger.warn({err:f},"open-items daily digest failed")}}let s=this.config.schedule.match(/^\d+\s+(\d+)/),n=s?parseInt(s[1],10):4;if(e.getHours()!==n||this.lastRunDay===t)return;if(this.lastRunDay=t,this.dbAdapter&&this.dbAdapter.type==="postgres"){let f=`reflection:${t}`;if((await this.dbAdapter.execute("INSERT INTO reasoning_slots (slot_key, node_id, claimed_at) VALUES (?, ?, ?) ON CONFLICT DO NOTHING",[f,this.nodeId,e.toISOString()])).changes===0){this.logger.debug("Reflection slot already claimed by another node");return}}this.logger.info("Reflection cycle starting");let i=Date.now(),r="master",a=await Promise.allSettled([this.watchReflector.reflect(r),this.workflowReflector.reflect(r),this.reminderReflector.reflect(r),this.conversationReflector.reflect(r),this.docReflector.reflect(r)]),o=[],c=["watch","workflow","reminder","conversation","docs"];for(let f=0;f<a.length;f++){let g=a[f];g.status==="fulfilled"?o.push(...g.value):this.logger.warn({err:g.reason,reflector:c[f]},"Reflector failed")}o.length>0&&await this.actionExecutor.execute(o);let d=Date.now()-i,u=o.filter(f=>f.risk==="auto").length,h=o.filter(f=>f.risk==="proactive").length,p=o.filter(f=>f.risk==="confirm").length;this.logger.info({total:o.length,auto:u,proactive:h,confirm:p,durationMs:d},"Reflection cycle complete")}}});var FR={};Le(FR,{RefusalCorrectionReflector:()=>df});var UR,xB,df,E_=A(()=>{"use strict";UR=[/\b(kann ich nicht|kann ich leider nicht|nicht möglich|geht nicht|funktioniert nicht|nicht implementiert|keine möglichkeit|habe keine möglichkeit)\b/i,/\b(i can'?t|i cannot|not possible|not implemented|no way to)\b/i],xB=[/\b(doch|geht doch|hast du schon|hast du in der vergangenheit|musst du|du kannst|funktioniert doch|war doch|ist doch|aber du)\b/i,/\b(yes you can|you did|you have done|you should|works)\b/i],df=class{static{m(this,"RefusalCorrectionReflector")}conversationRepo;recipeRepo;logger;windowMinutes;maxStepsToSuccess;lookbackHours;seen=new Set;constructor(e,t,s,n){this.conversationRepo=e,this.recipeRepo=t,this.logger=s,this.windowMinutes=n?.windowMinutes??30,this.maxStepsToSuccess=n?.maxStepsToSuccess??6,this.lookbackHours=n?.lookbackHours??24}async scanForUser(e){let t=[];try{let s=await this.conversationRepo.listConversations({userId:e,limit:20});for(let n of s){let i=await this.conversationRepo.getMessages(n.id,100),r=this.detectInMessages(n.id,e,i);for(let a of r){let o=`${a.refusalMessageId}:${a.correctionMessageId}:${a.successMessageId}`;this.seen.has(o)||(this.seen.add(o),await this.recipeRepo.create({userId:e,triggerPhrase:a.triggerPhrase,triggerKeywords:a.triggerKeywords,actionSequence:a.actionSequence,contextHint:a.contextHint,source:"refusal_correction",confidence:.5}),t.push(a),this.logger.info({userId:e,conversationId:n.id,trigger:a.triggerPhrase.slice(0,60),steps:a.actionSequence.length},"v722 refusal-correction pattern \u2192 learned recipe persisted"))}}}catch(s){this.logger.warn({err:s,userId:e},"v722 refusal-correction scan failed")}return t}detectInMessages(e,t,s){let n=[],i=new Date(Date.now()-this.lookbackHours*36e5).toISOString(),r=s.filter(a=>a.createdAt>=i);for(let a=0;a<r.length;a++){let o=r[a];if(o.role!=="assistant"||!UR.some(f=>f.test(o.content)))continue;let c;for(let f=a-1;f>=0;f--)if(r[f].role==="user"){c=r[f];break}if(!c)continue;let d=-1;for(let f=a+1;f<Math.min(a+1+this.maxStepsToSuccess,r.length);f++){let g=r[f];if(g.role==="user"){if(this.spanMinutes(o.createdAt,g.createdAt)>this.windowMinutes)break;if(xB.some(y=>y.test(g.content))){d=f;break}}}if(d<0)continue;let u;for(let f=d+1;f<Math.min(d+1+this.maxStepsToSuccess,r.length);f++){let g=r[f];if(g.role==="assistant"&&!UR.some(y=>y.test(g.content))&&g.toolCalls){u=g;break}}if(!u?.toolCalls)continue;let h=this.extractActions(u.toolCalls);if(h.length===0)continue;let p=c.content.slice(0,200);n.push({conversationId:e,userId:t,triggerPhrase:p,triggerKeywords:this.tokenize(p),actionSequence:h,contextHint:this.extractContextHint(u.content),refusalMessageId:o.id,correctionMessageId:r[d].id,successMessageId:u.id,detectedAt:new Date().toISOString()})}return n}spanMinutes(e,t){return Math.abs(new Date(t).getTime()-new Date(e).getTime())/6e4}tokenize(e){let s=e.toLowerCase().match(/[a-zäöüß0-9_]+/g)??[],n=new Set(["der","die","das","ein","eine","und","oder","aber","mit","ohne","f\xFCr","von","auf","bitte","kannst","k\xF6nntest","starte","spiel","spiele"]),i=new Set;for(let r of s)r.length<4||n.has(r)||i.add(r);return Array.from(i).slice(0,8)}extractActions(e){try{let t=JSON.parse(e);if(!Array.isArray(t))return[];let s=[];for(let n of t){let i=n.skill??n.skillName??n.name;if(typeof i!="string")continue;let r=n.args??n.params??n.parameters??{};s.push({skill:i,action:typeof r.action=="string"?r.action:void 0,params:r})}return s}catch{return[]}}extractContextHint(e){let t=e.match(/(?:memory|gemerkt|gespeichert)[^\n.]{0,80}/i);if(t)return t[0].slice(0,120)}}});function uf(l){return{enabled:l?.enabled??!0,schedule:l?.schedule??"0 4 * * *",watches:{staleAfterDays:l?.watches?.staleAfterDays??14,deleteAfterDays:l?.watches?.deleteAfterDays??30,maxTriggersPerDay:l?.watches?.maxTriggersPerDay??10,ignoredAlertsBeforePause:l?.watches?.ignoredAlertsBeforePause??5,failedActionsBeforeDisable:l?.watches?.failedActionsBeforeDisable??3},workflows:{staleAfterDays:l?.workflows?.staleAfterDays??30,failedStepsBeforeSuggest:l?.workflows?.failedStepsBeforeSuggest??3},reminders:{repeatPatternDays:l?.reminders?.repeatPatternDays??7,quickDismissSeconds:l?.reminders?.quickDismissSeconds??30},conversation:{repeatQueryThreshold:l?.conversation?.repeatQueryThreshold??3,repeatSequenceThreshold:l?.conversation?.repeatSequenceThreshold??3,analysisWindowDays:l?.conversation?.analysisWindowDays??7},docs:{configSnapshotIntervalDays:l?.docs?.configSnapshotIntervalDays??30,staleDocWarningDays:l?.docs?.staleDocWarningDays??90,runbookValidation:l?.docs?.runbookValidation??!0},autonomy:{adjustParams:l?.autonomy?.adjustParams??"auto",deleteWatch:l?.autonomy?.deleteWatch??"proactive",createAutomation:l?.autonomy?.createAutomation??"confirm",deactivate:l?.autonomy?.deactivate??"proactive"}}}var jR=A(()=>{"use strict";m(uf,"resolveReflectionConfig")});var k_=A(()=>{"use strict";f_();m_();g_();y_();w_();__();E_();jR()});var BR={};Le(BR,{ProviderPuls:()=>od});var od,b_=A(()=>{"use strict";od=class{static{m(this,"ProviderPuls")}logger;persistenz;now;tiers=new Map;schreibTimer;dirty=new Set;constructor(e,t,s=()=>new Date){this.logger=e,this.persistenz=t,this.now=s}async lade(){if(this.persistenz)try{for(let e of await this.persistenz.ladeAlle())this.tiers.set(e.tier,e)}catch(e){this.logger.warn({err:e.message},"Lebenszeichen: Provider-Puls konnte nicht geladen werden")}}verarbeite(e){let t=this.now().toISOString(),s=this.tiers.get(e.tier)??{tier:e.tier,provider:e.provider,model:e.model,erfolge:0,fehler:0,updatedAt:t};return s.provider=e.provider,s.model=e.model,s.updatedAt=t,e.art==="erfolg"?(s.letzterErfolg=t,s.erfolge++,s.gestoertSeit=void 0,s.fehlerKlasse=void 0,s.fehlerText=void 0):(s.letzterFehler=t,s.fehler++,s.fehlerKlasse=e.klasse??"unbekannt",s.fehlerText=e.fehler,s.gestoertSeit||(s.gestoertSeit=t)),this.tiers.set(e.tier,s),this.markiere(e.tier),s}zustand(e){return this.tiers.get(e)}alle(){return[...this.tiers.values()].sort((e,t)=>e.tier.localeCompare(t.tier))}static istGestoert(e){return e.letzterFehler?e.letzterErfolg?e.letzterFehler>e.letzterErfolg:!0:!1}markiere(e){this.persistenz&&(this.dirty.add(e),!this.schreibTimer&&(this.schreibTimer=setTimeout(()=>{this.schreibe()},3e4),this.schreibTimer.unref?.()))}async schreibe(){if(this.schreibTimer&&(clearTimeout(this.schreibTimer),this.schreibTimer=void 0),!this.persistenz)return;let e=[...this.dirty];this.dirty.clear();for(let t of e){let s=this.tiers.get(t);s&&await this.persistenz.speichere(s).catch(n=>this.logger.debug({err:n.message,tier:t},"Lebenszeichen: Puls-Schreiben fehlgeschlagen"))}}}});var HR,zR=A(()=>{"use strict";HR={name:"alfred.memory.recall",description:"Search Alfred's persisted memories (user preferences, project context, learned facts). Returns top-matching memories by keyword or semantic similarity. Read-only.",inputSchema:{type:"object",properties:{query:{type:"string",description:'Search query (natural language or keywords). Example: "alpbyte-games stack" or "deploy server preferences".'},limit:{type:"number",description:"Maximum number of results (default 10, max 50).",default:10},type:{type:"string",description:'Optional: filter by memory type (e.g. "user", "feedback", "project", "reference"). Omit to search all.'}},required:["query"]},async handler(l,e){let t=String(l.query??"").trim();if(!t)return{matches:[],note:"empty query \u2014 provide search terms"};let s=Math.max(1,Math.min(50,Number(l.limit??10))),n=typeof l.type=="string"?l.type:void 0,i=e.masterUserId,r=[`%${t}%`,`%${t}%`],a=`SELECT key, value, type, last_used_at FROM memories
7186
+ Antworte wenn du einen Vorschlag umsetzen moechtest.`)}e.length>0&&this.logger.info({auto:t.length,proactive:s.length,confirm:n.length},"Reflection: execution complete")}async executeAction(e){switch(e.target.type){case"watch":if(!e.target.id)return;switch(e.action){case"adjust":e.params&&await this.watchRepo.updateSettings(e.target.id,e.params);break;case"delete":await this.watchRepo.delete(e.target.id);break;case"deactivate":case"pause":await this.watchRepo.toggle(e.target.id,!1);break}break;case"workflow":if(!e.target.id||!this.workflowRepo)return;switch(e.action){case"deactivate":await this.workflowRepo.toggle(e.target.id,!1);break;case"delete":await this.workflowRepo.delete(e.target.id);break}break;case"reminder":if(!e.target.id||!this.adapter)return;e.action==="delete"&&await this.adapter.execute("DELETE FROM reminders WHERE id = ?",[e.target.id]);break}}async notifyUser(e){let t=this.adapters.get(this.defaultPlatform);if(t)try{await t.sendMessage(this.defaultChatId,e)}catch(s){this.logger.warn({err:s},"Reflection: failed to notify user")}}}});var ad,T_=A(()=>{"use strict";f_();m_();g_();y_();w_();PR();__();ad=class{static{m(this,"ReflectionEngine")}logger;watchReflector;workflowReflector;reminderReflector;conversationReflector;docReflector;openItemsReflector;actionExecutor;lastOpenItemsHour=-1;config;nodeId;dbAdapter;timer;lastRunDay="";constructor(e,t){this.logger=e.logger.child({component:"reflection-engine"}),this.config=e.config,this.nodeId=e.nodeId,this.dbAdapter=t;let s=e.adapters.get(e.defaultPlatform);this.watchReflector=new Io(e.watchRepo,e.activityRepo,e.logger.child({component:"watch-reflector"}),e.config.watches),this.workflowReflector=new Ao(e.workflowRepo,e.activityRepo,e.logger.child({component:"workflow-reflector"}),e.config.workflows),this.reminderReflector=new Ro(t,e.memoryRepo,e.logger.child({component:"reminder-reflector"}),e.config.reminders),this.conversationReflector=new No(e.llm,e.activityRepo,e.memoryRepo,t,e.logger.child({component:"conversation-reflector"}),e.config.conversation),this.docReflector=new rd(e.cmdbRepo,e.logger.child({component:"doc-reflector"}),e.config.docs),e.projectRepo&&e.ownerUserId&&(this.openItemsReflector=new lf({projectRepo:e.projectRepo,memoryRepo:e.memoryRepo,adapters:e.adapters,defaultPlatform:e.defaultPlatform,defaultChatId:e.defaultChatId,ownerUserId:e.ownerUserId,logger:e.logger.child({component:"open-items-reflector"}),confirmationQueue:e.confirmationQueue,resolveAgent:e.resolveAgent})),this.actionExecutor=new $o(e.watchRepo,e.workflowRepo,t,e.adapters,e.defaultChatId,e.defaultPlatform,e.logger.child({component:"action-executor"}))}start(){if(!this.config.enabled){this.logger.info("Reflection engine disabled");return}this.logger.info({schedule:this.config.schedule},"Reflection engine started"),this.timer=setInterval(()=>{this.tick().catch(e=>this.logger.error({err:e},"Reflection tick error"))},60*6e4)}stop(){this.timer&&(clearInterval(this.timer),this.timer=void 0,this.logger.info("Reflection engine stopped"))}async tick(){let e=new Date,t=e.toISOString().slice(0,10);if(this.openItemsReflector&&this.lastOpenItemsHour!==e.getHours()){this.lastOpenItemsHour=e.getHours();try{await this.openItemsReflector.hourlySweep()}catch(f){this.logger.warn({err:f},"open-items hourly sweep failed")}if(e.getHours()===9)try{await this.openItemsReflector.dailyDigest()}catch(f){this.logger.warn({err:f},"open-items daily digest failed")}}let s=this.config.schedule.match(/^\d+\s+(\d+)/),n=s?parseInt(s[1],10):4;if(e.getHours()!==n||this.lastRunDay===t)return;if(this.lastRunDay=t,this.dbAdapter&&this.dbAdapter.type==="postgres"){let f=`reflection:${t}`;if((await this.dbAdapter.execute("INSERT INTO reasoning_slots (slot_key, node_id, claimed_at) VALUES (?, ?, ?) ON CONFLICT DO NOTHING",[f,this.nodeId,e.toISOString()])).changes===0){this.logger.debug("Reflection slot already claimed by another node");return}}this.logger.info("Reflection cycle starting");let i=Date.now(),r="master",a=await Promise.allSettled([this.watchReflector.reflect(r),this.workflowReflector.reflect(r),this.reminderReflector.reflect(r),this.conversationReflector.reflect(r),this.docReflector.reflect(r)]),o=[],c=["watch","workflow","reminder","conversation","docs"];for(let f=0;f<a.length;f++){let g=a[f];g.status==="fulfilled"?o.push(...g.value):this.logger.warn({err:g.reason,reflector:c[f]},"Reflector failed")}o.length>0&&await this.actionExecutor.execute(o);let d=Date.now()-i,u=o.filter(f=>f.risk==="auto").length,h=o.filter(f=>f.risk==="proactive").length,p=o.filter(f=>f.risk==="confirm").length;this.logger.info({total:o.length,auto:u,proactive:h,confirm:p,durationMs:d},"Reflection cycle complete")}}});var FR={};Le(FR,{RefusalCorrectionReflector:()=>df});var UR,xB,df,E_=A(()=>{"use strict";UR=[/\b(kann ich nicht|kann ich leider nicht|nicht möglich|geht nicht|funktioniert nicht|nicht implementiert|keine möglichkeit|habe keine möglichkeit)\b/i,/\b(i can'?t|i cannot|not possible|not implemented|no way to)\b/i],xB=[/\b(doch|geht doch|hast du schon|hast du in der vergangenheit|musst du|du kannst|funktioniert doch|war doch|ist doch|aber du)\b/i,/\b(yes you can|you did|you have done|you should|works)\b/i],df=class{static{m(this,"RefusalCorrectionReflector")}conversationRepo;recipeRepo;logger;windowMinutes;maxStepsToSuccess;lookbackHours;seen=new Set;constructor(e,t,s,n){this.conversationRepo=e,this.recipeRepo=t,this.logger=s,this.windowMinutes=n?.windowMinutes??30,this.maxStepsToSuccess=n?.maxStepsToSuccess??6,this.lookbackHours=n?.lookbackHours??24}async scanForUser(e){let t=[];try{let s=await this.conversationRepo.listConversations({userId:e,limit:20});for(let n of s){let i=await this.conversationRepo.getMessages(n.id,100),r=this.detectInMessages(n.id,e,i);for(let a of r){let o=`${a.refusalMessageId}:${a.correctionMessageId}:${a.successMessageId}`;this.seen.has(o)||(this.seen.add(o),await this.recipeRepo.create({userId:e,triggerPhrase:a.triggerPhrase,triggerKeywords:a.triggerKeywords,actionSequence:a.actionSequence,contextHint:a.contextHint,source:"refusal_correction",confidence:.5}),t.push(a),this.logger.info({userId:e,conversationId:n.id,trigger:a.triggerPhrase.slice(0,60),steps:a.actionSequence.length},"v722 refusal-correction pattern \u2192 learned recipe persisted"))}}}catch(s){this.logger.warn({err:s,userId:e},"v722 refusal-correction scan failed")}return t}detectInMessages(e,t,s){let n=[],i=new Date(Date.now()-this.lookbackHours*36e5).toISOString(),r=s.filter(a=>a.createdAt>=i);for(let a=0;a<r.length;a++){let o=r[a];if(o.role!=="assistant"||!UR.some(f=>f.test(o.content)))continue;let c;for(let f=a-1;f>=0;f--)if(r[f].role==="user"){c=r[f];break}if(!c)continue;let d=-1;for(let f=a+1;f<Math.min(a+1+this.maxStepsToSuccess,r.length);f++){let g=r[f];if(g.role==="user"){if(this.spanMinutes(o.createdAt,g.createdAt)>this.windowMinutes)break;if(xB.some(y=>y.test(g.content))){d=f;break}}}if(d<0)continue;let u;for(let f=d+1;f<Math.min(d+1+this.maxStepsToSuccess,r.length);f++){let g=r[f];if(g.role==="assistant"&&!UR.some(y=>y.test(g.content))&&g.toolCalls){u=g;break}}if(!u?.toolCalls)continue;let h=this.extractActions(u.toolCalls);if(h.length===0)continue;let p=c.content.slice(0,200);n.push({conversationId:e,userId:t,triggerPhrase:p,triggerKeywords:this.tokenize(p),actionSequence:h,contextHint:this.extractContextHint(u.content),refusalMessageId:o.id,correctionMessageId:r[d].id,successMessageId:u.id,detectedAt:new Date().toISOString()})}return n}spanMinutes(e,t){return Math.abs(new Date(t).getTime()-new Date(e).getTime())/6e4}tokenize(e){let s=e.toLowerCase().match(/[a-zäöüß0-9_]+/g)??[],n=new Set(["der","die","das","ein","eine","und","oder","aber","mit","ohne","f\xFCr","von","auf","bitte","kannst","k\xF6nntest","starte","spiel","spiele"]),i=new Set;for(let r of s)r.length<4||n.has(r)||i.add(r);return Array.from(i).slice(0,8)}extractActions(e){try{let t=JSON.parse(e);if(!Array.isArray(t))return[];let s=[];for(let n of t){let i=n.skill??n.skillName??n.name;if(typeof i!="string")continue;let r=n.args??n.params??n.parameters??{};s.push({skill:i,action:typeof r.action=="string"?r.action:void 0,params:r})}return s}catch{return[]}}extractContextHint(e){let t=e.match(/(?:memory|gemerkt|gespeichert)[^\n.]{0,80}/i);if(t)return t[0].slice(0,120)}}});function uf(l){return{enabled:l?.enabled??!0,schedule:l?.schedule??"0 4 * * *",watches:{staleAfterDays:l?.watches?.staleAfterDays??14,deleteAfterDays:l?.watches?.deleteAfterDays??30,maxTriggersPerDay:l?.watches?.maxTriggersPerDay??10,ignoredAlertsBeforePause:l?.watches?.ignoredAlertsBeforePause??5,failedActionsBeforeDisable:l?.watches?.failedActionsBeforeDisable??3},workflows:{staleAfterDays:l?.workflows?.staleAfterDays??30,failedStepsBeforeSuggest:l?.workflows?.failedStepsBeforeSuggest??3},reminders:{repeatPatternDays:l?.reminders?.repeatPatternDays??7,quickDismissSeconds:l?.reminders?.quickDismissSeconds??30},conversation:{repeatQueryThreshold:l?.conversation?.repeatQueryThreshold??3,repeatSequenceThreshold:l?.conversation?.repeatSequenceThreshold??3,analysisWindowDays:l?.conversation?.analysisWindowDays??7},docs:{configSnapshotIntervalDays:l?.docs?.configSnapshotIntervalDays??30,staleDocWarningDays:l?.docs?.staleDocWarningDays??90,runbookValidation:l?.docs?.runbookValidation??!0},autonomy:{adjustParams:l?.autonomy?.adjustParams??"auto",deleteWatch:l?.autonomy?.deleteWatch??"proactive",createAutomation:l?.autonomy?.createAutomation??"confirm",deactivate:l?.autonomy?.deactivate??"proactive"}}}var jR=A(()=>{"use strict";m(uf,"resolveReflectionConfig")});var k_=A(()=>{"use strict";f_();m_();g_();y_();w_();__();E_();jR()});var BR={};Le(BR,{ProviderPuls:()=>od});var od,b_=A(()=>{"use strict";od=class l{static{m(this,"ProviderPuls")}logger;persistenz;now;tiers=new Map;schreibTimer;dirty=new Set;constructor(e,t,s=()=>new Date){this.logger=e,this.persistenz=t,this.now=s}async lade(){if(this.persistenz)try{for(let e of await this.persistenz.ladeAlle()){let t=this.tiers.get(e.tier);if(!t){this.tiers.set(e.tier,e);continue}t.erfolge+=e.erfolge,t.fehler+=e.fehler,e.letzterErfolg&&(!t.letzterErfolg||e.letzterErfolg>t.letzterErfolg)&&(t.letzterErfolg=e.letzterErfolg),e.letzterFehler&&(!t.letzterFehler||e.letzterFehler>t.letzterFehler)&&(t.letzterFehler=e.letzterFehler);let s=!t.letzterErfolg||e.gestoertSeit!==void 0&&t.letzterErfolg<e.gestoertSeit;l.istGestoert(t)&&e.gestoertSeit&&s&&(t.gestoertSeit=e.gestoertSeit),this.markiere(e.tier)}}catch(e){this.logger.warn({err:e.message},"Lebenszeichen: Provider-Puls konnte nicht geladen werden")}}verarbeite(e){let t=this.now().toISOString(),s=this.tiers.get(e.tier)??{tier:e.tier,provider:e.provider,model:e.model,erfolge:0,fehler:0,updatedAt:t};return s.provider=e.provider,s.model=e.model,s.updatedAt=t,e.art==="erfolg"?(s.letzterErfolg=t,s.erfolge++,s.gestoertSeit=void 0,s.fehlerKlasse=void 0,s.fehlerText=void 0):(s.letzterFehler=t,s.fehler++,s.fehlerKlasse=e.klasse??"unbekannt",s.fehlerText=e.fehler,s.gestoertSeit||(s.gestoertSeit=t)),this.tiers.set(e.tier,s),this.markiere(e.tier),s}zustand(e){return this.tiers.get(e)}alle(){return[...this.tiers.values()].sort((e,t)=>e.tier.localeCompare(t.tier))}static istGestoert(e){return e.letzterFehler?e.letzterErfolg?e.letzterFehler>e.letzterErfolg:!0:!1}markiere(e){this.persistenz&&(this.dirty.add(e),!this.schreibTimer&&(this.schreibTimer=setTimeout(()=>{this.schreibe()},3e4),this.schreibTimer.unref?.()))}async schreibe(){if(this.schreibTimer&&(clearTimeout(this.schreibTimer),this.schreibTimer=void 0),!this.persistenz)return;let e=[...this.dirty];this.dirty.clear();for(let t of e){let s=this.tiers.get(t);s&&await this.persistenz.speichere(s).catch(n=>this.logger.debug({err:n.message,tier:t},"Lebenszeichen: Puls-Schreiben fehlgeschlagen"))}}}});var HR,zR=A(()=>{"use strict";HR={name:"alfred.memory.recall",description:"Search Alfred's persisted memories (user preferences, project context, learned facts). Returns top-matching memories by keyword or semantic similarity. Read-only.",inputSchema:{type:"object",properties:{query:{type:"string",description:'Search query (natural language or keywords). Example: "alpbyte-games stack" or "deploy server preferences".'},limit:{type:"number",description:"Maximum number of results (default 10, max 50).",default:10},type:{type:"string",description:'Optional: filter by memory type (e.g. "user", "feedback", "project", "reference"). Omit to search all.'}},required:["query"]},async handler(l,e){let t=String(l.query??"").trim();if(!t)return{matches:[],note:"empty query \u2014 provide search terms"};let s=Math.max(1,Math.min(50,Number(l.limit??10))),n=typeof l.type=="string"?l.type:void 0,i=e.masterUserId,r=[`%${t}%`,`%${t}%`],a=`SELECT key, value, type, last_used_at FROM memories
7187
7187
  WHERE (key LIKE ? OR value LIKE ?)`;i&&(a+=" AND user_id = ?",r.push(i)),n&&(a+=" AND type = ?",r.push(n)),a+=" ORDER BY last_used_at DESC NULLS LAST LIMIT ?",r.push(s);let o=await e.adapter.query(a,r);return{matches:o.map(c=>({key:c.key,value:String(c.value??"").slice(0,2e3),type:c.type,lastUsedAt:c.last_used_at??null})),total:o.length}}}});var XR,WR=A(()=>{"use strict";XR={name:"alfred.kg.query",description:"Query Alfred's knowledge graph for entities (people, orgs, projects, concepts) and their relations. Returns matching entities + their direct neighbors. Read-only.",inputSchema:{type:"object",properties:{entity:{type:"string",description:'Entity name to look up (case-insensitive partial match). Example: "alpbyte", "madh".'},relation:{type:"string",description:'Optional: filter neighbors by relation type (e.g. "works_at", "uses_tech", "depends_on").'},limit:{type:"number",description:"Maximum number of neighbor relations per entity (default 20, max 100).",default:20}},required:["entity"]},async handler(l,e){let t=String(l.entity??"").trim();if(!t)return{entities:[]};let s=typeof l.relation=="string"?l.relation:void 0,n=Math.max(1,Math.min(100,Number(l.limit??20))),i=e.masterUserId,r=[`%${t.toLowerCase()}%`],a="SELECT id, name, type, attributes_json FROM kg_entities WHERE LOWER(name) LIKE ?";i&&(a+=" AND user_id = ?",r.push(i)),a+=" LIMIT 5";let o=await e.adapter.query(a,r);if(o.length===0)return{entities:[],note:"no matching entity"};let c=[];for(let d of o){let u=[d.id,d.id],h=`SELECT r.relation, e2.name AS target_name, e2.type AS target_type
7188
7188
  FROM kg_relations r
7189
7189
  JOIN kg_entities e2 ON e2.id = (CASE WHEN r.from_entity_id = ? THEN r.to_entity_id ELSE r.from_entity_id END)
@@ -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.1162",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,
@@ -8306,7 +8306,7 @@ Confidence-Skala:
8306
8306
  - 0.5-0.7: m\xF6glicherweise hilfreich, aber L\xF6sung nicht eindeutig
8307
8307
  - < 0.5: keine konkrete Erkenntnis/L\xF6sung erkennbar \u2192 is_runbook_candidate: false
8308
8308
 
8309
- Wenn is_runbook_candidate false ist, alle anderen Felder d\xFCrfen leer sein.`,c={};try{let y=(await this.llm.complete({messages:[{role:"user",content:o}],maxTokens:1500,temperature:.2,tier:"default"})).content.trim().match(/\{[\s\S]*\}/);y&&(c=JSON.parse(y[0]))}catch(f){this.logger.debug({err:f,conversationId:e},"Runbook-reflector LLM call failed"),await this.markProcessed(t,n);return}let d=typeof c.confidence=="number"?c.confidence:0,u=c.is_runbook_candidate===!0,h=!!c.title&&Array.isArray(c.steps)&&c.steps.length>=2;if(!u||!h||d<l.DRAFT_THRESHOLD){await this.markProcessed(t,n);return}if(await this.runbookRepo.findBySource(t,"chat_session",e)){await this.markProcessed(t,n);return}try{let f=new Set((c.tags??[]).map(y=>y.toLowerCase())),g=sO(c.title??"");if(g.size>=2||f.size>=2){let w=(await this.runbookRepo.list(t,{limit:200})).find(_=>{if([...f].filter(v=>_.tags.map(N=>N.toLowerCase()).includes(v)).length>=3)return!0;let T=sO(_.title);if(g.size===0||T.size===0)return!1;let k=[...g].filter(v=>T.has(v)).length,b=Math.min(g.size,T.size);return b>0&&k/b>=.6});if(w){this.logger.info({conversationId:e,newTitle:c.title?.slice(0,60),existingId:w.id.slice(0,8),existingTitle:w.title.slice(0,60)},"Runbook-reflector R2: similar runbook already exists \u2014 skipping"),await this.markProcessed(t,n);return}}}catch(f){this.logger.debug({err:f},"Runbook-reflector R2: similarity-dedup failed (non-critical, falling through)")}if(d>=l.CONFIRM_THRESHOLD)await this.confirmationQueue.enqueue({chatId:this.ownerChatId,platform:this.ownerPlatform,source:"reasoning",sourceId:`runbook-from-chat-${e.slice(0,8)}`,description:`Runbook aus Chat-Session erstellen (Confidence ${(d*100).toFixed(0)}%): "${c.title?.slice(0,80)}"?`,skillName:"runbook",skillParams:{action:"create",title:c.title,symptom:c.symptom??"",cause:c.cause??"",steps:c.steps,verification:c.verification??"",rollback:c.rollback??"",source_type:"chat_session",source_id:e,status:"draft",tags:[...c.tags??[],"auto-extracted","high-confidence"]},timeoutMinutes:1440}),this.logger.info({conversationId:e,title:c.title,confidence:d},"Chat-session runbook enqueued for confirmation");else try{await this.runbookRepo.create(t,{title:c.title,symptom:c.symptom,cause:c.cause,steps:c.steps,verification:c.verification,rollback:c.rollback,sourceType:"chat_session",sourceId:e,confidence:d,status:"draft",tags:[...c.tags??[],"auto-extracted","low-confidence"]}),this.logger.info({conversationId:e,title:c.title,confidence:d},"Chat-session runbook auto-saved as draft")}catch(f){this.logger.debug({err:f},"Auto-draft runbook creation failed")}await this.markProcessed(t,n)}async markProcessed(e,t){try{await this.memoryRepo.saveWithMetadata(e,t,new Date().toISOString(),"system","general",1,"auto");let s=new Date(Date.now()+l.MARKER_TTL_MS).toISOString();await this.memoryRepo.setExpiry(e,t,s)}catch{}}}});var rO={};Le(rO,{SkillFailureReflector:()=>SE});var SE,aO=A(()=>{"use strict";SE=class{static{m(this,"SkillFailureReflector")}activityRepo;logger;windowMinutes;minConsecutiveFails;maxWorkaroundSteps;constructor(e,t,s){this.activityRepo=e,this.logger=t,this.windowMinutes=s?.windowMinutes??30,this.minConsecutiveFails=s?.minConsecutiveFails??2,this.maxWorkaroundSteps=s?.maxWorkaroundSteps??10}async detect(e){let t=this.windowMinutes*60*1e3,s=new Date(Date.now()-t).toISOString(),n;try{n=(await this.activityRepo.query({eventType:"skill_exec",userId:e,since:s,limit:200})).map(o=>({id:o.id,skillName:o.action??"",success:o.outcome==="success",error:o.errorMessage,input:o.details,createdAt:o.timestamp}))}catch{return[]}if(n.length===0)return[];n.sort((a,o)=>a.createdAt.localeCompare(o.createdAt));let i=[],r=0;for(;r<n.length;){let a=n[r];if(a.success){r++;continue}let o=this.classifyError(a.error??""),c=1,d=r+1;for(;d<n.length&&!n[d].success&&n[d].skillName===a.skillName&&this.classifyError(n[d].error??"")===o;)c++,d++;if(c<this.minConsecutiveFails){r=d;continue}let u=Math.min(n.length,d+8),h=[],p=n.slice(r,d).map(g=>g.id),f=!1;for(let g=d;g<u;g++){let y=n[g];if(y.skillName==="shell"||y.skillName==="code_agent"||y.skillName==="deploy"){let w=typeof y.input?.command=="string"?y.input.command:JSON.stringify(y.input).slice(0,200);if(h.push(w),p.push(y.id),y.success&&(f=!0),h.length>=this.maxWorkaroundSteps)break}}if(h.length>0&&f){let g=this.extractScope(a.input);i.push({failedSkill:a.skillName,errorClass:o,scope:g,workaroundSteps:h,finalSuccess:f,detectedAt:new Date().toISOString(),participatingActivityIds:p}),this.logger.info({failedSkill:a.skillName,errorClass:o,scope:g,workaroundSteps:h.length},"SkillFailureReflector: workaround pattern detected")}r=u>d?u:d}return i}classifyError(e){let t=e.toLowerCase();return/command not found/.test(t)?"COMMAND_NOT_FOUND":/eacces|permission denied/.test(t)?"EACCES":/enoent|no such file/.test(t)?"ENOENT":/etimedout|timeout/.test(t)?"TIMEOUT":/ehostunreach|enetunreach|econnrefused/.test(t)?"NETWORK":/auth|unauthorized|forbidden/.test(t)?"AUTH_FAIL":/not found|404/.test(t)?"NOT_FOUND":"OTHER"}extractScope(e){if(e){if(typeof e.host=="string")return`host=${e.host}`;if(typeof e.target_host=="string")return`host=${e.target_host}`;if(typeof e.cwd=="string")return`cwd=${e.cwd}`}}}});import Ho from"node:fs";import vE from"node:os";import xt from"node:path";import{randomUUID as oO}from"node:crypto";import Z2 from"js-yaml";async function Q2(l,e,t,s,n){let i=t.toLowerCase(),r=s.map(c=>c.toLowerCase()).filter(c=>c.length>=4),a=m(c=>r.filter(d=>c.includes(d)||i.split(/\s+/).some(u=>c.includes(u.toLowerCase())&&u.length>=4)).length,"matchScore"),o=await l.listProblems(e,{isKnownError:!0,limit:50});for(let c of o)if(!(!c.workaround&&!c.knownErrorDescription)&&a(c.title.toLowerCase())>=2)return{...c,sourceKind:"problem"};if(n)try{let c=await n.listIncidents(e,{limit:300}),d=null;for(let u of c){if(u.status!=="closed"&&u.status!=="resolved"||!u.resolution||u.resolution.trim().length<20)continue;let h=a(`${u.title} ${u.rootCause??""}`.toLowerCase());h>=2&&(!d||h>d.score)&&(d={inc:u,score:h})}if(d)return{id:d.inc.id,title:d.inc.title,workaround:d.inc.resolution,knownErrorDescription:d.inc.rootCause,sourceKind:"incident"}}catch{}return null}function eX(l){let e=new Date(Date.UTC(l.getFullYear(),l.getMonth(),l.getDate()));e.setUTCDate(e.getUTCDate()+4-(e.getUTCDay()||7));let t=new Date(Date.UTC(e.getUTCFullYear(),0,1));return Math.ceil(((e.getTime()-t.getTime())/864e5+1)/7)}var Cr,cO=A(()=>{"use strict";zd();lt();an();Fu();ba();We();dw();XA();KA();Tw();Ew();kw();bw();Sw();vw();Iw();Aw();Rw();Nw();$w();Cw();SR();Vp();Pw();Uw();Fw();Qw();OR();e_();vr();qp();t_();s_();n_();i_();r_();c_();l_();d_();u_();h_();p_();vl();El();T_();k_();m(Q2,"findKnownErrorMatch");m(eX,"getISOWeek");Cr=class{static{m(this,"Alfred")}config;logger;database;pipeline;llmProvider;reminderScheduler;backgroundTaskRunner;proactiveScheduler;watchEngine;triggerManager;confirmationQueue;adapters=new Map;formatter=new Ll;userRepo;skillRegistry;skillSandbox;mcpManager;calendarSkill;calendarWatcher;todoWatcher;reasoningEngine;reflectionEngine;chatSessionRunbookReflector;usageRepo;serviceUsageRepo;auditRepo;summaryRepo;activityRepo;memoryRepo;runbookRepo;projectRepo;agentConventionsRepo;agentConventionsSkillRef;buildConventionsEmbeddingLookup(e,t){if(!e||!t||!this.embeddingServiceRef||!this.embeddingRepoRef||!this.agentConventionsRepo||!this.config.agentConventions?.embeddingInjection)return;let n=this.agentConventionsRepo,i=this.llmProvider;return async(r,a)=>{try{if(!i||!i.supportsEmbeddings?.())return[];let c=(await n.listForProject(e).catch(()=>[])).flatMap(f=>f.neutralFormat.lessons.map(g=>({...g,packagePath:f.packagePath})));if(c.length===0)return[];let d=await i.embed(r.slice(0,800));if(!d)return[];let u=d.embedding,h=[];for(let f of c.slice(0,50)){let g=await i.embed(f.text.slice(0,800)).catch(()=>null);g&&h.push({lesson:f,emb:g.embedding})}let p=m((f,g)=>{let y=0,w=0,_=0;for(let T=0;T<f.length;T++)y+=f[T]*g[T],w+=f[T]*f[T],_+=g[T]*g[T];let E=Math.sqrt(w)*Math.sqrt(_);return E===0?0:y/E},"cosine");return h.map(({lesson:f,emb:g})=>({text:f.text,source:`lesson:${f.source}:conf=${f.confidence.toFixed(2)}`,similarity:p(u,g)})).filter(f=>f.similarity>.55).sort((f,g)=>g.similarity-f.similarity).slice(0,5)}catch(o){return this.logger.debug({err:o,projectId:e},"v830 conventions-embedding-lookup failed (non-fatal)"),[]}}}embeddingServiceRef;embeddingRepoRef;learnedRecipeRepo;envRepoRef;envCryptoRef;dbSeedRepoRef;envSkillFactory;conversationRepo;insightsRepo;notificationRouter;insightEngine;legacyDataUids=[];projectManager;projectHealthMonitor;projectSkillRef;projectAgentSkillRef;codeAgentTaskAborts=new Map;async gitInWorktree(e,t,s={}){let{execFile:n}=await import("node:child_process"),{promisify:i}=await import("node:util"),r=await import("node:fs"),a=await import("node:path"),o=i(n),c=s.timeout??3e4,d=s.maxBuffer??1024*1024;if(!(typeof process.getuid=="function"&&process.getuid()===0))return o("git",t,{cwd:e,timeout:c,maxBuffer:d});let h=0;try{let p=a.join(e,".git"),f=r.statSync(p);if(f.isFile()){let g=r.readFileSync(p,"utf8").trim(),y=/^gitdir:\s*(.+)$/.exec(g);if(y){let w=y[1].trim(),_=a.isAbsolute(w)?w:a.resolve(e,w);h=r.statSync(_).uid}else h=f.uid}else h=f.uid}catch{try{h=r.statSync(e).uid}catch{}}if(h===0)return o("git",t,{cwd:e,timeout:c,maxBuffer:d});try{let{stdout:p}=await o("id",["-nu",String(h)],{timeout:3e3}),f=p.trim();if(!f)throw new Error(`uid ${h} resolves to empty name`);return o("sudo",["-u",f,"git",...t],{cwd:e,timeout:c,maxBuffer:d})}catch(p){return this.logger.warn({err:p,cwd:e,effectiveUid:h},"v796 gitInWorktree sudo-wrap setup failed, falling back to direct git (may hit dubious-ownership)"),o("git",t,{cwd:e,timeout:c,maxBuffer:d})}}agentSessionManager;projectAgentRunnerRef;commitsRepoRef;cliRunsRepoRef;agentBusyRegistry=new Kp;projectSessionRepoRef;plansRepoRef;featuresRepoRef;delegateSkillRef;codeAgentSkillRef;mcpTokenStoreRef;watchRepo;scheduledActionRepo;skillHealthRepo;clusterManager;adapterClaimManager;webAuthCallback;reminderRepo;todoRepo;noteRepo;attachmentRepo;documentRepoRef;fileStoreRef;projectAutomationsRepo;automationEngine;shareManager;projectMoveService;spotifySkill;bmwSkill;bmwTelematicRepo;memorySkillRef;kgServiceRef;sonosSkill;skillHealthTracker;healthCheckTimer;jobRegister;providerPuls;degradationsWaechter;lebenszeichenRepo;letzteProben={ergebnisse:[]};temporalAnalyzerTimer;socialRepo;socialSkillRef;publishingEngine;contentStudio;contentStudioTimer;speechSynthesizerRef;interestsRepo;interestsSkillRef;topicCollector;sourceProvisioner;interestDetector;topicDigestBuilder;sourceMaintenance;interestsDailyTimer;async sendeAnOwner(e){let t=this.config.security?.ownerUserId;if(!t)return!1;let s=this.config.telegram?.enabled?"telegram":this.config.matrix?.enabled?"matrix":this.config.discord?.enabled?"discord":void 0,n=s?this.adapters.get(s):void 0;if(!n)return!1;try{return await n.sendMessage(t,e),!0}catch(i){return this.logger.warn({err:i.message},"Lebenszeichen: Owner-Satz konnte nicht gesendet werden"),!1}}async lebenszeichenStatus(){let{JobRunsRepository:e}=await Promise.resolve().then(()=>(lt(),ht)),t=new e(this.database.getAdapter()),s=[];for(let n of this.jobRegister?.definitionen()??[]){let i=await t.letzterLauf(n.key).catch(()=>{});s.push({...n,letzterLauf:i??null})}return{registerGestartetAm:this.jobRegister?.gestartetAm??null,jobs:s,puls:this.providerPuls?.alle()??[],proben:this.letzteProben,offen:this.degradationsWaechter?.offeneZustaende()??[],letzteLaeufe:await t.listeLetzte(60).catch(()=>[])}}async claimDailySlot(e){if(this.database?.getAdapter().type!=="postgres")return!0;try{return((await this.database.getAdapter().execute("INSERT INTO reasoning_slots (slot_key, node_id, claimed_at) VALUES (?, ?, ?) ON CONFLICT DO NOTHING",[e,this.config.cluster?.nodeId??"single",new Date().toISOString()])).changes??0)>0}catch{return!0}}insightExpiryTimer;clusterMonitorTimer;cmdbDiscoveryTimer;cmdbHealthCheckTimer;agentConventionsDriftTimer;agentConventionsPatternMiningTimer;agentConventionsSelfModifyTimer;insightTracker;sandboxManager;ownerMasterUserId;identityResolver;requireOwner(){if(!this.ownerMasterUserId)throw new Error("Alfred.requireOwner() called before init() completed. Check that this code path runs AFTER alfred.initialize() \u2014 see ADR-0001 (docs/adr/0001-user-identity-model.md) for the init-order requirement.");return this.ownerMasterUserId}tryOwner(){return this.ownerMasterUserId}async resolveCliAgent(e,t,s){let n=(this.config.codeAgents?.agents??[]).map(a=>a.name),i;if(e&&this.projectRepo)try{let a=this.tryOwner();a&&(i=(await this.projectRepo.getById(a,e))?.agentStrategy)}catch{}let r=new Set;for(let a of n)this.agentBusyRegistry.isBusy(a,e)&&r.add(a);try{if(this.projectSessionRepoRef){let a=await this.projectSessionRepoRef.listRunning();for(let o of a)o.agentName&&n.includes(o.agentName)&&r.add(o.agentName)}}catch{}return WA({available:n,strategy:i,requestedAgent:t,busy:r,isAutomatic:s?.isAutomatic,resumeAgent:s?.resumeAgent})}userServiceResolverRef;startedAt=new Date().toISOString();withLegacyForOwner(e,t){if(!this.ownerMasterUserId||e!==this.ownerMasterUserId||this.legacyDataUids.length===0)return t;let s=[...t];for(let n of this.legacyDataUids)s.includes(n)||s.push(n);return s}constructor(e){this.config=e,this.logger=Mr("alfred",e.logger.level)}async initialize(){this.logger.info("Initializing Alfred..."),this.database=await Ws.create({backend:this.config.storage.backend??"sqlite",path:this.config.storage.path,connectionString:this.config.storage.connectionString});let e=this.database.getAdapter();try{let{SandboxChatRepository:M,ProjectAgentSessionRepository:q}=await Promise.resolve().then(()=>(lt(),ht)),x=await new M(e).failOrphanedCodeAgentTasks();x>0&&this.logger.info({count:x},"v767 startup: marked orphaned chat-tasks as failed");let Z=await new q(e).failOrphanedSessions();Z>0&&this.logger.info({count:Z},"v768 startup: marked orphaned project-agent-sessions as failed")}catch(M){this.logger.warn({err:M},"v767/v768 startup orphan-cleanup failed (non-fatal)")}let t=new Pr(e);this.conversationRepo=t;let s=new Ur(e);this.userRepo=s;let n=new si(e);this.auditRepo=n;let i=new Fr(e);this.memoryRepo=i;let r=new ri(e),a=new jr(e);this.reminderRepo=a;let o=new Br(e);this.noteRepo=o;{let{bereinigeAttributeNachSchema:M}=await Promise.resolve().then(()=>(Wl(),NR));ks.setAttributSanitizer((q,O)=>M(q,O).bereinigt)}let c=new Gi(e),d=new Hr(e),u=new zr(e),h=new Kr(e);this.scheduledActionRepo=h;let p=new ii(e);this.activityRepo=p;let f=new Yl(p,this.logger.child({component:"activity"})),g=new Qr(e);this.skillHealthRepo=g;let y=new Zl(g,this.logger.child({component:"skill-health"}),f);this.skillHealthTracker=y,this.logger.info("Storage initialized");let w=new Ea,_=this.loadSecurityRules();w.loadRules(_);let E;try{let{AuditLogger:M}=await Promise.resolve().then(()=>(zd(),_k)),q=this.config.logger.auditLogPath??"./data/logs/audit.log";E=new M(q),this.logger.info({path:q},"File-based audit logger initialized")}catch(M){this.logger.warn({err:M},"File-based audit logger init failed \u2014 DB-audit still active")}let T=new ka(w,n,this.logger.child({component:"security"}),E);this.logger.info({ruleCount:_.length},"Security engine initialized");let k=Pu(this.config.llm,this.logger.child({component:"llm"}));await k.initialize(),this.llmProvider=k;let b=new Zr(e);this.usageRepo=b,k.setPersist((M,q,O,x,D,Z)=>{b.record(M,q,O,x,D,Z).catch(()=>{})});{let{ProviderPuls:M}=await Promise.resolve().then(()=>(b_(),BR)),{LebenszeichenRepository:q}=await Promise.resolve().then(()=>(lt(),ht));this.lebenszeichenRepo=new q(e);let O=this.lebenszeichenRepo;this.providerPuls=new M(this.logger.child({component:"lebenszeichen"}),{speichere:m(D=>O.speicherePuls(D),"speichere"),ladeAlle:m(()=>O.ladePuls(),"ladeAlle")}),await this.providerPuls.lade();let x=this.providerPuls;k.setPulsCallback(D=>{x.verarbeite(D)})}k.setBillingAlertCallback(M=>{this.logger.warn({...M},M.kind==="recovered"?"v868.3 LLM billing recovered":"v868 LLM billing failure (Owner-Satz kommt vom Lebenszeichen-W\xE4chter)")});let v=new na(e);this.serviceUsageRepo=v;let N=new Ol(k,c,this.logger.child({component:"embeddings"}));this.embeddingServiceRef=N,this.embeddingRepoRef=c;let I=this.config.llm.embeddings?.model??this.config.llm.default?.model??"unknown";if(k.supportsEmbeddings())try{await N.validateModelConsistency(I)>0&&setTimeout(async()=>{try{let q=await s.listAll(),O=0;for(let x of q){let D=await i.listAll(x.id);for(let Z of D)await N.embedAndStore(x.id,`${Z.key}: ${Z.value}`,"memory",Z.id),O++}this.logger.info({count:O,model:I},"Re-embedded all memories with new model")}catch(q){this.logger.error({err:q},"Background re-embedding failed")}},5e3)}catch(M){this.logger.error({err:M},"Embedding model consistency check failed")}let C=this.config.activeLearning?.enabled!==!1,L,B;C&&(L=new Hl({llm:k,memoryRepo:i,logger:this.logger.child({component:"active-learning"}),embeddingService:N,minMessageLength:this.config.activeLearning?.minMessageLength,minConfidence:this.config.activeLearning?.minConfidence,maxExtractionsPerMinute:this.config.activeLearning?.maxExtractionsPerMinute}),B=new zl(i,this.logger.child({component:"memory-retriever"}),N),this.logger.info("Active learning & memory retriever initialized"));let j=new Yr(e);this.summaryRepo=j;let P=new Vl(k,j,this.logger.child({component:"summarizer"}));this.logger.info("Conversation summarizer initialized");let $=this.skillSandbox=new Na(this.logger.child({component:"sandbox"})),R=this.skillRegistry=new Ra;R.register(new $a),R.register(new Ca),R.register(new La(this.config.search?{provider:this.config.search.provider,apiKey:this.config.search.apiKey,baseUrl:this.config.search.baseUrl}:void 0)),R.register(new Oa(a));let H=new Da(o);R.register(H);let F=new Vr(e);this.todoRepo=F;let U=new eo(F);R.register(U),R.register(new xa),R.register(new Ma);let Ee=new Pa(i,N);R.register(Ee),this.memorySkillRef=Ee;let Me=new Ua(k,R,$,T);R.register(Me),this.delegateSkillRef=Me;{let{ChatHistorySkill:M}=await Promise.resolve().then(()=>(We(),Ze));R.register(new M(t))}{let{BrainstormingSkill:M}=await Promise.resolve().then(()=>(We(),Ze)),{BrainstormingRepository:q}=await Promise.resolve().then(()=>(lt(),ht)),O=new q(e),x=new M(O);x.setKgContextFn(async(D,Z)=>{if(!this.kgServiceRef)return"";let ce=this.ownerMasterUserId??D,le=await new ks(e).getFullGraph(ce,"personal"),Q=Z.toLowerCase(),ze=le.entities.filter(se=>se.name.toLowerCase().includes(Q)||se.normalizedName.includes(Q)||se.attributes?.value&&String(se.attributes.value).toLowerCase().includes(Q)),re=new Set(ze.map(se=>se.id)),Ae=le.relations.filter(se=>re.has(se.sourceEntityId)||re.has(se.targetEntityId)),ue=new Set;for(let se of Ae)ue.add(se.sourceEntityId),ue.add(se.targetEntityId);let je=le.entities.filter(se=>re.has(se.id)||ue.has(se.id)),Y=je.slice(0,20).map(se=>{let he=Object.entries(se.attributes??{}).filter(([Fe])=>!["skillName","type","memoryKey","memoryConfidence"].includes(Fe)).map(([Fe,He])=>`${Fe}=${String(He).slice(0,60)}`).join(", ");return`- [${se.entityType}] ${se.name}${he?` (${he})`:""}`}),K=Ae.slice(0,15).map(se=>{let he=je.find(He=>He.id===se.sourceEntityId)?.name??"?",Fe=je.find(He=>He.id===se.targetEntityId)?.name??"?";return`- ${he} \u2192 ${se.relationType} \u2192 ${Fe}`}),z="";try{z=(await i.search(ce,Z)).slice(0,5).map(he=>`- [memory] ${he.key}: ${he.value.slice(0,100)}`).join(`
8309
+ Wenn is_runbook_candidate false ist, alle anderen Felder d\xFCrfen leer sein.`,c={};try{let y=(await this.llm.complete({messages:[{role:"user",content:o}],maxTokens:1500,temperature:.2,tier:"default"})).content.trim().match(/\{[\s\S]*\}/);y&&(c=JSON.parse(y[0]))}catch(f){this.logger.debug({err:f,conversationId:e},"Runbook-reflector LLM call failed"),await this.markProcessed(t,n);return}let d=typeof c.confidence=="number"?c.confidence:0,u=c.is_runbook_candidate===!0,h=!!c.title&&Array.isArray(c.steps)&&c.steps.length>=2;if(!u||!h||d<l.DRAFT_THRESHOLD){await this.markProcessed(t,n);return}if(await this.runbookRepo.findBySource(t,"chat_session",e)){await this.markProcessed(t,n);return}try{let f=new Set((c.tags??[]).map(y=>y.toLowerCase())),g=sO(c.title??"");if(g.size>=2||f.size>=2){let w=(await this.runbookRepo.list(t,{limit:200})).find(_=>{if([...f].filter(v=>_.tags.map(N=>N.toLowerCase()).includes(v)).length>=3)return!0;let T=sO(_.title);if(g.size===0||T.size===0)return!1;let k=[...g].filter(v=>T.has(v)).length,b=Math.min(g.size,T.size);return b>0&&k/b>=.6});if(w){this.logger.info({conversationId:e,newTitle:c.title?.slice(0,60),existingId:w.id.slice(0,8),existingTitle:w.title.slice(0,60)},"Runbook-reflector R2: similar runbook already exists \u2014 skipping"),await this.markProcessed(t,n);return}}}catch(f){this.logger.debug({err:f},"Runbook-reflector R2: similarity-dedup failed (non-critical, falling through)")}if(d>=l.CONFIRM_THRESHOLD)await this.confirmationQueue.enqueue({chatId:this.ownerChatId,platform:this.ownerPlatform,source:"reasoning",sourceId:`runbook-from-chat-${e.slice(0,8)}`,description:`Runbook aus Chat-Session erstellen (Confidence ${(d*100).toFixed(0)}%): "${c.title?.slice(0,80)}"?`,skillName:"runbook",skillParams:{action:"create",title:c.title,symptom:c.symptom??"",cause:c.cause??"",steps:c.steps,verification:c.verification??"",rollback:c.rollback??"",source_type:"chat_session",source_id:e,status:"draft",tags:[...c.tags??[],"auto-extracted","high-confidence"]},timeoutMinutes:1440}),this.logger.info({conversationId:e,title:c.title,confidence:d},"Chat-session runbook enqueued for confirmation");else try{await this.runbookRepo.create(t,{title:c.title,symptom:c.symptom,cause:c.cause,steps:c.steps,verification:c.verification,rollback:c.rollback,sourceType:"chat_session",sourceId:e,confidence:d,status:"draft",tags:[...c.tags??[],"auto-extracted","low-confidence"]}),this.logger.info({conversationId:e,title:c.title,confidence:d},"Chat-session runbook auto-saved as draft")}catch(f){this.logger.debug({err:f},"Auto-draft runbook creation failed")}await this.markProcessed(t,n)}async markProcessed(e,t){try{await this.memoryRepo.saveWithMetadata(e,t,new Date().toISOString(),"system","general",1,"auto");let s=new Date(Date.now()+l.MARKER_TTL_MS).toISOString();await this.memoryRepo.setExpiry(e,t,s)}catch{}}}});var rO={};Le(rO,{SkillFailureReflector:()=>SE});var SE,aO=A(()=>{"use strict";SE=class{static{m(this,"SkillFailureReflector")}activityRepo;logger;windowMinutes;minConsecutiveFails;maxWorkaroundSteps;constructor(e,t,s){this.activityRepo=e,this.logger=t,this.windowMinutes=s?.windowMinutes??30,this.minConsecutiveFails=s?.minConsecutiveFails??2,this.maxWorkaroundSteps=s?.maxWorkaroundSteps??10}async detect(e){let t=this.windowMinutes*60*1e3,s=new Date(Date.now()-t).toISOString(),n;try{n=(await this.activityRepo.query({eventType:"skill_exec",userId:e,since:s,limit:200})).map(o=>({id:o.id,skillName:o.action??"",success:o.outcome==="success",error:o.errorMessage,input:o.details,createdAt:o.timestamp}))}catch{return[]}if(n.length===0)return[];n.sort((a,o)=>a.createdAt.localeCompare(o.createdAt));let i=[],r=0;for(;r<n.length;){let a=n[r];if(a.success){r++;continue}let o=this.classifyError(a.error??""),c=1,d=r+1;for(;d<n.length&&!n[d].success&&n[d].skillName===a.skillName&&this.classifyError(n[d].error??"")===o;)c++,d++;if(c<this.minConsecutiveFails){r=d;continue}let u=Math.min(n.length,d+8),h=[],p=n.slice(r,d).map(g=>g.id),f=!1;for(let g=d;g<u;g++){let y=n[g];if(y.skillName==="shell"||y.skillName==="code_agent"||y.skillName==="deploy"){let w=typeof y.input?.command=="string"?y.input.command:JSON.stringify(y.input).slice(0,200);if(h.push(w),p.push(y.id),y.success&&(f=!0),h.length>=this.maxWorkaroundSteps)break}}if(h.length>0&&f){let g=this.extractScope(a.input);i.push({failedSkill:a.skillName,errorClass:o,scope:g,workaroundSteps:h,finalSuccess:f,detectedAt:new Date().toISOString(),participatingActivityIds:p}),this.logger.info({failedSkill:a.skillName,errorClass:o,scope:g,workaroundSteps:h.length},"SkillFailureReflector: workaround pattern detected")}r=u>d?u:d}return i}classifyError(e){let t=e.toLowerCase();return/command not found/.test(t)?"COMMAND_NOT_FOUND":/eacces|permission denied/.test(t)?"EACCES":/enoent|no such file/.test(t)?"ENOENT":/etimedout|timeout/.test(t)?"TIMEOUT":/ehostunreach|enetunreach|econnrefused/.test(t)?"NETWORK":/auth|unauthorized|forbidden/.test(t)?"AUTH_FAIL":/not found|404/.test(t)?"NOT_FOUND":"OTHER"}extractScope(e){if(e){if(typeof e.host=="string")return`host=${e.host}`;if(typeof e.target_host=="string")return`host=${e.target_host}`;if(typeof e.cwd=="string")return`cwd=${e.cwd}`}}}});import Ho from"node:fs";import vE from"node:os";import xt from"node:path";import{randomUUID as oO}from"node:crypto";import Z2 from"js-yaml";async function Q2(l,e,t,s,n){let i=t.toLowerCase(),r=s.map(c=>c.toLowerCase()).filter(c=>c.length>=4),a=m(c=>r.filter(d=>c.includes(d)||i.split(/\s+/).some(u=>c.includes(u.toLowerCase())&&u.length>=4)).length,"matchScore"),o=await l.listProblems(e,{isKnownError:!0,limit:50});for(let c of o)if(!(!c.workaround&&!c.knownErrorDescription)&&a(c.title.toLowerCase())>=2)return{...c,sourceKind:"problem"};if(n)try{let c=await n.listIncidents(e,{limit:300}),d=null;for(let u of c){if(u.status!=="closed"&&u.status!=="resolved"||!u.resolution||u.resolution.trim().length<20)continue;let h=a(`${u.title} ${u.rootCause??""}`.toLowerCase());h>=2&&(!d||h>d.score)&&(d={inc:u,score:h})}if(d)return{id:d.inc.id,title:d.inc.title,workaround:d.inc.resolution,knownErrorDescription:d.inc.rootCause,sourceKind:"incident"}}catch{}return null}function eX(l){let e=new Date(Date.UTC(l.getFullYear(),l.getMonth(),l.getDate()));e.setUTCDate(e.getUTCDate()+4-(e.getUTCDay()||7));let t=new Date(Date.UTC(e.getUTCFullYear(),0,1));return Math.ceil(((e.getTime()-t.getTime())/864e5+1)/7)}var Cr,cO=A(()=>{"use strict";zd();lt();an();Fu();ba();We();dw();XA();KA();Tw();Ew();kw();bw();Sw();vw();Iw();Aw();Rw();Nw();$w();Cw();SR();Vp();Pw();Uw();Fw();Qw();OR();e_();vr();qp();t_();s_();n_();i_();r_();c_();l_();d_();u_();h_();p_();vl();El();T_();k_();m(Q2,"findKnownErrorMatch");m(eX,"getISOWeek");Cr=class{static{m(this,"Alfred")}config;logger;database;pipeline;llmProvider;reminderScheduler;backgroundTaskRunner;proactiveScheduler;watchEngine;triggerManager;confirmationQueue;adapters=new Map;formatter=new Ll;userRepo;skillRegistry;skillSandbox;mcpManager;calendarSkill;calendarWatcher;todoWatcher;reasoningEngine;reflectionEngine;chatSessionRunbookReflector;usageRepo;serviceUsageRepo;auditRepo;summaryRepo;activityRepo;memoryRepo;runbookRepo;projectRepo;agentConventionsRepo;agentConventionsSkillRef;buildConventionsEmbeddingLookup(e,t){if(!e||!t||!this.embeddingServiceRef||!this.embeddingRepoRef||!this.agentConventionsRepo||!this.config.agentConventions?.embeddingInjection)return;let n=this.agentConventionsRepo,i=this.llmProvider;return async(r,a)=>{try{if(!i||!i.supportsEmbeddings?.())return[];let c=(await n.listForProject(e).catch(()=>[])).flatMap(f=>f.neutralFormat.lessons.map(g=>({...g,packagePath:f.packagePath})));if(c.length===0)return[];let d=await i.embed(r.slice(0,800));if(!d)return[];let u=d.embedding,h=[];for(let f of c.slice(0,50)){let g=await i.embed(f.text.slice(0,800)).catch(()=>null);g&&h.push({lesson:f,emb:g.embedding})}let p=m((f,g)=>{let y=0,w=0,_=0;for(let T=0;T<f.length;T++)y+=f[T]*g[T],w+=f[T]*f[T],_+=g[T]*g[T];let E=Math.sqrt(w)*Math.sqrt(_);return E===0?0:y/E},"cosine");return h.map(({lesson:f,emb:g})=>({text:f.text,source:`lesson:${f.source}:conf=${f.confidence.toFixed(2)}`,similarity:p(u,g)})).filter(f=>f.similarity>.55).sort((f,g)=>g.similarity-f.similarity).slice(0,5)}catch(o){return this.logger.debug({err:o,projectId:e},"v830 conventions-embedding-lookup failed (non-fatal)"),[]}}}embeddingServiceRef;embeddingRepoRef;learnedRecipeRepo;envRepoRef;envCryptoRef;dbSeedRepoRef;envSkillFactory;conversationRepo;insightsRepo;notificationRouter;insightEngine;legacyDataUids=[];projectManager;projectHealthMonitor;projectSkillRef;projectAgentSkillRef;codeAgentTaskAborts=new Map;async gitInWorktree(e,t,s={}){let{execFile:n}=await import("node:child_process"),{promisify:i}=await import("node:util"),r=await import("node:fs"),a=await import("node:path"),o=i(n),c=s.timeout??3e4,d=s.maxBuffer??1024*1024;if(!(typeof process.getuid=="function"&&process.getuid()===0))return o("git",t,{cwd:e,timeout:c,maxBuffer:d});let h=0;try{let p=a.join(e,".git"),f=r.statSync(p);if(f.isFile()){let g=r.readFileSync(p,"utf8").trim(),y=/^gitdir:\s*(.+)$/.exec(g);if(y){let w=y[1].trim(),_=a.isAbsolute(w)?w:a.resolve(e,w);h=r.statSync(_).uid}else h=f.uid}else h=f.uid}catch{try{h=r.statSync(e).uid}catch{}}if(h===0)return o("git",t,{cwd:e,timeout:c,maxBuffer:d});try{let{stdout:p}=await o("id",["-nu",String(h)],{timeout:3e3}),f=p.trim();if(!f)throw new Error(`uid ${h} resolves to empty name`);return o("sudo",["-u",f,"git",...t],{cwd:e,timeout:c,maxBuffer:d})}catch(p){return this.logger.warn({err:p,cwd:e,effectiveUid:h},"v796 gitInWorktree sudo-wrap setup failed, falling back to direct git (may hit dubious-ownership)"),o("git",t,{cwd:e,timeout:c,maxBuffer:d})}}agentSessionManager;projectAgentRunnerRef;commitsRepoRef;cliRunsRepoRef;agentBusyRegistry=new Kp;projectSessionRepoRef;plansRepoRef;featuresRepoRef;delegateSkillRef;codeAgentSkillRef;mcpTokenStoreRef;watchRepo;scheduledActionRepo;skillHealthRepo;clusterManager;adapterClaimManager;webAuthCallback;reminderRepo;todoRepo;noteRepo;attachmentRepo;documentRepoRef;fileStoreRef;projectAutomationsRepo;automationEngine;shareManager;projectMoveService;spotifySkill;bmwSkill;bmwTelematicRepo;memorySkillRef;kgServiceRef;sonosSkill;skillHealthTracker;healthCheckTimer;jobRegister;providerPuls;degradationsWaechter;lebenszeichenRepo;letzteProben={ergebnisse:[]};temporalAnalyzerTimer;socialRepo;socialSkillRef;publishingEngine;contentStudio;contentStudioTimer;speechSynthesizerRef;interestsRepo;interestsSkillRef;topicCollector;sourceProvisioner;interestDetector;topicDigestBuilder;sourceMaintenance;interestsDailyTimer;async sendeAnOwner(e){let t=this.config.security?.ownerUserId;if(!t)return!1;let s=this.config.telegram?.enabled?"telegram":this.config.matrix?.enabled?"matrix":this.config.discord?.enabled?"discord":void 0,n=s?this.adapters.get(s):void 0;if(!n)return!1;try{return await n.sendMessage(t,e),!0}catch(i){return this.logger.warn({err:i.message},"Lebenszeichen: Owner-Satz konnte nicht gesendet werden"),!1}}async lebenszeichenStatus(){let{JobRunsRepository:e}=await Promise.resolve().then(()=>(lt(),ht)),t=new e(this.database.getAdapter()),s=[];for(let n of this.jobRegister?.definitionen()??[]){let i=await t.letzterLauf(n.key).catch(()=>{});s.push({...n,letzterLauf:i??null})}return{registerGestartetAm:this.jobRegister?.gestartetAm??null,jobs:s,puls:this.providerPuls?.alle()??[],proben:this.letzteProben,offen:this.degradationsWaechter?.offeneZustaende()??[],letzteLaeufe:await t.listeLetzte(60).catch(()=>[])}}async claimDailySlot(e){if(this.database?.getAdapter().type!=="postgres")return!0;try{return((await this.database.getAdapter().execute("INSERT INTO reasoning_slots (slot_key, node_id, claimed_at) VALUES (?, ?, ?) ON CONFLICT DO NOTHING",[e,this.config.cluster?.nodeId??"single",new Date().toISOString()])).changes??0)>0}catch{return!0}}insightExpiryTimer;clusterMonitorTimer;cmdbDiscoveryTimer;cmdbHealthCheckTimer;agentConventionsDriftTimer;agentConventionsPatternMiningTimer;agentConventionsSelfModifyTimer;insightTracker;sandboxManager;ownerMasterUserId;identityResolver;requireOwner(){if(!this.ownerMasterUserId)throw new Error("Alfred.requireOwner() called before init() completed. Check that this code path runs AFTER alfred.initialize() \u2014 see ADR-0001 (docs/adr/0001-user-identity-model.md) for the init-order requirement.");return this.ownerMasterUserId}tryOwner(){return this.ownerMasterUserId}async resolveCliAgent(e,t,s){let n=(this.config.codeAgents?.agents??[]).map(a=>a.name),i;if(e&&this.projectRepo)try{let a=this.tryOwner();a&&(i=(await this.projectRepo.getById(a,e))?.agentStrategy)}catch{}let r=new Set;for(let a of n)this.agentBusyRegistry.isBusy(a,e)&&r.add(a);try{if(this.projectSessionRepoRef){let a=await this.projectSessionRepoRef.listRunning();for(let o of a)o.agentName&&n.includes(o.agentName)&&r.add(o.agentName)}}catch{}return WA({available:n,strategy:i,requestedAgent:t,busy:r,isAutomatic:s?.isAutomatic,resumeAgent:s?.resumeAgent})}userServiceResolverRef;startedAt=new Date().toISOString();withLegacyForOwner(e,t){if(!this.ownerMasterUserId||e!==this.ownerMasterUserId||this.legacyDataUids.length===0)return t;let s=[...t];for(let n of this.legacyDataUids)s.includes(n)||s.push(n);return s}constructor(e){this.config=e,this.logger=Mr("alfred",e.logger.level)}async initialize(){this.logger.info("Initializing Alfred..."),this.database=await Ws.create({backend:this.config.storage.backend??"sqlite",path:this.config.storage.path,connectionString:this.config.storage.connectionString});let e=this.database.getAdapter();try{let{SandboxChatRepository:M,ProjectAgentSessionRepository:q}=await Promise.resolve().then(()=>(lt(),ht)),x=await new M(e).failOrphanedCodeAgentTasks();x>0&&this.logger.info({count:x},"v767 startup: marked orphaned chat-tasks as failed");let Z=await new q(e).failOrphanedSessions();Z>0&&this.logger.info({count:Z},"v768 startup: marked orphaned project-agent-sessions as failed")}catch(M){this.logger.warn({err:M},"v767/v768 startup orphan-cleanup failed (non-fatal)")}let t=new Pr(e);this.conversationRepo=t;let s=new Ur(e);this.userRepo=s;let n=new si(e);this.auditRepo=n;let i=new Fr(e);this.memoryRepo=i;let r=new ri(e),a=new jr(e);this.reminderRepo=a;let o=new Br(e);this.noteRepo=o;{let{bereinigeAttributeNachSchema:M}=await Promise.resolve().then(()=>(Wl(),NR));ks.setAttributSanitizer((q,O)=>M(q,O).bereinigt)}let c=new Gi(e),d=new Hr(e),u=new zr(e),h=new Kr(e);this.scheduledActionRepo=h;let p=new ii(e);this.activityRepo=p;let f=new Yl(p,this.logger.child({component:"activity"})),g=new Qr(e);this.skillHealthRepo=g;let y=new Zl(g,this.logger.child({component:"skill-health"}),f);this.skillHealthTracker=y,this.logger.info("Storage initialized");let w=new Ea,_=this.loadSecurityRules();w.loadRules(_);let E;try{let{AuditLogger:M}=await Promise.resolve().then(()=>(zd(),_k)),q=this.config.logger.auditLogPath??"./data/logs/audit.log";E=new M(q),this.logger.info({path:q},"File-based audit logger initialized")}catch(M){this.logger.warn({err:M},"File-based audit logger init failed \u2014 DB-audit still active")}let T=new ka(w,n,this.logger.child({component:"security"}),E);this.logger.info({ruleCount:_.length},"Security engine initialized");let k=Pu(this.config.llm,this.logger.child({component:"llm"}));await k.initialize(),this.llmProvider=k;let b=new Zr(e);this.usageRepo=b,k.setPersist((M,q,O,x,D,Z)=>{b.record(M,q,O,x,D,Z).catch(()=>{})});{let{ProviderPuls:M}=await Promise.resolve().then(()=>(b_(),BR)),{LebenszeichenRepository:q}=await Promise.resolve().then(()=>(lt(),ht));this.lebenszeichenRepo=new q(e);let O=this.lebenszeichenRepo;this.providerPuls=new M(this.logger.child({component:"lebenszeichen"}),{speichere:m(D=>O.speicherePuls(D),"speichere"),ladeAlle:m(()=>O.ladePuls(),"ladeAlle")});let x=this.providerPuls;k.setPulsCallback(D=>{x.verarbeite(D)})}k.setBillingAlertCallback(M=>{this.logger.warn({...M},M.kind==="recovered"?"v868.3 LLM billing recovered":"v868 LLM billing failure (Owner-Satz kommt vom Lebenszeichen-W\xE4chter)")});let v=new na(e);this.serviceUsageRepo=v;let N=new Ol(k,c,this.logger.child({component:"embeddings"}));this.embeddingServiceRef=N,this.embeddingRepoRef=c;let I=this.config.llm.embeddings?.model??this.config.llm.default?.model??"unknown";if(k.supportsEmbeddings())try{await N.validateModelConsistency(I)>0&&setTimeout(async()=>{try{let q=await s.listAll(),O=0;for(let x of q){let D=await i.listAll(x.id);for(let Z of D)await N.embedAndStore(x.id,`${Z.key}: ${Z.value}`,"memory",Z.id),O++}this.logger.info({count:O,model:I},"Re-embedded all memories with new model")}catch(q){this.logger.error({err:q},"Background re-embedding failed")}},5e3)}catch(M){this.logger.error({err:M},"Embedding model consistency check failed")}let C=this.config.activeLearning?.enabled!==!1,L,B;C&&(L=new Hl({llm:k,memoryRepo:i,logger:this.logger.child({component:"active-learning"}),embeddingService:N,minMessageLength:this.config.activeLearning?.minMessageLength,minConfidence:this.config.activeLearning?.minConfidence,maxExtractionsPerMinute:this.config.activeLearning?.maxExtractionsPerMinute}),B=new zl(i,this.logger.child({component:"memory-retriever"}),N),this.logger.info("Active learning & memory retriever initialized"));let j=new Yr(e);this.summaryRepo=j;let P=new Vl(k,j,this.logger.child({component:"summarizer"}));this.logger.info("Conversation summarizer initialized");let $=this.skillSandbox=new Na(this.logger.child({component:"sandbox"})),R=this.skillRegistry=new Ra;R.register(new $a),R.register(new Ca),R.register(new La(this.config.search?{provider:this.config.search.provider,apiKey:this.config.search.apiKey,baseUrl:this.config.search.baseUrl}:void 0)),R.register(new Oa(a));let H=new Da(o);R.register(H);let F=new Vr(e);this.todoRepo=F;let U=new eo(F);R.register(U),R.register(new xa),R.register(new Ma);let Ee=new Pa(i,N);R.register(Ee),this.memorySkillRef=Ee;let Me=new Ua(k,R,$,T);R.register(Me),this.delegateSkillRef=Me;{let{ChatHistorySkill:M}=await Promise.resolve().then(()=>(We(),Ze));R.register(new M(t))}{let{BrainstormingSkill:M}=await Promise.resolve().then(()=>(We(),Ze)),{BrainstormingRepository:q}=await Promise.resolve().then(()=>(lt(),ht)),O=new q(e),x=new M(O);x.setKgContextFn(async(D,Z)=>{if(!this.kgServiceRef)return"";let ce=this.ownerMasterUserId??D,le=await new ks(e).getFullGraph(ce,"personal"),Q=Z.toLowerCase(),ze=le.entities.filter(se=>se.name.toLowerCase().includes(Q)||se.normalizedName.includes(Q)||se.attributes?.value&&String(se.attributes.value).toLowerCase().includes(Q)),re=new Set(ze.map(se=>se.id)),Ae=le.relations.filter(se=>re.has(se.sourceEntityId)||re.has(se.targetEntityId)),ue=new Set;for(let se of Ae)ue.add(se.sourceEntityId),ue.add(se.targetEntityId);let je=le.entities.filter(se=>re.has(se.id)||ue.has(se.id)),Y=je.slice(0,20).map(se=>{let he=Object.entries(se.attributes??{}).filter(([Fe])=>!["skillName","type","memoryKey","memoryConfidence"].includes(Fe)).map(([Fe,He])=>`${Fe}=${String(He).slice(0,60)}`).join(", ");return`- [${se.entityType}] ${se.name}${he?` (${he})`:""}`}),K=Ae.slice(0,15).map(se=>{let he=je.find(He=>He.id===se.sourceEntityId)?.name??"?",Fe=je.find(He=>He.id===se.targetEntityId)?.name??"?";return`- ${he} \u2192 ${se.relationType} \u2192 ${Fe}`}),z="";try{z=(await i.search(ce,Z)).slice(0,5).map(he=>`- [memory] ${he.key}: ${he.value.slice(0,100)}`).join(`
8310
8310
  `)}catch{}return`Entities:
8311
8311
  ${Y.join(`
8312
8312
  `)}
@@ -8643,7 +8643,7 @@ A clean, idiomatic scaffold matching the stack. After this, "npm run dev" (or eq
8643
8643
 
8644
8644
  `)}catch{}w=E.size})}catch{}});return()=>{_.close()}},"streamAppLog")})}if(e&&"setClusterCallbacks"in e){let t=this.database?.getAdapter(),s=this.config.cluster?.nodeId??"single",n=this.config.cluster?.enabled===!0,i=this.config.reasoning?.schedule??"hourly",r=this.startedAt;e.setClusterCallbacks({getHealth:m(async()=>{let a=[],o=[],c=[];if(t){try{let u=await t.query("SELECT * FROM node_heartbeats ORDER BY last_seen_at DESC",[]),h=Date.now();for(let p of u){let f={};try{f=JSON.parse(p.metrics??"{}")}catch{}a.push({nodeId:p.node_id,host:p.host??"",lastSeenAt:p.last_seen_at,startedAt:p.started_at,uptimeS:p.uptime_s??0,adapters:JSON.parse(p.adapters??"[]"),version:p.version??"",alive:h-new Date(p.last_seen_at).getTime()<6e4,metrics:f})}}catch{}try{let u=await t.query("SELECT * FROM adapter_claims ORDER BY platform",[]),h=new Date().toISOString();for(let p of u)o.push({platform:p.platform,nodeId:p.node_id,claimedAt:p.claimed_at,expiresAt:p.expires_at,active:p.expires_at>h})}catch{}try{let u=await t.query("SELECT * FROM reasoning_slots ORDER BY claimed_at DESC LIMIT 20",[]);for(let h of u)c.push({slotKey:h.slot_key,nodeId:h.node_id,claimedAt:h.claimed_at})}catch{}}if(!n&&a.length===0){let u=Math.floor((Date.now()-new Date(r).getTime())/1e3),h=[...this.adapters?.keys()??[]],{collectNodeMetrics:p}=await Promise.resolve().then(()=>(Hf(),uC)),f=await Promise.resolve().then(()=>(jf(),Ff)).catch(()=>({default:{version:""}})),g=["/",this.config.storage?.path,this.config.fileStore?.basePath].filter(_=>typeof _=="string"&&_.length>0),y=await p(g).catch(()=>{}),{hostname:w}=await import("node:os");a.push({nodeId:s,host:w(),lastSeenAt:new Date().toISOString(),startedAt:r,uptimeS:u,adapters:h,version:f.default.version??"",alive:!0,metrics:y})}let d={};try{if(t?.type==="postgres"){let u=await t.query("SELECT pg_database_size(current_database()) AS size",[]);d.database={type:"postgres",ok:!0,sizeMb:Math.round(Number(u[0]?.size??0)/1024/1024)}}else if(t&&this.config.storage?.path){let{stat:u}=await import("node:fs/promises"),h=await u(this.config.storage.path).catch(()=>null);d.database={type:"sqlite",ok:!0,sizeMb:h?Math.round(h.size/1024/1024):void 0}}}catch(u){d.database={type:t?.type??"unknown",ok:!1,error:u.message.slice(0,200)}}if(n&&(d.redis={ok:await this.clusterManager?.pingRedis().catch(()=>!1)??!1}),this.fileStoreRef){let u=await this.fileStoreRef.healthCheck().catch(h=>({ok:!1,error:h.message.slice(0,200)}));d.fileStore={backend:this.config.fileStore?.backend??"local",...u}}return{clusterEnabled:n,thisNodeId:s,nodes:a,claims:o,recentReasoningSlots:c,infra:d,operations:{reasoning:{schedule:i},backup:this.config.backup?.schedule?{schedule:this.config.backup.schedule}:void 0}}},"getHealth")})}if(e&&"setLebenszeichenCallback"in e&&e.setLebenszeichenCallback(()=>this.lebenszeichenStatus()),e&&"setCliUsageCallback"in e&&e.setCliUsageCallback(async t=>{if(!this.cliRunsRepoRef)return null;try{let s=await this.cliRunsRepoRef.overview(t);try{let n=await this.database.getAdapter().query("SELECT id, COALESCE(display_name, username, id) AS label FROM users",[]),i=new Map(n.map(r=>[r.id,r.label]));for(let r of s.byUser){let a=i.get(r.key);a&&a!==r.key&&(r.subKey=r.key,r.key=a)}}catch{}return s}catch(s){return this.logger.warn({err:s},"v866 cli-usage overview failed"),null}}),this.projectRepo)try{let t=await this.projectRepo.listImplementingMarkers(),s=0;for(let n of t)try{let i=await this.database.getAdapter().queryOne("SELECT current_phase FROM project_agent_sessions WHERE task_id = ?",[n.taskId]).catch(()=>null);if(i?.current_phase&&!["done","failed"].includes(i.current_phase))continue;s+=await this.projectRepo.revertItemsForSession(n.taskId)}catch{}s>0&&this.logger.warn({reverted:s,markers:t.length},"v871.1 Startup: verwaiste in_progress-Items (implementing:-Marker) auf open zur\xFCckgesetzt")}catch(t){this.logger.debug({err:t},"v871.1 implementing-marker cleanup skipped")}try{let t={audit:await this.auditRepo?.cleanup(90)??0,summaries:await this.summaryRepo?.cleanup(180)??0,activity:await this.activityRepo?.cleanup(90)??0,usage:await this.usageRepo?.cleanup(365)??0,usageHourly:await this.usageRepo?.cleanupHourly(62)??0,expiredMemories:await this.memoryRepo?.cleanupExpired()??0,processedMessages:this.config.cluster?.enabled?await new(await Promise.resolve().then(()=>(lt(),ht))).ProcessedMessageRepository(this.database.getAdapter()).cleanup():0};(t.audit||t.summaries||t.activity||t.usage||t.usageHourly)&&this.logger.info(t,"Startup DB cleanup completed")}catch(t){this.logger.warn({err:t},"Startup DB cleanup failed")}if(this.skillHealthTracker&&(this.healthCheckTimer=setInterval(()=>this.skillHealthTracker.checkReEnables(),5*6e4)),this.config.activeLearning?.enabled!==!1&&this.memoryRepo){let t=new Kl(this.llmProvider,this.memoryRepo,this.logger.child({component:"memory-consolidator"}));if(this.database){let{EmbeddingRepository:a}=await Promise.resolve().then(()=>(lt(),ht)),o=new a(this.database.getAdapter());t.setEmbeddingRepo(o)}let s=this.userRepo;try{let a=Intl.DateTimeFormat().resolvedOptions().timeZone,o=await s.listMasters();for(let c of o){let d=await t.migrateLegacyMemoriesV582(c.id,a);(d.resolved>0||d.relevantUntilSet>0||d.refsSet>0||d.resolvedExpirySet>0)&&this.logger.info({userId:c.id,...d},"Legacy memory migration v582 applied")}}catch(a){this.logger.warn({err:a},"Legacy memory migration v582 startup hook failed")}let{JobRegister:n}=await Promise.resolve().then(()=>(qL(),VL)),{JobRunsRepository:i}=await Promise.resolve().then(()=>(lt(),ht));this.jobRegister=new n({logger:this.logger.child({component:"lebenszeichen"}),nodeId:this.config.cluster?.nodeId??"single",listMasters:m(()=>s.listMasters(),"listMasters"),listAll:m(()=>s.listAll(),"listAll"),claimSlot:m(a=>this.claimDailySlot(a),"claimSlot"),runs:new i(this.database.getAdapter())});let r=this.jobRegister;if(r.registriere({key:"consolidation",beschreibung:"Memory-Konsolidierung",takt:{art:"taeglich",um:"03:00"},bereich:"master",slot:!0,run:m(async({userId:a})=>{let o=await t.consolidate(a);return(o.deleted>0||o.merged>0)&&this.logger.info({userId:a,...o},"Memory consolidation completed"),{ok:!0,zaehler:{deleted:o.deleted,merged:o.merged}}},"run")}),this.activityRepo){let a=new cf(this.llmProvider,this.memoryRepo,this.activityRepo,this.logger.child({component:"pattern-analyzer"}));r.registriere({key:"pattern-analysis",beschreibung:"Verhaltensmuster + Skill-Regeln",takt:{art:"taeglich",um:"03:30"},bereich:"master",slot:!0,run:m(async({userId:d})=>{let u=await a.analyze(d);return u>0&&this.logger.info({userId:d,patterns:u},"Pattern analysis completed"),{ok:!0,zaehler:{patterns:u}}},"run")});let o=new Gl(this.activityRepo,this.memoryRepo,this.logger.child({component:"temporal-analyzer"})),c="";this.temporalAnalyzerTimer=setInterval(async()=>{let d=new Date,u=`${d.getFullYear()}-W${String(eX(d)).padStart(2,"0")}`;if(!(d.getDay()!==0||d.getHours()!==4||c===u)){if(c=u,this.database.getAdapter().type==="postgres")try{let h=`maintenance:${u}`;if((await this.database.getAdapter().execute("INSERT INTO reasoning_slots (slot_key, node_id, claimed_at) VALUES (?, ?, ?) ON CONFLICT DO NOTHING",[h,this.config.cluster?.nodeId??"single",d.toISOString()])).changes===0){this.logger.debug("Weekly maintenance slot already claimed by another node");return}}catch{}try{let h=await s.listMasters(),p=this.reasoningEngine?new Sr(new ks(this.database.getAdapter()),this.logger.child({component:"knowledge-graph"}),this.memoryRepo):void 0;for(let f of h){let g=await o.analyze(f.id);if((g.trends.length>0||g.anomalies.length>0)&&this.logger.info({userId:f.id,trends:g.trends.length,anomalies:g.anomalies.length},"Temporal analysis completed"),this.activityRepo&&this.memoryRepo&&await new wr(this.activityRepo,this.memoryRepo,this.logger.child({component:"action-feedback"})).analyze(f.id),this.memoryRepo)try{let y=await this.memoryRepo.cleanupExpired();y>0&&this.logger.info({cleaned:y},"Expired memories cleaned up")}catch(y){this.logger.warn({err:y.message},"Memory cleanup failed")}if(this.bmwTelematicRepo){let y=await this.bmwTelematicRepo.prune(90);y>0&&this.logger.info({pruned:y},"BMW telematic history pruned")}if(p?.getLLMLinker())try{let w=await this.database.getAdapter().query(`SELECT role, content FROM messages WHERE conversation_id IN (
8645
8645
  SELECT id FROM conversations WHERE user_id = ?
8646
- ) ORDER BY created_at DESC LIMIT 100`,[f.id]);if(w.length>10){let _=await p.getLLMLinker().analyzeRecentChats(f.id,w.reverse());(_.relations>0||_.newEntities>0)&&this.logger.info({..._},"Weekly chat analysis completed")}}catch(y){this.logger.debug({err:y},"Weekly chat analysis failed")}}}catch(h){this.logger.warn({err:h},"Temporal analysis failed")}try{if(this.config.cmdb?.enabled!==!1&&this.database){let h=this.database.getAdapter(),{CmdbRepository:p,ItsmRepository:f}=await Promise.resolve().then(()=>(lt(),ht)),g=new p(h),y=new f(h),w=this.userRepo?await this.userRepo.findOrCreate("telegram",this.config.security?.ownerUserId??""):void 0,_=w?.masterUserId??w?.id??this.config.security?.ownerUserId??"";if(_){let E=await g.listAssets(_),T=E.filter(N=>["server","vm","lxc","container","application","service"].includes(N.assetType)&&N.status==="active"),k=await y.listServices(_),b=new Set;for(let N of k)for(let I of N.assetIds??[])b.add(I);let v=0;for(let N of T){if(b.has(N.id))continue;let I=["server","vm","lxc"].includes(N.assetType)?"infrastructure":N.assetType==="container"||N.assetType==="application"?"application":"infrastructure",C=N.environment==="production"?"high":"medium";try{await y.createService(_,{name:`${N.name} Service`,description:`Automatisch abgeleitet aus CMDB-Asset (${N.assetType}). ${N.purpose??""}`.trim(),category:I,environment:N.environment,criticality:C,assetIds:[N.id],tags:"auto-discovered"}),v++}catch{}}v>0&&this.logger.info({createdServices:v,totalAssets:E.length},"Weekly service-discovery completed")}}}catch(h){this.logger.warn({err:h},"Weekly service-discovery failed")}}},60*6e4),r.registriere({key:"kg-maintenance",beschreibung:"KG-Wartung + Entity-Embeddings + Stammdaten-Sync",takt:{art:"taeglich",um:"04:30"},bereich:"master",slot:!0,run:m(async({userId:d})=>{let u=new Sr(new ks(this.database.getAdapter()),this.logger.child({component:"knowledge-graph"}),this.memoryRepo);this.embeddingServiceRef&&u.setEmbeddingService(this.embeddingServiceRef,this.embeddingRepoRef),await u.maintenance(d);let h=0;if(this.memoryRepo){let{StammdatenSync:p}=await Promise.resolve().then(()=>(BT(),jT));h=(await new p(new ks(this.database.getAdapter()),this.memoryRepo,this.logger.child({component:"stammdaten-sync"})).run(d).catch(()=>{}))?.gesetzt??0}return{ok:!0,zaehler:{stammdatenGesetzt:h}}},"run")})}{let{DegradationsWaechter:a,bewertePuls:o,bewerteProben:c,formatiereMeldungen:d}=await Promise.resolve().then(()=>(tO(),eO)),{fuehreProbenAus:u}=await Promise.resolve().then(()=>(EE(),ZL)),h=this.lebenszeichenRepo;this.degradationsWaechter=new a({logger:this.logger.child({component:"lebenszeichen"}),persistenz:h?{ladeMeldungen:m(()=>h.ladeMeldungen(),"ladeMeldungen"),speichereMeldung:m(_=>h.speichereMeldung(_),"speichereMeldung"),loescheMeldung:m(_=>h.loescheMeldung(_),"loescheMeldung")}:void 0}),await this.degradationsWaechter.lade();let p=this.degradationsWaechter,f=this.providerPuls,g=new i(this.database.getAdapter()),y=this.jobRegister,w=m(async _=>{let E=new Date().toISOString().slice(0,10),T=[];for(let b of _)await this.claimDailySlot(`lz-${b.art}:${b.key}:${E}`)&&T.push(b);let k=d(T);return k?(await this.sendeAnOwner(k),this.logger.info({meldungen:T.map(b=>`${b.art}:${b.key}`)},"Lebenszeichen: Owner-Satz gesendet"),T.length):0},"melde");y.registriere({key:"degradations-waechter",beschreibung:"Provider-Puls bewerten (Degradation/Guthaben)",takt:{art:"intervall",minuten:10},bereich:"global",run:m(async()=>{if(!f)return{ok:!0};let _=o(f.alle(),new Date),E=await p.abgleich(_,{wiederholen:!1,nurBereiche:["tier"]}),T=await w(E);return{ok:!0,zaehler:{befunde:_.length,gesendet:T}}},"run")}),y.registriere({key:"lebenszeichen-proben",beschreibung:"Synthetische Proben: Tiers, Job-Takte, Daten-Frische",takt:{art:"taeglich",um:"06:50"},bereich:"global",slot:!0,run:m(async()=>{let _=await u({tiers:{konfigurierteTiers:m(()=>this.llmProvider.konfigurierteTiers(),"konfigurierteTiers"),probeTier:m(v=>this.llmProvider.probeTier(v),"probeTier")},embed:this.llmProvider.supportsEmbeddings()?()=>this.llmProvider.embed("OK"):void 0,jobs:m(()=>y.definitionen(),"jobs"),registerGestartetAm:y.gestartetAm,letzterLauf:m(async v=>{let N=await g.letzterLauf(v);return N?{startedAt:N.startedAt,ok:N.ok}:void 0},"letzterLauf"),juengsteZeit:h?v=>h.juengsteZeit(v):void 0,ausgenommen:["lebenszeichen-proben","degradations-waechter"]});this.letzteProben={zeit:new Date().toISOString(),ergebnisse:_};let E=[...f?o(f.alle(),new Date):[],...c(_)],T=await p.abgleich(E,{wiederholen:!0}),k=await w(T),b=_.filter(v=>!v.ok);return this.logger.info({proben:_.length,fehlgeschlagen:b.map(v=>`${v.art}:${v.name}`),befunde:E.length,gesendet:k},"Lebenszeichen: Proben gelaufen"),{ok:!0,zaehler:{proben:_.length,fehlgeschlagen:b.length,befunde:E.length,gesendet:k}}},"run")})}this.jobRegister.start()}if(this.config.reflection?.enabled!==!1&&this.watchRepo&&this.memoryRepo&&this.activityRepo&&this.skillRegistry&&this.skillSandbox)try{let t=uf(this.config.reflection),s=this.config.telegram?.enabled?"telegram":this.config.discord?.enabled?"discord":this.config.whatsapp?.enabled?"whatsapp":"api",n=this.database?.getAdapter(),i=this.config.cmdb?.enabled!==!1&&n?new ai(n):void 0,r=this.config.telegram?.enabled?this.config.security?.ownerUserId??"":"";this.reflectionEngine=new ad({watchRepo:this.watchRepo,memoryRepo:this.memoryRepo,activityRepo:this.activityRepo,cmdbRepo:i,projectRepo:this.projectRepo,runbookRepo:this.runbookRepo,ownerUserId:this.tryOwner(),confirmationQueue:this.confirmationQueue,resolveAgent:m(a=>this.resolveCliAgent(a,void 0),"resolveAgent"),skillRegistry:this.skillRegistry,skillSandbox:this.skillSandbox,llm:this.llmProvider,adapters:this.adapters,logger:this.logger.child({component:"reflection-engine"}),defaultChatId:r,defaultPlatform:s,nodeId:this.config.cluster?.nodeId??"single",config:t},this.database?.getAdapter()),this.reflectionEngine.start(),this.logger.info("Reflection engine initialized")}catch(t){this.logger.warn({err:t},"Reflection engine initialization failed")}if(this.runbookRepo&&this.memoryRepo&&this.confirmationQueue&&this.database&&this.llmProvider)try{let{ChatSessionRunbookReflector:t}=await Promise.resolve().then(()=>(iO(),nO)),{ConversationRepository:s}=await Promise.resolve().then(()=>(lt(),ht)),n=this.database.getAdapter(),i=new s(n),r=this.config.telegram?.enabled?"telegram":this.config.discord?.enabled?"discord":this.config.whatsapp?.enabled?"whatsapp":"api";this.chatSessionRunbookReflector=new t(n,i,this.runbookRepo,this.memoryRepo,this.confirmationQueue,this.llmProvider,this.logger.child({component:"runbook-reflector"}),r,this.config.security?.ownerUserId??""),this.chatSessionRunbookReflector.start(),this.logger.info("Chat-session runbook reflector started")}catch(t){this.logger.warn({err:t},"Chat-session runbook reflector init failed")}if(this.activityRepo&&this.confirmationQueue&&this.runbookRepo)try{let{SkillFailureReflector:t}=await Promise.resolve().then(()=>(aO(),rO)),s=new t(this.activityRepo,this.logger.child({component:"skill-failure-reflector"}));setInterval(async()=>{let n=this.tryOwner();if(!(!n||!this.confirmationQueue))try{let i=await s.detect(n);for(let r of i){let a=`skill-failure-runbook-${r.failedSkill}-${(r.scope??"").replace(/[^a-z0-9]/gi,"_").slice(0,30)}-${r.errorClass}`,o=`Skill "${r.failedSkill}" auf ${r.scope??"?"} \u2192 Workaround`,c=this.config.telegram?.enabled?"telegram":this.config.discord?.enabled?"discord":this.config.whatsapp?.enabled?"whatsapp":"api";if(await this.confirmationQueue.enqueue({chatId:this.config.security?.ownerUserId??"",platform:c,source:"reasoning",sourceId:a,description:`Runbook aus Skill-Failure-Workaround erstellen: "${o}"?`,skillName:"runbook",skillParams:{action:"create",title:o,symptom:`Skill "${r.failedSkill}" scheiterte ${r.errorClass} bei ${r.scope??"(unbekannter Scope)"}`,steps:r.workaroundSteps.map((d,u)=>`${u+1}. ${d}`),source_type:"chat_session",source_id:a,status:"draft",tags:["skill-failure","workaround","auto",r.failedSkill,r.errorClass.toLowerCase()]},timeoutMinutes:1440}),this.logger.info({skill:r.failedSkill,scope:r.scope,errorClass:r.errorClass},"SkillFailureReflector: runbook-confirmation enqueued"),r.workaroundSteps.length>=2&&r.scope?.startsWith("host=")){let d=`${r.failedSkill}-workaround-${r.errorClass.toLowerCase()}`.replace(/[^a-z0-9-]/gi,"-").replace(/-+/g,"-").slice(0,40),u=r.workaroundSteps.map(h=>({type:"action",skillName:"shell",inputMapping:{command:h},onError:"stop"}));await this.confirmationQueue.enqueue({chatId:this.config.security?.ownerUserId??"",platform:c,source:"reasoning",sourceId:`${a}-workflow`,description:`Workflow '${d}' aus Skill-Failure-Workaround speichern (${u.length} Schritte)?`,skillName:"workflow",skillParams:{action:"create",name:d,description:`Auto-extrahiert aus Workaround f\xFCr ${r.failedSkill}/${r.errorClass} auf ${r.scope}`,steps:u,triggerType:"manual",autoExtracted:!0},timeoutMinutes:1440}),this.logger.info({workflowName:d,steps:u.length},"SkillFailureReflector: workflow-confirmation enqueued (D4)")}}}catch(i){this.logger.debug({err:i},"SkillFailureReflector sweep failed (non-critical)")}},15*6e4),this.logger.info("Skill-failure reflector started (15min sweep interval)")}catch(t){this.logger.warn({err:t},"Skill-failure reflector init failed")}if(this.conversationRepo&&this.learnedRecipeRepo)try{let{RefusalCorrectionReflector:t}=await Promise.resolve().then(()=>(E_(),FR)),s=new t(this.conversationRepo,this.learnedRecipeRepo,this.logger.child({component:"refusal-correction-reflector"}));setInterval(async()=>{let n=this.tryOwner();if(n)try{let i=await s.scanForUser(n);i.length>0&&this.logger.info({count:i.length},"v722 refusal-correction patterns \u2192 recipes persisted")}catch(i){this.logger.debug({err:i},"v722 refusal-correction sweep failed (non-critical)")}},30*6e4),this.logger.info("v722 RefusalCorrectionReflector started (30min sweep interval)")}catch(t){this.logger.warn({err:t},"v722 RefusalCorrectionReflector init failed")}if(this.memoryRepo&&this.confirmationQueue&&this.learnedRecipeRepo&&setTimeout(async()=>{let t=this.tryOwner();if(!(!t||!this.confirmationQueue||!this.memoryRepo))try{let s=await this.learnedRecipeRepo.list(t,{includeInvalidated:!0,limit:500}),n=new Set(s.map(c=>c.triggerPhrase.toLowerCase().trim())),i=await this.memoryRepo.search(t,"wie"),r=/\b(merke dir|wenn der user|wenn ich sage|du sollst dann)\b/i,a=this.config.telegram?.enabled?"telegram":this.config.discord?.enabled?"discord":this.config.whatsapp?.enabled?"whatsapp":"api",o=0;for(let c of i.slice(0,20)){if(!r.test(c.value))continue;let d=(c.key+" "+c.value).toLowerCase().slice(0,200).trim();if(n.has(d))continue;let u=`audit-prose-rule-${c.key}`;if(await this.confirmationQueue.enqueue({chatId:this.config.security?.ownerUserId??"",platform:a,source:"reasoning",sourceId:u,description:`Audit (v722): Memory "${c.key}" sieht aus wie eine prosaische Regel \u2014 soll daraus ein strukturiertes Recipe werden? Inhalt: "${c.value.slice(0,120)}..."`,skillName:"memory",skillParams:{action:"learn_recipe",trigger_phrase:c.key.replace(/^(?:rule_|behavior_|auto_)/,"").replace(/_/g," "),action_sequence:"[]",context_hint:`Quelle: bestehende Memory "${c.key}". Original-Text: ${c.value.slice(0,200)}`},timeoutMinutes:10080}),o++,o>=5)break}o>0?this.logger.info({enqueued:o},"v722 auto-rules audit: enqueued recipe-creation confirmations"):this.logger.debug("v722 auto-rules audit: no prose rules found")}catch(s){this.logger.warn({err:s},"v722 auto-rules audit failed (non-fatal)")}},3e4),this.clusterManager&&(this.clusterMonitorTimer=setInterval(async()=>{try{let t=await this.clusterManager.getNodesAny();t.length>0&&this.logger.debug({liveNodes:t.map(s=>s.id)},"Cluster node status")}catch{}},6e4)),this.insightTracker&&this.ownerMasterUserId){let t=this.ownerMasterUserId;this.insightExpiryTimer=setInterval(()=>{this.insightTracker.processExpired(t).catch(s=>{this.logger.warn({err:s},"Insight expiry processing failed")})},30*6e4)}this.adapters.size===0&&this.logger.warn("No messaging adapters enabled. Configure at least one platform."),this.logger.info(`Alfred is running with ${this.adapters.size} adapter(s)`)}async startWithCLI(){this.adapters.clear();let{CLIAdapter:e}=await Promise.resolve().then(()=>(Zn(),Yn)),t=new e;this.adapters.set("cli",t),t.on("disconnected",()=>{this.stop().then(()=>process.exit(0))}),await this.start()}async stop(){this.logger.info("Stopping Alfred..."),this.bmwSkill&&"stopStreaming"in this.bmwSkill&&this.bmwSkill.stopStreaming(),this.reminderScheduler?.stop(),this.backgroundTaskRunner?.stop(),this.proactiveScheduler?.stop(),this.watchEngine?.stop(),this.triggerManager?.stop(),this.confirmationQueue?.stop(),this.calendarWatcher?.stop(),this.todoWatcher?.stop(),this.reasoningEngine?.stop(),this.projectHealthMonitor?.stop(),this.adapterClaimManager?.stop(),this.clusterManager?.stopPgHeartbeat(),this.healthCheckTimer&&(clearInterval(this.healthCheckTimer),this.healthCheckTimer=void 0),this.jobRegister?.stop(),await this.providerPuls?.schreibe().catch(()=>{}),this.temporalAnalyzerTimer&&(clearInterval(this.temporalAnalyzerTimer),this.temporalAnalyzerTimer=void 0),this.insightExpiryTimer&&(clearInterval(this.insightExpiryTimer),this.insightExpiryTimer=void 0),this.topicCollector&&(this.topicCollector.stop(),this.topicCollector=void 0),this.interestsDailyTimer&&(clearInterval(this.interestsDailyTimer),this.interestsDailyTimer=void 0),this.publishingEngine&&(this.publishingEngine.stop(),this.publishingEngine=void 0),this.contentStudioTimer&&(clearInterval(this.contentStudioTimer),this.contentStudioTimer=void 0),this.clusterMonitorTimer&&(clearInterval(this.clusterMonitorTimer),this.clusterMonitorTimer=void 0),this.cmdbDiscoveryTimer&&(clearInterval(this.cmdbDiscoveryTimer),this.cmdbDiscoveryTimer=void 0),this.agentConventionsDriftTimer&&(clearInterval(this.agentConventionsDriftTimer),this.agentConventionsDriftTimer=void 0),this.agentConventionsPatternMiningTimer&&(clearInterval(this.agentConventionsPatternMiningTimer),this.agentConventionsPatternMiningTimer=void 0),this.agentConventionsSelfModifyTimer&&(clearInterval(this.agentConventionsSelfModifyTimer),this.agentConventionsSelfModifyTimer=void 0),this.cmdbHealthCheckTimer&&(clearInterval(this.cmdbHealthCheckTimer),this.cmdbHealthCheckTimer=void 0),this.reflectionEngine?.stop(),this.mcpManager&&await this.mcpManager.shutdown();let e=5e3;for(let[t,s]of this.adapters)try{await Promise.race([s.disconnect(),new Promise(n=>setTimeout(n,e))]),this.logger.info({platform:t},"Adapter disconnected")}catch(n){this.logger.error({platform:t,err:n},"Failed to disconnect adapter")}try{this.database&&(this.database.getDb().pragma("wal_checkpoint(TRUNCATE)"),this.database.close())}catch{}this.logger.info("Alfred stopped")}async reloadService(e){try{Pm();let t=new Zt().loadConfig();if(this.skillRegistry.has(e)&&this.skillRegistry.unregister(e),e==="proxmox"&&t.proxmox){let{ProxmoxSkill:s}=await Promise.resolve().then(()=>(We(),Ze));this.skillRegistry.register(new s(t.proxmox)),this.config.proxmox=t.proxmox,this.logger.info({baseUrl:t.proxmox.baseUrl},"Proxmox skill hot-reloaded")}if(e==="unifi"&&t.unifi){let{UniFiSkill:s}=await Promise.resolve().then(()=>(We(),Ze));this.skillRegistry.register(new s(t.unifi)),this.config.unifi=t.unifi,this.logger.info({baseUrl:t.unifi.baseUrl},"UniFi skill hot-reloaded")}if(e==="homeassistant"&&t.homeassistant){let{HomeAssistantSkill:s}=await Promise.resolve().then(()=>(We(),Ze));this.skillRegistry.register(new s(t.homeassistant)),this.config.homeassistant=t.homeassistant,this.logger.info({baseUrl:t.homeassistant.baseUrl},"Home Assistant skill hot-reloaded")}if(e==="contacts"&&t.contacts){let{ContactsSkill:s,createContactsProvider:n}=await Promise.resolve().then(()=>(We(),Ze)),i=await n(t.contacts);this.skillRegistry.register(new s(i)),this.config.contacts=t.contacts,this.logger.info({provider:t.contacts.provider},"Contacts skill hot-reloaded")}if(e==="docker"&&t.docker){let{DockerSkill:s}=await Promise.resolve().then(()=>(We(),Ze));this.skillRegistry.register(new s(t.docker)),this.config.docker=t.docker,this.logger.info("Docker skill hot-reloaded")}if(e==="bmw"&&t.bmw){let{BMWSkill:s}=await Promise.resolve().then(()=>(We(),Ze));this.bmwSkill=new s(t.bmw),this.skillRegistry.register(this.bmwSkill),this.userServiceResolverRef&&"setServiceResolver"in this.bmwSkill&&this.bmwSkill.setServiceResolver(this.userServiceResolverRef,this.ownerMasterUserId),this.bmwTelematicRepo&&"setTelematicRepo"in this.bmwSkill&&this.bmwSkill.setTelematicRepo(this.bmwTelematicRepo),this.config.bmw=t.bmw,this.logger.info("BMW CarData skill hot-reloaded")}if(e==="goe_charger"&&t.goeCharger?.host){let{GoeChargerSkill:s}=await Promise.resolve().then(()=>(We(),Ze));this.skillRegistry.register(new s(t.goeCharger,t.energy)),this.config.goeCharger=t.goeCharger,this.logger.info("go-e Charger skill hot-reloaded")}if(e==="routing"&&t.routing){let{RoutingSkill:s}=await Promise.resolve().then(()=>(We(),Ze));this.skillRegistry.register(new s(t.routing)),this.config.routing=t.routing,this.logger.info("Routing skill hot-reloaded")}if(e==="todo"&&t.todo){let{MicrosoftTodoSkill:s}=await Promise.resolve().then(()=>(We(),Ze));this.skillRegistry.register(new s(t.todo)),this.config.todo=t.todo,this.logger.info("Microsoft To Do skill hot-reloaded")}return{success:!0}}catch(t){let s=t instanceof Error?t.message:String(t);return this.logger.error({err:t,service:e},"Failed to hot-reload service"),{success:!1,error:s}}}getConfiguredServices(){let e=[],t=this.config.speech;if(t){let n=t.sttProvider??t.provider,i=t.ttsProvider??t.provider;if(n){let r=n==="mistral"?"voxtral-mini-latest":n==="groq"?"whisper-large-v3-turbo":"whisper-1";e.push({name:"Speech-to-Text",provider:n,model:r,status:"active"})}if(t.ttsEnabled!==!1&&i){let r=i==="mistral"?"voxtral-mini-tts-2603":"tts-1";e.push({name:"Text-to-Speech",provider:i,model:r,status:"active"})}}if(this.config.mistralApiKey&&e.push({name:"OCR",provider:"mistral",model:"mistral-ocr-latest",status:"active"}),this.config.security?.moderation?.enabled){let n=this.config.security.moderation.provider??"mistral",i=this.config.security.moderation.model??(n==="mistral"?"mistral-moderation-latest":"omni-moderation-latest");e.push({name:"Moderation",provider:n,model:i,status:"active"})}let s=this.config.llm.embeddings;if(s?.provider&&e.push({name:"Embeddings",provider:s.provider,model:s.model??"unknown",status:"active"}),this.config.reasoning?.llmLinking?.enabled){let n=this.config.reasoning.llmLinking;e.push({name:"KG Entity-Linking",provider:n.provider??"mistral",model:n.model??"mistral-small-latest",status:"active"})}return e}resolveWebUiPath(){let e;try{e=xt.dirname(new URL(import.meta.url).pathname),process.platform==="win32"&&e.startsWith("/")&&(e=e.slice(1))}catch{e=process.cwd()}let t=[xt.join(process.cwd(),"web-ui"),xt.join(e,"..","web-ui"),xt.join(e,"web-ui"),xt.join(e,"..","..","web-ui"),xt.join(e,"..","..","apps","web","out")];for(let s of t)try{let n=xt.resolve(s);if(Ho.existsSync(xt.join(n,"index.html")))return this.logger.info({path:n},"Web UI found"),n}catch{}this.logger.debug("Web UI not found \u2014 serving API only")}async runProblemRca(e,t,s,n){if(!this.llmProvider)return;let i=await s.getProblemById(e,t);if(!i||(i.linkedIncidentIds?.length??0)<2||i.rootCauseDescription)return;let r=[];for(let o of i.linkedIncidentIds.slice(0,8))try{let c=await n.getIncidentById(e,o);if(!c)continue;r.push(`- **${c.title}** (${c.openedAt?.slice(0,16)??"?"})
8646
+ ) ORDER BY created_at DESC LIMIT 100`,[f.id]);if(w.length>10){let _=await p.getLLMLinker().analyzeRecentChats(f.id,w.reverse());(_.relations>0||_.newEntities>0)&&this.logger.info({..._},"Weekly chat analysis completed")}}catch(y){this.logger.debug({err:y},"Weekly chat analysis failed")}}}catch(h){this.logger.warn({err:h},"Temporal analysis failed")}try{if(this.config.cmdb?.enabled!==!1&&this.database){let h=this.database.getAdapter(),{CmdbRepository:p,ItsmRepository:f}=await Promise.resolve().then(()=>(lt(),ht)),g=new p(h),y=new f(h),w=this.userRepo?await this.userRepo.findOrCreate("telegram",this.config.security?.ownerUserId??""):void 0,_=w?.masterUserId??w?.id??this.config.security?.ownerUserId??"";if(_){let E=await g.listAssets(_),T=E.filter(N=>["server","vm","lxc","container","application","service"].includes(N.assetType)&&N.status==="active"),k=await y.listServices(_),b=new Set;for(let N of k)for(let I of N.assetIds??[])b.add(I);let v=0;for(let N of T){if(b.has(N.id))continue;let I=["server","vm","lxc"].includes(N.assetType)?"infrastructure":N.assetType==="container"||N.assetType==="application"?"application":"infrastructure",C=N.environment==="production"?"high":"medium";try{await y.createService(_,{name:`${N.name} Service`,description:`Automatisch abgeleitet aus CMDB-Asset (${N.assetType}). ${N.purpose??""}`.trim(),category:I,environment:N.environment,criticality:C,assetIds:[N.id],tags:"auto-discovered"}),v++}catch{}}v>0&&this.logger.info({createdServices:v,totalAssets:E.length},"Weekly service-discovery completed")}}}catch(h){this.logger.warn({err:h},"Weekly service-discovery failed")}}},60*6e4),r.registriere({key:"kg-maintenance",beschreibung:"KG-Wartung + Entity-Embeddings + Stammdaten-Sync",takt:{art:"taeglich",um:"04:30"},bereich:"master",slot:!0,run:m(async({userId:d})=>{let u=new Sr(new ks(this.database.getAdapter()),this.logger.child({component:"knowledge-graph"}),this.memoryRepo);this.embeddingServiceRef&&u.setEmbeddingService(this.embeddingServiceRef,this.embeddingRepoRef),await u.maintenance(d);let h=0;if(this.memoryRepo){let{StammdatenSync:p}=await Promise.resolve().then(()=>(BT(),jT));h=(await new p(new ks(this.database.getAdapter()),this.memoryRepo,this.logger.child({component:"stammdaten-sync"})).run(d).catch(()=>{}))?.gesetzt??0}return{ok:!0,zaehler:{stammdatenGesetzt:h}}},"run")})}{let{DegradationsWaechter:a,bewertePuls:o,bewerteProben:c,formatiereMeldungen:d}=await Promise.resolve().then(()=>(tO(),eO)),{fuehreProbenAus:u}=await Promise.resolve().then(()=>(EE(),ZL)),h=this.lebenszeichenRepo;this.degradationsWaechter=new a({logger:this.logger.child({component:"lebenszeichen"}),persistenz:h?{ladeMeldungen:m(()=>h.ladeMeldungen(),"ladeMeldungen"),speichereMeldung:m(_=>h.speichereMeldung(_),"speichereMeldung"),loescheMeldung:m(_=>h.loescheMeldung(_),"loescheMeldung")}:void 0}),await this.degradationsWaechter.lade(),await this.providerPuls?.lade();let p=this.degradationsWaechter,f=this.providerPuls,g=new i(this.database.getAdapter()),y=this.jobRegister,w=m(async _=>{let E=new Date().toISOString().slice(0,10),T=[];for(let b of _)await this.claimDailySlot(`lz-${b.art}:${b.key}:${E}`)&&T.push(b);let k=d(T);return k?(await this.sendeAnOwner(k),this.logger.info({meldungen:T.map(b=>`${b.art}:${b.key}`)},"Lebenszeichen: Owner-Satz gesendet"),T.length):0},"melde");y.registriere({key:"degradations-waechter",beschreibung:"Provider-Puls bewerten (Degradation/Guthaben)",takt:{art:"intervall",minuten:10},bereich:"global",run:m(async()=>{if(!f)return{ok:!0};let _=o(f.alle(),new Date),E=await p.abgleich(_,{wiederholen:!1,nurBereiche:["tier"]}),T=await w(E);return{ok:!0,zaehler:{befunde:_.length,gesendet:T}}},"run")}),y.registriere({key:"lebenszeichen-proben",beschreibung:"Synthetische Proben: Tiers, Job-Takte, Daten-Frische",takt:{art:"taeglich",um:"06:50"},bereich:"global",slot:!0,run:m(async()=>{let _=await u({tiers:{konfigurierteTiers:m(()=>this.llmProvider.konfigurierteTiers(),"konfigurierteTiers"),probeTier:m(v=>this.llmProvider.probeTier(v),"probeTier")},embed:this.llmProvider.supportsEmbeddings()?()=>this.llmProvider.embed("OK"):void 0,jobs:m(()=>y.definitionen(),"jobs"),registerGestartetAm:y.gestartetAm,letzterLauf:m(async v=>{let N=await g.letzterLauf(v);return N?{startedAt:N.startedAt,ok:N.ok}:void 0},"letzterLauf"),juengsteZeit:h?v=>h.juengsteZeit(v):void 0,ausgenommen:["lebenszeichen-proben","degradations-waechter"]});this.letzteProben={zeit:new Date().toISOString(),ergebnisse:_};let E=[...f?o(f.alle(),new Date):[],...c(_)],T=await p.abgleich(E,{wiederholen:!0}),k=await w(T),b=_.filter(v=>!v.ok);return this.logger.info({proben:_.length,fehlgeschlagen:b.map(v=>`${v.art}:${v.name}`),befunde:E.length,gesendet:k},"Lebenszeichen: Proben gelaufen"),{ok:!0,zaehler:{proben:_.length,fehlgeschlagen:b.length,befunde:E.length,gesendet:k}}},"run")})}this.jobRegister.start()}if(this.config.reflection?.enabled!==!1&&this.watchRepo&&this.memoryRepo&&this.activityRepo&&this.skillRegistry&&this.skillSandbox)try{let t=uf(this.config.reflection),s=this.config.telegram?.enabled?"telegram":this.config.discord?.enabled?"discord":this.config.whatsapp?.enabled?"whatsapp":"api",n=this.database?.getAdapter(),i=this.config.cmdb?.enabled!==!1&&n?new ai(n):void 0,r=this.config.telegram?.enabled?this.config.security?.ownerUserId??"":"";this.reflectionEngine=new ad({watchRepo:this.watchRepo,memoryRepo:this.memoryRepo,activityRepo:this.activityRepo,cmdbRepo:i,projectRepo:this.projectRepo,runbookRepo:this.runbookRepo,ownerUserId:this.tryOwner(),confirmationQueue:this.confirmationQueue,resolveAgent:m(a=>this.resolveCliAgent(a,void 0),"resolveAgent"),skillRegistry:this.skillRegistry,skillSandbox:this.skillSandbox,llm:this.llmProvider,adapters:this.adapters,logger:this.logger.child({component:"reflection-engine"}),defaultChatId:r,defaultPlatform:s,nodeId:this.config.cluster?.nodeId??"single",config:t},this.database?.getAdapter()),this.reflectionEngine.start(),this.logger.info("Reflection engine initialized")}catch(t){this.logger.warn({err:t},"Reflection engine initialization failed")}if(this.runbookRepo&&this.memoryRepo&&this.confirmationQueue&&this.database&&this.llmProvider)try{let{ChatSessionRunbookReflector:t}=await Promise.resolve().then(()=>(iO(),nO)),{ConversationRepository:s}=await Promise.resolve().then(()=>(lt(),ht)),n=this.database.getAdapter(),i=new s(n),r=this.config.telegram?.enabled?"telegram":this.config.discord?.enabled?"discord":this.config.whatsapp?.enabled?"whatsapp":"api";this.chatSessionRunbookReflector=new t(n,i,this.runbookRepo,this.memoryRepo,this.confirmationQueue,this.llmProvider,this.logger.child({component:"runbook-reflector"}),r,this.config.security?.ownerUserId??""),this.chatSessionRunbookReflector.start(),this.logger.info("Chat-session runbook reflector started")}catch(t){this.logger.warn({err:t},"Chat-session runbook reflector init failed")}if(this.activityRepo&&this.confirmationQueue&&this.runbookRepo)try{let{SkillFailureReflector:t}=await Promise.resolve().then(()=>(aO(),rO)),s=new t(this.activityRepo,this.logger.child({component:"skill-failure-reflector"}));setInterval(async()=>{let n=this.tryOwner();if(!(!n||!this.confirmationQueue))try{let i=await s.detect(n);for(let r of i){let a=`skill-failure-runbook-${r.failedSkill}-${(r.scope??"").replace(/[^a-z0-9]/gi,"_").slice(0,30)}-${r.errorClass}`,o=`Skill "${r.failedSkill}" auf ${r.scope??"?"} \u2192 Workaround`,c=this.config.telegram?.enabled?"telegram":this.config.discord?.enabled?"discord":this.config.whatsapp?.enabled?"whatsapp":"api";if(await this.confirmationQueue.enqueue({chatId:this.config.security?.ownerUserId??"",platform:c,source:"reasoning",sourceId:a,description:`Runbook aus Skill-Failure-Workaround erstellen: "${o}"?`,skillName:"runbook",skillParams:{action:"create",title:o,symptom:`Skill "${r.failedSkill}" scheiterte ${r.errorClass} bei ${r.scope??"(unbekannter Scope)"}`,steps:r.workaroundSteps.map((d,u)=>`${u+1}. ${d}`),source_type:"chat_session",source_id:a,status:"draft",tags:["skill-failure","workaround","auto",r.failedSkill,r.errorClass.toLowerCase()]},timeoutMinutes:1440}),this.logger.info({skill:r.failedSkill,scope:r.scope,errorClass:r.errorClass},"SkillFailureReflector: runbook-confirmation enqueued"),r.workaroundSteps.length>=2&&r.scope?.startsWith("host=")){let d=`${r.failedSkill}-workaround-${r.errorClass.toLowerCase()}`.replace(/[^a-z0-9-]/gi,"-").replace(/-+/g,"-").slice(0,40),u=r.workaroundSteps.map(h=>({type:"action",skillName:"shell",inputMapping:{command:h},onError:"stop"}));await this.confirmationQueue.enqueue({chatId:this.config.security?.ownerUserId??"",platform:c,source:"reasoning",sourceId:`${a}-workflow`,description:`Workflow '${d}' aus Skill-Failure-Workaround speichern (${u.length} Schritte)?`,skillName:"workflow",skillParams:{action:"create",name:d,description:`Auto-extrahiert aus Workaround f\xFCr ${r.failedSkill}/${r.errorClass} auf ${r.scope}`,steps:u,triggerType:"manual",autoExtracted:!0},timeoutMinutes:1440}),this.logger.info({workflowName:d,steps:u.length},"SkillFailureReflector: workflow-confirmation enqueued (D4)")}}}catch(i){this.logger.debug({err:i},"SkillFailureReflector sweep failed (non-critical)")}},15*6e4),this.logger.info("Skill-failure reflector started (15min sweep interval)")}catch(t){this.logger.warn({err:t},"Skill-failure reflector init failed")}if(this.conversationRepo&&this.learnedRecipeRepo)try{let{RefusalCorrectionReflector:t}=await Promise.resolve().then(()=>(E_(),FR)),s=new t(this.conversationRepo,this.learnedRecipeRepo,this.logger.child({component:"refusal-correction-reflector"}));setInterval(async()=>{let n=this.tryOwner();if(n)try{let i=await s.scanForUser(n);i.length>0&&this.logger.info({count:i.length},"v722 refusal-correction patterns \u2192 recipes persisted")}catch(i){this.logger.debug({err:i},"v722 refusal-correction sweep failed (non-critical)")}},30*6e4),this.logger.info("v722 RefusalCorrectionReflector started (30min sweep interval)")}catch(t){this.logger.warn({err:t},"v722 RefusalCorrectionReflector init failed")}if(this.memoryRepo&&this.confirmationQueue&&this.learnedRecipeRepo&&setTimeout(async()=>{let t=this.tryOwner();if(!(!t||!this.confirmationQueue||!this.memoryRepo))try{let s=await this.learnedRecipeRepo.list(t,{includeInvalidated:!0,limit:500}),n=new Set(s.map(c=>c.triggerPhrase.toLowerCase().trim())),i=await this.memoryRepo.search(t,"wie"),r=/\b(merke dir|wenn der user|wenn ich sage|du sollst dann)\b/i,a=this.config.telegram?.enabled?"telegram":this.config.discord?.enabled?"discord":this.config.whatsapp?.enabled?"whatsapp":"api",o=0;for(let c of i.slice(0,20)){if(!r.test(c.value))continue;let d=(c.key+" "+c.value).toLowerCase().slice(0,200).trim();if(n.has(d))continue;let u=`audit-prose-rule-${c.key}`;if(await this.confirmationQueue.enqueue({chatId:this.config.security?.ownerUserId??"",platform:a,source:"reasoning",sourceId:u,description:`Audit (v722): Memory "${c.key}" sieht aus wie eine prosaische Regel \u2014 soll daraus ein strukturiertes Recipe werden? Inhalt: "${c.value.slice(0,120)}..."`,skillName:"memory",skillParams:{action:"learn_recipe",trigger_phrase:c.key.replace(/^(?:rule_|behavior_|auto_)/,"").replace(/_/g," "),action_sequence:"[]",context_hint:`Quelle: bestehende Memory "${c.key}". Original-Text: ${c.value.slice(0,200)}`},timeoutMinutes:10080}),o++,o>=5)break}o>0?this.logger.info({enqueued:o},"v722 auto-rules audit: enqueued recipe-creation confirmations"):this.logger.debug("v722 auto-rules audit: no prose rules found")}catch(s){this.logger.warn({err:s},"v722 auto-rules audit failed (non-fatal)")}},3e4),this.clusterManager&&(this.clusterMonitorTimer=setInterval(async()=>{try{let t=await this.clusterManager.getNodesAny();t.length>0&&this.logger.debug({liveNodes:t.map(s=>s.id)},"Cluster node status")}catch{}},6e4)),this.insightTracker&&this.ownerMasterUserId){let t=this.ownerMasterUserId;this.insightExpiryTimer=setInterval(()=>{this.insightTracker.processExpired(t).catch(s=>{this.logger.warn({err:s},"Insight expiry processing failed")})},30*6e4)}this.adapters.size===0&&this.logger.warn("No messaging adapters enabled. Configure at least one platform."),this.logger.info(`Alfred is running with ${this.adapters.size} adapter(s)`)}async startWithCLI(){this.adapters.clear();let{CLIAdapter:e}=await Promise.resolve().then(()=>(Zn(),Yn)),t=new e;this.adapters.set("cli",t),t.on("disconnected",()=>{this.stop().then(()=>process.exit(0))}),await this.start()}async stop(){this.logger.info("Stopping Alfred..."),this.bmwSkill&&"stopStreaming"in this.bmwSkill&&this.bmwSkill.stopStreaming(),this.reminderScheduler?.stop(),this.backgroundTaskRunner?.stop(),this.proactiveScheduler?.stop(),this.watchEngine?.stop(),this.triggerManager?.stop(),this.confirmationQueue?.stop(),this.calendarWatcher?.stop(),this.todoWatcher?.stop(),this.reasoningEngine?.stop(),this.projectHealthMonitor?.stop(),this.adapterClaimManager?.stop(),this.clusterManager?.stopPgHeartbeat(),this.healthCheckTimer&&(clearInterval(this.healthCheckTimer),this.healthCheckTimer=void 0),this.jobRegister?.stop(),await this.providerPuls?.schreibe().catch(()=>{}),this.temporalAnalyzerTimer&&(clearInterval(this.temporalAnalyzerTimer),this.temporalAnalyzerTimer=void 0),this.insightExpiryTimer&&(clearInterval(this.insightExpiryTimer),this.insightExpiryTimer=void 0),this.topicCollector&&(this.topicCollector.stop(),this.topicCollector=void 0),this.interestsDailyTimer&&(clearInterval(this.interestsDailyTimer),this.interestsDailyTimer=void 0),this.publishingEngine&&(this.publishingEngine.stop(),this.publishingEngine=void 0),this.contentStudioTimer&&(clearInterval(this.contentStudioTimer),this.contentStudioTimer=void 0),this.clusterMonitorTimer&&(clearInterval(this.clusterMonitorTimer),this.clusterMonitorTimer=void 0),this.cmdbDiscoveryTimer&&(clearInterval(this.cmdbDiscoveryTimer),this.cmdbDiscoveryTimer=void 0),this.agentConventionsDriftTimer&&(clearInterval(this.agentConventionsDriftTimer),this.agentConventionsDriftTimer=void 0),this.agentConventionsPatternMiningTimer&&(clearInterval(this.agentConventionsPatternMiningTimer),this.agentConventionsPatternMiningTimer=void 0),this.agentConventionsSelfModifyTimer&&(clearInterval(this.agentConventionsSelfModifyTimer),this.agentConventionsSelfModifyTimer=void 0),this.cmdbHealthCheckTimer&&(clearInterval(this.cmdbHealthCheckTimer),this.cmdbHealthCheckTimer=void 0),this.reflectionEngine?.stop(),this.mcpManager&&await this.mcpManager.shutdown();let e=5e3;for(let[t,s]of this.adapters)try{await Promise.race([s.disconnect(),new Promise(n=>setTimeout(n,e))]),this.logger.info({platform:t},"Adapter disconnected")}catch(n){this.logger.error({platform:t,err:n},"Failed to disconnect adapter")}try{this.database&&(this.database.getDb().pragma("wal_checkpoint(TRUNCATE)"),this.database.close())}catch{}this.logger.info("Alfred stopped")}async reloadService(e){try{Pm();let t=new Zt().loadConfig();if(this.skillRegistry.has(e)&&this.skillRegistry.unregister(e),e==="proxmox"&&t.proxmox){let{ProxmoxSkill:s}=await Promise.resolve().then(()=>(We(),Ze));this.skillRegistry.register(new s(t.proxmox)),this.config.proxmox=t.proxmox,this.logger.info({baseUrl:t.proxmox.baseUrl},"Proxmox skill hot-reloaded")}if(e==="unifi"&&t.unifi){let{UniFiSkill:s}=await Promise.resolve().then(()=>(We(),Ze));this.skillRegistry.register(new s(t.unifi)),this.config.unifi=t.unifi,this.logger.info({baseUrl:t.unifi.baseUrl},"UniFi skill hot-reloaded")}if(e==="homeassistant"&&t.homeassistant){let{HomeAssistantSkill:s}=await Promise.resolve().then(()=>(We(),Ze));this.skillRegistry.register(new s(t.homeassistant)),this.config.homeassistant=t.homeassistant,this.logger.info({baseUrl:t.homeassistant.baseUrl},"Home Assistant skill hot-reloaded")}if(e==="contacts"&&t.contacts){let{ContactsSkill:s,createContactsProvider:n}=await Promise.resolve().then(()=>(We(),Ze)),i=await n(t.contacts);this.skillRegistry.register(new s(i)),this.config.contacts=t.contacts,this.logger.info({provider:t.contacts.provider},"Contacts skill hot-reloaded")}if(e==="docker"&&t.docker){let{DockerSkill:s}=await Promise.resolve().then(()=>(We(),Ze));this.skillRegistry.register(new s(t.docker)),this.config.docker=t.docker,this.logger.info("Docker skill hot-reloaded")}if(e==="bmw"&&t.bmw){let{BMWSkill:s}=await Promise.resolve().then(()=>(We(),Ze));this.bmwSkill=new s(t.bmw),this.skillRegistry.register(this.bmwSkill),this.userServiceResolverRef&&"setServiceResolver"in this.bmwSkill&&this.bmwSkill.setServiceResolver(this.userServiceResolverRef,this.ownerMasterUserId),this.bmwTelematicRepo&&"setTelematicRepo"in this.bmwSkill&&this.bmwSkill.setTelematicRepo(this.bmwTelematicRepo),this.config.bmw=t.bmw,this.logger.info("BMW CarData skill hot-reloaded")}if(e==="goe_charger"&&t.goeCharger?.host){let{GoeChargerSkill:s}=await Promise.resolve().then(()=>(We(),Ze));this.skillRegistry.register(new s(t.goeCharger,t.energy)),this.config.goeCharger=t.goeCharger,this.logger.info("go-e Charger skill hot-reloaded")}if(e==="routing"&&t.routing){let{RoutingSkill:s}=await Promise.resolve().then(()=>(We(),Ze));this.skillRegistry.register(new s(t.routing)),this.config.routing=t.routing,this.logger.info("Routing skill hot-reloaded")}if(e==="todo"&&t.todo){let{MicrosoftTodoSkill:s}=await Promise.resolve().then(()=>(We(),Ze));this.skillRegistry.register(new s(t.todo)),this.config.todo=t.todo,this.logger.info("Microsoft To Do skill hot-reloaded")}return{success:!0}}catch(t){let s=t instanceof Error?t.message:String(t);return this.logger.error({err:t,service:e},"Failed to hot-reload service"),{success:!1,error:s}}}getConfiguredServices(){let e=[],t=this.config.speech;if(t){let n=t.sttProvider??t.provider,i=t.ttsProvider??t.provider;if(n){let r=n==="mistral"?"voxtral-mini-latest":n==="groq"?"whisper-large-v3-turbo":"whisper-1";e.push({name:"Speech-to-Text",provider:n,model:r,status:"active"})}if(t.ttsEnabled!==!1&&i){let r=i==="mistral"?"voxtral-mini-tts-2603":"tts-1";e.push({name:"Text-to-Speech",provider:i,model:r,status:"active"})}}if(this.config.mistralApiKey&&e.push({name:"OCR",provider:"mistral",model:"mistral-ocr-latest",status:"active"}),this.config.security?.moderation?.enabled){let n=this.config.security.moderation.provider??"mistral",i=this.config.security.moderation.model??(n==="mistral"?"mistral-moderation-latest":"omni-moderation-latest");e.push({name:"Moderation",provider:n,model:i,status:"active"})}let s=this.config.llm.embeddings;if(s?.provider&&e.push({name:"Embeddings",provider:s.provider,model:s.model??"unknown",status:"active"}),this.config.reasoning?.llmLinking?.enabled){let n=this.config.reasoning.llmLinking;e.push({name:"KG Entity-Linking",provider:n.provider??"mistral",model:n.model??"mistral-small-latest",status:"active"})}return e}resolveWebUiPath(){let e;try{e=xt.dirname(new URL(import.meta.url).pathname),process.platform==="win32"&&e.startsWith("/")&&(e=e.slice(1))}catch{e=process.cwd()}let t=[xt.join(process.cwd(),"web-ui"),xt.join(e,"..","web-ui"),xt.join(e,"web-ui"),xt.join(e,"..","..","web-ui"),xt.join(e,"..","..","apps","web","out")];for(let s of t)try{let n=xt.resolve(s);if(Ho.existsSync(xt.join(n,"index.html")))return this.logger.info({path:n},"Web UI found"),n}catch{}this.logger.debug("Web UI not found \u2014 serving API only")}async runProblemRca(e,t,s,n){if(!this.llmProvider)return;let i=await s.getProblemById(e,t);if(!i||(i.linkedIncidentIds?.length??0)<2||i.rootCauseDescription)return;let r=[];for(let o of i.linkedIncidentIds.slice(0,8))try{let c=await n.getIncidentById(e,o);if(!c)continue;r.push(`- **${c.title}** (${c.openedAt?.slice(0,16)??"?"})
8647
8647
  Symptoms: ${(c.symptoms??"").slice(0,200)}`)}catch{}if(r.length===0)return;let a=`Du bist ein erfahrener Site-Reliability-Engineer. Analysiere die folgenden ${r.length} \xE4hnlichen Incidents und formuliere eine Root-Cause-Hypothese.
8648
8648
 
8649
8649
  **Problem-Titel:** ${i.title}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@madh-io/alfred-ai",
3
- "version": "0.19.0-jarvis.1162",
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": {