import {b,a}from'./chunks/chunk-2WS5ZGKQ.mjs';import {GRAPH_ENTITY_TYPE_DEFINITIONS,GRAPH_RELATION_TYPE_DEFINITIONS}from'@easbot/types';export{GRAPH_ENTITY_TYPE_DEFINITIONS,GRAPH_RELATION_TYPE_DEFINITIONS}from'@easbot/types';import*as P from'jieba-wasm';import {loadTextFile,Filesystem,formatLocalISO}from'@easbot/utils';import Se from'better-sqlite3';import {randomBytes,createHash}from'crypto';import w from'fs/promises';import R from'path';import {promises}from'fs';import {embed,embedMany,streamText}from'ai';var re=["user_preference","task_context","technical_fact","decision","relationship","reminder","error_pattern","workflow","exploration_finding","experience_summary","tool_usage","skill_creation","test","other"],x=class extends Error{constructor(t,n,r){super(t,{cause:r});this.code=n;this.cause=r;this.name="MemoryError";}},N=class extends x{constructor(e,t){super(e,"MEMORY_VALIDATION_ERROR",t),this.name="MemoryValidationError";}},j=class extends x{constructor(e){super(`Memory not found: ${e}`,"MEMORY_NOT_FOUND"),this.name="MemoryNotFoundError";}},B=class extends x{constructor(e){super(e,"MEMORY_PERMISSION_ERROR"),this.name="MemoryPermissionError";}},T=class extends x{constructor(e,t){super(e,"MEMORY_DATABASE_ERROR",t),this.name="MemoryDatabaseError";}},S=class extends x{constructor(e,t){super(e,"MEMORY_FILE_ERROR",t),this.name="MemoryFileError";}},G=class extends x{constructor(e,t){super(e,"MEMORY_SEARCH_ERROR",t),this.name="MemorySearchError";}},Y=class extends x{constructor(e,t){super(e,"MEMORY_EMBEDDING_ERROR",t),this.name="MemoryEmbeddingError";}},Re=(m=>(m.VALIDATION_ERROR="MEMORY_VALIDATION_ERROR",m.NOT_FOUND="MEMORY_NOT_FOUND",m.PERMISSION_ERROR="MEMORY_PERMISSION_ERROR",m.DATABASE_ERROR="MEMORY_DATABASE_ERROR",m.FILE_ERROR="MEMORY_FILE_ERROR",m.SEARCH_ERROR="MEMORY_SEARCH_ERROR",m.EMBEDDING_ERROR="MEMORY_EMBEDDING_ERROR",m))(Re||{});var M=b.create({service:"memory.tokenizer"}),F=false,we=loadTextFile("./assets/jieba_dict.txt",import.meta.url);async function ce(g){if(!F)try{M.debug("Initializing jieba tokenizer");let e=we();if(P.with_dict(e),M.debug("Built-in dictionary loaded"),g?.dictPath&&g.dictPath.length>0)for(let t of g.dictPath)await Ie(t);F=!0,M.debug("Jieba tokenizer initialized successfully");}catch(e){M.error("Failed to initialize jieba tokenizer",{error:String(e)}),M.warn("Using fallback tokenization (space-based)");}}async function Ie(g){if(!F)throw new Error("Tokenizer not initialized");try{let e=await Filesystem.readText(g);M.debug("Loading custom dictionary",{dictPath:g}),P.with_dict(e),M.debug("Custom dictionary loaded successfully",{dictPath:g});}catch(e){M.warn("Failed to load custom dictionary",{dictPath:g,error:String(e)});}}function Ae(g){if(!F)return g.split(/\s+/).filter(Boolean);try{return P.cut(g)}catch(e){return M.warn("Tokenization failed, using fallback",{error:String(e)}),g.split(/\s+/).filter(Boolean)}}function Ne(g){if(!F)return g.split(/\s+/).filter(Boolean);try{return P.cut_for_search(g)}catch(e){return M.warn("Tokenization for search failed, using fallback",{error:String(e)}),g.split(/\s+/).filter(Boolean)}}function Je(g,e,t){if(F)try{P.add_word(g,e,t),M.debug("Word added to dictionary",{word:g,freq:e,tag:t});}catch(n){M.warn("Failed to add word",{word:g,error:String(n)});}}function Ge(){return F}async function Ke(){F=false,M.debug("Tokenizer closed");}function se(g){if(!F)return g.split(/\s+/).filter(Boolean).join(" ");try{return Ae(g).join(" ")}catch(e){return M.warn("Tokenization failed, using fallback",{error:String(e)}),g.split(/\s+/).filter(Boolean).join(" ")}}function me(g){if(!F)return g.split(/\s+/).filter(Boolean).join(" ");try{return Ne(g).join(" ")}catch(e){return M.warn("Tokenization for search failed, using fallback",{error:String(e)}),g.split(/\s+/).filter(Boolean).join(" ")}}var X=class{constructor(e){a(this,"db",null);a(this,"storagePath");a(this,"initialized",false);a(this,"initPromise",null);this.storagePath=Filesystem.toUnixPath(e);}async initialize(){if(!this.initialized){if(this.initPromise){await this.initPromise;return}this.initPromise=this.doInitialize(),await this.initPromise,this.initialized=true;}}async doInitialize(){try{this.db=await this.openDatabaseAsync(),this.createTables(),this.db.pragma("foreign_keys = ON");}catch(e){throw new T(`Database initialization failed: ${e.message}`,e)}}async openDatabaseAsync(){return new Promise((e,t)=>{setImmediate(()=>{try{let n=new Se(this.storagePath);n.pragma("journal_mode = WAL"),n.pragma("synchronous = NORMAL"),n.pragma("cache_size = -64000"),n.pragma("temp_store = MEMORY"),e(n);}catch(n){t(n);}});})}createTables(){if(!this.db)throw new T("Database not initialized");let e=this.db;e.exec(`
      CREATE TABLE IF NOT EXISTS memory_facts (
        id TEXT PRIMARY KEY,
        agent_id TEXT NOT NULL,
        session_id TEXT,
        msg_id TEXT,
        parent_msg_id TEXT,
        content TEXT NOT NULL,
        category TEXT NOT NULL,
        importance INTEGER NOT NULL CHECK(importance >= 1 AND importance <= 10),
        source TEXT NOT NULL CHECK(source IN ('session_self_write', 'historical')),
        tags TEXT,
        node_ids TEXT,
        file_path TEXT,
        created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
        updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
        UNIQUE(session_id, msg_id)
      )
    `),e.exec("CREATE INDEX IF NOT EXISTS idx_memory_facts_agent_id ON memory_facts(agent_id)"),e.exec("CREATE INDEX IF NOT EXISTS idx_memory_facts_agent_category ON memory_facts(agent_id, category)"),e.exec("CREATE INDEX IF NOT EXISTS idx_memory_facts_agent_importance ON memory_facts(agent_id, importance DESC)"),e.exec("CREATE INDEX IF NOT EXISTS idx_memory_facts_created_at ON memory_facts(created_at)"),e.exec(`
      CREATE TABLE IF NOT EXISTS memory_vectors (
        fact_id TEXT PRIMARY KEY,
        embedding BLOB NOT NULL,
        FOREIGN KEY (fact_id) REFERENCES memory_facts(id) ON DELETE CASCADE
      )
    `),e.exec(`
      CREATE TABLE IF NOT EXISTS embedding_cache (
        content_hash TEXT PRIMARY KEY,
        embedding BLOB NOT NULL,
        created_at DATETIME DEFAULT CURRENT_TIMESTAMP
      )
    `),e.exec(`
      CREATE VIRTUAL TABLE IF NOT EXISTS memory_facts_fts USING fts5(
        fact_id UNINDEXED,
        agent_id UNINDEXED,
        content,
        tags,
        tokenize='porter unicode61'
      )
    `),e.exec(`
      CREATE TABLE IF NOT EXISTS nodes (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT NOT NULL,
        type TEXT NOT NULL,
        properties TEXT,
        createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
        updatedAt DATETIME DEFAULT CURRENT_TIMESTAMP
      )
    `),e.exec("CREATE INDEX IF NOT EXISTS idx_nodes_name ON nodes(name)"),e.exec("CREATE INDEX IF NOT EXISTS idx_nodes_type ON nodes(type)"),e.exec("CREATE UNIQUE INDEX IF NOT EXISTS idx_nodes_name_type ON nodes(name, type)"),e.exec(`
      CREATE TABLE IF NOT EXISTS edges (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        source INTEGER NOT NULL,
        target INTEGER NOT NULL,
        relation TEXT NOT NULL,
        properties TEXT,
        createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
        FOREIGN KEY (source) REFERENCES nodes(id) ON DELETE CASCADE,
        FOREIGN KEY (target) REFERENCES nodes(id) ON DELETE CASCADE
      )
    `),e.exec("CREATE INDEX IF NOT EXISTS idx_edges_source ON edges(source)"),e.exec("CREATE INDEX IF NOT EXISTS idx_edges_target ON edges(target)"),e.exec("CREATE INDEX IF NOT EXISTS idx_edges_relation ON edges(relation)"),e.exec("CREATE UNIQUE INDEX IF NOT EXISTS idx_edges_unique ON edges(source, target, relation)"),e.exec(`
      CREATE TABLE IF NOT EXISTS meta (
        key TEXT PRIMARY KEY,
        value TEXT
      )
    `);}query(e,t){if(!this.db)throw new T("Database not initialized. Call initialize() first.");try{let n=this.db.prepare(e);return t?n.all(...t):n.all()}catch(n){throw new T(`Query failed: ${n.message}`,n)}}run(e,t){if(!this.db)throw new T("Database not initialized. Call initialize() first.");try{let n=this.db.prepare(e),r=t?n.run(...t):n.run();return {lastID:Number(r.lastInsertRowid),changes:r.changes}}catch(n){throw new T(`Write failed: ${n.message}`,n)}}transaction(e){if(!this.db)throw new T("Database not initialized. Call initialize() first.");return this.db.transaction(e)()}prepare(e){if(!this.db)throw new T("Database not initialized. Call initialize() first.");return this.db.prepare(e)}exec(e){if(!this.db)throw new T("Database not initialized. Call initialize() first.");this.db.exec(e);}getDb(){if(!this.db)throw new T("Database not initialized. Call initialize() first.");return this.db}getPath(){return this.storagePath}close(){this.db&&(this.db.close(),this.db=null,this.initialized=false);}healthCheck(){try{return this.db?(this.db.prepare("SELECT 1").get(),!0):!1}catch{return  false}}getMeta(e){if(!this.db)throw new Error("Database not initialized");return this.db.prepare("SELECT value FROM meta WHERE key = ?").get(e)?.value??null}setMeta(e,t){if(!this.db)throw new Error("Database not initialized");this.db.prepare("INSERT OR REPLACE INTO meta (key, value) VALUES (?, ?)").run(e,t);}};var Le=["id","agentId","category","importance"],q="---",O=class g{static generateId(){let e=Date.now(),t=randomBytes(3).toString("hex");return `mem_${e}_${t}`}static serialize(e){let t=new Date(e.createdAt),n=e.updatedAt?new Date(e.updatedAt):new Date,r={id:e.id,agentId:e.agentId,category:e.category,importance:e.importance,createdAt:formatLocalISO(t),updatedAt:formatLocalISO(n),source:e.source};e.sessionId&&(r.sessionId=e.sessionId),e.msgId&&(r.msgId=e.msgId),e.parentMsgId&&(r.parentMsgId=e.parentMsgId),e.tags&&e.tags.length>0&&(r.tags=e.tags),e.nodeIds&&e.nodeIds.length>0&&(r.nodeIds=e.nodeIds),e.filePath&&(r.filePath=e.filePath);let i=Object.entries(r).map(([s,m])=>Array.isArray(m)?`${s}: [${m.join(", ")}]`:`${s}: ${m}`);return [q,...i,q,"",e.content.trim(),""].join(`
`)}static serializeFile(e){return e.map(t=>g.serialize(t)).join(`
`)}static parse(e){let t=[],n=e.split(`
`),r=0;for(;r<n.length;){if(n[r]?.trim()!==q){r++;continue}let i=r+1,s=-1;for(let u=i;u<n.length;u++)if(n[u]?.trim()===q){s=u;break}if(s===-1){r++;continue}let m=n.slice(i,s),o=g.parseFrontmatter(m);g.validateFrontmatter(o);let d=s+1,c=n.length;for(let u=d;u<n.length;u++)if(n[u]?.trim()===q){c=u;break}let a=n.slice(d,c).join(`
`).trim(),l={id:String(o.id),agentId:String(o.agentId),category:o.category,importance:Number(o.importance),source:o.source??"session_self_write",content:a,createdAt:o.createdAt?new Date(String(o.createdAt)).toISOString():new Date().toISOString(),updatedAt:o.updatedAt?new Date(String(o.updatedAt)).toISOString():new Date().toISOString()};o.sessionId&&(l.sessionId=String(o.sessionId)),o.msgId&&(l.msgId=String(o.msgId)),o.parentMsgId&&(l.parentMsgId=String(o.parentMsgId)),o.filePath&&(l.filePath=String(o.filePath)),o.tags&&(l.tags=g.parseArrayField(o.tags)),o.nodeIds&&(l.nodeIds=g.parseArrayField(o.nodeIds).map(Number).filter(u=>!Number.isNaN(u))),t.push(l),r=c;}return t}static parseFrontmatter(e){let t={};for(let n of e){let r=n.indexOf(":");if(r===-1)continue;let i=n.slice(0,r).trim(),s=n.slice(r+1).trim();if(i)if(s.startsWith("[")&&s.endsWith("]")){let m=s.slice(1,-1).trim();t[i]=m?m.split(",").map(o=>o.trim()).filter(Boolean):[];}else t[i]=s;}return t}static validateFrontmatter(e){for(let r of Le)if(e[r]===void 0||e[r]==="")throw new N(`Missing required field in memory frontmatter: ${r}`);let t=e.category;if(!re.includes(t))throw new N(`Invalid category: "${t}". Valid values: ${re.join(", ")}`);let n=Number(e.importance);if(Number.isNaN(n)||n<1||n>10)throw new N(`Invalid importance: "${e.importance}". Must be an integer between 1 and 10.`)}static parseArrayField(e){if(Array.isArray(e))return e.map(String);if(typeof e=="string"){let t=e.trim();if(t.startsWith("[")&&t.endsWith("]")){let n=t.slice(1,-1).trim();return n?n.split(",").map(r=>r.trim()).filter(Boolean):[]}return t?[t]:[]}return []}};var ue="MEMORY.md",pe="active",ve="archive",A=class g{static getMemoryMdPath(e){return R.join(e,ue)}static getActiveFilePath(e,t,n){let r=n??new Date,i=r.getFullYear(),s=String(r.getMonth()+1).padStart(2,"0"),m=String(r.getDate()).padStart(2,"0"),o=`${i}-${s}-${m}`;return R.join(e,pe,t,`${o}.md`)}static getArchiveFilePath(e,t,n,r){let i=new Date(n),s=`${i.getFullYear()}-${String(i.getMonth()+1).padStart(2,"0")}`;return R.join(e,ve,s,t,r)}static async readMemoryMd(e){let t=g.getMemoryMdPath(e);try{return await w.readFile(t,"utf-8")}catch(n){if(n.code==="ENOENT")return null;throw new S(`Failed to read MEMORY.md: ${n.message}`,n)}}static async write(e,t){let n=g.getActiveFilePath(e,t.category);Filesystem.toUnixPath(R.relative(e,n));if(R.basename(n)===ue)throw new B("Writing to MEMORY.md is not allowed. MEMORY.md is read-only.");try{await w.mkdir(R.dirname(n),{recursive:!0});let i=O.serialize(t),s="";try{s=await w.readFile(n,"utf-8");}catch{}let m=s.length>0&&!s.endsWith(`
`)?`
`:"";return await w.writeFile(n,`${s}${m}${i}`,"utf-8"),Filesystem.normalize(n)}catch(i){throw i instanceof B?i:new S(`Failed to write memory to ${n}: ${i.message}`,i)}}static async read(e){try{let t=await w.readFile(e,"utf-8");return O.parse(t)}catch(t){if(t.code==="ENOENT")return [];throw new S(`Failed to read memory file ${e}: ${t.message}`,t)}}static async delete(e,t){try{let n=await g.read(e),r=n.filter(i=>i.id!==t);if(r.length===n.length)return;r.length===0?await w.unlink(e).catch(()=>{}):await w.writeFile(e,O.serializeFile(r),"utf-8");}catch(n){throw n instanceof S?n:new S(`Failed to delete memory ${t} from ${e}: ${n.message}`,n)}}static async update(e,t,n){try{let r=await g.read(e),i=r.findIndex(m=>m.id===t);if(i===-1)return;let s={...r[i],...n,updatedAt:new Date().toISOString()};r[i]=s,await w.writeFile(e,O.serializeFile(r),"utf-8");}catch(r){throw r instanceof S?r:new S(`Failed to update memory ${t} in ${e}: ${r.message}`,r)}}static async listActiveFiles(e){let t=R.join(e,pe),n=[];try{await g.scanDir(t,n);}catch(r){if(r.code==="ENOENT")return [];throw new S(`Failed to list active memory files: ${r.message}`,r)}return n}static async scanDir(e,t){let n=await w.readdir(e,{withFileTypes:true});for(let r of n){let i=R.join(e,r.name);r.isDirectory()?await g.scanDir(i,t):r.isFile()&&r.name.endsWith(".md")&&t.push(i);}}};var H=class{constructor(e,t){a(this,"db");a(this,"config");this.db=e,this.config=t;}async archive(){let t=(this.config.archiveDays??30)*864e5,n=Date.now(),r=[],i=await A.listActiveFiles(this.config.workspaceDir);for(let s of i){let m=await A.read(s);if(m.length===0)continue;let o=m[0]?.createdAt,d=o?new Date(o).getTime():n;if(n-d<=t)continue;let c=m[0]?.category;if(!c)continue;let a=R.basename(s),l=A.getArchiveFilePath(this.config.workspaceDir,c,d,a);await promises.mkdir(R.dirname(l),{recursive:true}),await promises.rename(s,l);let u=Filesystem.toUnixPath(R.relative(this.config.workspaceDir,l)),p=Filesystem.toUnixPath(R.relative(this.config.workspaceDir,s));this.db.prepare("UPDATE memory_facts SET file_path = ? WHERE file_path = ?").run(u,p),r.push({source:s,target:l,timestamp:n});}return {archivedCount:r.length,records:r}}};var Q=b.create({service:"memory.graph-store"}),V=class{constructor(e){a(this,"db");this.db=e;}async upsertNode(e,t,n){let r=Date.now(),i=this.db.prepare("SELECT id FROM nodes WHERE name = ? AND type = ?").get(e,t);if(i)return this.db.prepare("UPDATE nodes SET properties = ?, updatedAt = ? WHERE id = ?").run(JSON.stringify(n??{}),r,i.id),i.id;let s=this.db.prepare("INSERT INTO nodes (name, type, properties, createdAt, updatedAt) VALUES (?, ?, ?, ?, ?)").run(e,t,JSON.stringify(n??{}),r,r);return Number(s.lastInsertRowid)}async deleteNode(e){this.db.prepare("DELETE FROM nodes WHERE id = ?").run(e);}async upsertEdge(e,t,n,r){let i=this.db.prepare("INSERT INTO edges (source, target, relation, properties, createdAt) VALUES (?, ?, ?, ?, ?)").run(e,t,n,JSON.stringify(r??{}),Date.now());return Number(i.lastInsertRowid)}async queryNodes(e={}){let t="SELECT id, name, type, properties, createdAt, updatedAt FROM nodes",n=[],r=[];if(e.ids&&e.ids.length>0){let s=e.ids.map(m=>typeof m=="string"?parseInt(m,10):m).filter(m=>!Number.isNaN(m));r.push(`id IN (${s.map(()=>"?").join(", ")})`),n.push(...s);}e.name&&(r.push("name LIKE ?"),n.push(`%${e.name}%`)),e.type&&(r.push("type = ?"),n.push(e.type)),r.length>0&&(t+=` WHERE ${r.join(" AND ")}`),t+=" ORDER BY id",e.limit&&(t+=" LIMIT ?",n.push(e.limit)),Q.debug("queryNodes",{sql:t,params:n,filter:e});let i=this.db.prepare(t).all(...n);return Q.debug("queryNodes result",{count:i.length}),i.map(s=>({id:s.id,name:s.name,type:s.type,properties:s.properties?JSON.parse(s.properties):void 0,createdAt:s.createdAt,updatedAt:s.updatedAt}))}async queryEdges(e={}){let t="SELECT id, source, target, relation, properties, createdAt FROM edges",n=[],r=[];if(e.ids&&e.ids.length>0&&(r.push(`id IN (${e.ids.map(()=>"?").join(", ")})`),n.push(...e.ids)),e.source!==void 0&&(r.push("source = ?"),n.push(e.source)),e.target!==void 0&&(r.push("target = ?"),n.push(e.target)),e.sourceOrTarget&&e.sourceOrTarget.length>0){let d=e.sourceOrTarget.map(c=>typeof c=="string"?parseInt(c,10):c).filter(c=>!Number.isNaN(c));r.push(`(source IN (${d.map(()=>"?").join(", ")}) OR target IN (${d.map(()=>"?").join(", ")}))`),n.push(...d,...d);}e.relation&&(r.push("relation = ?"),n.push(e.relation)),r.length>0&&(t+=` WHERE ${r.join(" AND ")}`),t+=" ORDER BY id",e.limit&&(t+=" LIMIT ?",n.push(e.limit)),Q.debug("queryEdges",{sql:t,params:n,filter:e});let i=this.db.prepare(t).all(...n);Q.debug("queryEdges result",{count:i.length});let s=[...new Set(i.map(d=>d.target))],m=s.length>0?await this.queryNodes({ids:s,limit:s.length}):[],o=new Map(m.map(d=>[d.id,d]));return i.map(d=>{let c={id:d.id,source:d.source,target:d.target,relation:d.relation,properties:d.properties?JSON.parse(d.properties):void 0,createdAt:d.createdAt},a=o.get(d.target);return a&&(c.targetNode=a),c})}async queryNeighbors(e,t=1,n){let r=new Set,i=[{id:e,level:0}],s=[],m=n?.maxEdgesPerNode??50;for(;i.length>0;){let o=i.shift();if(!o)break;if(r.has(o.id)||o.level>t)continue;r.add(o.id);let c=(await this.queryNodes({ids:[o.id],limit:1}))[0];if(!c)continue;let a=await this.queryEdges({sourceOrTarget:[o.id],limit:m});if(s.push({...c,edges:a}),o.level<t)for(let l of a){let u=l.source===o.id?l.target:l.source;r.has(u)||i.push({id:u,level:o.level+1});}}return s}};var $;(c=>{let g=null;function e(a){t()||(g={models:a.models,options:a.options??{}});}c.init=e;function t(){return g!==null}c.isInitialized=t;function n(){return g?{embedding:!!g.models.embeddingLlm,graph:!!g.models.graphLlm}:{embedding:false,graph:false}}c.capabilities=n;async function r(a){let u=m().models.embeddingLlm;if(!u)throw new Error("embeddingLlm model is not configured.");try{let p=await embed({model:u,value:a});return new Float32Array(p.embedding)}catch(p){let b=u.doEmbed;if(typeof b!="function")throw new Error("embeddingLlm model does not support embedding generation.",{cause:p});let I=(await b({values:[a]}))?.embeddings?.[0];if(!I||!Array.isArray(I))throw new Error("embeddingLlm model returned invalid embedding result.",{cause:p});return new Float32Array(I)}}c.embedText=r;async function i(a){let u=m().models.embeddingLlm;if(!u)throw new Error("embeddingLlm model is not configured.");try{return (await embedMany({model:u,values:a})).embeddings.map(b=>new Float32Array(b))}catch{return ((await u.doEmbed?.({values:a}))?.embeddings??[]).map(b=>new Float32Array(b))}}c.embedTexts=i;async function s(a,l){let u=m(),p=u.models.graphLlm;if(!p)throw new Error("llm model is not configured.");try{return (await streamText({model:p,prompt:a,maxOutputTokens:l?.maxOutputTokens??u.options.graph?.maxOutputTokens,temperature:l?.temperature??u.options.graph?.temperature})).text}catch{return (await p.doGenerate?.({prompt:[{role:"user",content:[{type:"text",text:a}]}],maxOutputTokens:l?.maxOutputTokens??u.options.graph?.maxOutputTokens}))?.content?.find(D=>D.type==="text")?.text??""}}c.generate=s;let m=()=>{if(!g)throw new Error("Llm is not initialized. Please call Llm.init() first.");return g};c.embed=r,c.embedMany=i;})($||($={}));var Z=class{constructor(e,t){a(this,"db");a(this,"config");a(this,"embeddingModel");this.db=e,this.config=t,this.embeddingModel=t.embeddingLlm,this.embeddingModel&&$.init({models:{embeddingLlm:this.embeddingModel,graphLlm:t.graphLlm}});}async search(e,t){if(!e.trim())return [];if(!t?.agentId)return [];let n=t.maxResults??this.config.search.maxResults,r=await this.hybridSearch(e,{...t,maxResults:n*2});return r.length===0?[]:r.slice(0,n)}async hybridSearch(e,t){let{maxResults:n=this.config.search.maxResults,minScore:r=this.config.search.minScore,vectorWeight:i=this.config.search.hybrid.vectorWeight,textWeight:s=this.config.search.hybrid.textWeight,enableEmbedding:m=true}=t??{},d=m&&!!this.embeddingModel?await this.embed(e):null,c=["mf.agent_id = ?"],a=[t?.agentId];t?.category&&(c.push("mf.category = ?"),a.push(t.category)),t?.minImportance!==void 0&&(c.push("mf.importance >= ?"),a.push(t.minImportance)),t?.source&&(c.push("mf.source = ?"),a.push(t.source)),t?.fromTime!==void 0&&(c.push("mf.created_at >= ?"),a.push(t.fromTime)),t?.toTime!==void 0&&(c.push("mf.created_at <= ?"),a.push(t.toTime));let l=c.join(" AND "),[u,p]=await Promise.all([d?this.vectorSearch(d,l,a,n,r,t?.candidateFactIds):Promise.resolve([]),this.ftsSearch(e,l,a,n,r)]),b=d?i:0,D=d?s:1;return this.mergeResults(u,p,b,D,l,a,r)}async vectorSearch(e,t,n,r,i,s){if(!this.embeddingModel)return [];try{let m;if(s&&s.length>0){let d=s.map(()=>"?").join(",");m=this.db.prepare(`
          SELECT mf.id, mv.embedding
          FROM memory_facts mf
          JOIN memory_vectors mv ON mf.id = mv.fact_id
          WHERE ${t} AND mf.id IN (${d})
        `).all(...n,...s);}else m=this.db.prepare(`
          SELECT mf.id, mv.embedding
          FROM memory_facts mf
          JOIN memory_vectors mv ON mf.id = mv.fact_id
          WHERE ${t}
          LIMIT ?
        `).all(...n,Math.max(r*100,1e3));let o=[];for(let d of m){let c=new Float32Array(d.embedding.buffer,d.embedding.byteOffset,d.embedding.length/4),a=this.cosineSimilarity(e,c);o.push({id:d.id,score:a});}return o.sort((d,c)=>c.score-d.score).slice(0,r)}catch(m){throw new G(`\u5411\u91CF\u641C\u7D22\u5931\u8D25: ${m instanceof Error?m.message:String(m)}`,m instanceof Error?m:void 0)}}async ftsSearch(e,t,n,r,i){let s=()=>[];try{let o=(me(e).trim()||e.trim()).split(/\s+/).filter(a=>a.length>0).map(a=>`"${a.replace(/"/g,'""')}"`).join(" "),d=this.db.prepare(`
        SELECT mf.id, bm25(memory_facts_fts) as score
        FROM memory_facts mf
        JOIN memory_facts_fts ON mf.id = memory_facts_fts.fact_id
        WHERE ${t} AND memory_facts_fts.content MATCH ?
        ORDER BY score DESC
        LIMIT ?
      `).all(...n,o,r);if(d.length===0)return s();let c=Math.max(...d.map(a=>Math.abs(a.score)),1);return d.map(a=>({id:a.id,score:1-Math.abs(a.score)/c})).filter(a=>a.score>=0)}catch{return s()}}async mergeResults(e,t,n,r,i,s,m){let o=n+r,d=n/o,c=r/o,a=new Map;for(let h of e)a.set(h.id,h.score*d);for(let h of t){let _=a.get(h.id)||0;a.set(h.id,_+h.score*c);}let l=Array.from(a.entries()).map(([h,_])=>({id:h,score:_})).sort((h,_)=>_.score-h.score).map(h=>h.id);if(l.length===0)return [];let u=l.map(()=>"?").join(","),p=this.db.prepare(`
      SELECT
        mf.id as memoryId,
        mf.category,
        mf.importance,
        mf.agent_id as agentId,
        SUBSTR(mf.content, 1, 200) as snippet,
        mf.created_at as createdAt,
        mf.source,
        mf.file_path as filePath,
        mf.node_ids
      FROM memory_facts mf
      WHERE mf.id IN (${u})
    `).all(...l),b=[],D=new Map;for(let h of p)if(h.node_ids)try{let _=JSON.parse(h.node_ids);D.set(h.memoryId,_),b.push(..._);}catch{}let I=Array.from(new Set(b)),oe=new Map,W=new Map;if(I.length>0){let h=I.map(()=>"?").join(", "),_=this.db.prepare(`SELECT id, name, type FROM nodes WHERE id IN (${h})`).all(...I);for(let y of _)oe.set(y.id,y);let J=this.db.prepare(`SELECT e.id, e.source, e.target, e.relation, e.properties, e.createdAt, n.name as targetName, n.type as targetType
         FROM edges e JOIN nodes n ON n.id = e.target
         WHERE e.source IN (${h})`).all(...I);for(let y of J){let U=W.get(y.source)??[];U.push({id:y.id,source:y.source,target:y.target,relation:y.relation,properties:y.properties?JSON.parse(y.properties):void 0,createdAt:y.createdAt,targetNode:{id:y.target,name:y.targetName,type:y.targetType,createdAt:y.createdAt,updatedAt:y.createdAt}}),W.set(y.source,U);}let te=this.db.prepare(`SELECT e.id, e.source, e.target, e.relation, e.properties, e.createdAt, n.name as sourceName, n.type as sourceType
         FROM edges e JOIN nodes n ON n.id = e.source
         WHERE e.target IN (${h})`).all(...I);for(let y of te){let U=W.get(y.target)??[];U.push({id:y.id,source:y.source,target:y.target,relation:y.relation,properties:y.properties?JSON.parse(y.properties):void 0,createdAt:y.createdAt,targetNode:{id:y.source,name:y.sourceName,type:y.sourceType,createdAt:y.createdAt,updatedAt:y.createdAt}}),W.set(y.target,U);}}return p.map(h=>{let _=D.get(h.memoryId)??[],J=_.length>0?_.flatMap(ae=>{let de=oe.get(ae);return de?[{...de,edges:W.get(ae)}]:[]}):void 0,te=a.get(h.memoryId)??0,y=new Date(h.createdAt),U=(Date.now()-y.getTime())/864e5,Ee=Math.exp(-0.05*U),be=(h.importance-1)/9,Te=.4*te+.3*Ee+.3*be;return {memoryId:h.memoryId,category:h.category,importance:h.importance,agentId:h.agentId,snippet:h.snippet,score:Te,createdAt:h.createdAt,source:h.source,filePath:h.filePath,nodes:(J?.length??0)>0?J:void 0}}).filter(h=>h.score>=m).sort((h,_)=>_.score-h.score)}async embed(e){if(!this.embeddingModel)throw new Y("Embedding \u6A21\u578B\u672A\u914D\u7F6E\uFF0C\u65E0\u6CD5\u751F\u6210\u5411\u91CF");try{return await $.embedText(e)}catch(t){throw new Y(`\u751F\u6210\u5411\u91CF\u5931\u8D25: ${t instanceof Error?t.message:String(t)}`,t instanceof Error?t:void 0)}}cosineSimilarity(e,t){if(e.length!==t.length||e.length===0)return 0;let n=0,r=0,i=0;for(let s=0;s<e.length;s++){let m=e[s],o=t[s];n+=m*o,r+=m*m,i+=o*o;}return n/(Math.sqrt(r)*Math.sqrt(i))}};var f=b.create({service:"memory.system"}),Ce=.7,ze=.3,$e=10;var Ue=new Set(GRAPH_ENTITY_TYPE_DEFINITIONS.map(g=>g.type)),We=new Set(GRAPH_RELATION_TYPE_DEFINITIONS.map(g=>g.type)),ee=class{constructor(e){a(this,"config");a(this,"db");a(this,"archiver",null);a(this,"searchEngine",null);a(this,"graphStore",null);a(this,"embeddingModel");a(this,"vectorDims");e.search?.hybrid;this.config={workspaceDir:e.workspaceDir,database:e.database,archiveDays:e.archiveDays??30,search:{maxResults:e.search?.maxResults??$e,minScore:e.search?.minScore??.3,hybrid:{enabled:e.search?.hybrid?.enabled??true,vectorWeight:e.search?.hybrid?.vectorWeight??Ce,textWeight:e.search?.hybrid?.textWeight??ze}},embedding:e.embedding??{},tokenizer:e.tokenizer??{},indexer:e.indexer??{batchSize:50,ignorePatterns:[],incremental:false},logDir:e.logDir??"",graphLlm:e.graphLlm,embeddingLlm:e.embeddingLlm},this.embeddingModel=e.embeddingLlm,this.db=new X(e.database.path),this.embeddingModel&&$.init({models:{embeddingLlm:this.embeddingModel,graphLlm:this.config.graphLlm}});}async initialize(){await b.init({logDir:this.config.logDir??R.join(this.config.workspaceDir,"logs"),print:process.argv.includes("--print-logs"),dev:false,level:"INFO"}),await w.mkdir(R.dirname(this.config.database.path),{recursive:true}),await w.mkdir(R.join(this.config.workspaceDir,"active"),{recursive:true}),await w.mkdir(R.join(this.config.workspaceDir,"archive"),{recursive:true}),await this.db.initialize(),this.archiver=new H(this.db.getDb(),this.config),this.graphStore=new V(this.db.getDb()),this.searchEngine=new Z(this.db.getDb(),this.config);let e=this.db.query("SELECT value FROM meta WHERE key = ?",["vectorDims"]);e[0]&&(this.vectorDims=parseInt(e[0].value,10));let t=[["version","1.0.0"],["createdAt",new Date().toISOString()]];for(let[n,r]of t)this.db.run("INSERT OR IGNORE INTO meta (key, value) VALUES (?, ?)",[n,r]);await ce({dictPath:this.config.tokenizer.dictPath}).catch(n=>{f.warn("Tokenizer initialization failed, using fallback",{error:String(n)});}),f.info("Memory system initialized",{workspaceDir:this.config.workspaceDir,dbPath:this.config.database.path});}async remember(e){if(!e.agentId?.trim())throw new N("agentId is required for remember operation");let t=new Date().toISOString(),n=O.generateId(),r={...e,id:n,source:"session_self_write",createdAt:t,updatedAt:t};A.write(this.config.workspaceDir,r).then(a=>{r.filePath=a,f.debug("Memory written to file",{id:n,filePath:a});}).catch(a=>{f.warn("Failed to write memory to file",{id:n,error:String(a)});});let i=[],s=this.config,m=this.extractEntities(r.content);if(i=this.storeEntitiesAndRelations(m.entities,m.relations).nodeIds,s.graphLlm){let a=r.content,l=r.agentId,u=r.id;f.debug("Scheduling background LLM extraction",{id:u,contentLength:a.length}),this.extractEntitiesWithLlm(a).then(p=>{f.debug("Background LLM extraction completed",{id:u,entities:p.entities.length,relations:p.relations.length}),this.mergeEntitiesAndRelations(u,l,p.entities,p.relations);}).catch(p=>{f.warn("Background graph extraction failed",{id:u,error:String(p)});});}r.nodeIds=i;let d=await this.embed(r.content),c=d?Buffer.from(d.buffer,d.byteOffset,d.byteLength):null;return this.db.transaction(()=>{this.db.run(`INSERT OR REPLACE INTO memory_facts
          (id, agent_id, session_id, msg_id, parent_msg_id, content, category, importance,
           source, tags, node_ids, file_path, created_at, updated_at)
         VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[r.id,r.agentId,r.sessionId??null,r.msgId??null,r.parentMsgId??null,r.content,r.category,r.importance,r.source,r.tags?JSON.stringify(r.tags):null,r.nodeIds?JSON.stringify(r.nodeIds):null,r.filePath?Filesystem.toUnixPath(r.filePath):null,r.createdAt,r.updatedAt]),c&&this.db.run("INSERT OR REPLACE INTO memory_vectors (fact_id, embedding) VALUES (?, ?)",[r.id,c]),this.writeFts(r.id,r.agentId,r.content,r.tags);}),f.info("Memory stored",{id:r.id,category:r.category,agentId:r.agentId,nodeCount:i.length}),r}async query(e,t){if(!t?.agentId?.trim())throw new N("agentId is required for query operation");return this.getSearchEngine().search(e,t)}async queryEdgesByNodeId(e,t){if(!this.graphStore)return {nodes:[],edges:[]};let n=Math.min(Math.max(t?.maxDepth??2,1),3),r=await this.graphStore.queryNeighbors(e,n,{maxEdgesPerNode:t?.maxEdgesPerNode??20}),i=r.find(s=>s.id===e);return {node:i?{id:i.id,name:i.name,type:i.type}:void 0,nodes:r.map(s=>s),edges:r.flatMap(s=>s.edges??[])}}async forget(e,t){if(!e?.trim())throw new N("agentId is required for forget operation");let n=this.db.query("SELECT file_path, node_ids, content FROM memory_facts WHERE id = ? AND agent_id = ?",[t,e]);if(n.length===0)throw new j(t);let r=n[0]?.file_path,i=n[0]?.node_ids?JSON.parse(n[0].node_ids):[],s=n[0]?.content,m=s?createHash("sha256").update(s).digest("hex"):null,o=new Set;if(i.length>0){i.map(()=>"?").join(",");let a=this.db.query("SELECT node_ids FROM memory_facts WHERE id != ? AND agent_id = ? AND node_ids IS NOT NULL",[t,e]);for(let l of a)if(l.node_ids){let u=JSON.parse(l.node_ids);for(let p of u)o.add(p);}}let d=i.filter(c=>!o.has(c));if(this.db.transaction(()=>{if(this.db.run("DELETE FROM memory_facts WHERE id = ? AND agent_id = ?",[t,e]),this.db.run("DELETE FROM memory_facts_fts WHERE fact_id = ?",[t]),d.length>0){let c=d.map(()=>"?").join(",");this.db.run(`DELETE FROM nodes WHERE id IN (${c})`,d);}m&&this.db.run("DELETE FROM embedding_cache WHERE content_hash = ?",[m]);}),r){let c=R.isAbsolute(r)?r:R.join(this.config.workspaceDir,r);await A.delete(c,t).catch(a=>{f.warn("Failed to delete memory from file",{memoryId:t,filePath:r,error:String(a)});});}f.info("Memory deleted",{memoryId:t,agentId:e,orphanNodes:d.length});}async update(e,t,n){if(!e?.trim())throw new N("agentId is required for update operation");let r=this.db.query("SELECT * FROM memory_facts WHERE id = ? AND agent_id = ?",[t,e]);if(r.length===0)throw new j(t);let i=r[0],s=new Date().toISOString(),m=n.content??i.content,o=n.importance??i.importance,d=n.tags??(i.tags?JSON.parse(i.tags):void 0),c=n.content?await this.embed(m).then(l=>l?Buffer.from(l.buffer,l.byteOffset,l.byteLength):null):null;if(this.db.transaction(()=>{this.db.run(`UPDATE memory_facts SET content = ?, importance = ?, tags = ?, updated_at = ?
         WHERE id = ? AND agent_id = ?`,[m,o,d?JSON.stringify(d):null,s,t,e]),c&&this.db.run("INSERT OR REPLACE INTO memory_vectors (fact_id, embedding) VALUES (?, ?)",[t,c]),this.writeFts(t,e,m,d);}),i.file_path){let l=R.isAbsolute(i.file_path)?i.file_path:R.join(this.config.workspaceDir,i.file_path);await A.update(l,t,n).catch(u=>{f.warn("Failed to update memory in file",{memoryId:t,error:String(u)});});}let a={id:i.id,agentId:i.agent_id,sessionId:i.session_id??void 0,msgId:i.msg_id??void 0,parentMsgId:i.parent_msg_id??void 0,content:m,category:i.category,importance:o,source:i.source,tags:d,nodeIds:i.node_ids?JSON.parse(i.node_ids):void 0,filePath:i.file_path??void 0,createdAt:String(i.created_at),updatedAt:s};return f.info("Memory updated",{memoryId:t,agentId:e}),a}async listAgentIds(){return this.db.query("SELECT DISTINCT agent_id FROM memory_facts ORDER BY agent_id").map(t=>t.agent_id)}async queryForSummary(e,t=10){return e?.trim()?this.db.query(`SELECT * FROM memory_facts
       WHERE agent_id = ?
       ORDER BY importance DESC, created_at DESC
       LIMIT ?`,[e,t]).map(r=>({id:r.id,agentId:r.agent_id,sessionId:r.session_id??void 0,msgId:r.msg_id??void 0,parentMsgId:r.parent_msg_id??void 0,content:r.content,category:r.category,importance:r.importance,source:r.source,tags:r.tags?JSON.parse(r.tags):void 0,nodeIds:r.node_ids?JSON.parse(r.node_ids):void 0,filePath:r.file_path??void 0,createdAt:String(r.created_at),updatedAt:String(r.updated_at)})):[]}async archive(){await this.getArchiver().archive();}async cleanupOrphanRecords(){let e=this.db.transaction(()=>{let t=this.db.run("DELETE FROM memory_facts_fts WHERE fact_id NOT IN (SELECT id FROM memory_facts)"),n=this.db.run("DELETE FROM memory_vectors WHERE fact_id NOT IN (SELECT id FROM memory_facts)"),r=this.db.run("DELETE FROM embedding_cache WHERE content_hash NOT IN (SELECT content_hash FROM memory_facts)");return {orphanFts:t.changes,orphanVectors:n.changes,orphanCache:r.changes}});(e.orphanFts>0||e.orphanVectors>0||e.orphanCache>0)&&f.info("Cleaned orphan records",e);}async clear(){this.db.transaction(()=>{this.db.run("DELETE FROM memory_facts"),this.db.run("DELETE FROM memory_vectors"),this.db.run("DELETE FROM embedding_cache"),this.db.run("DELETE FROM memory_facts_fts"),this.db.run("DELETE FROM nodes"),this.db.run("DELETE FROM edges");});try{let e=await A.listActiveFiles(this.config.workspaceDir);for(let t of e)await w.rm(t,{force:!0}).catch(()=>{});}catch(e){f.warn("Failed to clean memory files",{error:String(e)});}f.info("Memory system cleared");}async close(){this.db.close(),await b.close(),f.info("Memory system closed");}async getStatus(){try{let e=this.db.query("SELECT COUNT(*) as c FROM memory_facts"),t=this.db.query("SELECT COUNT(*) as c FROM graph_nodes"),n=this.db.query("SELECT COUNT(*) as c FROM graph_edges"),r=this.db.query("SELECT key, value FROM meta"),i={};for(let s of r)i[s.key]=s.value;return {dbPath:this.config.database.path,workspaceDir:this.config.workspaceDir,factsCount:e[0]?.c??0,nodesCount:t[0]?.c??0,edgesCount:n[0]?.c??0,embeddingLlmAvailable:!!this.config.embeddingLlm,graphLlmAvailable:!!this.config.graphLlm,healthy:!0,meta:i}}catch{return {dbPath:this.config.database.path,workspaceDir:this.config.workspaceDir,factsCount:0,nodesCount:0,edgesCount:0,embeddingLlmAvailable:false,graphLlmAvailable:false,healthy:false,meta:{}}}}async sync(){let e={synced:0,created:0,updated:0,errors:[]};await this.hasMemoryFiles()||await this.clearFiles();let n=this.db.query("SELECT * FROM memory_facts ORDER BY category, created_at ASC",[]),r=new Map;for(let i of n){let s=i.category,m=new Date(i.created_at),d=`${`${m.getFullYear()}-${String(m.getMonth()+1).padStart(2,"0")}-${String(m.getDate()).padStart(2,"0")}`}.md`,c=`${s}/${d}`;if(!r.has(c)){let a=R.join(this.config.workspaceDir,"active",s,d);r.set(c,{path:a,facts:[]});}r.get(c).facts.push(i);}for(let[i,{path:s,facts:m}]of r)try{let o=R.dirname(s);await w.mkdir(o,{recursive:!0});let d=m.map(a=>{let l=this.rowToFact(a);return O.serialize(l)}).join(`
`);if(await w.access(s).then(()=>!0).catch(()=>!1)){if((await w.readFile(s,"utf-8")).trim()===d.trim()){e.synced++;continue}e.updated++;}else e.created++;await w.writeFile(s,d,"utf-8"),e.synced++;}catch(o){let d=o instanceof Error?o.message:String(o);e.errors.push(`Failed to sync ${i}: ${d}`),f.warn("Memory file sync failed",{key:i,error:d});}return f.info("Memory sync completed",{synced:e.synced,created:e.created,updated:e.updated,errors:e.errors.length}),this.db.setMeta("lastSync",new Date().toISOString()),e}async hasMemoryFiles(){let e=[R.join(this.config.workspaceDir,"active"),R.join(this.config.workspaceDir,"archive")];for(let t of e)try{let n=await w.readdir(t,{withFileTypes:!0});for(let r of n){let i=R.join(t,r.name);if(r.isDirectory()){if((await w.readdir(i,{withFileTypes:!0})).length>0)return !0}else if(r.name.endsWith(".md"))return !0}}catch(n){if(n.code==="ENOENT")continue;throw n}return  false}async clearFiles(){let e=[R.join(this.config.workspaceDir,"active"),R.join(this.config.workspaceDir,"archive")];for(let t of e)try{let n=await w.readdir(t,{withFileTypes:!0});for(let r of n){let i=R.join(t,r.name);r.isDirectory()?await w.rm(i,{recursive:!0,force:!0}):r.name.endsWith(".md")&&await w.unlink(i);}}catch(n){if(n.code!=="ENOENT")throw n}f.info("Memory files cleared");}rowToFact(e){return {id:e.id,agentId:e.agent_id,sessionId:e.session_id??void 0,msgId:e.msg_id??void 0,parentMsgId:e.parent_msg_id??void 0,content:e.content,category:e.category,importance:e.importance,source:e.source,tags:e.tags?JSON.parse(e.tags):void 0,nodeIds:e.node_ids?JSON.parse(e.node_ids):void 0,filePath:e.file_path??void 0,createdAt:new Date(e.created_at).toISOString(),updatedAt:new Date(e.updated_at).toISOString()}}extractEntities(e){let t=[],n=[],r=new Set,i=new Set,s=/([A-Za-z][\w.-]{1,80})\s+(is_a|part_of|has_attribute|located_in|occurs_in|causes|influences|owned_by|member_of|uses|depends_on|related_to)\s+([A-Za-z][\w.-]{1,80})/g;for(let o of e.matchAll(s)){let d=this.sanitizeEntityToken(o[1]??""),c=(o[2]??"related_to").trim(),a=this.sanitizeEntityToken(o[3]??"");if(!d||!a||d===a)continue;let l=d.toLowerCase();r.has(l)||(r.add(l),t.push({name:d,type:this.inferEntityType(d),properties:{source:"rule_extracted"}}));let u=a.toLowerCase();r.has(u)||(r.add(u),t.push({name:a,type:this.inferEntityType(a),properties:{source:"rule_extracted"}}));let p=`${l}|${u}|${c}`;i.has(p)||(i.add(p),n.push({source:d,target:a,relation:c}));}let m=e.match(/[\p{L}\p{N}][\p{L}\p{N}_.-]{1,80}/gu)??[];for(let o of m){let d=this.sanitizeEntityToken(o);if(!d)continue;let c=d.toLowerCase();r.has(c)||(r.add(c),t.push({name:d,type:this.inferEntityType(d),properties:{source:"keyword_extracted"}}));}return {entities:t,relations:n}}async extractEntitiesWithLlm(e){if(!this.config.graphLlm)return this.extractEntities(e);try{let n=this.buildEntityExtractionPrompt(e);f.debug("LLM extracting entities...",{contentLength:e.length});let r=await $.generate(n,{maxOutputTokens:2e3});f.debug("LLM extraction result",{resultLength:r.length,result:r.slice(0,200)});let i=this.parseEntityExtractionResult(r);return f.debug("Parsed entities",{entityCount:i.entities.length,relationCount:i.relations.length}),i}catch(n){return f.warn("LLM entity extraction failed, falling back to simple extraction",{error:String(n)}),this.extractEntities(e)}}buildEntityExtractionPrompt(e){let t=GRAPH_ENTITY_TYPE_DEFINITIONS.map(i=>`- ${i.type}: ${i.rule}`).join(`
`),n=GRAPH_RELATION_TYPE_DEFINITIONS.map(i=>`- ${i.type}: ${i.rule}`).join(`
`),r=e.slice(0,1e3);return `You are an information extraction engine for a general-purpose memory graph.

Extract entities and directed relations from the text.

Entity type taxonomy:
${t}

Relation type taxonomy:
${n}

Extraction rules:
- Output valid JSON only. Do not include markdown, prose, or code fences.
- Use canonical, concise entity names (deduplicated, case-insensitive).
- Prefer specific entity types over "keyword".
- Include relation only if both source and target entities are present in the entities list.
- Do not invent facts not grounded in the input text.
- Keep relation direction meaningful (source -> target).
- properties should contain short factual attributes only (plain JSON object).

Return this exact JSON shape:
{
  "entities": [
    { "name": "string", "type": "one_of_entity_types", "properties": {} }
  ],
  "relations": [
    { "source": "entity_name", "target": "entity_name", "relation": "one_of_relation_types" }
  ]
}

Input text:
${r}`}storeEntitiesAndRelations(e,t){if(e.length===0)return {nodeIds:[]};let n=new Map,r=new Date().toISOString(),i=e.map(()=>"?").join(","),s=this.db.query(`SELECT id, name, type FROM nodes WHERE name IN (${i})`,e.map(o=>o.name)),m=new Map(s.map(o=>[`${o.name}::${o.type}`,o.id]));return this.db.transaction(()=>{for(let o of e){let d=`${o.name}::${o.type}`,c=m.get(d);if(c!==void 0)this.db.run("UPDATE nodes SET properties = ?, updatedAt = ? WHERE id = ?",[JSON.stringify(o.properties),r,c]),n.set(o.name,c);else {let a=this.db.run("INSERT INTO nodes (name, type, properties, createdAt, updatedAt) VALUES (?, ?, ?, ?, ?)",[o.name,o.type,JSON.stringify(o.properties),r,r]);a.lastID>0&&n.set(o.name,a.lastID);}}for(let o of t){let d=n.get(o.source),c=n.get(o.target);d&&c&&this.db.run("INSERT INTO edges (source, target, relation, createdAt) VALUES (?, ?, ?, ?)",[d,c,o.relation,r]);}}),{nodeIds:Array.from(n.values())}}mergeEntitiesAndRelations(e,t,n,r){if(n.length===0&&r.length===0)return;let i=new Map,s=new Date().toISOString(),m=n.map(()=>"?").join(","),o=this.db.query(`SELECT id, name, type FROM nodes WHERE name IN (${m})`,n.map(c=>c.name)),d=new Map(o.map(c=>[`${c.name}::${c.type}`,c.id]));this.db.transaction(()=>{for(let a of n){let l=`${a.name}::${a.type}`,u=d.get(l);if(u!==void 0)i.set(a.name,u);else {let p=this.db.run("INSERT INTO nodes (name, type, properties, createdAt, updatedAt) VALUES (?, ?, ?, ?, ?)",[a.name,a.type,JSON.stringify(a.properties),s,s]);p.lastID>0&&i.set(a.name,p.lastID);}}for(let a of r){let l=i.get(a.source),u=i.get(a.target);l&&u&&this.db.run("INSERT INTO edges (source, target, relation, createdAt) VALUES (?, ?, ?, ?)",[l,u,a.relation,s]);}let c=Array.from(i.values());c.length>0&&this.db.run("UPDATE memory_facts SET node_ids = ? WHERE id = ?",[JSON.stringify(c),e]);});}async embed(e){if(!this.embeddingModel)return null;let t=createHash("sha256").update(e).digest("hex"),n=this.db.query("SELECT embedding FROM embedding_cache WHERE content_hash = ?",[t])[0];if(n)return new Float32Array(n.embedding.buffer,n.embedding.byteOffset,n.embedding.byteLength/4);try{let i=(await this.embeddingModel.doEmbed({values:[e]})).embeddings[0];if(!i||i.length===0)return null;let s=new Float32Array(i),m=Buffer.from(s.buffer,s.byteOffset,s.byteLength);return this.db.run("INSERT OR REPLACE INTO embedding_cache (content_hash, embedding) VALUES (?, ?)",[t,m]),this.vectorDims===void 0&&(this.vectorDims=i.length,this.db.run("INSERT OR REPLACE INTO meta (key, value) VALUES (?, ?)",["vectorDims",String(i.length)])),s}catch(r){return f.warn("Embedding failed",{error:String(r)}),null}}async embedAndStore(e,t){let n=await this.embed(t);if(!n)return;let r=Buffer.from(n.buffer,n.byteOffset,n.byteLength);try{this.db.run("INSERT OR REPLACE INTO memory_vectors (fact_id, embedding) VALUES (?, ?)",[e,r]);}catch(i){f.warn("Vector store failed (fact may not exist yet)",{factId:e,error:String(i)});}}writeVector(e,t){try{this.db.run("INSERT OR REPLACE INTO memory_vectors (fact_id, embedding) VALUES (?, ?)",[e,t]);}catch(n){f.warn("Vector write failed",{factId:e,error:String(n)});}}writeFts(e,t,n,r){try{let i=se(n),s=r?se(r.join(" ")):"";this.db.run("DELETE FROM memory_facts_fts WHERE fact_id = ?",[e]),this.db.run("INSERT INTO memory_facts_fts (fact_id, agent_id, content, tags) VALUES (?, ?, ?, ?)",[e,t,i,s]);}catch(i){f.warn("FTS index write failed",{factId:e,error:String(i)});}}parseEntityExtractionResult(e){try{let t=e.match(/\{[\s\S]*\}/);if(t){let n=JSON.parse(t[0]);return this.normalizeExtractionResult(n)}}catch(t){f.debug("Failed to parse entity extraction result",{error:String(t)});}return {entities:[],relations:[]}}normalizeExtractionResult(e){let t=e,n=Array.isArray(t.entities)?t.entities:[],r=Array.isArray(t.relations)?t.relations:[],i=[],s=new Set,m=new Map;for(let c of n){let a=typeof c?.name=="string"?c.name.trim():"";if(!a)continue;let l=a.toLowerCase();if(s.has(l))continue;s.add(l),m.set(l,a);let u=typeof c?.type=="string"?c.type.trim():"",p=Ue.has(u)?u:"keyword",b=c?.properties&&typeof c.properties=="object"&&!Array.isArray(c.properties)?c.properties:{};i.push({name:a,type:p,properties:b});}let o=[],d=new Set;for(let c of r){let a=typeof c?.source=="string"?c.source.trim():"",l=typeof c?.target=="string"?c.target.trim():"";if(!a||!l)continue;let u=m.get(a.toLowerCase()),p=m.get(l.toLowerCase());if(!u||!p||u===p)continue;let b=typeof c?.relation=="string"?c.relation.trim():"",D=We.has(b)?b:"related_to",I=`${u.toLowerCase()}|${p.toLowerCase()}|${D}`;d.has(I)||(d.add(I),o.push({source:u,target:p,relation:D}));}return {entities:i,relations:o}}sanitizeEntityToken(e){return e.trim().replace(/^[^\p{L}\p{N}]+|[^\p{L}\p{N}]+$/gu,"").replace(/\s+/g," ").slice(0,120)}inferEntityType(e){let t=e.toLowerCase();return /(\.md|\.ts|\.json|readme|doc|spec|guideline)/i.test(e)?"document":/(api|service|system|engine|pipeline|server|db|database|memorysystem|contextengine)/i.test(e)?"process":/(team|group|org|company|inc|ltd|corp)/i.test(e)?"organization":/(deadline|date|day|week|month|year|q[1-4]|sprint)/i.test(e)?"time":/(score|rate|ratio|latency|accuracy|recall|precision|throughput|kpi)/i.test(e)?"metric":/(task|issue|ticket|todo|action)/i.test(e)?"task":/(event|incident|release|meeting|migration|launch)/i.test(e)?"event":/(process|workflow|procedure|flow|lifecycle)/i.test(e)?"process":/(file|model|dataset|artifact|resource|tool|sdk|ollama|sqlite|embedding|vector|fts)/i.test(e)?"object":/(concept|principle|policy|method|pattern|strategy)/i.test(e)?"concept":/[A-Z]/.test(e)&&t!==e?"object":"keyword"}getSearchEngine(){if(!this.searchEngine)throw new T("Memory system not initialized. Call initialize() first.");return this.searchEngine}getGraphStore(){if(!this.graphStore)throw new T("Memory system not initialized. Call initialize() first.");return this.graphStore}getArchiver(){if(!this.archiver)throw new T("Memory system not initialized. Call initialize() first.");return this.archiver}};async function je(g){let e=new ee(g);return await e.initialize(),e}async function tr(g){let{Log:e}=await import('./chunks/log-P32ZYYG2.mjs'),t=false;await e.init({logDir:g.logDir??process.env.EASBOT_LOG_PATH??process.cwd(),print:g.print??false,dev:g.dev??t,level:g.level??("INFO")});}export{V as GraphStore,re as MEMORY_CATEGORIES,H as MemoryArchiver,T as MemoryDatabaseError,X as MemoryDatabaseManager,Y as MemoryEmbeddingError,x as MemoryError,Re as MemoryErrorCode,S as MemoryFileError,A as MemoryFileManager,O as MemoryFormatter,j as MemoryNotFoundError,B as MemoryPermissionError,G as MemorySearchError,ee as MemorySystem,N as MemoryValidationError,Je as addWord,Ke as closeTokenizer,je as createMemorySystem,tr as initLog,ce as initTokenizer,Ge as isInitialized,Ie as loadCustomDict,se as toFtsTokens,me as toFtsTokensForSearch,Ae as tokenize,Ne as tokenizeForSearch};