@madh-io/alfred-ai 0.10.16 → 0.10.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundle/index.js +4 -3
- package/package.json +1 -1
package/bundle/index.js
CHANGED
|
@@ -381,6 +381,7 @@ var ma=Object.defineProperty;var u=(c,e)=>ma(c,"name",{value:e,configurable:!0})
|
|
|
381
381
|
- Be concise. No filler text, no unnecessary explanations.
|
|
382
382
|
- If a tool fails or is denied, explain why and try an alternative approach.
|
|
383
383
|
- **If a tool call fails with the same error twice, STOP.** Tell the user what went wrong and ask how to proceed. Do NOT retry the same call.
|
|
384
|
+
- **If a delegate sub-agent fails or returns incomplete results, do NOT re-delegate the same task.** Analyze the failure, fix the issue yourself, and continue directly.
|
|
384
385
|
|
|
385
386
|
## Follow-ups and corrections
|
|
386
387
|
- When the user refers back to a previous request or corrects you, **reconnect to the original task**. Don't start fresh \u2014 continue where you left off.
|
|
@@ -409,7 +410,7 @@ For complex tasks, work through multiple steps:
|
|
|
409
410
|
|
|
410
411
|
## Available tools
|
|
411
412
|
`;for(let h of s)a+=`- **${h.name}** (${h.riskLevel}): ${h.description}
|
|
412
|
-
`;s.some(h=>h.name==="code_sandbox")&&(a+="\n## File generation (PDF, HTML, images, etc.)\nTo generate and send a file to the user:\n1. Use `code_sandbox` to run code that creates the file (e.g. pdfkit for PDF, HTML generation, etc.)\n2. The sandbox **automatically collects all files** written to the working directory and sends them as attachments to the user.\n3. Do NOT use `file send` afterwards \u2014 the files are already delivered. Using `file send` on sandbox-generated files will fail because the sandbox runs in an isolated temp directory.\n"),s.some(h=>h.name==="code_agent")&&(a+='\n## Code agent delegation\nWhen the user asks you to **write code, edit files, fix bugs, refactor, implement features, or perform any coding task
|
|
413
|
+
`;s.some(h=>h.name==="code_sandbox")&&(a+="\n## File generation (PDF, HTML, images, etc.)\nTo generate and send a file to the user:\n1. Use `code_sandbox` to run code that creates the file (e.g. pdfkit for PDF, HTML generation, etc.)\n2. The sandbox **automatically collects all files** written to the working directory and sends them as attachments to the user.\n3. Do NOT use `file send` afterwards \u2014 the files are already delivered. Using `file send` on sandbox-generated files will fail because the sandbox runs in an isolated temp directory.\n"),s.some(h=>h.name==="code_agent")&&(a+='\n## Code agent delegation\nWhen the user asks you to **write code, edit files, fix bugs, refactor, implement features, or perform any coding task in a repository**, delegate to the `code_agent` tool. You are an orchestrator, not a coder.\n\n- For **single, focused tasks**: use `code_agent` with `action: "run"` and pick the best agent.\n- For **complex, multi-step tasks**: use `code_agent` with `action: "orchestrate"` \u2014 the system will decompose the task, run agents in parallel, and validate results.\n- Add `git: true` when the user wants the changes committed, pushed, and a PR/MR created.\n- Use `action: "list_agents"` if you\'re unsure which agents are available.\n\n**Do NOT delegate to code_agent** when the task requires your own data or tools (documents, memories, emails, todos, calendar, etc.). For these tasks, use your tools directly \u2014 the code agent has no access to your skills or data.\n\n## Data-to-file workflow\nWhen the user asks to **collect data and produce a file** (e.g. "list all invoices in an Excel"):\n1. **Gather data** using your own tools first (document search/summarize, file list, email, etc.)\n2. **Generate the file** using `code_sandbox` \u2014 pass the collected data as variables in the code, then write the output file (Excel via exceljs, PDF via pdfkit, CSV, etc.)\n3. Do NOT try to do both steps inside code_sandbox \u2014 it cannot access your documents or skills.'),s.some(h=>h.name==="watch")&&s.some(h=>h.name==="scheduled_task")&&(a+='\n## Automation: watch vs. scheduled_task\n- **"Alert me when X happens"** \u2192 use `watch` (polls a skill, evaluates condition, no LLM cost per check)\n- **"Do X every day at 9 AM"** / **"Check X and report"** \u2192 use `scheduled_task` (time-based, can use LLM via prompt_template)\n- For infrastructure monitoring on a schedule, use `scheduled_task` with `prompt_template` that instructs you to run the `monitor` tool and report only problems.')}if(r&&(a+=`
|
|
413
414
|
|
|
414
415
|
## User profile`,r.displayName&&(a+=`
|
|
415
416
|
- Name: ${r.displayName}`),r.timezone&&(a+=`
|
|
@@ -587,7 +588,7 @@ ${l}`}}summarize(e){let t=e.document_id;if(!t||typeof t!="string")return{success
|
|
|
587
588
|
|
|
588
589
|
[... truncated]`:n;return{success:!0,data:{document:s,content:a,totalChunks:r.length,truncated:i},display:`Document: **${s.filename}** (${r.length} chunks, ${s.sizeBytes} bytes)
|
|
589
590
|
|
|
590
|
-
${a}`}}list(e,t){let s=e.limit||50,r=z(t),n=new Set,o=[];for(let l of r)for(let d of this.docRepo.listByUser(l))n.has(d.id)||(n.add(d.id),o.push(d));let i=o.slice(0,s);if(i.length===0)return{success:!0,data:[],display:"No documents found."};let a=i.map(l=>`- **${l.filename}**
|
|
591
|
+
${a}`}}list(e,t){let s=e.limit||50,r=z(t),n=new Set,o=[];for(let l of r)for(let d of this.docRepo.listByUser(l))n.has(d.id)||(n.add(d.id),o.push(d));let i=o.slice(0,s);if(i.length===0)return{success:!0,data:[],display:"No documents found."};let a=i.map(l=>`- **${l.filename}** [id=${l.id}] \u2014 ${l.mimeType}, ${l.chunkCount} chunks, ${l.sizeBytes} bytes`).join(`
|
|
591
592
|
`);return{success:!0,data:i,display:`${i.length} document(s):
|
|
592
593
|
${a}`}}deleteDoc(e){let t=e.document_id;if(!t||typeof t!="string")return{success:!1,error:'Missing required field "document_id" for delete action'};let s=this.docRepo.getDocument(t);return s?(this.docRepo.deleteDocument(t),{success:!0,data:{documentId:t},display:`Document "${s.filename}" deleted.`}):{success:!1,error:`Document "${t}" not found`}}}});var ts,Bc=_(()=>{"use strict";P();ts=class extends A{static{u(this,"TTSSkill")}synthesizer;metadata={name:"text_to_speech",category:"media",description:"Send a voice/audio message to the user. You MUST use this tool whenever the user asks you to respond as a voice message, speak, or reply with audio. Pass the full response text \u2014 it will be converted to speech and delivered as a playable voice message.",riskLevel:"read",version:"1.0.0",inputSchema:{type:"object",properties:{text:{type:"string",description:"The text to convert to speech"}},required:["text"]}};constructor(e){super(),this.synthesizer=e}async execute(e,t){let s=e.text;if(!s)return{success:!1,error:"No text provided for speech synthesis."};try{return{success:!0,display:"Voice message sent.",attachments:[{fileName:"voice.ogg",data:await this.synthesizer.synthesize(s),mimeType:"audio/ogg"}]}}catch(r){return{success:!1,error:`Speech synthesis failed: ${r instanceof Error?r.message:String(r)}`}}}}});var ss,Hc=_(()=>{"use strict";P();ss=class extends A{static{u(this,"ImageGenerateSkill")}generator;metadata={name:"image_generate",category:"media",description:"Generate an image from a text description. Use this tool when the user asks you to create, generate, draw, or design an image or picture. Returns the generated image that will be sent to the user.",riskLevel:"read",version:"1.0.0",timeoutMs:12e4,inputSchema:{type:"object",properties:{prompt:{type:"string",description:"Detailed description of the image to generate. Be specific about style, composition, colors, and subject matter."},model:{type:"string",description:"Optional model to use (e.g. gpt-image-1, gpt-image-1-mini, gemini-2.0-flash-exp). Uses provider default if omitted."},size:{type:"string",enum:["1024x1024","1536x1024","1024x1536"],description:"Image dimensions. 1024x1024 (square, default), 1536x1024 (landscape), 1024x1536 (portrait)."},quality:{type:"string",enum:["low","medium","high"],description:"Image quality level. Higher quality takes longer and costs more."}},required:["prompt"]}};constructor(e){super(),this.generator=e}async execute(e,t){let s=e.prompt;if(!s)return{success:!1,error:"No prompt provided for image generation."};try{let r=await this.generator.generate(s,{model:e.model,size:e.size,quality:e.quality});return{success:!0,display:"Image generated.",attachments:[{fileName:"image.png",data:r.data,mimeType:r.mimeType}]}}catch(r){return{success:!1,error:`Image generation failed: ${r instanceof Error?r.message:String(r)}`}}}}});function ie(c){return c==null?"-":c<1024?`${c} B`:c<1024**2?`${(c/1024).toFixed(1)} KiB`:c<1024**3?`${(c/1024**2).toFixed(1)} MiB`:`${(c/1024**3).toFixed(2)} GiB`}function lr(c){return c==null?"-":`${(c*100).toFixed(1)}%`}function cn(c){if(!c)return"-";let e=Math.floor(c/86400),t=Math.floor(c%86400/3600),s=Math.floor(c%3600/60),r=[];return e&&r.push(`${e}d`),t&&r.push(`${t}h`),r.push(`${s}m`),r.join(" ")}var ln,qc=_(()=>{"use strict";P();u(ie,"bytes");u(lr,"pct");u(cn,"uptimeStr");ln=class c extends A{static{u(this,"ProxmoxSkill")}metadata={name:"proxmox",category:"infrastructure",description:'Manage Proxmox VE virtual machines, containers, and cluster. Use action "list_vms" to see VMs, "start_vm"/"shutdown_vm" to control them, "cluster_status" for health, "create_snapshot" for backups.',riskLevel:"write",version:"1.0.0",inputSchema:{type:"object",properties:{action:{type:"string",enum:["cluster_status","list_nodes","node_stats","list_vms","vm_status","list_snapshots","list_storage","list_tasks","task_status","start_vm","shutdown_vm","reboot_vm","suspend_vm","resume_vm","create_snapshot","backup_vm","migrate_vm","stop_vm","delete_snapshot","rollback_snapshot"],description:"The Proxmox action to perform"},vmid:{type:"number",description:"Virtual machine / container ID"},node:{type:"string",description:"Proxmox node name (optional \u2014 resolved automatically when omitted)"},type:{type:"string",enum:["qemu","lxc"],description:"VM type filter for list_vms (default: both)"},name:{type:"string",description:"Snapshot name (for create/delete/rollback_snapshot)"},description:{type:"string",description:"Snapshot description (optional)"},target:{type:"string",description:"Target node for migration"},storage:{type:"string",description:"Storage target for backup_vm"},upid:{type:"string",description:"Task UPID for task_status"}},required:["action"]}};config;vmCache=null;static VM_CACHE_TTL=3e4;constructor(e){super(),this.config=e}async execute(e,t){let s=e.action;if(!s)return{success:!1,error:'Missing required field "action"'};try{switch(s){case"cluster_status":return await this.clusterStatus();case"list_nodes":return await this.listNodes();case"node_stats":return await this.nodeStats(e.node);case"list_vms":return await this.listVms(e.node,e.type);case"vm_status":return await this.vmStatus(e.vmid,e.node);case"list_snapshots":return await this.listSnapshots(e.vmid,e.node);case"list_storage":return await this.listStorage(e.node);case"list_tasks":return await this.listTasks(e.node);case"task_status":return await this.taskStatus(e.upid);case"start_vm":return await this.vmPowerAction("start",e);case"shutdown_vm":return await this.vmPowerAction("shutdown",e);case"reboot_vm":return await this.vmPowerAction("reboot",e);case"suspend_vm":return await this.vmPowerAction("suspend",e);case"resume_vm":return await this.vmPowerAction("resume",e);case"stop_vm":return await this.vmPowerAction("stop",e);case"create_snapshot":return await this.createSnapshot(e);case"backup_vm":return await this.backupVm(e);case"migrate_vm":return await this.migrateVm(e);case"delete_snapshot":return await this.deleteSnapshot(e);case"rollback_snapshot":return await this.rollbackSnapshot(e);default:return{success:!1,error:`Unknown action "${s}"`}}}catch(r){return{success:!1,error:`Proxmox API error: ${r instanceof Error?r.message:String(r)}. Check baseUrl and connectivity.`}}}async api(e,t,s){let r=`${this.config.baseUrl}/api2/json${t}`,n={Authorization:`PVEAPIToken=${this.config.tokenId}=${this.config.tokenSecret}`},o={method:e,headers:n};s&&e!=="GET"&&(n["Content-Type"]="application/json",o.body=JSON.stringify(s));let i=this.config.verifyTls===!1,a=process.env.NODE_TLS_REJECT_UNAUTHORIZED;i&&(process.env.NODE_TLS_REJECT_UNAUTHORIZED="0");let l;try{l=await fetch(r,o)}finally{i&&(a===void 0?delete process.env.NODE_TLS_REJECT_UNAUTHORIZED:process.env.NODE_TLS_REJECT_UNAUTHORIZED=a)}if(!l.ok){let m="";try{m=(await l.text()).slice(0,500)}catch{}throw new Error(`HTTP ${l.status} ${l.statusText} \u2014 ${m}`)}return(await l.json()).data}async get(e){return this.api("GET",e)}async post(e,t){return this.api("POST",e,t)}async del(e){return this.api("DELETE",e)}async resolveVm(e,t){if(t)try{return await this.get(`/nodes/${t}/qemu/${e}/status/current`),{node:t,type:"qemu"}}catch{try{return await this.get(`/nodes/${t}/lxc/${e}/status/current`),{node:t,type:"lxc"}}catch{throw new Error(`VM ${e} not found on node "${t}"`)}}let r=(await this.getAllVms()).find(n=>n.vmid===e);if(!r)throw new Error(`VM ${e} not found on any node. Use "list_vms" to see available VMs.`);return{node:r.node,type:r.type}}async getAllVms(){let e=Date.now();if(this.vmCache&&e-this.vmCache.ts<c.VM_CACHE_TTL)return this.vmCache.entries;let t=await this.get("/nodes"),s=[];for(let r of t){let[n,o]=await Promise.all([this.get(`/nodes/${r.node}/qemu`).catch(()=>[]),this.get(`/nodes/${r.node}/lxc`).catch(()=>[])]);for(let i of n)s.push({...i,node:r.node,type:"qemu"});for(let i of o)s.push({...i,node:r.node,type:"lxc"})}return this.vmCache={entries:s,ts:e},s}async clusterStatus(){let e=await this.get("/cluster/status"),t=["## Cluster Status",""],s=e.find(n=>n.type==="cluster");s&&(t.push(`**Cluster:** ${s.name}`),t.push(`**Quorum:** ${s.quorate?"Yes":"No"}`),t.push(`**Nodes:** ${s.nodes??"-"}`),t.push(`**Version:** ${s.version??"-"}`),t.push(""));let r=e.filter(n=>n.type==="node");if(r.length){t.push("| Node | Online | Level | ID |"),t.push("|------|--------|-------|----|");for(let n of r)t.push(`| ${n.name} | ${n.online?"Yes":"**No**"} | ${n.level??"-"} | ${n.nodeid??"-"} |`)}return{success:!0,data:e,display:t.join(`
|
|
593
594
|
`)}}async listNodes(){let e=await this.get("/nodes"),t=["## Nodes","","| Node | Status | CPU | RAM Used / Total | Uptime |"];t.push("|------|--------|-----|------------------|--------|");for(let s of e){let r=typeof s.cpu=="number"?lr(s.cpu):"-",n=ie(s.mem),o=ie(s.maxmem);t.push(`| ${s.node} | ${s.status} | ${r} | ${n} / ${o} | ${cn(s.uptime)} |`)}return{success:!0,data:e,display:t.join(`
|
|
@@ -797,7 +798,7 @@ ${e.allModifiedFiles.map(r=>`- ${r}`).join(`
|
|
|
797
798
|
|
|
798
799
|
**Git:**
|
|
799
800
|
${s.join(`
|
|
800
|
-
`)}`:"";return{...t,data:{...t.data,git:{branch:r.branch,commit:r.commit,pullRequest:r.pullRequest,warnings:r.warnings}},display:(t.display??"")+n}}}});var Ml=_(()=>{"use strict";Dl();vn();Ti();hi();yi()});var J={};oe(J,{ActivityTracker:()=>gt,BMWSkill:()=>Tn,BackgroundTaskSkill:()=>Yt,BrowserSkill:()=>Vt,CalculatorSkill:()=>Nt,CalendarProvider:()=>Le,CalendarSkill:()=>yt,ClipboardSkill:()=>Wt,CodeAgentSkill:()=>gr,CodeExecutionSkill:()=>cr,CodeExecutor:()=>_t,ConfigureSkill:()=>as,ContactsProvider:()=>Ne,ContactsSkill:()=>ur,CrossPlatformSkill:()=>Xt,DelegateSkill:()=>Bt,DockerSkill:()=>gn,DocumentSkill:()=>es,EmailProvider:()=>We,EmailSkill:()=>Je,EnergyPriceSkill:()=>En,FileSkill:()=>qt,ForgeClient:()=>bt,HomeAssistantSkill:()=>un,HttpSkill:()=>Ht,ImageGenerateSkill:()=>ss,MCPClient:()=>wt,MCPManager:()=>ar,MCPSkillAdapter:()=>Tt,MemorySkill:()=>jt,MicrosoftTodoSkill:()=>$n,MonitorSkill:()=>bn,NoteSkill:()=>Pt,PluginLoader:()=>en,ProfileSkill:()=>Kt,ProxmoxSkill:()=>ln,ReminderSkill:()=>Ot,RoutingSkill:()=>_n,ScheduledTaskSkill:()=>Jt,ScreenshotSkill:()=>Gt,ShellSkill:()=>Ft,Skill:()=>A,SkillRegistry:()=>Ct,SkillSandbox:()=>Lt,SystemInfoSkill:()=>Dt,TTSSkill:()=>ts,TodoSkill:()=>rs,TransitSkill:()=>os,UniFiSkill:()=>dn,WatchSkill:()=>cs,WeatherSkill:()=>Ut,WebSearchSkill:()=>Mt,allUserIds:()=>z,createCalendarProvider:()=>ir,createContactsProvider:()=>ti,createEmailProvider:()=>rr,createForgeClient:()=>us,effectiveUserId:()=>te,gitAddRemote:()=>hr,gitGetRemoteUrl:()=>ls,gitInitRepo:()=>pr,orchestrate:()=>$t,orchestrateWithGit:()=>fr,parseRemoteUrl:()=>ds});var X=_(()=>{"use strict";P();Ue();Qa();ec();Bo();tc();sc();rc();nc();oc();ic();ac();dc();uc();mc();gc();wc();_c();Ec();$c();vc();Sc();Lc();Nc();Dc();Mc();Pc();Fc();jc();Bc();Hc();qc();zc();Gc();Zc();Qc();nl();ul();ml();Tl();_l();$l();kl();vl();Al();Ml()});var yr,_i=_(()=>{"use strict";yr=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 Ge(c,e){let t;if(e.platformUserId)t=c.findOrCreate(e.platform,e.platformUserId,e.userName,e.displayName);else if(e.userId)t=c.findById(e.userId)??c.findOrCreate(e.platform,e.userId);else throw new Error("ContextSource must provide either platformUserId or userId");let s="getMasterUserId"in c?c.getMasterUserId(t.id):t.id,r=[];"getLinkedUsers"in c&&(r=c.getLinkedUsers(s).map(a=>a.platformUserId));let n;try{"getProfile"in c?n=c.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 ms=_(()=>{"use strict";u(Ge,"buildSkillContext")});function Ol(c,e){let t=new Set(["core"]),s=!1;for(let[r,n]of Object.entries(ip))e.has(r)&&n.test(c)&&(t.add(r),s=!0);if(!s)for(let r of e)t.add(r);return t}function Pl(c,e){return c.filter(t=>e.has(t.category??"core"))}var ip,Ul=_(()=>{"use strict";ip={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)\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(Ol,"selectCategories");u(Pl,"filterSkills")});import Ei from"node:fs";import Fl from"node:path";var ap,jl,cp,Bl,lp,dp,up,Hl,wr,bi=_(()=>{"use strict";Fo();ms();Ul();ap=15*60*1e3,jl=50,cp=2,Bl=.85,lp=1e5,dp=2e3,up=.1,Hl=3,wr=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 Zs}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}=Ge(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),l=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,y=m&&!p;if(this.memoryRetriever&&e.text&&!y)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&&!y)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,T=this.skillRegistry?this.skillRegistry.getAll().map(B=>B.metadata):void 0,$=T;if(T&&e.text){let B=new Set(T.map(se=>se.category??"core")),Q=Ol(e.text,B);$=Pl(T,Q)}let I=$?this.promptBuilder.buildTools($):void 0,x=this.promptBuilder.buildSystemPrompt({memories:d,skills:$,userProfile:f}),U=this.buildActiveAgentStatus();U&&(x+=`
|
|
801
|
+
`)}`:"";return{...t,data:{...t.data,git:{branch:r.branch,commit:r.commit,pullRequest:r.pullRequest,warnings:r.warnings}},display:(t.display??"")+n}}}});var Ml=_(()=>{"use strict";Dl();vn();Ti();hi();yi()});var J={};oe(J,{ActivityTracker:()=>gt,BMWSkill:()=>Tn,BackgroundTaskSkill:()=>Yt,BrowserSkill:()=>Vt,CalculatorSkill:()=>Nt,CalendarProvider:()=>Le,CalendarSkill:()=>yt,ClipboardSkill:()=>Wt,CodeAgentSkill:()=>gr,CodeExecutionSkill:()=>cr,CodeExecutor:()=>_t,ConfigureSkill:()=>as,ContactsProvider:()=>Ne,ContactsSkill:()=>ur,CrossPlatformSkill:()=>Xt,DelegateSkill:()=>Bt,DockerSkill:()=>gn,DocumentSkill:()=>es,EmailProvider:()=>We,EmailSkill:()=>Je,EnergyPriceSkill:()=>En,FileSkill:()=>qt,ForgeClient:()=>bt,HomeAssistantSkill:()=>un,HttpSkill:()=>Ht,ImageGenerateSkill:()=>ss,MCPClient:()=>wt,MCPManager:()=>ar,MCPSkillAdapter:()=>Tt,MemorySkill:()=>jt,MicrosoftTodoSkill:()=>$n,MonitorSkill:()=>bn,NoteSkill:()=>Pt,PluginLoader:()=>en,ProfileSkill:()=>Kt,ProxmoxSkill:()=>ln,ReminderSkill:()=>Ot,RoutingSkill:()=>_n,ScheduledTaskSkill:()=>Jt,ScreenshotSkill:()=>Gt,ShellSkill:()=>Ft,Skill:()=>A,SkillRegistry:()=>Ct,SkillSandbox:()=>Lt,SystemInfoSkill:()=>Dt,TTSSkill:()=>ts,TodoSkill:()=>rs,TransitSkill:()=>os,UniFiSkill:()=>dn,WatchSkill:()=>cs,WeatherSkill:()=>Ut,WebSearchSkill:()=>Mt,allUserIds:()=>z,createCalendarProvider:()=>ir,createContactsProvider:()=>ti,createEmailProvider:()=>rr,createForgeClient:()=>us,effectiveUserId:()=>te,gitAddRemote:()=>hr,gitGetRemoteUrl:()=>ls,gitInitRepo:()=>pr,orchestrate:()=>$t,orchestrateWithGit:()=>fr,parseRemoteUrl:()=>ds});var X=_(()=>{"use strict";P();Ue();Qa();ec();Bo();tc();sc();rc();nc();oc();ic();ac();dc();uc();mc();gc();wc();_c();Ec();$c();vc();Sc();Lc();Nc();Dc();Mc();Pc();Fc();jc();Bc();Hc();qc();zc();Gc();Zc();Qc();nl();ul();ml();Tl();_l();$l();kl();vl();Al();Ml()});var yr,_i=_(()=>{"use strict";yr=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 Ge(c,e){let t;if(e.platformUserId)t=c.findOrCreate(e.platform,e.platformUserId,e.userName,e.displayName);else if(e.userId)t=c.findById(e.userId)??c.findOrCreate(e.platform,e.userId);else throw new Error("ContextSource must provide either platformUserId or userId");let s="getMasterUserId"in c?c.getMasterUserId(t.id):t.id,r=[];"getLinkedUsers"in c&&(r=c.getLinkedUsers(s).map(a=>a.platformUserId));let n;try{"getProfile"in c?n=c.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 ms=_(()=>{"use strict";u(Ge,"buildSkillContext")});function Ol(c,e){let t=new Set(["core"]),s=!1;for(let[r,n]of Object.entries(ip))e.has(r)&&n.test(c)&&(t.add(r),s=!0);if(!s)for(let r of e)t.add(r);return t}function Pl(c,e){return c.filter(t=>e.has(t.category??"core"))}var ip,Ul=_(()=>{"use strict";ip={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(Ol,"selectCategories");u(Pl,"filterSkills")});import Ei from"node:fs";import Fl from"node:path";var ap,jl,cp,Bl,lp,dp,up,Hl,wr,bi=_(()=>{"use strict";Fo();ms();Ul();ap=15*60*1e3,jl=50,cp=2,Bl=.85,lp=1e5,dp=2e3,up=.1,Hl=3,wr=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 Zs}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}=Ge(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),l=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,y=m&&!p;if(this.memoryRetriever&&e.text&&!y)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&&!y)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,T=this.skillRegistry?this.skillRegistry.getAll().map(B=>B.metadata):void 0,$=T;if(T&&e.text){let B=new Set(T.map(se=>se.category??"core")),Q=Ol(e.text,B);$=Pl(T,Q)}let I=$?this.promptBuilder.buildTools($):void 0,x=this.promptBuilder.buildSystemPrompt({memories:d,skills:$,userProfile:f}),U=this.buildActiveAgentStatus();U&&(x+=`
|
|
801
802
|
|
|
802
803
|
`+U);let C=this.promptBuilder.buildMessages(l),Z=this.collapseRepeatedToolErrors(C),Fe=await this.buildUserContent(e,t);Z.push({role:"user",content:Fe});let Se=I?Ce(JSON.stringify(I)):0,Me=1,ce=this.trimToContextWindow(x,Z,Se,Me),W,pe=0,he=Date.now(),le="",re=0,L=0,G=0,_e=[];for(t?.("Thinking...");;){pe>0&&this.compressToolLoop(ce,x,Se);try{W=await this.llm.complete({messages:ce,system:x,tools:I&&I.length>0?I:void 0}),L+=W.usage?.inputTokens??0,G+=W.usage?.outputTokens??0}catch(Ee){if((Ee instanceof Error?Ee.message:String(Ee)).includes("prompt is too long")&&Me>.3){Me*=.5,this.logger.warn({budgetMultiplier:Me},"Prompt too long, retrimming with reduced budget"),ce=this.trimToContextWindow(x,Z,Se,Me);continue}throw Ee}if(!W.toolCalls||W.toolCalls.length===0)break;let B=Date.now()-he;if(B>=ap){let Ee=Math.round(B/6e4);this.logger.warn({iteration:pe,elapsedMin:Ee,pendingToolCalls:W.toolCalls.length},"Tool loop timeout reached"),W=await this.abortToolLoop(ce,W,a.id,x,`Das Zeitlimit von ${Ee} Minuten f\xFCr Tool-Aufrufe wurde erreicht.`);break}if(pe>=jl){this.logger.warn({iteration:pe,pendingToolCalls:W.toolCalls.length},"Tool loop iteration cap reached"),W=await this.abortToolLoop(ce,W,a.id,x,`Das Iterationslimit von ${jl} Tool-Aufrufen wurde erreicht.`);break}pe++,this.logger.info({iteration:pe,toolCalls:W.toolCalls.length},"Processing tool calls");let Q=[];W.content&&Q.push({type:"text",text:W.content});for(let Ee of W.toolCalls)Q.push({type:"tool_use",id:Ee.id,name:Ee.name,input:Ee.input});ce.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 St=this.buildErrorSignature(ee);if(St){if(St===le?re++:(re=1,le=St),re>=cp){this.logger.warn({iteration:pe,consecutiveErrors:re,errorSignature:St},"Tool loop aborted: same error repeated consecutively"),W=await this.abortToolLoop(ce,W,a.id,x,`Der gleiche Tool-Fehler ist ${re}x hintereinander aufgetreten: "${le.slice(0,200)}". Erkl\xE4re dem User kurz was nicht funktioniert hat und schlage eine Alternative vor.`,!0);break}}else re=0,le="";ce.push({role:"user",content:ee}),t?.("Thinking...")}let Y=W.content;if(!Y)for(let B=ce.length-1;B>=0;B--){let Q=ce[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){Y=se.text;break}}}Y||(Y="(no response)"),this.conversationManager.addMessage(a.id,"assistant",Y),this.activeLearning&&this.activeLearning.onMessageProcessed(n,e.text,Y);let fs=Date.now()-s;return this.logger.info({duration:fs,tokens:W.usage,totalTokens:{inputTokens:L,outputTokens:G},stopReason:W.stopReason,toolIterations:pe},"Message processed"),{text:Y,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 l=[];t.content&&l.push({type:"text",text:t.content});for(let d of t.toolCalls)l.push({type:"tool_use",id:d.id,name:d.name,input:d.input});e.push({role:"assistant",content:l})}let i=t.toolCalls.map(l=>({type:"tool_result",tool_use_id:l.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 l=e[a],d=e[a+1];if(l.role==="assistant"&&d?.role==="user"&&this.toolPairSignature(l,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((a,l)=>{let d=l.content;if(l.attachments&&l.attachments.length>0){r.push(...l.attachments);let m=l.attachments.map(p=>p.fileName).join(", ");d+=`
|
|
803
804
|
|