@madh-io/alfred-ai 0.9.5 → 0.9.6
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 +29 -22
- package/package.json +1 -1
package/bundle/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var Rr=Object.defineProperty;var d=(c,e)=>Rr(c,"name",{value:e,configurable:!0});var f=(c,e)=>()=>(c&&(e=c(c=0)),e);var V=(c,e)=>{for(var t in e)Rr(c,t,{get:e[t],enumerable:!0})};import{z as g}from"zod";var Ar,Lr,Mr,Nr,Dr,Or,Cr,Ur,de,zo,
|
|
2
|
+
var Rr=Object.defineProperty;var d=(c,e)=>Rr(c,"name",{value:e,configurable:!0});var f=(c,e)=>()=>(c&&(e=c(c=0)),e);var V=(c,e)=>{for(var t in e)Rr(c,t,{get:e[t],enumerable:!0})};import{z as g}from"zod";var Ar,Lr,Mr,Nr,Dr,Or,Cr,Ur,de,Xo,zo,qo,Ko,Vo,Go,Yo,Jo,Zo,Qo,ei,ti,si,xs,Is=f(()=>{"use strict";Ar=g.object({token:g.string().optional(),enabled:g.boolean()}),Lr=g.object({token:g.string().optional(),enabled:g.boolean()}),Mr=g.object({enabled:g.boolean(),dataPath:g.string()}),Nr=g.object({homeserverUrl:g.string(),accessToken:g.string().optional(),userId:g.string().optional(),enabled:g.boolean()}),Dr=g.object({apiUrl:g.string(),phoneNumber:g.string().optional(),enabled:g.boolean()}),Or=g.object({path:g.string()}),Cr=g.object({level:g.enum(["trace","debug","info","warn","error","fatal"]),pretty:g.boolean(),auditLogPath:g.string().optional()}),Ur=g.object({rulesPath:g.string(),defaultEffect:g.enum(["allow","deny"]),ownerUserId:g.string().optional()}),de=g.object({provider:g.enum(["anthropic","openai","openrouter","ollama","openwebui"]),apiKey:g.string().optional(),baseUrl:g.string().optional(),model:g.string(),temperature:g.number().optional(),maxTokens:g.number().optional()}),Xo=g.object({default:de,strong:de.optional(),fast:de.optional(),embeddings:de.optional(),local:de.optional()}),zo=g.union([de,Xo]),qo=g.object({provider:g.enum(["brave","searxng","tavily","duckduckgo"]),apiKey:g.string().optional(),baseUrl:g.string().optional()}),Ko=g.object({imap:g.object({host:g.string(),port:g.number(),secure:g.boolean()}),smtp:g.object({host:g.string(),port:g.number(),secure:g.boolean()}),auth:g.object({user:g.string(),pass:g.string()})}),Vo=g.object({provider:g.enum(["openai","groq"]),apiKey:g.string(),baseUrl:g.string().optional()}),Go=g.object({serverUrl:g.string(),username:g.string(),password:g.string()}),Yo=g.object({clientId:g.string(),clientSecret:g.string(),refreshToken:g.string()}),Jo=g.object({clientId:g.string(),clientSecret:g.string(),tenantId:g.string(),refreshToken:g.string()}),Zo=g.object({provider:g.enum(["caldav","google","microsoft"]),caldav:Go.optional(),google:Yo.optional(),microsoft:Jo.optional()}),Qo=g.object({name:g.string(),command:g.string().optional(),args:g.array(g.string()).optional(),env:g.record(g.string()).optional(),url:g.string().optional()}),ei=g.object({servers:g.array(Qo)}),ti=g.object({enabled:g.boolean(),allowedLanguages:g.array(g.enum(["javascript","python"])).optional(),maxTimeoutMs:g.number().optional(),allowNetwork:g.boolean().optional()}),si=g.object({enabled:g.boolean().optional(),minMessageLength:g.number().optional(),minConfidence:g.number().min(0).max(1).optional(),maxExtractionsPerMinute:g.number().optional()}),xs=g.object({name:g.string(),telegram:Ar,discord:Lr.optional(),whatsapp:Mr.optional(),matrix:Nr.optional(),signal:Dr.optional(),llm:zo,storage:Or,logger:Cr,security:Ur,search:qo.optional(),email:Ko.optional(),speech:Vo.optional(),calendar:Zo.optional(),mcp:ei.optional(),codeSandbox:ti.optional(),activeLearning:si.optional()})});var $s,Rs=f(()=>{"use strict";$s={name:"Alfred",telegram:{token:"",enabled:!1},discord:{token:"",enabled:!1},whatsapp:{enabled:!1,dataPath:"./data/whatsapp"},matrix:{homeserverUrl:"https://matrix.org",accessToken:"",userId:"",enabled:!1},signal:{apiUrl:"http://localhost:8080",phoneNumber:"",enabled:!1},llm:{provider:"anthropic",model:"claude-sonnet-4-20250514",temperature:.7,maxTokens:4096},storage:{path:"./data/alfred.db"},logger:{level:"info",pretty:!0},security:{rulesPath:"./config/rules",defaultEffect:"deny"}}});import Pr from"node:fs";import ri from"node:path";import{config as ni}from"dotenv";import oi from"js-yaml";function Fr(c,e){let t={...c};for(let s of Object.keys(e)){let r=e[s],n=t[s];r!=null&&typeof r=="object"&&!Array.isArray(r)&&n!==null&&n!==void 0&&typeof n=="object"&&!Array.isArray(n)?t[s]=Fr(n,r):t[s]=r}return t}function ai(c){let e={...c};for(let[t,s]of Object.entries(ii)){let r=process.env[t];if(r===void 0)continue;let n=e;for(let o=0;o<s.length-1;o++){let i=s[o];(n[i]===void 0||n[i]===null||typeof n[i]!="object")&&(n[i]={}),n[i]={...n[i]},n=n[i]}n[s[s.length-1]]=r}return e}var ii,z,jr=f(()=>{"use strict";Is();Rs();d(Fr,"deepMerge");ii={ALFRED_TELEGRAM_TOKEN:["telegram","token"],ALFRED_DISCORD_TOKEN:["discord","token"],ALFRED_MATRIX_HOMESERVER_URL:["matrix","homeserverUrl"],ALFRED_MATRIX_ACCESS_TOKEN:["matrix","accessToken"],ALFRED_MATRIX_USER_ID:["matrix","userId"],ALFRED_SIGNAL_API_URL:["signal","apiUrl"],ALFRED_SIGNAL_PHONE_NUMBER:["signal","phoneNumber"],ALFRED_ANTHROPIC_API_KEY:["llm","apiKey"],ALFRED_OPENAI_API_KEY:["llm","apiKey"],ALFRED_OPENROUTER_API_KEY:["llm","apiKey"],ALFRED_OPENWEBUI_API_KEY:["llm","apiKey"],ALFRED_LLM_PROVIDER:["llm","provider"],ALFRED_LLM_MODEL:["llm","model"],ALFRED_LLM_BASE_URL:["llm","baseUrl"],ALFRED_LLM_STRONG_PROVIDER:["llm","strong","provider"],ALFRED_LLM_STRONG_MODEL:["llm","strong","model"],ALFRED_LLM_STRONG_API_KEY:["llm","strong","apiKey"],ALFRED_LLM_FAST_PROVIDER:["llm","fast","provider"],ALFRED_LLM_FAST_MODEL:["llm","fast","model"],ALFRED_LLM_FAST_API_KEY:["llm","fast","apiKey"],ALFRED_LLM_EMBEDDINGS_PROVIDER:["llm","embeddings","provider"],ALFRED_LLM_EMBEDDINGS_MODEL:["llm","embeddings","model"],ALFRED_LLM_EMBEDDINGS_API_KEY:["llm","embeddings","apiKey"],ALFRED_LLM_LOCAL_PROVIDER:["llm","local","provider"],ALFRED_LLM_LOCAL_MODEL:["llm","local","model"],ALFRED_LLM_LOCAL_BASE_URL:["llm","local","baseUrl"],ALFRED_STORAGE_PATH:["storage","path"],ALFRED_LOG_LEVEL:["logger","level"],ALFRED_OWNER_USER_ID:["security","ownerUserId"],ALFRED_SEARCH_PROVIDER:["search","provider"],ALFRED_SEARCH_API_KEY:["search","apiKey"],ALFRED_SEARCH_BASE_URL:["search","baseUrl"],ALFRED_EMAIL_USER:["email","auth","user"],ALFRED_EMAIL_PASS:["email","auth","pass"],ALFRED_SPEECH_PROVIDER:["speech","provider"],ALFRED_SPEECH_API_KEY:["speech","apiKey"],ALFRED_SPEECH_BASE_URL:["speech","baseUrl"],ALFRED_CALENDAR_PROVIDER:["calendar","provider"],ALFRED_CALDAV_SERVER_URL:["calendar","caldav","serverUrl"],ALFRED_CALDAV_USERNAME:["calendar","caldav","username"],ALFRED_CALDAV_PASSWORD:["calendar","caldav","password"],ALFRED_GOOGLE_CALENDAR_CLIENT_ID:["calendar","google","clientId"],ALFRED_GOOGLE_CALENDAR_CLIENT_SECRET:["calendar","google","clientSecret"],ALFRED_GOOGLE_CALENDAR_REFRESH_TOKEN:["calendar","google","refreshToken"],ALFRED_MICROSOFT_CALENDAR_CLIENT_ID:["calendar","microsoft","clientId"],ALFRED_MICROSOFT_CALENDAR_CLIENT_SECRET:["calendar","microsoft","clientSecret"],ALFRED_MICROSOFT_CALENDAR_TENANT_ID:["calendar","microsoft","tenantId"],ALFRED_MICROSOFT_CALENDAR_REFRESH_TOKEN:["calendar","microsoft","refreshToken"]};d(ai,"applyEnvOverrides");z=class{static{d(this,"ConfigLoader")}loadConfig(e){ni();let t=e??process.env.ALFRED_CONFIG_PATH??"./config/default.yml",s={},r=ri.resolve(t);if(Pr.existsSync(r)){let l=Pr.readFileSync(r,"utf-8"),u=oi.load(l);u&&typeof u=="object"&&(s=u)}let n=Fr($s,s),o=ai(n),i=xs.parse(o),a=i.llm;return a&&"provider"in a&&(i.llm={default:a}),i}}});var ue=f(()=>{"use strict";Is();Rs();jr()});import As from"pino";function ot(c,e){let t=e??process.env.LOG_LEVEL??"info";if(t==="debug"||t==="trace"||process.env.NODE_ENV!=="production"){let r=As.transport({target:"pino-pretty",options:{colorize:!0}});return As({name:c,level:t},r)}return As({name:c,level:t})}var Br=f(()=>{"use strict";d(ot,"createLogger")});import Ya from"pino";var Wr=f(()=>{"use strict"});var Ls=f(()=>{"use strict";Br();Wr()});var Ie,Qt=f(()=>{"use strict";Ie=class{static{d(this,"Migrator")}db;constructor(e){this.db=e,this.ensureMigrationsTable()}ensureMigrationsTable(){this.db.exec(`
|
|
3
3
|
CREATE TABLE IF NOT EXISTS _migrations (
|
|
4
4
|
version INTEGER PRIMARY KEY,
|
|
5
5
|
description TEXT,
|
|
@@ -206,10 +206,10 @@ var Rr=Object.defineProperty;var d=(c,e)=>Rr(c,"name",{value:e,configurable:!0})
|
|
|
206
206
|
|
|
207
207
|
CREATE INDEX IF NOT EXISTS idx_users_platform
|
|
208
208
|
ON users(platform, platform_user_id);
|
|
209
|
-
`)}runMigrations(){new Ie(this.db).migrate(Ms)}getDb(){return this.db}close(){this.db.close()}}});import
|
|
209
|
+
`)}runMigrations(){new Ie(this.db).migrate(Ms)}getDb(){return this.db}close(){this.db.close()}}});import Xr from"node:crypto";var it,zr=f(()=>{"use strict";it=class{static{d(this,"ConversationRepository")}db;constructor(e){this.db=e}create(e,t,s){let r=new Date().toISOString(),n={id:Xr.randomUUID(),platform:e,chatId:t,userId:s,createdAt:r,updatedAt:r};return this.db.prepare(`
|
|
210
210
|
INSERT INTO conversations (id, platform, chat_id, user_id, created_at, updated_at)
|
|
211
211
|
VALUES (?, ?, ?, ?, ?, ?)
|
|
212
|
-
`).run(n.id,n.platform,n.chatId,n.userId,n.createdAt,n.updatedAt),n}findById(e){let t=this.db.prepare("SELECT * FROM conversations WHERE id = ?").get(e);if(t)return this.mapRow(t)}findByPlatformChat(e,t){let s=this.db.prepare("SELECT * FROM conversations WHERE platform = ? AND chat_id = ?").get(e,t);if(s)return this.mapRow(s)}addMessage(e,t,s,r){let n={id:
|
|
212
|
+
`).run(n.id,n.platform,n.chatId,n.userId,n.createdAt,n.updatedAt),n}findById(e){let t=this.db.prepare("SELECT * FROM conversations WHERE id = ?").get(e);if(t)return this.mapRow(t)}findByPlatformChat(e,t){let s=this.db.prepare("SELECT * FROM conversations WHERE platform = ? AND chat_id = ?").get(e,t);if(s)return this.mapRow(s)}addMessage(e,t,s,r){let n={id:Xr.randomUUID(),conversationId:e,role:t,content:s,toolCalls:r,createdAt:new Date().toISOString()};return this.db.prepare(`
|
|
213
213
|
INSERT INTO messages (id, conversation_id, role, content, tool_calls, created_at)
|
|
214
214
|
VALUES (?, ?, ?, ?, ?, ?)
|
|
215
215
|
`).run(n.id,n.conversationId,n.role,n.content,n.toolCalls??null,n.createdAt),n}getMessages(e,t=50){return this.db.prepare("SELECT * FROM messages WHERE conversation_id = ? ORDER BY created_at ASC LIMIT ?").all(e,t).map(r=>({id:r.id,conversationId:r.conversation_id,role:r.role,content:r.content,toolCalls:r.tool_calls??void 0,createdAt:r.created_at}))}updateTimestamp(e){this.db.prepare("UPDATE conversations SET updated_at = ? WHERE id = ?").run(new Date().toISOString(),e)}mapRow(e){return{id:e.id,platform:e.platform,chatId:e.chat_id,userId:e.user_id,createdAt:e.created_at,updatedAt:e.updated_at}}}});import ui from"node:crypto";var at,qr=f(()=>{"use strict";at=class{static{d(this,"UserRepository")}db;constructor(e){this.db=e}findOrCreate(e,t,s,r){let n=this.db.prepare("SELECT * FROM users WHERE platform = ? AND platform_user_id = ?").get(e,t);if(n)return this.mapRow(n);let o=new Date().toISOString(),i={id:ui.randomUUID(),platform:e,platformUserId:t,username:s,displayName:r,createdAt:o,updatedAt:o};return this.db.prepare(`
|
|
@@ -251,22 +251,29 @@ var Rr=Object.defineProperty;var d=(c,e)=>Rr(c,"name",{value:e,configurable:!0})
|
|
|
251
251
|
UPDATE scheduled_actions
|
|
252
252
|
SET last_run_at = ?, next_run_at = ?
|
|
253
253
|
WHERE id = ?
|
|
254
|
-
`).run(t,s,e)}setEnabled(e,t){return this.db.prepare("UPDATE scheduled_actions SET enabled = ? WHERE id = ?").run(t?1:0,e).changes>0}delete(e){return this.db.prepare("DELETE FROM scheduled_actions WHERE id = ?").run(e).changes>0}calculateInitialNextRun(e,t){let s=new Date;switch(e){case"interval":{let r=parseInt(t,10);return isNaN(r)||r<=0?null:new Date(s.getTime()+r*6e4).toISOString()}case"once":return new Date(t).toISOString();case"cron":return this.getNextCronDate(t,s)?.toISOString()??null;default:return null}}getNextCronDate(e,t){let s=e.trim().split(/\s+/);if(s.length!==5)return null;let r=new Date(t.getTime()+6e4);r.setSeconds(0,0);for(let n=0;n<1440;n++){if(this.matchesCron(s,r))return r;r.setTime(r.getTime()+6e4)}return null}matchesCron(e,t){let s=t.getMinutes(),r=t.getHours(),n=t.getDate(),o=t.getMonth()+1,i=t.getDay();return this.matchCronField(e[0],s)&&this.matchCronField(e[1],r)&&this.matchCronField(e[2],n)&&this.matchCronField(e[3],o)&&this.matchCronField(e[4],i)}matchCronField(e,t){if(e==="*")return!0;let s=/^\*\/(\d+)$/.exec(e);if(s){let n=parseInt(s[1],10);return t%n===0}let r=parseInt(e,10);return isNaN(r)?!1:t===r}mapRow(e){return{id:e.id,userId:e.user_id,platform:e.platform,chatId:e.chat_id,name:e.name,description:e.description,scheduleType:e.schedule_type,scheduleValue:e.schedule_value,skillName:e.skill_name,skillInput:e.skill_input,promptTemplate:e.prompt_template,enabled:e.enabled===1,lastRunAt:e.last_run_at,nextRunAt:e.next_run_at,createdAt:e.created_at}}}});import{randomUUID as tn}from"node:crypto";var ft,sn=f(()=>{"use strict";ft=class{static{d(this,"DocumentRepository")}db;constructor(e){this.db=e}createDocument(e,t,s,r){let n=tn(),o=new Date().toISOString();return this.db.prepare("INSERT INTO documents (id, user_id, filename, mime_type, size_bytes, chunk_count, created_at) VALUES (?, ?, ?, ?, ?, 0, ?)").run(n,e,t,s,r,o),{id:n,userId:e,filename:t,mimeType:s,sizeBytes:r,chunkCount:0,createdAt:o}}updateChunkCount(e,t){this.db.prepare("UPDATE documents SET chunk_count = ? WHERE id = ?").run(t,e)}addChunk(e,t,s,r){let n=tn(),o=new Date().toISOString();return this.db.prepare("INSERT INTO document_chunks (id, document_id, chunk_index, content, embedding_id, created_at) VALUES (?, ?, ?, ?, ?, ?)").run(n,e,t,s,r??null,o),{id:n,documentId:e,chunkIndex:t,content:s,embeddingId:r,createdAt:o}}getDocument(e){let t=this.db.prepare("SELECT * FROM documents WHERE id = ?").get(e);return t?this.mapDocumentRow(t):void 0}getChunks(e){return this.db.prepare("SELECT * FROM document_chunks WHERE document_id = ? ORDER BY chunk_index ASC").all(e).map(s=>this.mapChunkRow(s))}listByUser(e){return this.db.prepare("SELECT * FROM documents WHERE user_id = ? ORDER BY created_at DESC").all(e).map(s=>this.mapDocumentRow(s))}deleteDocument(e){this.db.transaction(()=>{let s=this.db.prepare("SELECT embedding_id FROM document_chunks WHERE document_id = ? AND embedding_id IS NOT NULL").all(e);if(s.length>0){let r=s.map(o=>o.embedding_id),n=r.map(()=>"?").join(", ");this.db.prepare(`DELETE FROM embeddings WHERE key IN (${n})`).run(...r)}this.db.prepare("DELETE FROM document_chunks WHERE document_id = ?").run(e),this.db.prepare("DELETE FROM documents WHERE id = ?").run(e)})()}getChunksByEmbeddingIds(e){if(e.length===0)return[];let t=e.map(()=>"?").join(", ");return this.db.prepare(`SELECT * FROM document_chunks WHERE embedding_id IN (${t}) ORDER BY chunk_index ASC`).all(...e).map(r=>this.mapChunkRow(r))}mapDocumentRow(e){return{id:e.id,userId:e.user_id,filename:e.filename,mimeType:e.mime_type,sizeBytes:e.size_bytes,chunkCount:e.chunk_count,createdAt:e.created_at}}mapChunkRow(e){return{id:e.id,documentId:e.document_id,chunkIndex:e.chunk_index,content:e.content,embeddingId:e.embedding_id||void 0,createdAt:e.created_at}}}});var Ds=f(()=>{"use strict";Hr();Xr();qr();Kr();Vr();Qt();Ns();Gr();Yr();Jr();Zr();Qr();en();sn()});function he(c){if(Os[c])return Os[c];for(let[e,t]of Object.entries(Os))if(c.startsWith(e))return t}var Os,Ei,G,$e=f(()=>{"use strict";Os={"claude-opus-4-20250514":{maxInputTokens:2e5,maxOutputTokens:32e3},"claude-sonnet-4-20250514":{maxInputTokens:2e5,maxOutputTokens:16e3},"claude-haiku-3-5-20241022":{maxInputTokens:2e5,maxOutputTokens:8192},"gpt-4o":{maxInputTokens:128e3,maxOutputTokens:16384},"gpt-4o-mini":{maxInputTokens:128e3,maxOutputTokens:16384},"gpt-4-turbo":{maxInputTokens:128e3,maxOutputTokens:4096},"gpt-4":{maxInputTokens:8192,maxOutputTokens:4096},"gpt-3.5-turbo":{maxInputTokens:16384,maxOutputTokens:4096},o1:{maxInputTokens:2e5,maxOutputTokens:1e5},"o1-mini":{maxInputTokens:128e3,maxOutputTokens:65536},"o3-mini":{maxInputTokens:2e5,maxOutputTokens:1e5},"llama3.2":{maxInputTokens:128e3,maxOutputTokens:4096},"llama3.1":{maxInputTokens:128e3,maxOutputTokens:4096},llama3:{maxInputTokens:8192,maxOutputTokens:4096},mistral:{maxInputTokens:32e3,maxOutputTokens:4096},"mistral-small":{maxInputTokens:32e3,maxOutputTokens:4096},mixtral:{maxInputTokens:32e3,maxOutputTokens:4096},gemma2:{maxInputTokens:8192,maxOutputTokens:4096},"qwen2.5":{maxInputTokens:128e3,maxOutputTokens:4096},phi3:{maxInputTokens:128e3,maxOutputTokens:4096},"deepseek-r1":{maxInputTokens:128e3,maxOutputTokens:8192},"command-r":{maxInputTokens:128e3,maxOutputTokens:4096}},Ei={maxInputTokens:8192,maxOutputTokens:4096};d(he,"lookupContextWindow");G=class{static{d(this,"LLMProvider")}config;contextWindow=Ei;constructor(e){this.config=e}getContextWindow(){return this.contextWindow}async embed(e){}supportsEmbeddings(){return!1}}});import Ti from"@anthropic-ai/sdk";var gt,Cs=f(()=>{"use strict";$e();gt=class extends G{static{d(this,"AnthropicProvider")}client;constructor(e){super(e)}async initialize(){this.client=new Ti({apiKey:this.config.apiKey});let e=he(this.config.model);e&&(this.contextWindow=e)}async complete(e){let t=this.mapMessages(e.messages),s=e.tools?this.mapTools(e.tools):void 0,r={model:this.config.model,max_tokens:e.maxTokens??this.config.maxTokens??4096,temperature:e.temperature??this.config.temperature,system:e.system,messages:t,tools:s},n=await this.client.messages.create(r);return this.mapResponse(n)}async*stream(e){let t=this.mapMessages(e.messages),s=e.tools?this.mapTools(e.tools):void 0,r=this.client.messages.stream({model:this.config.model,max_tokens:e.maxTokens??this.config.maxTokens??4096,temperature:e.temperature??this.config.temperature,system:e.system,messages:t,tools:s});for await(let n of r)if(n.type==="content_block_delta")n.delta.type==="text_delta"?yield{type:"text_delta",text:n.delta.text}:n.delta.type==="input_json_delta"&&(yield{type:"tool_use_delta",toolCall:{input:n.delta.partial_json}});else if(n.type==="content_block_start")n.content_block.type==="tool_use"&&(yield{type:"tool_use_start",toolCall:{id:n.content_block.id,name:n.content_block.name}});else if(n.type==="message_stop"){let o=await r.finalMessage();yield{type:"message_complete",response:this.mapResponse(o)}}}isAvailable(){return!!this.config.apiKey}mapMessages(e){return e.map(t=>{if(typeof t.content=="string")return{role:t.role,content:t.content};let s=t.content.map(r=>{switch(r.type){case"text":return{type:"text",text:r.text};case"image":return{type:"image",source:{type:"base64",media_type:r.source.media_type,data:r.source.data}};case"tool_use":return{type:"tool_use",id:r.id,name:r.name,input:r.input};case"tool_result":return{type:"tool_result",tool_use_id:r.tool_use_id,content:r.content,is_error:r.is_error}}});return{role:t.role,content:s}})}mapTools(e){return e.map(t=>({name:t.name,description:t.description,input_schema:t.inputSchema}))}mapResponse(e){let t="",s=[];for(let r of e.content)r.type==="text"?t+=r.text:r.type==="tool_use"&&s.push({id:r.id,name:r.name,input:r.input});return{content:t,toolCalls:s.length>0?s:void 0,usage:{inputTokens:e.usage.input_tokens,outputTokens:e.usage.output_tokens},stopReason:e.stop_reason}}}});import bi from"openai";var te,yt=f(()=>{"use strict";$e();te=class extends G{static{d(this,"OpenAIProvider")}client;constructor(e){super(e)}async initialize(){this.client=new bi({apiKey:this.config.apiKey,baseURL:this.config.baseUrl});let e=he(this.config.model);e&&(this.contextWindow=e)}async complete(e){let t=this.mapMessages(e.messages,e.system),s=e.tools?this.mapTools(e.tools):void 0,r={model:this.config.model,max_tokens:e.maxTokens??this.config.maxTokens??4096,temperature:e.temperature??this.config.temperature,messages:t,...s?{tools:s}:{}},n=await this.client.chat.completions.create(r);return this.mapResponse(n)}async*stream(e){let t=this.mapMessages(e.messages,e.system),s=e.tools?this.mapTools(e.tools):void 0,r=await this.client.chat.completions.create({model:this.config.model,max_tokens:e.maxTokens??this.config.maxTokens??4096,temperature:e.temperature??this.config.temperature,messages:t,...s?{tools:s}:{},stream:!0}),n,o,i="",a="",l=[],u=null,h=0,m=0;for await(let p of r){let E=p.choices[0];if(!E)continue;let w=E.delta;if(w?.content&&(a+=w.content,yield{type:"text_delta",text:w.content}),w?.tool_calls)for(let T of w.tool_calls)T.id?(n&&l.push({id:n,name:o,input:JSON.parse(i||"{}")}),n=T.id,o=T.function?.name,i=T.function?.arguments??"",yield{type:"tool_use_start",toolCall:{id:n,name:o}}):T.function?.arguments&&(i+=T.function.arguments,yield{type:"tool_use_delta",toolCall:{input:T.function.arguments}});E.finish_reason&&(u=E.finish_reason),p.usage&&(h=p.usage.prompt_tokens,m=p.usage.completion_tokens)}n&&l.push({id:n,name:o,input:JSON.parse(i||"{}")}),yield{type:"message_complete",response:{content:a,toolCalls:l.length>0?l:void 0,usage:{inputTokens:h,outputTokens:m},stopReason:this.mapStopReason(u)}}}isAvailable(){return!!this.config.apiKey}async embed(e){try{let s=(await this.client.embeddings.create({model:"text-embedding-3-small",input:e})).data[0];return{embedding:s.embedding,model:"text-embedding-3-small",dimensions:s.embedding.length}}catch{return}}supportsEmbeddings(){return!0}mapMessages(e,t){let s=[];t&&s.push({role:"system",content:t});for(let r of e){if(typeof r.content=="string"){s.push({role:r.role,content:r.content});continue}let n=[],o=[],i=[];for(let a of r.content)switch(a.type){case"text":n.push({type:"text",text:a.text});break;case"image":n.push({type:"image_url",image_url:{url:`data:${a.source.media_type};base64,${a.source.data}`}});break;case"tool_use":o.push({id:a.id,type:"function",function:{name:a.name,arguments:JSON.stringify(a.input)}});break;case"tool_result":i.push({tool_call_id:a.tool_use_id,content:a.content});break}if(r.role==="assistant"&&o.length>0){let a=n.map(l=>l.text).join("");s.push({role:"assistant",content:a||null,tool_calls:o})}else if(i.length>0)for(let a of i)s.push({role:"tool",tool_call_id:a.tool_call_id,content:a.content});else n.length>0&&(r.role==="user"?s.push({role:"user",content:n}):s.push({role:r.role,content:n.map(a=>a.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,r=s?.content??"",n=s?.tool_calls?.map(o=>({id:o.id,name:o.function.name,input:(()=>{try{return JSON.parse(o.function.arguments)}catch{return{}}})()}));return{content:r,toolCalls:n&&n.length>0?n:void 0,usage:{inputTokens:e.usage?.prompt_tokens??0,outputTokens:e.usage?.completion_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 wt,Us=f(()=>{"use strict";yt();wt=class extends te{static{d(this,"OpenRouterProvider")}constructor(e){super({...e,baseUrl:e.baseUrl??"https://openrouter.ai/api/v1"})}isAvailable(){return!!this.config.apiKey}supportsEmbeddings(){return!1}}});var Et,Ps=f(()=>{"use strict";$e();Et=class extends G{static{d(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=he(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??{},r=Object.keys(s).find(o=>o.includes("context_length")||o==="num_ctx"),n=r?Number(s[r]):0;n>0&&(this.contextWindow={maxInputTokens:n,maxOutputTokens:Math.min(n,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,r={model:this.config.model,messages:t,stream:!1,options:this.buildOptions(e)};s&&s.length>0&&(r.tools=s);let n=await fetch(`${this.baseUrl}/api/chat`,{method:"POST",headers:this.getHeaders(),body:JSON.stringify(r)});if(!n.ok){let i=await n.text();throw new Error(`Ollama API error (${n.status}): ${i}`)}let o=await n.json();return this.mapResponse(o)}async*stream(e){let t=this.buildMessages(e.messages,e.system),s=e.tools?this.mapTools(e.tools):void 0,r={model:this.config.model,messages:t,stream:!0,options:this.buildOptions(e)};s&&s.length>0&&(r.tools=s);let n=await fetch(`${this.baseUrl}/api/chat`,{method:"POST",headers:this.getHeaders(),body:JSON.stringify(r)});if(!n.ok){let p=await n.text();throw new Error(`Ollama API error (${n.status}): ${p}`)}if(!n.body)throw new Error("Ollama streaming response has no body");let o=n.body.getReader(),i=new TextDecoder,a="",l="",u=0,h=0,m=[];try{for(;;){let{done:p,value:E}=await o.read();if(p)break;a+=i.decode(E,{stream:!0});let w=a.split(`
|
|
254
|
+
`).run(t,s,e)}setEnabled(e,t){return this.db.prepare("UPDATE scheduled_actions SET enabled = ? WHERE id = ?").run(t?1:0,e).changes>0}delete(e){return this.db.prepare("DELETE FROM scheduled_actions WHERE id = ?").run(e).changes>0}calculateInitialNextRun(e,t){let s=new Date;switch(e){case"interval":{let r=parseInt(t,10);return isNaN(r)||r<=0?null:new Date(s.getTime()+r*6e4).toISOString()}case"once":return new Date(t).toISOString();case"cron":return this.getNextCronDate(t,s)?.toISOString()??null;default:return null}}getNextCronDate(e,t){let s=e.trim().split(/\s+/);if(s.length!==5)return null;let r=new Date(t.getTime()+6e4);r.setSeconds(0,0);for(let n=0;n<1440;n++){if(this.matchesCron(s,r))return r;r.setTime(r.getTime()+6e4)}return null}matchesCron(e,t){let s=t.getMinutes(),r=t.getHours(),n=t.getDate(),o=t.getMonth()+1,i=t.getDay();return this.matchCronField(e[0],s)&&this.matchCronField(e[1],r)&&this.matchCronField(e[2],n)&&this.matchCronField(e[3],o)&&this.matchCronField(e[4],i)}matchCronField(e,t){if(e==="*")return!0;let s=/^\*\/(\d+)$/.exec(e);if(s){let n=parseInt(s[1],10);return t%n===0}let r=parseInt(e,10);return isNaN(r)?!1:t===r}mapRow(e){return{id:e.id,userId:e.user_id,platform:e.platform,chatId:e.chat_id,name:e.name,description:e.description,scheduleType:e.schedule_type,scheduleValue:e.schedule_value,skillName:e.skill_name,skillInput:e.skill_input,promptTemplate:e.prompt_template,enabled:e.enabled===1,lastRunAt:e.last_run_at,nextRunAt:e.next_run_at,createdAt:e.created_at}}}});import{randomUUID as tn}from"node:crypto";var ft,sn=f(()=>{"use strict";ft=class{static{d(this,"DocumentRepository")}db;constructor(e){this.db=e}createDocument(e,t,s,r){let n=tn(),o=new Date().toISOString();return this.db.prepare("INSERT INTO documents (id, user_id, filename, mime_type, size_bytes, chunk_count, created_at) VALUES (?, ?, ?, ?, ?, 0, ?)").run(n,e,t,s,r,o),{id:n,userId:e,filename:t,mimeType:s,sizeBytes:r,chunkCount:0,createdAt:o}}updateChunkCount(e,t){this.db.prepare("UPDATE documents SET chunk_count = ? WHERE id = ?").run(t,e)}addChunk(e,t,s,r){let n=tn(),o=new Date().toISOString();return this.db.prepare("INSERT INTO document_chunks (id, document_id, chunk_index, content, embedding_id, created_at) VALUES (?, ?, ?, ?, ?, ?)").run(n,e,t,s,r??null,o),{id:n,documentId:e,chunkIndex:t,content:s,embeddingId:r,createdAt:o}}getDocument(e){let t=this.db.prepare("SELECT * FROM documents WHERE id = ?").get(e);return t?this.mapDocumentRow(t):void 0}getChunks(e){return this.db.prepare("SELECT * FROM document_chunks WHERE document_id = ? ORDER BY chunk_index ASC").all(e).map(s=>this.mapChunkRow(s))}listByUser(e){return this.db.prepare("SELECT * FROM documents WHERE user_id = ? ORDER BY created_at DESC").all(e).map(s=>this.mapDocumentRow(s))}deleteDocument(e){this.db.transaction(()=>{let s=this.db.prepare("SELECT embedding_id FROM document_chunks WHERE document_id = ? AND embedding_id IS NOT NULL").all(e);if(s.length>0){let r=s.map(o=>o.embedding_id),n=r.map(()=>"?").join(", ");this.db.prepare(`DELETE FROM embeddings WHERE key IN (${n})`).run(...r)}this.db.prepare("DELETE FROM document_chunks WHERE document_id = ?").run(e),this.db.prepare("DELETE FROM documents WHERE id = ?").run(e)})()}getChunksByEmbeddingIds(e){if(e.length===0)return[];let t=e.map(()=>"?").join(", ");return this.db.prepare(`SELECT * FROM document_chunks WHERE embedding_id IN (${t}) ORDER BY chunk_index ASC`).all(...e).map(r=>this.mapChunkRow(r))}mapDocumentRow(e){return{id:e.id,userId:e.user_id,filename:e.filename,mimeType:e.mime_type,sizeBytes:e.size_bytes,chunkCount:e.chunk_count,createdAt:e.created_at}}mapChunkRow(e){return{id:e.id,documentId:e.document_id,chunkIndex:e.chunk_index,content:e.content,embeddingId:e.embedding_id||void 0,createdAt:e.created_at}}}});var Ds=f(()=>{"use strict";Hr();zr();qr();Kr();Vr();Qt();Ns();Gr();Yr();Jr();Zr();Qr();en();sn()});function he(c){if(Os[c])return Os[c];for(let[e,t]of Object.entries(Os))if(c.startsWith(e))return t}var Os,Ei,G,$e=f(()=>{"use strict";Os={"claude-opus-4-20250514":{maxInputTokens:2e5,maxOutputTokens:32e3},"claude-sonnet-4-20250514":{maxInputTokens:2e5,maxOutputTokens:16e3},"claude-haiku-3-5-20241022":{maxInputTokens:2e5,maxOutputTokens:8192},"gpt-4o":{maxInputTokens:128e3,maxOutputTokens:16384},"gpt-4o-mini":{maxInputTokens:128e3,maxOutputTokens:16384},"gpt-4-turbo":{maxInputTokens:128e3,maxOutputTokens:4096},"gpt-4":{maxInputTokens:8192,maxOutputTokens:4096},"gpt-3.5-turbo":{maxInputTokens:16384,maxOutputTokens:4096},o1:{maxInputTokens:2e5,maxOutputTokens:1e5},"o1-mini":{maxInputTokens:128e3,maxOutputTokens:65536},"o3-mini":{maxInputTokens:2e5,maxOutputTokens:1e5},"llama3.2":{maxInputTokens:128e3,maxOutputTokens:4096},"llama3.1":{maxInputTokens:128e3,maxOutputTokens:4096},llama3:{maxInputTokens:8192,maxOutputTokens:4096},mistral:{maxInputTokens:32e3,maxOutputTokens:4096},"mistral-small":{maxInputTokens:32e3,maxOutputTokens:4096},mixtral:{maxInputTokens:32e3,maxOutputTokens:4096},gemma2:{maxInputTokens:8192,maxOutputTokens:4096},"qwen2.5":{maxInputTokens:128e3,maxOutputTokens:4096},phi3:{maxInputTokens:128e3,maxOutputTokens:4096},"deepseek-r1":{maxInputTokens:128e3,maxOutputTokens:8192},"command-r":{maxInputTokens:128e3,maxOutputTokens:4096}},Ei={maxInputTokens:8192,maxOutputTokens:4096};d(he,"lookupContextWindow");G=class{static{d(this,"LLMProvider")}config;contextWindow=Ei;constructor(e){this.config=e}getContextWindow(){return this.contextWindow}async embed(e){}supportsEmbeddings(){return!1}}});import Ti from"@anthropic-ai/sdk";var gt,Cs=f(()=>{"use strict";$e();gt=class extends G{static{d(this,"AnthropicProvider")}client;constructor(e){super(e)}async initialize(){this.client=new Ti({apiKey:this.config.apiKey});let e=he(this.config.model);e&&(this.contextWindow=e)}async complete(e){let t=this.mapMessages(e.messages),s=e.tools?this.mapTools(e.tools):void 0,r={model:this.config.model,max_tokens:e.maxTokens??this.config.maxTokens??4096,temperature:e.temperature??this.config.temperature,system:e.system,messages:t,tools:s},n=await this.client.messages.create(r);return this.mapResponse(n)}async*stream(e){let t=this.mapMessages(e.messages),s=e.tools?this.mapTools(e.tools):void 0,r=this.client.messages.stream({model:this.config.model,max_tokens:e.maxTokens??this.config.maxTokens??4096,temperature:e.temperature??this.config.temperature,system:e.system,messages:t,tools:s});for await(let n of r)if(n.type==="content_block_delta")n.delta.type==="text_delta"?yield{type:"text_delta",text:n.delta.text}:n.delta.type==="input_json_delta"&&(yield{type:"tool_use_delta",toolCall:{input:n.delta.partial_json}});else if(n.type==="content_block_start")n.content_block.type==="tool_use"&&(yield{type:"tool_use_start",toolCall:{id:n.content_block.id,name:n.content_block.name}});else if(n.type==="message_stop"){let o=await r.finalMessage();yield{type:"message_complete",response:this.mapResponse(o)}}}isAvailable(){return!!this.config.apiKey}mapMessages(e){return e.map(t=>{if(typeof t.content=="string")return{role:t.role,content:t.content};let s=t.content.map(r=>{switch(r.type){case"text":return{type:"text",text:r.text};case"image":return{type:"image",source:{type:"base64",media_type:r.source.media_type,data:r.source.data}};case"tool_use":return{type:"tool_use",id:r.id,name:r.name,input:r.input};case"tool_result":return{type:"tool_result",tool_use_id:r.tool_use_id,content:r.content,is_error:r.is_error}}});return{role:t.role,content:s}})}mapTools(e){return e.map(t=>({name:t.name,description:t.description,input_schema:t.inputSchema}))}mapResponse(e){let t="",s=[];for(let r of e.content)r.type==="text"?t+=r.text:r.type==="tool_use"&&s.push({id:r.id,name:r.name,input:r.input});return{content:t,toolCalls:s.length>0?s:void 0,usage:{inputTokens:e.usage.input_tokens,outputTokens:e.usage.output_tokens},stopReason:e.stop_reason}}}});import bi from"openai";var te,yt=f(()=>{"use strict";$e();te=class extends G{static{d(this,"OpenAIProvider")}client;constructor(e){super(e)}async initialize(){this.client=new bi({apiKey:this.config.apiKey,baseURL:this.config.baseUrl});let e=he(this.config.model);e&&(this.contextWindow=e)}async complete(e){let t=this.mapMessages(e.messages,e.system),s=e.tools?this.mapTools(e.tools):void 0,r={model:this.config.model,max_tokens:e.maxTokens??this.config.maxTokens??4096,temperature:e.temperature??this.config.temperature,messages:t,...s?{tools:s}:{}},n=await this.client.chat.completions.create(r);return this.mapResponse(n)}async*stream(e){let t=this.mapMessages(e.messages,e.system),s=e.tools?this.mapTools(e.tools):void 0,r=await this.client.chat.completions.create({model:this.config.model,max_tokens:e.maxTokens??this.config.maxTokens??4096,temperature:e.temperature??this.config.temperature,messages:t,...s?{tools:s}:{},stream:!0}),n,o,i="",a="",l=[],u=null,h=0,m=0;for await(let p of r){let E=p.choices[0];if(!E)continue;let w=E.delta;if(w?.content&&(a+=w.content,yield{type:"text_delta",text:w.content}),w?.tool_calls)for(let T of w.tool_calls)T.id?(n&&l.push({id:n,name:o,input:JSON.parse(i||"{}")}),n=T.id,o=T.function?.name,i=T.function?.arguments??"",yield{type:"tool_use_start",toolCall:{id:n,name:o}}):T.function?.arguments&&(i+=T.function.arguments,yield{type:"tool_use_delta",toolCall:{input:T.function.arguments}});E.finish_reason&&(u=E.finish_reason),p.usage&&(h=p.usage.prompt_tokens,m=p.usage.completion_tokens)}n&&l.push({id:n,name:o,input:JSON.parse(i||"{}")}),yield{type:"message_complete",response:{content:a,toolCalls:l.length>0?l:void 0,usage:{inputTokens:h,outputTokens:m},stopReason:this.mapStopReason(u)}}}isAvailable(){return!!this.config.apiKey}async embed(e){try{let s=(await this.client.embeddings.create({model:"text-embedding-3-small",input:e})).data[0];return{embedding:s.embedding,model:"text-embedding-3-small",dimensions:s.embedding.length}}catch{return}}supportsEmbeddings(){return!0}mapMessages(e,t){let s=[];t&&s.push({role:"system",content:t});for(let r of e){if(typeof r.content=="string"){s.push({role:r.role,content:r.content});continue}let n=[],o=[],i=[];for(let a of r.content)switch(a.type){case"text":n.push({type:"text",text:a.text});break;case"image":n.push({type:"image_url",image_url:{url:`data:${a.source.media_type};base64,${a.source.data}`}});break;case"tool_use":o.push({id:a.id,type:"function",function:{name:a.name,arguments:JSON.stringify(a.input)}});break;case"tool_result":i.push({tool_call_id:a.tool_use_id,content:a.content});break}if(r.role==="assistant"&&o.length>0){let a=n.map(l=>l.text).join("");s.push({role:"assistant",content:a||null,tool_calls:o})}else if(i.length>0)for(let a of i)s.push({role:"tool",tool_call_id:a.tool_call_id,content:a.content});else n.length>0&&(r.role==="user"?s.push({role:"user",content:n}):s.push({role:r.role,content:n.map(a=>a.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,r=s?.content??"",n=s?.tool_calls?.map(o=>({id:o.id,name:o.function.name,input:(()=>{try{return JSON.parse(o.function.arguments)}catch{return{}}})()}));return{content:r,toolCalls:n&&n.length>0?n:void 0,usage:{inputTokens:e.usage?.prompt_tokens??0,outputTokens:e.usage?.completion_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 wt,Us=f(()=>{"use strict";yt();wt=class extends te{static{d(this,"OpenRouterProvider")}constructor(e){super({...e,baseUrl:e.baseUrl??"https://openrouter.ai/api/v1"})}isAvailable(){return!!this.config.apiKey}supportsEmbeddings(){return!1}}});var Et,Ps=f(()=>{"use strict";$e();Et=class extends G{static{d(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=he(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??{},r=Object.keys(s).find(o=>o.includes("context_length")||o==="num_ctx"),n=r?Number(s[r]):0;n>0&&(this.contextWindow={maxInputTokens:n,maxOutputTokens:Math.min(n,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,r={model:this.config.model,messages:t,stream:!1,options:this.buildOptions(e)};s&&s.length>0&&(r.tools=s);let n=await fetch(`${this.baseUrl}/api/chat`,{method:"POST",headers:this.getHeaders(),body:JSON.stringify(r)});if(!n.ok){let i=await n.text();throw new Error(`Ollama API error (${n.status}): ${i}`)}let o=await n.json();return this.mapResponse(o)}async*stream(e){let t=this.buildMessages(e.messages,e.system),s=e.tools?this.mapTools(e.tools):void 0,r={model:this.config.model,messages:t,stream:!0,options:this.buildOptions(e)};s&&s.length>0&&(r.tools=s);let n=await fetch(`${this.baseUrl}/api/chat`,{method:"POST",headers:this.getHeaders(),body:JSON.stringify(r)});if(!n.ok){let p=await n.text();throw new Error(`Ollama API error (${n.status}): ${p}`)}if(!n.body)throw new Error("Ollama streaming response has no body");let o=n.body.getReader(),i=new TextDecoder,a="",l="",u=0,h=0,m=[];try{for(;;){let{done:p,value:E}=await o.read();if(p)break;a+=i.decode(E,{stream:!0});let w=a.split(`
|
|
255
255
|
`);a=w.pop()??"";for(let T of w){let k=T.trim();if(!k)continue;let b;try{b=JSON.parse(k)}catch{continue}if(b.message?.content&&(l+=b.message.content,yield{type:"text_delta",text:b.message.content}),b.message?.tool_calls)for(let x of b.message.tool_calls){let L={id:`ollama_tool_${m.length}`,name:x.function.name,input:x.function.arguments};m.push(L),yield{type:"tool_use_start",toolCall:{id:L.id,name:L.name}},yield{type:"tool_use_delta",toolCall:{input:L.input}}}b.done&&(u=b.prompt_eval_count??0,h=b.eval_count??0,yield{type:"message_complete",response:{content:l,toolCalls:m.length>0?m:void 0,usage:{inputTokens:u,outputTokens:h},stopReason:m.length>0?"tool_use":"end_turn"}})}}if(a.trim()){let p;try{p=JSON.parse(a.trim())}catch{return}if(p.message?.content&&(l+=p.message.content,yield{type:"text_delta",text:p.message.content}),p.message?.tool_calls)for(let E of p.message.tool_calls){let w={id:`ollama_tool_${m.length}`,name:E.function.name,input:E.function.arguments};m.push(w),yield{type:"tool_use_start",toolCall:{id:w.id,name:w.name}},yield{type:"tool_use_delta",toolCall:{input:w.input}}}p.done&&(u=p.prompt_eval_count??0,h=p.eval_count??0,yield{type:"message_complete",response:{content:l,toolCalls:m.length>0?m:void 0,usage:{inputTokens:u,outputTokens:h},stopReason:m.length>0?"tool_use":"end_turn"}})}}finally{o.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 r=s.embeddings[0];return{embedding:r,model:"nomic-embed-text",dimensions:r.length}}catch{return}}supportsEmbeddings(){return!0}buildOptions(e){let t={},s=e.temperature??this.config.temperature;s!==void 0&&(t.temperature=s);let r=e.maxTokens??this.config.maxTokens;return r!==void 0&&(t.num_predict=r),t}buildMessages(e,t){let s=[];t&&s.push({role:"system",content:t});for(let r of e)typeof r.content=="string"?s.push({role:r.role,content:r.content}):s.push(this.mapContentBlocks(r.role,r.content));return s}mapContentBlocks(e,t){let s=[],r=[];for(let o of t)switch(o.type){case"text":s.push(o.text);break;case"image":r.push(o.source.data);break;case"tool_use":s.push(`[Tool call: ${o.name}(${JSON.stringify(o.input)})]`);break;case"tool_result":s.push(`[Tool result for ${o.tool_use_id}]: ${o.content}`);break}let n={role:e,content:s.join(`
|
|
256
256
|
`)};return r.length>0&&(n.images=r),n}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,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 Tt,Fs=f(()=>{"use strict";yt();Tt=class extends te{static{d(this,"OpenWebUIProvider")}constructor(e){super({...e,apiKey:e.apiKey||"openwebui",baseUrl:e.baseUrl??"http://localhost:3000/api/v1"})}isAvailable(){return!0}supportsEmbeddings(){return!1}}});function js(c){switch(c.provider){case"anthropic":return new gt(c);case"openai":return new te(c);case"openrouter":return new wt(c);case"ollama":return new Et(c);case"openwebui":return new Tt(c);default:throw new Error(`Unknown LLM provider: ${c.provider}`)}}var Bs=f(()=>{"use strict";Cs();yt();Us();Ps();Fs();d(js,"createLLMProvider")});function Ws(c){return new es(c)}var _i,es,rn=f(()=>{"use strict";$e();Bs();_i=["default","strong","fast","embeddings","local"],es=class extends G{static{d(this,"ModelRouter")}providers=new Map;multiConfig;constructor(e){super(e.default),this.multiConfig=e}async initialize(){for(let e of _i){let t=this.multiConfig[e];if(t){let s=js(t);await s.initialize(),this.providers.set(e,s)}}}resolve(e){return e&&this.providers.has(e)?this.providers.get(e):this.providers.get("default")}async complete(e){return this.resolve(e.tier).complete(e)}async*stream(e){yield*this.resolve(e.tier).stream(e)}async embed(e){return(this.providers.get("embeddings")??this.resolve()).embed(e)}supportsEmbeddings(){return(this.providers.get("embeddings")??this.resolve()).supportsEmbeddings()}isAvailable(){return this.resolve().isAvailable()}getContextWindow(){return this.resolve().getContextWindow()}};d(Ws,"createModelRouter")});function oe(c){return Math.ceil(c.length/3.5)}function ts(c){if(typeof c.content=="string")return oe(c.content)+4;let e=4;for(let t of c.content)switch(t.type){case"text":e+=oe(t.text);break;case"image":e+=1e3;break;case"tool_use":e+=oe(t.name)+oe(JSON.stringify(t.input));break;case"tool_result":e+=oe(t.content);break}return e}var bt,nn=f(()=>{"use strict";d(oe,"estimateTokens");d(ts,"estimateMessageTokens");bt=class{static{d(this,"PromptBuilder")}buildSystemPrompt(e={}){let{memories:t,skills:s,userProfile:r,todayEvents:n}=e,o=process.platform==="darwin"?"macOS":process.platform==="win32"?"Windows":"Linux",i=process.env.HOME||process.env.USERPROFILE||"~",a=`You are Alfred, a personal AI assistant. You run on ${o} (home: ${i}).
|
|
257
257
|
|
|
258
258
|
## Core principles
|
|
259
|
-
- ACT, don't just talk.
|
|
259
|
+
- ACT, don't just talk. For simple, safe tasks (searches, calculations, reminders, reading files), USE YOUR TOOLS immediately.
|
|
260
|
+
- **Ask before acting** on anything that changes the system: installing software, deleting files, writing to disk, running commands with side effects. Briefly confirm what you'll do and wait for the user's OK.
|
|
261
|
+
- Do exactly what the user asks. If the user asks for X, don't install Y instead. If you think an alternative is better, **recommend it first** and let the user decide.
|
|
260
262
|
- Respond in the same language the user writes in.
|
|
261
263
|
- Be concise. No filler text, no unnecessary explanations.
|
|
262
264
|
- If a tool fails or is denied, explain why and try an alternative approach.
|
|
263
265
|
|
|
266
|
+
## Follow-ups and corrections
|
|
267
|
+
- 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.
|
|
268
|
+
- If the user says "I asked for X" or "you should have done X", understand this as a correction and execute X immediately, don't explain what X is.
|
|
269
|
+
|
|
264
270
|
## Multi-step reasoning
|
|
265
271
|
For complex tasks, work through multiple steps:
|
|
266
|
-
1. **Understand** what the user wants.
|
|
267
|
-
2. **
|
|
268
|
-
3. **
|
|
269
|
-
4. **
|
|
272
|
+
1. **Understand** what the user actually wants \u2014 ask if unclear.
|
|
273
|
+
2. **Confirm** before doing anything irreversible (installs, downloads, deletions).
|
|
274
|
+
3. **Execute** using the right tools \u2014 chain multiple tool calls if needed.
|
|
275
|
+
4. **Continue** after each tool result. If the task isn't done, use the next tool. Don't stop after one call.
|
|
276
|
+
5. **Summarize** the final result clearly.
|
|
270
277
|
|
|
271
278
|
## Environment
|
|
272
279
|
- OS: ${o}
|
|
@@ -302,7 +309,7 @@ For complex tasks, work through multiple steps:
|
|
|
302
309
|
`;a+=`
|
|
303
310
|
Use these memories to personalize your responses. When the user tells you new facts or preferences, use the memory tool to save them.`}else a+=`
|
|
304
311
|
|
|
305
|
-
When the user tells you facts about themselves or preferences, use the memory tool to save them for future reference.`;return a}buildMessages(e){let t=e.filter(s=>s.role==="user"||s.role==="assistant").map(s=>{if(s.toolCalls){let r;try{r=JSON.parse(s.toolCalls)}catch{r=[]}if(s.role==="assistant"){let i=r,a=[];s.content&&a.push({type:"text",text:s.content});for(let l of i)a.push({type:"tool_use",id:l.id,name:l.name,input:l.input});return{role:"assistant",content:a}}let n=r,o=[];for(let i of n)i.type==="tool_result"&&o.push(i);return o.length>0?{role:"user",content:o}:{role:"user",content:s.content||""}}return{role:s.role,content:s.content}});return this.sanitizeToolMessages(t)}sanitizeToolMessages(e){let t=new Set;for(let n of e)if(n.role==="assistant"&&Array.isArray(n.content))for(let o of n.content)o.type==="tool_use"&&t.add(o.id);let s=new Set;for(let n of e)if(n.role==="user"&&Array.isArray(n.content))for(let o of n.content)o.type==="tool_result"&&s.add(o.tool_use_id);let r=[];for(let n of e){if(!Array.isArray(n.content)){r.push(n);continue}let o=n.content.filter(i=>i.type==="tool_use"?s.has(i.id):i.type==="tool_result"?t.has(i.tool_use_id):!0);o.length!==0&&r.push({...n,content:o})}return r}buildTools(e){return e.map(t=>({name:t.name,description:t.description,inputSchema:t.inputSchema}))}}});var Hs=f(()=>{"use strict";$e();Cs();yt();Us();Ps();Fs();Bs();rn();nn()});var _t,zs=f(()=>{"use strict";_t=class{static{d(this,"RateLimiter")}buckets=new Map;check(e,t){let s=Date.now(),r=t.windowSeconds*1e3,n=this.buckets.get(e);if(!n)return{allowed:!0,remaining:t.maxInvocations,resetsAt:s+r};if(s>n.windowStart+r)return{allowed:!0,remaining:t.maxInvocations,resetsAt:s+r};let o=Math.max(0,t.maxInvocations-n.count);return{allowed:n.count<t.maxInvocations,remaining:o,resetsAt:n.windowStart+r}}increment(e,t){let s=Date.now(),r=t.windowSeconds*1e3,n=this.buckets.get(e);!n||s>n.windowStart+r?this.buckets.set(e,{count:1,windowStart:s}):n.count+=1}reset(){this.buckets.clear()}}});var St,on=f(()=>{"use strict";zs();St=class{static{d(this,"RuleEngine")}rules=[];rateLimiter=new _t;loadRules(e){this.rules=[...e].sort((t,s)=>t.priority-s.priority)}getRules(){return this.rules}evaluate(e){for(let t of this.rules)if(this.ruleMatches(t,e))return t.rateLimit&&t.effect==="allow"&&!this.checkRateLimit(t,e)?{allowed:!1,matchedRule:t,reason:`Rate limit exceeded for rule: ${t.id}`,timestamp:new Date}:{allowed:t.effect==="allow",matchedRule:t,reason:`Matched rule: ${t.id}`,timestamp:new Date};return{allowed:!1,matchedRule:void 0,reason:"No matching rule found \u2014 default deny",timestamp:new Date}}checkRateLimit(e,t){if(!e.rateLimit)return!0;let s=this.getScopeKey(e.scope,t),r=`${e.id}:${s}`;return this.rateLimiter.check(r,e.rateLimit).allowed?(this.rateLimiter.increment(r,e.rateLimit),!0):!1}resetRateLimits(){this.rateLimiter.reset()}getScopeKey(e,t){switch(e){case"global":return"global";case"user":return t.userId;case"conversation":return t.chatId??"unknown";case"platform":return t.platform}}ruleMatches(e,t){return!(!e.actions.includes("*")&&!e.actions.includes(t.action)||!e.riskLevels.includes(t.riskLevel)||e.conditions&&(e.conditions.users&&e.conditions.users.length>0&&!e.conditions.users.includes(t.userId)||e.conditions.platforms&&e.conditions.platforms.length>0&&!e.conditions.platforms.includes(t.platform)||e.conditions.chatType&&t.chatType&&e.conditions.chatType!==t.chatType||e.conditions.timeWindow&&!this.matchesTimeWindow(e.conditions.timeWindow)))}matchesTimeWindow(e){if(!e)return!0;let t=new Date;if(e.daysOfWeek&&e.daysOfWeek.length>0&&!e.daysOfWeek.includes(t.getDay()))return!1;let s=t.getHours();if(e.startHour!==void 0&&e.endHour!==void 0){if(e.startHour<=e.endHour){if(s<e.startHour||s>=e.endHour)return!1}else if(s>=e.endHour&&s<e.startHour)return!1}else if(e.startHour!==void 0){if(s<e.startHour)return!1}else if(e.endHour!==void 0&&s>=e.endHour)return!1;return!0}}});var an,cn,ln,fe,dn=f(()=>{"use strict";an=["allow","deny"],cn=["global","user","conversation","platform"],ln=["read","write","destructive","admin"],fe=class{static{d(this,"RuleLoader")}loadFromObject(e){if(!e||!Array.isArray(e.rules))throw new Error('Invalid data: expected an object with a "rules" array');return e.rules.map((t,s)=>this.validateRule(t,s))}validateRule(e,t){if(typeof e!="object"||e===null)throw new Error(`Rule at index ${t} is not an object`);let s=e;if(typeof s.id!="string"||s.id.length===0)throw new Error(`Rule at index ${t} is missing a valid "id" string`);if(typeof s.effect!="string"||!an.includes(s.effect))throw new Error(`Rule "${s.id}" has invalid "effect": expected one of ${an.join(", ")}`);if(typeof s.priority!="number"||!Number.isFinite(s.priority))throw new Error(`Rule "${s.id}" is missing a valid "priority" number`);if(typeof s.scope!="string"||!cn.includes(s.scope))throw new Error(`Rule "${s.id}" has invalid "scope": expected one of ${cn.join(", ")}`);if(!Array.isArray(s.actions)||s.actions.length===0)throw new Error(`Rule "${s.id}" is missing a valid "actions" array`);for(let n of s.actions)if(typeof n!="string")throw new Error(`Rule "${s.id}" has a non-string entry in "actions"`);if(!Array.isArray(s.riskLevels)||s.riskLevels.length===0)throw new Error(`Rule "${s.id}" is missing a valid "riskLevels" array`);for(let n of s.riskLevels)if(!ln.includes(n))throw new Error(`Rule "${s.id}" has invalid risk level "${n}": expected one of ${ln.join(", ")}`);let r={id:s.id,effect:s.effect,priority:s.priority,scope:s.scope,actions:s.actions,riskLevels:s.riskLevels};if(s.conditions!==void 0){if(typeof s.conditions!="object"||s.conditions===null)throw new Error(`Rule "${s.id}" has invalid "conditions": expected an object`);r.conditions=s.conditions}if(s.rateLimit!==void 0){if(typeof s.rateLimit!="object"||s.rateLimit===null)throw new Error(`Rule "${s.id}" has invalid "rateLimit": expected an object`);let n=s.rateLimit;if(typeof n.maxInvocations!="number"||typeof n.windowSeconds!="number")throw new Error(`Rule "${s.id}" has invalid "rateLimit": expected maxInvocations and windowSeconds numbers`);r.rateLimit=s.rateLimit}return r}}});import Si from"node:crypto";var kt,un=f(()=>{"use strict";kt=class{static{d(this,"SecurityManager")}ruleEngine;auditRepository;logger;constructor(e,t,s){this.ruleEngine=e,this.auditRepository=t,this.logger=s}evaluate(e){let t=this.ruleEngine.evaluate(e),s={id:Si.randomUUID(),timestamp:t.timestamp,userId:e.userId,action:e.action,riskLevel:e.riskLevel,ruleId:t.matchedRule?.id,effect:t.allowed?"allow":"deny",platform:e.platform,chatId:e.chatId,context:{chatType:e.chatType,reason:t.reason}};try{this.auditRepository.log(s)}catch(r){this.logger.error({err:r,auditEntry:s},"Failed to write audit log entry")}return this.logger.debug({userId:e.userId,action:e.action,allowed:t.allowed,ruleId:t.matchedRule?.id,reason:t.reason},"Security evaluation completed"),t}}});var ss=f(()=>{"use strict";on();zs();dn();un()});var _,O=f(()=>{"use strict";_=class{static{d(this,"Skill")}}});var Re,mn=f(()=>{"use strict";Re=class{static{d(this,"SkillRegistry")}skills=new Map;register(e){let{name:t}=e.metadata;if(this.skills.has(t))throw new Error(`Skill "${t}" is already registered`);this.skills.set(t,e)}get(e){return this.skills.get(e)}getAll(){return[...this.skills.values()]}has(e){return this.skills.has(e)}toToolDefinitions(){return this.getAll().map(e=>({name:e.metadata.name,description:e.metadata.description,inputSchema:e.metadata.inputSchema}))}}});var Ae,pn=f(()=>{"use strict";Ae=class{static{d(this,"SkillSandbox")}logger;constructor(e){this.logger=e}async execute(e,t,s,r,n){r=r??e.metadata.timeoutMs??3e4;let{name:o}=e.metadata;return this.logger.info({skill:o,input:t},"Skill execution started"),n?this.executeWithTracker(e,t,s,o,r,n):this.executeWithHardTimeout(e,t,s,o,r)}async executeWithTracker(e,t,s,r,n,o){return new Promise(i=>{let a=!1,l,u,h,m=d(()=>{l&&clearInterval(l),u&&clearTimeout(u),h&&clearTimeout(h)},"cleanup"),p=d(E=>{a||(a=!0,m(),i(E))},"finish");e.execute(t,s).then(E=>{this.logger.info({skill:r,success:E.success},"Skill execution completed"),p(E)},E=>{let w=E instanceof Error?E.message:String(E);this.logger.error({skill:r,error:w},"Skill execution failed"),p({success:!1,error:w})}),h=setTimeout(()=>{if(a)return;let E=o.getIdleMs();if(E>=12e4){let T=o.getSnapshot();this.logger.warn({skill:r,idleMs:E,state:T.state,iteration:T.iteration},"Agent inactive after initial timeout \u2014 aborting"),p({success:!1,error:`Skill "${r}" timed out \u2014 inactive for ${Math.round(E/1e3)}s (last state: ${T.state})`});return}let w=o.getSnapshot();this.logger.info({skill:r,idleMs:E,state:w.state,iteration:w.iteration,totalMs:w.totalElapsedMs},"Initial timeout reached but agent is active \u2014 extending"),l=setInterval(()=>{if(a){m();return}let T=o.getIdleMs(),k=o.getSnapshot();T>=12e4?(this.logger.warn({skill:r,idleMs:T,state:k.state,iteration:k.iteration,totalMs:k.totalElapsedMs},"Agent went inactive \u2014 aborting"),p({success:!1,error:`Skill "${r}" killed \u2014 inactive for ${Math.round(T/1e3)}s (last state: ${k.state})`})):this.logger.debug({skill:r,idleMs:T,state:k.state,iteration:k.iteration},"Agent still active, continuing...")},1e4)},n),u=setTimeout(()=>{if(a)return;let E=o.getSnapshot();this.logger.error({skill:r,totalMs:E.totalElapsedMs,state:E.state,iteration:E.iteration},"Absolute time limit reached \u2014 force killing agent"),p({success:!1,error:`Skill "${r}" force-killed after ${Math.round(12e5/6e4)} minutes (safety limit)`})},12e5)})}async executeWithHardTimeout(e,t,s,r,n){try{let o=await Promise.race([e.execute(t,s),new Promise((i,a)=>{setTimeout(()=>a(new Error(`Skill "${r}" timed out after ${n}ms`)),n)})]);return this.logger.info({skill:r,success:o.success},"Skill execution completed"),o}catch(o){let i=o instanceof Error?o.message:String(o);return this.logger.error({skill:r,error:i},"Skill execution failed"),{success:!1,error:i}}}}});var ge,Xs=f(()=>{"use strict";ge=class{static{d(this,"ActivityTracker")}state="starting";iteration=0;maxIterations=0;currentTool;lastPingAt;startedAt;history=[];onProgress;constructor(e){this.startedAt=Date.now(),this.lastPingAt=Date.now(),this.onProgress=e}ping(e,t){this.state=e,this.lastPingAt=Date.now(),t?.iteration!==void 0&&(this.iteration=t.iteration),t?.maxIterations!==void 0&&(this.maxIterations=t.maxIterations),this.currentTool=t?.tool,this.history.push({state:e,tool:t?.tool,iteration:this.iteration,timestamp:this.lastPingAt}),this.onProgress&&this.onProgress(this.formatStatus())}getIdleMs(){return Date.now()-this.lastPingAt}getTotalElapsedMs(){return Date.now()-this.startedAt}formatStatus(){let e=this.maxIterations>0?` (${this.iteration}/${this.maxIterations})`:"";switch(this.state){case"starting":return"Sub-agent starting...";case"llm_call":return`Sub-agent thinking...${e}`;case"tool_call":return this.currentTool?`Sub-agent using ${this.currentTool}${e}`:`Sub-agent using tool...${e}`;case"processing":return`Sub-agent processing...${e}`;case"done":return`Sub-agent done${e}`;default:return`Sub-agent working...${e}`}}getSnapshot(){return{state:this.state,iteration:this.iteration,maxIterations:this.maxIterations,lastPingAt:this.lastPingAt,idleMs:this.getIdleMs(),currentTool:this.currentTool,totalElapsedMs:this.getTotalElapsedMs(),history:[...this.history]}}}});import ki from"node:fs";import qs from"node:path";var rs,hn=f(()=>{"use strict";O();rs=class{static{d(this,"PluginLoader")}async loadFromDirectory(e){let t=qs.resolve(e),s;try{s=await ki.promises.readdir(t)}catch(o){let i=o instanceof Error?o.message:String(o);return console.warn(`PluginLoader: failed to read directory "${t}": ${i}`),[]}let r=s.filter(o=>o.endsWith(".js")),n=[];for(let o of r){let i=qs.join(t,o);try{let a=await this.loadFromFile(i);n.push(a)}catch(a){let l=a instanceof Error?a.message:String(a);console.warn(`PluginLoader: skipping "${i}": ${l}`)}}return n}async loadFromFile(e){let t=qs.resolve(e),n=(await import(`file:///${t.replace(/\\/g,"/")}`)).default;if(typeof n!="function")throw new Error(`Module "${t}" does not have a default export that is a class`);let o=new n;if(!(o instanceof _))throw new Error(`Default export of "${t}" does not extend Skill`);return this.validateMetadata(o,t),o}validateMetadata(e,t){let{metadata:s}=e;if(!s)throw new Error(`Plugin "${t}" is missing metadata`);if(!s.name||typeof s.name!="string")throw new Error(`Plugin "${t}" has invalid or missing metadata.name`);if(!s.description||typeof s.description!="string")throw new Error(`Plugin "${t}" has invalid or missing metadata.description`);if(!["read","write","destructive","admin"].includes(s.riskLevel))throw new Error(`Plugin "${t}" has invalid metadata.riskLevel: "${String(s.riskLevel)}"`);if(!s.version||typeof s.version!="string")throw new Error(`Plugin "${t}" has invalid or missing metadata.version`)}}});var vi,xi,Le,fn=f(()=>{"use strict";O();vi=/^[\d+\-*/().,%\s]|Math\.(sin|cos|tan|sqrt|pow|abs|floor|ceil|round|log|log2|log10|PI|E)/,xi=/^[0-9+\-*/().,\s%]*(Math\.(sin|cos|tan|sqrt|pow|abs|floor|ceil|round|log|log2|log10|PI|E)[(0-9+\-*/().,\s%]*)*$/,Le=class extends _{static{d(this,"CalculatorSkill")}metadata={name:"calculator",description:"Evaluate mathematical expressions. Use for any calculation, unit conversion, or math question the user asks.",riskLevel:"read",version:"1.0.0",inputSchema:{type:"object",properties:{expression:{type:"string",description:"The mathematical expression to evaluate"}},required:["expression"]}};async execute(e,t){let s=e.expression;if(!s||typeof s!="string")return{success:!1,error:"Invalid expression: input must be a non-empty string"};let r=s.trim();if(!vi.test(r))return{success:!1,error:`Invalid expression: "${r}" contains disallowed characters`};if(!xi.test(r))return{success:!1,error:`Invalid expression: "${r}" contains disallowed constructs`};try{let o=new Function("Math",`"use strict"; return (${r});`)(Math);return typeof o!="number"||!isFinite(o)?{success:!1,error:`Invalid expression: "${r}" did not produce a finite number`}:{success:!0,data:o,display:`${r} = ${o}`}}catch{return{success:!1,error:`Invalid expression: "${r}"`}}}}});var Me,gn=f(()=>{"use strict";O();Me=class extends _{static{d(this,"SystemInfoSkill")}metadata={name:"system_info",description:'Get system information: current date/time (datetime), system stats (general), memory usage (memory), or uptime (uptime). Use "datetime" when the user asks what day/time it is.',riskLevel:"read",version:"1.0.0",inputSchema:{type:"object",properties:{category:{type:"string",enum:["general","memory","uptime","datetime"],description:"Category of system info (use datetime for current date/time)"}},required:["category"]}};async execute(e,t){let s=e.category;switch(s){case"general":return this.getGeneralInfo();case"memory":return this.getMemoryInfo();case"uptime":return this.getUptimeInfo();case"datetime":return this.getDateTimeInfo();default:return{success:!1,error:`Unknown category: "${String(s)}". Valid categories: general, memory, uptime`}}}getGeneralInfo(){let e={nodeVersion:process.version,platform:process.platform,arch:process.arch};return{success:!0,data:e,display:`Node.js ${e.nodeVersion} on ${e.platform} (${e.arch})`}}getMemoryInfo(){let e=process.memoryUsage(),t=d(r=>(r/1024/1024).toFixed(2),"toMB"),s={rss:`${t(e.rss)} MB`,heapTotal:`${t(e.heapTotal)} MB`,heapUsed:`${t(e.heapUsed)} MB`,external:`${t(e.external)} MB`};return{success:!0,data:s,display:`Memory \u2014 RSS: ${s.rss}, Heap: ${s.heapUsed} / ${s.heapTotal}, External: ${s.external}`}}getUptimeInfo(){let e=process.uptime(),t=Math.floor(e/3600),s=Math.floor(e%3600/60),r=Math.floor(e%60),n={uptimeSeconds:e,formatted:`${t}h ${s}m ${r}s`};return{success:!0,data:n,display:`Uptime: ${n.formatted}`}}getDateTimeInfo(){let e=new Date,t={iso:e.toISOString(),date:e.toLocaleDateString("de-DE",{weekday:"long",year:"numeric",month:"long",day:"numeric"}),time:e.toLocaleTimeString("de-DE"),timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,timestamp:e.getTime()};return{success:!0,data:t,display:`${t.date}, ${t.time} (${t.timezone})`}}}});var Ne,yn=f(()=>{"use strict";O();Ne=class extends _{static{d(this,"WebSearchSkill")}config;metadata={name:"web_search",description:"Search the internet for current information, news, facts, or anything the user asks about that you don't know. Use this whenever you need up-to-date information.",riskLevel:"read",version:"1.1.0",inputSchema:{type:"object",properties:{query:{type:"string",description:"The search query"},count:{type:"number",description:"Number of results to return (default: 5, max: 10)"}},required:["query"]}};constructor(e){super(),this.config=e}async execute(e,t){let s=e.query,r=Math.min(Math.max(1,e.count||5),10);if(!s||typeof s!="string")return{success:!1,error:'Invalid input: "query" must be a non-empty string'};if(!this.config)return{success:!1,error:"Web search is not configured. Run `alfred setup` to configure a search provider."};if((this.config.provider==="brave"||this.config.provider==="tavily")&&!this.config.apiKey)return{success:!1,error:`Web search requires an API key for ${this.config.provider}. Run \`alfred setup\` to configure it.`};try{let o;switch(this.config.provider){case"brave":o=await this.searchBrave(s,r);break;case"searxng":o=await this.searchSearXNG(s,r);break;case"tavily":o=await this.searchTavily(s,r);break;case"duckduckgo":o=await this.searchDuckDuckGo(s,r);break;default:return{success:!1,error:`Unknown search provider: ${this.config.provider}`}}if(o.length===0)return{success:!0,data:{results:[]},display:`No results found for "${s}".`};let i=o.map((a,l)=>`${l+1}. **${a.title}**
|
|
312
|
+
When the user tells you facts about themselves or preferences, use the memory tool to save them for future reference.`;return a}buildMessages(e){let t=e.filter(s=>s.role==="user"||s.role==="assistant").map(s=>{if(s.toolCalls){let r;try{r=JSON.parse(s.toolCalls)}catch{r=[]}if(s.role==="assistant"){let i=r,a=[];s.content&&a.push({type:"text",text:s.content});for(let l of i)a.push({type:"tool_use",id:l.id,name:l.name,input:l.input});return{role:"assistant",content:a}}let n=r,o=[];for(let i of n)i.type==="tool_result"&&o.push(i);return o.length>0?{role:"user",content:o}:{role:"user",content:s.content||""}}return{role:s.role,content:s.content}});return this.sanitizeToolMessages(t)}sanitizeToolMessages(e){let t=new Set;for(let n of e)if(n.role==="assistant"&&Array.isArray(n.content))for(let o of n.content)o.type==="tool_use"&&t.add(o.id);let s=new Set;for(let n of e)if(n.role==="user"&&Array.isArray(n.content))for(let o of n.content)o.type==="tool_result"&&s.add(o.tool_use_id);let r=[];for(let n of e){if(!Array.isArray(n.content)){r.push(n);continue}let o=n.content.filter(i=>i.type==="tool_use"?s.has(i.id):i.type==="tool_result"?t.has(i.tool_use_id):!0);o.length!==0&&r.push({...n,content:o})}return r}buildTools(e){return e.map(t=>({name:t.name,description:t.description,inputSchema:t.inputSchema}))}}});var Hs=f(()=>{"use strict";$e();Cs();yt();Us();Ps();Fs();Bs();rn();nn()});var _t,Xs=f(()=>{"use strict";_t=class{static{d(this,"RateLimiter")}buckets=new Map;check(e,t){let s=Date.now(),r=t.windowSeconds*1e3,n=this.buckets.get(e);if(!n)return{allowed:!0,remaining:t.maxInvocations,resetsAt:s+r};if(s>n.windowStart+r)return{allowed:!0,remaining:t.maxInvocations,resetsAt:s+r};let o=Math.max(0,t.maxInvocations-n.count);return{allowed:n.count<t.maxInvocations,remaining:o,resetsAt:n.windowStart+r}}increment(e,t){let s=Date.now(),r=t.windowSeconds*1e3,n=this.buckets.get(e);!n||s>n.windowStart+r?this.buckets.set(e,{count:1,windowStart:s}):n.count+=1}reset(){this.buckets.clear()}}});var St,on=f(()=>{"use strict";Xs();St=class{static{d(this,"RuleEngine")}rules=[];rateLimiter=new _t;loadRules(e){this.rules=[...e].sort((t,s)=>t.priority-s.priority)}getRules(){return this.rules}evaluate(e){for(let t of this.rules)if(this.ruleMatches(t,e))return t.rateLimit&&t.effect==="allow"&&!this.checkRateLimit(t,e)?{allowed:!1,matchedRule:t,reason:`Rate limit exceeded for rule: ${t.id}`,timestamp:new Date}:{allowed:t.effect==="allow",matchedRule:t,reason:`Matched rule: ${t.id}`,timestamp:new Date};return{allowed:!1,matchedRule:void 0,reason:"No matching rule found \u2014 default deny",timestamp:new Date}}checkRateLimit(e,t){if(!e.rateLimit)return!0;let s=this.getScopeKey(e.scope,t),r=`${e.id}:${s}`;return this.rateLimiter.check(r,e.rateLimit).allowed?(this.rateLimiter.increment(r,e.rateLimit),!0):!1}resetRateLimits(){this.rateLimiter.reset()}getScopeKey(e,t){switch(e){case"global":return"global";case"user":return t.userId;case"conversation":return t.chatId??"unknown";case"platform":return t.platform}}ruleMatches(e,t){return!(!e.actions.includes("*")&&!e.actions.includes(t.action)||!e.riskLevels.includes(t.riskLevel)||e.conditions&&(e.conditions.users&&e.conditions.users.length>0&&!e.conditions.users.includes(t.userId)||e.conditions.platforms&&e.conditions.platforms.length>0&&!e.conditions.platforms.includes(t.platform)||e.conditions.chatType&&t.chatType&&e.conditions.chatType!==t.chatType||e.conditions.timeWindow&&!this.matchesTimeWindow(e.conditions.timeWindow)))}matchesTimeWindow(e){if(!e)return!0;let t=new Date;if(e.daysOfWeek&&e.daysOfWeek.length>0&&!e.daysOfWeek.includes(t.getDay()))return!1;let s=t.getHours();if(e.startHour!==void 0&&e.endHour!==void 0){if(e.startHour<=e.endHour){if(s<e.startHour||s>=e.endHour)return!1}else if(s>=e.endHour&&s<e.startHour)return!1}else if(e.startHour!==void 0){if(s<e.startHour)return!1}else if(e.endHour!==void 0&&s>=e.endHour)return!1;return!0}}});var an,cn,ln,fe,dn=f(()=>{"use strict";an=["allow","deny"],cn=["global","user","conversation","platform"],ln=["read","write","destructive","admin"],fe=class{static{d(this,"RuleLoader")}loadFromObject(e){if(!e||!Array.isArray(e.rules))throw new Error('Invalid data: expected an object with a "rules" array');return e.rules.map((t,s)=>this.validateRule(t,s))}validateRule(e,t){if(typeof e!="object"||e===null)throw new Error(`Rule at index ${t} is not an object`);let s=e;if(typeof s.id!="string"||s.id.length===0)throw new Error(`Rule at index ${t} is missing a valid "id" string`);if(typeof s.effect!="string"||!an.includes(s.effect))throw new Error(`Rule "${s.id}" has invalid "effect": expected one of ${an.join(", ")}`);if(typeof s.priority!="number"||!Number.isFinite(s.priority))throw new Error(`Rule "${s.id}" is missing a valid "priority" number`);if(typeof s.scope!="string"||!cn.includes(s.scope))throw new Error(`Rule "${s.id}" has invalid "scope": expected one of ${cn.join(", ")}`);if(!Array.isArray(s.actions)||s.actions.length===0)throw new Error(`Rule "${s.id}" is missing a valid "actions" array`);for(let n of s.actions)if(typeof n!="string")throw new Error(`Rule "${s.id}" has a non-string entry in "actions"`);if(!Array.isArray(s.riskLevels)||s.riskLevels.length===0)throw new Error(`Rule "${s.id}" is missing a valid "riskLevels" array`);for(let n of s.riskLevels)if(!ln.includes(n))throw new Error(`Rule "${s.id}" has invalid risk level "${n}": expected one of ${ln.join(", ")}`);let r={id:s.id,effect:s.effect,priority:s.priority,scope:s.scope,actions:s.actions,riskLevels:s.riskLevels};if(s.conditions!==void 0){if(typeof s.conditions!="object"||s.conditions===null)throw new Error(`Rule "${s.id}" has invalid "conditions": expected an object`);r.conditions=s.conditions}if(s.rateLimit!==void 0){if(typeof s.rateLimit!="object"||s.rateLimit===null)throw new Error(`Rule "${s.id}" has invalid "rateLimit": expected an object`);let n=s.rateLimit;if(typeof n.maxInvocations!="number"||typeof n.windowSeconds!="number")throw new Error(`Rule "${s.id}" has invalid "rateLimit": expected maxInvocations and windowSeconds numbers`);r.rateLimit=s.rateLimit}return r}}});import Si from"node:crypto";var kt,un=f(()=>{"use strict";kt=class{static{d(this,"SecurityManager")}ruleEngine;auditRepository;logger;constructor(e,t,s){this.ruleEngine=e,this.auditRepository=t,this.logger=s}evaluate(e){let t=this.ruleEngine.evaluate(e),s={id:Si.randomUUID(),timestamp:t.timestamp,userId:e.userId,action:e.action,riskLevel:e.riskLevel,ruleId:t.matchedRule?.id,effect:t.allowed?"allow":"deny",platform:e.platform,chatId:e.chatId,context:{chatType:e.chatType,reason:t.reason}};try{this.auditRepository.log(s)}catch(r){this.logger.error({err:r,auditEntry:s},"Failed to write audit log entry")}return this.logger.debug({userId:e.userId,action:e.action,allowed:t.allowed,ruleId:t.matchedRule?.id,reason:t.reason},"Security evaluation completed"),t}}});var ss=f(()=>{"use strict";on();Xs();dn();un()});var _,O=f(()=>{"use strict";_=class{static{d(this,"Skill")}}});var Re,mn=f(()=>{"use strict";Re=class{static{d(this,"SkillRegistry")}skills=new Map;register(e){let{name:t}=e.metadata;if(this.skills.has(t))throw new Error(`Skill "${t}" is already registered`);this.skills.set(t,e)}get(e){return this.skills.get(e)}getAll(){return[...this.skills.values()]}has(e){return this.skills.has(e)}toToolDefinitions(){return this.getAll().map(e=>({name:e.metadata.name,description:e.metadata.description,inputSchema:e.metadata.inputSchema}))}}});var Ae,pn=f(()=>{"use strict";Ae=class{static{d(this,"SkillSandbox")}logger;constructor(e){this.logger=e}async execute(e,t,s,r,n){r=r??e.metadata.timeoutMs??3e4;let{name:o}=e.metadata;return this.logger.info({skill:o,input:t},"Skill execution started"),n?this.executeWithTracker(e,t,s,o,r,n):this.executeWithHardTimeout(e,t,s,o,r)}async executeWithTracker(e,t,s,r,n,o){return new Promise(i=>{let a=!1,l,u,h,m=d(()=>{l&&clearInterval(l),u&&clearTimeout(u),h&&clearTimeout(h)},"cleanup"),p=d(E=>{a||(a=!0,m(),i(E))},"finish");e.execute(t,s).then(E=>{this.logger.info({skill:r,success:E.success},"Skill execution completed"),p(E)},E=>{let w=E instanceof Error?E.message:String(E);this.logger.error({skill:r,error:w},"Skill execution failed"),p({success:!1,error:w})}),h=setTimeout(()=>{if(a)return;let E=o.getIdleMs();if(E>=12e4){let T=o.getSnapshot();this.logger.warn({skill:r,idleMs:E,state:T.state,iteration:T.iteration},"Agent inactive after initial timeout \u2014 aborting"),p({success:!1,error:`Skill "${r}" timed out \u2014 inactive for ${Math.round(E/1e3)}s (last state: ${T.state})`});return}let w=o.getSnapshot();this.logger.info({skill:r,idleMs:E,state:w.state,iteration:w.iteration,totalMs:w.totalElapsedMs},"Initial timeout reached but agent is active \u2014 extending"),l=setInterval(()=>{if(a){m();return}let T=o.getIdleMs(),k=o.getSnapshot();T>=12e4?(this.logger.warn({skill:r,idleMs:T,state:k.state,iteration:k.iteration,totalMs:k.totalElapsedMs},"Agent went inactive \u2014 aborting"),p({success:!1,error:`Skill "${r}" killed \u2014 inactive for ${Math.round(T/1e3)}s (last state: ${k.state})`})):this.logger.debug({skill:r,idleMs:T,state:k.state,iteration:k.iteration},"Agent still active, continuing...")},1e4)},n),u=setTimeout(()=>{if(a)return;let E=o.getSnapshot();this.logger.error({skill:r,totalMs:E.totalElapsedMs,state:E.state,iteration:E.iteration},"Absolute time limit reached \u2014 force killing agent"),p({success:!1,error:`Skill "${r}" force-killed after ${Math.round(12e5/6e4)} minutes (safety limit)`})},12e5)})}async executeWithHardTimeout(e,t,s,r,n){try{let o=await Promise.race([e.execute(t,s),new Promise((i,a)=>{setTimeout(()=>a(new Error(`Skill "${r}" timed out after ${n}ms`)),n)})]);return this.logger.info({skill:r,success:o.success},"Skill execution completed"),o}catch(o){let i=o instanceof Error?o.message:String(o);return this.logger.error({skill:r,error:i},"Skill execution failed"),{success:!1,error:i}}}}});var ge,zs=f(()=>{"use strict";ge=class{static{d(this,"ActivityTracker")}state="starting";iteration=0;maxIterations=0;currentTool;lastPingAt;startedAt;history=[];onProgress;constructor(e){this.startedAt=Date.now(),this.lastPingAt=Date.now(),this.onProgress=e}ping(e,t){this.state=e,this.lastPingAt=Date.now(),t?.iteration!==void 0&&(this.iteration=t.iteration),t?.maxIterations!==void 0&&(this.maxIterations=t.maxIterations),this.currentTool=t?.tool,this.history.push({state:e,tool:t?.tool,iteration:this.iteration,timestamp:this.lastPingAt}),this.onProgress&&this.onProgress(this.formatStatus())}getIdleMs(){return Date.now()-this.lastPingAt}getTotalElapsedMs(){return Date.now()-this.startedAt}formatStatus(){let e=this.maxIterations>0?` (${this.iteration}/${this.maxIterations})`:"";switch(this.state){case"starting":return"Sub-agent starting...";case"llm_call":return`Sub-agent thinking...${e}`;case"tool_call":return this.currentTool?`Sub-agent using ${this.currentTool}${e}`:`Sub-agent using tool...${e}`;case"processing":return`Sub-agent processing...${e}`;case"done":return`Sub-agent done${e}`;default:return`Sub-agent working...${e}`}}getSnapshot(){return{state:this.state,iteration:this.iteration,maxIterations:this.maxIterations,lastPingAt:this.lastPingAt,idleMs:this.getIdleMs(),currentTool:this.currentTool,totalElapsedMs:this.getTotalElapsedMs(),history:[...this.history]}}}});import ki from"node:fs";import qs from"node:path";var rs,hn=f(()=>{"use strict";O();rs=class{static{d(this,"PluginLoader")}async loadFromDirectory(e){let t=qs.resolve(e),s;try{s=await ki.promises.readdir(t)}catch(o){let i=o instanceof Error?o.message:String(o);return console.warn(`PluginLoader: failed to read directory "${t}": ${i}`),[]}let r=s.filter(o=>o.endsWith(".js")),n=[];for(let o of r){let i=qs.join(t,o);try{let a=await this.loadFromFile(i);n.push(a)}catch(a){let l=a instanceof Error?a.message:String(a);console.warn(`PluginLoader: skipping "${i}": ${l}`)}}return n}async loadFromFile(e){let t=qs.resolve(e),n=(await import(`file:///${t.replace(/\\/g,"/")}`)).default;if(typeof n!="function")throw new Error(`Module "${t}" does not have a default export that is a class`);let o=new n;if(!(o instanceof _))throw new Error(`Default export of "${t}" does not extend Skill`);return this.validateMetadata(o,t),o}validateMetadata(e,t){let{metadata:s}=e;if(!s)throw new Error(`Plugin "${t}" is missing metadata`);if(!s.name||typeof s.name!="string")throw new Error(`Plugin "${t}" has invalid or missing metadata.name`);if(!s.description||typeof s.description!="string")throw new Error(`Plugin "${t}" has invalid or missing metadata.description`);if(!["read","write","destructive","admin"].includes(s.riskLevel))throw new Error(`Plugin "${t}" has invalid metadata.riskLevel: "${String(s.riskLevel)}"`);if(!s.version||typeof s.version!="string")throw new Error(`Plugin "${t}" has invalid or missing metadata.version`)}}});var vi,xi,Le,fn=f(()=>{"use strict";O();vi=/^[\d+\-*/().,%\s]|Math\.(sin|cos|tan|sqrt|pow|abs|floor|ceil|round|log|log2|log10|PI|E)/,xi=/^[0-9+\-*/().,\s%]*(Math\.(sin|cos|tan|sqrt|pow|abs|floor|ceil|round|log|log2|log10|PI|E)[(0-9+\-*/().,\s%]*)*$/,Le=class extends _{static{d(this,"CalculatorSkill")}metadata={name:"calculator",description:"Evaluate mathematical expressions. Use for any calculation, unit conversion, or math question the user asks.",riskLevel:"read",version:"1.0.0",inputSchema:{type:"object",properties:{expression:{type:"string",description:"The mathematical expression to evaluate"}},required:["expression"]}};async execute(e,t){let s=e.expression;if(!s||typeof s!="string")return{success:!1,error:"Invalid expression: input must be a non-empty string"};let r=s.trim();if(!vi.test(r))return{success:!1,error:`Invalid expression: "${r}" contains disallowed characters`};if(!xi.test(r))return{success:!1,error:`Invalid expression: "${r}" contains disallowed constructs`};try{let o=new Function("Math",`"use strict"; return (${r});`)(Math);return typeof o!="number"||!isFinite(o)?{success:!1,error:`Invalid expression: "${r}" did not produce a finite number`}:{success:!0,data:o,display:`${r} = ${o}`}}catch{return{success:!1,error:`Invalid expression: "${r}"`}}}}});var Me,gn=f(()=>{"use strict";O();Me=class extends _{static{d(this,"SystemInfoSkill")}metadata={name:"system_info",description:'Get system information: current date/time (datetime), system stats (general), memory usage (memory), or uptime (uptime). Use "datetime" when the user asks what day/time it is.',riskLevel:"read",version:"1.0.0",inputSchema:{type:"object",properties:{category:{type:"string",enum:["general","memory","uptime","datetime"],description:"Category of system info (use datetime for current date/time)"}},required:["category"]}};async execute(e,t){let s=e.category;switch(s){case"general":return this.getGeneralInfo();case"memory":return this.getMemoryInfo();case"uptime":return this.getUptimeInfo();case"datetime":return this.getDateTimeInfo();default:return{success:!1,error:`Unknown category: "${String(s)}". Valid categories: general, memory, uptime`}}}getGeneralInfo(){let e={nodeVersion:process.version,platform:process.platform,arch:process.arch};return{success:!0,data:e,display:`Node.js ${e.nodeVersion} on ${e.platform} (${e.arch})`}}getMemoryInfo(){let e=process.memoryUsage(),t=d(r=>(r/1024/1024).toFixed(2),"toMB"),s={rss:`${t(e.rss)} MB`,heapTotal:`${t(e.heapTotal)} MB`,heapUsed:`${t(e.heapUsed)} MB`,external:`${t(e.external)} MB`};return{success:!0,data:s,display:`Memory \u2014 RSS: ${s.rss}, Heap: ${s.heapUsed} / ${s.heapTotal}, External: ${s.external}`}}getUptimeInfo(){let e=process.uptime(),t=Math.floor(e/3600),s=Math.floor(e%3600/60),r=Math.floor(e%60),n={uptimeSeconds:e,formatted:`${t}h ${s}m ${r}s`};return{success:!0,data:n,display:`Uptime: ${n.formatted}`}}getDateTimeInfo(){let e=new Date,t={iso:e.toISOString(),date:e.toLocaleDateString("de-DE",{weekday:"long",year:"numeric",month:"long",day:"numeric"}),time:e.toLocaleTimeString("de-DE"),timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,timestamp:e.getTime()};return{success:!0,data:t,display:`${t.date}, ${t.time} (${t.timezone})`}}}});var Ne,yn=f(()=>{"use strict";O();Ne=class extends _{static{d(this,"WebSearchSkill")}config;metadata={name:"web_search",description:"Search the internet for current information, news, facts, or anything the user asks about that you don't know. Use this whenever you need up-to-date information.",riskLevel:"read",version:"1.1.0",inputSchema:{type:"object",properties:{query:{type:"string",description:"The search query"},count:{type:"number",description:"Number of results to return (default: 5, max: 10)"}},required:["query"]}};constructor(e){super(),this.config=e}async execute(e,t){let s=e.query,r=Math.min(Math.max(1,e.count||5),10);if(!s||typeof s!="string")return{success:!1,error:'Invalid input: "query" must be a non-empty string'};if(!this.config)return{success:!1,error:"Web search is not configured. Run `alfred setup` to configure a search provider."};if((this.config.provider==="brave"||this.config.provider==="tavily")&&!this.config.apiKey)return{success:!1,error:`Web search requires an API key for ${this.config.provider}. Run \`alfred setup\` to configure it.`};try{let o;switch(this.config.provider){case"brave":o=await this.searchBrave(s,r);break;case"searxng":o=await this.searchSearXNG(s,r);break;case"tavily":o=await this.searchTavily(s,r);break;case"duckduckgo":o=await this.searchDuckDuckGo(s,r);break;default:return{success:!1,error:`Unknown search provider: ${this.config.provider}`}}if(o.length===0)return{success:!0,data:{results:[]},display:`No results found for "${s}".`};let i=o.map((a,l)=>`${l+1}. **${a.title}**
|
|
306
313
|
${a.url}
|
|
307
314
|
${a.snippet}`).join(`
|
|
308
315
|
|
|
@@ -328,7 +335,7 @@ ${r.map(n=>`- ${n.key}: "${n.value}"`).join(`
|
|
|
328
335
|
${r.map(o=>`- [${o.category}] ${o.key}: "${o.value}"`).join(`
|
|
329
336
|
`)}`}}deleteMemory(e,t){let s=e.key;if(!s||typeof s!="string")return{success:!1,error:'Missing required field "key" for delete action'};let r=this.memoryRepo.delete(t.userId,s);return{success:!0,data:{key:s,deleted:r},display:r?`Memory "${s}" deleted.`:`No memory found for key "${s}".`}}async semanticSearchMemories(e,t){let s=e.query;if(!s||typeof s!="string")return{success:!1,error:'Missing required field "query" for semantic_search action'};if(!this.embeddingService)return this.searchMemories(e,t);let r=await this.embeddingService.semanticSearch(t.userId,s,10);return r.length===0?this.searchMemories(e,t):{success:!0,data:r,display:`Found ${r.length} semantically related memory(ies):
|
|
330
337
|
${r.map(n=>`- ${n.key}: "${n.value}" (score: ${n.score.toFixed(2)})`).join(`
|
|
331
|
-
`)}`}}}});var Ai,Li,Mi,Fe,vn=f(()=>{"use strict";O();
|
|
338
|
+
`)}`}}}});var Ai,Li,Mi,Fe,vn=f(()=>{"use strict";O();zs();Ai=5,Li=15,Mi=12e4,Fe=class extends _{static{d(this,"DelegateSkill")}llm;skillRegistry;skillSandbox;securityManager;metadata={name:"delegate",description:'Delegate a complex sub-task to an autonomous sub-agent that has full tool access. The sub-agent can use shell, web search, calculator, memory, email, and all other tools. Use when a task is independent enough to run in parallel or when it requires a focused, multi-step workflow (e.g. "research X and summarize", "find all TODO files and list them", "check the weather and draft a packing list"). Control depth with max_iterations (default 5, max 15).',riskLevel:"write",version:"3.0.0",timeoutMs:Mi,inputSchema:{type:"object",properties:{task:{type:"string",description:"The task to delegate to the sub-agent. Be specific about what you want."},context:{type:"string",description:"Additional context the sub-agent needs (optional)"},max_iterations:{type:"number",description:"Max tool iterations (1-15). Use higher values for complex multi-step tasks. Default: 5."}},required:["task"]}};onProgress;constructor(e,t,s,r){super(),this.llm=e,this.skillRegistry=t,this.skillSandbox=s,this.securityManager=r}setProgressCallback(e){this.onProgress=e}createTracker(){return new ge(this.onProgress)}async execute(e,t){let s=e.task,r=e.context;if(!s||typeof s!="string")return{success:!1,error:'Missing required field "task"'};let n=e.max_iterations,o=n?Math.max(1,Math.min(Li,Math.round(n))):Ai,i=t.onProgress??this.onProgress,a=t.tracker?t.tracker:new ge(i);a.ping("starting",{maxIterations:o});let l=this.buildSubAgentTools(),u="You are a sub-agent of Alfred, a personal AI assistant. Complete the assigned task using the tools available to you. Work step by step: use tools to gather information, then synthesize a clear result. Be concise and return only the final answer when done.",h=s;r&&typeof r=="string"&&(h=`${s}
|
|
332
339
|
|
|
333
340
|
Additional context: ${r}`);let m=[{role:"user",content:h}];try{let p=0,E=0,w=0;for(;;){a.ping("llm_call",{iteration:p,maxIterations:o});let T=await this.llm.complete({messages:m,system:u,tools:l.length>0?l:void 0,maxTokens:2048,tier:"strong"});if(E+=T.usage.inputTokens,w+=T.usage.outputTokens,a.ping("processing",{iteration:p,maxIterations:o}),!T.toolCalls||T.toolCalls.length===0||p>=o)return a.ping("done",{iteration:p,maxIterations:o}),{success:!0,data:{response:T.content,iterations:p,usage:{inputTokens:E,outputTokens:w}},display:T.content};p++;let k=[];T.content&&k.push({type:"text",text:T.content});for(let x of T.toolCalls)k.push({type:"tool_use",id:x.id,name:x.name,input:x.input});m.push({role:"assistant",content:k});let b=[];for(let x of T.toolCalls){a.ping("tool_call",{iteration:p,maxIterations:o,tool:x.name});let L=await this.executeSubAgentTool(x,t);b.push({type:"tool_result",tool_use_id:x.id,content:L.content,is_error:L.isError})}m.push({role:"user",content:b})}}catch(p){return{success:!1,error:`Sub-agent failed: ${p instanceof Error?p.message:String(p)}`}}}buildSubAgentTools(){return this.skillRegistry?this.skillRegistry.getAll().filter(e=>e.metadata.name!=="delegate").map(e=>({name:e.metadata.name,description:e.metadata.description,inputSchema:e.metadata.inputSchema})):[]}async executeSubAgentTool(e,t){let s=this.skillRegistry?.get(e.name);if(!s)return{content:`Error: Unknown tool "${e.name}"`,isError:!0};if(this.securityManager){let r=this.securityManager.evaluate({userId:t.userId,action:e.name,riskLevel:s.metadata.riskLevel,platform:t.platform,chatId:t.chatId,chatType:t.chatType});if(!r.allowed)return{content:`Access denied: ${r.reason}`,isError:!0}}if(this.skillSandbox){let r=await this.skillSandbox.execute(s,e.input,t);return{content:r.display??(r.success?JSON.stringify(r.data):r.error??"Unknown error"),isError:!r.success}}try{let r=await s.execute(e.input,t);return{content:r.display??(r.success?JSON.stringify(r.data):r.error??"Unknown error"),isError:!r.success}}catch(r){return{content:`Skill execution failed: ${r instanceof Error?r.message:String(r)}`,isError:!0}}}}});var je,xn=f(()=>{"use strict";O();je=class extends _{static{d(this,"EmailSkill")}config;metadata={name:"email",description:"Access the user's email: check inbox, read messages, search emails, or send new emails. Use when the user asks about their emails or wants to send one.",riskLevel:"write",version:"1.0.0",inputSchema:{type:"object",properties:{action:{type:"string",enum:["inbox","read","search","send"],description:"The email action to perform"},count:{type:"number",description:"Number of emails to fetch (for inbox, default: 10)"},messageId:{type:"string",description:"Message sequence number to read (for read action)"},query:{type:"string",description:"Search query (for search action)"},to:{type:"string",description:"Recipient email address (for send action)"},subject:{type:"string",description:"Email subject (for send action)"},body:{type:"string",description:"Email body text (for send action)"}},required:["action"]}};constructor(e){super(),this.config=e}async execute(e,t){if(!this.config)return{success:!1,error:"Email is not configured. Run `alfred setup` to configure email access."};let s=e.action;try{switch(s){case"inbox":return await this.fetchInbox(e.count);case"read":return await this.readMessage(e.messageId);case"search":return await this.searchMessages(e.query,e.count);case"send":return await this.sendMessage(e.to,e.subject,e.body);default:return{success:!1,error:`Unknown action: ${s}. Use: inbox, read, search, send`}}}catch(r){return{success:!1,error:`Email error: ${r instanceof Error?r.message:String(r)}`}}}async fetchInbox(e){let t=Math.min(Math.max(1,e??10),50),{ImapFlow:s}=await import("imapflow"),r=new s({host:this.config.imap.host,port:this.config.imap.port,secure:this.config.imap.secure,auth:this.config.auth,logger:!1});try{await r.connect();let n=await r.getMailboxLock("INBOX");try{let o=[],i=r.mailbox,a=i&&typeof i=="object"?i.exists??0:0;if(a===0)return{success:!0,data:{messages:[]},display:"Inbox is empty."};let u=`${Math.max(1,a-t+1)}:*`;for await(let p of r.fetch(u,{envelope:!0,flags:!0})){let E=p.envelope?.from?.[0],w=E?E.name?`${E.name} <${E.address}>`:E.address??"unknown":"unknown";o.push({seq:p.seq,from:w,subject:p.envelope?.subject??"(no subject)",date:p.envelope?.date?.toISOString()??"",seen:p.flags?.has("\\Seen")??!1})}o.reverse();let h=o.length===0?"No messages found.":o.map((p,E)=>{let w=p.seen?"":" [UNREAD]";return`${E+1}. [#${p.seq}]${w} ${p.subject}
|
|
334
341
|
From: ${p.from}
|
|
@@ -368,9 +375,9 @@ ${E.slice(0,2e3)}`}}catch(a){return{success:!1,error:`HTTP request failed: ${a i
|
|
|
368
375
|
${r}`}}let s=j.readFileSync(e,"utf-8");return{success:!0,data:{path:e,size:t.size,content:s},display:s}}catch(t){return{success:!1,error:`Cannot read "${e}": ${t.message}`}}}writeFile(e,t){if(t==null)return{success:!1,error:'Missing "content" for write action'};try{let s=vt.dirname(e);return j.mkdirSync(s,{recursive:!0}),j.writeFileSync(e,t,"utf-8"),{success:!0,data:{path:e,bytes:Buffer.byteLength(t)},display:`Written ${Buffer.byteLength(t)} bytes to ${e}`}}catch(s){return{success:!1,error:`Cannot write "${e}": ${s.message}`}}}appendFile(e,t){if(t==null)return{success:!1,error:'Missing "content" for append action'};try{return j.appendFileSync(e,t,"utf-8"),{success:!0,data:{path:e,appendedBytes:Buffer.byteLength(t)},display:`Appended ${Buffer.byteLength(t)} bytes to ${e}`}}catch(s){return{success:!1,error:`Cannot append to "${e}": ${s.message}`}}}listDir(e){try{let s=j.readdirSync(e,{withFileTypes:!0}).map(n=>({name:n.name,type:n.isDirectory()?"dir":n.isSymbolicLink()?"symlink":"file"})),r=s.length===0?`${e}: (empty)`:s.map(n=>`${n.type==="dir"?"\u{1F4C1}":"\u{1F4C4}"} ${n.name}`).join(`
|
|
369
376
|
`);return{success:!0,data:{path:e,entries:s},display:r}}catch(t){return{success:!1,error:`Cannot list "${e}": ${t.message}`}}}fileInfo(e){try{let t=j.statSync(e),s={path:e,type:t.isDirectory()?"directory":t.isFile()?"file":"other",size:t.size,created:t.birthtime.toISOString(),modified:t.mtime.toISOString(),permissions:t.mode.toString(8)};return{success:!0,data:s,display:`${s.type}: ${e}
|
|
370
377
|
Size: ${t.size} bytes
|
|
371
|
-
Modified: ${s.modified}`}}catch(t){return{success:!1,error:`Cannot stat "${e}": ${t.message}`}}}fileExists(e){let t=j.existsSync(e);return{success:!0,data:{path:e,exists:t},display:t?`Yes, "${e}" exists`:`No, "${e}" does not exist`}}writeBinaryFile(e,t){if(!t)return{success:!1,error:'Missing "content" (base64-encoded) for write_binary action'};try{let s=vt.dirname(e);j.mkdirSync(s,{recursive:!0});let r=Buffer.from(t,"base64");return j.writeFileSync(e,r),{success:!0,data:{path:e,bytes:r.length},display:`Written ${r.length} bytes (binary) to ${e}`}}catch(s){return{success:!1,error:`Cannot write "${e}": ${s.message}`}}}moveFile(e,t){if(!t)return{success:!1,error:'Missing "destination" for move action'};let s=this.resolvePath(t);try{let r=vt.dirname(s);return j.mkdirSync(r,{recursive:!0}),j.renameSync(e,s),{success:!0,data:{from:e,to:s},display:`Moved ${e} \u2192 ${s}`}}catch{try{return j.copyFileSync(e,s),j.unlinkSync(e),{success:!0,data:{from:e,to:s},display:`Moved ${e} \u2192 ${s}`}}catch(n){return{success:!1,error:`Cannot move "${e}" to "${s}": ${n.message}`}}}}copyFile(e,t){if(!t)return{success:!1,error:'Missing "destination" for copy action'};let s=this.resolvePath(t);try{let r=vt.dirname(s);return j.mkdirSync(r,{recursive:!0}),j.copyFileSync(e,s),{success:!0,data:{from:e,to:s},display:`Copied ${e} \u2192 ${s}`}}catch(r){return{success:!1,error:`Cannot copy "${e}" to "${s}": ${r.message}`}}}deleteFile(e){try{return j.existsSync(e)?j.statSync(e).isDirectory()?{success:!1,error:`"${e}" is a directory. Use shell for directory deletion.`}:(j.unlinkSync(e),{success:!0,data:{path:e},display:`Deleted ${e}`}):{success:!1,error:`"${e}" does not exist`}}catch(t){return{success:!1,error:`Cannot delete "${e}": ${t.message}`}}}}});import{execSync as He}from"node:child_process";var
|
|
378
|
+
Modified: ${s.modified}`}}catch(t){return{success:!1,error:`Cannot stat "${e}": ${t.message}`}}}fileExists(e){let t=j.existsSync(e);return{success:!0,data:{path:e,exists:t},display:t?`Yes, "${e}" exists`:`No, "${e}" does not exist`}}writeBinaryFile(e,t){if(!t)return{success:!1,error:'Missing "content" (base64-encoded) for write_binary action'};try{let s=vt.dirname(e);j.mkdirSync(s,{recursive:!0});let r=Buffer.from(t,"base64");return j.writeFileSync(e,r),{success:!0,data:{path:e,bytes:r.length},display:`Written ${r.length} bytes (binary) to ${e}`}}catch(s){return{success:!1,error:`Cannot write "${e}": ${s.message}`}}}moveFile(e,t){if(!t)return{success:!1,error:'Missing "destination" for move action'};let s=this.resolvePath(t);try{let r=vt.dirname(s);return j.mkdirSync(r,{recursive:!0}),j.renameSync(e,s),{success:!0,data:{from:e,to:s},display:`Moved ${e} \u2192 ${s}`}}catch{try{return j.copyFileSync(e,s),j.unlinkSync(e),{success:!0,data:{from:e,to:s},display:`Moved ${e} \u2192 ${s}`}}catch(n){return{success:!1,error:`Cannot move "${e}" to "${s}": ${n.message}`}}}}copyFile(e,t){if(!t)return{success:!1,error:'Missing "destination" for copy action'};let s=this.resolvePath(t);try{let r=vt.dirname(s);return j.mkdirSync(r,{recursive:!0}),j.copyFileSync(e,s),{success:!0,data:{from:e,to:s},display:`Copied ${e} \u2192 ${s}`}}catch(r){return{success:!1,error:`Cannot copy "${e}" to "${s}": ${r.message}`}}}deleteFile(e){try{return j.existsSync(e)?j.statSync(e).isDirectory()?{success:!1,error:`"${e}" is a directory. Use shell for directory deletion.`}:(j.unlinkSync(e),{success:!0,data:{path:e},display:`Deleted ${e}`}):{success:!1,error:`"${e}" does not exist`}}catch(t){return{success:!1,error:`Cannot delete "${e}": ${t.message}`}}}}});import{execSync as He}from"node:child_process";var Xe,An=f(()=>{"use strict";O();Xe=class extends _{static{d(this,"ClipboardSkill")}metadata={name:"clipboard",description:"Read or write the system clipboard. Use when the user asks to copy something, paste from clipboard, or check what is in their clipboard.",riskLevel:"write",version:"1.0.0",inputSchema:{type:"object",properties:{action:{type:"string",enum:["read","write"],description:'"read" to get clipboard contents, "write" to set clipboard contents'},text:{type:"string",description:"Text to copy to clipboard (required for write)"}},required:["action"]}};async execute(e,t){let s=e.action;switch(s){case"read":return this.readClipboard();case"write":return this.writeClipboard(e.text);default:return{success:!1,error:`Unknown action "${s}". Valid: read, write`}}}readClipboard(){try{let e;switch(process.platform){case"darwin":e=He("pbpaste",{encoding:"utf-8",timeout:5e3});break;case"win32":e=He("powershell -NoProfile -Command Get-Clipboard",{encoding:"utf-8",timeout:5e3}).replace(/\r\n$/,"");break;default:e=He("xclip -selection clipboard -o 2>/dev/null || xsel --clipboard --output",{encoding:"utf-8",timeout:5e3});break}return!e||e.trim().length===0?{success:!0,data:{content:""},display:"Clipboard is empty."}:{success:!0,data:{content:e},display:e.length>2e3?e.slice(0,2e3)+`
|
|
372
379
|
|
|
373
|
-
[... truncated]`:e}}catch(e){return{success:!1,error:`Failed to read clipboard: ${e.message}`}}}writeClipboard(e){if(!e||typeof e!="string")return{success:!1,error:'Missing "text" for write action'};try{switch(process.platform){case"darwin":He("pbcopy",{input:e,timeout:5e3});break;case"win32":He('powershell -NoProfile -Command "$input | Set-Clipboard"',{input:e,timeout:5e3});break;default:He("xclip -selection clipboard 2>/dev/null || xsel --clipboard --input",{input:e,timeout:5e3});break}return{success:!0,data:{copiedLength:e.length},display:`Copied ${e.length} characters to clipboard.`}}catch(t){return{success:!1,error:`Failed to write clipboard: ${t.message}`}}}}});import{execSync as xt}from"node:child_process";import Ln from"node:path";import Ni from"node:os";var
|
|
380
|
+
[... truncated]`:e}}catch(e){return{success:!1,error:`Failed to read clipboard: ${e.message}`}}}writeClipboard(e){if(!e||typeof e!="string")return{success:!1,error:'Missing "text" for write action'};try{switch(process.platform){case"darwin":He("pbcopy",{input:e,timeout:5e3});break;case"win32":He('powershell -NoProfile -Command "$input | Set-Clipboard"',{input:e,timeout:5e3});break;default:He("xclip -selection clipboard 2>/dev/null || xsel --clipboard --input",{input:e,timeout:5e3});break}return{success:!0,data:{copiedLength:e.length},display:`Copied ${e.length} characters to clipboard.`}}catch(t){return{success:!1,error:`Failed to write clipboard: ${t.message}`}}}}});import{execSync as xt}from"node:child_process";import Ln from"node:path";import Ni from"node:os";var ze,Mn=f(()=>{"use strict";O();ze=class extends _{static{d(this,"ScreenshotSkill")}metadata={name:"screenshot",description:"Take a screenshot of the current screen and save it to a file. Use when the user asks to capture their screen or take a screenshot.",riskLevel:"write",version:"1.0.0",inputSchema:{type:"object",properties:{path:{type:"string",description:"Output file path (optional, defaults to ~/Desktop/screenshot-<timestamp>.png)"}}}};async execute(e,t){let s=new Date().toISOString().replace(/[:.]/g,"-").slice(0,19),r=Ln.join(Ni.homedir(),"Desktop"),n=e.path||Ln.join(r,`screenshot-${s}.png`);try{switch(process.platform){case"darwin":xt(`screencapture -x "${n}"`,{timeout:1e4});break;case"win32":xt(`powershell -NoProfile -Command "Add-Type -AssemblyName System.Windows.Forms; $screen = [System.Windows.Forms.Screen]::PrimaryScreen.Bounds; $bitmap = New-Object System.Drawing.Bitmap($screen.Width, $screen.Height); $graphics = [System.Drawing.Graphics]::FromImage($bitmap); $graphics.CopyFromScreen($screen.Location, [System.Drawing.Point]::Empty, $screen.Size); $bitmap.Save('${n.replace(/'/g,"''")}'); $graphics.Dispose(); $bitmap.Dispose()"`,{timeout:1e4});break;default:try{xt(`scrot "${n}"`,{timeout:1e4})}catch{try{xt(`import -window root "${n}"`,{timeout:1e4})}catch{xt(`gnome-screenshot -f "${n}"`,{timeout:1e4})}}break}return{success:!0,data:{path:n},display:`Screenshot saved to ${n}`}}catch(o){return{success:!1,error:`Screenshot failed: ${o.message}`}}}}});import Di from"node:path";import Oi from"node:os";var Nn,qe,Dn=f(()=>{"use strict";O();Nn=5e4,qe=class extends _{static{d(this,"BrowserSkill")}browser=null;page=null;metadata={name:"browser",description:"Open web pages in a real browser (Puppeteer/Chromium). Renders JavaScript, so it works with SPAs and dynamic sites. Can also interact with pages: click buttons, fill forms, take screenshots. Use when http skill returns empty/broken content, or when you need to interact with a web page.",riskLevel:"write",version:"1.0.0",inputSchema:{type:"object",properties:{action:{type:"string",enum:["open","screenshot","click","type","evaluate","close"],description:"open = navigate to URL and return page text. screenshot = save screenshot of current page. click = click element by CSS selector. type = type text into input by CSS selector. evaluate = run JavaScript on the page. close = close the browser."},url:{type:"string",description:'URL to open (required for "open", optional for "screenshot")'},selector:{type:"string",description:'CSS selector for the element (required for "click" and "type")'},text:{type:"string",description:'Text to type (required for "type")'},script:{type:"string",description:'JavaScript code to evaluate (required for "evaluate")'},path:{type:"string",description:"File path to save screenshot (optional, defaults to Desktop)"}},required:["action"]}};async execute(e,t){let s=e.action;if(s==="close")return this.closeBrowser();let r=await this.loadPuppeteer();if(!r)return{success:!1,error:`Puppeteer is not installed. Run: npm install -g puppeteer
|
|
374
381
|
Or add it to Alfred: npm install puppeteer`};switch(s){case"open":return this.openPage(r,e);case"screenshot":return this.screenshotPage(r,e);case"click":return this.clickElement(e);case"type":return this.typeText(e);case"evaluate":return this.evaluateScript(e);default:return{success:!1,error:`Unknown action "${s}". Valid: open, screenshot, click, type, evaluate, close`}}}async loadPuppeteer(){try{let e=await Function('return import("puppeteer")')();return this.resolvePuppeteerModule(e)}catch{try{let e=await Function('return import("puppeteer-core")')();return this.resolvePuppeteerModule(e)}catch{return null}}}resolvePuppeteerModule(e){let t=e;return typeof t.launch=="function"?t:t.default}async ensureBrowser(e){return this.browser&&this.browser.connected?this.browser:(this.browser=await e.launch({headless:!0,args:["--no-sandbox","--disable-setuid-sandbox","--disable-dev-shm-usage"]}),this.browser)}async ensurePage(e){let t=await this.ensureBrowser(e);return this.page||(this.page=await t.newPage(),await this.page.setViewport({width:1280,height:900})),this.page}async openPage(e,t){let s=t.url;if(!s)return{success:!1,error:'Missing "url" for open action'};try{let r=await this.ensurePage(e);await r.goto(s,{waitUntil:"networkidle2",timeout:3e4});let n=await r.title(),o=await r.evaluate(`
|
|
375
382
|
(() => {
|
|
376
383
|
document.querySelectorAll('script, style, noscript').forEach(el => el.remove());
|
|
@@ -414,10 +421,10 @@ Your memories, preferences, and context are now shared across platforms.`}}async
|
|
|
414
421
|
${r.join(`
|
|
415
422
|
`)}`}}async unlink(e,t){let s=e.platform;if(!s)return{success:!1,error:'Missing required field "platform"'};let r=this.users.getMasterUserId(t.userId),o=this.users.getLinkedUsers(r).find(i=>i.platform===s&&i.id!==t.userId);return o?(this.users.setMasterUser(o.id,o.id),{success:!0,data:{unlinkedPlatform:s,unlinkedUserId:o.id},display:`Unlinked ${s} account (${o.displayName??o.username??o.platformUserId}).`}):{success:!1,error:`No linked account found on platform "${s}".`}}}});var Ge,Hn=f(()=>{"use strict";O();Ge=class extends _{static{d(this,"BackgroundTaskSkill")}taskRepo;metadata={name:"background_task",description:'Schedule, list, or cancel background tasks that run independently. Use "schedule" to queue a skill to execute in the background (user will be notified when done). Use "list" to see active/recent tasks. Use "cancel" to stop a pending or running task.',riskLevel:"write",version:"1.0.0",inputSchema:{type:"object",properties:{action:{type:"string",enum:["schedule","list","cancel"],description:"The background task action to perform"},description:{type:"string",description:"Human-readable description of what the task does (for schedule)"},skill_name:{type:"string",description:"The skill to run in the background (for schedule)"},skill_input:{type:"object",description:"Input to pass to the skill (for schedule)"},task_id:{type:"string",description:"Task ID (for cancel)"}},required:["action"]}};constructor(e){super(),this.taskRepo=e}async execute(e,t){let s=e.action;switch(s){case"schedule":return this.scheduleTask(e,t);case"list":return this.listTasks(t);case"cancel":return this.cancelTask(e);default:return{success:!1,error:`Unknown action: "${String(s)}". Valid actions: schedule, list, cancel`}}}scheduleTask(e,t){let s=e.description,r=e.skill_name,n=e.skill_input;if(!s||typeof s!="string")return{success:!1,error:'Missing required field "description" for schedule action'};if(!r||typeof r!="string")return{success:!1,error:'Missing required field "skill_name" for schedule action'};let o=this.taskRepo.create(t.userId,t.platform,t.chatId,s,r,JSON.stringify(n??{}));return{success:!0,data:{taskId:o.id,description:s,skillName:r,status:o.status},display:`Background task scheduled (${o.id}): "${s}" using skill "${r}". You'll be notified when it completes.`}}listTasks(e){let t=this.taskRepo.getByUser(e.userId);if(t.length===0)return{success:!0,data:[],display:"No active or recent background tasks."};let s={pending:"\u23F3",running:"\u25B6\uFE0F",completed:"\u2705",failed:"\u274C"},r=t.map(n=>`- ${s[n.status]??"?"} ${n.id}: "${n.description}" [${n.status}] (${n.skillName})`);return{success:!0,data:t.map(n=>({taskId:n.id,description:n.description,status:n.status,skillName:n.skillName,createdAt:n.createdAt,completedAt:n.completedAt})),display:`Background tasks:
|
|
416
423
|
${r.join(`
|
|
417
|
-
`)}`}}cancelTask(e){let t=e.task_id;return!t||typeof t!="string"?{success:!1,error:'Missing required field "task_id" for cancel action'}:this.taskRepo.cancel(t)?{success:!0,data:{taskId:t},display:`Background task "${t}" cancelled.`}:{success:!1,error:`Task "${t}" not found or already completed`}}}});var Ye,
|
|
424
|
+
`)}`}}cancelTask(e){let t=e.task_id;return!t||typeof t!="string"?{success:!1,error:'Missing required field "task_id" for cancel action'}:this.taskRepo.cancel(t)?{success:!0,data:{taskId:t},display:`Background task "${t}" cancelled.`}:{success:!1,error:`Task "${t}" not found or already completed`}}}});var Ye,Xn=f(()=>{"use strict";O();Ye=class extends _{static{d(this,"ScheduledTaskSkill")}actionRepo;metadata={name:"scheduled_task",description:'Create, list, enable, disable, or delete scheduled actions that run automatically on a recurring basis. Supports cron expressions (e.g. "0 9 * * *" for daily at 9 AM), intervals (in minutes), and one-time schedules. Each scheduled action executes a skill or sends a prompt to the LLM at the configured time.',riskLevel:"write",version:"1.0.0",inputSchema:{type:"object",properties:{action:{type:"string",enum:["create","list","enable","disable","delete"],description:"The scheduled task action to perform"},name:{type:"string",description:"Name for the scheduled action (for create)"},description:{type:"string",description:"What the scheduled action does (for create)"},schedule_type:{type:"string",enum:["cron","interval","once"],description:"Type of schedule: cron expression, interval in minutes, or one-time ISO date (for create)"},schedule_value:{type:"string",description:"Schedule value: cron expression, minutes as string, or ISO date (for create)"},skill_name:{type:"string",description:"The skill to execute on schedule (for create)"},skill_input:{type:"object",description:"Input to pass to the skill (for create)"},prompt_template:{type:"string",description:"Optional LLM prompt to run instead of a skill (for create)"},action_id:{type:"string",description:"Scheduled action ID (for enable, disable, delete)"}},required:["action"]}};constructor(e){super(),this.actionRepo=e}async execute(e,t){let s=e.action;switch(s){case"create":return this.createAction(e,t);case"list":return this.listActions(t);case"enable":return this.toggleAction(e,!0);case"disable":return this.toggleAction(e,!1);case"delete":return this.deleteAction(e);default:return{success:!1,error:`Unknown action: "${String(s)}". Valid actions: create, list, enable, disable, delete`}}}createAction(e,t){let s=e.name,r=e.description,n=e.schedule_type,o=e.schedule_value,i=e.skill_name,a=e.skill_input,l=e.prompt_template;if(!s||typeof s!="string")return{success:!1,error:'Missing required field "name" for create action'};if(!r||typeof r!="string")return{success:!1,error:'Missing required field "description" for create action'};if(!n||!["cron","interval","once"].includes(n))return{success:!1,error:'Missing or invalid "schedule_type". Must be "cron", "interval", or "once"'};if(!o||typeof o!="string")return{success:!1,error:'Missing required field "schedule_value" for create action'};if(!i||typeof i!="string")return{success:!1,error:'Missing required field "skill_name" for create action'};if(n==="interval"){let m=parseInt(o,10);if(isNaN(m)||m<=0)return{success:!1,error:"For interval schedule, value must be a positive number of minutes"}}if(n==="cron"&&o.trim().split(/\s+/).length!==5)return{success:!1,error:"Cron expression must have 5 fields: minute hour dayOfMonth month dayOfWeek"};if(n==="once"){let m=new Date(o);if(isNaN(m.getTime()))return{success:!1,error:"For once schedule, value must be a valid ISO date string"};if(m.getTime()<=Date.now())return{success:!1,error:"The scheduled time is in the past. Please specify a future time."}}let u=this.actionRepo.create({userId:t.userId,platform:t.platform,chatId:t.chatId,name:s,description:r,scheduleType:n,scheduleValue:o,skillName:i,skillInput:JSON.stringify(a??{}),promptTemplate:l}),h=n==="cron"?`cron: ${o}`:n==="interval"?`every ${o} minutes`:`once at ${o}`;return{success:!0,data:{actionId:u.id,name:s,scheduleType:n,scheduleValue:o,skillName:i},display:`Scheduled action created (${u.id}): "${s}" \u2014 ${h}, running "${i}"${u.nextRunAt?`. Next run: ${u.nextRunAt}`:""}`}}listActions(e){let t=this.actionRepo.getByUser(e.userId);if(t.length===0)return{success:!0,data:[],display:"No scheduled actions."};let s=t.map(r=>{let n=r.enabled?"\u2705":"\u23F8\uFE0F",o=r.scheduleType==="cron"?`cron: ${r.scheduleValue}`:r.scheduleType==="interval"?`every ${r.scheduleValue} min`:`once: ${r.scheduleValue}`,i=r.nextRunAt?` | next: ${r.nextRunAt}`:"";return`- ${n} ${r.id}: "${r.name}" [${o}] \u2192 ${r.skillName}${i}`});return{success:!0,data:t.map(r=>({actionId:r.id,name:r.name,scheduleType:r.scheduleType,scheduleValue:r.scheduleValue,skillName:r.skillName,enabled:r.enabled,nextRunAt:r.nextRunAt,lastRunAt:r.lastRunAt})),display:`Scheduled actions:
|
|
418
425
|
${s.join(`
|
|
419
426
|
`)}`}}toggleAction(e,t){let s=e.action_id;return!s||typeof s!="string"?{success:!1,error:`Missing required field "action_id" for ${t?"enable":"disable"} action`}:this.actionRepo.setEnabled(s,t)?{success:!0,data:{actionId:s,enabled:t},display:`Scheduled action "${s}" ${t?"enabled":"disabled"}.`}:{success:!1,error:`Scheduled action "${s}" not found`}}deleteAction(e){let t=e.action_id;return!t||typeof t!="string"?{success:!1,error:'Missing required field "action_id" for delete action'}:this.actionRepo.delete(t)?{success:!0,data:{actionId:t},display:`Scheduled action "${t}" deleted.`}:{success:!1,error:`Scheduled action "${t}" not found`}}}});var we,Js=f(()=>{"use strict";we=class{static{d(this,"MCPClient")}serverName;config;logger;client;transport;connected=!1;constructor(e,t,s){this.serverName=e,this.config=t,this.logger=s}async connect(){try{let{Client:e}=await import("@modelcontextprotocol/sdk/client/index.js");if(this.client=new e({name:`alfred-${this.serverName}`,version:"1.0.0"},{capabilities:{}}),this.config.command){let{StdioClientTransport:t}=await import("@modelcontextprotocol/sdk/client/stdio.js"),s={PATH:process.env.PATH??"",HOME:process.env.HOME??process.env.USERPROFILE??"",LANG:process.env.LANG??"en_US.UTF-8",NODE_ENV:process.env.NODE_ENV??"",SYSTEMROOT:process.env.SYSTEMROOT??""};if(this.config.env)for(let[r,n]of Object.entries(this.config.env))s[r]=n.replace(/\$\{(\w+)\}/g,(o,i)=>process.env[i]??"");this.transport=new t({command:this.config.command,args:this.config.args??[],env:s})}else if(this.config.url){let{SSEClientTransport:t}=await import("@modelcontextprotocol/sdk/client/sse.js");this.transport=new t(new URL(this.config.url))}else throw new Error(`MCP server "${this.serverName}": must specify either command or url`);await this.client.connect(this.transport),this.connected=!0,this.logger.info({server:this.serverName},"MCP server connected")}catch(e){throw this.logger.error({server:this.serverName,err:e},"Failed to connect MCP server"),e}}async listTools(){if(!this.connected||!this.client)return[];try{return((await this.client.listTools()).tools??[]).map(t=>({name:t.name,description:t.description,inputSchema:t.inputSchema??{type:"object",properties:{}}}))}catch(e){return this.logger.error({server:this.serverName,err:e},"Failed to list MCP tools"),[]}}async callTool(e,t){if(!this.connected||!this.client)return{content:"MCP server not connected",isError:!0};try{let s=await this.client.callTool({name:e,arguments:t});return{content:(s.content??[]).map(n=>n.text??JSON.stringify(n)).join(`
|
|
420
|
-
`),isError:s.isError}}catch(s){return{content:`MCP tool error: ${s instanceof Error?s.message:String(s)}`,isError:!0}}}async disconnect(){if(this.transport)try{await this.transport.close?.()}catch{}this.connected=!1,this.logger.info({server:this.serverName},"MCP server disconnected")}}});var Ee,Zs=f(()=>{"use strict";O();Ee=class extends _{static{d(this,"MCPSkillAdapter")}client;serverName;toolName;metadata;constructor(e,t,s,r,n){super(),this.client=e,this.serverName=t,this.toolName=s,this.metadata={name:`mcp__${t}__${s}`,description:`[MCP/${t}] ${r||s}`,riskLevel:"write",version:"1.0.0",inputSchema:n}}async execute(e,t){let s=await this.client.callTool(this.toolName,e);return{success:s.isError!==!0,data:s.content,display:s.content,error:s.isError===!0?s.content:void 0}}}});var Rt,
|
|
427
|
+
`),isError:s.isError}}catch(s){return{content:`MCP tool error: ${s instanceof Error?s.message:String(s)}`,isError:!0}}}async disconnect(){if(this.transport)try{await this.transport.close?.()}catch{}this.connected=!1,this.logger.info({server:this.serverName},"MCP server disconnected")}}});var Ee,Zs=f(()=>{"use strict";O();Ee=class extends _{static{d(this,"MCPSkillAdapter")}client;serverName;toolName;metadata;constructor(e,t,s,r,n){super(),this.client=e,this.serverName=t,this.toolName=s,this.metadata={name:`mcp__${t}__${s}`,description:`[MCP/${t}] ${r||s}`,riskLevel:"write",version:"1.0.0",inputSchema:n}}async execute(e,t){let s=await this.client.callTool(this.toolName,e);return{success:s.isError!==!0,data:s.content,display:s.content,error:s.isError===!0?s.content:void 0}}}});var Rt,zn=f(()=>{"use strict";Js();Zs();Rt=class{static{d(this,"MCPManager")}logger;clients=[];skills=[];constructor(e){this.logger=e}async initialize(e){for(let t of e.servers)try{let s=new we(t.name,t,this.logger.child({mcp:t.name}));await s.connect(),this.clients.push(s);let r=await s.listTools();for(let n of r){let o=new Ee(s,t.name,n.name,n.description??"",n.inputSchema);this.skills.push(o)}this.logger.info({server:t.name,tools:r.length},"MCP server initialized")}catch(s){this.logger.error({server:t.name,err:s},"Failed to initialize MCP server")}}getSkills(){return this.skills}async shutdown(){for(let e of this.clients)await e.disconnect();this.clients.length=0,this.skills.length=0}}});var qn=f(()=>{"use strict";Js();Zs();zn()});import{spawn as Ci}from"node:child_process";import Je from"node:fs";import Qs from"node:path";import Ui from"node:os";import Pi from"node:crypto";var Te,er=f(()=>{"use strict";Te=class{static{d(this,"CodeExecutor")}async execute(e,t,s){let r=Math.min(s?.timeout??3e4,12e4),n=Qs.join(Ui.tmpdir(),`alfred-sandbox-${Pi.randomUUID()}`);Je.mkdirSync(n,{recursive:!0});try{let o=t==="javascript"?"js":"py",i=Qs.join(n,`script.${o}`);Je.writeFileSync(i,e);let a=t==="javascript"?"node":process.platform==="win32"?"python":"python3",l=[i],u=Date.now();return await new Promise(h=>{let m=Ci(a,l,{cwd:n,timeout:r,env:{PATH:process.env.PATH??"",HOME:process.env.HOME??process.env.USERPROFILE??"",LANG:process.env.LANG??"en_US.UTF-8",NODE_ENV:"sandbox",PYTHONDONTWRITEBYTECODE:"1",...s?.env,TMPDIR:n,TEMP:n,TMP:n},stdio:["pipe","pipe","pipe"]}),p="",E="";m.stdout.on("data",w=>{p+=w.toString()}),m.stderr.on("data",w=>{E+=w.toString()}),m.on("close",w=>{let T=Date.now()-u,k=[];try{let b=Je.readdirSync(n).filter(x=>!x.startsWith("script."));for(let x of b){let L=Qs.join(n,x),v=Je.statSync(L);if(v.isFile()&&v.size<1e7){let M=Je.readFileSync(L),R=x.endsWith(".png")?"image/png":x.endsWith(".jpg")||x.endsWith(".jpeg")?"image/jpeg":x.endsWith(".svg")?"image/svg+xml":x.endsWith(".csv")?"text/csv":x.endsWith(".json")?"application/json":"application/octet-stream";k.push({name:x,data:M,mimeType:R})}}}catch{}h({stdout:p.slice(0,5e4),stderr:E.slice(0,1e4),exitCode:w??1,files:k.length>0?k:void 0,durationMs:T})}),m.on("error",w=>{h({stdout:"",stderr:w.message,exitCode:1,durationMs:Date.now()-u})}),m.stdin.end()})}finally{try{Je.rmSync(n,{recursive:!0,force:!0})}catch{}}}}});var At,Kn=f(()=>{"use strict";O();er();At=class extends _{static{d(this,"CodeExecutionSkill")}metadata={name:"code_sandbox",description:"Execute code in a sandboxed environment. Supports JavaScript (Node.js) and Python. Use for calculations, data processing, generating charts, or testing code snippets. Code runs in an isolated temp directory with a timeout.",riskLevel:"destructive",version:"1.0.0",timeoutMs:12e4,inputSchema:{type:"object",properties:{action:{type:"string",enum:["run","run_with_data"],description:"Action to perform"},code:{type:"string",description:"Code to execute"},language:{type:"string",enum:["javascript","python"],description:"Programming language"},data:{type:"string",description:"Input data to pass (available as DATA env var or stdin)"},timeout:{type:"number",description:"Timeout in ms (max 120000)"}},required:["action","code","language"]}};executor=new Te;allowedLanguages;maxTimeout;constructor(e){super(),this.allowedLanguages=new Set(e?.allowedLanguages??["javascript","python"]),this.maxTimeout=e?.maxTimeoutMs??12e4}async execute(e,t){let s=e.action,r=e.code,n=e.language,o=e.data,i=Math.min(e.timeout??3e4,this.maxTimeout);if(!r)return{success:!1,error:'Missing required field "code"'};if(!n)return{success:!1,error:'Missing required field "language"'};if(!this.allowedLanguages.has(n))return{success:!1,error:`Language "${n}" is not allowed. Allowed: ${[...this.allowedLanguages].join(", ")}`};let a=r;s==="run_with_data"&&o&&(n==="javascript"?a=`const INPUT_DATA = ${JSON.stringify(o)};
|
|
421
428
|
${r}`:a=`INPUT_DATA = ${JSON.stringify(o)}
|
|
422
429
|
${r}`);let l=await this.executor.execute(a,n,{timeout:i}),u=[l.stdout?`Output:
|
|
423
430
|
${l.stdout}`:"",l.stderr?`Errors:
|
|
@@ -435,7 +442,7 @@ ${i}`}}summarize(e){let t=e.document_id;if(!t||typeof t!="string")return{success
|
|
|
435
442
|
|
|
436
443
|
${a}`}}list(e,t){let s=e.limit||50,n=this.docRepo.listByUser(t.userId).slice(0,s);if(n.length===0)return{success:!0,data:[],display:"No documents found."};let o=n.map(i=>`- **${i.filename}** (${i.id.slice(0,8)}...) \u2014 ${i.mimeType}, ${i.chunkCount} chunks, ${i.sizeBytes} bytes`).join(`
|
|
437
444
|
`);return{success:!0,data:n,display:`${n.length} document(s):
|
|
438
|
-
${o}`}}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 as={};V(as,{ActivityTracker:()=>ge,BackgroundTaskSkill:()=>Ge,BrowserSkill:()=>qe,CalculatorSkill:()=>Le,CalendarProvider:()=>Y,CalendarSkill:()=>ye,ClipboardSkill:()=>
|
|
445
|
+
${o}`}}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 as={};V(as,{ActivityTracker:()=>ge,BackgroundTaskSkill:()=>Ge,BrowserSkill:()=>qe,CalculatorSkill:()=>Le,CalendarProvider:()=>Y,CalendarSkill:()=>ye,ClipboardSkill:()=>Xe,CodeExecutionSkill:()=>At,CodeExecutor:()=>Te,CrossPlatformSkill:()=>Ve,DelegateSkill:()=>Fe,DocumentSkill:()=>Ze,EmailSkill:()=>je,FileSkill:()=>We,HttpSkill:()=>Be,MCPClient:()=>we,MCPManager:()=>Rt,MCPSkillAdapter:()=>Ee,MemorySkill:()=>Pe,NoteSkill:()=>Oe,PluginLoader:()=>rs,ProfileSkill:()=>Ke,ReminderSkill:()=>De,ScheduledTaskSkill:()=>Ye,ScreenshotSkill:()=>ze,ShellSkill:()=>Ue,Skill:()=>_,SkillRegistry:()=>Re,SkillSandbox:()=>Ae,SystemInfoSkill:()=>Me,WeatherSkill:()=>Ce,WebSearchSkill:()=>Ne,createCalendarProvider:()=>$t});var Lt=f(()=>{"use strict";O();mn();pn();zs();hn();fn();gn();yn();wn();En();Tn();Sn();kn();vn();xn();$n();Rn();An();Mn();Dn();On();Bn();Wn();Hn();Xn();qn();Vn();Gn()});var Mt,tr=f(()=>{"use strict";Mt=class{static{d(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)}}});import Yn from"node:fs";import Jn from"node:path";var Fi,ji,Bi,Nt,sr=f(()=>{"use strict";Hs();Fi=15*60*1e3,ji=.85,Bi=1e5,Nt=class{static{d(this,"MessagePipeline")}promptBuilder;llm;conversationManager;users;logger;skillRegistry;skillSandbox;securityManager;memoryRepo;speechTranscriber;inboxPath;embeddingService;activeLearning;memoryRetriever;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.promptBuilder=new bt}async process(e,t){let s=Date.now();this.logger.info({platform:e.platform,userId:e.userId,chatId:e.chatId},"Processing message");try{let r=this.users.findOrCreate(e.platform,e.userId,e.userName,e.displayName),n="getMasterUserId"in this.users?this.users.getMasterUserId(r.id):r.id,o=this.conversationManager.getOrCreateConversation(e.platform,e.chatId,r.id),i=this.conversationManager.getHistory(o.id,50);this.conversationManager.addMessage(o.id,"user",e.text);let a;if(this.memoryRetriever&&e.text)try{a=await this.memoryRetriever.retrieve(n,e.text,15)}catch(R){this.logger.debug({err:R},"Hybrid memory retrieval failed")}if(!a&&this.memoryRepo)try{if(this.embeddingService&&e.text&&this.llm.supportsEmbeddings()){let R=await this.embeddingService.semanticSearch(n,e.text,10),C=this.memoryRepo.getRecentForPrompt(n,5),F=new Set;a=[];for(let U of R)F.has(U.key)||(F.add(U.key),a.push(U));for(let U of C)F.has(U.key)||(F.add(U.key),a.push(U))}else a=this.memoryRepo.getRecentForPrompt(n,20)}catch(R){this.logger.debug({err:R},"Memory loading failed")}let l;try{"getProfile"in this.users&&(l=this.users.getProfile(r.id),l&&!l.displayName&&(l.displayName=r.displayName??r.username))}catch(R){this.logger.debug({err:R},"Profile loading failed")}let u=l?.timezone||Intl.DateTimeFormat().resolvedOptions().timeZone,h=this.skillRegistry?this.skillRegistry.getAll().map(R=>R.metadata):void 0,m=h?this.promptBuilder.buildTools(h):void 0,p=this.promptBuilder.buildSystemPrompt({memories:a,skills:h,userProfile:l}),E=this.buildActiveAgentStatus();E&&(p+=`
|
|
439
446
|
|
|
440
447
|
`+E);let w=this.promptBuilder.buildMessages(i),T=await this.buildUserContent(e,t);w.push({role:"user",content:T});let k=this.trimToContextWindow(p,w),b,x=0,L=Date.now();for(t?.("Thinking...");b=await this.llm.complete({messages:k,system:p,tools:m&&m.length>0?m:void 0}),!(!b.toolCalls||b.toolCalls.length===0);){let R=Date.now()-L;if(R>=Fi){let U=Math.round(R/6e4);this.logger.warn({iteration:x,elapsedMin:U,pendingToolCalls:b.toolCalls.length},"Tool loop timeout reached");let le=[];b.content&&le.push({type:"text",text:b.content});for(let H of b.toolCalls)le.push({type:"tool_use",id:H.id,name:H.name,input:H.input});k.push({role:"assistant",content:le});let N=b.toolCalls.map(H=>({type:"tool_result",tool_use_id:H.id,content:`Error: time limit reached (${U} min), execution skipped.`,is_error:!0}));k.push({role:"user",content:N}),this.conversationManager.addMessage(o.id,"assistant",b.content??"",JSON.stringify(b.toolCalls)),this.conversationManager.addMessage(o.id,"user","",JSON.stringify(N)),k.push({role:"user",content:`[System: Das Zeitlimit von ${U} Minuten f\xFCr Tool-Aufrufe wurde erreicht. Fasse dem User kurz zusammen was du bisher geschafft hast und was noch offen ist. Der User kann dir dann sagen ob du weitermachen sollst.]`}),b=await this.llm.complete({messages:k,system:p});break}x++,this.logger.info({iteration:x,toolCalls:b.toolCalls.length},"Processing tool calls");let C=[];b.content&&C.push({type:"text",text:b.content});for(let U of b.toolCalls)C.push({type:"tool_use",id:U.id,name:U.name,input:U.input});k.push({role:"assistant",content:C});let F=await this.executeToolCallsParallel(b.toolCalls,{userId:e.userId,chatId:e.chatId,chatType:e.chatType,platform:e.platform,conversationId:o.id,timezone:u},t);this.conversationManager.addMessage(o.id,"assistant",b.content??"",JSON.stringify(b.toolCalls)),this.conversationManager.addMessage(o.id,"user","",JSON.stringify(F)),k.push({role:"user",content:F}),t?.("Thinking...")}let v=b.content;if(!v)for(let R=k.length-1;R>=0;R--){let C=k[R];if(C.role==="assistant"&&Array.isArray(C.content)){let F=C.content.find(U=>U.type==="text");if(F&&"text"in F&&F.text){v=F.text;break}}}v||(v="(no response)"),this.conversationManager.addMessage(o.id,"assistant",v),this.activeLearning&&this.activeLearning.onMessageProcessed(n,e.text,v);let M=Date.now()-s;return this.logger.info({duration:M,tokens:b.usage,stopReason:b.stopReason,toolIterations:x},"Message processed"),v}catch(r){throw this.logger.error({err:r},"Failed to process message"),r}}async executeToolCallsParallel(e,t,s){if(e.length===1){let n=e[0],o=this.getToolLabel(n.name,n.input);s?.(o);let i=await this.executeToolCall(n,t,s);return[{type:"tool_result",tool_use_id:n.id,content:i.content,is_error:i.isError}]}s?.(`Running ${e.length} tools in parallel...`);let r=await Promise.allSettled(e.map(n=>this.executeToolCall(n,t,s)));return e.map((n,o)=>{let i=r[o];return i.status==="fulfilled"?{type:"tool_result",tool_use_id:n.id,content:i.value.content,is_error:i.value.isError}:{type:"tool_result",tool_use_id:n.id,content:`Tool execution failed: ${i.reason}`,is_error:!0}})}async executeToolCall(e,t,s){let r=this.skillRegistry?.get(e.name);if(!r)return this.logger.warn({tool:e.name},"Unknown skill requested"),{content:`Error: Unknown tool "${e.name}"`,isError:!0};if(this.securityManager){let n=this.securityManager.evaluate({userId:t.userId,action:e.name,riskLevel:r.metadata.riskLevel,platform:t.platform,chatId:t.chatId,chatType:t.chatType});if(!n.allowed)return this.logger.warn({tool:e.name,reason:n.reason,rule:n.matchedRule?.id},"Skill execution denied by security rules"),{content:`Access denied: ${n.reason}`,isError:!0}}if(this.skillSandbox){let n,o;if(e.name==="delegate"){let{ActivityTracker:a}=await Promise.resolve().then(()=>(Lt(),as));n=new a(s),o=`agent-${++this.agentIdCounter}`,this.activeAgents.set(o,{chatId:t.chatId,task:String(e.input.task??"").slice(0,200),tracker:n,startedAt:Date.now()})}let i=e.name==="delegate"?{...t,tracker:n,onProgress:s}:t;try{let a=await this.skillSandbox.execute(r,e.input,i,void 0,n);return{content:a.display??(a.success?JSON.stringify(a.data):a.error??"Unknown error"),isError:!a.success}}finally{o&&this.activeAgents.delete(o)}}try{let n=await r.execute(e.input,t);return{content:n.display??(n.success?JSON.stringify(n.data):n.error??"Unknown error"),isError:!n.success}}catch(n){return{content:`Skill execution failed: ${n instanceof Error?n.message:String(n)}`,isError:!0}}}getToolLabel(e,t){switch(e){case"shell":return`Running: ${String(t.command??"").slice(0,60)}`;case"web_search":return`Searching: ${String(t.query??"")}`;case"email":return`Email: ${String(t.action??"")}`;case"memory":return`Memory: ${String(t.action??"")}`;case"reminder":return`Reminder: ${String(t.action??"")}`;case"calculator":return"Calculating...";case"system_info":return"Getting system info...";case"delegate":return"Delegating sub-task...";case"http":return`Fetching: ${String(t.url??"").slice(0,60)}`;case"file":return`File: ${String(t.action??"")} ${String(t.path??"").slice(0,50)}`;case"clipboard":return`Clipboard: ${String(t.action??"")}`;case"screenshot":return"Taking screenshot...";case"browser":return`Browser: ${String(t.action??"")} ${String(t.url??"").slice(0,50)}`;case"weather":return`Weather: ${String(t.location??"")}`;case"note":return`Note: ${String(t.action??"")}`;case"profile":return`Profile: ${String(t.action??"")}`;case"calendar":return`Calendar: ${String(t.action??"")}`;case"background_task":return`Background task: ${String(t.action??"")}`;case"scheduled_task":return`Scheduled task: ${String(t.action??"")}`;case"cross_platform":return`Cross-platform: ${String(t.action??"")}`;case"code_sandbox":return"Running code...";case"document":return`Document: ${String(t.action??"")}`;default:return`Using ${e}...`}}buildActiveAgentStatus(){if(this.activeAgents.size===0)return;let e=["## Currently running sub-agents"];for(let[t,s]of this.activeAgents){let r=s.tracker.getSnapshot(),n=Math.round(r.totalElapsedMs/1e3);e.push(`- **${t}**: "${s.task}"`,` Status: ${s.tracker.formatStatus()}`,` Running for ${n}s | Last activity ${Math.round(r.idleMs/1e3)}s ago`)}return e.push(""),e.push("If the user asks what you or the agent is doing, describe the above status in natural language."),e.join(`
|
|
441
448
|
`)}trimToContextWindow(e,t){let s=this.llm.getContextWindow(),r=Math.floor(s.maxInputTokens*ji),n=oe(e),o=t[t.length-1],i=ts(o),a=n+i+200,l=r-a;if(l<=0)return this.logger.warn({maxInputTokens:r,systemTokens:n,latestTokens:i},"Context window very tight, sending only latest message"),[o];let u=t.slice(0,-1),h=this.groupToolPairs(u),m=[];for(let w=h.length-1;w>=0;w--){let T=h[w].reduce((k,b)=>k+ts(b),0);if(T>l)break;l-=T,m.unshift(h[w])}let p=m.flat(),E=u.length-p.length;return E>0&&(this.logger.info({trimmedCount:E,totalMessages:t.length,maxInputTokens:r},"Trimmed conversation history to fit context window"),p.unshift({role:"user",content:`[System note: ${E} older message(s) were omitted to fit the context window. The conversation continues from the most recent messages.]`})),p.push(o),p}groupToolPairs(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=[r];if(s+1<e.length&&e[s+1].role==="user"){let o=e[s+1];if(Array.isArray(o.content)&&o.content.some(i=>i.type==="tool_result")){n.push(o),s+=2,t.push(n);continue}}t.push(n),s++}else t.push([r]),s++}return t}async buildUserContent(e,t){let s=e.attachments?.filter(o=>o.data)??[];if(s.length===0)return e.text;let r=[];for(let o of s)if(o.type==="image"&&o.data)r.push({type:"image",source:{type:"base64",media_type:o.mimeType??"image/jpeg",data:o.data.toString("base64")}}),this.logger.info({mimeType:o.mimeType,size:o.size},"Image attached to LLM request");else if(o.type==="audio"&&o.data)if(this.speechTranscriber){t?.("Transcribing voice...");try{let i=await this.speechTranscriber.transcribe(o.data,o.mimeType??"audio/ogg"),a=e.text==="[Voice message]"?"":`${e.text}
|
|
@@ -453,7 +460,7 @@ Error: ${o.error}`;await a.sendMessage(e.chatId,l)}}catch(t){let s=t instanceof
|
|
|
453
460
|
|
|
454
461
|
Error: ${s}`)}}}});var jt,lr=f(()=>{"use strict";jt=class{static{d(this,"ProactiveScheduler")}actionRepo;skillRegistry;skillSandbox;llm;adapters;logger;tickTimer;tickIntervalMs=6e4;constructor(e,t,s,r,n,o){this.actionRepo=e,this.skillRegistry=t,this.skillSandbox=s,this.llm=r,this.adapters=n,this.logger=o}start(){this.tickTimer=setInterval(()=>this.tick(),this.tickIntervalMs),this.logger.info("Proactive scheduler started")}stop(){this.tickTimer&&(clearInterval(this.tickTimer),this.tickTimer=void 0),this.logger.info("Proactive scheduler stopped")}async tick(){try{let e=this.actionRepo.getDue();for(let t of e)try{await this.executeAction(t)}catch(s){this.logger.error({err:s,actionId:t.id},"Failed to execute scheduled action")}}catch(e){this.logger.error({err:e},"Error during proactive scheduler tick")}}async executeAction(e){let t=new Date().toISOString();this.logger.info({actionId:e.id,name:e.name},"Executing scheduled action");let s;if(e.promptTemplate)try{s=(await this.llm.complete({messages:[{role:"user",content:e.promptTemplate}],maxTokens:1024,tier:"fast"})).content}catch(o){let i=o instanceof Error?o.message:String(o);this.logger.error({actionId:e.id,err:o},"LLM call failed for scheduled action"),s=`Scheduled action "${e.name}" failed: ${i}`}else{let o=this.skillRegistry.get(e.skillName);if(!o)this.logger.warn({actionId:e.id,skillName:e.skillName},"Unknown skill for scheduled action"),s=`Scheduled action "${e.name}" failed: unknown skill "${e.skillName}"`;else try{let i;try{i=JSON.parse(e.skillInput)}catch{i={},this.logger.warn({actionId:e.id},"Invalid skillInput JSON, using empty input")}let a={userId:e.userId,chatId:e.chatId,platform:e.platform,conversationId:"",chatType:"dm"},l=await this.skillSandbox.execute(o,i,a);s=l.success?`\u{1F514} Scheduled: ${e.name}
|
|
455
462
|
|
|
456
|
-
${l.display??JSON.stringify(l.data)}`:`\u274C Scheduled action "${e.name}" failed: ${l.error}`}catch(i){let a=i instanceof Error?i.message:String(i);s=`\u274C Scheduled action "${e.name}" failed: ${a}`}}let r=this.adapters.get(e.platform);if(r)try{await r.sendMessage(e.chatId,s)}catch(o){this.logger.error({err:o,actionId:e.id},"Failed to send scheduled action result")}let n=this.calculateNextRun(e);n?this.actionRepo.updateLastRun(e.id,t,n):(this.actionRepo.updateLastRun(e.id,t,null),this.actionRepo.setEnabled(e.id,!1))}calculateNextRun(e){let t=new Date;switch(e.scheduleType){case"interval":{let s=parseInt(e.scheduleValue,10);return isNaN(s)||s<=0?null:new Date(t.getTime()+s*6e4).toISOString()}case"once":return null;case"cron":return this.getNextCronDate(e.scheduleValue,t)?.toISOString()??null;default:return null}}getNextCronDate(e,t){let s=e.trim().split(/\s+/);if(s.length!==5)return null;let r=new Date(t.getTime()+6e4);r.setSeconds(0,0);for(let n=0;n<1440;n++){if(this.matchesCron(s,r))return r;r.setTime(r.getTime()+6e4)}return null}matchesCron(e,t){let s=t.getMinutes(),r=t.getHours(),n=t.getDate(),o=t.getMonth()+1,i=t.getDay();return this.matchCronField(e[0],s)&&this.matchCronField(e[1],r)&&this.matchCronField(e[2],n)&&this.matchCronField(e[3],o)&&this.matchCronField(e[4],i)}matchCronField(e,t){if(e==="*")return!0;let s=/^\*\/(\d+)$/.exec(e);if(s){let n=parseInt(s[1],10);return t%n===0}let r=parseInt(e,10);return isNaN(r)?!1:t===r}}});function dr(c){let e=c.trim();if(e.length<10)return{level:"low",matchedPatterns:[]};for(let s of Wi)if(s.test(e))return{level:"low",matchedPatterns:[]};let t=[];for(let s of Hi)for(let r of s.patterns)if(r.test(e)){t.push(s.name);break}return t.length>0?{level:"high",matchedPatterns:t}:{level:"low",matchedPatterns:[]}}var Wi,Hi,ur=f(()=>{"use strict";Wi=[/^(what|where|when|who|why|how|which|can you|could you|do you|is there|are there|was |wer |wo |wann |warum |wie |welch|kannst du|könntest du|gibt es)/i,/^(hi|hey|hello|hallo|guten (morgen|tag|abend)|moin|servus|grüß|na\b|yo\b|sup\b|good (morning|evening|night))\b/i,/^(tell me|show me|find|search|help|explain|describe|translate|summarize|zeig|such|hilf|erklär|beschreib|übersetze|fass zusammen)/i,/^(ok|okay|yes|no|ja|nein|danke|thanks|thank you|sure|alright|klar|gut|cool|nice|great|perfect|genau|stimmt|richtig)\b/i],Hi=[{name:"fact:name",patterns:[/\b(my name is|i'm called|i am called|ich heiße|ich bin der|ich bin die|mein name ist)\b/i]},{name:"fact:location",patterns:[/\b(i live in|i'm from|i am from|ich wohne|ich lebe in|ich komme aus|ich bin aus)\b/i]},{name:"fact:work",patterns:[/\b(i work at|i work as|i work for|ich arbeite|mein job|mein beruf|ich bin .{0,20}(entwickler|ingenieur|lehrer|arzt|designer))\b/i]},{name:"fact:birthday",patterns:[/\b(my birthday|i was born|ich bin geboren|mein geburtstag|ich habe am .{1,15} geburtstag)\b/i]},{name:"fact:age",patterns:[/\b(i'm \d+ years|i am \d+ years|ich bin \d+ (jahre|jahr))\b/i]},{name:"preference:like",patterns:[/\b(i love|i really like|i enjoy|ich liebe|ich mag|mir gefällt|mir gefallen)\b/i]},{name:"preference:dislike",patterns:[/\b(i hate|i dislike|i can't stand|ich hasse|ich mag .{0,5} nicht|ich kann .{0,10} nicht leiden)\b/i]},{name:"preference:prefer",patterns:[/\b(i prefer|i'd rather|ich bevorzuge|ich nehme lieber|mir ist .{0,10} lieber)\b/i]},{name:"preference:favorite",patterns:[/\b(my fav|my favorite|my favourite|mein lieblings|meine lieblings|am liebsten)\b/i]},{name:"correction",patterns:[/\b(actually|actually,? (i|my|it)|eigentlich|das stimmt nicht|nein,? ich|that's not right|that's wrong|nicht ganz)\b/i]},{name:"relationship:family",patterns:[/\b(my wife|my husband|my partner|meine frau|mein mann|mein partner|meine partnerin|my daughter|my son|mein sohn|meine tochter|my kids|meine kinder|my mother|my father|meine mutter|mein vater)\b/i]},{name:"relationship:professional",patterns:[/\b(my boss|my manager|my colleague|mein chef|mein vorgesetzter|mein kollege|meine kollegin)\b/i]},{name:"relationship:social",patterns:[/\b(my friend|my best friend|mein freund|meine freundin|mein bester freund)\b/i]},{name:"fact:language",patterns:[/\b(i speak|ich spreche|my native|meine muttersprache)\b/i]},{name:"fact:education",patterns:[/\b(i studied|i went to|ich habe .{0,10} studiert|ich war auf der|mein studium)\b/i]},{name:"fact:hobby",patterns:[/\b(my hobby|i play .{0,10}(guitar|piano|football|tennis|chess)|mein hobby|ich spiele|in my free time|in meiner freizeit)\b/i]},{name:"decision",patterns:[/\b(i've decided|i decided|i will always|ich habe (mich )?entschieden|ich werde immer)\b/i]},{name:"commitment",patterns:[/\b(i always|i never|ich mache immer|ich mache nie|i'm trying to|ich versuche)\b/i]}];d(dr,"scanSignal")});var zi,
|
|
463
|
+
${l.display??JSON.stringify(l.data)}`:`\u274C Scheduled action "${e.name}" failed: ${l.error}`}catch(i){let a=i instanceof Error?i.message:String(i);s=`\u274C Scheduled action "${e.name}" failed: ${a}`}}let r=this.adapters.get(e.platform);if(r)try{await r.sendMessage(e.chatId,s)}catch(o){this.logger.error({err:o,actionId:e.id},"Failed to send scheduled action result")}let n=this.calculateNextRun(e);n?this.actionRepo.updateLastRun(e.id,t,n):(this.actionRepo.updateLastRun(e.id,t,null),this.actionRepo.setEnabled(e.id,!1))}calculateNextRun(e){let t=new Date;switch(e.scheduleType){case"interval":{let s=parseInt(e.scheduleValue,10);return isNaN(s)||s<=0?null:new Date(t.getTime()+s*6e4).toISOString()}case"once":return null;case"cron":return this.getNextCronDate(e.scheduleValue,t)?.toISOString()??null;default:return null}}getNextCronDate(e,t){let s=e.trim().split(/\s+/);if(s.length!==5)return null;let r=new Date(t.getTime()+6e4);r.setSeconds(0,0);for(let n=0;n<1440;n++){if(this.matchesCron(s,r))return r;r.setTime(r.getTime()+6e4)}return null}matchesCron(e,t){let s=t.getMinutes(),r=t.getHours(),n=t.getDate(),o=t.getMonth()+1,i=t.getDay();return this.matchCronField(e[0],s)&&this.matchCronField(e[1],r)&&this.matchCronField(e[2],n)&&this.matchCronField(e[3],o)&&this.matchCronField(e[4],i)}matchCronField(e,t){if(e==="*")return!0;let s=/^\*\/(\d+)$/.exec(e);if(s){let n=parseInt(s[1],10);return t%n===0}let r=parseInt(e,10);return isNaN(r)?!1:t===r}}});function dr(c){let e=c.trim();if(e.length<10)return{level:"low",matchedPatterns:[]};for(let s of Wi)if(s.test(e))return{level:"low",matchedPatterns:[]};let t=[];for(let s of Hi)for(let r of s.patterns)if(r.test(e)){t.push(s.name);break}return t.length>0?{level:"high",matchedPatterns:t}:{level:"low",matchedPatterns:[]}}var Wi,Hi,ur=f(()=>{"use strict";Wi=[/^(what|where|when|who|why|how|which|can you|could you|do you|is there|are there|was |wer |wo |wann |warum |wie |welch|kannst du|könntest du|gibt es)/i,/^(hi|hey|hello|hallo|guten (morgen|tag|abend)|moin|servus|grüß|na\b|yo\b|sup\b|good (morning|evening|night))\b/i,/^(tell me|show me|find|search|help|explain|describe|translate|summarize|zeig|such|hilf|erklär|beschreib|übersetze|fass zusammen)/i,/^(ok|okay|yes|no|ja|nein|danke|thanks|thank you|sure|alright|klar|gut|cool|nice|great|perfect|genau|stimmt|richtig)\b/i],Hi=[{name:"fact:name",patterns:[/\b(my name is|i'm called|i am called|ich heiße|ich bin der|ich bin die|mein name ist)\b/i]},{name:"fact:location",patterns:[/\b(i live in|i'm from|i am from|ich wohne|ich lebe in|ich komme aus|ich bin aus)\b/i]},{name:"fact:work",patterns:[/\b(i work at|i work as|i work for|ich arbeite|mein job|mein beruf|ich bin .{0,20}(entwickler|ingenieur|lehrer|arzt|designer))\b/i]},{name:"fact:birthday",patterns:[/\b(my birthday|i was born|ich bin geboren|mein geburtstag|ich habe am .{1,15} geburtstag)\b/i]},{name:"fact:age",patterns:[/\b(i'm \d+ years|i am \d+ years|ich bin \d+ (jahre|jahr))\b/i]},{name:"preference:like",patterns:[/\b(i love|i really like|i enjoy|ich liebe|ich mag|mir gefällt|mir gefallen)\b/i]},{name:"preference:dislike",patterns:[/\b(i hate|i dislike|i can't stand|ich hasse|ich mag .{0,5} nicht|ich kann .{0,10} nicht leiden)\b/i]},{name:"preference:prefer",patterns:[/\b(i prefer|i'd rather|ich bevorzuge|ich nehme lieber|mir ist .{0,10} lieber)\b/i]},{name:"preference:favorite",patterns:[/\b(my fav|my favorite|my favourite|mein lieblings|meine lieblings|am liebsten)\b/i]},{name:"correction",patterns:[/\b(actually|actually,? (i|my|it)|eigentlich|das stimmt nicht|nein,? ich|that's not right|that's wrong|nicht ganz)\b/i]},{name:"relationship:family",patterns:[/\b(my wife|my husband|my partner|meine frau|mein mann|mein partner|meine partnerin|my daughter|my son|mein sohn|meine tochter|my kids|meine kinder|my mother|my father|meine mutter|mein vater)\b/i]},{name:"relationship:professional",patterns:[/\b(my boss|my manager|my colleague|mein chef|mein vorgesetzter|mein kollege|meine kollegin)\b/i]},{name:"relationship:social",patterns:[/\b(my friend|my best friend|mein freund|meine freundin|mein bester freund)\b/i]},{name:"fact:language",patterns:[/\b(i speak|ich spreche|my native|meine muttersprache)\b/i]},{name:"fact:education",patterns:[/\b(i studied|i went to|ich habe .{0,10} studiert|ich war auf der|mein studium)\b/i]},{name:"fact:hobby",patterns:[/\b(my hobby|i play .{0,10}(guitar|piano|football|tennis|chess)|mein hobby|ich spiele|in my free time|in meiner freizeit)\b/i]},{name:"decision",patterns:[/\b(i've decided|i decided|i will always|ich habe (mich )?entschieden|ich werde immer)\b/i]},{name:"commitment",patterns:[/\b(i always|i never|ich mache immer|ich mache nie|i'm trying to|ich versuche)\b/i]}];d(dr,"scanSignal")});var Xi,zi,Bt,mr=f(()=>{"use strict";Xi=["fact","preference","correction","entity","decision","relationship","principle","commitment","moment","skill"],zi=`You are a memory extraction system. Analyze the user message and extract personal facts about the USER (not about what they're asking).
|
|
457
464
|
|
|
458
465
|
Rules:
|
|
459
466
|
- Only extract information the user STATES about themselves
|
|
@@ -473,20 +480,20 @@ Extract memories from this conversation:
|
|
|
473
480
|
User: {USER_MESSAGE}
|
|
474
481
|
Assistant: {ASSISTANT_RESPONSE}
|
|
475
482
|
|
|
476
|
-
Return ONLY a valid JSON array, no explanation:`,Bt=class{static{d(this,"MemoryExtractor")}llm;memoryRepo;logger;embeddingService;minConfidence;constructor(e,t,s,r,n=.4){this.llm=e,this.memoryRepo=t,this.logger=s,this.embeddingService=r,this.minConfidence=n}async extract(e,t,s){try{let r=Xi.replace("{USER_MESSAGE}",t).replace("{ASSISTANT_RESPONSE}",s),n=await this.llm.complete({messages:[{role:"user",content:r}],temperature:.1,tier:"fast",maxTokens:1024}),o=this.parseResponse(n.content);if(o.length===0)return 0;let i=0;for(let a of o)if(!(a.confidence<this.minConfidence))try{let l=this.memoryRepo.saveWithMetadata(e,a.key,a.value,a.category,a.type,a.confidence,"auto");this.embeddingService&&this.embeddingService.embedAndStore(e,`${a.key}: ${a.value}`,"memory",l.id).catch(u=>this.logger.debug({err:u},"Auto-embed failed")),i++,this.logger.info({key:a.key,type:a.type,confidence:a.confidence},"Auto-extracted memory saved")}catch(l){this.logger.warn({err:l,key:a.key},"Failed to save extracted memory")}return i}catch(r){return this.logger.error({err:r},"Memory extraction failed"),0}}parseResponse(e){try{let t=e.match(/\[[\s\S]*\]/);if(!t)return[];let s=JSON.parse(t[0]);return Array.isArray(s)?s.filter(r=>typeof r=="object"&&r!==null).map(r=>({key:String(r.key||""),value:String(r.value||""),type:this.validateType(String(r.type||"fact")),confidence:this.clampConfidence(Number(r.confidence)||.5),category:String(r.category||"general")})).filter(r=>r.key&&r.value):[]}catch{return this.logger.debug({content:e.slice(0,200)},"Failed to parse extraction response"),[]}}validateType(e){return zi.includes(e)?e:"fact"}clampConfidence(e){return Math.max(0,Math.min(1,e))}}});var Wt,pr=f(()=>{"use strict";ur();mr();Wt=class{static{d(this,"ActiveLearningService")}extractor;logger;minMessageLength;maxExtractionsPerMinute;extractionTimestamps=new Map;constructor(e){this.logger=e.logger,this.minMessageLength=e.minMessageLength??15,this.maxExtractionsPerMinute=e.maxExtractionsPerMinute??5,this.extractor=new Bt(e.llm,e.memoryRepo,this.logger,e.embeddingService,e.minConfidence??.4)}onMessageProcessed(e,t,s){if(!t||t.length<this.minMessageLength)return;let r=dr(t);if(r.level==="low"){this.logger.debug({signal:"low"},"Skipping extraction \u2014 low signal");return}if(!this.checkRateLimit(e)){this.logger.debug({userId:e},"Skipping extraction \u2014 rate limit reached");return}this.logger.info({signal:r.level,patterns:r.matchedPatterns},"High signal detected, triggering extraction"),this.extractor.extract(e,t,s).then(n=>{n>0&&this.logger.info({userId:e,extractedCount:n},"Auto-extraction complete")}).catch(n=>{this.logger.error({err:n},"Auto-extraction failed")})}checkRateLimit(e){let t=Date.now(),s=t-6e4,r=this.extractionTimestamps.get(e);r||(r=[],this.extractionTimestamps.set(e,r));let n=r.filter(o=>o>s);return this.extractionTimestamps.set(e,n),n.length>=this.maxExtractionsPerMinute?!1:(n.push(t),!0)}}});var qi,Ki,Vi,Gi,Ht,hr=f(()=>{"use strict";qi=Math.LN2,Ki=.3,Vi=.7,Gi=3,Ht=class{static{d(this,"MemoryRetriever")}memoryRepo;logger;embeddingService;constructor(e,t,s){this.memoryRepo=e,this.logger=t,this.embeddingService=s}async retrieve(e,t,s=15){try{let r=this.memoryRepo.keywordSearch(e,t,30),n=[],o=!1;if(this.embeddingService)try{n=await this.embeddingService.semanticSearch(e,t,30),o=n.length>0}catch(m){this.logger.debug({err:m},"Semantic search failed, falling back to keyword-only")}let i=new Map,a=r.length;for(let m=0;m<r.length;m++){let p=r[m],E=a>0?1-m/a:0,w=o?Ki:1,T=this.applyBoosts(E*w,p);i.set(p.id,{memory:{key:p.key,value:p.value,category:p.category,type:p.type,score:T},score:T}),this.memoryRepo.recordAccess(p.id)}if(o)for(let m of n){let p=m.score*Vi,E=i.get(m.key);if(E)E.score+=p,E.memory.score=E.score;else{let w=this.memoryRepo.recall(e,m.key),T=this.applyBoosts(p,w||void 0);i.set(m.key,{memory:{key:m.key,value:m.value,category:m.category,type:w?.type||"general",score:T},score:T}),w&&this.memoryRepo.recordAccess(w.id)}}let l=Array.from(i.values()).sort((m,p)=>p.score-m.score),u=new Map,h=[];for(let{memory:m}of l){let p=u.get(m.type)||0;if(!(p>=Gi)&&(u.set(m.type,p+1),h.push(m),h.length>=s))break}return this.logger.debug({keywordCount:r.length,semanticCount:n.length,resultCount:h.length,hasSemanticSearch:o},"Hybrid memory retrieval complete"),h}catch(r){return this.logger.error({err:r},"Memory retrieval failed"),this.memoryRepo.getRecentForPrompt(e,s).map(n=>({key:n.key,value:n.value,category:n.category,type:n.type,score:0}))}}applyBoosts(e,t){let s=e;if(t){s*=.5+.5*t.confidence;let r=new Date(t.updatedAt).getTime(),n=Date.now()-r,o=Math.exp(-qi*n/2592e6);s*=o}return s}}});import{EventEmitter as Yi}from"node:events";var z,ie=f(()=>{"use strict";z=class extends Yi{static{d(this,"MessagingAdapter")}status="disconnected";async sendPhoto(e,t,s){}async sendFile(e,t,s,r){}getStatus(){return this.status}}});import{Bot as Ji,InputFile as Zn}from"grammy";function Qn(c){if(c==="markdown")return"MarkdownV2";if(c==="html")return"HTML"}var cs,eo=f(()=>{"use strict";ie();d(Qn,"mapParseMode");cs=class extends z{static{d(this,"TelegramAdapter")}platform="telegram";bot;constructor(e){super(),this.bot=new Ji(e)}async connect(){this.status="connecting",this.bot.on("message:text",e=>{this.emit("message",this.normalizeMessage(e.message,e.message.text))}),this.bot.on("message:photo",async e=>{let t=e.message,r=(t.caption??"")||"[Photo]",n=t.photo[t.photo.length-1],o=await this.downloadAttachment(n.file_id,"image","image/jpeg"),i=this.normalizeMessage(t,r);i.attachments=o?[o]:void 0,this.emit("message",i)}),this.bot.on("message:voice",async e=>{let t=e.message,s=await this.downloadAttachment(t.voice.file_id,"audio",t.voice.mime_type??"audio/ogg"),r=this.normalizeMessage(t,"[Voice message]");r.attachments=s?[s]:void 0,this.emit("message",r)}),this.bot.on("message:audio",async e=>{let t=e.message,r=(t.caption??"")||`[Audio: ${t.audio.file_name??"audio"}]`,n=await this.downloadAttachment(t.audio.file_id,"audio",t.audio.mime_type??"audio/mpeg"),o=this.normalizeMessage(t,r);o.attachments=n?[n]:void 0,this.emit("message",o)}),this.bot.on("message:video",async e=>{let t=e.message,r=(t.caption??"")||"[Video]",n=await this.downloadAttachment(t.video.file_id,"video",t.video.mime_type??"video/mp4"),o=this.normalizeMessage(t,r);o.attachments=n?[n]:void 0,this.emit("message",o)}),this.bot.on("message:document",async e=>{let t=e.message,s=t.document,n=(t.caption??"")||`[Document: ${s.file_name??"file"}]`,o=await this.downloadAttachment(s.file_id,"document",s.mime_type??"application/octet-stream",s.file_name),i=this.normalizeMessage(t,n);i.attachments=o?[o]:void 0,this.emit("message",i)}),this.bot.on("message:video_note",async e=>{let t=e.message,s=await this.downloadAttachment(t.video_note.file_id,"video","video/mp4"),r=this.normalizeMessage(t,"[Video note]");r.attachments=s?[s]:void 0,this.emit("message",r)}),this.bot.on("message:sticker",e=>{let t=e.message,s=t.sticker.emoji??"\u{1F3F7}\uFE0F";this.emit("message",this.normalizeMessage(t,`[Sticker: ${s}]`))}),this.bot.catch(e=>{this.emit("error",e.error)}),this.bot.start({onStart:d(()=>{this.status="connected",this.emit("connected")},"onStart")})}async disconnect(){await this.bot.stop(),this.status="disconnected",this.emit("disconnected")}async sendMessage(e,t,s){let r=await this.bot.api.sendMessage(Number(e),t,{reply_to_message_id:s?.replyToMessageId?Number(s.replyToMessageId):void 0,parse_mode:Qn(s?.parseMode)});return String(r.message_id)}async editMessage(e,t,s,r){await this.bot.api.editMessageText(Number(e),Number(t),s,{parse_mode:Qn(r?.parseMode)})}async deleteMessage(e,t){await this.bot.api.deleteMessage(Number(e),Number(t))}async sendPhoto(e,t,s){let r=await this.bot.api.sendPhoto(Number(e),new Zn(t,"image.png"),{caption:s});return String(r.message_id)}async sendFile(e,t,s,r){let n=await this.bot.api.sendDocument(Number(e),new Zn(t,s),{caption:r});return String(n.message_id)}normalizeMessage(e,t){return{id:String(e.message_id),platform:"telegram",chatId:String(e.chat.id),chatType:e.chat.type==="private"?"dm":"group",userId:String(e.from.id),userName:e.from.username??String(e.from.id),displayName:[e.from.first_name,e.from.last_name].filter(Boolean).join(" "),text:t,timestamp:new Date(e.date*1e3),replyToMessageId:e.reply_to_message?String(e.reply_to_message.message_id):void 0}}async downloadAttachment(e,t,s,r){try{let o=(await this.bot.api.getFile(e)).file_path;if(!o)return;let i=`https://api.telegram.org/file/bot${this.bot.token}/${o}`,a=await fetch(i);if(!a.ok)return;let l=Buffer.from(await a.arrayBuffer());return{type:t,mimeType:s,fileName:r??o.split("/").pop(),size:l.length,data:l}}catch(n){console.error("[telegram] Failed to download file",e,n);return}}}});import{Client as Zi,GatewayIntentBits as ls,Events as fr}from"discord.js";var ds,to=f(()=>{"use strict";ie();ds=class extends z{static{d(this,"DiscordAdapter")}platform="discord";client=null;token;constructor(e){super(),this.token=e}async connect(){this.status="connecting",this.client=new Zi({intents:[ls.Guilds,ls.GuildMessages,ls.MessageContent,ls.DirectMessages]}),this.client.on(fr.MessageCreate,async e=>{if(!e.author.bot)try{let t=await this.downloadAttachments(e),s=e.content||this.inferTextFromAttachments(t),r={id:e.id,platform:"discord",chatId:e.channelId,chatType:e.channel.isDMBased()?"dm":"group",userId:e.author.id,userName:e.author.username,displayName:e.author.displayName,text:s,timestamp:e.createdAt,replyToMessageId:e.reference?.messageId??void 0,attachments:t.length>0?t:void 0};this.emit("message",r)}catch(t){this.emit("error",t instanceof Error?t:new Error(String(t)))}}),this.client.on(fr.ClientReady,()=>{this.status="connected",this.emit("connected")}),this.client.on(fr.Error,e=>{this.emit("error",e)}),await this.client.login(this.token)}async disconnect(){this.client?.destroy(),this.client=null,this.status="disconnected",this.emit("disconnected")}async sendMessage(e,t,s){if(!this.client)throw new Error("Client is not connected");let r=await this.client.channels.fetch(e);if(!r?.isTextBased()||!("send"in r))throw new Error(`Channel ${e} is not a text channel`);return s?.replyToMessageId?(await(await r.messages.fetch(s.replyToMessageId)).reply(t)).id:(await r.send(t)).id}async editMessage(e,t,s,r){if(!this.client)throw new Error("Client is not connected");let n=await this.client.channels.fetch(e);if(!n?.isTextBased()||!("messages"in n))throw new Error(`Channel ${e} is not a text channel`);await(await n.messages.fetch(t)).edit(s)}async deleteMessage(e,t){if(!this.client)throw new Error("Client is not connected");let s=await this.client.channels.fetch(e);if(!s?.isTextBased()||!("messages"in s))throw new Error(`Channel ${e} is not a text channel`);await(await s.messages.fetch(t)).delete()}async sendPhoto(e,t,s){if(!this.client)return;let r=await this.client.channels.fetch(e);return!r?.isTextBased()||!("send"in r)?void 0:(await r.send({content:s,files:[{attachment:t,name:"image.png"}]})).id}async sendFile(e,t,s,r){if(!this.client)return;let n=await this.client.channels.fetch(e);return!n?.isTextBased()||!("send"in n)?void 0:(await n.send({content:r,files:[{attachment:t,name:s}]})).id}async downloadAttachments(e){let t=[],s=e.attachments;if(!s||s.size===0)return t;for(let[,r]of s)try{let n=await fetch(r.url);if(!n.ok)continue;let o=await n.arrayBuffer(),i=Buffer.from(o),a=this.classifyContentType(r.contentType);t.push({type:a,url:r.url,mimeType:r.contentType??void 0,fileName:r.name??void 0,size:r.size??i.length,data:i})}catch(n){console.error("[discord] Failed to download attachment",r.url,n)}return t}classifyContentType(e){return e?e.startsWith("image/")?"image":e.startsWith("audio/")?"audio":e.startsWith("video/")?"video":"document":"other"}inferTextFromAttachments(e){if(e.length===0)return"";let t=e.map(s=>s.type);return t.includes("image")?"[Photo]":t.includes("audio")?"[Voice message]":t.includes("video")?"[Video]":t.includes("document")?"[Document]":"[File]"}}});var us,so=f(()=>{"use strict";ie();us=class extends z{static{d(this,"MatrixAdapter")}platform="matrix";client;homeserverUrl;accessToken;botUserId;constructor(e,t,s){super(),this.homeserverUrl=e.replace(/\/+$/,""),this.accessToken=t,this.botUserId=s}async connect(){this.status="connecting";let{MatrixClient:e,SimpleFsStorageProvider:t,AutojoinRoomsMixin:s}=await import("matrix-bot-sdk"),r=new t("./data/matrix-storage");this.client=new e(this.homeserverUrl,this.accessToken,r),s.setupOnClient(this.client),this.client.on("room.message",async(n,o)=>{if(o.sender===this.botUserId)return;let i=o.content?.msgtype;if(i)try{let a=await this.normalizeEvent(n,o,i);a&&this.emit("message",a)}catch(a){this.emit("error",a instanceof Error?a:new Error(String(a)))}}),await this.client.start(),this.status="connected",this.emit("connected")}async disconnect(){this.client.stop(),this.status="disconnected",this.emit("disconnected")}async sendMessage(e,t,s){return s?.parseMode==="html"?await this.client.sendEvent(e,"m.room.message",{msgtype:"m.text",body:t.replace(/<[^>]*>/g,""),format:"org.matrix.custom.html",formatted_body:t}):await this.client.sendText(e,t)}async editMessage(e,t,s,r){let n=r?.parseMode==="html",o={msgtype:"m.text",body:"* "+(n?s.replace(/<[^>]*>/g,""):s),"m.new_content":{msgtype:"m.text",body:n?s.replace(/<[^>]*>/g,""):s,...n?{format:"org.matrix.custom.html",formatted_body:s}:{}},"m.relates_to":{rel_type:"m.replace",event_id:t}};await this.client.sendEvent(e,"m.room.message",o)}async deleteMessage(e,t){await this.client.redactEvent(e,t)}async sendPhoto(e,t,s){let r=await this.client.uploadContent(t,"image/png","image.png"),n={msgtype:"m.image",body:s??"image.png",url:r,info:{mimetype:"image/png",size:t.length}};return await this.client.sendEvent(e,"m.room.message",n)}async sendFile(e,t,s,r){let n=this.guessMimeType(s),o=await this.client.uploadContent(t,n,s),i={msgtype:"m.file",body:r??s,filename:s,url:o,info:{mimetype:n,size:t.length}};return await this.client.sendEvent(e,"m.room.message",i)}async normalizeEvent(e,t,s){let r={id:t.event_id,platform:"matrix",chatId:e,chatType:"group",userId:t.sender,userName:t.sender.split(":")[0].slice(1),timestamp:new Date(t.origin_server_ts),replyToMessageId:t.content["m.relates_to"]?.["m.in_reply_to"]?.event_id};switch(s){case"m.text":return{...r,text:t.content.body};case"m.image":{let n=await this.downloadAttachment(t.content,"image");return{...r,text:t.content.body??"[Photo]",attachments:n?[n]:void 0}}case"m.audio":{let n=await this.downloadAttachment(t.content,"audio");return{...r,text:t.content.body??"[Voice message]",attachments:n?[n]:void 0}}case"m.video":{let n=await this.downloadAttachment(t.content,"video");return{...r,text:t.content.body??"[Video]",attachments:n?[n]:void 0}}case"m.file":{let n=await this.downloadAttachment(t.content,"document");return{...r,text:t.content.body??"[Document]",attachments:n?[n]:void 0}}default:return t.content.body?{...r,text:t.content.body}:void 0}}async downloadAttachment(e,t){let s=e.url;if(!s||!s.startsWith("mxc://"))return;let r=e.info??{},n=r.mimetype,o=r.size,i=e.filename??e.body??"file";try{let a=s.slice(6),l=`${this.homeserverUrl}/_matrix/media/v3/download/${a}`,u=await fetch(l,{headers:{Authorization:`Bearer ${this.accessToken}`}});if(!u.ok)return;let h=await u.arrayBuffer(),m=Buffer.from(h);return{type:t,mimeType:n,fileName:i,size:o??m.length,data:m}}catch(a){console.error("[matrix] Failed to download attachment",s,a);return}}guessMimeType(e){let t=e.split(".").pop()?.toLowerCase();return{pdf:"application/pdf",txt:"text/plain",json:"application/json",csv:"text/csv",png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",mp3:"audio/mpeg",ogg:"audio/ogg",mp4:"video/mp4",zip:"application/zip",doc:"application/msword",docx:"application/vnd.openxmlformats-officedocument.wordprocessingml.document",xlsx:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}[t??""]??"application/octet-stream"}}});var ms,ro=f(()=>{"use strict";ie();ms=class extends z{static{d(this,"WhatsAppAdapter")}platform="whatsapp";socket;downloadMedia;dataPath;reconnectAttempts=0;reconnectTimer;constructor(e){super(),this.dataPath=e}async connect(){this.status="connecting";let e=await import("@whiskeysockets/baileys"),t=e.default??e,{makeWASocket:s,useMultiFileAuthState:r,DisconnectReason:n,downloadMediaMessage:o}=t;this.downloadMedia=o;let{state:i,saveCreds:a}=await r(this.dataPath);this.socket=s({auth:i,printQRInTerminal:!0}),this.socket.ev.on("creds.update",a),this.socket.ev.on("connection.update",l=>{if(l.connection==="open"&&(this.status="connected",this.reconnectAttempts=0,this.emit("connected")),l.connection==="close"){let h=l.lastDisconnect?.error?.output?.statusCode!==n.loggedOut;if(this.status="disconnected",this.emit("disconnected"),h){let m=Math.min(1e3*Math.pow(2,this.reconnectAttempts),6e4);this.reconnectAttempts++,this.reconnectTimer=setTimeout(()=>this.connect(),m)}}}),this.socket.ev.on("messages.upsert",({messages:l,type:u})=>{if(u==="notify")for(let h of l)h.message&&(h.key.fromMe||this.processMessage(h).catch(m=>{this.emit("error",m instanceof Error?m:new Error(String(m)))}))})}async disconnect(){this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=void 0),this.reconnectAttempts=0,this.socket?.end(void 0),this.socket=void 0,this.status="disconnected",this.emit("disconnected")}async sendMessage(e,t,s){return(await this.socket.sendMessage(e,{text:t},s?.replyToMessageId?{quoted:{key:{remoteJid:e,id:s.replyToMessageId},message:{}}}:void 0))?.key?.id??""}async editMessage(e,t,s,r){await this.socket.sendMessage(e,{text:s,edit:{remoteJid:e,id:t,fromMe:!0}})}async deleteMessage(e,t){await this.socket.sendMessage(e,{delete:{remoteJid:e,id:t,fromMe:!0}})}async sendPhoto(e,t,s){return(await this.socket.sendMessage(e,{image:t,caption:s}))?.key?.id}async sendFile(e,t,s,r){return(await this.socket.sendMessage(e,{document:t,fileName:s,caption:r,mimetype:this.guessMimeType(s)}))?.key?.id}async processMessage(e){let t=e.message,s=t.conversation??t.extendedTextMessage?.text??t.imageMessage?.caption??t.videoMessage?.caption??t.documentMessage?.caption??"",r=[],n=s;if(t.imageMessage){let i=await this.downloadMediaSafe(e);i&&r.push({type:"image",mimeType:t.imageMessage.mimetype??"image/jpeg",size:t.imageMessage.fileLength??i.length,data:i}),n||(n="[Photo]")}else if(t.audioMessage){let i=await this.downloadMediaSafe(e);i&&r.push({type:"audio",mimeType:t.audioMessage.mimetype??"audio/ogg",size:t.audioMessage.fileLength??i.length,data:i}),n||(n="[Voice message]")}else if(t.videoMessage){let i=await this.downloadMediaSafe(e);i&&r.push({type:"video",mimeType:t.videoMessage.mimetype??"video/mp4",size:t.videoMessage.fileLength??i.length,data:i}),n||(n="[Video]")}else if(t.documentMessage){let i=await this.downloadMediaSafe(e);i&&r.push({type:"document",mimeType:t.documentMessage.mimetype??"application/octet-stream",fileName:t.documentMessage.fileName??"document",size:t.documentMessage.fileLength??i.length,data:i}),n||(n="[Document]")}else if(t.stickerMessage&&!s)return;if(!n&&r.length===0)return;let o={id:e.key.id??"",platform:"whatsapp",chatId:e.key.remoteJid??"",chatType:e.key.remoteJid?.endsWith("@g.us")?"group":"dm",userId:e.key.participant??e.key.remoteJid??"",userName:e.pushName??e.key.participant??e.key.remoteJid??"",text:n,timestamp:new Date(e.messageTimestamp*1e3),replyToMessageId:t.extendedTextMessage?.contextInfo?.stanzaId??void 0,attachments:r.length>0?r:void 0};this.emit("message",o)}async downloadMediaSafe(e){try{if(!this.downloadMedia)return;let t=await this.downloadMedia(e,"buffer",{});return Buffer.isBuffer(t)?t:Buffer.from(t)}catch(t){console.error("[whatsapp] Failed to download media",t);return}}guessMimeType(e){let t=e.split(".").pop()?.toLowerCase();return{pdf:"application/pdf",txt:"text/plain",json:"application/json",csv:"text/csv",png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",mp3:"audio/mpeg",ogg:"audio/ogg",mp4:"video/mp4",zip:"application/zip",doc:"application/msword",docx:"application/vnd.openxmlformats-officedocument.wordprocessingml.document",xlsx:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}[t??""]??"application/octet-stream"}}});var ps,no=f(()=>{"use strict";ie();ps=class extends z{static{d(this,"SignalAdapter")}apiUrl;phoneNumber;platform="signal";pollingInterval;constructor(e,t){super(),this.apiUrl=e,this.phoneNumber=t}async connect(){this.status="connecting";try{let e=await fetch(`${this.apiUrl}/v1/about`);if(!e.ok)throw new Error(`Signal API not reachable: ${e.status}`);this.pollingInterval=setInterval(()=>{this.pollMessages().catch(t=>{this.emit("error",t instanceof Error?t:new Error(String(t)))})},2e3),this.status="connected",this.emit("connected")}catch(e){this.status="error",this.emit("error",e instanceof Error?e:new Error(String(e)))}}async disconnect(){this.pollingInterval&&(clearInterval(this.pollingInterval),this.pollingInterval=void 0),this.status="disconnected",this.emit("disconnected")}async sendMessage(e,t,s){let r=e.startsWith("group."),n={message:t,number:this.phoneNumber};r?n.recipients=[e.replace("group.","")]:n.recipients=[e];let o=await fetch(`${this.apiUrl}/v2/send`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)});if(!o.ok)throw new Error(`Signal send failed: ${o.status} ${await o.text()}`);let i=await o.json();return String(i.timestamp??Date.now())}async editMessage(e,t,s,r){throw new Error("Signal does not support message editing")}async deleteMessage(e,t){let s={number:this.phoneNumber,recipients:[e],timestamp:Number(t)},r=await fetch(`${this.apiUrl}/v1/deleteMessage`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s)});if(!r.ok)throw new Error(`Signal delete failed: ${r.status} ${await r.text()}`)}async pollMessages(){let e=await fetch(`${this.apiUrl}/v1/receive/${this.phoneNumber}`);if(!e.ok)return;let t=await e.json();for(let s of t){let r=s.envelope?.dataMessage;if(!r||!r.message&&(!r.attachments||r.attachments.length===0))continue;let n=s.envelope,o=r.groupInfo?.groupId?`group.${r.groupInfo.groupId}`:n.sourceNumber??n.source??"",i=[];if(r.attachments)for(let u of r.attachments){let h=await this.downloadAttachment(u);h&&i.push(h)}let a=r.message||this.inferTextFromAttachments(i)||"";if(!a&&i.length===0)continue;let l={id:String(r.timestamp??Date.now()),platform:"signal",chatId:o,chatType:r.groupInfo?"group":"dm",userId:n.sourceNumber??n.source??"",userName:n.sourceName??n.sourceNumber??n.source??"",displayName:n.sourceName,text:a,timestamp:new Date(r.timestamp??Date.now()),attachments:i.length>0?i:void 0};this.emit("message",l)}}async downloadAttachment(e){if(e.id)try{let t=await fetch(`${this.apiUrl}/v1/attachments/${e.id}`);if(!t.ok)return;let s=await t.arrayBuffer(),r=Buffer.from(s);return{type:this.classifyContentType(e.contentType),mimeType:e.contentType??void 0,fileName:e.filename??void 0,size:e.size??r.length,data:r}}catch(t){console.error("[signal] Failed to download attachment",e.id,t);return}}classifyContentType(e){return e?e.startsWith("image/")?"image":e.startsWith("audio/")?"audio":e.startsWith("video/")?"video":"document":"other"}inferTextFromAttachments(e){if(e.length===0)return"";let t=e.map(s=>s.type);return t.includes("image")?"[Photo]":t.includes("audio")?"[Voice message]":t.includes("video")?"[Video]":t.includes("document")?"[Document]":"[File]"}}});import gr from"node:readline";var hs,oo=f(()=>{"use strict";ie();hs=class extends z{static{d(this,"CLIAdapter")}platform="cli";rl;messageCounter=0;async connect(){this.status="connecting",this.rl=gr.createInterface({input:process.stdin,output:process.stdout,prompt:"You: "}),console.log(`
|
|
483
|
+
Return ONLY a valid JSON array, no explanation:`,Bt=class{static{d(this,"MemoryExtractor")}llm;memoryRepo;logger;embeddingService;minConfidence;constructor(e,t,s,r,n=.4){this.llm=e,this.memoryRepo=t,this.logger=s,this.embeddingService=r,this.minConfidence=n}async extract(e,t,s){try{let r=zi.replace("{USER_MESSAGE}",t).replace("{ASSISTANT_RESPONSE}",s),n=await this.llm.complete({messages:[{role:"user",content:r}],temperature:.1,tier:"fast",maxTokens:1024}),o=this.parseResponse(n.content);if(o.length===0)return 0;let i=0;for(let a of o)if(!(a.confidence<this.minConfidence))try{let l=this.memoryRepo.saveWithMetadata(e,a.key,a.value,a.category,a.type,a.confidence,"auto");this.embeddingService&&this.embeddingService.embedAndStore(e,`${a.key}: ${a.value}`,"memory",l.id).catch(u=>this.logger.debug({err:u},"Auto-embed failed")),i++,this.logger.info({key:a.key,type:a.type,confidence:a.confidence},"Auto-extracted memory saved")}catch(l){this.logger.warn({err:l,key:a.key},"Failed to save extracted memory")}return i}catch(r){return this.logger.error({err:r},"Memory extraction failed"),0}}parseResponse(e){try{let t=e.match(/\[[\s\S]*\]/);if(!t)return[];let s=JSON.parse(t[0]);return Array.isArray(s)?s.filter(r=>typeof r=="object"&&r!==null).map(r=>({key:String(r.key||""),value:String(r.value||""),type:this.validateType(String(r.type||"fact")),confidence:this.clampConfidence(Number(r.confidence)||.5),category:String(r.category||"general")})).filter(r=>r.key&&r.value):[]}catch{return this.logger.debug({content:e.slice(0,200)},"Failed to parse extraction response"),[]}}validateType(e){return Xi.includes(e)?e:"fact"}clampConfidence(e){return Math.max(0,Math.min(1,e))}}});var Wt,pr=f(()=>{"use strict";ur();mr();Wt=class{static{d(this,"ActiveLearningService")}extractor;logger;minMessageLength;maxExtractionsPerMinute;extractionTimestamps=new Map;constructor(e){this.logger=e.logger,this.minMessageLength=e.minMessageLength??15,this.maxExtractionsPerMinute=e.maxExtractionsPerMinute??5,this.extractor=new Bt(e.llm,e.memoryRepo,this.logger,e.embeddingService,e.minConfidence??.4)}onMessageProcessed(e,t,s){if(!t||t.length<this.minMessageLength)return;let r=dr(t);if(r.level==="low"){this.logger.debug({signal:"low"},"Skipping extraction \u2014 low signal");return}if(!this.checkRateLimit(e)){this.logger.debug({userId:e},"Skipping extraction \u2014 rate limit reached");return}this.logger.info({signal:r.level,patterns:r.matchedPatterns},"High signal detected, triggering extraction"),this.extractor.extract(e,t,s).then(n=>{n>0&&this.logger.info({userId:e,extractedCount:n},"Auto-extraction complete")}).catch(n=>{this.logger.error({err:n},"Auto-extraction failed")})}checkRateLimit(e){let t=Date.now(),s=t-6e4,r=this.extractionTimestamps.get(e);r||(r=[],this.extractionTimestamps.set(e,r));let n=r.filter(o=>o>s);return this.extractionTimestamps.set(e,n),n.length>=this.maxExtractionsPerMinute?!1:(n.push(t),!0)}}});var qi,Ki,Vi,Gi,Ht,hr=f(()=>{"use strict";qi=Math.LN2,Ki=.3,Vi=.7,Gi=3,Ht=class{static{d(this,"MemoryRetriever")}memoryRepo;logger;embeddingService;constructor(e,t,s){this.memoryRepo=e,this.logger=t,this.embeddingService=s}async retrieve(e,t,s=15){try{let r=this.memoryRepo.keywordSearch(e,t,30),n=[],o=!1;if(this.embeddingService)try{n=await this.embeddingService.semanticSearch(e,t,30),o=n.length>0}catch(m){this.logger.debug({err:m},"Semantic search failed, falling back to keyword-only")}let i=new Map,a=r.length;for(let m=0;m<r.length;m++){let p=r[m],E=a>0?1-m/a:0,w=o?Ki:1,T=this.applyBoosts(E*w,p);i.set(p.id,{memory:{key:p.key,value:p.value,category:p.category,type:p.type,score:T},score:T}),this.memoryRepo.recordAccess(p.id)}if(o)for(let m of n){let p=m.score*Vi,E=i.get(m.key);if(E)E.score+=p,E.memory.score=E.score;else{let w=this.memoryRepo.recall(e,m.key),T=this.applyBoosts(p,w||void 0);i.set(m.key,{memory:{key:m.key,value:m.value,category:m.category,type:w?.type||"general",score:T},score:T}),w&&this.memoryRepo.recordAccess(w.id)}}let l=Array.from(i.values()).sort((m,p)=>p.score-m.score),u=new Map,h=[];for(let{memory:m}of l){let p=u.get(m.type)||0;if(!(p>=Gi)&&(u.set(m.type,p+1),h.push(m),h.length>=s))break}return this.logger.debug({keywordCount:r.length,semanticCount:n.length,resultCount:h.length,hasSemanticSearch:o},"Hybrid memory retrieval complete"),h}catch(r){return this.logger.error({err:r},"Memory retrieval failed"),this.memoryRepo.getRecentForPrompt(e,s).map(n=>({key:n.key,value:n.value,category:n.category,type:n.type,score:0}))}}applyBoosts(e,t){let s=e;if(t){s*=.5+.5*t.confidence;let r=new Date(t.updatedAt).getTime(),n=Date.now()-r,o=Math.exp(-qi*n/2592e6);s*=o}return s}}});import{EventEmitter as Yi}from"node:events";var X,ie=f(()=>{"use strict";X=class extends Yi{static{d(this,"MessagingAdapter")}status="disconnected";async sendPhoto(e,t,s){}async sendFile(e,t,s,r){}getStatus(){return this.status}}});import{Bot as Ji,InputFile as Zn}from"grammy";function Qn(c){if(c==="markdown")return"MarkdownV2";if(c==="html")return"HTML"}var cs,eo=f(()=>{"use strict";ie();d(Qn,"mapParseMode");cs=class extends X{static{d(this,"TelegramAdapter")}platform="telegram";bot;constructor(e){super(),this.bot=new Ji(e)}async connect(){this.status="connecting",this.bot.on("message:text",e=>{this.emit("message",this.normalizeMessage(e.message,e.message.text))}),this.bot.on("message:photo",async e=>{let t=e.message,r=(t.caption??"")||"[Photo]",n=t.photo[t.photo.length-1],o=await this.downloadAttachment(n.file_id,"image","image/jpeg"),i=this.normalizeMessage(t,r);i.attachments=o?[o]:void 0,this.emit("message",i)}),this.bot.on("message:voice",async e=>{let t=e.message,s=await this.downloadAttachment(t.voice.file_id,"audio",t.voice.mime_type??"audio/ogg"),r=this.normalizeMessage(t,"[Voice message]");r.attachments=s?[s]:void 0,this.emit("message",r)}),this.bot.on("message:audio",async e=>{let t=e.message,r=(t.caption??"")||`[Audio: ${t.audio.file_name??"audio"}]`,n=await this.downloadAttachment(t.audio.file_id,"audio",t.audio.mime_type??"audio/mpeg"),o=this.normalizeMessage(t,r);o.attachments=n?[n]:void 0,this.emit("message",o)}),this.bot.on("message:video",async e=>{let t=e.message,r=(t.caption??"")||"[Video]",n=await this.downloadAttachment(t.video.file_id,"video",t.video.mime_type??"video/mp4"),o=this.normalizeMessage(t,r);o.attachments=n?[n]:void 0,this.emit("message",o)}),this.bot.on("message:document",async e=>{let t=e.message,s=t.document,n=(t.caption??"")||`[Document: ${s.file_name??"file"}]`,o=await this.downloadAttachment(s.file_id,"document",s.mime_type??"application/octet-stream",s.file_name),i=this.normalizeMessage(t,n);i.attachments=o?[o]:void 0,this.emit("message",i)}),this.bot.on("message:video_note",async e=>{let t=e.message,s=await this.downloadAttachment(t.video_note.file_id,"video","video/mp4"),r=this.normalizeMessage(t,"[Video note]");r.attachments=s?[s]:void 0,this.emit("message",r)}),this.bot.on("message:sticker",e=>{let t=e.message,s=t.sticker.emoji??"\u{1F3F7}\uFE0F";this.emit("message",this.normalizeMessage(t,`[Sticker: ${s}]`))}),this.bot.catch(e=>{this.emit("error",e.error)}),this.bot.start({onStart:d(()=>{this.status="connected",this.emit("connected")},"onStart")})}async disconnect(){await this.bot.stop(),this.status="disconnected",this.emit("disconnected")}async sendMessage(e,t,s){let r=await this.bot.api.sendMessage(Number(e),t,{reply_to_message_id:s?.replyToMessageId?Number(s.replyToMessageId):void 0,parse_mode:Qn(s?.parseMode)});return String(r.message_id)}async editMessage(e,t,s,r){await this.bot.api.editMessageText(Number(e),Number(t),s,{parse_mode:Qn(r?.parseMode)})}async deleteMessage(e,t){await this.bot.api.deleteMessage(Number(e),Number(t))}async sendPhoto(e,t,s){let r=await this.bot.api.sendPhoto(Number(e),new Zn(t,"image.png"),{caption:s});return String(r.message_id)}async sendFile(e,t,s,r){let n=await this.bot.api.sendDocument(Number(e),new Zn(t,s),{caption:r});return String(n.message_id)}normalizeMessage(e,t){return{id:String(e.message_id),platform:"telegram",chatId:String(e.chat.id),chatType:e.chat.type==="private"?"dm":"group",userId:String(e.from.id),userName:e.from.username??String(e.from.id),displayName:[e.from.first_name,e.from.last_name].filter(Boolean).join(" "),text:t,timestamp:new Date(e.date*1e3),replyToMessageId:e.reply_to_message?String(e.reply_to_message.message_id):void 0}}async downloadAttachment(e,t,s,r){try{let o=(await this.bot.api.getFile(e)).file_path;if(!o)return;let i=`https://api.telegram.org/file/bot${this.bot.token}/${o}`,a=await fetch(i);if(!a.ok)return;let l=Buffer.from(await a.arrayBuffer());return{type:t,mimeType:s,fileName:r??o.split("/").pop(),size:l.length,data:l}}catch(n){console.error("[telegram] Failed to download file",e,n);return}}}});import{Client as Zi,GatewayIntentBits as ls,Events as fr}from"discord.js";var ds,to=f(()=>{"use strict";ie();ds=class extends X{static{d(this,"DiscordAdapter")}platform="discord";client=null;token;constructor(e){super(),this.token=e}async connect(){this.status="connecting",this.client=new Zi({intents:[ls.Guilds,ls.GuildMessages,ls.MessageContent,ls.DirectMessages]}),this.client.on(fr.MessageCreate,async e=>{if(!e.author.bot)try{let t=await this.downloadAttachments(e),s=e.content||this.inferTextFromAttachments(t),r={id:e.id,platform:"discord",chatId:e.channelId,chatType:e.channel.isDMBased()?"dm":"group",userId:e.author.id,userName:e.author.username,displayName:e.author.displayName,text:s,timestamp:e.createdAt,replyToMessageId:e.reference?.messageId??void 0,attachments:t.length>0?t:void 0};this.emit("message",r)}catch(t){this.emit("error",t instanceof Error?t:new Error(String(t)))}}),this.client.on(fr.ClientReady,()=>{this.status="connected",this.emit("connected")}),this.client.on(fr.Error,e=>{this.emit("error",e)}),await this.client.login(this.token)}async disconnect(){this.client?.destroy(),this.client=null,this.status="disconnected",this.emit("disconnected")}async sendMessage(e,t,s){if(!this.client)throw new Error("Client is not connected");let r=await this.client.channels.fetch(e);if(!r?.isTextBased()||!("send"in r))throw new Error(`Channel ${e} is not a text channel`);return s?.replyToMessageId?(await(await r.messages.fetch(s.replyToMessageId)).reply(t)).id:(await r.send(t)).id}async editMessage(e,t,s,r){if(!this.client)throw new Error("Client is not connected");let n=await this.client.channels.fetch(e);if(!n?.isTextBased()||!("messages"in n))throw new Error(`Channel ${e} is not a text channel`);await(await n.messages.fetch(t)).edit(s)}async deleteMessage(e,t){if(!this.client)throw new Error("Client is not connected");let s=await this.client.channels.fetch(e);if(!s?.isTextBased()||!("messages"in s))throw new Error(`Channel ${e} is not a text channel`);await(await s.messages.fetch(t)).delete()}async sendPhoto(e,t,s){if(!this.client)return;let r=await this.client.channels.fetch(e);return!r?.isTextBased()||!("send"in r)?void 0:(await r.send({content:s,files:[{attachment:t,name:"image.png"}]})).id}async sendFile(e,t,s,r){if(!this.client)return;let n=await this.client.channels.fetch(e);return!n?.isTextBased()||!("send"in n)?void 0:(await n.send({content:r,files:[{attachment:t,name:s}]})).id}async downloadAttachments(e){let t=[],s=e.attachments;if(!s||s.size===0)return t;for(let[,r]of s)try{let n=await fetch(r.url);if(!n.ok)continue;let o=await n.arrayBuffer(),i=Buffer.from(o),a=this.classifyContentType(r.contentType);t.push({type:a,url:r.url,mimeType:r.contentType??void 0,fileName:r.name??void 0,size:r.size??i.length,data:i})}catch(n){console.error("[discord] Failed to download attachment",r.url,n)}return t}classifyContentType(e){return e?e.startsWith("image/")?"image":e.startsWith("audio/")?"audio":e.startsWith("video/")?"video":"document":"other"}inferTextFromAttachments(e){if(e.length===0)return"";let t=e.map(s=>s.type);return t.includes("image")?"[Photo]":t.includes("audio")?"[Voice message]":t.includes("video")?"[Video]":t.includes("document")?"[Document]":"[File]"}}});var us,so=f(()=>{"use strict";ie();us=class extends X{static{d(this,"MatrixAdapter")}platform="matrix";client;homeserverUrl;accessToken;botUserId;constructor(e,t,s){super(),this.homeserverUrl=e.replace(/\/+$/,""),this.accessToken=t,this.botUserId=s}async connect(){this.status="connecting";let{MatrixClient:e,SimpleFsStorageProvider:t,AutojoinRoomsMixin:s}=await import("matrix-bot-sdk"),r=new t("./data/matrix-storage");this.client=new e(this.homeserverUrl,this.accessToken,r),s.setupOnClient(this.client),this.client.on("room.message",async(n,o)=>{if(o.sender===this.botUserId)return;let i=o.content?.msgtype;if(i)try{let a=await this.normalizeEvent(n,o,i);a&&this.emit("message",a)}catch(a){this.emit("error",a instanceof Error?a:new Error(String(a)))}}),await this.client.start(),this.status="connected",this.emit("connected")}async disconnect(){this.client.stop(),this.status="disconnected",this.emit("disconnected")}async sendMessage(e,t,s){return s?.parseMode==="html"?await this.client.sendEvent(e,"m.room.message",{msgtype:"m.text",body:t.replace(/<[^>]*>/g,""),format:"org.matrix.custom.html",formatted_body:t}):await this.client.sendText(e,t)}async editMessage(e,t,s,r){let n=r?.parseMode==="html",o={msgtype:"m.text",body:"* "+(n?s.replace(/<[^>]*>/g,""):s),"m.new_content":{msgtype:"m.text",body:n?s.replace(/<[^>]*>/g,""):s,...n?{format:"org.matrix.custom.html",formatted_body:s}:{}},"m.relates_to":{rel_type:"m.replace",event_id:t}};await this.client.sendEvent(e,"m.room.message",o)}async deleteMessage(e,t){await this.client.redactEvent(e,t)}async sendPhoto(e,t,s){let r=await this.client.uploadContent(t,"image/png","image.png"),n={msgtype:"m.image",body:s??"image.png",url:r,info:{mimetype:"image/png",size:t.length}};return await this.client.sendEvent(e,"m.room.message",n)}async sendFile(e,t,s,r){let n=this.guessMimeType(s),o=await this.client.uploadContent(t,n,s),i={msgtype:"m.file",body:r??s,filename:s,url:o,info:{mimetype:n,size:t.length}};return await this.client.sendEvent(e,"m.room.message",i)}async normalizeEvent(e,t,s){let r={id:t.event_id,platform:"matrix",chatId:e,chatType:"group",userId:t.sender,userName:t.sender.split(":")[0].slice(1),timestamp:new Date(t.origin_server_ts),replyToMessageId:t.content["m.relates_to"]?.["m.in_reply_to"]?.event_id};switch(s){case"m.text":return{...r,text:t.content.body};case"m.image":{let n=await this.downloadAttachment(t.content,"image");return{...r,text:t.content.body??"[Photo]",attachments:n?[n]:void 0}}case"m.audio":{let n=await this.downloadAttachment(t.content,"audio");return{...r,text:t.content.body??"[Voice message]",attachments:n?[n]:void 0}}case"m.video":{let n=await this.downloadAttachment(t.content,"video");return{...r,text:t.content.body??"[Video]",attachments:n?[n]:void 0}}case"m.file":{let n=await this.downloadAttachment(t.content,"document");return{...r,text:t.content.body??"[Document]",attachments:n?[n]:void 0}}default:return t.content.body?{...r,text:t.content.body}:void 0}}async downloadAttachment(e,t){let s=e.url;if(!s||!s.startsWith("mxc://"))return;let r=e.info??{},n=r.mimetype,o=r.size,i=e.filename??e.body??"file";try{let a=s.slice(6),l=`${this.homeserverUrl}/_matrix/media/v3/download/${a}`,u=await fetch(l,{headers:{Authorization:`Bearer ${this.accessToken}`}});if(!u.ok)return;let h=await u.arrayBuffer(),m=Buffer.from(h);return{type:t,mimeType:n,fileName:i,size:o??m.length,data:m}}catch(a){console.error("[matrix] Failed to download attachment",s,a);return}}guessMimeType(e){let t=e.split(".").pop()?.toLowerCase();return{pdf:"application/pdf",txt:"text/plain",json:"application/json",csv:"text/csv",png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",mp3:"audio/mpeg",ogg:"audio/ogg",mp4:"video/mp4",zip:"application/zip",doc:"application/msword",docx:"application/vnd.openxmlformats-officedocument.wordprocessingml.document",xlsx:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}[t??""]??"application/octet-stream"}}});var ms,ro=f(()=>{"use strict";ie();ms=class extends X{static{d(this,"WhatsAppAdapter")}platform="whatsapp";socket;downloadMedia;dataPath;reconnectAttempts=0;reconnectTimer;constructor(e){super(),this.dataPath=e}async connect(){this.status="connecting";let e=await import("@whiskeysockets/baileys"),t=e.default??e,{makeWASocket:s,useMultiFileAuthState:r,DisconnectReason:n,downloadMediaMessage:o}=t;this.downloadMedia=o;let{state:i,saveCreds:a}=await r(this.dataPath);this.socket=s({auth:i,printQRInTerminal:!0}),this.socket.ev.on("creds.update",a),this.socket.ev.on("connection.update",l=>{if(l.connection==="open"&&(this.status="connected",this.reconnectAttempts=0,this.emit("connected")),l.connection==="close"){let h=l.lastDisconnect?.error?.output?.statusCode!==n.loggedOut;if(this.status="disconnected",this.emit("disconnected"),h){let m=Math.min(1e3*Math.pow(2,this.reconnectAttempts),6e4);this.reconnectAttempts++,this.reconnectTimer=setTimeout(()=>this.connect(),m)}}}),this.socket.ev.on("messages.upsert",({messages:l,type:u})=>{if(u==="notify")for(let h of l)h.message&&(h.key.fromMe||this.processMessage(h).catch(m=>{this.emit("error",m instanceof Error?m:new Error(String(m)))}))})}async disconnect(){this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=void 0),this.reconnectAttempts=0,this.socket?.end(void 0),this.socket=void 0,this.status="disconnected",this.emit("disconnected")}async sendMessage(e,t,s){return(await this.socket.sendMessage(e,{text:t},s?.replyToMessageId?{quoted:{key:{remoteJid:e,id:s.replyToMessageId},message:{}}}:void 0))?.key?.id??""}async editMessage(e,t,s,r){await this.socket.sendMessage(e,{text:s,edit:{remoteJid:e,id:t,fromMe:!0}})}async deleteMessage(e,t){await this.socket.sendMessage(e,{delete:{remoteJid:e,id:t,fromMe:!0}})}async sendPhoto(e,t,s){return(await this.socket.sendMessage(e,{image:t,caption:s}))?.key?.id}async sendFile(e,t,s,r){return(await this.socket.sendMessage(e,{document:t,fileName:s,caption:r,mimetype:this.guessMimeType(s)}))?.key?.id}async processMessage(e){let t=e.message,s=t.conversation??t.extendedTextMessage?.text??t.imageMessage?.caption??t.videoMessage?.caption??t.documentMessage?.caption??"",r=[],n=s;if(t.imageMessage){let i=await this.downloadMediaSafe(e);i&&r.push({type:"image",mimeType:t.imageMessage.mimetype??"image/jpeg",size:t.imageMessage.fileLength??i.length,data:i}),n||(n="[Photo]")}else if(t.audioMessage){let i=await this.downloadMediaSafe(e);i&&r.push({type:"audio",mimeType:t.audioMessage.mimetype??"audio/ogg",size:t.audioMessage.fileLength??i.length,data:i}),n||(n="[Voice message]")}else if(t.videoMessage){let i=await this.downloadMediaSafe(e);i&&r.push({type:"video",mimeType:t.videoMessage.mimetype??"video/mp4",size:t.videoMessage.fileLength??i.length,data:i}),n||(n="[Video]")}else if(t.documentMessage){let i=await this.downloadMediaSafe(e);i&&r.push({type:"document",mimeType:t.documentMessage.mimetype??"application/octet-stream",fileName:t.documentMessage.fileName??"document",size:t.documentMessage.fileLength??i.length,data:i}),n||(n="[Document]")}else if(t.stickerMessage&&!s)return;if(!n&&r.length===0)return;let o={id:e.key.id??"",platform:"whatsapp",chatId:e.key.remoteJid??"",chatType:e.key.remoteJid?.endsWith("@g.us")?"group":"dm",userId:e.key.participant??e.key.remoteJid??"",userName:e.pushName??e.key.participant??e.key.remoteJid??"",text:n,timestamp:new Date(e.messageTimestamp*1e3),replyToMessageId:t.extendedTextMessage?.contextInfo?.stanzaId??void 0,attachments:r.length>0?r:void 0};this.emit("message",o)}async downloadMediaSafe(e){try{if(!this.downloadMedia)return;let t=await this.downloadMedia(e,"buffer",{});return Buffer.isBuffer(t)?t:Buffer.from(t)}catch(t){console.error("[whatsapp] Failed to download media",t);return}}guessMimeType(e){let t=e.split(".").pop()?.toLowerCase();return{pdf:"application/pdf",txt:"text/plain",json:"application/json",csv:"text/csv",png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",mp3:"audio/mpeg",ogg:"audio/ogg",mp4:"video/mp4",zip:"application/zip",doc:"application/msword",docx:"application/vnd.openxmlformats-officedocument.wordprocessingml.document",xlsx:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}[t??""]??"application/octet-stream"}}});var ps,no=f(()=>{"use strict";ie();ps=class extends X{static{d(this,"SignalAdapter")}apiUrl;phoneNumber;platform="signal";pollingInterval;constructor(e,t){super(),this.apiUrl=e,this.phoneNumber=t}async connect(){this.status="connecting";try{let e=await fetch(`${this.apiUrl}/v1/about`);if(!e.ok)throw new Error(`Signal API not reachable: ${e.status}`);this.pollingInterval=setInterval(()=>{this.pollMessages().catch(t=>{this.emit("error",t instanceof Error?t:new Error(String(t)))})},2e3),this.status="connected",this.emit("connected")}catch(e){this.status="error",this.emit("error",e instanceof Error?e:new Error(String(e)))}}async disconnect(){this.pollingInterval&&(clearInterval(this.pollingInterval),this.pollingInterval=void 0),this.status="disconnected",this.emit("disconnected")}async sendMessage(e,t,s){let r=e.startsWith("group."),n={message:t,number:this.phoneNumber};r?n.recipients=[e.replace("group.","")]:n.recipients=[e];let o=await fetch(`${this.apiUrl}/v2/send`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)});if(!o.ok)throw new Error(`Signal send failed: ${o.status} ${await o.text()}`);let i=await o.json();return String(i.timestamp??Date.now())}async editMessage(e,t,s,r){throw new Error("Signal does not support message editing")}async deleteMessage(e,t){let s={number:this.phoneNumber,recipients:[e],timestamp:Number(t)},r=await fetch(`${this.apiUrl}/v1/deleteMessage`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s)});if(!r.ok)throw new Error(`Signal delete failed: ${r.status} ${await r.text()}`)}async pollMessages(){let e=await fetch(`${this.apiUrl}/v1/receive/${this.phoneNumber}`);if(!e.ok)return;let t=await e.json();for(let s of t){let r=s.envelope?.dataMessage;if(!r||!r.message&&(!r.attachments||r.attachments.length===0))continue;let n=s.envelope,o=r.groupInfo?.groupId?`group.${r.groupInfo.groupId}`:n.sourceNumber??n.source??"",i=[];if(r.attachments)for(let u of r.attachments){let h=await this.downloadAttachment(u);h&&i.push(h)}let a=r.message||this.inferTextFromAttachments(i)||"";if(!a&&i.length===0)continue;let l={id:String(r.timestamp??Date.now()),platform:"signal",chatId:o,chatType:r.groupInfo?"group":"dm",userId:n.sourceNumber??n.source??"",userName:n.sourceName??n.sourceNumber??n.source??"",displayName:n.sourceName,text:a,timestamp:new Date(r.timestamp??Date.now()),attachments:i.length>0?i:void 0};this.emit("message",l)}}async downloadAttachment(e){if(e.id)try{let t=await fetch(`${this.apiUrl}/v1/attachments/${e.id}`);if(!t.ok)return;let s=await t.arrayBuffer(),r=Buffer.from(s);return{type:this.classifyContentType(e.contentType),mimeType:e.contentType??void 0,fileName:e.filename??void 0,size:e.size??r.length,data:r}}catch(t){console.error("[signal] Failed to download attachment",e.id,t);return}}classifyContentType(e){return e?e.startsWith("image/")?"image":e.startsWith("audio/")?"audio":e.startsWith("video/")?"video":"document":"other"}inferTextFromAttachments(e){if(e.length===0)return"";let t=e.map(s=>s.type);return t.includes("image")?"[Photo]":t.includes("audio")?"[Voice message]":t.includes("video")?"[Video]":t.includes("document")?"[Document]":"[File]"}}});import gr from"node:readline";var hs,oo=f(()=>{"use strict";ie();hs=class extends X{static{d(this,"CLIAdapter")}platform="cli";rl;messageCounter=0;async connect(){this.status="connecting",this.rl=gr.createInterface({input:process.stdin,output:process.stdout,prompt:"You: "}),console.log(`
|
|
477
484
|
Alfred Chat \u2014 type your message and press Enter. Use /quit or /exit to leave.
|
|
478
485
|
`),this.rl.on("line",e=>{let t=e.trim();if(!t){this.prompt();return}if(t==="/quit"||t==="/exit"){console.log(`
|
|
479
486
|
Goodbye!
|
|
480
487
|
`),this.emit("disconnected");return}this.messageCounter++;let s={id:`cli-${this.messageCounter}`,platform:"cli",chatId:"cli-chat",chatType:"dm",userId:"cli-user",userName:"cli-user",displayName:"You",text:t,timestamp:new Date};this.emit("message",s)}),this.rl.on("close",()=>{this.emit("disconnected")}),this.status="connected",this.emit("connected"),this.prompt()}async disconnect(){this.rl?.close(),this.rl=void 0,this.status="disconnected"}async sendMessage(e,t,s){let r=`cli-resp-${++this.messageCounter}`;return process.stdout.write(`
|
|
481
488
|
Alfred: ${t}
|
|
482
|
-
`),this.prompt(),r}async editMessage(e,t,s,r){gr.clearLine(process.stdout,0),gr.cursorTo(process.stdout,0),process.stdout.write(`Alfred: ${s}`)}async deleteMessage(e,t){}prompt(){this.rl?.prompt()}}});var be={};V(be,{CLIAdapter:()=>hs,DiscordAdapter:()=>ds,MatrixAdapter:()=>us,MessagingAdapter:()=>z,SignalAdapter:()=>ps,TelegramAdapter:()=>cs,WhatsAppAdapter:()=>ms});var _e=f(()=>{"use strict";ie();eo();to();so();ro();no();oo()});import fs from"node:fs";import gs from"node:path";import Qi from"js-yaml";var Se,io=f(()=>{"use strict";Ls();Ds();Hs();ss();Lt();tr();sr();rr();nr();or();ir();ar();cr();lr();pr();hr();Se=class{static{d(this,"Alfred")}config;logger;database;pipeline;reminderScheduler;backgroundTaskRunner;proactiveScheduler;adapters=new Map;formatter=new Ct;mcpManager;calendarSkill;constructor(e){this.config=e,this.logger=ot("alfred",e.logger.level)}async initialize(){this.logger.info("Initializing Alfred..."),this.database=new me(this.config.storage.path);let e=this.database.getDb(),t=new it(e),s=new at(e),r=new pe(e),n=new ct(e),o=new lt(e),i=new dt(e),a=new ut(e),l=new mt(e),u=new pt(e),h=new ht(e);this.logger.info("Storage initialized");let m=new St,p=this.loadSecurityRules();m.loadRules(p);let E=new kt(m,r,this.logger.child({component:"security"}));this.logger.info({ruleCount:p.length},"Security engine initialized");let w=Ws(this.config.llm);await w.initialize(),this.logger.info({provider:this.config.llm.default.provider,model:this.config.llm.default.model},"LLM provider initialized");let T=new Ut(w,a,this.logger.child({component:"embeddings"})),k=this.config.activeLearning?.enabled!==!1,b,x;k&&(b=new Wt({llm:w,memoryRepo:n,logger:this.logger.child({component:"active-learning"}),embeddingService:T,minMessageLength:this.config.activeLearning?.minMessageLength,minConfidence:this.config.activeLearning?.minConfidence,maxExtractionsPerMinute:this.config.activeLearning?.maxExtractionsPerMinute}),x=new Ht(n,this.logger.child({component:"memory-retriever"}),T),this.logger.info("Active learning & memory retriever initialized"));let L=new Ae(this.logger.child({component:"sandbox"})),v=new Re;v.register(new Le),v.register(new Me),v.register(new Ne(this.config.search?{provider:this.config.search.provider,apiKey:this.config.search.apiKey,baseUrl:this.config.search.baseUrl}:void 0)),v.register(new De(o)),v.register(new Oe(i)),v.register(new Ce),v.register(new Ue),v.register(new Pe(n,T)),v.register(new Fe(w,v,L,E)),v.register(new je(this.config.email?{imap:this.config.email.imap,smtp:this.config.email.smtp,auth:this.config.email.auth}:void 0)),v.register(new Be),v.register(new We),v.register(new ze),v.register(new Xe),v.register(new qe),v.register(new Ke(s)),v.register(new Ve(s,l,this.adapters)),v.register(new Ge(u)),v.register(new Ye(h));let M=new ft(e),R=new Pt(M,T,this.logger.child({component:"documents"}));v.register(new Ze(M,R,T));let C;if(this.config.calendar)try{let N=await $t(this.config.calendar);C=new ye(N),v.register(C),this.logger.info({provider:this.config.calendar.provider},"Calendar initialized")}catch(N){this.logger.warn({err:N},"Calendar initialization failed, continuing without calendar")}if(this.calendarSkill=C,this.config.mcp?.servers?.length){let{MCPManager:N}=await Promise.resolve().then(()=>(Lt(),as));this.mcpManager=new N(this.logger.child({component:"mcp"})),await this.mcpManager.initialize(this.config.mcp);for(let Q of this.mcpManager.getSkills())v.register(Q);this.logger.info({mcpSkills:this.mcpManager.getSkills().length},"MCP skills registered")}if(this.config.codeSandbox?.enabled){let{CodeExecutionSkill:N}=await Promise.resolve().then(()=>(Lt(),as));v.register(new N({allowedLanguages:this.config.codeSandbox.allowedLanguages,maxTimeoutMs:this.config.codeSandbox.maxTimeoutMs})),this.logger.info("Code sandbox enabled")}this.logger.info({skills:v.getAll().map(N=>N.metadata.name)},"Skills registered");let F;this.config.speech?.apiKey&&(F=new Ot(this.config.speech,this.logger.child({component:"speech"})),this.logger.info({provider:this.config.speech.provider},"Speech-to-text initialized"));let U=new Mt(t),le=gs.resolve(gs.dirname(this.config.storage.path),"inbox");this.pipeline=new Nt({llm:w,conversationManager:U,users:s,logger:this.logger.child({component:"pipeline"}),skillRegistry:v,skillSandbox:L,securityManager:E,memoryRepo:n,speechTranscriber:F,inboxPath:le,embeddingService:T,activeLearning:b,memoryRetriever:x}),this.reminderScheduler=new Dt(o,async(N,Q,H)=>{let tt=this.adapters.get(N);tt?await tt.sendMessage(Q,H):this.logger.warn({platform:N,chatId:Q},"No adapter for reminder platform")},this.logger.child({component:"reminders"})),this.backgroundTaskRunner=new Ft(v,L,u,this.adapters,this.logger.child({component:"background-tasks"})),this.proactiveScheduler=new jt(h,v,L,w,this.adapters,this.logger.child({component:"proactive-scheduler"})),await this.initializeAdapters(),this.logger.info("Alfred initialized")}async initializeAdapters(){let{config:e}=this;if(e.telegram.enabled&&e.telegram.token){let{TelegramAdapter:t}=await Promise.resolve().then(()=>(_e(),be));this.adapters.set("telegram",new t(e.telegram.token)),this.logger.info("Telegram adapter registered")}if(e.discord?.enabled&&e.discord.token){let{DiscordAdapter:t}=await Promise.resolve().then(()=>(_e(),be));this.adapters.set("discord",new t(e.discord.token)),this.logger.info("Discord adapter registered")}if(e.whatsapp?.enabled){let{WhatsAppAdapter:t}=await Promise.resolve().then(()=>(_e(),be));this.adapters.set("whatsapp",new t(e.whatsapp.dataPath)),this.logger.info("WhatsApp adapter registered")}if(e.matrix?.enabled&&e.matrix.accessToken){let{MatrixAdapter:t}=await Promise.resolve().then(()=>(_e(),be));this.adapters.set("matrix",new t(e.matrix.homeserverUrl,e.matrix.accessToken,e.matrix.userId)),this.logger.info("Matrix adapter registered")}if(e.signal?.enabled&&e.signal.phoneNumber){let{SignalAdapter:t}=await Promise.resolve().then(()=>(_e(),be));this.adapters.set("signal",new t(e.signal.apiUrl,e.signal.phoneNumber)),this.logger.info("Signal adapter registered")}}async start(){this.logger.info("Starting Alfred...");for(let[e,t]of this.adapters)this.setupAdapterHandlers(e,t),await t.connect(),this.logger.info({platform:e},"Adapter connected");this.reminderScheduler?.start(),this.backgroundTaskRunner?.start(),this.proactiveScheduler?.start(),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(()=>(_e(),be)),t=new e;this.adapters.set("cli",t),this.setupAdapterHandlers("cli",t),t.on("disconnected",()=>{this.stop().then(()=>process.exit(0))}),await this.start()}async stop(){this.logger.info("Stopping Alfred..."),this.reminderScheduler?.stop(),this.backgroundTaskRunner?.stop(),this.proactiveScheduler?.stop(),this.mcpManager&&await this.mcpManager.shutdown();for(let[e,t]of this.adapters)try{await t.disconnect(),this.logger.info({platform:e},"Adapter disconnected")}catch(s){this.logger.error({platform:e,err:s},"Failed to disconnect adapter")}this.database.close(),this.logger.info("Alfred stopped")}setupAdapterHandlers(e,t){t.on("message",async s=>{try{let r,n="",o=d(async u=>{if(u!==n){n=u;try{r?await t.editMessage(s.chatId,r,u):r=await t.sendMessage(s.chatId,u)}catch(h){this.logger.debug({err:h,chatId:s.chatId},"Status message edit failed")}}},"onProgress"),i=await this.pipeline.process(s,o),a=this.formatter.format(i,s.platform),l=a.parseMode!=="text"?{parseMode:a.parseMode}:void 0;if(r)try{await t.editMessage(s.chatId,r,a.text,l)}catch(u){this.logger.debug({err:u,chatId:s.chatId},"Final response edit failed, sending as new message"),await t.sendMessage(s.chatId,a.text,l)}else await t.sendMessage(s.chatId,a.text,l)}catch(r){this.logger.error({platform:e,err:r,chatId:s.chatId},"Failed to handle message");try{await t.sendMessage(s.chatId,"Sorry, I encountered an error processing your message. Please try again.")}catch(n){this.logger.error({err:n},"Failed to send error message")}}}),t.on("error",s=>{this.logger.error({platform:e,err:s},"Adapter error")}),t.on("connected",()=>{this.logger.info({platform:e},"Adapter connected")}),t.on("disconnected",()=>{this.logger.warn({platform:e},"Adapter disconnected")})}loadSecurityRules(){let e=gs.resolve(this.config.security.rulesPath),t=[];if(!fs.existsSync(e))return this.logger.warn({rulesPath:e},"Security rules directory not found, using default deny"),t;if(!fs.statSync(e).isDirectory())return this.logger.warn({rulesPath:e},"Security rules path is not a directory"),t;let r=fs.readdirSync(e).filter(n=>n.endsWith(".yml")||n.endsWith(".yaml"));for(let n of r)try{let o=gs.join(e,n),i=fs.readFileSync(o,"utf-8"),a=Qi.load(i);a?.rules&&Array.isArray(a.rules)&&(t.push(...a.rules),this.logger.info({file:n,count:a.rules.length},"Loaded security rules"))}catch(o){this.logger.error({err:o,file:n},"Failed to load security rules file")}return t}}});var ao=f(()=>{"use strict"});var yr=f(()=>{"use strict";io();sr();tr();rr();nr();or();ir();cr();lr();ar();pr();hr();mr();ao();ur()});var co={};V(co,{startCommand:()=>ea});async function ea(){let c=new X,e;try{e=c.loadConfig()}catch(o){console.error("Failed to load configuration:",o.message),process.exit(1)}let t=ot("cli",e.logger.level);t.info({name:e.name},"Configuration loaded");let s=new Se(e),r=!1,n=d(async o=>{if(!r){r=!0,t.info({signal:o},"Received shutdown signal");try{await s.stop(),t.info("Graceful shutdown complete"),process.exit(0)}catch(i){t.error({error:i},"Error during shutdown"),process.exit(1)}}},"shutdown");process.on("SIGINT",()=>n("SIGINT")),process.on("SIGTERM",()=>n("SIGTERM")),process.on("uncaughtException",o=>{t.fatal({error:o},"Uncaught exception"),n("uncaughtException")}),process.on("unhandledRejection",o=>{t.fatal({reason:o},"Unhandled rejection"),n("unhandledRejection")});try{await s.initialize(),await s.start(),t.info("Alfred is ready")}catch(o){t.fatal({error:o},"Failed to start Alfred"),process.exit(1)}}var lo=f(()=>{"use strict";ue();Ls();yr();d(ea,"startCommand")});var uo={};V(uo,{chatCommand:()=>ta});async function ta(c){let e=new X,t;try{t=e.loadConfig()}catch(r){console.error("Failed to load configuration:",r.message),process.exit(1)}if(t.logger.level="warn",c.model&&(t.llm.default.model=c.model),c.tier){let r=t.llm[c.tier];r?t.llm.default=r:(console.error(`Unknown tier: ${c.tier}. Available tiers: default, strong, fast, embeddings, local`),process.exit(1))}let s=new Se(t);try{await s.initialize(),await s.startWithCLI()}catch(r){console.error("Failed to start chat:",r.message),process.exit(1)}}var mo=f(()=>{"use strict";ue();yr();d(ta,"chatCommand")});var ho={};V(ho,{setupCommand:()=>la});import{createInterface as sa}from"node:readline/promises";import{stdin as ra,stdout as na}from"node:process";import q from"node:fs";import se from"node:path";import Er from"js-yaml";function P(c){return`${ys}${c}${A}`}function aa(c){return`${Z}${c}${A}`}function ke(c){return`${ws}${c}${A}`}function po(c){return`${oa}${c}${A}`}function I(c){return`${et}${c}${A}`}function S(c){return`${ce}${c}${A}`}function ve(c){return c.length<=4?"****":"*".repeat(c.length-4)+c.slice(-4)}function ca(c){let e={},t={},s=!1,r=!1,n=30,o=se.join(c,"config","default.yml");if(q.existsSync(o))try{let l=Er.load(q.readFileSync(o,"utf-8"));l&&typeof l=="object"&&Object.assign(e,l)}catch{}let i=se.join(c,".env");if(q.existsSync(i))try{let l=q.readFileSync(i,"utf-8").split(`
|
|
489
|
+
`),this.prompt(),r}async editMessage(e,t,s,r){gr.clearLine(process.stdout,0),gr.cursorTo(process.stdout,0),process.stdout.write(`Alfred: ${s}`)}async deleteMessage(e,t){}prompt(){this.rl?.prompt()}}});var be={};V(be,{CLIAdapter:()=>hs,DiscordAdapter:()=>ds,MatrixAdapter:()=>us,MessagingAdapter:()=>X,SignalAdapter:()=>ps,TelegramAdapter:()=>cs,WhatsAppAdapter:()=>ms});var _e=f(()=>{"use strict";ie();eo();to();so();ro();no();oo()});import fs from"node:fs";import gs from"node:path";import Qi from"js-yaml";var Se,io=f(()=>{"use strict";Ls();Ds();Hs();ss();Lt();tr();sr();rr();nr();or();ir();ar();cr();lr();pr();hr();Se=class{static{d(this,"Alfred")}config;logger;database;pipeline;reminderScheduler;backgroundTaskRunner;proactiveScheduler;adapters=new Map;formatter=new Ct;mcpManager;calendarSkill;constructor(e){this.config=e,this.logger=ot("alfred",e.logger.level)}async initialize(){this.logger.info("Initializing Alfred..."),this.database=new me(this.config.storage.path);let e=this.database.getDb(),t=new it(e),s=new at(e),r=new pe(e),n=new ct(e),o=new lt(e),i=new dt(e),a=new ut(e),l=new mt(e),u=new pt(e),h=new ht(e);this.logger.info("Storage initialized");let m=new St,p=this.loadSecurityRules();m.loadRules(p);let E=new kt(m,r,this.logger.child({component:"security"}));this.logger.info({ruleCount:p.length},"Security engine initialized");let w=Ws(this.config.llm);await w.initialize(),this.logger.info({provider:this.config.llm.default.provider,model:this.config.llm.default.model},"LLM provider initialized");let T=new Ut(w,a,this.logger.child({component:"embeddings"})),k=this.config.activeLearning?.enabled!==!1,b,x;k&&(b=new Wt({llm:w,memoryRepo:n,logger:this.logger.child({component:"active-learning"}),embeddingService:T,minMessageLength:this.config.activeLearning?.minMessageLength,minConfidence:this.config.activeLearning?.minConfidence,maxExtractionsPerMinute:this.config.activeLearning?.maxExtractionsPerMinute}),x=new Ht(n,this.logger.child({component:"memory-retriever"}),T),this.logger.info("Active learning & memory retriever initialized"));let L=new Ae(this.logger.child({component:"sandbox"})),v=new Re;v.register(new Le),v.register(new Me),v.register(new Ne(this.config.search?{provider:this.config.search.provider,apiKey:this.config.search.apiKey,baseUrl:this.config.search.baseUrl}:void 0)),v.register(new De(o)),v.register(new Oe(i)),v.register(new Ce),v.register(new Ue),v.register(new Pe(n,T)),v.register(new Fe(w,v,L,E)),v.register(new je(this.config.email?{imap:this.config.email.imap,smtp:this.config.email.smtp,auth:this.config.email.auth}:void 0)),v.register(new Be),v.register(new We),v.register(new Xe),v.register(new ze),v.register(new qe),v.register(new Ke(s)),v.register(new Ve(s,l,this.adapters)),v.register(new Ge(u)),v.register(new Ye(h));let M=new ft(e),R=new Pt(M,T,this.logger.child({component:"documents"}));v.register(new Ze(M,R,T));let C;if(this.config.calendar)try{let N=await $t(this.config.calendar);C=new ye(N),v.register(C),this.logger.info({provider:this.config.calendar.provider},"Calendar initialized")}catch(N){this.logger.warn({err:N},"Calendar initialization failed, continuing without calendar")}if(this.calendarSkill=C,this.config.mcp?.servers?.length){let{MCPManager:N}=await Promise.resolve().then(()=>(Lt(),as));this.mcpManager=new N(this.logger.child({component:"mcp"})),await this.mcpManager.initialize(this.config.mcp);for(let Q of this.mcpManager.getSkills())v.register(Q);this.logger.info({mcpSkills:this.mcpManager.getSkills().length},"MCP skills registered")}if(this.config.codeSandbox?.enabled){let{CodeExecutionSkill:N}=await Promise.resolve().then(()=>(Lt(),as));v.register(new N({allowedLanguages:this.config.codeSandbox.allowedLanguages,maxTimeoutMs:this.config.codeSandbox.maxTimeoutMs})),this.logger.info("Code sandbox enabled")}this.logger.info({skills:v.getAll().map(N=>N.metadata.name)},"Skills registered");let F;this.config.speech?.apiKey&&(F=new Ot(this.config.speech,this.logger.child({component:"speech"})),this.logger.info({provider:this.config.speech.provider},"Speech-to-text initialized"));let U=new Mt(t),le=gs.resolve(gs.dirname(this.config.storage.path),"inbox");this.pipeline=new Nt({llm:w,conversationManager:U,users:s,logger:this.logger.child({component:"pipeline"}),skillRegistry:v,skillSandbox:L,securityManager:E,memoryRepo:n,speechTranscriber:F,inboxPath:le,embeddingService:T,activeLearning:b,memoryRetriever:x}),this.reminderScheduler=new Dt(o,async(N,Q,H)=>{let tt=this.adapters.get(N);tt?await tt.sendMessage(Q,H):this.logger.warn({platform:N,chatId:Q},"No adapter for reminder platform")},this.logger.child({component:"reminders"})),this.backgroundTaskRunner=new Ft(v,L,u,this.adapters,this.logger.child({component:"background-tasks"})),this.proactiveScheduler=new jt(h,v,L,w,this.adapters,this.logger.child({component:"proactive-scheduler"})),await this.initializeAdapters(),this.logger.info("Alfred initialized")}async initializeAdapters(){let{config:e}=this;if(e.telegram.enabled&&e.telegram.token){let{TelegramAdapter:t}=await Promise.resolve().then(()=>(_e(),be));this.adapters.set("telegram",new t(e.telegram.token)),this.logger.info("Telegram adapter registered")}if(e.discord?.enabled&&e.discord.token){let{DiscordAdapter:t}=await Promise.resolve().then(()=>(_e(),be));this.adapters.set("discord",new t(e.discord.token)),this.logger.info("Discord adapter registered")}if(e.whatsapp?.enabled){let{WhatsAppAdapter:t}=await Promise.resolve().then(()=>(_e(),be));this.adapters.set("whatsapp",new t(e.whatsapp.dataPath)),this.logger.info("WhatsApp adapter registered")}if(e.matrix?.enabled&&e.matrix.accessToken){let{MatrixAdapter:t}=await Promise.resolve().then(()=>(_e(),be));this.adapters.set("matrix",new t(e.matrix.homeserverUrl,e.matrix.accessToken,e.matrix.userId)),this.logger.info("Matrix adapter registered")}if(e.signal?.enabled&&e.signal.phoneNumber){let{SignalAdapter:t}=await Promise.resolve().then(()=>(_e(),be));this.adapters.set("signal",new t(e.signal.apiUrl,e.signal.phoneNumber)),this.logger.info("Signal adapter registered")}}async start(){this.logger.info("Starting Alfred...");for(let[e,t]of this.adapters)this.setupAdapterHandlers(e,t),await t.connect(),this.logger.info({platform:e},"Adapter connected");this.reminderScheduler?.start(),this.backgroundTaskRunner?.start(),this.proactiveScheduler?.start(),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(()=>(_e(),be)),t=new e;this.adapters.set("cli",t),this.setupAdapterHandlers("cli",t),t.on("disconnected",()=>{this.stop().then(()=>process.exit(0))}),await this.start()}async stop(){this.logger.info("Stopping Alfred..."),this.reminderScheduler?.stop(),this.backgroundTaskRunner?.stop(),this.proactiveScheduler?.stop(),this.mcpManager&&await this.mcpManager.shutdown();for(let[e,t]of this.adapters)try{await t.disconnect(),this.logger.info({platform:e},"Adapter disconnected")}catch(s){this.logger.error({platform:e,err:s},"Failed to disconnect adapter")}this.database.close(),this.logger.info("Alfred stopped")}setupAdapterHandlers(e,t){t.on("message",async s=>{try{let r,n="",o=d(async u=>{if(u!==n){n=u;try{r?await t.editMessage(s.chatId,r,u):r=await t.sendMessage(s.chatId,u)}catch(h){this.logger.debug({err:h,chatId:s.chatId},"Status message edit failed")}}},"onProgress"),i=await this.pipeline.process(s,o),a=this.formatter.format(i,s.platform),l=a.parseMode!=="text"?{parseMode:a.parseMode}:void 0;if(r)try{await t.editMessage(s.chatId,r,a.text,l)}catch(u){this.logger.debug({err:u,chatId:s.chatId},"Final response edit failed, sending as new message"),await t.sendMessage(s.chatId,a.text,l)}else await t.sendMessage(s.chatId,a.text,l)}catch(r){this.logger.error({platform:e,err:r,chatId:s.chatId},"Failed to handle message");try{await t.sendMessage(s.chatId,"Sorry, I encountered an error processing your message. Please try again.")}catch(n){this.logger.error({err:n},"Failed to send error message")}}}),t.on("error",s=>{this.logger.error({platform:e,err:s},"Adapter error")}),t.on("connected",()=>{this.logger.info({platform:e},"Adapter connected")}),t.on("disconnected",()=>{this.logger.warn({platform:e},"Adapter disconnected")})}loadSecurityRules(){let e=gs.resolve(this.config.security.rulesPath),t=[];if(!fs.existsSync(e))return this.logger.warn({rulesPath:e},"Security rules directory not found, using default deny"),t;if(!fs.statSync(e).isDirectory())return this.logger.warn({rulesPath:e},"Security rules path is not a directory"),t;let r=fs.readdirSync(e).filter(n=>n.endsWith(".yml")||n.endsWith(".yaml"));for(let n of r)try{let o=gs.join(e,n),i=fs.readFileSync(o,"utf-8"),a=Qi.load(i);a?.rules&&Array.isArray(a.rules)&&(t.push(...a.rules),this.logger.info({file:n,count:a.rules.length},"Loaded security rules"))}catch(o){this.logger.error({err:o,file:n},"Failed to load security rules file")}return t}}});var ao=f(()=>{"use strict"});var yr=f(()=>{"use strict";io();sr();tr();rr();nr();or();ir();cr();lr();ar();pr();hr();mr();ao();ur()});var co={};V(co,{startCommand:()=>ea});async function ea(){let c=new z,e;try{e=c.loadConfig()}catch(o){console.error("Failed to load configuration:",o.message),process.exit(1)}let t=ot("cli",e.logger.level);t.info({name:e.name},"Configuration loaded");let s=new Se(e),r=!1,n=d(async o=>{if(!r){r=!0,t.info({signal:o},"Received shutdown signal");try{await s.stop(),t.info("Graceful shutdown complete"),process.exit(0)}catch(i){t.error({error:i},"Error during shutdown"),process.exit(1)}}},"shutdown");process.on("SIGINT",()=>n("SIGINT")),process.on("SIGTERM",()=>n("SIGTERM")),process.on("uncaughtException",o=>{t.fatal({error:o},"Uncaught exception"),n("uncaughtException")}),process.on("unhandledRejection",o=>{t.fatal({reason:o},"Unhandled rejection"),n("unhandledRejection")});try{await s.initialize(),await s.start(),t.info("Alfred is ready")}catch(o){t.fatal({error:o},"Failed to start Alfred"),process.exit(1)}}var lo=f(()=>{"use strict";ue();Ls();yr();d(ea,"startCommand")});var uo={};V(uo,{chatCommand:()=>ta});async function ta(c){let e=new z,t;try{t=e.loadConfig()}catch(r){console.error("Failed to load configuration:",r.message),process.exit(1)}if(t.logger.level="warn",c.model&&(t.llm.default.model=c.model),c.tier){let r=t.llm[c.tier];r?t.llm.default=r:(console.error(`Unknown tier: ${c.tier}. Available tiers: default, strong, fast, embeddings, local`),process.exit(1))}let s=new Se(t);try{await s.initialize(),await s.startWithCLI()}catch(r){console.error("Failed to start chat:",r.message),process.exit(1)}}var mo=f(()=>{"use strict";ue();yr();d(ta,"chatCommand")});var ho={};V(ho,{setupCommand:()=>la});import{createInterface as sa}from"node:readline/promises";import{stdin as ra,stdout as na}from"node:process";import q from"node:fs";import se from"node:path";import Er from"js-yaml";function P(c){return`${ys}${c}${A}`}function aa(c){return`${Z}${c}${A}`}function ke(c){return`${ws}${c}${A}`}function po(c){return`${oa}${c}${A}`}function I(c){return`${et}${c}${A}`}function S(c){return`${ce}${c}${A}`}function ve(c){return c.length<=4?"****":"*".repeat(c.length-4)+c.slice(-4)}function ca(c){let e={},t={},s=!1,r=!1,n=30,o=se.join(c,"config","default.yml");if(q.existsSync(o))try{let l=Er.load(q.readFileSync(o,"utf-8"));l&&typeof l=="object"&&Object.assign(e,l)}catch{}let i=se.join(c,".env");if(q.existsSync(i))try{let l=q.readFileSync(i,"utf-8").split(`
|
|
483
490
|
`);for(let u of l){let h=u.trim();if(!h||h.startsWith("#"))continue;let m=h.indexOf("=");m>0&&(t[h.slice(0,m)]=h.slice(m+1))}}catch{}let a=se.join(c,"config","rules","default-rules.yml");if(q.existsSync(a))try{let l=Er.load(q.readFileSync(a,"utf-8"));if(l?.rules){s=l.rules.some(m=>m.id==="allow-owner-admin"&&m.effect==="allow"),l.rules.find(m=>m.id==="allow-write-for-dm"||m.id==="allow-write-all")?.id==="allow-write-all"&&(r=!0);let h=l.rules.find(m=>m.id==="rate-limit-write");h?.rateLimit?.maxInvocations&&(n=h.rateLimit.maxInvocations)}}catch{}return{config:e,env:t,shellEnabled:s,writeInGroups:r,rateLimit:n}}async function la(){let c=sa({input:ra,output:na}),e=process.cwd(),t=ca(e),s=Object.keys(t.config).length>0;try{da(),console.log(s?`${ws}Existing configuration found \u2014 press Enter to keep current values.${A}
|
|
484
491
|
${ce}Only change what you need to update.${A}
|
|
485
492
|
`:`${ws}Welcome to the Alfred setup wizard!${A}
|
|
486
493
|
${ce}This will walk you through configuring your AI assistant.${A}
|
|
487
494
|
${ce}Press Enter to accept defaults shown in [brackets].${A}
|
|
488
|
-
`);let r=await B(c,"What should your bot be called?",t.config.name??"Alfred"),n=t.config.llm?.provider?
|
|
489
|
-
${I("Which LLM provider would you like to use?")}`);for(let y=0;y<
|
|
495
|
+
`);let r=await B(c,"What should your bot be called?",t.config.name??"Alfred"),n=t.config.llm?.provider?Xt.findIndex(y=>y.name===t.config.llm?.provider):-1,o=n>=0?n+1:1;console.log(`
|
|
496
|
+
${I("Which LLM provider would you like to use?")}`);for(let y=0;y<Xt.length;y++){let $=y===n?` ${S("(current)")}`:"";console.log(` ${ke(String(y+1)+")")} ${Xt[y].label}${$}`)}let i=await wr(c,"> ",1,Xt.length,o),a=Xt[i-1];console.log(` ${P(">")} Selected: ${I(a.label)}`);let l="",u=t.env[a.envKeyName]??"";a.needsApiKey&&(console.log(""),u?l=await B(c,`${a.name.charAt(0).toUpperCase()+a.name.slice(1)} API key`,u):l=await ae(c,`Enter your ${a.name.charAt(0).toUpperCase()+a.name.slice(1)} API key`),console.log(` ${P(">")} API key set: ${S(ve(l))}`));let h=a.baseUrl??"";if(["ollama","openwebui","openai","openrouter"].includes(a.name)){let $=(t.config.llm?.baseUrl??t.env.ALFRED_LLM_BASE_URL??"")||a.baseUrl||"";if($){let W={ollama:"Ollama URL (use a remote address if Ollama runs on another machine)",openwebui:"OpenWebUI URL",openai:"OpenAI-compatible API URL (leave default for official API)",openrouter:"OpenRouter API URL"};console.log(""),h=await B(c,W[a.name]??"API Base URL",$.replace(/\/+$/,"")),h=h.replace(/\/+$/,""),console.log(` ${P(">")} URL: ${S(h)}`)}}let p=t.config.llm?.model??a.defaultModel;console.log("");let E=await B(c,"Which model?",p),w=["brave","tavily","duckduckgo","searxng"],T=t.config.search?.provider??t.env.ALFRED_SEARCH_PROVIDER??"",k=w.indexOf(T),b=k>=0?k+1:0;console.log(`
|
|
490
497
|
${I("Web Search provider (for searching the internet):")}`);let x=["Brave Search \u2014 recommended, free tier (2,000/month)","Tavily \u2014 built for AI agents, free tier (1,000/month)","DuckDuckGo \u2014 free, no API key needed","SearXNG \u2014 self-hosted, no API key needed"],L=d(y=>k===y?` ${S("(current)")}`:"","mark");console.log(` ${ke("0)")} None (disable web search)${k===-1&&T===""?` ${S("(current)")}`:""}`);for(let y=0;y<x.length;y++)console.log(` ${ke(String(y+1)+")")} ${x[y]}${L(y)}`);let v=await wr(c,"> ",0,w.length,b),M,R="",C="";if(v>=1&&v<=w.length&&(M=w[v-1]),M==="brave"){let y=t.env.ALFRED_SEARCH_API_KEY??"";y?R=await B(c," Brave Search API key",y):(console.log(` ${S("Get your free API key at: https://brave.com/search/api/")}`),R=await ae(c," Brave Search API key")),console.log(` ${P(">")} Brave Search: ${S(ve(R))}`)}else if(M==="tavily"){let y=t.env.ALFRED_SEARCH_API_KEY??"";y?R=await B(c," Tavily API key",y):(console.log(` ${S("Get your free API key at: https://tavily.com/")}`),R=await ae(c," Tavily API key")),console.log(` ${P(">")} Tavily: ${S(ve(R))}`)}else if(M==="duckduckgo")console.log(` ${P(">")} DuckDuckGo: ${S("no API key needed")}`);else if(M==="searxng"){let y=t.config.search?.baseUrl??t.env.ALFRED_SEARCH_BASE_URL??"http://localhost:8080";C=await B(c," SearXNG URL",y),C=C.replace(/\/+$/,""),console.log(` ${P(">")} SearXNG: ${S(C)}`)}else console.log(` ${S("Web search disabled \u2014 you can configure it later.")}`);let F=[];for(let y=0;y<Qe.length;y++){let $=Qe[y];t.config[$.configKey]?.enabled&&F.push(y+1)}let U=F.length>0?F.join(","):"";console.log(`
|
|
491
498
|
${I("Which messaging platforms do you want to enable?")}`),console.log(`${S("(Enter comma-separated numbers, e.g. 1,3)")}`);for(let y=0;y<Qe.length;y++){let $=F.includes(y+1)?` ${S("(enabled)")}`:"";console.log(` ${ke(String(y+1)+")")} ${Qe[y].label}${$}`)}console.log(` ${ke("0)")} None (configure later)`);let le=(await c.question(`${Z}> ${A}${U?S(`[${U}] `):""}`)).trim(),N=[],Q=le||U;if(Q&&Q!=="0"){let y=Q.split(",").map($=>parseInt($.trim(),10));for(let $ of y)if($>=1&&$<=Qe.length){let W=Qe[$-1];N.includes(W)||N.push(W)}}N.length>0?console.log(` ${P(">")} Enabling: ${N.map(y=>I(y.label)).join(", ")}`):console.log(` ${S("No platforms selected \u2014 you can configure them later.")}`);let H={},tt={};for(let y of N){if(y.credentials.length===0){y.name==="whatsapp"&&console.log(`
|
|
492
499
|
${aa("i")} WhatsApp: a QR code will be displayed on first start.`);continue}console.log(`
|
|
@@ -578,7 +585,7 @@ ${ia}${et} _ _ _____ ____ _____ ____
|
|
|
578
585
|
/ ___ \\| |___| _| | _ <| |___| |_| |
|
|
579
586
|
/_/ \\_\\_____|_| |_| \\_\\_____|____/ ${A}
|
|
580
587
|
${ce} Personal AI Assistant \u2014 Setup Wizard${A}
|
|
581
|
-
`)}var A,et,ce,ys,Z,ws,oa,ia,
|
|
588
|
+
`)}var A,et,ce,ys,Z,ws,oa,ia,Xt,Qe,fo=f(()=>{"use strict";A="\x1B[0m",et="\x1B[1m",ce="\x1B[2m",ys="\x1B[32m",Z="\x1B[33m",ws="\x1B[36m",oa="\x1B[31m",ia="\x1B[35m";d(P,"green");d(aa,"yellow");d(ke,"cyan");d(po,"red");d(I,"bold");d(S,"dim");d(ve,"maskKey");Xt=[{name:"anthropic",label:"Anthropic (Claude) \u2014 recommended",defaultModel:"claude-sonnet-4-20250514",envKeyName:"ALFRED_ANTHROPIC_API_KEY",needsApiKey:!0},{name:"openai",label:"OpenAI (GPT)",defaultModel:"gpt-4o",envKeyName:"ALFRED_OPENAI_API_KEY",needsApiKey:!0},{name:"openrouter",label:"OpenRouter (multiple providers)",defaultModel:"anthropic/claude-sonnet-4-20250514",envKeyName:"ALFRED_OPENROUTER_API_KEY",needsApiKey:!0,baseUrl:"https://openrouter.ai/api/v1"},{name:"ollama",label:"Ollama (local, no API key needed)",defaultModel:"llama3.2",envKeyName:"",needsApiKey:!1,baseUrl:"http://localhost:11434"},{name:"openwebui",label:"OpenWebUI (local OpenAI-compatible UI)",defaultModel:"llama3.2",envKeyName:"ALFRED_OPENWEBUI_API_KEY",needsApiKey:!0,baseUrl:"http://localhost:3000/api/v1"}],Qe=[{name:"telegram",label:"Telegram",configKey:"telegram",credentials:[{envKey:"ALFRED_TELEGRAM_TOKEN",configField:"token",prompt:"Enter your Telegram Bot token (from @BotFather)",required:!0}]},{name:"discord",label:"Discord",configKey:"discord",credentials:[{envKey:"ALFRED_DISCORD_TOKEN",configField:"token",prompt:"Enter your Discord Bot token",required:!0}]},{name:"whatsapp",label:"WhatsApp",configKey:"whatsapp",credentials:[]},{name:"matrix",label:"Matrix",configKey:"matrix",credentials:[{envKey:"ALFRED_MATRIX_HOMESERVER_URL",configField:"homeserverUrl",prompt:"Enter your Matrix homeserver URL",defaultValue:"https://matrix.org",required:!0},{envKey:"ALFRED_MATRIX_ACCESS_TOKEN",configField:"accessToken",prompt:"Enter your Matrix access token",required:!0},{envKey:"ALFRED_MATRIX_USER_ID",configField:"userId",prompt:"Enter your Matrix user ID (e.g. @bot:matrix.org)",required:!0}]},{name:"signal",label:"Signal",configKey:"signal",credentials:[{envKey:"ALFRED_SIGNAL_API_URL",configField:"apiUrl",prompt:"Enter the Signal REST API URL",defaultValue:"http://localhost:8080",required:!0},{envKey:"ALFRED_SIGNAL_PHONE_NUMBER",configField:"phoneNumber",prompt:"Enter the Signal phone number (e.g. +15551234567)",required:!0}]}];d(ca,"loadExistingConfig");d(la,"setupCommand");d(B,"askWithDefault");d(ae,"askRequired");d(wr,"askNumber");d(da,"printBanner")});var yo={};V(yo,{configCommand:()=>ha});function ma(c){let e=c.toLowerCase();return ua.some(t=>e.includes(t))}function pa(c){return typeof c!="string"||c.length===0?"(empty)":c.length<=8?"***":c.slice(0,4)+"..."+c.slice(-4)}function go(c){let e={};for(let[t,s]of Object.entries(c))ma(t)?e[t]=pa(s):s!=null&&typeof s=="object"&&!Array.isArray(s)?e[t]=go(s):e[t]=s;return e}async function ha(){let c=new z,e;try{e=c.loadConfig()}catch(s){console.error("Failed to load configuration:",s.message),process.exit(1)}let t=go(e);console.log("Alfred \u2014 Resolved Configuration"),console.log("================================"),console.log(JSON.stringify(t,null,2))}var ua,wo=f(()=>{"use strict";ue();ua=["token","apikey","api_key","accesstoken","secret","password"];d(ma,"isSensitiveKey");d(pa,"redactValue");d(go,"redactObject");d(ha,"configCommand")});var To={};V(To,{rulesCommand:()=>ga});import Es from"node:fs";import Eo from"node:path";import fa from"js-yaml";async function ga(){let c=new z,e;try{e=c.loadConfig()}catch(a){console.error("Failed to load configuration:",a.message),process.exit(1)}let t=Eo.resolve(e.security.rulesPath);if(!Es.existsSync(t)){console.log(`Rules directory not found: ${t}`),console.log("No security rules loaded.");return}Es.statSync(t).isDirectory()||(console.error(`Rules path is not a directory: ${t}`),process.exit(1));let r=Es.readdirSync(t).filter(a=>a.endsWith(".yml")||a.endsWith(".yaml"));if(r.length===0){console.log(`No YAML rule files found in: ${t}`);return}let n=new fe,o=[],i=[];for(let a of r){let l=Eo.join(t,a);try{let u=Es.readFileSync(l,"utf-8"),h=fa.load(u),m=n.loadFromObject(h);o.push(...m)}catch(u){i.push(` ${a}: ${u.message}`)}}if(console.log("Alfred \u2014 Security Rules"),console.log("======================="),console.log(`Rules directory: ${t}`),console.log(`Rule files found: ${r.length}`),console.log(`Total rules loaded: ${o.length}`),console.log(""),i.length>0){console.log("Errors:");for(let a of i)console.log(a);console.log("")}if(o.length!==0){o.sort((a,l)=>a.priority-l.priority),console.log("Loaded rules (sorted by priority):"),console.log("");for(let a of o){let l=a.rateLimit?` | rate-limit: ${a.rateLimit.maxInvocations}/${a.rateLimit.windowSeconds}s`:"";console.log(` [${a.priority}] ${a.id}`),console.log(` effect: ${a.effect} | scope: ${a.scope}`),console.log(` actions: ${a.actions.join(", ")}`),console.log(` risk levels: ${a.riskLevels.join(", ")}${l}`),a.conditions&&console.log(` conditions: ${JSON.stringify(a.conditions)}`),console.log("")}}}var bo=f(()=>{"use strict";ue();ss();d(ga,"rulesCommand")});var _o={};V(_o,{statusCommand:()=>wa});import zt from"node:fs";import Tr from"node:path";import ya from"js-yaml";async function wa(){let c=new z,e;try{e=c.loadConfig()}catch(l){console.error("Failed to load configuration:",l.message),process.exit(1)}console.log("Alfred \u2014 Status"),console.log("================"),console.log("");let t=[{name:"Telegram",enabled:e.telegram.enabled,configured:!!e.telegram.token},{name:"Discord",enabled:!!e.discord?.enabled,configured:!!e.discord?.token},{name:"WhatsApp",enabled:!!e.whatsapp?.enabled,configured:!!e.whatsapp?.dataPath},{name:"Matrix",enabled:!!e.matrix?.enabled,configured:!!e.matrix?.accessToken},{name:"Signal",enabled:!!e.signal?.enabled,configured:!!e.signal?.phoneNumber}];console.log("Messaging Adapters:");for(let l of t){let u=l.enabled?"enabled":l.configured?"configured (disabled)":"not configured",h=l.enabled?"+":"-";console.log(` [${h}] ${l.name}: ${u}`)}console.log(""),console.log("LLM Provider:");let s=e.llm.default;console.log(` Provider: ${s.provider}`),console.log(` Model: ${s.model}`),console.log(` API Key: ${s.apiKey?"set":"not set"}`),s.baseUrl&&console.log(` Base URL: ${s.baseUrl}`);for(let l of["strong","fast","embeddings","local"]){let u=e.llm[l];u&&console.log(` ${l}: ${u.provider}/${u.model}`)}console.log(""),console.log("Storage:");let r=Tr.resolve(e.storage.path),n=zt.existsSync(r);console.log(` Database: ${r}`),console.log(` Status: ${n?"exists":"not yet created"}`),console.log("");let o=Tr.resolve(e.security.rulesPath),i=0,a=0;if(zt.existsSync(o)&&zt.statSync(o).isDirectory()){let l=zt.readdirSync(o).filter(h=>h.endsWith(".yml")||h.endsWith(".yaml"));a=l.length;let u=new fe;for(let h of l){let m=Tr.join(o,h);try{let p=zt.readFileSync(m,"utf-8"),E=ya.load(p),w=u.loadFromObject(E);i+=w.length}catch{}}}console.log("Security:"),console.log(` Rules path: ${o}`),console.log(` Rule files: ${a}`),console.log(` Rules loaded: ${i}`),console.log(` Default effect: ${e.security.defaultEffect}`),e.security.ownerUserId&&console.log(` Owner user ID: ${e.security.ownerUserId}`),console.log(""),console.log("Logger:"),console.log(` Level: ${e.logger.level}`),console.log(` Pretty: ${e.logger.pretty}`)}var So=f(()=>{"use strict";ue();ss();d(wa,"statusCommand")});var ko={};V(ko,{logsCommand:()=>ba});import Ea from"node:fs";import Ta from"node:path";async function ba(c){let e=new z,t;try{t=e.loadConfig()}catch(n){console.error("Failed to load configuration:",n.message),process.exit(1)}let s=Ta.resolve(t.storage.path);if(!Ea.existsSync(s)){console.log(`Database not found at: ${s}`),console.log("No audit log entries. Alfred has not been run yet, or the database path is incorrect.");return}let r;try{r=new me(s);let n=new pe(r.getDb()),o=n.count({}),i=n.query({limit:c});if(console.log("Alfred \u2014 Audit Log"),console.log("==================="),console.log(`Total entries: ${o}`),console.log(`Showing last ${Math.min(c,o)} entries:`),console.log(""),i.length===0){console.log("No audit log entries found.");return}for(let a of i){let l=a.timestamp.toISOString(),u=a.effect==="allow"?"ALLOW":"DENY ";console.log(` ${l} [${u}] ${a.action}`),console.log(` user: ${a.userId} | platform: ${a.platform} | risk: ${a.riskLevel}`),a.ruleId&&console.log(` rule: ${a.ruleId}`),a.chatId&&console.log(` chat: ${a.chatId}`),a.context&&console.log(` context: ${JSON.stringify(a.context)}`),console.log("")}}catch(n){console.error("Failed to read audit log:",n.message),process.exit(1)}finally{r&&r.close()}}var vo=f(()=>{"use strict";ue();Ds();d(ba,"logsCommand")});import{readFileSync as _a}from"node:fs";import{fileURLToPath as Sa}from"node:url";import{dirname as ka,join as va}from"node:path";function xa(){try{let c=ka(Sa(import.meta.url));for(let e of["../package.json","../../package.json"])try{let t=JSON.parse(_a(va(c,e),"utf-8"));if(t.version)return t.version}catch{}}catch{}return"0.0.0"}d(xa,"getVersion");var xo=xa(),br=`
|
|
582
589
|
Alfred CLI v${xo}
|
|
583
590
|
Personal AI Assistant
|
|
584
591
|
|