@madh-io/alfred-ai 0.10.34 → 0.10.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/bundle/index.js +2 -2
  2. package/package.json +1 -1
package/bundle/index.js CHANGED
@@ -678,7 +678,7 @@ ${r}`}}catch(s){return{success:!1,error:`Failed to list contacts: ${s instanceof
678
678
  ${s.join(`
679
679
  `)}`}formatDetail(e){let t=[];if(t.push(`**Name:** ${e.displayName}`),e.firstName&&t.push(`**First name:** ${e.firstName}`),e.lastName&&t.push(`**Last name:** ${e.lastName}`),e.emails.length>0&&t.push(`**Email(s):** ${e.emails.map(s=>`${s.address}${s.label?` (${s.label})`:""}`).join(", ")}`),e.phones.length>0&&t.push(`**Phone(s):** ${e.phones.map(s=>`${s.number}${s.label?` (${s.label})`:""}`).join(", ")}`),e.addresses.length>0)for(let s of e.addresses){let r=[s.street,s.city,s.region,s.postalCode,s.country].filter(Boolean);t.push(`**Address${s.label?` (${s.label})`:""}:** ${r.join(", ")}`)}return e.organization&&t.push(`**Organization:** ${e.organization}`),e.birthday&&t.push(`**Birthday:** ${e.birthday}`),e.notes&&t.push(`**Notes:** ${e.notes}`),t.push(`**ID:** ${e.id}`),t.join(`
680
680
  `)}}});var ol=T(()=>{"use strict";ur();ri();ni();oi();rl();nl()});var ns,il=T(()=>{"use strict";P();Be();ns=class extends A{static{u(this,"TodoSkill")}todoRepo;metadata={name:"todo",category:"productivity",description:"Manage todo lists with multiple named lists. Actions: add, list, complete, uncomplete, delete, lists, clear.",riskLevel:"write",version:"1.0.0",inputSchema:{type:"object",properties:{action:{type:"string",enum:["add","list","complete","uncomplete","delete","lists","clear"],description:"The todo action to perform"},title:{type:"string",description:"The todo title (required for add)"},list:{type:"string",description:'The list name (default: "default")'},description:{type:"string",description:"Optional description for the todo"},priority:{type:"string",enum:["low","normal","high","urgent"],description:'Priority level (default: "normal")'},dueDate:{type:"string",description:"Due date for the todo (ISO string)"},todoId:{type:"string",description:"The ID of the todo (required for complete, uncomplete, delete)"},includeCompleted:{type:"boolean",description:"Include completed todos in list output (default: false)"}},required:["action"]}};constructor(e){super(),this.todoRepo=e}async execute(e,t){let s=e.action;switch(s){case"add":return this.addTodo(e,t);case"list":return this.listTodos(e,t);case"complete":return this.completeTodo(e,t);case"uncomplete":return this.uncompleteTodo(e,t);case"delete":return this.deleteTodo(e,t);case"lists":return this.showLists(t);case"clear":return this.clearCompleted(e,t);default:return{success:!1,error:`Unknown action: "${String(s)}". Valid actions: add, list, complete, uncomplete, delete, lists, clear`}}}addTodo(e,t){let s=e.title;if(!s||typeof s!="string")return{success:!1,error:'Missing required field "title" for add action'};let r=e.list??"default",n=e.description,o=e.priority,i=e.dueDate,a=this.todoRepo.add(te(t),s,{list:r,description:n,priority:o,dueDate:i});return{success:!0,data:{todoId:a.id,title:a.title,list:a.list},display:`Todo added: "${s}"`}}listTodos(e,t){let s=e.list,r=e.includeCompleted??!1,n=new Set,o=[];for(let c of z(t))for(let d of this.todoRepo.list(c,s,r))n.has(d.id)||(n.add(d.id),o.push(d));if(o.length===0)return{success:!0,data:[],display:"No todos found."};let i=`| | Priority | Title | Due | ID |
681
- |---|---|---|---|---|`,a=o.map(c=>{let d=c.completed?"\u2611":"\u2610",m=c.dueDate??"",p=c.id.slice(0,8);return`| ${d} | ${c.priority} | ${c.title} | ${m} | ${p} |`}).join(`
681
+ |---|---|---|---|---|`,a=o.map(c=>{let d=c.completed?"\u2611":"\u2610",m=c.dueDate??"";return`| ${d} | ${c.priority} | ${c.title} | ${m} | ${c.id} |`}).join(`
682
682
  `);return{success:!0,data:o,display:`${o.length} todo(s):
683
683
  ${i}
684
684
  ${a}`}}completeTodo(e,t){let s=e.todoId;if(!s||typeof s!="string")return{success:!1,error:'Missing required field "todoId" for complete action'};let r=this.todoRepo.getById(s);return r?z(t).includes(r.userId)?this.todoRepo.complete(s)?{success:!0,data:{todoId:s},display:"Todo completed."}:{success:!1,error:`Todo "${s}" is already completed`}:{success:!1,error:`Todo "${s}" not found`}:{success:!1,error:`Todo "${s}" not found`}}uncompleteTodo(e,t){let s=e.todoId;if(!s||typeof s!="string")return{success:!1,error:'Missing required field "todoId" for uncomplete action'};let r=this.todoRepo.getById(s);return r?z(t).includes(r.userId)?this.todoRepo.uncomplete(s)?{success:!0,data:{todoId:s},display:"Todo reopened."}:{success:!1,error:`Todo "${s}" is not completed`}:{success:!1,error:`Todo "${s}" not found`}:{success:!1,error:`Todo "${s}" not found`}}deleteTodo(e,t){let s=e.todoId;if(!s||typeof s!="string")return{success:!1,error:'Missing required field "todoId" for delete action'};let r=this.todoRepo.getById(s);return r?z(t).includes(r.userId)?this.todoRepo.delete(s)?{success:!0,data:{todoId:s},display:"Todo deleted."}:{success:!1,error:`Todo "${s}" not found`}:{success:!1,error:`Todo "${s}" not found`}:{success:!1,error:`Todo "${s}" not found`}}showLists(e){let t=new Map;for(let o of z(e))for(let i of this.todoRepo.getLists(o)){let a=t.get(i.list);a?(a.open+=i.open,a.completed+=i.completed,a.total+=i.total):t.set(i.list,{open:i.open,completed:i.completed,total:i.total})}if(t.size===0)return{success:!0,data:[],display:"No todo lists found."};let s=[...t.entries()].map(([o,i])=>({list:o,...i})),r=`| List | Open | Completed | Total |
@@ -817,7 +817,7 @@ ${e.allModifiedFiles.map(r=>`- ${r}`).join(`
817
817
 
818
818
  **Git:**
819
819
  ${s.join(`
820
- `)}`:"";return{...t,data:{...t.data,git:{branch:r.branch,commit:r.commit,pullRequest:r.pullRequest,warnings:r.warnings}},display:(t.display??"")+n}}}});var Gl=T(()=>{"use strict";Wl();Rn();Si();Ei();ki()});var J={};ie(J,{ActivityTracker:()=>wt,BMWSkill:()=>$n,BackgroundTaskSkill:()=>Qt,BrowserSkill:()=>Yt,CalculatorSkill:()=>Ot,CalendarProvider:()=>Le,CalendarSkill:()=>Tt,ClipboardSkill:()=>Kt,CodeAgentSkill:()=>_r,CodeExecutionSkill:()=>lr,CodeExecutor:()=>bt,ConfigureSkill:()=>cs,ContactsProvider:()=>Pe,ContactsSkill:()=>mr,CrossPlatformSkill:()=>Zt,DelegateSkill:()=>zt,DockerSkill:()=>_n,DocumentSkill:()=>ts,EmailProvider:()=>Ve,EmailSkill:()=>Qe,EnergyPriceSkill:()=>vn,FileSkill:()=>Gt,ForgeClient:()=>vt,HomeAssistantSkill:()=>fn,HttpSkill:()=>Wt,ImageGenerateSkill:()=>rs,MCPClient:()=>_t,MCPManager:()=>cr,MCPSkillAdapter:()=>Et,MarketplaceSkill:()=>fr,MemorySkill:()=>qt,MicrosoftTodoSkill:()=>An,MonitorSkill:()=>Sn,NoteSkill:()=>jt,PluginLoader:()=>nn,ProfileSkill:()=>Jt,ProxmoxSkill:()=>pn,ReminderSkill:()=>Ft,RoutingSkill:()=>kn,ScheduledTaskSkill:()=>es,ScreenshotSkill:()=>Xt,ShellSkill:()=>Ht,Skill:()=>A,SkillRegistry:()=>Lt,SkillSandbox:()=>Mt,SystemInfoSkill:()=>Pt,TTSSkill:()=>ss,TodoSkill:()=>ns,TransitSkill:()=>is,UniFiSkill:()=>hn,WatchSkill:()=>ls,WeatherSkill:()=>Bt,WebSearchSkill:()=>Ut,allUserIds:()=>z,createCalendarProvider:()=>ar,createContactsProvider:()=>ii,createEmailProvider:()=>nr,createForgeClient:()=>ms,effectiveUserId:()=>te,gitAddRemote:()=>wr,gitGetRemoteUrl:()=>ds,gitInitRepo:()=>yr,orchestrate:()=>St,orchestrateWithGit:()=>Tr,parseRemoteUrl:()=>us});var Y=T(()=>{"use strict";P();Be();ic();ac();Go();cc();lc();dc();uc();mc();pc();hc();yc();wc();Tc();$c();vc();Ac();Ic();Rc();Dc();Nc();Fc();jc();Bc();Hc();zc();Gc();Vc();Kc();Xc();Yc();Jc();Qc();ol();il();ul();wl();Tl();Sl();Al();Rl();Cl();Dl();Ll();Ul();Gl()});var Er,Ai=T(()=>{"use strict";Er=class{static{u(this,"ConversationManager")}conversations;constructor(e){this.conversations=e}getOrCreateConversation(e,t,s){let r=this.conversations.findByPlatformChat(e,t);return r?(this.conversations.updateTimestamp(r.id),r):this.conversations.create(e,t,s)}addMessage(e,t,s,r){return this.conversations.addMessage(e,t,s,r)}getHistory(e,t=20){return this.conversations.getMessages(e,t)}pruneMessages(e,t){return this.conversations.pruneMessages(e,t)}}});function Ke(l,e){let t;if(e.platformUserId)t=l.findOrCreate(e.platform,e.platformUserId,e.userName,e.displayName);else if(e.userId)t=l.findById(e.userId)??l.findOrCreate(e.platform,e.userId);else throw new Error("ContextSource must provide either platformUserId or userId");let s="getMasterUserId"in l?l.getMasterUserId(t.id):t.id,r=[];"getLinkedUsers"in l&&(r=l.getLinkedUsers(s).map(a=>a.platformUserId));let n;try{"getProfile"in l?n=l.getProfile(s)?.timezone||Intl.DateTimeFormat().resolvedOptions().timeZone:n=Intl.DateTimeFormat().resolvedOptions().timeZone}catch{n=Intl.DateTimeFormat().resolvedOptions().timeZone}return{context:{userId:t.platformUserId,masterUserId:s,linkedPlatformUserIds:r,chatId:e.chatId,chatType:e.chatType,platform:e.platform,conversationId:e.conversationId??"",timezone:n},user:t,masterUserId:s,linkedPlatformUserIds:r}}var ps=T(()=>{"use strict";u(Ke,"buildSkillContext")});function Vl(l,e){let t=new Set(["core"]),s=!1;for(let[r,n]of Object.entries(wp))e.has(r)&&n.test(l)&&(t.add(r),s=!0);if(!s)for(let r of e)t.add(r);return t}function Kl(l,e){return l.filter(t=>e.has(t.category??"core"))}var wp,Xl=T(()=>{"use strict";wp={productivity:/\b(todo|note|remind|calendar|termin|event|email|e-mail|mail|contact|kontakt)\b/i,information:/\b(search|such|weather|wetter|calculat|rechn|time|date|zeit|datum|uhrzeit|system.?info|transit|bahn|zug|bus|tram|u.?bahn|s.?bahn|abfahrt|verbindung|haltestelle|öffi|fahrplan|strom|energy|preis|price|kwh|awattar|marktpreis|spot|günstig|cheapest|netzentgelt)\b/i,media:/\b(voice|stimme|tts|speak|sprech|sprich|screenshot|clipboard|zwischenablage|brows)\b/i,automation:/\b(background|hintergrund|shell|bash|cron|schedul|code.?agent|sandbox|automat|watch|alert|benachrichtig|bescheid|meld|überwach|monitor|täglich|stündlich|wöchentlich|monatlich|jeden\s+(tag|morgen|abend|montag|dienstag|mittwoch|donnerstag|freitag|samstag|sonntag)|um\s+\d{1,2}\s*(uhr|:|h)|alle\s+\d+\s*(min|stund|sekund)|daily|hourly|weekly|every\s+(day|hour|morning|evening|night|\d+\s*min))\b/i,files:/\b(file|datei|document|dokument|pdf|http|download|upload)\b/i,infrastructure:/\b(proxmox|vm|container|docker|unifi|wifi|wlan|homeassistant|home.?assistant|smarthome|smart.?home|licht|light|schalter|switch)\b/i,identity:/\b(link|verknüpf|cross.?platform|identity|identität)\b/i,mcp:/\bmcp\b/i};u(Vl,"selectCategories");u(Kl,"filterSkills")});import Ii from"node:fs";import Yl from"node:path";var Tp,Jl,_p,Zl,Ep,bp,$p,Ql,br,xi=T(()=>{"use strict";zo();ps();Xl();Tp=15*60*1e3,Jl=50,_p=2,Zl=.85,Ep=1e5,bp=2e3,$p=.1,Ql=3,br=class{static{u(this,"MessagePipeline")}promptBuilder;llm;conversationManager;users;logger;skillRegistry;skillSandbox;securityManager;memoryRepo;speechTranscriber;inboxPath;embeddingService;activeLearning;memoryRetriever;maxHistoryMessages;documentProcessor;activeAgents=new Map;agentIdCounter=0;constructor(e){this.llm=e.llm,this.conversationManager=e.conversationManager,this.users=e.users,this.logger=e.logger,this.skillRegistry=e.skillRegistry,this.skillSandbox=e.skillSandbox,this.securityManager=e.securityManager,this.memoryRepo=e.memoryRepo,this.speechTranscriber=e.speechTranscriber,this.inboxPath=e.inboxPath,this.embeddingService=e.embeddingService,this.activeLearning=e.activeLearning,this.memoryRetriever=e.memoryRetriever,this.maxHistoryMessages=e.maxHistoryMessages??100,this.documentProcessor=e.documentProcessor,this.promptBuilder=new Qs}async process(e,t){let s=Date.now();this.logger.info({platform:e.platform,userId:e.userId,chatId:e.chatId},"Processing message");try{let{user:r,masterUserId:n,linkedPlatformUserIds:o,context:i}=Ke(this.users,{platformUserId:e.userId,platform:e.platform,chatId:e.chatId,chatType:e.chatType,userName:e.userName,displayName:e.displayName}),a=this.conversationManager.getOrCreateConversation(e.platform,e.chatId,r.id),c=this.conversationManager.getHistory(a.id,this.maxHistoryMessages);this.conversationManager.addMessage(a.id,"user",e.text);let d,m=this.isSyntheticLabel(e.text),p=e.attachments?.some(B=>B.type==="audio")??!1,g=m&&!p;if(this.memoryRetriever&&e.text&&!g)try{d=await this.memoryRetriever.retrieve(n,e.text,15,o)}catch(B){this.logger.debug({err:B},"Hybrid memory retrieval failed")}if(!d&&this.memoryRepo&&!g)try{let B=[n,...(o??[]).filter(Q=>Q!==n)];if(this.embeddingService&&e.text&&this.llm.supportsEmbeddings()){let Q=new Set;d=[];for(let se of B)for(let ee of await this.embeddingService.semanticSearch(se,e.text,10))Q.has(ee.key)||(Q.add(ee.key),d.push(ee));for(let se of B)for(let ee of this.memoryRepo.getRecentForPrompt(se,5))Q.has(ee.key)||(Q.add(ee.key),d.push(ee))}else{let Q=new Set;d=[];for(let se of B)for(let ee of this.memoryRepo.getRecentForPrompt(se,20))Q.has(ee.key)||(Q.add(ee.key),d.push(ee))}}catch(B){this.logger.debug({err:B},"Memory loading failed")}d&&d.length>0&&(d=this.applyMemoryBudget(d));let f;try{"getProfile"in this.users&&(f=this.users.getProfile(n),f&&!f.displayName&&(f.displayName=r.displayName??r.username))}catch(B){this.logger.debug({err:B},"Profile loading failed")}let h=i.timezone??Intl.DateTimeFormat().resolvedOptions().timeZone,_=this.skillRegistry?this.skillRegistry.getAll().map(B=>B.metadata):void 0,b=_;if(_&&e.text){let B=new Set(_.map(se=>se.category??"core")),Q=Vl(e.text,B);b=Kl(_,Q)}let I=b?this.promptBuilder.buildTools(b):void 0,C=this.promptBuilder.buildSystemPrompt({memories:d,skills:b,userProfile:f}),U=this.buildActiveAgentStatus();U&&(C+=`
820
+ `)}`:"";return{...t,data:{...t.data,git:{branch:r.branch,commit:r.commit,pullRequest:r.pullRequest,warnings:r.warnings}},display:(t.display??"")+n}}}});var Gl=T(()=>{"use strict";Wl();Rn();Si();Ei();ki()});var J={};ie(J,{ActivityTracker:()=>wt,BMWSkill:()=>$n,BackgroundTaskSkill:()=>Qt,BrowserSkill:()=>Yt,CalculatorSkill:()=>Ot,CalendarProvider:()=>Le,CalendarSkill:()=>Tt,ClipboardSkill:()=>Kt,CodeAgentSkill:()=>_r,CodeExecutionSkill:()=>lr,CodeExecutor:()=>bt,ConfigureSkill:()=>cs,ContactsProvider:()=>Pe,ContactsSkill:()=>mr,CrossPlatformSkill:()=>Zt,DelegateSkill:()=>zt,DockerSkill:()=>_n,DocumentSkill:()=>ts,EmailProvider:()=>Ve,EmailSkill:()=>Qe,EnergyPriceSkill:()=>vn,FileSkill:()=>Gt,ForgeClient:()=>vt,HomeAssistantSkill:()=>fn,HttpSkill:()=>Wt,ImageGenerateSkill:()=>rs,MCPClient:()=>_t,MCPManager:()=>cr,MCPSkillAdapter:()=>Et,MarketplaceSkill:()=>fr,MemorySkill:()=>qt,MicrosoftTodoSkill:()=>An,MonitorSkill:()=>Sn,NoteSkill:()=>jt,PluginLoader:()=>nn,ProfileSkill:()=>Jt,ProxmoxSkill:()=>pn,ReminderSkill:()=>Ft,RoutingSkill:()=>kn,ScheduledTaskSkill:()=>es,ScreenshotSkill:()=>Xt,ShellSkill:()=>Ht,Skill:()=>A,SkillRegistry:()=>Lt,SkillSandbox:()=>Mt,SystemInfoSkill:()=>Pt,TTSSkill:()=>ss,TodoSkill:()=>ns,TransitSkill:()=>is,UniFiSkill:()=>hn,WatchSkill:()=>ls,WeatherSkill:()=>Bt,WebSearchSkill:()=>Ut,allUserIds:()=>z,createCalendarProvider:()=>ar,createContactsProvider:()=>ii,createEmailProvider:()=>nr,createForgeClient:()=>ms,effectiveUserId:()=>te,gitAddRemote:()=>wr,gitGetRemoteUrl:()=>ds,gitInitRepo:()=>yr,orchestrate:()=>St,orchestrateWithGit:()=>Tr,parseRemoteUrl:()=>us});var Y=T(()=>{"use strict";P();Be();ic();ac();Go();cc();lc();dc();uc();mc();pc();hc();yc();wc();Tc();$c();vc();Ac();Ic();Rc();Dc();Nc();Fc();jc();Bc();Hc();zc();Gc();Vc();Kc();Xc();Yc();Jc();Qc();ol();il();ul();wl();Tl();Sl();Al();Rl();Cl();Dl();Ll();Ul();Gl()});var Er,Ai=T(()=>{"use strict";Er=class{static{u(this,"ConversationManager")}conversations;constructor(e){this.conversations=e}getOrCreateConversation(e,t,s){let r=this.conversations.findByPlatformChat(e,t);return r?(this.conversations.updateTimestamp(r.id),r):this.conversations.create(e,t,s)}addMessage(e,t,s,r){return this.conversations.addMessage(e,t,s,r)}getHistory(e,t=20){return this.conversations.getMessages(e,t)}pruneMessages(e,t){return this.conversations.pruneMessages(e,t)}}});function Ke(l,e){let t;if(e.platformUserId)t=l.findOrCreate(e.platform,e.platformUserId,e.userName,e.displayName);else if(e.userId)t=l.findById(e.userId)??l.findOrCreate(e.platform,e.userId);else throw new Error("ContextSource must provide either platformUserId or userId");let s="getMasterUserId"in l?l.getMasterUserId(t.id):t.id,r=[];"getLinkedUsers"in l&&(r=l.getLinkedUsers(s).map(a=>a.platformUserId));let n;try{"getProfile"in l?n=l.getProfile(s)?.timezone||Intl.DateTimeFormat().resolvedOptions().timeZone:n=Intl.DateTimeFormat().resolvedOptions().timeZone}catch{n=Intl.DateTimeFormat().resolvedOptions().timeZone}return{context:{userId:t.platformUserId,masterUserId:s,linkedPlatformUserIds:r,chatId:e.chatId,chatType:e.chatType,platform:e.platform,conversationId:e.conversationId??"",timezone:n},user:t,masterUserId:s,linkedPlatformUserIds:r}}var ps=T(()=>{"use strict";u(Ke,"buildSkillContext")});function Vl(l,e){let t=new Set(["core"]),s=!1;for(let[r,n]of Object.entries(wp))e.has(r)&&n.test(l)&&(t.add(r),s=!0);if(!s)for(let r of e)t.add(r);return t}function Kl(l,e){return l.filter(t=>e.has(t.category??"core"))}var wp,Xl=T(()=>{"use strict";wp={productivity:/\b(todo|note|remind|calendar|termin|event|email|e-mail|mail|contact|kontakt)\b/i,information:/\b(search|such|weather|wetter|calculat|rechn|time|date|zeit|datum|uhrzeit|system.?info|transit|bahn|zug|bus|tram|u.?bahn|s.?bahn|abfahrt|verbindung|haltestelle|öffi|fahrplan|strom|energy|preis|price|kwh|awattar|marktpreis|spot|günstig|cheapest|netzentgelt)\b/i,media:/\b(voice|stimme|tts|speak|sprech|sprich|screenshot|clipboard|zwischenablage|brows)\b/i,automation:/\b(background|hintergrund|shell|bash|cron|schedul|code.?agent|sandbox|automat|watch|alert|benachrichtig|bescheid|meld|überwach|monitor|tägliche?r?s?|stündliche?r?s?|wöchentliche?r?s?|monatliche?r?s?|jeden\s+(tag|morgen|abend|montag|dienstag|mittwoch|donnerstag|freitag|samstag|sonntag)|um\s+\d{1,2}\s*(uhr|:|h)|alle\s+\d+\s*(min|stund|sekund)|daily|hourly|weekly|every\s+(day|hour|morning|evening|night|\d+\s*min))\b/i,files:/\b(file|datei|document|dokument|pdf|http|download|upload)\b/i,infrastructure:/\b(proxmox|vm|container|docker|unifi|wifi|wlan|homeassistant|home.?assistant|smarthome|smart.?home|licht|light|schalter|switch)\b/i,identity:/\b(link|verknüpf|cross.?platform|identity|identität)\b/i,mcp:/\bmcp\b/i};u(Vl,"selectCategories");u(Kl,"filterSkills")});import Ii from"node:fs";import Yl from"node:path";var Tp,Jl,_p,Zl,Ep,bp,$p,Ql,br,xi=T(()=>{"use strict";zo();ps();Xl();Tp=15*60*1e3,Jl=50,_p=2,Zl=.85,Ep=1e5,bp=2e3,$p=.1,Ql=3,br=class{static{u(this,"MessagePipeline")}promptBuilder;llm;conversationManager;users;logger;skillRegistry;skillSandbox;securityManager;memoryRepo;speechTranscriber;inboxPath;embeddingService;activeLearning;memoryRetriever;maxHistoryMessages;documentProcessor;activeAgents=new Map;agentIdCounter=0;constructor(e){this.llm=e.llm,this.conversationManager=e.conversationManager,this.users=e.users,this.logger=e.logger,this.skillRegistry=e.skillRegistry,this.skillSandbox=e.skillSandbox,this.securityManager=e.securityManager,this.memoryRepo=e.memoryRepo,this.speechTranscriber=e.speechTranscriber,this.inboxPath=e.inboxPath,this.embeddingService=e.embeddingService,this.activeLearning=e.activeLearning,this.memoryRetriever=e.memoryRetriever,this.maxHistoryMessages=e.maxHistoryMessages??100,this.documentProcessor=e.documentProcessor,this.promptBuilder=new Qs}async process(e,t){let s=Date.now();this.logger.info({platform:e.platform,userId:e.userId,chatId:e.chatId},"Processing message");try{let{user:r,masterUserId:n,linkedPlatformUserIds:o,context:i}=Ke(this.users,{platformUserId:e.userId,platform:e.platform,chatId:e.chatId,chatType:e.chatType,userName:e.userName,displayName:e.displayName}),a=this.conversationManager.getOrCreateConversation(e.platform,e.chatId,r.id),c=this.conversationManager.getHistory(a.id,this.maxHistoryMessages);this.conversationManager.addMessage(a.id,"user",e.text);let d,m=this.isSyntheticLabel(e.text),p=e.attachments?.some(B=>B.type==="audio")??!1,g=m&&!p;if(this.memoryRetriever&&e.text&&!g)try{d=await this.memoryRetriever.retrieve(n,e.text,15,o)}catch(B){this.logger.debug({err:B},"Hybrid memory retrieval failed")}if(!d&&this.memoryRepo&&!g)try{let B=[n,...(o??[]).filter(Q=>Q!==n)];if(this.embeddingService&&e.text&&this.llm.supportsEmbeddings()){let Q=new Set;d=[];for(let se of B)for(let ee of await this.embeddingService.semanticSearch(se,e.text,10))Q.has(ee.key)||(Q.add(ee.key),d.push(ee));for(let se of B)for(let ee of this.memoryRepo.getRecentForPrompt(se,5))Q.has(ee.key)||(Q.add(ee.key),d.push(ee))}else{let Q=new Set;d=[];for(let se of B)for(let ee of this.memoryRepo.getRecentForPrompt(se,20))Q.has(ee.key)||(Q.add(ee.key),d.push(ee))}}catch(B){this.logger.debug({err:B},"Memory loading failed")}d&&d.length>0&&(d=this.applyMemoryBudget(d));let f;try{"getProfile"in this.users&&(f=this.users.getProfile(n),f&&!f.displayName&&(f.displayName=r.displayName??r.username))}catch(B){this.logger.debug({err:B},"Profile loading failed")}let h=i.timezone??Intl.DateTimeFormat().resolvedOptions().timeZone,_=this.skillRegistry?this.skillRegistry.getAll().map(B=>B.metadata):void 0,b=_;if(_&&e.text){let B=new Set(_.map(se=>se.category??"core")),Q=Vl(e.text,B);b=Kl(_,Q)}let I=b?this.promptBuilder.buildTools(b):void 0,C=this.promptBuilder.buildSystemPrompt({memories:d,skills:b,userProfile:f}),U=this.buildActiveAgentStatus();U&&(C+=`
821
821
 
822
822
  `+U);let x=this.promptBuilder.buildMessages(c),V=this.collapseRepeatedToolErrors(x),Te=await this.buildUserContent(e,t);V.push({role:"user",content:Te});let he=I?Ne(JSON.stringify(I)):0,le=1,re=this.trimToContextWindow(C,V,he,le),W,fe=0,ge=Date.now(),de="",ne=0,D=0,G=0,$e=[];for(t?.("Thinking...");;){fe>0&&this.compressToolLoop(re,C,he);try{W=await this.llm.complete({messages:re,system:C,tools:I&&I.length>0?I:void 0}),D+=W.usage?.inputTokens??0,G+=W.usage?.outputTokens??0}catch(ke){if((ke instanceof Error?ke.message:String(ke)).includes("prompt is too long")&&le>.3){le*=.5,this.logger.warn({budgetMultiplier:le},"Prompt too long, retrimming with reduced budget"),re=this.trimToContextWindow(C,V,he,le);continue}throw ke}if(!W.toolCalls||W.toolCalls.length===0)break;let B=Date.now()-ge;if(B>=Tp){let ke=Math.round(B/6e4);this.logger.warn({iteration:fe,elapsedMin:ke,pendingToolCalls:W.toolCalls.length},"Tool loop timeout reached"),W=await this.abortToolLoop(re,W,a.id,C,`Das Zeitlimit von ${ke} Minuten f\xFCr Tool-Aufrufe wurde erreicht.`);break}if(fe>=Jl){this.logger.warn({iteration:fe,pendingToolCalls:W.toolCalls.length},"Tool loop iteration cap reached"),W=await this.abortToolLoop(re,W,a.id,C,`Das Iterationslimit von ${Jl} Tool-Aufrufen wurde erreicht.`);break}fe++,this.logger.info({iteration:fe,toolCalls:W.toolCalls.length},"Processing tool calls");let Q=[];W.content&&Q.push({type:"text",text:W.content});for(let ke of W.toolCalls)Q.push({type:"tool_use",id:ke.id,name:ke.name,input:ke.input});re.push({role:"assistant",content:Q});let se=await this.executeToolCallsParallel(W.toolCalls,{...i,conversationId:a.id,timezone:h},t),ee=se.blocks;se.attachments.length>0&&$e.push(...se.attachments),this.conversationManager.addMessage(a.id,"assistant",W.content??"",JSON.stringify(W.toolCalls)),this.conversationManager.addMessage(a.id,"user","",JSON.stringify(ee));let xt=this.buildErrorSignature(ee);if(xt){if(xt===de?ne++:(ne=1,de=xt),ne>=_p){this.logger.warn({iteration:fe,consecutiveErrors:ne,errorSignature:xt},"Tool loop aborted: same error repeated consecutively"),W=await this.abortToolLoop(re,W,a.id,C,`Der gleiche Tool-Fehler ist ${ne}x hintereinander aufgetreten: "${de.slice(0,200)}". Erkl\xE4re dem User kurz was nicht funktioniert hat und schlage eine Alternative vor.`,!0);break}}else ne=0,de="";re.push({role:"user",content:ee}),t?.("Thinking...")}let Z=W.content;if(!Z)for(let B=re.length-1;B>=0;B--){let Q=re[B];if(Q.role==="assistant"&&Array.isArray(Q.content)){let se=Q.content.find(ee=>ee.type==="text");if(se&&"text"in se&&se.text){Z=se.text;break}}}Z||(Z="(no response)"),this.conversationManager.addMessage(a.id,"assistant",Z),this.activeLearning&&this.activeLearning.onMessageProcessed(n,e.text,Z);let gs=Date.now()-s;return this.logger.info({duration:gs,tokens:W.usage,totalTokens:{inputTokens:D,outputTokens:G},stopReason:W.stopReason,toolIterations:fe},"Message processed"),{text:Z,attachments:$e.length>0?$e:void 0}}catch(r){throw this.logger.error({err:r},"Failed to process message"),r}}async abortToolLoop(e,t,s,r,n,o=!1){if(!o){let c=[];t.content&&c.push({type:"text",text:t.content});for(let d of t.toolCalls)c.push({type:"tool_use",id:d.id,name:d.name,input:d.input});e.push({role:"assistant",content:c})}let i=t.toolCalls.map(c=>({type:"tool_result",tool_use_id:c.id,content:`Error: tool loop aborted \u2014 ${n}`,is_error:!0}));e.push({role:"user",content:i}),o||this.conversationManager.addMessage(s,"assistant",t.content??"",JSON.stringify(t.toolCalls)),this.conversationManager.addMessage(s,"user","",JSON.stringify(i));let a=e[e.length-1];return a&&a.role==="user"&&Array.isArray(a.content)?a.content.push({type:"text",text:`[System: ${n} Fasse dem User kurz zusammen was du bisher geschafft hast und was noch offen ist.]`}):e.push({role:"user",content:`[System: ${n} Fasse dem User kurz zusammen was du bisher geschafft hast und was noch offen ist.]`}),await this.llm.complete({messages:e,system:r})}buildErrorSignature(e){let t=[];for(let s of e)s.type==="tool_result"&&s.is_error&&t.push(s.content);return t.length>0?t.join("|"):""}collapseRepeatedToolErrors(e){let t=[],s=0;for(;s<e.length;){let r=e[s];if(r.role==="assistant"&&Array.isArray(r.content)&&r.content.some(n=>n.type==="tool_use")){let n=s+1<e.length?e[s+1]:null;if(n&&n.role==="user"&&Array.isArray(n.content)&&n.content.every(o=>o.type==="tool_result"&&o.is_error)){let o=this.toolPairSignature(r,n),i=1,a=s+2;for(;a+1<e.length;){let c=e[a],d=e[a+1];if(c.role==="assistant"&&d?.role==="user"&&this.toolPairSignature(c,d)===o)i++,a+=2;else break}if(i>1){t.push(r),t.push(n),t.push({role:"user",content:`[System: The above tool error repeated ${i} times with identical input. The loop was aborted.]`}),s=a;continue}}}t.push(r),s++}return t}toolPairSignature(e,t){let s=Array.isArray(e.content)?e.content.filter(n=>n.type==="tool_use").map(n=>`${n.name}:${JSON.stringify(n.input)}`).join(","):"",r=Array.isArray(t.content)?t.content.filter(n=>n.type==="tool_result").map(n=>n.content).join(","):"";return`${s}|${r}`}async executeToolCallsParallel(e,t,s){let r=[],n=u((m,p)=>{let g=p.content;if(p.attachments&&p.attachments.length>0){r.push(...p.attachments);let f=p.attachments.map(h=>h.fileName).join(", ");g+=`
823
823
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@madh-io/alfred-ai",
3
- "version": "0.10.34",
3
+ "version": "0.10.36",
4
4
  "description": "Alfred — Personal AI Assistant across Telegram, Discord, WhatsApp, Matrix & Signal",
5
5
  "type": "module",
6
6
  "bin": {